refactor(core): Ensure that previousOrParentTNode always belongs to current TView. (#38707)

`previousOrParentTNode` stores current `TNode`. Due to inconsistent
implementation the value stored would sometimes belong to the current
`TView` and sometimes to the parent. We have extra logic which accounts
for it. A better solution is to just ensure that `previousOrParentTNode`
always belongs to current `TNode`. This simplifies the mental model
and cleans up some code.

PR Close #38707
This commit is contained in:
Misko Hevery
2020-09-03 22:46:11 -07:00
parent 689651b52f
commit 33aaa9e7d0
21 changed files with 63 additions and 29 deletions

View File

@ -1031,6 +1031,9 @@
{
"name": "getNodeInjectable"
},
{
"name": "getNonViewFirstChild"
},
{
"name": "getNullInjector"
},

View File

@ -395,6 +395,9 @@
{
"name": "getNodeInjectable"
},
{
"name": "getNonViewFirstChild"
},
{
"name": "getOrCreateInjectable"
},

View File

@ -228,7 +228,7 @@ describe('di', () => {
const contentView = createLView(
null, createTView(TViewType.Component, -1, null, 1, 0, null, null, null, null, null), {},
LViewFlags.CheckAlways, null, null, {} as any, {} as any);
enterView(contentView, null);
enterView(contentView);
try {
const parentTNode =
getOrCreateTNode(contentView[TVIEW], null, 0, TNodeType.Element, null, null);

View File

@ -459,7 +459,9 @@ describe('Runtime i18n', () => {
const nbConsts = 2;
const index = 1;
const opCodes = getOpCodes(attrs, () => {
ɵɵelementStart(0, 'div');
ɵɵi18nAttributes(index, 0);
ɵɵelementEnd();
}, null, nbConsts, index);
expect(opCodes).toEqual(debugMatch([
@ -473,7 +475,9 @@ describe('Runtime i18n', () => {
const nbConsts = 2;
const index = 1;
const opCodes = getOpCodes(attrs, () => {
ɵɵelementStart(0, 'div');
ɵɵi18nAttributes(index, 0);
ɵɵelementEnd();
}, null, nbConsts, index);
expect(opCodes).toEqual(debugMatch([
@ -487,7 +491,9 @@ describe('Runtime i18n', () => {
const nbConsts = 2;
const index = 1;
const opCodes = getOpCodes(attrs, () => {
ɵɵelementStart(0, 'div');
ɵɵi18nAttributes(index, 0);
ɵɵelementEnd();
}, null, nbConsts, index);
expect(opCodes).toEqual(debugMatch([

View File

@ -17,7 +17,7 @@ import {KeyValueArray} from '@angular/core/src/util/array_utils';
describe('lView_debug', () => {
const mockFirstUpdatePassLView: LView = [null, {firstUpdatePass: true}] as any;
beforeEach(() => enterView(mockFirstUpdatePassLView, null));
beforeEach(() => enterView(mockFirstUpdatePassLView));
afterEach(() => leaveView());
describe('TNode', () => {

View File

@ -45,7 +45,7 @@ export function enterViewWithOneDiv() {
null);
lView[0 + HEADER_OFFSET] = div;
tView.data[0 + HEADER_OFFSET] = tNode;
enterView(lView, tNode);
enterView(lView);
}
export function clearFirstUpdatePass() {

View File

@ -265,7 +265,7 @@ export function renderTemplate<T>(
const hostLView = createLView(
null, tView, {}, LViewFlags.CheckAlways | LViewFlags.IsRoot, null, null,
providedRendererFactory, renderer);
enterView(hostLView, null);
enterView(hostLView);
const def: ComponentDef<any> = ɵɵdefineComponent({
type: Object,

View File

@ -16,7 +16,7 @@ describe('static styling', () => {
const mockFirstCreatePassLView: LView = [null, {firstCreatePass: true}] as any;
let tNode!: TNode;
beforeEach(() => {
enterView(mockFirstCreatePassLView, null);
enterView(mockFirstCreatePassLView);
tNode = createTNode(null!, null!, TNodeType.Element, 0, '', null);
});
it('should initialize when no attrs', () => {

View File

@ -16,7 +16,7 @@ import {newArray} from '@angular/core/src/util/array_utils';
describe('TNode styling linked list', () => {
const mockFirstUpdatePassLView: LView = [null, {firstUpdatePass: true}] as any;
beforeEach(() => enterView(mockFirstUpdatePassLView, null));
beforeEach(() => enterView(mockFirstUpdatePassLView));
afterEach(() => leaveView());
describe('insertTStylingBinding', () => {
it('should append template only', () => {

View File

@ -20,7 +20,7 @@ function fakeLView(): LView {
}
describe('sanitization', () => {
beforeEach(() => enterView(fakeLView(), null));
beforeEach(() => enterView(fakeLView()));
afterEach(() => leaveView());
class Wrap {
constructor(private value: string) {}