diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts index 3a616ea5fe..9de9616075 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {compileComponentFromMetadata, ConstantPool, CssSelector, DEFAULT_INTERPOLATION_CONFIG, DomElementSchemaRegistry, Expression, ExternalExpr, Identifiers, InterpolationConfig, LexerRange, makeBindingParser, ParseError, ParseSourceFile, parseTemplate, ParseTemplateOptions, R3ComponentMetadata, R3FactoryTarget, R3TargetBinder, SchemaMetadata, SelectorMatcher, Statement, TmplAstNode, WrappedNodeExpr} from '@angular/compiler'; +import {compileComponentFromMetadata, ConstantPool, CssSelector, DEFAULT_INTERPOLATION_CONFIG, DomElementSchemaRegistry, Expression, ExternalExpr, Identifiers, InterpolationConfig, LexerRange, makeBindingParser, ParsedTemplate, ParseSourceFile, parseTemplate, R3ComponentMetadata, R3FactoryTarget, R3TargetBinder, SchemaMetadata, SelectorMatcher, Statement, TmplAstNode, WrappedNodeExpr} from '@angular/compiler'; import * as ts from 'typescript'; import {CycleAnalyzer} from '../../cycles'; @@ -31,7 +31,7 @@ import {createValueHasWrongTypeError, getDirectiveDiagnostics, getProviderDiagno import {extractDirectiveMetadata, parseFieldArrayValue} from './directive'; import {compileNgFactoryDefField} from './factory'; import {generateSetClassMetadataCall} from './metadata'; -import {findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, makeDuplicateDeclarationError, readBaseClass, resolveProvidersRequiringFactory, unwrapExpression, wrapFunctionExpressionsInParens} from './util'; +import {findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, readBaseClass, resolveProvidersRequiringFactory, unwrapExpression, wrapFunctionExpressionsInParens} from './util'; const EMPTY_MAP = new Map(); const EMPTY_ARRAY: any[] = []; @@ -260,7 +260,7 @@ export class ComponentDecoratorHandler implements let diagnostics: ts.Diagnostic[]|undefined = undefined; - if (template.errors !== undefined) { + if (template.errors !== null) { // If there are any template parsing errors, convert them to `ts.Diagnostic`s for display. const id = getTemplateId(node); diagnostics = template.errors.map(error => { @@ -336,11 +336,11 @@ export class ComponentDecoratorHandler implements meta: { ...metadata, template: { - nodes: template.emitNodes, + nodes: template.nodes, ngContentSelectors: template.ngContentSelectors, }, encapsulation, - interpolation: template.interpolation, + interpolation: template.interpolationConfig ?? DEFAULT_INTERPOLATION_CONFIG, styles: styles || [], // These will be replaced during the compilation step, after all `NgModule`s have been @@ -772,7 +772,7 @@ export class ComponentDecoratorHandler implements private _parseTemplate( component: Map, templateStr: string, templateUrl: string, - templateRange: LexerRange|undefined, escapedString: boolean): ParsedTemplate { + templateRange: LexerRange|undefined, escapedString: boolean): ParsedComponentTemplate { let preserveWhitespaces: boolean = this.defaultPreserveWhitespaces; if (component.has('preserveWhitespaces')) { const expr = component.get('preserveWhitespaces')!; @@ -783,7 +783,7 @@ export class ComponentDecoratorHandler implements preserveWhitespaces = value; } - let interpolation: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG; + let interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; if (component.has('interpolation')) { const expr = component.get('interpolation')!; const value = this.evaluator.evaluate(expr); @@ -792,21 +792,20 @@ export class ComponentDecoratorHandler implements throw createValueHasWrongTypeError( expr, value, 'interpolation must be an array with 2 elements of string type'); } - interpolation = InterpolationConfig.fromArray(value as [string, string]); + interpolationConfig = InterpolationConfig.fromArray(value as [string, string]); } // We always normalize line endings if the template has been escaped (i.e. is inline). const i18nNormalizeLineEndingsInICUs = escapedString || this.i18nNormalizeLineEndingsInICUs; - const {errors, nodes: emitNodes, styleUrls, styles, ngContentSelectors} = - parseTemplate(templateStr, templateUrl, { - preserveWhitespaces, - interpolationConfig: interpolation, - range: templateRange, - escapedString, - enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat, - i18nNormalizeLineEndingsInICUs, - }); + const parsedTemplate = parseTemplate(templateStr, templateUrl, { + preserveWhitespaces, + interpolationConfig, + range: templateRange, + escapedString, + enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat, + i18nNormalizeLineEndingsInICUs, + }); // Unfortunately, the primary parse of the template above may not contain accurate source map // information. If used directly, it would result in incorrect code locations in template @@ -823,7 +822,7 @@ export class ComponentDecoratorHandler implements const {nodes: diagNodes} = parseTemplate(templateStr, templateUrl, { preserveWhitespaces: true, - interpolationConfig: interpolation, + interpolationConfig, range: templateRange, escapedString, enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat, @@ -832,13 +831,8 @@ export class ComponentDecoratorHandler implements }); return { - interpolation, - emitNodes, + ...parsedTemplate, diagNodes, - styleUrls, - styles, - ngContentSelectors, - errors, template: templateStr, templateUrl, isInline: component.has('template'), @@ -905,12 +899,7 @@ function sourceMapUrl(resourceUrl: string): string { * This contains the actual parsed template as well as any metadata collected during its parsing, * some of which might be useful for re-parsing the template with different options. */ -export interface ParsedTemplate { - /** - * The `InterpolationConfig` specified by the user. - */ - interpolation: InterpolationConfig; - +export interface ParsedComponentTemplate extends ParsedTemplate { /** * A full path to the file which contains the template. * @@ -920,22 +909,10 @@ export interface ParsedTemplate { templateUrl: string; /** - * The string contents of the template. - * - * This is the "logical" template string, after expansion of any escaped characters (for inline - * templates). This may differ from the actual template bytes as they appear in the .ts file. + * True if the original template was stored inline; + * False if the template was in an external file. */ - template: string; - - /** - * Any errors from parsing the template the first time. - */ - errors?: ParseError[]|undefined; - - /** - * The template AST, parsed according to the user's specifications. - */ - emitNodes: TmplAstNode[]; + isInline: boolean; /** * The template AST, parsed in a manner which preserves source map information for diagnostics. @@ -944,36 +921,12 @@ export interface ParsedTemplate { */ diagNodes: TmplAstNode[]; - /** - * - */ - - /** - * Any styleUrls extracted from the metadata. - */ - styleUrls: string[]; - - /** - * Any inline styles extracted from the metadata. - */ - styles: string[]; - - /** - * Any ng-content selectors extracted from the template. - */ - ngContentSelectors: string[]; - - /** - * Whether the template was inline. - */ - isInline: boolean; - /** * The `ParseSourceFile` for the template. */ file: ParseSourceFile; } -export interface ParsedTemplateWithSource extends ParsedTemplate { +export interface ParsedTemplateWithSource extends ParsedComponentTemplate { sourceMapping: TemplateSourceMapping; } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts index ac29846329..db8ef3487a 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts @@ -79,7 +79,7 @@ export class TemplateTypeCheckerImpl implements TemplateTypeChecker { leadingTriviaChars: [], }); - if (errors !== undefined) { + if (errors !== null) { return {nodes, errors}; } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/test_utils.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/test_utils.ts index 248f5ea352..d87a8141e3 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/test_utils.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/test_utils.ts @@ -354,7 +354,7 @@ export function setup(targets: TypeCheckingTarget[], overrides: { const templateUrl = `${className}.html`; const templateFile = new ParseSourceFile(template, templateUrl); const {nodes, errors} = parseTemplate(template, templateUrl); - if (errors !== undefined) { + if (errors !== null) { throw new Error('Template parse errors: \n' + errors.join('\n')); } diff --git a/packages/compiler/src/compiler.ts b/packages/compiler/src/compiler.ts index ca5cd12c06..06405307ad 100644 --- a/packages/compiler/src/compiler.ts +++ b/packages/compiler/src/compiler.ts @@ -99,7 +99,7 @@ export {Identifiers as R3Identifiers} from './render3/r3_identifiers'; export {R3DependencyMetadata, R3ResolvedDependencyType, compileFactoryFunction, R3FactoryMetadata, R3FactoryTarget} from './render3/r3_factory'; export {compileInjector, compileNgModule, R3InjectorMetadata, R3NgModuleMetadata} from './render3/r3_module_compiler'; export {compilePipeFromMetadata, R3PipeMetadata} from './render3/r3_pipe_compiler'; -export {makeBindingParser, parseTemplate, ParseTemplateOptions} from './render3/view/template'; +export {makeBindingParser, ParsedTemplate, parseTemplate, ParseTemplateOptions} from './render3/view/template'; export {R3Reference} from './render3/util'; export {compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings, ParsedHostBindings, verifyHostBindings} from './render3/view/compiler'; export {publishFacade} from './jit_compiler_facade'; diff --git a/packages/compiler/src/jit_compiler_facade.ts b/packages/compiler/src/jit_compiler_facade.ts index b3c92ac387..540c0a3e22 100644 --- a/packages/compiler/src/jit_compiler_facade.ts +++ b/packages/compiler/src/jit_compiler_facade.ts @@ -129,7 +129,7 @@ export class CompilerFacadeImpl implements CompilerFacade { const template = parseTemplate( facade.template, sourceMapUrl, {preserveWhitespaces: facade.preserveWhitespaces, interpolationConfig}); - if (template.errors !== undefined) { + if (template.errors !== null) { const errors = template.errors.map(err => err.toString()).join(', '); throw new Error(`Errors during JIT compilation of template for ${facade.name}: ${errors}`); } diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index b0599fc717..3dea5078b0 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -2025,13 +2025,7 @@ export interface ParseTemplateOptions { * @param options options to modify how the template is parsed */ export function parseTemplate( - template: string, templateUrl: string, options: ParseTemplateOptions = {}): { - errors?: ParseError[], - nodes: t.Node[], - styleUrls: string[], - styles: string[], - ngContentSelectors: string[] -} { + template: string, templateUrl: string, options: ParseTemplateOptions = {}): ParsedTemplate { const {interpolationConfig, preserveWhitespaces, enableI18nLegacyMessageIdFormat} = options; const bindingParser = makeBindingParser(interpolationConfig); const htmlParser = new HtmlParser(); @@ -2041,6 +2035,9 @@ export function parseTemplate( if (parseResult.errors && parseResult.errors.length > 0) { return { + interpolationConfig, + preserveWhitespaces, + template, errors: parseResult.errors, nodes: [], styleUrls: [], @@ -2076,10 +2073,28 @@ export function parseTemplate( const {nodes, errors, styleUrls, styles, ngContentSelectors} = htmlAstToRender3Ast(rootNodes, bindingParser); if (errors && errors.length > 0) { - return {errors, nodes: [], styleUrls: [], styles: [], ngContentSelectors: []}; + return { + interpolationConfig, + preserveWhitespaces, + template, + errors, + nodes: [], + styleUrls: [], + styles: [], + ngContentSelectors: [] + }; } - return {nodes, styleUrls, styles, ngContentSelectors}; + return { + interpolationConfig, + preserveWhitespaces, + errors: null, + template, + nodes, + styleUrls, + styles, + ngContentSelectors + }; } const elementRegistry = new DomElementSchemaRegistry(); @@ -2196,3 +2211,54 @@ function createClosureModeGuard(): o.BinaryOperatorExpr { .notIdentical(o.literal('undefined', o.STRING_TYPE)) .and(o.variable(NG_I18N_CLOSURE_MODE)); } + +/** + * Information about the template which was extracted during parsing. + * + * This contains the actual parsed template as well as any metadata collected during its parsing, + * some of which might be useful for re-parsing the template with different options. + */ +export interface ParsedTemplate { + /** + * Include whitespace nodes in the parsed output. + */ + preserveWhitespaces?: boolean; + + /** + * How to parse interpolation markers. + */ + interpolationConfig?: InterpolationConfig; + + /** + * The string contents of the template. + * + * This is the "logical" template string, after expansion of any escaped characters (for inline + * templates). This may differ from the actual template bytes as they appear in the .ts file. + */ + template: string; + + /** + * Any errors from parsing the template the first time. + */ + errors: ParseError[]|null; + + /** + * The template AST, parsed from the template. + */ + nodes: t.Node[]; + + /** + * Any styleUrls extracted from the metadata. + */ + styleUrls: string[]; + + /** + * Any inline styles extracted from the metadata. + */ + styles: string[]; + + /** + * Any ng-content selectors extracted from the template. + */ + ngContentSelectors: string[]; +} diff --git a/packages/language-service/ivy/test/hybrid_visitor_spec.ts b/packages/language-service/ivy/test/hybrid_visitor_spec.ts index 30eb4daf73..43820c7e45 100644 --- a/packages/language-service/ivy/test/hybrid_visitor_spec.ts +++ b/packages/language-service/ivy/test/hybrid_visitor_spec.ts @@ -14,7 +14,7 @@ import {findNodeAtPosition, isExpressionNode, isTemplateNode} from '../hybrid_vi interface ParseResult { nodes: t.Node[]; - errors?: ParseError[]; + errors: ParseError[]|null; position: number; } @@ -34,7 +34,7 @@ function parse(template: string): ParseResult { describe('findNodeAtPosition for template AST', () => { it('should locate element in opening tag', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Element); @@ -42,7 +42,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate element in closing tag', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Element); @@ -50,7 +50,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate element when cursor is at the beginning', () => { const {errors, nodes, position} = parse(`<¦div>
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Element); @@ -58,7 +58,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate element when cursor is at the end', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Element); @@ -66,7 +66,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate attribute key', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.TextAttribute); @@ -74,7 +74,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate attribute value', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); // TODO: Note that we do not have the ability to detect the RHS (yet) @@ -83,7 +83,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate bound attribute key', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.BoundAttribute); @@ -91,7 +91,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate bound attribute value', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -99,7 +99,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate bound event key', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.BoundEvent); @@ -107,7 +107,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate bound event value', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.MethodCall); @@ -115,7 +115,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate element children', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Element); @@ -124,7 +124,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate element reference', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Reference); @@ -132,7 +132,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template text attribute', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.TextAttribute); @@ -140,7 +140,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template bound attribute key', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.BoundAttribute); @@ -148,7 +148,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template bound attribute value', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -156,7 +156,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template bound attribute key in two-way binding', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.BoundAttribute); @@ -165,7 +165,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template bound attribute value in two-way binding', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -174,7 +174,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template bound event key', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.BoundEvent); @@ -182,14 +182,14 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template bound event value', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(node).toBeInstanceOf(e.MethodCall); }); it('should locate template attribute key', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.TextAttribute); @@ -197,7 +197,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template attribute value', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); // TODO: Note that we do not have the ability to detect the RHS (yet) @@ -206,7 +206,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template reference key via the # notation', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Reference); @@ -215,7 +215,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template reference key via the ref- notation', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Reference); @@ -224,7 +224,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template reference value via the # notation', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Reference); @@ -234,7 +234,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template reference value via the ref- notation', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Reference); @@ -244,7 +244,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template variable key', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Variable); @@ -252,7 +252,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template variable value', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Variable); @@ -260,7 +260,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate template children', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Element); @@ -268,7 +268,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate ng-content', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Content); @@ -276,7 +276,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate ng-content attribute key', () => { const {errors, nodes, position} = parse(''); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.TextAttribute); @@ -284,7 +284,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate ng-content attribute value', () => { const {errors, nodes, position} = parse(''); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); // TODO: Note that we do not have the ability to detect the RHS (yet) expect(isTemplateNode(node!)).toBe(true); @@ -293,7 +293,7 @@ describe('findNodeAtPosition for template AST', () => { it('should not locate implicit receiver', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -301,7 +301,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate bound attribute key in two-way binding', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.BoundAttribute); @@ -310,7 +310,7 @@ describe('findNodeAtPosition for template AST', () => { it('should locate bound attribute value in two-way binding', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -321,7 +321,7 @@ describe('findNodeAtPosition for template AST', () => { describe('findNodeAtPosition for expression AST', () => { it('should not locate implicit receiver', () => { const {errors, nodes, position} = parse(`{{ ¦title }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -330,7 +330,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate property read', () => { const {errors, nodes, position} = parse(`{{ ti¦tle }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -339,7 +339,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate safe property read', () => { const {errors, nodes, position} = parse(`{{ foo?¦.bar }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.SafePropertyRead); @@ -348,7 +348,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate keyed read', () => { const {errors, nodes, position} = parse(`{{ foo['bar']¦ }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.KeyedRead); @@ -356,7 +356,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate property write', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyWrite); @@ -364,7 +364,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate keyed write', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.KeyedWrite); @@ -372,7 +372,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate binary', () => { const {errors, nodes, position} = parse(`{{ 1 +¦ 2 }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.Binary); @@ -380,7 +380,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate binding pipe with an identifier', () => { const {errors, nodes, position} = parse(`{{ title | p¦ }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.BindingPipe); @@ -391,7 +391,7 @@ describe('findNodeAtPosition for expression AST', () => { // TODO: We are not able to locate pipe if identifier is missing because the // parser throws an error. This case is important for autocomplete. // const {errors, nodes, position} = parse(`{{ title | ¦ }}`); - // expect(errors).toBeUndefined(); + // expect(errors).toBe(null); // const node = findNodeAtPosition(nodes, position); // expect(isExpressionNode(node!)).toBe(true); // expect(node).toBeInstanceOf(e.BindingPipe); @@ -399,7 +399,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate method call', () => { const {errors, nodes, position} = parse(`{{ title.toString(¦) }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.MethodCall); @@ -407,7 +407,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate safe method call', () => { const {errors, nodes, position} = parse(`{{ title?.toString(¦) }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.SafeMethodCall); @@ -415,7 +415,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate literal primitive in interpolation', () => { const {errors, nodes, position} = parse(`{{ title.indexOf('t¦') }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.LiteralPrimitive); @@ -424,7 +424,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate literal primitive in binding', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.LiteralPrimitive); @@ -433,7 +433,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate empty expression', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.EmptyExpr); @@ -441,7 +441,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate literal array', () => { const {errors, nodes, position} = parse(`{{ [1, 2,¦ 3] }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.LiteralArray); @@ -449,7 +449,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate literal map', () => { const {errors, nodes, position} = parse(`{{ { hello:¦ "world" } }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.LiteralMap); @@ -457,7 +457,7 @@ describe('findNodeAtPosition for expression AST', () => { it('should locate conditional', () => { const {errors, nodes, position} = parse(`{{ cond ?¦ true : false }}`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.Conditional); @@ -467,7 +467,7 @@ describe('findNodeAtPosition for expression AST', () => { describe('findNodeAtPosition for microsyntax expression', () => { it('should locate template key', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.BoundAttribute); @@ -475,7 +475,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { it('should locate template value', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -485,7 +485,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { const {errors, nodes, position} = parse(`
`); // ngFor is a text attribute because the desugared form is // - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); // TODO: this is currently wrong because it should point to ngFor text // attribute instead of ngForOf bound attribute @@ -493,7 +493,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { it('should locate not let keyword', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); // TODO: this is currently wrong because node is currently pointing to // "item". In this case, it should return undefined. @@ -501,7 +501,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { it('should locate let variable', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Variable); @@ -510,7 +510,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { it('should locate bound attribute key', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.BoundAttribute); @@ -519,7 +519,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { it('should locate bound attribute value', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -528,7 +528,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { it('should locate template children', () => { const {errors, nodes, position} = parse(``); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Element); @@ -540,7 +540,7 @@ describe('findNodeAtPosition for microsyntax expression', () => {
{{ i¦ }}
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isExpressionNode(node!)).toBe(true); expect(node).toBeInstanceOf(e.PropertyRead); @@ -548,7 +548,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { it('should locate LHS of variable declaration', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Variable); @@ -558,7 +558,7 @@ describe('findNodeAtPosition for microsyntax expression', () => { it('should locate RHS of variable declaration', () => { const {errors, nodes, position} = parse(`
`); - expect(errors).toBeUndefined(); + expect(errors).toBe(null); const node = findNodeAtPosition(nodes, position); expect(isTemplateNode(node!)).toBe(true); expect(node).toBeInstanceOf(t.Variable);