refactor(compiler): element.startSourceSpan is required (#38581)
Previously, the `startSourceSpan` property could be null but in reality it is always well defined - except for a legacy case in the old i18n extraction/merging code, where the typings for source-spans are already being undermined. Making this property non-null, simplifies code elsewhere in the project. PR Close #38581
This commit is contained in:
parent
86e11f1110
commit
a68f1a78a7
|
@ -124,7 +124,7 @@ class _Visitor implements html.Visitor {
|
||||||
this._translations = translations;
|
this._translations = translations;
|
||||||
|
|
||||||
// Construct a single fake root element
|
// Construct a single fake root element
|
||||||
const wrapper = new html.Element('wrapper', [], nodes, undefined!, undefined, undefined);
|
const wrapper = new html.Element('wrapper', [], nodes, undefined!, undefined!, undefined);
|
||||||
|
|
||||||
const translatedNode = wrapper.visit(this, null);
|
const translatedNode = wrapper.visit(this, null);
|
||||||
|
|
||||||
|
@ -492,7 +492,7 @@ class _Visitor implements html.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _reportError(node: html.Node, msg: string): void {
|
private _reportError(node: html.Node, msg: string): void {
|
||||||
this._errors.push(new I18nError(node.sourceSpan!, msg));
|
this._errors.push(new I18nError(node.sourceSpan, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ class _I18nVisitor implements html.Visitor {
|
||||||
const isVoid: boolean = getHtmlTagDefinition(el.name).isVoid;
|
const isVoid: boolean = getHtmlTagDefinition(el.name).isVoid;
|
||||||
const startPhName =
|
const startPhName =
|
||||||
context.placeholderRegistry.getStartTagPlaceholderName(el.name, attrs, isVoid);
|
context.placeholderRegistry.getStartTagPlaceholderName(el.name, attrs, isVoid);
|
||||||
context.placeholderToContent[startPhName] = el.sourceSpan!.toString();
|
context.placeholderToContent[startPhName] = el.sourceSpan.toString();
|
||||||
|
|
||||||
let closePhName = '';
|
let closePhName = '';
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class _I18nVisitor implements html.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = new i18n.TagPlaceholder(
|
const node = new i18n.TagPlaceholder(
|
||||||
el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan!);
|
el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan);
|
||||||
return context.visitNodeFn(el, node);
|
return context.visitNodeFn(el, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ class _I18nVisitor implements html.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
visitText(text: html.Text, context: I18nMessageVisitorContext): i18n.Node {
|
visitText(text: html.Text, context: I18nMessageVisitorContext): i18n.Node {
|
||||||
const node = this._visitTextWithInterpolation(text.value, text.sourceSpan!, context);
|
const node = this._visitTextWithInterpolation(text.value, text.sourceSpan, context);
|
||||||
return context.visitNodeFn(text, node);
|
return context.visitNodeFn(text, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,9 +231,9 @@ class XliffParser implements ml.Visitor {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _TARGET_TAG:
|
case _TARGET_TAG:
|
||||||
const innerTextStart = element.startSourceSpan!.end.offset;
|
const innerTextStart = element.startSourceSpan.end.offset;
|
||||||
const innerTextEnd = element.endSourceSpan!.start.offset;
|
const innerTextEnd = element.endSourceSpan!.start.offset;
|
||||||
const content = element.startSourceSpan!.start.file.content;
|
const content = element.startSourceSpan.start.file.content;
|
||||||
const innerText = content.slice(innerTextStart, innerTextEnd);
|
const innerText = content.slice(innerTextStart, innerTextEnd);
|
||||||
this._unitMlString = innerText;
|
this._unitMlString = innerText;
|
||||||
break;
|
break;
|
||||||
|
@ -264,7 +264,7 @@ class XliffParser implements ml.Visitor {
|
||||||
visitExpansionCase(expansionCase: ml.ExpansionCase, context: any): any {}
|
visitExpansionCase(expansionCase: ml.ExpansionCase, context: any): any {}
|
||||||
|
|
||||||
private _addError(node: ml.Node, message: string): void {
|
private _addError(node: ml.Node, message: string): void {
|
||||||
this._errors.push(new I18nError(node.sourceSpan!, message));
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,14 +288,14 @@ class XmlToI18n implements ml.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
visitText(text: ml.Text, context: any) {
|
visitText(text: ml.Text, context: any) {
|
||||||
return new i18n.Text(text.value, text.sourceSpan!);
|
return new i18n.Text(text.value, text.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitElement(el: ml.Element, context: any): i18n.Placeholder|ml.Node[]|null {
|
visitElement(el: ml.Element, context: any): i18n.Placeholder|ml.Node[]|null {
|
||||||
if (el.name === _PLACEHOLDER_TAG) {
|
if (el.name === _PLACEHOLDER_TAG) {
|
||||||
const nameAttr = el.attrs.find((attr) => attr.name === 'id');
|
const nameAttr = el.attrs.find((attr) => attr.name === 'id');
|
||||||
if (nameAttr) {
|
if (nameAttr) {
|
||||||
return new i18n.Placeholder('', nameAttr.value, el.sourceSpan!);
|
return new i18n.Placeholder('', nameAttr.value, el.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "id" attribute`);
|
this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "id" attribute`);
|
||||||
|
@ -332,7 +332,7 @@ class XmlToI18n implements ml.Visitor {
|
||||||
visitAttribute(attribute: ml.Attribute, context: any) {}
|
visitAttribute(attribute: ml.Attribute, context: any) {}
|
||||||
|
|
||||||
private _addError(node: ml.Node, message: string): void {
|
private _addError(node: ml.Node, message: string): void {
|
||||||
this._errors.push(new I18nError(node.sourceSpan!, message));
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,9 +246,9 @@ class Xliff2Parser implements ml.Visitor {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _TARGET_TAG:
|
case _TARGET_TAG:
|
||||||
const innerTextStart = element.startSourceSpan!.end.offset;
|
const innerTextStart = element.startSourceSpan.end.offset;
|
||||||
const innerTextEnd = element.endSourceSpan!.start.offset;
|
const innerTextEnd = element.endSourceSpan!.start.offset;
|
||||||
const content = element.startSourceSpan!.start.file.content;
|
const content = element.startSourceSpan.start.file.content;
|
||||||
const innerText = content.slice(innerTextStart, innerTextEnd);
|
const innerText = content.slice(innerTextStart, innerTextEnd);
|
||||||
this._unitMlString = innerText;
|
this._unitMlString = innerText;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -130,9 +130,9 @@ class XtbParser implements ml.Visitor {
|
||||||
if (this._msgIdToHtml.hasOwnProperty(id)) {
|
if (this._msgIdToHtml.hasOwnProperty(id)) {
|
||||||
this._addError(element, `Duplicated translations for msg ${id}`);
|
this._addError(element, `Duplicated translations for msg ${id}`);
|
||||||
} else {
|
} else {
|
||||||
const innerTextStart = element.startSourceSpan!.end.offset;
|
const innerTextStart = element.startSourceSpan.end.offset;
|
||||||
const innerTextEnd = element.endSourceSpan!.start.offset;
|
const innerTextEnd = element.endSourceSpan!.start.offset;
|
||||||
const content = element.startSourceSpan!.start.file.content;
|
const content = element.startSourceSpan.start.file.content;
|
||||||
const innerText = content.slice(innerTextStart!, innerTextEnd!);
|
const innerText = content.slice(innerTextStart!, innerTextEnd!);
|
||||||
this._msgIdToHtml[id] = innerText;
|
this._msgIdToHtml[id] = innerText;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ class XtbParser implements ml.Visitor {
|
||||||
visitExpansionCase(expansionCase: ml.ExpansionCase, context: any): any {}
|
visitExpansionCase(expansionCase: ml.ExpansionCase, context: any): any {}
|
||||||
|
|
||||||
private _addError(node: ml.Node, message: string): void {
|
private _addError(node: ml.Node, message: string): void {
|
||||||
this._errors.push(new I18nError(node.sourceSpan!, message));
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ class XmlToI18n implements ml.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
visitText(text: ml.Text, context: any) {
|
visitText(text: ml.Text, context: any) {
|
||||||
return new i18n.Text(text.value, text.sourceSpan!);
|
return new i18n.Text(text.value, text.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitExpansion(icu: ml.Expansion, context: any) {
|
visitExpansion(icu: ml.Expansion, context: any) {
|
||||||
|
@ -203,7 +203,7 @@ class XmlToI18n implements ml.Visitor {
|
||||||
if (el.name === _PLACEHOLDER_TAG) {
|
if (el.name === _PLACEHOLDER_TAG) {
|
||||||
const nameAttr = el.attrs.find((attr) => attr.name === 'name');
|
const nameAttr = el.attrs.find((attr) => attr.name === 'name');
|
||||||
if (nameAttr) {
|
if (nameAttr) {
|
||||||
return new i18n.Placeholder('', nameAttr.value, el.sourceSpan!);
|
return new i18n.Placeholder('', nameAttr.value, el.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "name" attribute`);
|
this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "name" attribute`);
|
||||||
|
@ -218,6 +218,6 @@ class XmlToI18n implements ml.Visitor {
|
||||||
visitAttribute(attribute: ml.Attribute, context: any) {}
|
visitAttribute(attribute: ml.Attribute, context: any) {}
|
||||||
|
|
||||||
private _addError(node: ml.Node, message: string): void {
|
private _addError(node: ml.Node, message: string): void {
|
||||||
this._errors.push(new I18nError(node.sourceSpan!, message));
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ export class Attribute extends NodeWithI18n {
|
||||||
export class Element extends NodeWithI18n {
|
export class Element extends NodeWithI18n {
|
||||||
constructor(
|
constructor(
|
||||||
public name: string, public attrs: Attribute[], public children: Node[],
|
public name: string, public attrs: Attribute[], public children: Node[],
|
||||||
sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan|null = null,
|
sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
|
||||||
public endSourceSpan: ParseSourceSpan|null = null, i18n?: I18nMeta) {
|
public endSourceSpan: ParseSourceSpan|null = null, i18n?: I18nMeta) {
|
||||||
super(sourceSpan, i18n);
|
super(sourceSpan, i18n);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,13 +79,8 @@ export class Element implements Node {
|
||||||
constructor(
|
constructor(
|
||||||
public name: string, public attributes: TextAttribute[], public inputs: BoundAttribute[],
|
public name: string, public attributes: TextAttribute[], public inputs: BoundAttribute[],
|
||||||
public outputs: BoundEvent[], public children: Node[], public references: Reference[],
|
public outputs: BoundEvent[], public children: Node[], public references: Reference[],
|
||||||
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan|null,
|
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
|
||||||
public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nMeta) {
|
public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nMeta) {}
|
||||||
// If the element is empty then the source span should include any closing tag
|
|
||||||
if (children.length === 0 && startSourceSpan && endSourceSpan) {
|
|
||||||
this.sourceSpan = new ParseSourceSpan(sourceSpan.start, endSourceSpan.end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
visit<Result>(visitor: Visitor<Result>): Result {
|
visit<Result>(visitor: Visitor<Result>): Result {
|
||||||
return visitor.visitElement(this);
|
return visitor.visitElement(this);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +91,7 @@ export class Template implements Node {
|
||||||
public tagName: string, public attributes: TextAttribute[], public inputs: BoundAttribute[],
|
public tagName: string, public attributes: TextAttribute[], public inputs: BoundAttribute[],
|
||||||
public outputs: BoundEvent[], public templateAttrs: (BoundAttribute|TextAttribute)[],
|
public outputs: BoundEvent[], public templateAttrs: (BoundAttribute|TextAttribute)[],
|
||||||
public children: Node[], public references: Reference[], public variables: Variable[],
|
public children: Node[], public references: Reference[], public variables: Variable[],
|
||||||
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan|null,
|
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
|
||||||
public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nMeta) {}
|
public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nMeta) {}
|
||||||
visit<Result>(visitor: Visitor<Result>): Result {
|
visit<Result>(visitor: Visitor<Result>): Result {
|
||||||
return visitor.visitTemplate(this);
|
return visitor.visitTemplate(this);
|
||||||
|
|
|
@ -244,9 +244,9 @@ class TemplateParseVisitor implements html.Visitor {
|
||||||
visitText(text: html.Text, parent: ElementContext): any {
|
visitText(text: html.Text, parent: ElementContext): any {
|
||||||
const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR())!;
|
const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR())!;
|
||||||
const valueNoNgsp = replaceNgsp(text.value);
|
const valueNoNgsp = replaceNgsp(text.value);
|
||||||
const expr = this._bindingParser.parseInterpolation(valueNoNgsp, text.sourceSpan!);
|
const expr = this._bindingParser.parseInterpolation(valueNoNgsp, text.sourceSpan);
|
||||||
return expr ? new t.BoundTextAst(expr, ngContentIndex, text.sourceSpan!) :
|
return expr ? new t.BoundTextAst(expr, ngContentIndex, text.sourceSpan) :
|
||||||
new t.TextAst(valueNoNgsp, ngContentIndex, text.sourceSpan!);
|
new t.TextAst(valueNoNgsp, ngContentIndex, text.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitAttribute(attribute: html.Attribute, context: any): any {
|
visitAttribute(attribute: html.Attribute, context: any): any {
|
||||||
|
@ -335,14 +335,14 @@ class TemplateParseVisitor implements html.Visitor {
|
||||||
const boundDirectivePropNames = new Set<string>();
|
const boundDirectivePropNames = new Set<string>();
|
||||||
const directiveAsts = this._createDirectiveAsts(
|
const directiveAsts = this._createDirectiveAsts(
|
||||||
isTemplateElement, element.name, directiveMetas, elementOrDirectiveProps,
|
isTemplateElement, element.name, directiveMetas, elementOrDirectiveProps,
|
||||||
elementOrDirectiveRefs, element.sourceSpan!, references, boundDirectivePropNames);
|
elementOrDirectiveRefs, element.sourceSpan, references, boundDirectivePropNames);
|
||||||
const elementProps: t.BoundElementPropertyAst[] = this._createElementPropertyAsts(
|
const elementProps: t.BoundElementPropertyAst[] = this._createElementPropertyAsts(
|
||||||
element.name, elementOrDirectiveProps, boundDirectivePropNames);
|
element.name, elementOrDirectiveProps, boundDirectivePropNames);
|
||||||
const isViewRoot = parent.isTemplateElement || hasInlineTemplates;
|
const isViewRoot = parent.isTemplateElement || hasInlineTemplates;
|
||||||
|
|
||||||
const providerContext = new ProviderElementContext(
|
const providerContext = new ProviderElementContext(
|
||||||
this.providerViewContext, parent.providerContext!, isViewRoot, directiveAsts, attrs,
|
this.providerViewContext, parent.providerContext!, isViewRoot, directiveAsts, attrs,
|
||||||
references, isTemplateElement, queryStartIndex, element.sourceSpan!);
|
references, isTemplateElement, queryStartIndex, element.sourceSpan);
|
||||||
|
|
||||||
const children: t.TemplateAst[] = html.visitAll(
|
const children: t.TemplateAst[] = html.visitAll(
|
||||||
preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
|
preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
|
||||||
|
@ -360,26 +360,26 @@ class TemplateParseVisitor implements html.Visitor {
|
||||||
if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
|
if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
|
||||||
// `<ng-content>` element
|
// `<ng-content>` element
|
||||||
if (element.children && !element.children.every(_isEmptyTextNode)) {
|
if (element.children && !element.children.every(_isEmptyTextNode)) {
|
||||||
this._reportError(`<ng-content> element cannot have content.`, element.sourceSpan!);
|
this._reportError(`<ng-content> element cannot have content.`, element.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedElement = new t.NgContentAst(
|
parsedElement = new t.NgContentAst(
|
||||||
this.ngContentCount++, hasInlineTemplates ? null! : ngContentIndex, element.sourceSpan!);
|
this.ngContentCount++, hasInlineTemplates ? null! : ngContentIndex, element.sourceSpan);
|
||||||
} else if (isTemplateElement) {
|
} else if (isTemplateElement) {
|
||||||
// `<ng-template>` element
|
// `<ng-template>` element
|
||||||
this._assertAllEventsPublishedByDirectives(directiveAsts, events);
|
this._assertAllEventsPublishedByDirectives(directiveAsts, events);
|
||||||
this._assertNoComponentsNorElementBindingsOnTemplate(
|
this._assertNoComponentsNorElementBindingsOnTemplate(
|
||||||
directiveAsts, elementProps, element.sourceSpan!);
|
directiveAsts, elementProps, element.sourceSpan);
|
||||||
|
|
||||||
parsedElement = new t.EmbeddedTemplateAst(
|
parsedElement = new t.EmbeddedTemplateAst(
|
||||||
attrs, events, references, elementVars, providerContext.transformedDirectiveAsts,
|
attrs, events, references, elementVars, providerContext.transformedDirectiveAsts,
|
||||||
providerContext.transformProviders, providerContext.transformedHasViewContainer,
|
providerContext.transformProviders, providerContext.transformedHasViewContainer,
|
||||||
providerContext.queryMatches, children, hasInlineTemplates ? null! : ngContentIndex,
|
providerContext.queryMatches, children, hasInlineTemplates ? null! : ngContentIndex,
|
||||||
element.sourceSpan!);
|
element.sourceSpan);
|
||||||
} else {
|
} else {
|
||||||
// element other than `<ng-content>` and `<ng-template>`
|
// element other than `<ng-content>` and `<ng-template>`
|
||||||
this._assertElementExists(matchElement, element);
|
this._assertElementExists(matchElement, element);
|
||||||
this._assertOnlyOneComponent(directiveAsts, element.sourceSpan!);
|
this._assertOnlyOneComponent(directiveAsts, element.sourceSpan);
|
||||||
|
|
||||||
const ngContentIndex =
|
const ngContentIndex =
|
||||||
hasInlineTemplates ? null : parent.findNgContentIndex(projectionSelector);
|
hasInlineTemplates ? null : parent.findNgContentIndex(projectionSelector);
|
||||||
|
@ -397,22 +397,22 @@ class TemplateParseVisitor implements html.Visitor {
|
||||||
const {directives} = this._parseDirectives(this.selectorMatcher, templateSelector);
|
const {directives} = this._parseDirectives(this.selectorMatcher, templateSelector);
|
||||||
const templateBoundDirectivePropNames = new Set<string>();
|
const templateBoundDirectivePropNames = new Set<string>();
|
||||||
const templateDirectiveAsts = this._createDirectiveAsts(
|
const templateDirectiveAsts = this._createDirectiveAsts(
|
||||||
true, elName, directives, templateElementOrDirectiveProps, [], element.sourceSpan!, [],
|
true, elName, directives, templateElementOrDirectiveProps, [], element.sourceSpan, [],
|
||||||
templateBoundDirectivePropNames);
|
templateBoundDirectivePropNames);
|
||||||
const templateElementProps: t.BoundElementPropertyAst[] = this._createElementPropertyAsts(
|
const templateElementProps: t.BoundElementPropertyAst[] = this._createElementPropertyAsts(
|
||||||
elName, templateElementOrDirectiveProps, templateBoundDirectivePropNames);
|
elName, templateElementOrDirectiveProps, templateBoundDirectivePropNames);
|
||||||
this._assertNoComponentsNorElementBindingsOnTemplate(
|
this._assertNoComponentsNorElementBindingsOnTemplate(
|
||||||
templateDirectiveAsts, templateElementProps, element.sourceSpan!);
|
templateDirectiveAsts, templateElementProps, element.sourceSpan);
|
||||||
const templateProviderContext = new ProviderElementContext(
|
const templateProviderContext = new ProviderElementContext(
|
||||||
this.providerViewContext, parent.providerContext!, parent.isTemplateElement,
|
this.providerViewContext, parent.providerContext!, parent.isTemplateElement,
|
||||||
templateDirectiveAsts, [], [], true, templateQueryStartIndex, element.sourceSpan!);
|
templateDirectiveAsts, [], [], true, templateQueryStartIndex, element.sourceSpan);
|
||||||
templateProviderContext.afterElement();
|
templateProviderContext.afterElement();
|
||||||
|
|
||||||
parsedElement = new t.EmbeddedTemplateAst(
|
parsedElement = new t.EmbeddedTemplateAst(
|
||||||
[], [], [], templateElementVars, templateProviderContext.transformedDirectiveAsts,
|
[], [], [], templateElementVars, templateProviderContext.transformedDirectiveAsts,
|
||||||
templateProviderContext.transformProviders,
|
templateProviderContext.transformProviders,
|
||||||
templateProviderContext.transformedHasViewContainer, templateProviderContext.queryMatches,
|
templateProviderContext.transformedHasViewContainer, templateProviderContext.queryMatches,
|
||||||
[parsedElement], ngContentIndex, element.sourceSpan!);
|
[parsedElement], ngContentIndex, element.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsedElement;
|
return parsedElement;
|
||||||
|
@ -707,7 +707,7 @@ class TemplateParseVisitor implements html.Visitor {
|
||||||
errorMsg +=
|
errorMsg +=
|
||||||
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`;
|
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`;
|
||||||
}
|
}
|
||||||
this._reportError(errorMsg, element.sourceSpan!);
|
this._reportError(errorMsg, element.sourceSpan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,7 +815,7 @@ class NonBindableVisitor implements html.Visitor {
|
||||||
|
|
||||||
visitText(text: html.Text, parent: ElementContext): t.TextAst {
|
visitText(text: html.Text, parent: ElementContext): t.TextAst {
|
||||||
const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR())!;
|
const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR())!;
|
||||||
return new t.TextAst(text.value, ngContentIndex, text.sourceSpan!);
|
return new t.TextAst(text.value, ngContentIndex, text.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitExpansion(expansion: html.Expansion, context: any): any {
|
visitExpansion(expansion: html.Expansion, context: any): any {
|
||||||
|
|
|
@ -42,7 +42,7 @@ class _Humanizer implements html.Visitor {
|
||||||
visitElement(element: html.Element, context: any): any {
|
visitElement(element: html.Element, context: any): any {
|
||||||
const res = this._appendContext(element, [html.Element, element.name, this.elDepth++]);
|
const res = this._appendContext(element, [html.Element, element.name, this.elDepth++]);
|
||||||
if (this.includeSourceSpan) {
|
if (this.includeSourceSpan) {
|
||||||
res.push(element.startSourceSpan?.toString() ?? null);
|
res.push(element.startSourceSpan.toString() ?? null);
|
||||||
res.push(element.endSourceSpan?.toString() ?? null);
|
res.push(element.endSourceSpan?.toString() ?? null);
|
||||||
}
|
}
|
||||||
this.result.push(res);
|
this.result.push(res);
|
||||||
|
@ -82,7 +82,7 @@ class _Humanizer implements html.Visitor {
|
||||||
|
|
||||||
private _appendContext(ast: html.Node, input: any[]): any[] {
|
private _appendContext(ast: html.Node, input: any[]): any[] {
|
||||||
if (!this.includeSourceSpan) return input;
|
if (!this.includeSourceSpan) return input;
|
||||||
input.push(ast.sourceSpan!.toString());
|
input.push(ast.sourceSpan.toString());
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -667,8 +667,8 @@ import {humanizeDom, humanizeDomSourceSpans, humanizeLineColumn} from './ast_spe
|
||||||
it('should set the start and end source spans', () => {
|
it('should set the start and end source spans', () => {
|
||||||
const node = <html.Element>parser.parse('<div>a</div>', 'TestComp').rootNodes[0];
|
const node = <html.Element>parser.parse('<div>a</div>', 'TestComp').rootNodes[0];
|
||||||
|
|
||||||
expect(node.startSourceSpan!.start.offset).toEqual(0);
|
expect(node.startSourceSpan.start.offset).toEqual(0);
|
||||||
expect(node.startSourceSpan!.end.offset).toEqual(5);
|
expect(node.startSourceSpan.end.offset).toEqual(5);
|
||||||
|
|
||||||
expect(node.endSourceSpan!.start.offset).toEqual(6);
|
expect(node.endSourceSpan!.start.offset).toEqual(6);
|
||||||
expect(node.endSourceSpan!.end.offset).toEqual(12);
|
expect(node.endSourceSpan!.end.offset).toEqual(12);
|
||||||
|
|
|
@ -56,10 +56,10 @@ import {humanizeNodes} from './ast_spec_utils';
|
||||||
const nodes = expand(`{messages.length, plural,=0 {<b>bold</b>}}`).nodes;
|
const nodes = expand(`{messages.length, plural,=0 {<b>bold</b>}}`).nodes;
|
||||||
|
|
||||||
const container: html.Element = <html.Element>nodes[0];
|
const container: html.Element = <html.Element>nodes[0];
|
||||||
expect(container.sourceSpan!.start.col).toEqual(0);
|
expect(container.sourceSpan.start.col).toEqual(0);
|
||||||
expect(container.sourceSpan!.end.col).toEqual(42);
|
expect(container.sourceSpan.end.col).toEqual(42);
|
||||||
expect(container.startSourceSpan!.start.col).toEqual(0);
|
expect(container.startSourceSpan.start.col).toEqual(0);
|
||||||
expect(container.startSourceSpan!.end.col).toEqual(42);
|
expect(container.startSourceSpan.end.col).toEqual(42);
|
||||||
expect(container.endSourceSpan!.start.col).toEqual(0);
|
expect(container.endSourceSpan!.start.col).toEqual(0);
|
||||||
expect(container.endSourceSpan!.end.col).toEqual(42);
|
expect(container.endSourceSpan!.end.col).toEqual(42);
|
||||||
|
|
||||||
|
@ -68,15 +68,15 @@ import {humanizeNodes} from './ast_spec_utils';
|
||||||
expect(switchExp.sourceSpan.end.col).toEqual(16);
|
expect(switchExp.sourceSpan.end.col).toEqual(16);
|
||||||
|
|
||||||
const template: html.Element = <html.Element>container.children[0];
|
const template: html.Element = <html.Element>container.children[0];
|
||||||
expect(template.sourceSpan!.start.col).toEqual(25);
|
expect(template.sourceSpan.start.col).toEqual(25);
|
||||||
expect(template.sourceSpan!.end.col).toEqual(41);
|
expect(template.sourceSpan.end.col).toEqual(41);
|
||||||
|
|
||||||
const switchCheck = template.attrs[0];
|
const switchCheck = template.attrs[0];
|
||||||
expect(switchCheck.sourceSpan.start.col).toEqual(25);
|
expect(switchCheck.sourceSpan.start.col).toEqual(25);
|
||||||
expect(switchCheck.sourceSpan.end.col).toEqual(28);
|
expect(switchCheck.sourceSpan.end.col).toEqual(28);
|
||||||
|
|
||||||
const b: html.Element = <html.Element>template.children[0];
|
const b: html.Element = <html.Element>template.children[0];
|
||||||
expect(b.sourceSpan!.start.col).toEqual(29);
|
expect(b.sourceSpan.start.col).toEqual(29);
|
||||||
expect(b.endSourceSpan!.end.col).toEqual(40);
|
expect(b.endSourceSpan!.end.col).toEqual(40);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ class TemplateHumanizer implements TemplateAstVisitor {
|
||||||
|
|
||||||
private _appendSourceSpan(ast: TemplateAst, input: any[]): any[] {
|
private _appendSourceSpan(ast: TemplateAst, input: any[]): any[] {
|
||||||
if (!this.includeSourceSpan) return input;
|
if (!this.includeSourceSpan) return input;
|
||||||
input.push(ast.sourceSpan!.toString());
|
input.push(ast.sourceSpan.toString());
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ function getBoundedWordSpan(
|
||||||
// The HTML tag may include `-` (e.g. `app-root`),
|
// The HTML tag may include `-` (e.g. `app-root`),
|
||||||
// so use the HtmlAst to get the span before ayazhafiz refactor the code.
|
// so use the HtmlAst to get the span before ayazhafiz refactor the code.
|
||||||
return {
|
return {
|
||||||
start: templateInfo.template.span.start + ast.startSourceSpan!.start.offset + 1,
|
start: templateInfo.template.span.start + ast.startSourceSpan.start.offset + 1,
|
||||||
length: ast.name.length
|
length: ast.name.length
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ export function parseInnerRange(element: Element): ParseTreeResult {
|
||||||
* @param element The element whose inner range we want to compute.
|
* @param element The element whose inner range we want to compute.
|
||||||
*/
|
*/
|
||||||
function getInnerRange(element: Element): LexerRange {
|
function getInnerRange(element: Element): LexerRange {
|
||||||
const start = element.startSourceSpan!.end;
|
const start = element.startSourceSpan.end;
|
||||||
const end = element.endSourceSpan!.start;
|
const end = element.endSourceSpan!.start;
|
||||||
return {
|
return {
|
||||||
startPos: start.offset,
|
startPos: start.offset,
|
||||||
|
|
Loading…
Reference in New Issue