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',
module: 'commonjs',
declaration: true,
noImplicitAny: true,
// Don't use the version of typescript that gulp-typescript depends on
// see https://github.com/ivogabe/gulp-typescript#typescript-version
typescript: require('typescript')

View File

@ -122,8 +122,8 @@ export class AngularBuilder {
}
private rebuild(builder, name) {
return builder.build().then(
private rebuild(builder: BroccoliBuilder, name: string): Promise<BuildResult> {
return builder.build().then<BuildResult>(
(result) => {
if (!this.firstResult) {
this.firstResult = result;
@ -131,8 +131,9 @@ export class AngularBuilder {
printSlowTrees(result.graph);
writeBuildLog(result, name);
return result;
},
(error) => {
(error): any => {
// 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
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;
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.outputPath, broccoliNode.selfTime / (1000 * 1000 * 1000),
broccoliNode.totalTime / (1000 * 1000 * 1000),
@ -169,5 +170,5 @@ function broccoliNodeToBuildNode(broccoliNode) {
class BuildNode {
constructor(public pluginName: string, public inputPaths: string[], public cachePath: string,
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_PATH_REGEXP = new RegExp(`['"]([^'"]+)+['"]`, "m");
static ALLOWED_IMPORTS = {
static ALLOWED_IMPORTS: {[s: string]: string[]} = {
"angular2/src/core": ["angular2/src/facade"],
"angular2/src/facade": ["rxjs"],
"angular2/src/common": ["angular2/core", "angular2/src/facade"],
@ -28,7 +28,7 @@ class CheckImports implements DiffingBroccoliPlugin {
private initRun = true;
constructor(private inputPath, private cachePath, private options) {}
constructor(private inputPath: string, private cachePath: string, private options: number) {}
rebuild(treeDiff: DiffResult) {
const errors = this.checkAllPaths(treeDiff);

View File

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

View File

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

View File

@ -2,6 +2,8 @@ import fs = require('fs');
import fse = require('fs-extra');
import path = require('path');
import {wrapDiffingPlugin, DiffingBroccoliPlugin, DiffResult} from './diffing-broccoli-plugin';
import {AngularBuilderOptions} from './angular_builder';
var symlinkOrCopy = require('symlink-or-copy').sync;
var isWindows = process.platform === 'win32';
@ -12,7 +14,8 @@ var isWindows = process.platform === 'win32';
* the associated changes.
*/
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) {

View File

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

View File

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

View File

@ -3,23 +3,22 @@
let mockfs = require('mock-fs');
import fs = require('fs');
import {TreeDiffer} from './tree-differ';
import {TreeDiffer, DiffResult} from './tree-differ';
import {MergeTrees} from './broccoli-merge-trees';
describe('MergeTrees', () => {
afterEach(() => mockfs.restore());
function mergeTrees(inputPaths, cachePath, options) {
function mergeTrees(inputPaths: string[], cachePath: string, options: {}) {
return new MergeTrees(inputPaths, cachePath, options);
}
function MakeTreeDiffers(rootDirs) {
let treeDiffers = rootDirs.map((rootDir) => new TreeDiffer('MergeTrees', rootDir));
treeDiffers.diffTrees = () => { return treeDiffers.map(tree => tree.diffTree()); };
return treeDiffers;
function MakeTreeDiffers(rootDirs: string[]): TreeDiffer[] {
return rootDirs.map((rootDir) => new TreeDiffer('MergeTrees', rootDir));
}
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', () => {
let testDir: any = {
@ -30,18 +29,18 @@ describe('MergeTrees', () => {
mockfs(testDir);
let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']);
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');
delete testDir.tree2['foo.js'];
delete testDir.tree3['foo.js'];
mockfs(testDir);
treeMerger.rebuild(treeDiffer.diffTrees());
treeMerger.rebuild(diffTrees(treeDiffer));
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)});
mockfs(testDir);
treeMerger.rebuild(treeDiffer.diffTrees());
treeMerger.rebuild(diffTrees(treeDiffer));
expect(read('dest/foo.js')).toBe('tree2/foo.js content');
});
@ -54,7 +53,7 @@ describe('MergeTrees', () => {
mockfs(testDir);
let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']);
let treeMerger = mergeTrees(['tree1', 'tree2', 'tree3'], 'dest', {});
expect(() => treeMerger.rebuild(treeDiffer.diffTrees()))
expect(() => treeMerger.rebuild(diffTrees(treeDiffer)))
.toThrowError(
'Duplicate path found while merging trees. Path: "foo.js".\n' +
'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', () => {
let testDir = {
let testDir: any = {
'tree1': {'foo.js': mockfs.file({content: 'tree1/foo.js content', mtime: new Date(1000)})},
'tree2': {},
'tree3': {}
@ -78,12 +77,12 @@ describe('MergeTrees', () => {
let treeDiffer = MakeTreeDiffers(['tree1', 'tree2', 'tree3']);
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)});
mockfs(testDir);
expect(() => treeMerger.rebuild(treeDiffer.diffTrees()))
expect(() => treeMerger.rebuild(diffTrees(treeDiffer)))
.toThrowError(
'Duplicate path found while merging trees. Path: "foo.js".\n' +
'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; }
function outputFileSync(sourcePath, destPath) {
function outputFileSync(sourcePath: string, destPath: string) {
let dirname = path.dirname(destPath);
fse.mkdirsSync(dirname, {fs: fs});
symlinkOrCopySync(sourcePath, destPath);
}
function pathOverwrittenError(path) {
function pathOverwrittenError(path: string) {
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}`);
}
@ -34,14 +34,14 @@ export class MergeTrees implements DiffingBroccoliPlugin {
let pathsToEmit: string[] = [];
let pathsToRemove: string[] = [];
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) {
if (cache[i] === val) return true;
}
return false;
};
let emit = (relativePath) => {
let emit = (relativePath: string) => {
// ASSERT(!emitted[relativePath]);
pathsToEmit.push(relativePath);
emitted[relativePath] = true;
@ -51,7 +51,7 @@ export class MergeTrees implements DiffingBroccoliPlugin {
this.firstBuild = false;
// Build initial cache
treeDiffs.reverse().forEach((treeDiff: DiffResult, index) => {
treeDiffs.reverse().forEach((treeDiff: DiffResult, index: number) => {
index = treeDiffs.length - 1 - index;
treeDiff.addedPaths.forEach((changedPath) => {
let cache = this.pathCache[changedPath];
@ -69,7 +69,7 @@ export class MergeTrees implements DiffingBroccoliPlugin {
} else {
// Update cache
treeDiffs.reverse().forEach((treeDiff: DiffResult, index) => {
treeDiffs.reverse().forEach((treeDiff: DiffResult, index: number) => {
index = treeDiffs.length - 1 - index;
if (treeDiff.removedPaths) {
treeDiff.removedPaths.forEach((removedPath) => {

View File

@ -11,7 +11,8 @@ var FILE_ENCODING = {encoding: 'utf-8'};
* the associated changes.
*/
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) {
var patterns = this.options.patterns;
@ -27,13 +28,13 @@ class DiffingReplace implements DiffingBroccoliPlugin {
fse.mkdirpSync(destDirPath);
}
var fileMatches = files.some((filePath) => minimatch(changedFilePath, filePath));
var fileMatches = files.some((filePath: string) => minimatch(changedFilePath, filePath));
if (fileMatches) {
var content = fs.readFileSync(sourceFilePath, FILE_ENCODING);
patterns.forEach((pattern) => {
patterns.forEach((pattern: any) => {
var replacement = pattern.replacement;
if (typeof replacement === 'function') {
replacement = function(content) {
replacement = function(content: string) {
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);
}

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@ var fs = require('fs');
var path = require('path');
module.exports = read;
function read(file) {
function read(file: string) {
var content = fs.readFileSync(path.join('tools/broccoli/html-replace', file + '.html'),
{encoding: 'utf-8'});
// 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');
module.exports = readJs;
function readJs(file) {
function readJs(file: string) {
var content =
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

View File

@ -23,9 +23,9 @@ export interface MultiCopyOptions {
* given by glob patterns, .
*/
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)
.then((inputPath: string) => {
var fileName = path.basename(this.options.srcPath);

View File

@ -290,7 +290,7 @@ describe('TreeDiffer', () => {
describe('diff of new files', () => {
it('should detect file additions', () => {
let testDir = {
let testDir: any = {
'dir1':
{'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', () => {
let testDir = {
let testDir: any = {
'dir1':
{'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', () => {
let testDir = {
let testDir: any = {
'dir1': {
'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)})

View File

@ -4,7 +4,7 @@ import fs = require('fs');
import path = require('path');
function tryStatSync(path) {
function tryStatSync(path: string) {
try {
return fs.statSync(path);
} catch (e) {
@ -25,12 +25,12 @@ export class TreeDiffer {
excludeExtensions?: string[]) {
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.exclude = (excludeExtensions || []).length ? buildRegexp(excludeExtensions) : null;
function combine(prev, curr) {
function combine(prev: string, curr: string) {
if (curr.charAt(0) !== ".") {
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)})`;
}
log(verbose) {
log(verbose: boolean) {
let prefixedPaths = this.addedPaths.map(p => `+ ${p}`)
.concat(this.changedPaths.map(p => `* ${p}`))
.concat(this.removedPaths.map(p => `- ${p}`));
@ -161,8 +161,8 @@ class DirtyCheckingDiffResult extends DiffResult {
}
function pad(value, length) {
value = '' + value;
function pad(v: string | number, length: number) {
let value = '' + v;
let whitespaceLength = (value.length < length) ? length - value.length : 0;
whitespaceLength = whitespaceLength + 1;
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 noTypeChecks = options.noTypeChecks;
const generateEs6 = options.generateEs6;
@ -136,7 +137,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
var scriptPathPatternReplacement = {
match: '@@PATH',
replacement: function(replacement, relativePath) {
replacement: function(replacement: string, relativePath: string) {
var parts = relativePath.replace(/\\/g, '/').split('/');
return parts.splice(0, parts.length - 1).join('/');
}
@ -144,7 +145,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
var scriptFilePatternReplacement = {
match: '@@FILENAME',
replacement: function(replacement, relativePath) {
replacement: function(replacement: string, relativePath: string) {
var parts = relativePath.replace(/\\/g, '/').split('/');
return parts[parts.length - 1].replace('html', 'js');
}
@ -152,7 +153,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
var useBundlesPatternReplacement = {
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
@ -205,7 +206,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
// Get scripts for each benchmark or example
let servingTrees = kServedPaths.reduce(getServedFunnels, []);
function getServedFunnels(funnels, destDir) {
function getServedFunnels(funnels: BroccoliTree[], destDir: string) {
let options = {srcDir: '/', destDir: destDir};
funnels.push(new Funnel(vendorScriptsTree, options));
if (destDir.indexOf('benchmarks') > -1) {

View File

@ -104,9 +104,9 @@ function getSourceTree(options: AngularBuilderOptions) {
return mergeTrees([compiledTree, generatedDartTestFiles], {overwrite: true});
}
function fixDartFolderLayout(sourceTree) {
function fixDartFolderLayout(sourceTree: BroccoliTree) {
// 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.
var replacements = [
{pattern: /^benchmarks\/test\//, insertion: ''},
@ -139,7 +139,7 @@ function getHtmlSourcesTree() {
{files: ['*/**'], patterns: [{match: '$SCRIPTS$', replacement: replaceScriptTagInHtml}]});
// 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',
targetPatterns: ['modules/benchmarks*/src/*', 'modules/benchmarks*/src/*/*'],
});
@ -173,7 +173,7 @@ function getTemplatedPubspecsTree() {
function getDocsTree() {
// LICENSE files
var licenses = new MultiCopy('', {
var licenses = new MultiCopy(<any>'', {
srcPath: 'LICENSE',
targetPatterns: ['modules/*'],
exclude: [
@ -190,7 +190,7 @@ function getDocsTree() {
// Documentation.
// Rename *.dart.md -> *.dart.
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).
var docs = modulesFunnel(['**/*.md', '**/*.png', '**/*.html', '**/*.css', '**/*.scss'],
['**/*.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, '..', '..', '..', '..'));
module.exports = function makeNodeTree(projects, destinationPath) {
module.exports = function makeNodeTree(projects: string[], destinationPath: string) {
// list of npm packages that this build will create
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` +
`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);
};
function compileTree(tree, genInternalTypings, rootFilePaths: string[] = []) {
function compileTree(tree: BroccoliTree, genInternalTypings: boolean,
rootFilePaths: string[] = []) {
return compileWithTypescript(tree, {
// build pipeline options
"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']});
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
var COMMON_PACKAGE_JSON = {
version: BASE_PACKAGE_JSON.version,

View File

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

View File

@ -11,29 +11,29 @@ require('zone.js/dist/fake-async-test.js');
require('reflect-metadata/Reflect');
var jrunner = new JasmineRunner();
var distAll = process.cwd() + '/dist/all';
function distAllRequire(moduleId) {
var distAll: string = process.cwd() + '/dist/all';
function distAllRequire(moduleId: string) {
return require(path.join(distAll, moduleId));
}
// Tun on full stack traces in errors to help debugging
Error['stackTraceLimit'] = Infinity;
(<any>Error)['stackTraceLimit'] = Infinity;
jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 100;
// Support passing multiple globs
var globsIndex = process.argv.indexOf('--');
var args;
var args: string[];
if (globsIndex < 0) {
args = [process.argv[2]];
} else {
args = process.argv.slice(globsIndex + 1);
}
var specFiles =
args.map(function(globstr) {
var tests = glob.sync(globstr, {
var specFiles: any =
args.map(function(globstr: string): string[] {
var tests: string[] = glob.sync(globstr, {
cwd: distAll,
ignore: [
// 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}));
return tests;
})
.reduce(function(specFiles, paths) { return specFiles.concat(paths); }, []);
.reduce((specFiles: string[], paths: string[]) => specFiles.concat(paths), <string[]>[]);
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100;
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.specDir = '';
require('./test-cjs-main.js');
require('zone.js/dist/jasmine-patch.js');
distAllRequire('@angular/platform-server/src/parse5_adapter.js').Parse5DomAdapter.makeCurrent();
specFiles.forEach((file) => {
specFiles.forEach((file: string) => {
var r = distAllRequire(file);
if (r.main) r.main();
});

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import * as ts from 'typescript';
import {MetadataCollector} from '../src/collector';
import {ClassMetadata} from '../src/schema';
import {ClassMetadata, ModuleMetadata} from '../src/schema';
import {Directory, expectValidSources, Host} from './typescript.mocks';
@ -185,8 +185,8 @@ describe('Collector', () => {
expect(metadata).toBeFalsy();
});
let casesFile;
let casesMetadata;
let casesFile: ts.SourceFile;
let casesMetadata: ModuleMetadata;
beforeEach(() => {
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();
for (const name of names) {
if (!current || typeof current === 'string') return undefined;
current = current[name];
current = (<any>current)[name];
}
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 => {
const result = cb(node);
if (result) {

View File

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

View File

@ -8,7 +8,7 @@ enum State {
}
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 {
private tsconfig: string;
@ -47,11 +47,12 @@ export class TscWatch {
tsc.then(() => this.triggerCmds(), code => process.exit(code));
}
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,
stdErr = pipeStdErr): Promise<number> {
private runCmd(argsOrCmd: string[] | Command, env?: {[k: string]: string},
stdOut = pipeStdOut, stdErr = pipeStdErr): Promise<number>
{
if (typeof argsOrCmd == 'function') {
return (argsOrCmd as Command)(stdErr, stdOut);
} 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) {
console.error(e.message);
console.error(e.stack);
@ -164,9 +165,9 @@ export function reportError(e) {
return Promise.reject(e);
}
function pipeStdOut(d) {
function pipeStdOut(d: any) {
process.stdout.write(d);
}
function pipeStdErr(d) {
function pipeStdErr(d: any) {
process.stderr.write(d);
}

View File

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