-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ivy): implement pipes #22254
feat(ivy): implement pipes #22254
Changes from all commits
e2bff81
2735971
1a5118b
916ac00
caab959
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,17 +6,32 @@ | |
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {PipeTransform} from '../change_detection/pipe_transform'; | ||
|
||
import {getTView, load, store} from './instructions'; | ||
import {PipeDef} from './interfaces/definition'; | ||
import {pureFunction1, pureFunction2, pureFunction3, pureFunction4, pureFunctionV} from './pure_function'; | ||
|
||
|
||
/** | ||
* Create a pipe. | ||
* | ||
* @param index Pipe index where the pipe will be stored. | ||
* @param pipeDef Pipe definition object for registering life cycle hooks. | ||
* @param pipe A Pipe instance. | ||
* @param firstInstance (optional) The first instance of the pipe that can be reused for pure pipes. | ||
* @returns T the instance of the pipe. | ||
*/ | ||
export function pipe<T>(index: number, pipeDef: PipeDef<T>, pipe: T): void { | ||
throw new Error('TODO: implement!'); | ||
export function pipe<T>(index: number, pipeDef: PipeDef<T>, firstInstance?: T): T { | ||
const tView = getTView(); | ||
if (tView.firstTemplatePass) { | ||
tView.data[index] = pipeDef; | ||
if (pipeDef.onDestroy != null) { | ||
(tView.destroyHooks || (tView.destroyHooks = [])).push(index, pipeDef.onDestroy); | ||
} | ||
} | ||
const pipeInstance = pipeDef.pure && firstInstance ? firstInstance : pipeDef.n(); | ||
store(index, pipeInstance); | ||
return pipeInstance; | ||
} | ||
|
||
/** | ||
|
@@ -29,7 +44,9 @@ export function pipe<T>(index: number, pipeDef: PipeDef<T>, pipe: T): void { | |
* @param v1 1st argument to {@link PipeTransform#transform}. | ||
*/ | ||
export function pipeBind1(index: number, v1: any): any { | ||
throw new Error('TODO: implement!'); | ||
const pipeInstance = load<PipeTransform>(index); | ||
return isPure(index) ? pureFunction1(pipeInstance.transform, v1, pipeInstance) : | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an asymmetry between args in pure and non-pure case. They should be the same. Maybe have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They can't be the same. In the pure case, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that we have removed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mhevery Can you please clarify what you have in mind? |
||
pipeInstance.transform(v1); | ||
} | ||
|
||
/** | ||
|
@@ -43,7 +60,9 @@ export function pipeBind1(index: number, v1: any): any { | |
* @param v2 2nd argument to {@link PipeTransform#transform}. | ||
*/ | ||
export function pipeBind2(index: number, v1: any, v2: any): any { | ||
throw new Error('TODO: implement!'); | ||
const pipeInstance = load<PipeTransform>(index); | ||
return isPure(index) ? pureFunction2(pipeInstance.transform, v1, v2, pipeInstance) : | ||
pipeInstance.transform(v1, v2); | ||
} | ||
|
||
/** | ||
|
@@ -58,7 +77,9 @@ export function pipeBind2(index: number, v1: any, v2: any): any { | |
* @param v3 4rd argument to {@link PipeTransform#transform}. | ||
*/ | ||
export function pipeBind3(index: number, v1: any, v2: any, v3: any): any { | ||
throw new Error('TODO: implement!'); | ||
const pipeInstance = load<PipeTransform>(index); | ||
return isPure(index) ? pureFunction3(pipeInstance.transform.bind(pipeInstance), v1, v2, v3) : | ||
pipeInstance.transform(v1, v2, v3); | ||
} | ||
|
||
/** | ||
|
@@ -74,7 +95,9 @@ export function pipeBind3(index: number, v1: any, v2: any, v3: any): any { | |
* @param v4 4th argument to {@link PipeTransform#transform}. | ||
*/ | ||
export function pipeBind4(index: number, v1: any, v2: any, v3: any, v4: any): any { | ||
throw new Error('TODO: implement!'); | ||
const pipeInstance = load<PipeTransform>(index); | ||
return isPure(index) ? pureFunction4(pipeInstance.transform, v1, v2, v3, v4, pipeInstance) : | ||
pipeInstance.transform(v1, v2, v3, v4); | ||
} | ||
|
||
/** | ||
|
@@ -87,5 +110,11 @@ export function pipeBind4(index: number, v1: any, v2: any, v3: any, v4: any): an | |
* @param values Array of arguments to pass to {@link PipeTransform#transform} method. | ||
*/ | ||
export function pipeBindV(index: number, values: any[]): any { | ||
throw new Error('TODO: implement!'); | ||
} | ||
const pipeInstance = load<PipeTransform>(index); | ||
return isPure(index) ? pureFunctionV(pipeInstance.transform, values, pipeInstance) : | ||
pipeInstance.transform.apply(pipeInstance, values); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The spread operator would be transpiled into a for loop, which doesn't seem to be a good idea. |
||
} | ||
|
||
function isPure(index: number): boolean { | ||
return (<PipeDef<any>>getTView().data[index]).pure; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing
firstInstance
as aPipe
we could pass it as an index which would greatly simplify the work which compiler has to do./cc @chuckjaz
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either is fine.
Storing it in a temporary that is not closure captured is simple to generate and is relatively efficient.
Passing in an index is easier. If it is already in an index then the index of the first one is an easy thing to track.
We should do whatever is consistent for the API of the instructions and the most efficient at runtime. The compiler can easily generate either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using index was my first idea, but it wouldn't work with embedded views, and it should.