chore(typing): enforce --noImplicitAny for tools directory.

Exposed a couple of bugs.

Closes #6645
This commit is contained in:
Alex Eagle 2016-01-22 10:51:16 -08:00 committed by Misko Hevery
parent 7112d008d0
commit ebe14720eb
34 changed files with 174 additions and 161 deletions

View File

@ -1161,6 +1161,7 @@ gulp.task('!build.tools', function() {
target: 'ES5', target: 'ES5',
module: 'commonjs', module: 'commonjs',
declaration: true, declaration: true,
noImplicitAny: true,
// Don't use the version of typescript that gulp-typescript depends on // Don't use the version of typescript that gulp-typescript depends on
// see https://github.com/ivogabe/gulp-typescript#typescript-version // see https://github.com/ivogabe/gulp-typescript#typescript-version
typescript: require('typescript') typescript: require('typescript')

View File

@ -122,8 +122,8 @@ export class AngularBuilder {
} }
private rebuild(builder, name) { private rebuild(builder: BroccoliBuilder, name: string): Promise<BuildResult> {
return builder.build().then( return builder.build().then<BuildResult>(
(result) => { (result) => {
if (!this.firstResult) { if (!this.firstResult) {
this.firstResult = result; this.firstResult = result;
@ -131,8 +131,9 @@ export class AngularBuilder {
printSlowTrees(result.graph); printSlowTrees(result.graph);
writeBuildLog(result, name); writeBuildLog(result, name);
return result;
}, },
(error) => { (error): any => {
// the build tree is the same during rebuilds, only leaf properties of the nodes change // the build tree is the same during rebuilds, only leaf properties of the nodes change
// so let's traverse it and get updated values for input/cache/output paths // so let's traverse it and get updated values for input/cache/output paths
if (this.firstResult) { if (this.firstResult) {
@ -155,10 +156,10 @@ function writeBuildLog(result: BuildResult, name: string) {
} }
function broccoliNodeToBuildNode(broccoliNode) { function broccoliNodeToBuildNode(broccoliNode: BroccoliNode): BuildNode {
let tree = broccoliNode.tree.newStyleTree || broccoliNode.tree; let tree = broccoliNode.tree.newStyleTree || broccoliNode.tree;
return new BuildNode(tree.description || tree.constructor.name, return new BuildNode(tree.description || (<any>tree.constructor).name,
tree.inputPath ? [tree.inputPath] : tree.inputPaths, tree.cachePath, tree.inputPath ? [tree.inputPath] : tree.inputPaths, tree.cachePath,
tree.outputPath, broccoliNode.selfTime / (1000 * 1000 * 1000), tree.outputPath, broccoliNode.selfTime / (1000 * 1000 * 1000),
broccoliNode.totalTime / (1000 * 1000 * 1000), broccoliNode.totalTime / (1000 * 1000 * 1000),
@ -169,5 +170,5 @@ function broccoliNodeToBuildNode(broccoliNode) {
class BuildNode { class BuildNode {
constructor(public pluginName: string, public inputPaths: string[], public cachePath: string, constructor(public pluginName: string, public inputPaths: string[], public cachePath: string,
public outputPath: string, public selfTime: number, public totalTime: number, public outputPath: string, public selfTime: number, public totalTime: number,
public inputNodes: BroccoliNode[]) {} public inputNodes: BuildNode[]) {}
} }

View File

@ -12,7 +12,7 @@ class CheckImports implements DiffingBroccoliPlugin {
static IMPORT_DECL_REGEXP = new RegExp(`^import[^;]+;`, "mg"); static IMPORT_DECL_REGEXP = new RegExp(`^import[^;]+;`, "mg");
static IMPORT_PATH_REGEXP = new RegExp(`['"]([^'"]+)+['"]`, "m"); static IMPORT_PATH_REGEXP = new RegExp(`['"]([^'"]+)+['"]`, "m");
static ALLOWED_IMPORTS = { static ALLOWED_IMPORTS: {[s: string]: string[]} = {
"angular2/src/core": ["angular2/src/facade"], "angular2/src/core": ["angular2/src/facade"],
"angular2/src/facade": ["rxjs"], "angular2/src/facade": ["rxjs"],
"angular2/src/common": ["angular2/core", "angular2/src/facade"], "angular2/src/common": ["angular2/core", "angular2/src/facade"],
@ -28,7 +28,7 @@ class CheckImports implements DiffingBroccoliPlugin {
private initRun = true; private initRun = true;
constructor(private inputPath, private cachePath, private options) {} constructor(private inputPath: string, private cachePath: string, private options: number) {}
rebuild(treeDiff: DiffResult) { rebuild(treeDiff: DiffResult) {
const errors = this.checkAllPaths(treeDiff); const errors = this.checkAllPaths(treeDiff);

View File

@ -3,12 +3,14 @@
import fse = require('fs-extra'); import fse = require('fs-extra');
import path = require('path'); import path = require('path');
import {wrapDiffingPlugin, DiffingBroccoliPlugin, DiffResult} from './diffing-broccoli-plugin'; import {wrapDiffingPlugin, DiffingBroccoliPlugin, DiffResult} from './diffing-broccoli-plugin';
import {AngularBuilderOptions} from './angular_builder';
var spawn = require('child_process').spawn; var spawn = require('child_process').spawn;
var exec = require('child_process').exec; var exec = require('child_process').exec;
function processToPromise(process) { function processToPromise(process: NodeJS.Process) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
process.on('close', function(code) { process.on('close', function(code: number) {
if (code) { if (code) {
reject(code); reject(code);
} else { } else {
@ -23,7 +25,7 @@ class DartFormatter implements DiffingBroccoliPlugin {
private verbose: boolean; private verbose: boolean;
private firstBuild: boolean = true; private firstBuild: boolean = true;
constructor(public inputPath: string, public cachePath: string, options) { constructor(public inputPath: string, public cachePath: string, options: AngularBuilderOptions) {
if (!options.dartSDK) throw new Error("Missing Dart SDK"); if (!options.dartSDK) throw new Error("Missing Dart SDK");
this.DARTFMT = options.dartSDK.DARTFMT; this.DARTFMT = options.dartSDK.DARTFMT;
this.verbose = options.logs.dartfmt; this.verbose = options.logs.dartfmt;
@ -32,7 +34,7 @@ class DartFormatter implements DiffingBroccoliPlugin {
rebuild(treeDiff: DiffResult): Promise<any> { rebuild(treeDiff: DiffResult): Promise<any> {
let args = ['-w']; let args = ['-w'];
let argsLength = 2; let argsLength = 2;
let argPackages = []; let argPackages: string[][] = [];
let firstBuild = this.firstBuild; let firstBuild = this.firstBuild;
treeDiff.addedPaths.concat(treeDiff.changedPaths) treeDiff.addedPaths.concat(treeDiff.changedPaths)
.forEach((changedFile) => { .forEach((changedFile) => {
@ -59,10 +61,10 @@ class DartFormatter implements DiffingBroccoliPlugin {
argPackages.push(args); argPackages.push(args);
} }
let execute = (args) => { let execute = (args: string[]) => {
if (args.length < 2) return Promise.resolve(); if (args.length < 2) return Promise.resolve();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
exec(this.DARTFMT + ' ' + args.join(' '), (err, stdout, stderr) => { exec(this.DARTFMT + ' ' + args.join(' '), (err: Error, stdout: string, stderr: string) => {
if (this.verbose) { if (this.verbose) {
console.log(stdout); console.log(stdout);
} }
@ -91,9 +93,9 @@ export default wrapDiffingPlugin(DartFormatter);
var ARROW_LINE = /^(\s+)\^+/; var ARROW_LINE = /^(\s+)\^+/;
var BEFORE_CHARS = 15; var BEFORE_CHARS = 15;
var stripAnsi = require('strip-ansi'); var stripAnsi = require('strip-ansi');
function shortenFormatterOutput(formatterOutput) { function shortenFormatterOutput(formatterOutput: string) {
var lines = formatterOutput.split('\n'); var lines = formatterOutput.split('\n');
var match, line; var match: string, line: string;
for (var i = 0; i < lines.length; i += 1) { for (var i = 0; i < lines.length; i += 1) {
line = lines[i]; line = lines[i];
if (match = stripAnsi(line).match(ARROW_LINE)) { if (match = stripAnsi(line).match(ARROW_LINE)) {

View File

@ -11,7 +11,7 @@ import {wrapDiffingPlugin, DiffingBroccoliPlugin, DiffResult} from './diffing-br
* and tees a copy to the given path outside the tmp dir. * and tees a copy to the given path outside the tmp dir.
*/ */
class DestCopy implements DiffingBroccoliPlugin { class DestCopy implements DiffingBroccoliPlugin {
constructor(private inputPath, private cachePath, private outputRoot: string) {} constructor(private inputPath: string, private cachePath: string, private outputRoot: string) {}
rebuild(treeDiff: DiffResult) { rebuild(treeDiff: DiffResult) {

View File

@ -10,11 +10,11 @@ import {DiffingFlatten} from './broccoli-flatten';
describe('Flatten', () => { describe('Flatten', () => {
afterEach(() => mockfs.restore()); afterEach(() => mockfs.restore());
function flatten(inputPaths) { return new DiffingFlatten(inputPaths, 'output', null); } let flatten = (inputPaths: string) => new DiffingFlatten(inputPaths, 'output', null);
let read = (path: string) => fs.readFileSync(path, {encoding: "utf-8"});
function read(path) { return fs.readFileSync(path, {encoding: "utf-8"}); } let rm = (path: string) => fs.unlinkSync(path);
function rm(path) { return fs.unlinkSync(path); } let write =
function write(path, content) { fs.writeFileSync(path, content, {encoding: "utf-8"}); } (path: string, content: string) => { fs.writeFileSync(path, content, {encoding: "utf-8"}); }
it('should flatten files and be incremental', () => { it('should flatten files and be incremental', () => {

View File

@ -2,6 +2,8 @@ import fs = require('fs');
import fse = require('fs-extra'); import fse = require('fs-extra');
import path = require('path'); import path = require('path');
import {wrapDiffingPlugin, DiffingBroccoliPlugin, DiffResult} from './diffing-broccoli-plugin'; import {wrapDiffingPlugin, DiffingBroccoliPlugin, DiffResult} from './diffing-broccoli-plugin';
import {AngularBuilderOptions} from './angular_builder';
var symlinkOrCopy = require('symlink-or-copy').sync; var symlinkOrCopy = require('symlink-or-copy').sync;
var isWindows = process.platform === 'win32'; var isWindows = process.platform === 'win32';
@ -12,7 +14,8 @@ var isWindows = process.platform === 'win32';
* the associated changes. * the associated changes.
*/ */
export class DiffingFlatten implements DiffingBroccoliPlugin { export class DiffingFlatten implements DiffingBroccoliPlugin {
constructor(private inputPath, private cachePath, private options) {} constructor(private inputPath: string, private cachePath: string,
private options: AngularBuilderOptions) {}
rebuild(treeDiff: DiffResult) { rebuild(treeDiff: DiffResult) {

View File

@ -13,10 +13,11 @@ import {wrapDiffingPlugin, DiffingBroccoliPlugin, DiffResult} from './diffing-br
class GeneratorForTest implements DiffingBroccoliPlugin { class GeneratorForTest implements DiffingBroccoliPlugin {
private seenFiles: {[key: string]: boolean} = {}; private seenFiles: {[key: string]: boolean} = {};
constructor(private inputPath, private outputPath, private options) {} constructor(private inputPath: string, private outputPath: string,
private options: { files: string[], dartPath: string }) {}
rebuild(treeDiff: DiffResult) { rebuild(treeDiff: DiffResult) {
var matchedFiles = []; var matchedFiles: string[] = [];
this.options.files.forEach( this.options.files.forEach(
(file) => { matchedFiles = matchedFiles.concat(glob.sync(file, {cwd: this.inputPath})); }); (file) => { matchedFiles = matchedFiles.concat(glob.sync(file, {cwd: this.inputPath})); });
return Promise.all(matchedFiles.map((matchedFile) => { return Promise.all(matchedFiles.map((matchedFile) => {
@ -46,9 +47,9 @@ class GeneratorForTest implements DiffingBroccoliPlugin {
private invokeGenerator(file: string, inputFilePath: string, private invokeGenerator(file: string, inputFilePath: string,
outputFilePath: string): Promise<any> { outputFilePath: string): Promise<any> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var args; var args: string[];
var vmPath; var vmPath: string;
var env; var env: {[key: string]: string};
if (this.options.dartPath) { if (this.options.dartPath) {
vmPath = this.options.dartPath; vmPath = this.options.dartPath;
args = [`--package-root=${this.inputPath}`, '--checked', inputFilePath, file]; args = [`--package-root=${this.inputPath}`, '--checked', inputFilePath, file];
@ -63,8 +64,10 @@ class GeneratorForTest implements DiffingBroccoliPlugin {
var stdoutStream = fs.createWriteStream(outputFilePath); var stdoutStream = fs.createWriteStream(outputFilePath);
var proc = childProcess.spawn( var proc = childProcess.spawn(
vmPath, args, vmPath, args,
{stdio: ['ignore', 'pipe', 'inherit'], env: Object['assign']({}, process.env, env)}); { stdio: ['ignore', 'pipe', 'inherit'],
proc.on('error', function(code) { env: (<any>Object)['assign']({}, process.env, env)
});
proc.on('error', function(code: any) {
console.error(code); console.error(code);
reject(new Error('Failed while generating code. Please run manually: ' + vmPath + ' ' + reject(new Error('Failed while generating code. Please run manually: ' + vmPath + ' ' +
args.join(' '))); args.join(' ')));

View File

@ -23,12 +23,12 @@ const kDefaultOptions: LodashRendererOptions = {
* the associated changes. * the associated changes.
*/ */
export class LodashRenderer implements DiffingBroccoliPlugin { export class LodashRenderer implements DiffingBroccoliPlugin {
constructor(private inputPath, private cachePath, constructor(private inputPath: string, private cachePath: string,
private options: LodashRendererOptions = kDefaultOptions) {} private options: LodashRendererOptions = kDefaultOptions) {}
rebuild(treeDiff: DiffResult) { rebuild(treeDiff: DiffResult) {
let {encoding = 'utf-8', context = {}} = this.options; let {encoding = 'utf-8', context = {}} = this.options;
let processFile = (relativePath) => { let processFile = (relativePath: string) => {
let sourceFilePath = path.join(this.inputPath, relativePath); let sourceFilePath = path.join(this.inputPath, relativePath);
let destFilePath = path.join(this.cachePath, relativePath); let destFilePath = path.join(this.cachePath, relativePath);
let content = fs.readFileSync(sourceFilePath, {encoding}); let content = fs.readFileSync(sourceFilePath, {encoding});
@ -36,7 +36,7 @@ export class LodashRenderer implements DiffingBroccoliPlugin {
fse.outputFileSync(destFilePath, transformedContent); fse.outputFileSync(destFilePath, transformedContent);
}; };
let removeFile = (relativePath) => { let removeFile = (relativePath: string) => {
let destFilePath = path.join(this.cachePath, relativePath); let destFilePath = path.join(this.cachePath, relativePath);
fs.unlinkSync(destFilePath); fs.unlinkSync(destFilePath);
}; };

View File

@ -3,23 +3,22 @@
let mockfs = require('mock-fs'); let mockfs = require('mock-fs');
import fs = require('fs'); import fs = require('fs');
import {TreeDiffer} from './tree-differ'; import {TreeDiffer, DiffResult} from './tree-differ';
import {MergeTrees} from './broccoli-merge-trees'; import {MergeTrees} from './broccoli-merge-trees';
describe('MergeTrees', () => { describe('MergeTrees', () => {
afterEach(() => mockfs.restore()); afterEach(() => mockfs.restore());
function mergeTrees(inputPaths, cachePath, options) { function mergeTrees(inputPaths: string[], cachePath: string, options: {}) {
return new MergeTrees(inputPaths, cachePath, options); return new MergeTrees(inputPaths, cachePath, options);
} }
function MakeTreeDiffers(rootDirs) { function MakeTreeDiffers(rootDirs: string[]): TreeDiffer[] {
let treeDiffers = rootDirs.map((rootDir) => new TreeDiffer('MergeTrees', rootDir)); return rootDirs.map((rootDir) => new TreeDiffer('MergeTrees', rootDir));
treeDiffers.diffTrees = () => { return treeDiffers.map(tree => tree.diffTree()); };
return treeDiffers;
} }
function read(path) { return fs.readFileSync(path, "utf-8"); } let diffTrees = (differs: TreeDiffer[]): DiffResult[] => differs.map(tree => tree.diffTree());
function read(path: string) { return fs.readFileSync(path, "utf-8"); }
it('should copy the file from the right-most inputTree with overwrite=true', () => { it('should copy the file from the right-most inputTree with overwrite=true', () => {
let testDir: any = { let testDir: any = {
@ -30,18 +29,18 @@ describe('MergeTrees', () => {
mockfs(testDir); mockfs(testDir);
let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']); let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']);
let treeMerger = mergeTrees(['tree1', 'tree2', 'tree3'], 'dest', {overwrite: true}); let treeMerger = mergeTrees(['tree1', 'tree2', 'tree3'], 'dest', {overwrite: true});
treeMerger.rebuild(treeDiffer.diffTrees()); treeMerger.rebuild(diffTrees(treeDiffer));
expect(read('dest/foo.js')).toBe('tree3/foo.js content'); expect(read('dest/foo.js')).toBe('tree3/foo.js content');
delete testDir.tree2['foo.js']; delete testDir.tree2['foo.js'];
delete testDir.tree3['foo.js']; delete testDir.tree3['foo.js'];
mockfs(testDir); mockfs(testDir);
treeMerger.rebuild(treeDiffer.diffTrees()); treeMerger.rebuild(diffTrees(treeDiffer));
expect(read('dest/foo.js')).toBe('tree1/foo.js content'); expect(read('dest/foo.js')).toBe('tree1/foo.js content');
testDir.tree2['foo.js'] = mockfs.file({content: 'tree2/foo.js content', mtime: new Date(1000)}); testDir.tree2['foo.js'] = mockfs.file({content: 'tree2/foo.js content', mtime: new Date(1000)});
mockfs(testDir); mockfs(testDir);
treeMerger.rebuild(treeDiffer.diffTrees()); treeMerger.rebuild(diffTrees(treeDiffer));
expect(read('dest/foo.js')).toBe('tree2/foo.js content'); expect(read('dest/foo.js')).toBe('tree2/foo.js content');
}); });
@ -54,7 +53,7 @@ describe('MergeTrees', () => {
mockfs(testDir); mockfs(testDir);
let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']); let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']);
let treeMerger = mergeTrees(['tree1', 'tree2', 'tree3'], 'dest', {}); let treeMerger = mergeTrees(['tree1', 'tree2', 'tree3'], 'dest', {});
expect(() => treeMerger.rebuild(treeDiffer.diffTrees())) expect(() => treeMerger.rebuild(diffTrees(treeDiffer)))
.toThrowError( .toThrowError(
'Duplicate path found while merging trees. Path: "foo.js".\n' + 'Duplicate path found while merging trees. Path: "foo.js".\n' +
'Either remove the duplicate or enable the "overwrite" option for this merge.'); 'Either remove the duplicate or enable the "overwrite" option for this merge.');
@ -69,7 +68,7 @@ describe('MergeTrees', () => {
it('should throw if duplicates are found during rebuild', () => { it('should throw if duplicates are found during rebuild', () => {
let testDir = { let testDir: any = {
'tree1': {'foo.js': mockfs.file({content: 'tree1/foo.js content', mtime: new Date(1000)})}, 'tree1': {'foo.js': mockfs.file({content: 'tree1/foo.js content', mtime: new Date(1000)})},
'tree2': {}, 'tree2': {},
'tree3': {} 'tree3': {}
@ -78,12 +77,12 @@ describe('MergeTrees', () => {
let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']); let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']);
let treeMerger = mergeTrees(['tree1', 'tree2', 'tree3'], 'dest', {}); let treeMerger = mergeTrees(['tree1', 'tree2', 'tree3'], 'dest', {});
expect(() => treeMerger.rebuild(treeDiffer.diffTrees())).not.toThrow(); expect(() => treeMerger.rebuild(diffTrees(treeDiffer))).not.toThrow();
testDir.tree2['foo.js'] = mockfs.file({content: 'tree2/foo.js content', mtime: new Date(1000)}); testDir.tree2['foo.js'] = mockfs.file({content: 'tree2/foo.js content', mtime: new Date(1000)});
mockfs(testDir); mockfs(testDir);
expect(() => treeMerger.rebuild(treeDiffer.diffTrees())) expect(() => treeMerger.rebuild(diffTrees(treeDiffer)))
.toThrowError( .toThrowError(
'Duplicate path found while merging trees. Path: "foo.js".\n' + 'Duplicate path found while merging trees. Path: "foo.js".\n' +
'Either remove the duplicate or enable the "overwrite" option for this merge.'); 'Either remove the duplicate or enable the "overwrite" option for this merge.');

View File

@ -8,13 +8,13 @@ var isWindows = process.platform === 'win32';
export interface MergeTreesOptions { overwrite?: boolean; } export interface MergeTreesOptions { overwrite?: boolean; }
function outputFileSync(sourcePath, destPath) { function outputFileSync(sourcePath: string, destPath: string) {
let dirname = path.dirname(destPath); let dirname = path.dirname(destPath);
fse.mkdirsSync(dirname, {fs: fs}); fse.mkdirsSync(dirname, {fs: fs});
symlinkOrCopySync(sourcePath, destPath); symlinkOrCopySync(sourcePath, destPath);
} }
function pathOverwrittenError(path) { function pathOverwrittenError(path: string) {
const msg = 'Either remove the duplicate or enable the "overwrite" option for this merge.'; const msg = 'Either remove the duplicate or enable the "overwrite" option for this merge.';
return new Error(`Duplicate path found while merging trees. Path: "${path}".\n${msg}`); return new Error(`Duplicate path found while merging trees. Path: "${path}".\n${msg}`);
} }
@ -34,14 +34,14 @@ export class MergeTrees implements DiffingBroccoliPlugin {
let pathsToEmit: string[] = []; let pathsToEmit: string[] = [];
let pathsToRemove: string[] = []; let pathsToRemove: string[] = [];
let emitted: {[key: string]: boolean} = Object.create(null); let emitted: {[key: string]: boolean} = Object.create(null);
let contains = (cache, val) => { let contains = (cache: number[], val: number) => {
for (let i = 0, ii = cache.length; i < ii; ++i) { for (let i = 0, ii = cache.length; i < ii; ++i) {
if (cache[i] === val) return true; if (cache[i] === val) return true;
} }
return false; return false;
}; };
let emit = (relativePath) => { let emit = (relativePath: string) => {
// ASSERT(!emitted[relativePath]); // ASSERT(!emitted[relativePath]);
pathsToEmit.push(relativePath); pathsToEmit.push(relativePath);
emitted[relativePath] = true; emitted[relativePath] = true;
@ -51,7 +51,7 @@ export class MergeTrees implements DiffingBroccoliPlugin {
this.firstBuild = false; this.firstBuild = false;
// Build initial cache // Build initial cache
treeDiffs.reverse().forEach((treeDiff: DiffResult, index) => { treeDiffs.reverse().forEach((treeDiff: DiffResult, index: number) => {
index = treeDiffs.length - 1 - index; index = treeDiffs.length - 1 - index;
treeDiff.addedPaths.forEach((changedPath) => { treeDiff.addedPaths.forEach((changedPath) => {
let cache = this.pathCache[changedPath]; let cache = this.pathCache[changedPath];
@ -69,7 +69,7 @@ export class MergeTrees implements DiffingBroccoliPlugin {
} else { } else {
// Update cache // Update cache
treeDiffs.reverse().forEach((treeDiff: DiffResult, index) => { treeDiffs.reverse().forEach((treeDiff: DiffResult, index: number) => {
index = treeDiffs.length - 1 - index; index = treeDiffs.length - 1 - index;
if (treeDiff.removedPaths) { if (treeDiff.removedPaths) {
treeDiff.removedPaths.forEach((removedPath) => { treeDiff.removedPaths.forEach((removedPath) => {

View File

@ -11,7 +11,8 @@ var FILE_ENCODING = {encoding: 'utf-8'};
* the associated changes. * the associated changes.
*/ */
class DiffingReplace implements DiffingBroccoliPlugin { class DiffingReplace implements DiffingBroccoliPlugin {
constructor(private inputPath, private cachePath, private options) {} // TODO: define an interface for options
constructor(private inputPath: string, private cachePath: string, private options: any) {}
rebuild(treeDiff: DiffResult) { rebuild(treeDiff: DiffResult) {
var patterns = this.options.patterns; var patterns = this.options.patterns;
@ -27,13 +28,13 @@ class DiffingReplace implements DiffingBroccoliPlugin {
fse.mkdirpSync(destDirPath); fse.mkdirpSync(destDirPath);
} }
var fileMatches = files.some((filePath) => minimatch(changedFilePath, filePath)); var fileMatches = files.some((filePath: string) => minimatch(changedFilePath, filePath));
if (fileMatches) { if (fileMatches) {
var content = fs.readFileSync(sourceFilePath, FILE_ENCODING); var content = fs.readFileSync(sourceFilePath, FILE_ENCODING);
patterns.forEach((pattern) => { patterns.forEach((pattern: any) => {
var replacement = pattern.replacement; var replacement = pattern.replacement;
if (typeof replacement === 'function') { if (typeof replacement === 'function') {
replacement = function(content) { replacement = function(content: string) {
return pattern.replacement(content, changedFilePath); return pattern.replacement(content, changedFilePath);
}; };
} }

View File

@ -40,6 +40,6 @@ class TreeStabilizer implements BroccoliTree {
} }
export default function stabilizeTree(inputTree): BroccoliTree { export default function stabilizeTree(inputTree: BroccoliTree): BroccoliTree {
return new TreeStabilizer(inputTree); return new TreeStabilizer(inputTree);
} }

View File

@ -59,7 +59,8 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
static includeExtensions = ['.ts']; static includeExtensions = ['.ts'];
constructor(public inputPath: string, public cachePath: string, public options) { constructor(public inputPath: string, public cachePath: string, public options: any) {
// TODO: define an interface for options
if (options.rootFilePaths) { if (options.rootFilePaths) {
this.rootFilePaths = options.rootFilePaths.splice(0); this.rootFilePaths = options.rootFilePaths.splice(0);
delete options.rootFilePaths; delete options.rootFilePaths;
@ -94,9 +95,9 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
rebuild(treeDiff: DiffResult) { rebuild(treeDiff: DiffResult) {
let pathsToEmit = []; let pathsToEmit: string[] = [];
let pathsWithErrors = []; let pathsWithErrors: string[] = [];
let errorMessages = []; let errorMessages: string[] = [];
treeDiff.addedPaths.concat(treeDiff.changedPaths) treeDiff.addedPaths.concat(treeDiff.changedPaths)
.forEach((tsFilePath) => { .forEach((tsFilePath) => {
@ -151,7 +152,7 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
this.previousRunFailed = true; this.previousRunFailed = true;
var error = var error =
new Error('Typescript found the following errors:\n' + errorMessages.join('\n')); new Error('Typescript found the following errors:\n' + errorMessages.join('\n'));
error['showStack'] = false; (<any>error)['showStack'] = false;
throw error; throw error;
} else if (this.previousRunFailed) { } else if (this.previousRunFailed) {
this.doFullBuild(); this.doFullBuild();
@ -175,11 +176,11 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
} }
} }
private collectErrors(tsFilePath): String { private collectErrors(tsFilePath: string): string {
let allDiagnostics = this.tsService.getCompilerOptionsDiagnostics() let allDiagnostics = this.tsService.getCompilerOptionsDiagnostics()
.concat(this.tsService.getSyntacticDiagnostics(tsFilePath)) .concat(this.tsService.getSyntacticDiagnostics(tsFilePath))
.concat(this.tsService.getSemanticDiagnostics(tsFilePath)); .concat(this.tsService.getSemanticDiagnostics(tsFilePath));
let errors = []; let errors: string[] = [];
allDiagnostics.forEach(diagnostic => { allDiagnostics.forEach(diagnostic => {
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
@ -230,7 +231,7 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
if (emitResult.emitSkipped) { if (emitResult.emitSkipped) {
let allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); let allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
let errorMessages = []; let errorMessages: string[] = [];
allDiagnostics.forEach(diagnostic => { allDiagnostics.forEach(diagnostic => {
var pos = ''; var pos = '';
@ -246,7 +247,7 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
this.previousRunFailed = true; this.previousRunFailed = true;
var error = var error =
new Error('Typescript found the following errors:\n' + errorMessages.join('\n')); new Error('Typescript found the following errors:\n' + errorMessages.join('\n'));
error['showStack'] = false; (<any>error)['showStack'] = false;
throw error; throw error;
} else { } else {
this.previousRunFailed = false; this.previousRunFailed = false;

View File

@ -2,7 +2,7 @@
declare module "broccoli-writer" { declare module "broccoli-writer" {
class Writer { class Writer {
write(readTree: (tree) => Promise<string>, destDir: string): Promise<any>; write(readTree: (tree: BroccoliTree) => Promise<string>, destDir: string): Promise<any>;
} }
export = Writer; export = Writer;
} }

View File

@ -9,21 +9,18 @@ import {TreeDiffer, DiffResult} from './tree-differ';
import stabilizeTree from './broccoli-tree-stabilizer'; import stabilizeTree from './broccoli-tree-stabilizer';
let symlinkOrCopy = require('symlink-or-copy'); let symlinkOrCopy = require('symlink-or-copy');
export {DiffResult} from './tree-differ'; export {DiffResult} from './tree-differ';
export type PluginClass = any;
/** /**
* Makes writing diffing plugins easy. * Makes writing diffing plugins easy.
* *
* Factory method that takes a class that implements the DiffingBroccoliPlugin interface and returns * Factory method that takes a class that implements the DiffingBroccoliPlugin interface and returns
* an instance of BroccoliTree. * an instance of BroccoliTree.
*
* @param pluginClass
* @returns {DiffingBroccoliPlugin}
*/ */
export function wrapDiffingPlugin(pluginClass): DiffingPluginWrapperFactory { export function wrapDiffingPlugin(pluginClass: PluginClass): DiffingPluginWrapperFactory {
return function() { return new DiffingPluginWrapper(pluginClass, arguments); }; return function() { return new DiffingPluginWrapper(pluginClass, arguments) };
} }
@ -33,8 +30,8 @@ export interface DiffingBroccoliPlugin {
} }
export type DiffingPluginWrapperFactory = (inputTrees: (BroccoliTree | BroccoliTree[]), options?) => export type DiffingPluginWrapperFactory =
BroccoliTree; (inputTrees: (BroccoliTree | BroccoliTree[]), options?: any) => BroccoliTree;
class DiffingPluginWrapper implements BroccoliTree { class DiffingPluginWrapper implements BroccoliTree {
@ -42,19 +39,19 @@ class DiffingPluginWrapper implements BroccoliTree {
treeDiffers: TreeDiffer[] = null; treeDiffers: TreeDiffer[] = null;
initialized = false; initialized = false;
wrappedPlugin: DiffingBroccoliPlugin = null; wrappedPlugin: DiffingBroccoliPlugin = null;
inputTree = null; inputTree: BroccoliTree = null;
inputTrees = null; inputTrees: BroccoliTree[] = null;
description = null; description: string = null;
// props monkey-patched by broccoli builder: // props monkey-patched by broccoli builder:
inputPath = null; inputPath: string = null;
inputPaths = null; inputPaths: string[] = null;
cachePath = null; cachePath: string = null;
outputPath = null; outputPath: string = null;
private diffResult: DiffResult = null; private diffResult: DiffResult = null;
constructor(private pluginClass, private wrappedPluginArguments) { constructor(private pluginClass: PluginClass, private wrappedPluginArguments: IArguments) {
if (Array.isArray(wrappedPluginArguments[0])) { if (Array.isArray(wrappedPluginArguments[0])) {
this.inputTrees = this.stabilizeTrees(wrappedPluginArguments[0]); this.inputTrees = this.stabilizeTrees(wrappedPluginArguments[0]);
} else { } else {
@ -65,7 +62,7 @@ class DiffingPluginWrapper implements BroccoliTree {
} }
private getDiffResult(): (DiffResult | DiffResult[]) { private getDiffResult(): (DiffResult | DiffResult[]) {
let returnOrCalculateDiffResult = (tree, index) => { let returnOrCalculateDiffResult = (tree: BroccoliTree, index: number) => {
// returnOrCalculateDiffResult will do one of two things: // returnOrCalculateDiffResult will do one of two things:
// //
// If `this.diffResult` is null, calculate a DiffResult using TreeDiffer // If `this.diffResult` is null, calculate a DiffResult using TreeDiffer
@ -74,16 +71,16 @@ class DiffingPluginWrapper implements BroccoliTree {
// Otherwise, `this.diffResult` was produced from the output of the // Otherwise, `this.diffResult` was produced from the output of the
// inputTree's rebuild() method, and can be used without being checked. // inputTree's rebuild() method, and can be used without being checked.
// Set `this.diffResult` to null and return the previously stored value. // Set `this.diffResult` to null and return the previously stored value.
let diffResult = tree.diffResult; let diffResult = this.diffResult;
if (diffResult) return diffResult; if (diffResult) return diffResult;
let differ = index === false ? this.treeDiffer : this.treeDiffers[index]; let differ = index === -1 ? this.treeDiffer : this.treeDiffers[index];
return differ.diffTree(); return differ.diffTree();
}; };
if (this.inputTrees) { if (this.inputTrees) {
return this.inputTrees.map(returnOrCalculateDiffResult); return this.inputTrees.map(returnOrCalculateDiffResult);
} else if (this.inputTree) { } else if (this.inputTree) {
return returnOrCalculateDiffResult(this.inputTree, false); return returnOrCalculateDiffResult(this.inputTree, -1);
} else { } else {
throw new Error("Missing TreeDiffer"); throw new Error("Missing TreeDiffer");
} }
@ -160,7 +157,7 @@ class DiffingPluginWrapper implements BroccoliTree {
private stabilizeTrees(trees: BroccoliTree[]) { private stabilizeTrees(trees: BroccoliTree[]) {
// Prevent extensions to prevent array from being mutated from the outside. // Prevent extensions to prevent array from being mutated from the outside.
// For-loop used to avoid re-allocating a new array. // For-loop used to avoid re-allocating a new array.
var stableTrees = []; var stableTrees: BroccoliTree[] = [];
for (let i = 0; i < trees.length; ++i) { for (let i = 0; i < trees.length; ++i) {
// ignore null/undefined input tries in order to support conditional build pipelines // ignore null/undefined input tries in order to support conditional build pipelines
if (trees[i]) { if (trees[i]) {
@ -182,8 +179,9 @@ class DiffingPluginWrapper implements BroccoliTree {
// Since it's not safe to use instanceof operator in node, we are checking the constructor.name. // Since it's not safe to use instanceof operator in node, we are checking the constructor.name.
// //
// New-style/rebuild trees should always be stable. // New-style/rebuild trees should always be stable.
let isNewStyleTree = !!(tree['newStyleTree'] || typeof tree.rebuild === 'function' || let isNewStyleTree =
tree['isReadAPICompatTree'] || tree.constructor['name'] === 'Funnel'); !!(tree['newStyleTree'] || typeof tree.rebuild === 'function' ||
(<any>tree)['isReadAPICompatTree'] || (<any>tree).constructor['name'] === 'Funnel');
return isNewStyleTree ? tree : stabilizeTree(tree); return isNewStyleTree ? tree : stabilizeTree(tree);
} }

View File

@ -2,7 +2,7 @@ var fs = require('fs');
var path = require('path'); var path = require('path');
module.exports = read; module.exports = read;
function read(file) { function read(file: string) {
var content = fs.readFileSync(path.join('tools/broccoli/html-replace', file + '.html'), var content = fs.readFileSync(path.join('tools/broccoli/html-replace', file + '.html'),
{encoding: 'utf-8'}); {encoding: 'utf-8'});
// TODO(broccoli): we don't really need this, it's here to make the output match the // TODO(broccoli): we don't really need this, it's here to make the output match the

View File

@ -2,7 +2,7 @@ var fs = require('fs');
var path = require('path'); var path = require('path');
module.exports = readJs; module.exports = readJs;
function readJs(file) { function readJs(file: string) {
var content = var content =
fs.readFileSync(path.join('tools/broccoli/js-replace', file + '.js'), {encoding: 'utf-8'}); fs.readFileSync(path.join('tools/broccoli/js-replace', file + '.js'), {encoding: 'utf-8'});
// TODO(broccoli): we don't really need this, it's here to make the output match the // TODO(broccoli): we don't really need this, it's here to make the output match the

View File

@ -23,9 +23,9 @@ export interface MultiCopyOptions {
* given by glob patterns, . * given by glob patterns, .
*/ */
export class MultiCopy extends Writer { export class MultiCopy extends Writer {
constructor(private inputTree, private options: MultiCopyOptions) { super(); } constructor(private inputTree: BroccoliTree, private options: MultiCopyOptions) { super(); }
write(readTree: (tree) => Promise<string>, destDir: string): Promise<any> { write(readTree: (tree: BroccoliTree) => Promise<string>, destDir: string): Promise<any> {
return readTree(this.inputTree) return readTree(this.inputTree)
.then((inputPath: string) => { .then((inputPath: string) => {
var fileName = path.basename(this.options.srcPath); var fileName = path.basename(this.options.srcPath);

View File

@ -290,7 +290,7 @@ describe('TreeDiffer', () => {
describe('diff of new files', () => { describe('diff of new files', () => {
it('should detect file additions', () => { it('should detect file additions', () => {
let testDir = { let testDir: any = {
'dir1': 'dir1':
{'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})} {'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})}
}; };
@ -310,7 +310,7 @@ describe('TreeDiffer', () => {
it('should detect file additions mixed with file changes', () => { it('should detect file additions mixed with file changes', () => {
let testDir = { let testDir: any = {
'dir1': 'dir1':
{'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})} {'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})}
}; };
@ -352,7 +352,7 @@ describe('TreeDiffer', () => {
it('should detect file removals mixed with file changes and additions', () => { it('should detect file removals mixed with file changes and additions', () => {
let testDir = { let testDir: any = {
'dir1': { 'dir1': {
'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)}), 'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)}),
'file-2.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)}) 'file-2.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})

View File

@ -4,7 +4,7 @@ import fs = require('fs');
import path = require('path'); import path = require('path');
function tryStatSync(path) { function tryStatSync(path: string) {
try { try {
return fs.statSync(path); return fs.statSync(path);
} catch (e) { } catch (e) {
@ -25,12 +25,12 @@ export class TreeDiffer {
excludeExtensions?: string[]) { excludeExtensions?: string[]) {
this.rootDirName = path.basename(rootPath); this.rootDirName = path.basename(rootPath);
let buildRegexp = (arr) => new RegExp(`(${arr.reduce(combine, "")})$`, "i"); let buildRegexp = (arr: string[]) => new RegExp(`(${arr.reduce(combine, "")})$`, "i");
this.include = (includeExtensions || []).length ? buildRegexp(includeExtensions) : null; this.include = (includeExtensions || []).length ? buildRegexp(includeExtensions) : null;
this.exclude = (excludeExtensions || []).length ? buildRegexp(excludeExtensions) : null; this.exclude = (excludeExtensions || []).length ? buildRegexp(excludeExtensions) : null;
function combine(prev, curr) { function combine(prev: string, curr: string) {
if (curr.charAt(0) !== ".") { if (curr.charAt(0) !== ".") {
throw new Error(`Extension must begin with '.'. Was: '${curr}'`); throw new Error(`Extension must begin with '.'. Was: '${curr}'`);
} }
@ -150,7 +150,7 @@ class DirtyCheckingDiffResult extends DiffResult {
`(files: ${pad(this.filesChecked, 5)}, dirs: ${pad(this.directoriesChecked, 4)})`; `(files: ${pad(this.filesChecked, 5)}, dirs: ${pad(this.directoriesChecked, 4)})`;
} }
log(verbose) { log(verbose: boolean) {
let prefixedPaths = this.addedPaths.map(p => `+ ${p}`) let prefixedPaths = this.addedPaths.map(p => `+ ${p}`)
.concat(this.changedPaths.map(p => `* ${p}`)) .concat(this.changedPaths.map(p => `* ${p}`))
.concat(this.removedPaths.map(p => `- ${p}`)); .concat(this.removedPaths.map(p => `- ${p}`));
@ -161,8 +161,8 @@ class DirtyCheckingDiffResult extends DiffResult {
} }
function pad(value, length) { function pad(v: string | number, length: number) {
value = '' + value; let value = '' + v;
let whitespaceLength = (value.length < length) ? length - value.length : 0; let whitespaceLength = (value.length < length) ? length - value.length : 0;
whitespaceLength = whitespaceLength + 1; whitespaceLength = whitespaceLength + 1;
return new Array(whitespaceLength).join(' ') + value; return new Array(whitespaceLength).join(' ') + value;

View File

@ -67,7 +67,8 @@ const kServedPaths = [
]; ];
module.exports = function makeBrowserTree(options, destinationPath) { module.exports = function makeBrowserTree(options: any, destinationPath: string) {
// TODO: define an interface for the options
const modules = options.projects; const modules = options.projects;
const noTypeChecks = options.noTypeChecks; const noTypeChecks = options.noTypeChecks;
const generateEs6 = options.generateEs6; const generateEs6 = options.generateEs6;
@ -136,7 +137,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
var scriptPathPatternReplacement = { var scriptPathPatternReplacement = {
match: '@@PATH', match: '@@PATH',
replacement: function(replacement, relativePath) { replacement: function(replacement: string, relativePath: string) {
var parts = relativePath.replace(/\\/g, '/').split('/'); var parts = relativePath.replace(/\\/g, '/').split('/');
return parts.splice(0, parts.length - 1).join('/'); return parts.splice(0, parts.length - 1).join('/');
} }
@ -144,7 +145,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
var scriptFilePatternReplacement = { var scriptFilePatternReplacement = {
match: '@@FILENAME', match: '@@FILENAME',
replacement: function(replacement, relativePath) { replacement: function(replacement: string, relativePath: string) {
var parts = relativePath.replace(/\\/g, '/').split('/'); var parts = relativePath.replace(/\\/g, '/').split('/');
return parts[parts.length - 1].replace('html', 'js'); return parts[parts.length - 1].replace('html', 'js');
} }
@ -152,7 +153,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
var useBundlesPatternReplacement = { var useBundlesPatternReplacement = {
match: '@@USE_BUNDLES', match: '@@USE_BUNDLES',
replacement: function(replacement, relativePath) { return useBundles; } replacement: function(replacement: string, relativePath: string) { return useBundles; }
}; };
// Check that imports do not break barrel boundaries // Check that imports do not break barrel boundaries
@ -205,7 +206,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
// Get scripts for each benchmark or example // Get scripts for each benchmark or example
let servingTrees = kServedPaths.reduce(getServedFunnels, []); let servingTrees = kServedPaths.reduce(getServedFunnels, []);
function getServedFunnels(funnels, destDir) { function getServedFunnels(funnels: BroccoliTree[], destDir: string) {
let options = {srcDir: '/', destDir: destDir}; let options = {srcDir: '/', destDir: destDir};
funnels.push(new Funnel(vendorScriptsTree, options)); funnels.push(new Funnel(vendorScriptsTree, options));
if (destDir.indexOf('benchmarks') > -1) { if (destDir.indexOf('benchmarks') > -1) {

View File

@ -104,9 +104,9 @@ function getSourceTree(options: AngularBuilderOptions) {
return mergeTrees([compiledTree, generatedDartTestFiles], {overwrite: true}); return mergeTrees([compiledTree, generatedDartTestFiles], {overwrite: true});
} }
function fixDartFolderLayout(sourceTree) { function fixDartFolderLayout(sourceTree: BroccoliTree) {
// Move around files to match Dart's layout expectations. // Move around files to match Dart's layout expectations.
return stew.rename(sourceTree, function(relativePath) { return stew.rename(sourceTree, function(relativePath: string) {
// If a file matches the `pattern`, insert the given `insertion` as the second path part. // If a file matches the `pattern`, insert the given `insertion` as the second path part.
var replacements = [ var replacements = [
{pattern: /^benchmarks\/test\//, insertion: ''}, {pattern: /^benchmarks\/test\//, insertion: ''},
@ -139,7 +139,7 @@ function getHtmlSourcesTree() {
{files: ['*/**'], patterns: [{match: '$SCRIPTS$', replacement: replaceScriptTagInHtml}]}); {files: ['*/**'], patterns: [{match: '$SCRIPTS$', replacement: replaceScriptTagInHtml}]});
// Copy a url_params_to_form.js for each benchmark html file. // Copy a url_params_to_form.js for each benchmark html file.
var urlParamsToFormTree = new MultiCopy('', { var urlParamsToFormTree = new MultiCopy(<any>'', {
srcPath: 'tools/build/snippets/url_params_to_form.js', srcPath: 'tools/build/snippets/url_params_to_form.js',
targetPatterns: ['modules/benchmarks*/src/*', 'modules/benchmarks*/src/*/*'], targetPatterns: ['modules/benchmarks*/src/*', 'modules/benchmarks*/src/*/*'],
}); });
@ -173,7 +173,7 @@ function getTemplatedPubspecsTree() {
function getDocsTree() { function getDocsTree() {
// LICENSE files // LICENSE files
var licenses = new MultiCopy('', { var licenses = new MultiCopy(<any>'', {
srcPath: 'LICENSE', srcPath: 'LICENSE',
targetPatterns: ['modules/*'], targetPatterns: ['modules/*'],
exclude: [ exclude: [
@ -190,7 +190,7 @@ function getDocsTree() {
// Documentation. // Documentation.
// Rename *.dart.md -> *.dart. // Rename *.dart.md -> *.dart.
var mdTree = stew.rename(modulesFunnel(['**/*.dart.md']), var mdTree = stew.rename(modulesFunnel(['**/*.dart.md']),
relativePath => relativePath.replace(/\.dart\.md$/, '.md')); (relativePath: string) => relativePath.replace(/\.dart\.md$/, '.md'));
// Copy all assets, ignore .js. and .dart. (handled above). // Copy all assets, ignore .js. and .dart. (handled above).
var docs = modulesFunnel(['**/*.md', '**/*.png', '**/*.html', '**/*.css', '**/*.scss'], var docs = modulesFunnel(['**/*.md', '**/*.png', '**/*.html', '**/*.css', '**/*.scss'],
['**/*.js.md', '**/*.dart.md', 'angular1_router/**/*']); ['**/*.js.md', '**/*.dart.md', 'angular1_router/**/*']);

View File

@ -14,7 +14,7 @@ var writeFile = require('broccoli-file-creator');
var projectRootDir = path.normalize(path.join(__dirname, '..', '..', '..', '..')); var projectRootDir = path.normalize(path.join(__dirname, '..', '..', '..', '..'));
module.exports = function makeNodeTree(projects, destinationPath) { module.exports = function makeNodeTree(projects: string[], destinationPath: string) {
// list of npm packages that this build will create // list of npm packages that this build will create
var outputPackages = ['angular2', 'benchpress']; var outputPackages = ['angular2', 'benchpress'];
@ -206,7 +206,7 @@ module.exports = function makeNodeTree(projects, destinationPath) {
`var parse5Adapter = require('angular2/src/platform/server/parse5_adapter');\r\n` + `var parse5Adapter = require('angular2/src/platform/server/parse5_adapter');\r\n` +
`parse5Adapter.Parse5DomAdapter.makeCurrent();` `parse5Adapter.Parse5DomAdapter.makeCurrent();`
}, },
{match: /$/, replacement: (_, relativePath) => "\r\n main(); \r\n"} {match: /$/, replacement: (_: any, relativePath: string) => "\r\n main(); \r\n"}
] ]
}); });
@ -218,7 +218,8 @@ module.exports = function makeNodeTree(projects, destinationPath) {
return destCopy(nodeTree, destinationPath); return destCopy(nodeTree, destinationPath);
}; };
function compileTree(tree, genInternalTypings, rootFilePaths: string[] = []) { function compileTree(tree: BroccoliTree, genInternalTypings: boolean,
rootFilePaths: string[] = []) {
return compileWithTypescript(tree, { return compileWithTypescript(tree, {
// build pipeline options // build pipeline options
"rootFilePaths": rootFilePaths, "rootFilePaths": rootFilePaths,
@ -238,12 +239,12 @@ function compileTree(tree, genInternalTypings, rootFilePaths: string[] = []) {
}); });
} }
function extractDocs(tree) { function extractDocs(tree: BroccoliTree) {
var docs = new Funnel(tree, {include: ['**/*.md', '**/*.png'], exclude: ['**/*.dart.md']}); var docs = new Funnel(tree, {include: ['**/*.md', '**/*.png'], exclude: ['**/*.dart.md']});
return stew.rename(docs, 'README.js.md', 'README.md'); return stew.rename(docs, 'README.js.md', 'README.md');
} }
function extractPkgJsons(tree, BASE_PACKAGE_JSON) { function extractPkgJsons(tree: BroccoliTree, BASE_PACKAGE_JSON: any) {
// Generate shared package.json info // Generate shared package.json info
var COMMON_PACKAGE_JSON = { var COMMON_PACKAGE_JSON = {
version: BASE_PACKAGE_JSON.version, version: BASE_PACKAGE_JSON.version,

View File

@ -11,34 +11,34 @@ require('zone.js/dist/fake-async-test.js');
var jrunner = new JasmineRunner(); var jrunner = new JasmineRunner();
var toolsDir = process.cwd() + '/dist/tools'; var toolsDir = process.cwd() + '/dist/tools';
function toolsDirRequire(moduleId) { function toolsDirRequire(moduleId: string) {
return require(path.join(toolsDir, moduleId)); return require(path.join(toolsDir, moduleId));
} }
// Tun on full stack traces in errors to help debugging // Tun on full stack traces in errors to help debugging
Error['stackTraceLimit'] = Infinity; (<any>Error)['stackTraceLimit'] = Infinity;
jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 100; jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 100;
// Support passing multiple globs // Support passing multiple globs
var globsIndex = process.argv.indexOf('--'); var globsIndex = process.argv.indexOf('--');
var args; var args: string[];
if (globsIndex < 0) { if (globsIndex < 0) {
args = [process.argv[2]]; args = [process.argv[2]];
} else { } else {
args = process.argv.slice(globsIndex + 1); args = process.argv.slice(globsIndex + 1);
} }
var specFiles = args.map(function(globstr) { return glob.sync(globstr, {cwd: toolsDir}); }) var specFiles = args.map(function(globstr: string) { return glob.sync(globstr, {cwd: toolsDir}); })
.reduce(function(specFiles, paths) { return specFiles.concat(paths); }, []); .reduce((specFiles:string[], paths: string[]) => specFiles.concat(paths), []);
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100; jasmine.DEFAULT_TIMEOUT_INTERVAL = 100;
jrunner.configureDefaultReporter({showColors: process.argv.indexOf('--no-color') === -1}); jrunner.configureDefaultReporter({showColors: process.argv.indexOf('--no-color') === -1});
jrunner.onComplete(function(passed) { process.exit(passed ? 0 : 1); }); jrunner.onComplete(function(passed: boolean) { process.exit(passed ? 0 : 1); });
jrunner.projectBaseDir = path.resolve(__dirname, '../../'); jrunner.projectBaseDir = path.resolve(__dirname, '../../');
jrunner.specDir = ''; jrunner.specDir = '';
require('zone.js/dist/jasmine-patch.js'); require('zone.js/dist/jasmine-patch.js');
specFiles.forEach((file) => { toolsDirRequire(file); }); specFiles.forEach((file: string) => { toolsDirRequire(file); });
jrunner.execute(); jrunner.execute();

View File

@ -11,29 +11,29 @@ require('zone.js/dist/fake-async-test.js');
require('reflect-metadata/Reflect'); require('reflect-metadata/Reflect');
var jrunner = new JasmineRunner(); var jrunner = new JasmineRunner();
var distAll = process.cwd() + '/dist/all'; var distAll: string = process.cwd() + '/dist/all';
function distAllRequire(moduleId) { function distAllRequire(moduleId: string) {
return require(path.join(distAll, moduleId)); return require(path.join(distAll, moduleId));
} }
// Tun on full stack traces in errors to help debugging // Tun on full stack traces in errors to help debugging
Error['stackTraceLimit'] = Infinity; (<any>Error)['stackTraceLimit'] = Infinity;
jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 100; jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 100;
// Support passing multiple globs // Support passing multiple globs
var globsIndex = process.argv.indexOf('--'); var globsIndex = process.argv.indexOf('--');
var args; var args: string[];
if (globsIndex < 0) { if (globsIndex < 0) {
args = [process.argv[2]]; args = [process.argv[2]];
} else { } else {
args = process.argv.slice(globsIndex + 1); args = process.argv.slice(globsIndex + 1);
} }
var specFiles = var specFiles: any =
args.map(function(globstr) { args.map(function(globstr: string): string[] {
var tests = glob.sync(globstr, { var tests: string[] = glob.sync(globstr, {
cwd: distAll, cwd: distAll,
ignore: [ ignore: [
// the following code and tests are not compatible with CJS/node environment // the following code and tests are not compatible with CJS/node environment
@ -56,19 +56,19 @@ var specFiles =
glob.sync('@angular/platform-browser/test/security/**/*_spec.js', {cwd: distAll})); glob.sync('@angular/platform-browser/test/security/**/*_spec.js', {cwd: distAll}));
return tests; return tests;
}) })
.reduce(function(specFiles, paths) { return specFiles.concat(paths); }, []); .reduce((specFiles: string[], paths: string[]) => specFiles.concat(paths), <string[]>[]);
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100; jasmine.DEFAULT_TIMEOUT_INTERVAL = 100;
jrunner.configureDefaultReporter({showColors: process.argv.indexOf('--no-color') === -1}); jrunner.configureDefaultReporter({showColors: process.argv.indexOf('--no-color') === -1});
jrunner.onComplete(function(passed) { process.exit(passed ? 0 : 1); }); jrunner.onComplete(function(passed: boolean) { process.exit(passed ? 0 : 1); });
jrunner.projectBaseDir = path.resolve(__dirname, '../../'); jrunner.projectBaseDir = path.resolve(__dirname, '../../');
jrunner.specDir = ''; jrunner.specDir = '';
require('./test-cjs-main.js'); require('./test-cjs-main.js');
require('zone.js/dist/jasmine-patch.js'); require('zone.js/dist/jasmine-patch.js');
distAllRequire('@angular/platform-server/src/parse5_adapter.js').Parse5DomAdapter.makeCurrent(); distAllRequire('@angular/platform-server/src/parse5_adapter.js').Parse5DomAdapter.makeCurrent();
specFiles.forEach((file) => { specFiles.forEach((file: string) => {
var r = distAllRequire(file); var r = distAllRequire(file);
if (r.main) r.main(); if (r.main) r.main();
}); });

View File

@ -33,7 +33,7 @@ export class MetadataCollector {
break; break;
} }
if (importDecl.importClause.name) { if (importDecl.importClause.name) {
newImport['defaultName'] = importDecl.importClause.name.text; (<any>newImport)['defaultName'] = importDecl.importClause.name.text;
} }
const bindings = importDecl.importClause.namedBindings; const bindings = importDecl.importClause.namedBindings;
if (bindings) { if (bindings) {
@ -44,14 +44,14 @@ export class MetadataCollector {
.elements.forEach(i => { .elements.forEach(i => {
const namedImport = {name: i.name.text}; const namedImport = {name: i.name.text};
if (i.propertyName) { if (i.propertyName) {
namedImport['propertyName'] = i.propertyName.text; (<any>namedImport)['propertyName'] = i.propertyName.text;
} }
namedImports.push(namedImport); namedImports.push(namedImport);
}); });
newImport['namedImports'] = namedImports; (<any>newImport)['namedImports'] = namedImports;
break; break;
case ts.SyntaxKind.NamespaceImport: case ts.SyntaxKind.NamespaceImport:
newImport['namespace'] = (<ts.NamespaceImport>bindings).name.text; (<any>newImport)['namespace'] = (<ts.NamespaceImport>bindings).name.text;
break; break;
} }
} }

View File

@ -257,14 +257,14 @@ export class Evaluator {
const assignment = <ts.PropertyAssignment>child; const assignment = <ts.PropertyAssignment>child;
const propertyName = this.nameOf(assignment.name); const propertyName = this.nameOf(assignment.name);
const propertyValue = this.evaluateNode(assignment.initializer); const propertyValue = this.evaluateNode(assignment.initializer);
obj[propertyName] = propertyValue; (<any>obj)[propertyName] = propertyValue;
allPropertiesDefined = isDefined(propertyValue) && allPropertiesDefined; allPropertiesDefined = isDefined(propertyValue) && allPropertiesDefined;
} }
}); });
if (allPropertiesDefined) return obj; if (allPropertiesDefined) return obj;
break; break;
case ts.SyntaxKind.ArrayLiteralExpression: case ts.SyntaxKind.ArrayLiteralExpression:
let arr = []; let arr: MetadataValue[] = [];
let allElementsDefined = true; let allElementsDefined = true;
ts.forEachChild(node, child => { ts.forEachChild(node, child => {
const value = this.evaluateNode(child); const value = this.evaluateNode(child);
@ -320,7 +320,7 @@ export class Evaluator {
const propertyAccessExpression = <ts.PropertyAccessExpression>node; const propertyAccessExpression = <ts.PropertyAccessExpression>node;
const expression = this.evaluateNode(propertyAccessExpression.expression); const expression = this.evaluateNode(propertyAccessExpression.expression);
const member = this.nameOf(propertyAccessExpression.name); const member = this.nameOf(propertyAccessExpression.name);
if (this.isFoldable(propertyAccessExpression.expression)) return expression[member]; if (this.isFoldable(propertyAccessExpression.expression)) return (<any>expression)[member];
if (this.findImportNamespace(propertyAccessExpression)) { if (this.findImportNamespace(propertyAccessExpression)) {
return this.nodeSymbolReference(propertyAccessExpression); return this.nodeSymbolReference(propertyAccessExpression);
} }
@ -335,7 +335,7 @@ export class Evaluator {
const index = this.evaluateNode(elementAccessExpression.argumentExpression); const index = this.evaluateNode(elementAccessExpression.argumentExpression);
if (this.isFoldable(elementAccessExpression.expression) && if (this.isFoldable(elementAccessExpression.expression) &&
this.isFoldable(elementAccessExpression.argumentExpression)) this.isFoldable(elementAccessExpression.argumentExpression))
return expression[<string | number>index]; return (<any>expression)[<string | number>index];
if (isDefined(expression) && isDefined(index)) { if (isDefined(expression) && isDefined(index)) {
return {__symbolic: "index", expression, index}; return {__symbolic: "index", expression, index};
} }

View File

@ -26,7 +26,7 @@ export class Symbols {
public has(symbol: ts.Symbol): boolean { return this.map.has(symbol.getDeclarations()[0]); } public has(symbol: ts.Symbol): boolean { return this.map.has(symbol.getDeclarations()[0]); }
public set(symbol: ts.Symbol, value): void { this.map.set(symbol.getDeclarations()[0], value); } public set(symbol: ts.Symbol, value: any): void { this.map.set(symbol.getDeclarations()[0], value); }
public get(symbol: ts.Symbol): any { return this.map.get(symbol.getDeclarations()[0]); } public get(symbol: ts.Symbol): any { return this.map.get(symbol.getDeclarations()[0]); }

View File

@ -1,6 +1,6 @@
import * as ts from 'typescript'; import * as ts from 'typescript';
import {MetadataCollector} from '../src/collector'; import {MetadataCollector} from '../src/collector';
import {ClassMetadata} from '../src/schema'; import {ClassMetadata, ModuleMetadata} from '../src/schema';
import {Directory, expectValidSources, Host} from './typescript.mocks'; import {Directory, expectValidSources, Host} from './typescript.mocks';
@ -185,8 +185,8 @@ describe('Collector', () => {
expect(metadata).toBeFalsy(); expect(metadata).toBeFalsy();
}); });
let casesFile; let casesFile: ts.SourceFile;
let casesMetadata; let casesMetadata: ModuleMetadata;
beforeEach(() => { beforeEach(() => {
casesFile = program.getSourceFile('/app/cases-data.ts'); casesFile = program.getSourceFile('/app/cases-data.ts');

View File

@ -37,7 +37,7 @@ export class Host implements ts.LanguageServiceHost {
if (names.length && names[0] === '') names.shift(); if (names.length && names[0] === '') names.shift();
for (const name of names) { for (const name of names) {
if (!current || typeof current === 'string') return undefined; if (!current || typeof current === 'string') return undefined;
current = current[name]; current = (<any>current)[name];
} }
if (typeof current === 'string') return current; if (typeof current === 'string') return current;
} }
@ -120,7 +120,7 @@ export function expectValidSources(service: ts.LanguageService, program: ts.Prog
} }
} }
export function allChildren<T>(node: ts.Node, cb: (node: ts.Node) => T) { export function allChildren<T>(node: ts.Node, cb: (node: ts.Node) => T): T {
return ts.forEachChild(node, child => { return ts.forEachChild(node, child => {
const result = cb(node); const result = cb(node);
if (result) { if (result) {

View File

@ -14,7 +14,7 @@ const OFFLINE_COMPILE = [
function processOutputEmitterCodeGen(): Promise<number> { function processOutputEmitterCodeGen(): Promise<number> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var outDir = 'dist/all/@angular/compiler/test/'; var outDir = 'dist/all/@angular/compiler/test/';
var promises = []; var promises: Promise<any>[] = [];
console.log('Processing codegen...'); console.log('Processing codegen...');
OFFLINE_COMPILE.forEach((file: string) => { OFFLINE_COMPILE.forEach((file: string) => {
var codegen = require('../../all/@angular/compiler/test/' + file + '.js'); var codegen = require('../../all/@angular/compiler/test/' + file + '.js');
@ -31,10 +31,10 @@ function processOutputEmitterCodeGen(): Promise<number> {
['--project', 'tools/cjs-jasmine/tsconfig-output_emitter_codegen.json']; ['--project', 'tools/cjs-jasmine/tsconfig-output_emitter_codegen.json'];
console.log(' compiling changes: tsc ' + args.join(' ')); console.log(' compiling changes: tsc ' + args.join(' '));
var tsc = spawn(TSC, args, {stdio: 'pipe'}); var tsc = spawn(TSC, args, {stdio: 'pipe'});
tsc.stdout.on('data', (data) => process.stdout.write(data)); tsc.stdout.on('data', (data: any) => process.stdout.write(data));
tsc.stderr.on('data', (data) => process.stderr.write(data)); tsc.stderr.on('data', (data: any) => process.stderr.write(data));
tsc.on('close', tsc.on('close',
(code) => code ? reject('Tsc exited with: ' + code) : resolve(code)); (code: any) => code ? reject('Tsc exited with: ' + code) : resolve(code));
}) })
.catch(reportError); .catch(reportError);
} else { } else {

View File

@ -8,7 +8,7 @@ enum State {
} }
export const TSC = 'node_modules/typescript/bin/tsc'; export const TSC = 'node_modules/typescript/bin/tsc';
export type Command = (stdIn, stdErr) => Promise<number>; export type Command = (stdIn: any, stdErr: any) => Promise<number>;
export class TscWatch { export class TscWatch {
private tsconfig: string; private tsconfig: string;
@ -47,11 +47,12 @@ export class TscWatch {
tsc.then(() => this.triggerCmds(), code => process.exit(code)); tsc.then(() => this.triggerCmds(), code => process.exit(code));
} }
this.state = State.waiting; this.state = State.waiting;
this.onStartCmds.forEach((cmd) => this.runCmd(cmd, () => null, () => null)); this.onStartCmds.forEach((cmd) => this.runCmd(cmd, null, () => null, () => null));
} }
private runCmd(argsOrCmd: string[] | Command, env?, stdOut = pipeStdOut, private runCmd(argsOrCmd: string[] | Command, env?: {[k: string]: string},
stdErr = pipeStdErr): Promise<number> { stdOut = pipeStdOut, stdErr = pipeStdErr): Promise<number>
{
if (typeof argsOrCmd == 'function') { if (typeof argsOrCmd == 'function') {
return (argsOrCmd as Command)(stdErr, stdOut); return (argsOrCmd as Command)(stdErr, stdOut);
} else if (argsOrCmd instanceof Array) { } else if (argsOrCmd instanceof Array) {
@ -153,7 +154,7 @@ function contains(line: string, text: string | RegExp): boolean {
} }
} }
export function reportError(e) { export function reportError(e: any) {
if (e.message && e.stack) { if (e.message && e.stack) {
console.error(e.message); console.error(e.message);
console.error(e.stack); console.error(e.stack);
@ -164,9 +165,9 @@ export function reportError(e) {
return Promise.reject(e); return Promise.reject(e);
} }
function pipeStdOut(d) { function pipeStdOut(d: any) {
process.stdout.write(d); process.stdout.write(d);
} }
function pipeStdErr(d) { function pipeStdErr(d: any) {
process.stderr.write(d); process.stderr.write(d);
} }

View File

@ -7,6 +7,7 @@
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"outDir": "../dist/tools/", "outDir": "../dist/tools/",
"noImplicitAny": true,
"paths": { "paths": {
}, },
"rootDir": ".", "rootDir": ".",