From 1f1064c6ab4f9049dfa8df490325b430631458e8 Mon Sep 17 00:00:00 2001 From: Adrian Zanescu Date: Tue, 11 Oct 2016 18:33:39 +0300 Subject: [PATCH] initial upload --- .gitignore | 12 + .../.vs/config/applicationhost.config | 1039 +++++++++++++++++ Linq.TypeScript/Linq.TypeScript.sln | 22 + .../Linq.TypeScript/Linq.TypeScript.csproj | 89 ++ Linq.TypeScript/Linq.TypeScript/index.html | 10 + .../Linq.TypeScript/linq.typescript.d.ts | 36 + .../Linq.TypeScript/linq.typescript.ts | 524 +++++++++ .../Linq.TypeScript/test.linq.typescript.ts | 24 + .../Linq.TypeScript/web.Debug.config | 30 + .../Linq.TypeScript/web.Release.config | 31 + Linq.TypeScript/Linq.TypeScript/web.config | 11 + 11 files changed, 1828 insertions(+) create mode 100644 .gitignore create mode 100644 Linq.TypeScript/.vs/config/applicationhost.config create mode 100644 Linq.TypeScript/Linq.TypeScript.sln create mode 100644 Linq.TypeScript/Linq.TypeScript/Linq.TypeScript.csproj create mode 100644 Linq.TypeScript/Linq.TypeScript/index.html create mode 100644 Linq.TypeScript/Linq.TypeScript/linq.typescript.d.ts create mode 100644 Linq.TypeScript/Linq.TypeScript/linq.typescript.ts create mode 100644 Linq.TypeScript/Linq.TypeScript/test.linq.typescript.ts create mode 100644 Linq.TypeScript/Linq.TypeScript/web.Debug.config create mode 100644 Linq.TypeScript/Linq.TypeScript/web.Release.config create mode 100644 Linq.TypeScript/Linq.TypeScript/web.config diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01f0a61 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ + +*.suo +*.user +*.map +/Linq.TypeScript/Linq.TypeScript/bin +/Linq.TypeScript/Linq.TypeScript/obj +/Linq.TypeScript/Linq.TypeScript/test.linq.typescript.js +/Linq.TypeScript/Linq.TypeScript/test.linq.typescript.d.ts +/Linq.TypeScript/Linq.TypeScript/linq.typescript.js diff --git a/Linq.TypeScript/.vs/config/applicationhost.config b/Linq.TypeScript/.vs/config/applicationhost.config new file mode 100644 index 0000000..11afc2a --- /dev/null +++ b/Linq.TypeScript/.vs/config/applicationhost.config @@ -0,0 +1,1039 @@ + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Linq.TypeScript/Linq.TypeScript.sln b/Linq.TypeScript/Linq.TypeScript.sln new file mode 100644 index 0000000..47709b1 --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Linq.TypeScript", "Linq.TypeScript\Linq.TypeScript.csproj", "{5C8DE574-F8CD-4EC7-A4B3-4CC61A46EB4C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5C8DE574-F8CD-4EC7-A4B3-4CC61A46EB4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5C8DE574-F8CD-4EC7-A4B3-4CC61A46EB4C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5C8DE574-F8CD-4EC7-A4B3-4CC61A46EB4C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5C8DE574-F8CD-4EC7-A4B3-4CC61A46EB4C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Linq.TypeScript/Linq.TypeScript/Linq.TypeScript.csproj b/Linq.TypeScript/Linq.TypeScript/Linq.TypeScript.csproj new file mode 100644 index 0000000..e967afd --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript/Linq.TypeScript.csproj @@ -0,0 +1,89 @@ + + + + + Debug + {5C8DE574-F8CD-4EC7-A4B3-4CC61A46EB4C} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + bin + v4.5.2 + full + true + 2.0 + true + + + + + + + + + + + + + + + + web.config + + + web.config + + + + + + + Code + + + + 12.0 + + + Linq.TypeScript + + + + + + + + True + True + 60514 + / + http://localhost:60514/ + False + False + + + False + + + + + + false + true + ES5 + None + True + False + None + + + True + True + + + + + true + false + + + \ No newline at end of file diff --git a/Linq.TypeScript/Linq.TypeScript/index.html b/Linq.TypeScript/Linq.TypeScript/index.html new file mode 100644 index 0000000..bf97f43 --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript/index.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Linq.TypeScript/Linq.TypeScript/linq.typescript.d.ts b/Linq.TypeScript/Linq.TypeScript/linq.typescript.d.ts new file mode 100644 index 0000000..33dd9d8 --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript/linq.typescript.d.ts @@ -0,0 +1,36 @@ +declare namespace Linq { + interface IEnumerable { + getEnumerator(): IEnumerator; + } + interface IEnumerator { + current(): T; + moveNext(): boolean; + } + interface IDictionary { + [key: string]: TValue; + } + function IsEnumerable(obj: any): obj is IEnumerable; + interface ILinqEnumerable extends IEnumerable { + selectMany(selector: (t: T, i: number) => IEnumerable | S): ILinqEnumerable; + select(selector: (t: T, i: number) => S): ILinqEnumerable; + where(predicate: (t: T, i: number) => boolean): ILinqEnumerable; + apply(action: (t: T) => void): ILinqEnumerable; + forEach(action: (t: T) => void): void; + toArray(): T[]; + toDictionary(keySelector: (t: T) => string, valueSelector: (t: T) => TValue): IDictionary; + join(right: IEnumerable, leftKey: (t: T) => any, rightKey: (r: TRight) => any, selector: (l: T, r: TRight) => TResult): ILinqEnumerable; + union(other: IEnumerable): ILinqEnumerable; + take(count: number): ILinqEnumerable; + skip(count: number): ILinqEnumerable; + zip(other: IEnumerable, selector: (t: T, s: S) => R): ILinqEnumerable; + aggregate(func: (t: T, acumulator: S) => S, seed?: S): S; + } + interface ILinqStatic { + (source: T[] | IEnumerable | T): ILinqEnumerable; + empty(): ILinqEnumerable; + generate(generator: (i: number) => T): ILinqEnumerable; + repeat(value: T, count: number): ILinqEnumerable; + } + var linqStatic: ILinqStatic; +} +declare var linq: Linq.ILinqStatic; diff --git a/Linq.TypeScript/Linq.TypeScript/linq.typescript.ts b/Linq.TypeScript/Linq.TypeScript/linq.typescript.ts new file mode 100644 index 0000000..be8c472 --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript/linq.typescript.ts @@ -0,0 +1,524 @@ +namespace Linq +{ + export interface IEnumerable + { + getEnumerator(): IEnumerator + } + + export interface IEnumerator + { + current(): T; + moveNext(): boolean; + } + + export interface IDictionary + { + [key: string]: TValue; + } + + class EmptyEnumerable implements IEnumerable + { + getEnumerator(): IEnumerator + { + return EmptyEnumerator.instance(); + } + } + + class EmptyEnumerator implements IEnumerator + { + moveNext() + { + return false; + } + + current() + { + return null; + } + + private static _instance = new EmptyEnumerator(); + static instance() + { + return EmptyEnumerator._instance; + } + } + + export function IsEnumerable(obj): obj is IEnumerable + { + if (!obj) + { + return false; + } + var en = >obj; + return en.isEnumerable && en.isEnumerable() || en.getEnumerator ? true : false; + } + + class Enumerable implements IEnumerable + { + private static _empty = new EmptyEnumerable(); + static empty(): IEnumerable + { + return Enumerable._empty; + } + + isEnumerable() + { + return true; + } + + _source: IEnumerable; + constructor(source: IEnumerable) + { + this._source = >(source || Enumerable.empty()); + } + + getEnumerator() + { + return this._source.getEnumerator(); + } + + forEach(action: (t: T) => void, shouldBreak?: (t: T) => boolean) + { + var iter = this.getEnumerator(); + while (iter.moveNext()) + { + var current = iter.current(); + if (shouldBreak && shouldBreak(current)) + { + break; + } + action(current); + } + } + + static toLinq(source: IEnumerable): ILinqEnumerable + { + return new LinqEnumerable(source); + } + + static fromArray(source: T[]): ILinqEnumerable + { + return Enumerable.toLinq(Implementations.fromArray(source)); + } + + static fromValue(source: T): ILinqEnumerable + { + return Enumerable.toLinq(Implementations.fromValue(source)); + } + + static generate(generator: (i: number) => IEnumerable | T): ILinqEnumerable + { + return Enumerable.toLinq(Implementations.generate(generator)); + } + + static repeat(value: T, count: number): ILinqEnumerable + { + return Enumerable.generate(() => value).take(count); + } + } + + export interface ILinqEnumerable extends IEnumerable + { + selectMany(selector: (t: T, i: number) => IEnumerable | S): ILinqEnumerable; + select(selector: (t: T, i: number) => S): ILinqEnumerable; + where(predicate: (t: T, i: number) => boolean): ILinqEnumerable; + + apply(action: (t: T) => void): ILinqEnumerable; + forEach(action: (t: T) => void): void; + + toArray(): T[]; + toDictionary(keySelector: (t: T) => string, valueSelector: (t: T) => TValue): IDictionary; + + join(right: IEnumerable, leftKey: (t: T) => any, rightKey: (r: TRight) => any + , selector: (l: T, r: TRight) => TResult): ILinqEnumerable; + union(other: IEnumerable): ILinqEnumerable; + + take(count: number): ILinqEnumerable; + skip(count: number): ILinqEnumerable; + zip(other: IEnumerable, selector: (t: T, s: S) => R): ILinqEnumerable + + aggregate(func: (t: T, acumulator: S) => S, seed?: S): S; + } + + class LinqEnumerable extends Enumerable implements ILinqEnumerable + { + selectMany(selector: (t: T, i: number) => IEnumerable | S): ILinqEnumerable + { + var index = -1; + var map = Implementations.flatMap(this, t => + { + index++; + return selector(t, index); + }); + return new LinqEnumerable(map); + } + + select(selector: (t: T, i: number) => S): ILinqEnumerable + { + return this.selectMany((t, i) => selector(t, i)); + } + + where(predicate: (t: T, i: number) => boolean): ILinqEnumerable + { + return this.selectMany((t, i) => + { + return predicate(t, i) ? t : Enumerable.empty(); + }); + } + + apply(action: (t: T) => void): ILinqEnumerable + { + return this.select(a => { action(a); return a }); + } + + toArray(): T[] + { + var result: T[] = []; + this.forEach(a => result.push(a)); + return result; + } + + toDictionary(keySelector: (t: T) => string, valueSelector: (t: T) => TValue): IDictionary + { + var result: IDictionary = {}; + this.forEach(a => + { + result[keySelector(a)] = valueSelector(a); + }); + return result; + } + + take(count: number): ILinqEnumerable + { + return new LinqEnumerable( + { + getEnumerator: () => + { + var inner = this.getEnumerator(); + var result = Implementations.generate(i => inner.current(), (a, i) => i < count && inner.moveNext()); + return result.getEnumerator(); + } + }); + } + + skip(count: number) + { + return this.where((_, i) => i >= count); + } + + union(other: ILinqEnumerable): ILinqEnumerable + { + return Enumerable.generate(i => i).take(2) + .selectMany(i => + { + if (i == 0) + { + return this; + } + return other; + }); + } + + join(right: ILinqEnumerable, leftKey: (t: T) => any, rightKey: (r: TRight) => any + , selector: (l: T, r: TRight) => TResult): ILinqEnumerable + { + return new LinqEnumerable( + { + getEnumerator: () => + { + var keys = {}; + var head = this.take(1).selectMany(l => + { + var lk = leftKey(l); + return right.select(r => + { + var rk = rightKey(r); + var rs: any[] = keys[rk] || []; + rs.push(r); + keys[rk] = rs; + return { rk: rk, r: r }; + }).where(a => a.rk == lk) + .select(a => selector(l, a.r)); + }); + var tail = this.skip(1).selectMany(l => + { + var lk = leftKey(l); + var rightJoin = Enumerable.fromArray(keys[lk]); + return rightJoin.select(r => + { + return selector(l, r); + }); + }); + return head.union(tail).getEnumerator(); + } + }); + } + + zip(other: IEnumerable, selector: (t: T, s: S) => R): ILinqEnumerable + { + return new LinqEnumerable( + { + getEnumerator: () => + { + var iter1 = this.getEnumerator(); + var iter2 = other.getEnumerator(); + var gen = Implementations.generate((i) => selector(iter1.current(), iter2.current()), (prev, i) => iter1.moveNext() && iter2.moveNext()); + return gen.getEnumerator(); + } + }); + } + + aggregate(func: (t: T, acumulator: S) => S, seed?: S): S + { + var iter = this.getEnumerator(); + while (iter.moveNext()) + { + seed = func(iter.current(), seed); + } + return seed; + } + } + + namespace Implementations + { + class ArrayEnumerable implements IEnumerable + { + _array: T[]; + constructor(array: T[]) + { + this._array = array || []; + } + + getEnumerator(): IEnumerator + { + return new ArrayEnumerator(this._array); + } + } + + export function fromArray(array: T[]): IEnumerable + { + return new ArrayEnumerable(array); + } + + class ArrayEnumerator extends ArrayEnumerable implements IEnumerator + { + private _index = -1; + constructor(array: T[]) + { + super(array); + } + + private reachedEnd() + { + return this._index >= this._array.length; + } + + moveNext() + { + this._index++; + return !this.reachedEnd(); + } + + current() + { + return this._array[this._index]; + } + } + + class ValueEnumerable implements IEnumerable + { + private _value: T; + constructor(value: T) + { + this._value = value; + } + + getEnumerator(): IEnumerator + { + return new ValueEnumerator(this._value); + } + } + + export function fromValue(source: T): IEnumerable + { + return new ValueEnumerable(source); + } + + class ValueEnumerator implements IEnumerator + { + private _value: T; + constructor(value: T) + { + this._value = value; + } + + private _moved = false; + + moveNext() + { + return this._moved ? false : (this._moved = true); + } + + current() + { + return this._value; + } + } + + class GeneratedEnumerable implements IEnumerable + { + private _generator: (i: number) => IEnumerable | T; + private _moveNext: (t: T, i: number) => boolean; + + constructor(generator: (i?: number) => IEnumerable | T, moveNext?: (previous: T, i: number) => boolean) + { + this._generator = generator || (i => null); + this._moveNext = moveNext || ((previous, i) => true); + } + + getEnumerator(): IEnumerator + { + var previous: T = null; + var index = -1; + var gen: IEnumerator = + { + moveNext: () => + { + index++; + return this._moveNext(previous, index); + }, + current: () => index + }; + return Linq.linqStatic({ getEnumerator: () => gen }).selectMany(a => this._generator(a)).select(a => + { + previous = a; + return a; + }).getEnumerator(); + }; + } + + export function generate(generator: (i: number) => IEnumerable | T, moveNext?: (previous: T, i: number) => boolean): IEnumerable + { + return new GeneratedEnumerable(generator, moveNext); + } + + class FlatMapEnumerable implements IEnumerable + { + private _source: IEnumerable; + private _selector: (T) => IEnumerable | S; + constructor(source: IEnumerable, selector: (t: T) => IEnumerable | S) + { + this._source = source || Linq.linqStatic.empty(); + this._selector = selector || (item => Linq.linqStatic.empty()); + } + + getEnumerator(): IEnumerator + { + return new FlatMapper(this._source, this._selector); + } + } + + export function flatMap(source: IEnumerable, selector: (t: T) => IEnumerable | S): IEnumerable + { + return new FlatMapEnumerable(source, selector); + } + + class FlatMapper implements IEnumerator + { + private _source: IEnumerable; + private _selector: (T) => IEnumerable | S; + + constructor(source: IEnumerable, selector: (t: T) => IEnumerable | S) + { + this._source = source || Linq.linqStatic.empty(); + this._selector = selector || (item => Linq.linqStatic.empty()); + } + + private _current: S; + private _enumerator: IEnumerator; + private _mapped: IEnumerator; + + moveNext() + { + this._enumerator = this._enumerator || this._source.getEnumerator(); + + if (this.innerMoveNext()) + { + return true; + } + while (this._enumerator.moveNext()) + { + var selectResult = this._selector(this._enumerator.current()); + if (Linq.IsEnumerable(selectResult)) + { + this._mapped = selectResult.getEnumerator(); + } + else + { + this._current = selectResult; + this._mapped = null; + return true; + } + if (this.innerMoveNext()) + { + return true; + } + } + return false; + } + + private innerMoveNext() + { + while (this._mapped && this._mapped.moveNext()) + { + this._current = this._mapped.current(); + return true; + } + return false; + } + + current() + { + return this._current; + } + } + } + + export interface ILinqStatic + { + (source: T[] | IEnumerable | T): ILinqEnumerable + empty(): ILinqEnumerable; + generate(generator: (i: number) => T): ILinqEnumerable; + repeat(value: T, count: number): ILinqEnumerable; + } + + export var linqStatic: ILinqStatic; + linqStatic = ((source) => + { + if (source) + { + if (source instanceof Array) + { + return Enumerable.fromArray(source); + } + if (source.getEnumerator) + { + if (source.selectMany) + { + return source; + } + return Enumerable.toLinq(source); + } + } + return Enumerable.fromValue(source); + }); + + var empty = Enumerable.toLinq(Enumerable.empty()); + linqStatic.empty = () => empty; + linqStatic.generate = Enumerable.generate; + linqStatic.repeat = Enumerable.repeat; + + linq = linqStatic; +} + +declare var linq: Linq.ILinqStatic; \ No newline at end of file diff --git a/Linq.TypeScript/Linq.TypeScript/test.linq.typescript.ts b/Linq.TypeScript/Linq.TypeScript/test.linq.typescript.ts new file mode 100644 index 0000000..6bafeb6 --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript/test.linq.typescript.ts @@ -0,0 +1,24 @@ +namespace Test.Linq +{ + function Do() + { + var source = linq.generate(i => i).take(1000 * 100); + + var count = 0; + source.where(a => a >= 5).select(a => a + 1) + .forEach(a => count++); + + var result = source.where(a => a >= 5).select(a => a + 1).toArray(); + console.log(result); + + var dict = linq(result).toDictionary(a => "key" + a.toString(), a => a); + result = source.union(linq(result)).toArray(); + console.log(result); + + var join = linq(source).join(linq(result), l => l, r => r, (l, r) => l + r).toArray(); + result = linq.generate(i => i).take(10).toArray(); + console.log(result); + } + + Do(); +} \ No newline at end of file diff --git a/Linq.TypeScript/Linq.TypeScript/web.Debug.config b/Linq.TypeScript/Linq.TypeScript/web.Debug.config new file mode 100644 index 0000000..2e302f9 --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript/web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Linq.TypeScript/Linq.TypeScript/web.Release.config b/Linq.TypeScript/Linq.TypeScript/web.Release.config new file mode 100644 index 0000000..c358444 --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript/web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Linq.TypeScript/Linq.TypeScript/web.config b/Linq.TypeScript/Linq.TypeScript/web.config new file mode 100644 index 0000000..bfb640d --- /dev/null +++ b/Linq.TypeScript/Linq.TypeScript/web.config @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file