chore(ts): duplicate the .es6 files in the facade directory to TypeScript.

Adds a gulp task which builds the .ts files (in the cjs build only).
The new files have extension .ts since they are now valid typescript.
Unfortunately until Typescript can emit System.require, we have to keep the old .es6 version
so traceur works inside the Karma preprocessor. This should be fixed soon.
This commit is contained in:
Alex Eagle 2015-04-01 10:45:56 -07:00
parent abea92af59
commit 894a0f0ee5
10 changed files with 669 additions and 7 deletions

View File

@ -1,3 +1,4 @@
var format = require('gulp-clang-format');
var gulp = require('gulp');
var gulpPlugins = require('gulp-load-plugins')();
var shell = require('gulp-shell');
@ -7,7 +8,6 @@ var merge = require('merge');
var path = require('path');
var gulpTraceur = require('./tools/transpiler/gulp-traceur');
var clean = require('./tools/build/clean');
var transpile = require('./tools/build/transpile');
var html = require('./tools/build/html');
@ -143,7 +143,8 @@ var CONFIG = {
}),
cjs: merge(true, _COMPILER_CONFIG_JS_DEFAULT, {
typeAssertionModule: 'rtts_assert/rtts_assert',
typeAssertions: true,
// Don't use type assertions since this is partly transpiled by typescript
typeAssertions: false,
modules: 'commonjs'
})
},
@ -296,6 +297,26 @@ gulp.task('build/clean.docs', clean(gulp, gulpPlugins, {
// ------------
// transpile
gulp.task('build/transpile.ts.cjs', function() {
var tsResult = gulp.src(CONFIG.transpile.src.ts)
.pipe(sourcemaps.init())
.pipe(tsc({
target: 'ES5',
module: /*system.js*/'commonjs',
allowNonTsExtensions: false,
typescript: require('typescript'),
//declarationFiles: true,
noEmitOnError: true
}));
var dest = gulp.dest(CONFIG.dest.js.cjs);
return merge([
// Write external sourcemap next to the js file
tsResult.js.pipe(sourcemaps.write('.')).pipe(dest),
tsResult.js.pipe(dest),
tsResult.dts.pipe(dest),
]);
});
gulp.task('build/transpile.js.dev.es6', transpile(gulp, gulpPlugins, {
src: CONFIG.transpile.src.js,
dest: CONFIG.dest.js.dev.es6,
@ -314,8 +335,7 @@ gulp.task('build/transpile.ts.dev.es5', function() {
module: 'commonjs',
typescript: require('typescript'),
noEmitOnError: true
}))
.js;
}));
return merge([
tsResult.js.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(CONFIG.dest.js.dev.es5)),
@ -524,7 +544,7 @@ gulp.task('build/pubbuild.dart', pubbuild(gulp, gulpPlugins, {
}));
// ------------
// format dart
// formatting
gulp.task('build/format.dart', rundartpackage(gulp, gulpPlugins, {
pub: DART_SDK.PUB,
@ -532,6 +552,11 @@ gulp.task('build/format.dart', rundartpackage(gulp, gulpPlugins, {
args: CONFIG.formatDart.args
}));
gulp.task('check-format', function() {
return gulp.src(['modules/**/*.ts', '!**/typings/**/*.d.ts'])
.pipe(format.checkFormat('file'));
});
// ------------
// check circular dependencies in Node.js context
gulp.task('build/checkCircularDependencies', function (done) {
@ -786,6 +811,9 @@ gulp.task('build.js.prod', function(done) {
gulp.task('build.js.cjs', function(done) {
runSequence(
['build/transpile.js.cjs', 'build/copy.js.cjs', 'build/multicopy.js.cjs'],
// Overwrite the .js.cjs transpilation with typescript outputs
// We still need traceur outputs everywhere else, for now.
'build/transpile.ts.cjs',
['build/linknodemodules.js.cjs'],
'build/transformCJSTests',
done

View File

@ -0,0 +1,23 @@
/**
* This file contains declarations of global symbols we reference in our code
*/
declare var assert: any;
declare var global: Window;
type int = number;
interface List<T> extends Array<T> {}
interface Window {
Object: typeof Object;
Array: typeof Array;
Map: typeof Map;
Set: typeof Set;
Date: typeof Date;
RegExp: typeof RegExp;
JSON: typeof JSON;
Math: typeof Math;
assert: typeof assert;
NaN: typeof NaN;
gc(): void;
}

View File

@ -76,7 +76,7 @@ export class CompileElement {
this.ignoreBindings = false;
this.contentTagSelector = null;
// description is calculated here as compilation steps may change the element
var tplDesc = assertionsEnabled()? getElementDescription(element) : null;
var tplDesc = getElementDescription(element);
if (compilationUnit !== '') {
this.elementDescription = compilationUnit;
if (isPresent(tplDesc)) this.elementDescription += ": " + tplDesc;

View File

@ -0,0 +1,83 @@
/// <reference path="../../typings/es6-promise/es6-promise.d.ts" />
/// <reference path="../../typings/rx/rx.all.d.ts" />
// HACK: workaround for Traceur behavior.
// It expects all transpiled modules to contain this marker.
// TODO: remove this when we no longer use traceur
export var __esModule = true;
import {int, global, isPresent} from 'angular2/src/facade/lang';
import {List} from 'angular2/src/facade/collection';
import * as Rx from 'rx';
export class PromiseWrapper {
static resolve(obj): Promise<any> { return Promise.resolve(obj); }
static reject(obj): Promise<any> { return Promise.reject(obj); }
// Note: We can't rename this method into `catch`, as this is not a valid
// method name in Dart.
static catchError<T>(promise: Promise<T>, onError: (error: any) => T | Thenable<T>): Promise<T> {
return promise.catch(onError);
}
static all(promises: List<Promise<any>>): Promise<any> {
if (promises.length == 0) return Promise.resolve([]);
return Promise.all(promises);
}
static then<T>(promise: Promise<T>, success: (value: any) => T | Thenable<T>,
rejection: (error: any) => T | Thenable<T>): Promise<T> {
return promise.then(success, rejection);
}
static completer() {
var resolve;
var reject;
var p = new Promise(function(res, rej) {
resolve = res;
reject = rej;
});
return {promise: p, resolve: resolve, reject: reject};
}
static setTimeout(fn: Function, millis: int) { global.setTimeout(fn, millis); }
static isPromise(maybePromise): boolean { return maybePromise instanceof Promise; }
}
/**
* Use Rx.Observable but provides an adapter to make it work as specified here:
* https://github.com/jhusain/observable-spec
*
* Once a reference implementation of the spec is available, switch to it.
*/
type Observable = Rx.Observable<any>;
type ObservableController = Rx.Subject<any>;
export class ObservableWrapper {
static createController(): Rx.Subject<any> { return new Rx.Subject(); }
static createObservable<T>(subject: Rx.Subject<T>): Rx.Observable<T> { return subject; }
static subscribe(observable: Rx.Observable<any>, generatorOrOnNext, onThrow = null,
onReturn = null) {
if (isPresent(generatorOrOnNext.next)) {
return observable.observeOn(Rx.Scheduler.timeout)
.subscribe((value) => generatorOrOnNext.next(value),
(error) => generatorOrOnNext.throw(error), () => generatorOrOnNext.return ());
} else {
return observable.observeOn(Rx.Scheduler.timeout)
.subscribe(generatorOrOnNext, onThrow, onReturn);
}
}
static callNext(subject: Rx.Subject<any>, value: any) { subject.onNext(value); }
static callThrow(subject: Rx.Subject<any>, error: any) { subject.onError(error); }
static callReturn(subject: Rx.Subject<any>) { subject.onCompleted(); }
}

View File

@ -0,0 +1,14 @@
/**
* JS version of browser APIs. This library can only run in the browser.
*/
// HACK: workaround for Traceur behavior.
// It expects all transpiled modules to contain this marker.
// TODO: remove this when we no longer use traceur
export var __esModule = true;
var win = window;
export {win as window};
export var document = window.document;
export var location = window.location;
export var gc = window.gc ? () => window.gc() : () => null;

View File

@ -0,0 +1,198 @@
import {int, isJsObject, global} from 'angular2/src/facade/lang';
// HACK: workaround for Traceur behavior.
// It expects all transpiled modules to contain this marker.
// TODO: remove this when we no longer use traceur
export var __esModule = true;
export var List = global.Array;
export var Map = global.Map;
export var Set = global.Set;
export var StringMap = global.Object;
export class MapWrapper {
static create(): Map<any, any> { return new Map(); }
static clone<K, V>(m: Map<K, V>): Map<K, V> { return new Map(m); }
static createFromStringMap(stringMap): Map<string, any> {
var result = MapWrapper.create();
for (var prop in stringMap) {
MapWrapper.set(result, prop, stringMap[prop]);
}
return result;
}
static createFromPairs(pairs: List<any>): Map<any, any> { return new Map(pairs); }
static get(m, k) { return m.get(k); }
static set(m, k, v) { m.set(k, v); }
static contains(m, k) { return m.has(k); }
static forEach(m, fn) { m.forEach(fn); }
static size(m) { return m.size; }
static delete (m, k) { m.delete(k); }
static clear(m) { m.clear(); }
static clearValues(m) {
var keyIterator = m.keys();
var k;
while (!((k = keyIterator.next()).done)) {
m.set(k.value, null);
}
}
static iterable(m) { return m; }
static keys(m) { return m.keys(); }
static values(m) { return m.values(); }
}
/**
* Wraps Javascript Objects
*/
export class StringMapWrapper {
static create(): Object {
// Note: We are not using Object.create(null) here due to
// performance!
// http://jsperf.com/ng2-object-create-null
return {};
}
static contains(map, key) { return map.hasOwnProperty(key); }
static get(map, key) { return map.hasOwnProperty(key) ? map[key] : undefined; }
static set(map, key, value) { map[key] = value; }
static isEmpty(map) {
for (var prop in map) {
return false;
}
return true;
}
static delete (map, key) { delete map[key]; }
static forEach(map, callback) {
for (var prop in map) {
if (map.hasOwnProperty(prop)) {
callback(map[prop], prop);
}
}
}
static merge(m1, m2) {
var m = {};
for (var attr in m1) {
if (m1.hasOwnProperty(attr)) {
m[attr] = m1[attr];
}
}
for (var attr in m2) {
if (m2.hasOwnProperty(attr)) {
m[attr] = m2[attr];
}
}
return m;
}
}
export class ListWrapper {
static create(): List<any> { return new List(); }
static createFixedSize(size): List<any> { return new List(size); }
static get(m, k) { return m[k]; }
static set(m, k, v) { m[k] = v; }
static clone(array: List<any>) { return array.slice(0); }
static map(array, fn) { return array.map(fn); }
static forEach(array: List<any>, fn: Function) {
for (var i = 0; i < array.length; i++) {
fn(array[i]);
}
}
static push(array, el) { array.push(el); }
static first(array) {
if (!array) return null;
return array[0];
}
static last(array) {
if (!array || array.length == 0) return null;
return array[array.length - 1];
}
static find(list: List<any>, pred: Function) {
for (var i = 0; i < list.length; ++i) {
if (pred(list[i])) return list[i];
}
return null;
}
static reduce<T>(list: List<T>,
fn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T,
init: T) {
return list.reduce(fn, init);
}
static filter(array, pred: Function) { return array.filter(pred); }
static any(list: List<any>, pred: Function) {
for (var i = 0; i < list.length; ++i) {
if (pred(list[i])) return true;
}
return false;
}
static contains(list: List<any>, el) { return list.indexOf(el) !== -1; }
static reversed(array) {
var a = ListWrapper.clone(array);
return a.reverse();
}
static concat(a, b) { return a.concat(b); }
static isList(list) { return Array.isArray(list); }
static insert(list, index: int, value) { list.splice(index, 0, value); }
static removeAt(list, index: int) {
var res = list[index];
list.splice(index, 1);
return res;
}
static removeAll(list, items) {
for (var i = 0; i < items.length; ++i) {
var index = list.indexOf(items[i]);
list.splice(index, 1);
}
}
static removeLast<T>(list: List<T>): T { return list.pop(); }
static remove(list, el): boolean {
var index = list.indexOf(el);
if (index > -1) {
list.splice(index, 1);
return true;
}
return false;
}
static clear(list) { list.splice(0, list.length); }
static join(list, s) { return list.join(s); }
static isEmpty(list) { return list.length == 0; }
static fill(list: List<any>, value, start: int = 0, end: int = null) {
list.fill(value, start, end === null ? undefined : end);
}
static equals(a: List<any>, b: List<any>): boolean {
if (a.length != b.length) return false;
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
static slice<T>(l: List<T>, from: int, to: int): List<T> { return l.slice(from, to); }
static sort<T>(l: List<T>, compareFn: (a: T, b: T) => number) { l.sort(compareFn); }
}
export function isListLikeIterable(obj): boolean {
if (!isJsObject(obj)) return false;
return ListWrapper.isList(obj) ||
(!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
Symbol.iterator in obj); // JS Iterable have a Symbol.iterator prop
}
export function iterateListLike(obj, fn: Function) {
if (ListWrapper.isList(obj)) {
for (var i = 0; i < obj.length; i++) {
fn(obj[i]);
}
} else {
var iterator = obj[Symbol.iterator]();
var item;
while (!((item = iterator.next()).done)) {
fn(item.value);
}
}
}
export class SetWrapper {
static createFromList<T>(lst: List<T>): Set<T> { return new Set(lst); }
static has<T>(s: Set<T>, key: T): boolean { return s.has(key); }
}

View File

@ -0,0 +1,230 @@
var _global = typeof window === 'undefined' ? global : window;
export {_global as global};
// HACK: workaround for Traceur behavior.
// It expects all transpiled modules to contain this marker.
// TODO: remove this when we no longer use traceur
export var __esModule = true;
export var Type = Function;
export var Math = _global.Math;
export var Date = _global.Date;
var assertionsEnabled_ = typeof assert !== 'undefined';
var int;
// global assert support, as Dart has it...
// TODO: `assert` calls need to be removed in production code!
if (assertionsEnabled_) {
_global.assert = assert;
// `int` is not a valid JS type
int = assert.define(
'int', function(value) { return typeof value === 'number' && value % 1 === 0; });
} else {
int = {};
_global.assert = function() {};
}
export {int};
export class CONST {}
export class ABSTRACT {}
export class IMPLEMENTS {}
export function isPresent(obj): boolean {
return obj !== undefined && obj !== null;
}
export function isBlank(obj): boolean {
return obj === undefined || obj === null;
}
export function isString(obj): boolean {
return typeof obj === "string";
}
export function isFunction(obj): boolean {
return typeof obj === "function";
}
export function stringify(token): string {
if (typeof token === 'string') {
return token;
}
if (token === undefined || token === null) {
return '' + token;
}
if (token.name) {
return token.name;
}
return token.toString();
}
export class StringWrapper {
static fromCharCode(code: int): string { return String.fromCharCode(code); }
static charCodeAt(s: string, index: int) { return s.charCodeAt(index); }
static split(s: string, regExp) { return s.split(regExp); }
static equals(s: string, s2: string): boolean { return s === s2; }
static replace(s: string, from: string, replace: string): string {
return s.replace(from, replace);
}
static replaceAll(s: string, from: RegExp, replace: string): string {
return s.replace(from, replace);
}
static startsWith(s: string, start: string) { return s.startsWith(start); }
static substring(s: string, start: int, end: int = null) {
return s.substring(start, end === null ? undefined : end);
}
static replaceAllMapped(s: string, from: RegExp, cb: Function): string {
return s.replace(from, function(...matches) {
// Remove offset & string from the result array
matches.splice(-2, 2);
// The callback receives match, p1, ..., pn
return cb(matches);
});
}
static contains(s: string, substr: string): boolean { return s.indexOf(substr) != -1; }
}
export class StringJoiner {
constructor(public parts = []) {}
add(part: string) { this.parts.push(part); }
toString(): string { return this.parts.join(""); }
}
export class NumberParseError implements Error {
name: string;
constructor(public message: string) {}
toString() { return this.message; }
}
export class NumberWrapper {
static toFixed(n: number, fractionDigits: int): string { return n.toFixed(fractionDigits); }
static equal(a, b): boolean { return a === b; }
static parseIntAutoRadix(text: string): int {
var result: int = parseInt(text);
if (isNaN(result)) {
throw new NumberParseError("Invalid integer literal when parsing " + text);
}
return result;
}
static parseInt(text: string, radix: int): int {
if (radix == 10) {
if (/^(\-|\+)?[0-9]+$/.test(text)) {
return parseInt(text, radix);
}
} else if (radix == 16) {
if (/^(\-|\+)?[0-9ABCDEFabcdef]+$/.test(text)) {
return parseInt(text, radix);
}
} else {
var result: int = parseInt(text, radix);
if (!isNaN(result)) {
return result;
}
}
throw new NumberParseError("Invalid integer literal when parsing " + text + " in base " +
radix);
}
// TODO: NaN is a valid literal but is returned by parseFloat to indicate an error.
static parseFloat(text: string): number { return parseFloat(text); }
static get NaN(): number { return NaN; }
static isNaN(value): boolean { return isNaN(value); }
static isInteger(value): boolean { return Number.isInteger(value); }
}
export var RegExp = _global.RegExp;
export class RegExpWrapper {
static create(regExpStr, flags: string = ''): RegExp {
flags = flags.replace(/g/g, '');
return new _global.RegExp(regExpStr, flags + 'g');
}
static firstMatch(regExp, input) {
// Reset multimatch regex state
regExp.lastIndex = 0;
return regExp.exec(input);
}
static matcher(regExp, input) {
// Reset regex state for the case
// someone did not loop over all matches
// last time.
regExp.lastIndex = 0;
return {re: regExp, input: input};
}
}
export class RegExpMatcherWrapper {
static next(matcher) { return matcher.re.exec(matcher.input); }
}
export class FunctionWrapper {
static apply(fn: Function, posArgs) { return fn.apply(null, posArgs); }
}
// No subclass so that we preserve error stack.
export var BaseException = Error;
// JS has NaN !== NaN
export function looseIdentical(a, b): boolean {
return a === b || typeof a === "number" && typeof b === "number" && isNaN(a) && isNaN(b);
}
// JS considers NaN is the same as NaN for map Key (while NaN !== NaN otherwise)
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
export function getMapKey(value) {
return value;
}
export function normalizeBlank(obj) {
return isBlank(obj) ? null : obj;
}
export function isJsObject(o): boolean {
return o !== null && (typeof o === "function" || typeof o === "object");
}
export function assertionsEnabled(): boolean {
return assertionsEnabled_;
}
export function print(obj) {
if (obj instanceof Error) {
console.log(obj.stack);
} else {
console.log(obj);
}
}
// Can't be all uppercase as our transpiler would think it is a special directive...
export var Json = _global.JSON;
export class DateWrapper {
static fromMillis(ms) { return new Date(ms); }
static toMillis(date: Date) { return date.getTime(); }
static now() { return new Date(); }
static toJson(date) { return date.toJSON(); }
}

View File

@ -0,0 +1,9 @@
import {global} from 'angular2/src/facade/lang';
// HACK: workaround for Traceur behavior.
// It expects all transpiled modules to contain this marker.
// TODO: remove this when we no longer use traceur
export var __esModule = true;
export var Math = global.Math;
export var NaN = global.NaN;

76
modules/angular2/traceur-runtime.d.ts vendored Normal file
View File

@ -0,0 +1,76 @@
// Extend the ES5 standard library with some ES6 features we polyfill at runtime
// by loading traceur-runtime.js
// These are mostly copied from lib.es6.d.ts
interface String {
/**
* Returns true if the sequence of elements of searchString converted to a String is the
* same as the corresponding elements of this object (converted to a String) starting at
* position. Otherwise returns false.
*/
startsWith(searchString: string, position ?: number): boolean;
}
interface NumberConstructor {
/**
* Returns true if the value passed is an integer, false otherwise.
* @param number A numeric value.
*/
isInteger(number: number): boolean;
}
interface Array<T> {
/**
* Returns the this object after filling the section identified by start and end with value
* @param value value to fill array section with
* @param start index to start filling the array at. If start is negative, it is treated as
* length+start where length is the length of the array.
* @param end index to stop filling the array at. If end is negative, it is treated as
* length+end.
*/
fill(value: T, start ?: number, end ?: number): T[];
}
// Copied from lib.dom.d.ts and modified
interface Map<K, V> {
clear(): void;
delete (key: K): boolean;
forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg ?: any): void;
get(key: K): V;
has(key: K): boolean;
set(key: K, value: V): Map<K, V>;
size: number;
}
declare var Map: {
new<K, V>(): Map<K, V>;
// alexeagle: PATCHED
new<K, V>(m: Map<K, V>): Map<K, V>;
new<K, V>(l: List<any>): Map<K, V>;
prototype: Map<any, any>;
};
interface Set<T> {
add(value: T): Set<T>;
clear(): void;
delete (value: T): boolean;
forEach(callbackfn: (value: T, index: T, set: Set<T>) => void, thisArg ?: any): void;
has(value: T): boolean;
size: number;
}
declare var Set: {
new<T>(): Set<T>;
// alexeagle PATCHED
new<T>(s: Set<T>): Set<T>;
new<T>(l: List<T>): Set<T>;
prototype: Set<any>;
};
interface SymbolConstructor {
/**
* A method that returns the default iterator for an object.Called by the semantics of the
* for-of statement.
*/
iterator: symbol;
}
declare var Symbol: SymbolConstructor;

View File

@ -51,6 +51,7 @@
"glob": "^4.0.6",
"gulp": "^3.8.8",
"gulp-changed": "^1.0.0",
"gulp-clang-format": "^1.0.3",
"gulp-concat": "^2.5.2",
"gulp-connect": "~1.0.5",
"gulp-jasmine": "^1.0.1",
@ -84,7 +85,7 @@
"temp": "^0.8.1",
"ternary-stream": "^1.2.3",
"through2": "^0.6.1",
"typescript": "Microsoft/TypeScript#cebe42b81fbeeaf68c8e228dda5e602ab94e151b",
"typescript": "alexeagle/TypeScript#93dbbe2a2d0b42cefd02ac949e4bc8ab6b5b5823",
"vinyl": "^0.4.6",
"yargs": "2.3.*"
}