perf: Don’t subclass Error; resulting in smaller binary (#14160)
Subclassing errors is problematic since Error returns a new instance. All of the patching which we do than prevent proper application of source maps. PR Close #14160
This commit is contained in:

committed by
Miško Hevery

parent
3c2842be96
commit
c33fda2607
@ -62,5 +62,5 @@ export * from './src/style_compiler';
|
||||
export * from './src/template_parser/template_parser';
|
||||
export {ViewCompiler} from './src/view_compiler/view_compiler';
|
||||
export {AnimationParser} from './src/animation/animation_parser';
|
||||
export {SyntaxError} from './src/util';
|
||||
export {isSyntaxError, syntaxError} from './src/util';
|
||||
// This file only reexports content of the `src` folder. Keep it that way.
|
||||
|
@ -9,7 +9,7 @@
|
||||
import {Attribute, Component, ContentChild, ContentChildren, Directive, Host, HostBinding, HostListener, Inject, Injectable, Input, NgModule, Optional, Output, Pipe, Self, SkipSelf, ViewChild, ViewChildren, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core';
|
||||
|
||||
import {ReflectorReader} from '../private_import_core';
|
||||
import {SyntaxError} from '../util';
|
||||
import {syntaxError} from '../util';
|
||||
|
||||
import {StaticSymbol} from './static_symbol';
|
||||
import {StaticSymbolResolver} from './static_symbol_resolver';
|
||||
@ -566,7 +566,7 @@ export class StaticReflector implements ReflectorReader {
|
||||
if (e.fileName) {
|
||||
throw positionalError(message, e.fileName, e.line, e.column);
|
||||
}
|
||||
throw new SyntaxError(message);
|
||||
throw syntaxError(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
|
||||
import * as chars from '../chars';
|
||||
import {BaseError} from '../facade/errors';
|
||||
import {isPresent} from '../facade/lang';
|
||||
|
||||
export enum CssTokenType {
|
||||
@ -42,7 +41,7 @@ export enum CssLexerMode {
|
||||
}
|
||||
|
||||
export class LexedCssResult {
|
||||
constructor(public error: CssScannerError, public token: CssToken) {}
|
||||
constructor(public error: Error, public token: CssToken) {}
|
||||
}
|
||||
|
||||
export function generateErrorMessage(
|
||||
@ -86,16 +85,22 @@ export class CssLexer {
|
||||
}
|
||||
}
|
||||
|
||||
export class CssScannerError extends BaseError {
|
||||
public rawMessage: string;
|
||||
public message: string;
|
||||
export function cssScannerError(token: CssToken, message: string): Error {
|
||||
const error = Error('CssParseError: ' + message);
|
||||
(error as any)[ERROR_RAW_MESSAGE] = message;
|
||||
(error as any)[ERROR_TOKEN] = token;
|
||||
return error;
|
||||
}
|
||||
|
||||
constructor(public token: CssToken, message: string) {
|
||||
super('Css Parse Error: ' + message);
|
||||
this.rawMessage = message;
|
||||
}
|
||||
const ERROR_TOKEN = 'ngToken';
|
||||
const ERROR_RAW_MESSAGE = 'ngRawMessage';
|
||||
|
||||
toString(): string { return this.message; }
|
||||
export function getRawMessage(error: Error): string {
|
||||
return (error as any)[ERROR_RAW_MESSAGE];
|
||||
}
|
||||
|
||||
export function getToken(error: Error): CssToken {
|
||||
return (error as any)[ERROR_TOKEN];
|
||||
}
|
||||
|
||||
function _trackWhitespace(mode: CssLexerMode) {
|
||||
@ -122,7 +127,7 @@ export class CssScanner {
|
||||
/** @internal */
|
||||
_currentMode: CssLexerMode = CssLexerMode.BLOCK;
|
||||
/** @internal */
|
||||
_currentError: CssScannerError = null;
|
||||
_currentError: Error = null;
|
||||
|
||||
constructor(public input: string, private _trackComments: boolean = false) {
|
||||
this.length = this.input.length;
|
||||
@ -221,7 +226,7 @@ export class CssScanner {
|
||||
// mode so that the parser can recover...
|
||||
this.setMode(mode);
|
||||
|
||||
let error: CssScannerError = null;
|
||||
let error: Error = null;
|
||||
if (!isMatchingType || (isPresent(value) && value != next.strValue)) {
|
||||
let errorMessage =
|
||||
CssTokenType[next.type] + ' does not match expected ' + CssTokenType[type] + ' value';
|
||||
@ -230,7 +235,7 @@ export class CssScanner {
|
||||
errorMessage += ' ("' + next.strValue + '" should match "' + value + '")';
|
||||
}
|
||||
|
||||
error = new CssScannerError(
|
||||
error = cssScannerError(
|
||||
next, generateErrorMessage(
|
||||
this.input, errorMessage, next.strValue, previousIndex, previousLine,
|
||||
previousColumn));
|
||||
@ -483,7 +488,7 @@ export class CssScanner {
|
||||
if (!doNotAdvance) {
|
||||
this.advance();
|
||||
}
|
||||
this._currentError = new CssScannerError(invalidToken, errorMessage);
|
||||
this._currentError = cssScannerError(invalidToken, errorMessage);
|
||||
return invalidToken;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import {isPresent} from '../facade/lang';
|
||||
import {ParseError, ParseLocation, ParseSourceFile, ParseSourceSpan} from '../parse_util';
|
||||
|
||||
import {BlockType, CssAst, CssAtRulePredicateAst, CssBlockAst, CssBlockDefinitionRuleAst, CssBlockRuleAst, CssDefinitionAst, CssInlineRuleAst, CssKeyframeDefinitionAst, CssKeyframeRuleAst, CssMediaQueryRuleAst, CssPseudoSelectorAst, CssRuleAst, CssSelectorAst, CssSelectorRuleAst, CssSimpleSelectorAst, CssStyleSheetAst, CssStyleValueAst, CssStylesBlockAst, CssUnknownRuleAst, CssUnknownTokenListAst, mergeTokens} from './css_ast';
|
||||
import {CssLexer, CssLexerMode, CssScanner, CssToken, CssTokenType, generateErrorMessage, isNewline} from './css_lexer';
|
||||
import {CssLexer, CssLexerMode, CssScanner, CssToken, CssTokenType, generateErrorMessage, getRawMessage, isNewline} from './css_lexer';
|
||||
|
||||
const SPACE_OPERATOR = ' ';
|
||||
|
||||
@ -378,7 +378,7 @@ export class CssParser {
|
||||
const token = output.token;
|
||||
const error = output.error;
|
||||
if (isPresent(error)) {
|
||||
this._error(error.rawMessage, token);
|
||||
this._error(getRawMessage(error), token);
|
||||
}
|
||||
this._lastToken = token;
|
||||
return token;
|
||||
@ -393,7 +393,7 @@ export class CssParser {
|
||||
const token = output.token;
|
||||
const error = output.error;
|
||||
if (isPresent(error)) {
|
||||
this._error(error.rawMessage, token);
|
||||
this._error(getRawMessage(error), token);
|
||||
}
|
||||
this._lastToken = token;
|
||||
return token;
|
||||
|
@ -19,7 +19,7 @@ import {ResourceLoader} from './resource_loader';
|
||||
import {extractStyleUrls, isStyleUrlResolvable} from './style_url_resolver';
|
||||
import {PreparsedElementType, preparseElement} from './template_parser/template_preparser';
|
||||
import {UrlResolver} from './url_resolver';
|
||||
import {SyncAsyncResult, SyntaxError} from './util';
|
||||
import {SyncAsyncResult, syntaxError} from './util';
|
||||
|
||||
export interface PrenormalizedTemplateMetadata {
|
||||
componentType: any;
|
||||
@ -67,19 +67,19 @@ export class DirectiveNormalizer {
|
||||
let normalizedTemplateAsync: Promise<CompileTemplateMetadata>;
|
||||
if (prenormData.template != null) {
|
||||
if (typeof prenormData.template !== 'string') {
|
||||
throw new SyntaxError(
|
||||
throw syntaxError(
|
||||
`The template specified for component ${stringify(prenormData.componentType)} is not a string`);
|
||||
}
|
||||
normalizedTemplateSync = this.normalizeTemplateSync(prenormData);
|
||||
normalizedTemplateAsync = Promise.resolve(normalizedTemplateSync);
|
||||
} else if (prenormData.templateUrl) {
|
||||
if (typeof prenormData.templateUrl !== 'string') {
|
||||
throw new SyntaxError(
|
||||
throw syntaxError(
|
||||
`The templateUrl specified for component ${stringify(prenormData.componentType)} is not a string`);
|
||||
}
|
||||
normalizedTemplateAsync = this.normalizeTemplateAsync(prenormData);
|
||||
} else {
|
||||
throw new SyntaxError(
|
||||
throw syntaxError(
|
||||
`No template specified for component ${stringify(prenormData.componentType)}`);
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ export class DirectiveNormalizer {
|
||||
template, stringify(prenomData.componentType), true, interpolationConfig);
|
||||
if (rootNodesAndErrors.errors.length > 0) {
|
||||
const errorString = rootNodesAndErrors.errors.join('\n');
|
||||
throw new SyntaxError(`Template parse errors:\n${errorString}`);
|
||||
throw syntaxError(`Template parse errors:\n${errorString}`);
|
||||
}
|
||||
|
||||
const templateMetadataStyles = this.normalizeStylesheet(new CompileStylesheetMetadata({
|
||||
|
@ -20,11 +20,11 @@ import {CompilerInjectable} from './injectable';
|
||||
import {hasLifecycleHook} from './lifecycle_reflector';
|
||||
import {NgModuleResolver} from './ng_module_resolver';
|
||||
import {PipeResolver} from './pipe_resolver';
|
||||
import {ComponentStillLoadingError, LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from './private_import_core';
|
||||
import {ERROR_COMPONENT_TYPE, LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from './private_import_core';
|
||||
import {ElementSchemaRegistry} from './schema/element_schema_registry';
|
||||
import {SummaryResolver} from './summary_resolver';
|
||||
import {getUrlScheme} from './url_resolver';
|
||||
import {MODULE_SUFFIX, SyntaxError, ValueTransformer, visitValue} from './util';
|
||||
import {MODULE_SUFFIX, ValueTransformer, syntaxError, visitValue} from './util';
|
||||
|
||||
export type ErrorCollector = (error: any, type?: any) => void;
|
||||
export const ERROR_COLLECTOR_TOKEN = new InjectionToken('ErrorCollector');
|
||||
@ -254,7 +254,7 @@ export class CompileMetadataResolver {
|
||||
return null;
|
||||
} else {
|
||||
if (isSync) {
|
||||
this._reportError(new ComponentStillLoadingError(directiveType), directiveType);
|
||||
this._reportError(componentStillLoadingError(directiveType), directiveType);
|
||||
return null;
|
||||
}
|
||||
return templateMeta.asyncResult.then(createDirectiveMetadata);
|
||||
@ -328,7 +328,7 @@ export class CompileMetadataResolver {
|
||||
// Directive
|
||||
if (!selector) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Directive ${stringifyType(directiveType)} has no selector, please add it!`),
|
||||
directiveType);
|
||||
selector = 'error';
|
||||
@ -383,7 +383,7 @@ export class CompileMetadataResolver {
|
||||
const dirMeta = this._directiveCache.get(directiveType);
|
||||
if (!dirMeta) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Illegal state: getDirectiveMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Directive ${stringifyType(directiveType)}.`),
|
||||
directiveType);
|
||||
}
|
||||
@ -395,7 +395,7 @@ export class CompileMetadataResolver {
|
||||
<cpl.CompileDirectiveSummary>this._loadSummary(dirType, cpl.CompileSummaryKind.Directive);
|
||||
if (!dirSummary) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Illegal state: Could not load the summary for directive ${stringifyType(dirType)}.`),
|
||||
dirType);
|
||||
}
|
||||
@ -478,7 +478,7 @@ export class CompileMetadataResolver {
|
||||
const importedModuleSummary = this.getNgModuleSummary(importedModuleType);
|
||||
if (!importedModuleSummary) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Unexpected ${this._getTypeDescriptor(importedType)} '${stringifyType(importedType)}' imported by the module '${stringifyType(moduleType)}'`),
|
||||
moduleType);
|
||||
return;
|
||||
@ -486,7 +486,7 @@ export class CompileMetadataResolver {
|
||||
importedModules.push(importedModuleSummary);
|
||||
} else {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Unexpected value '${stringifyType(importedType)}' imported by the module '${stringifyType(moduleType)}'`),
|
||||
moduleType);
|
||||
return;
|
||||
@ -498,7 +498,7 @@ export class CompileMetadataResolver {
|
||||
flattenAndDedupeArray(meta.exports).forEach((exportedType) => {
|
||||
if (!isValidType(exportedType)) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Unexpected value '${stringifyType(exportedType)}' exported by the module '${stringifyType(moduleType)}'`),
|
||||
moduleType);
|
||||
return;
|
||||
@ -519,7 +519,7 @@ export class CompileMetadataResolver {
|
||||
flattenAndDedupeArray(meta.declarations).forEach((declaredType) => {
|
||||
if (!isValidType(declaredType)) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Unexpected value '${stringifyType(declaredType)}' declared by the module '${stringifyType(moduleType)}'`),
|
||||
moduleType);
|
||||
return;
|
||||
@ -536,7 +536,7 @@ export class CompileMetadataResolver {
|
||||
this._addTypeToModule(declaredType, moduleType);
|
||||
} else {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Unexpected ${this._getTypeDescriptor(declaredType)} '${stringifyType(declaredType)}' declared by the module '${stringifyType(moduleType)}'`),
|
||||
moduleType);
|
||||
return;
|
||||
@ -555,7 +555,7 @@ export class CompileMetadataResolver {
|
||||
transitiveModule.addExportedPipe(exportedId);
|
||||
} else {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Can't export ${this._getTypeDescriptor(exportedId.reference)} ${stringifyType(exportedId.reference)} from ${stringifyType(moduleType)} as it was neither declared nor imported!`),
|
||||
moduleType);
|
||||
}
|
||||
@ -578,7 +578,7 @@ export class CompileMetadataResolver {
|
||||
flattenAndDedupeArray(meta.bootstrap).forEach(type => {
|
||||
if (!isValidType(type)) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Unexpected value '${stringifyType(type)}' used in the bootstrap property of module '${stringifyType(moduleType)}'`),
|
||||
moduleType);
|
||||
return;
|
||||
@ -642,7 +642,7 @@ export class CompileMetadataResolver {
|
||||
const oldModule = this._ngModuleOfTypes.get(type);
|
||||
if (oldModule && oldModule !== moduleType) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Type ${stringifyType(type)} is part of the declarations of 2 modules: ${stringifyType(oldModule)} and ${stringifyType(moduleType)}! ` +
|
||||
`Please consider moving ${stringifyType(type)} to a higher module that imports ${stringifyType(oldModule)} and ${stringifyType(moduleType)}. ` +
|
||||
`You can also create a new NgModule that exports and includes ${stringifyType(type)} then import that NgModule in ${stringifyType(oldModule)} and ${stringifyType(moduleType)}.`),
|
||||
@ -738,7 +738,7 @@ export class CompileMetadataResolver {
|
||||
const pipeMeta = this._pipeCache.get(pipeType);
|
||||
if (!pipeMeta) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Illegal state: getPipeMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Pipe ${stringifyType(pipeType)}.`),
|
||||
pipeType);
|
||||
}
|
||||
@ -750,7 +750,7 @@ export class CompileMetadataResolver {
|
||||
<cpl.CompilePipeSummary>this._loadSummary(pipeType, cpl.CompileSummaryKind.Pipe);
|
||||
if (!pipeSummary) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Illegal state: Could not load the summary for pipe ${stringifyType(pipeType)}.`),
|
||||
pipeType);
|
||||
}
|
||||
@ -833,7 +833,7 @@ export class CompileMetadataResolver {
|
||||
const depsTokens =
|
||||
dependenciesMetadata.map((dep) => dep ? stringifyType(dep.token) : '?').join(', ');
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Can't resolve all parameters for ${stringifyType(typeOrFunc)}: (${depsTokens}).`),
|
||||
typeOrFunc);
|
||||
}
|
||||
@ -868,7 +868,7 @@ export class CompileMetadataResolver {
|
||||
} else if (isValidType(provider)) {
|
||||
providerMeta = new cpl.ProviderMeta(provider, {useClass: provider});
|
||||
} else if (provider === void 0) {
|
||||
this._reportError(new SyntaxError(
|
||||
this._reportError(syntaxError(
|
||||
`Encountered undefined provider! Usually this means you have a circular dependencies (might be caused by using 'barrel' index.ts files.`));
|
||||
} else {
|
||||
const providersInfo =
|
||||
@ -886,7 +886,7 @@ export class CompileMetadataResolver {
|
||||
[]))
|
||||
.join(', ');
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Invalid ${debugInfo ? debugInfo : 'provider'} - only instances of Provider and Type are allowed, got: [${providersInfo}]`),
|
||||
type);
|
||||
}
|
||||
@ -902,7 +902,7 @@ export class CompileMetadataResolver {
|
||||
|
||||
private _validateProvider(provider: any): void {
|
||||
if (provider.hasOwnProperty('useClass') && provider.useClass == null) {
|
||||
this._reportError(new SyntaxError(
|
||||
this._reportError(syntaxError(
|
||||
`Invalid provider for ${stringifyType(provider.provide)}. useClass cannot be ${provider.useClass}.
|
||||
Usually it happens when:
|
||||
1. There's a circular dependency (might be caused by using index.ts (barrel) files).
|
||||
@ -917,13 +917,13 @@ export class CompileMetadataResolver {
|
||||
|
||||
if (provider.useFactory || provider.useExisting || provider.useClass) {
|
||||
this._reportError(
|
||||
new SyntaxError(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!`), type);
|
||||
syntaxError(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!`), type);
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!provider.multi) {
|
||||
this._reportError(
|
||||
new SyntaxError(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!`),
|
||||
syntaxError(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!`),
|
||||
type);
|
||||
return [];
|
||||
}
|
||||
@ -1006,7 +1006,7 @@ export class CompileMetadataResolver {
|
||||
} else {
|
||||
if (!q.selector) {
|
||||
this._reportError(
|
||||
new SyntaxError(
|
||||
syntaxError(
|
||||
`Can't construct a query for the property "${propertyName}" of "${stringifyType(typeOrFunc)}" since the query selector wasn't defined.`),
|
||||
typeOrFunc);
|
||||
}
|
||||
@ -1074,7 +1074,7 @@ export function componentModuleUrl(
|
||||
const scheme = getUrlScheme(moduleId);
|
||||
return scheme ? moduleId : `package:${moduleId}${MODULE_SUFFIX}`;
|
||||
} else if (moduleId !== null && moduleId !== void 0) {
|
||||
throw new SyntaxError(
|
||||
throw syntaxError(
|
||||
`moduleId should be a string in "${stringifyType(type)}". See https://goo.gl/wIDDiL for more information.\n` +
|
||||
`If you're using Webpack you should inline the template and the styles, see https://goo.gl/X2J8zc.`);
|
||||
}
|
||||
@ -1099,3 +1099,14 @@ function stringifyType(type: any): string {
|
||||
return stringify(type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that a component is still being loaded in a synchronous compile.
|
||||
*/
|
||||
function componentStillLoadingError(compType: Type<any>) {
|
||||
debugger;
|
||||
const error =
|
||||
Error(`Can't compile synchronously as ${stringify(compType)} is still being loaded!`);
|
||||
(error as any)[ERROR_COMPONENT_TYPE] = compType;
|
||||
return error;
|
||||
}
|
@ -58,6 +58,7 @@ export const AnimationStyles: typeof r.AnimationStyles = r.AnimationStyles;
|
||||
export const ANY_STATE = r.ANY_STATE;
|
||||
export const DEFAULT_STATE = r.DEFAULT_STATE;
|
||||
export const EMPTY_STATE = r.EMPTY_STATE;
|
||||
export const ERROR_COMPONENT_TYPE = r.ERROR_COMPONENT_TYPE;
|
||||
export const FILL_STYLE_FLAG = r.FILL_STYLE_FLAG;
|
||||
export const prepareFinalAnimationStyles: typeof r.prepareFinalAnimationStyles =
|
||||
r.prepareFinalAnimationStyles;
|
||||
@ -68,9 +69,6 @@ export const collectAndResolveStyles: typeof r.collectAndResolveStyles = r.colle
|
||||
export const renderStyles: typeof r.renderStyles = r.renderStyles;
|
||||
export type ViewMetadata = typeof r._ViewMetadata;
|
||||
export const ViewMetadata: typeof r.ViewMetadata = r.ViewMetadata;
|
||||
export type ComponentStillLoadingError = typeof r._ComponentStillLoadingError;
|
||||
export const ComponentStillLoadingError: typeof r.ComponentStillLoadingError =
|
||||
r.ComponentStillLoadingError;
|
||||
export const AnimationTransition: typeof r.AnimationTransition = r.AnimationTransition;
|
||||
export type SetterFn = typeof r._SetterFn;
|
||||
export type GetterFn = typeof r._GetterFn;
|
||||
|
@ -24,7 +24,7 @@ import {ProviderElementContext, ProviderViewContext} from '../provider_analyzer'
|
||||
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
|
||||
import {CssSelector, SelectorMatcher} from '../selector';
|
||||
import {isStyleUrlResolvable} from '../style_url_resolver';
|
||||
import {SyntaxError} from '../util';
|
||||
import {syntaxError} from '../util';
|
||||
import {BindingParser, BoundProperty} from './binding_parser';
|
||||
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from './template_ast';
|
||||
import {PreparsedElementType, preparseElement} from './template_preparser';
|
||||
@ -99,7 +99,7 @@ export class TemplateParser {
|
||||
|
||||
if (errors.length > 0) {
|
||||
const errorString = errors.join('\n');
|
||||
throw new SyntaxError(`Template parse errors:\n${errorString}`);
|
||||
throw syntaxError(`Template parse errors:\n${errorString}`);
|
||||
}
|
||||
|
||||
return result.templateAst;
|
||||
|
@ -6,7 +6,6 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {BaseError} from './facade/errors';
|
||||
import {isPrimitive, isStrictStringMap} from './facade/lang';
|
||||
export const MODULE_SUFFIX = '';
|
||||
|
||||
@ -79,4 +78,14 @@ export class SyncAsyncResult<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SyntaxError extends BaseError {}
|
||||
export function syntaxError(msg: string): Error {
|
||||
const error = Error(msg);
|
||||
(error as any)[ERROR_SYNTAX_ERROR] = true;
|
||||
return error;
|
||||
}
|
||||
|
||||
const ERROR_SYNTAX_ERROR = 'ngSyntaxError';
|
||||
|
||||
export function isSyntaxError(error: Error): boolean {
|
||||
return (error as any)[ERROR_SYNTAX_ERROR];
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, StaticSymbolResolverHost, SyntaxError} from '@angular/compiler';
|
||||
import {StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, StaticSymbolResolverHost} from '@angular/compiler';
|
||||
import {HostListener, Inject, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core';
|
||||
|
||||
import {MockStaticSymbolResolverHost, MockSummaryResolver} from './static_symbol_resolver_spec';
|
||||
@ -354,7 +354,6 @@ describe('StaticReflector', () => {
|
||||
'Could not resolve ./does-not-exist.component relative to /tmp/src/function-reference.ts'
|
||||
})))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
'Error encountered resolving symbol values statically. Could not resolve ./does-not-exist.component relative to /tmp/src/function-reference.ts, resolving symbol AppModule in /tmp/src/function-reference.ts');
|
||||
});
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {describe, expect, it} from '../../../core/testing/testing_internal';
|
||||
import {CssLexer, CssLexerMode, CssScannerError, CssToken, CssTokenType} from '../../src/css_parser/css_lexer';
|
||||
import {CssLexer, CssLexerMode, CssToken, CssTokenType, cssScannerError, getRawMessage, getToken} from '../../src/css_parser/css_lexer';
|
||||
import {isPresent} from '../../src/facade/lang';
|
||||
|
||||
export function main() {
|
||||
@ -22,7 +22,7 @@ export function main() {
|
||||
while (output != null) {
|
||||
const error = output.error;
|
||||
if (isPresent(error)) {
|
||||
throw new CssScannerError(error.token, error.rawMessage);
|
||||
throw cssScannerError(getToken(error), getRawMessage(error));
|
||||
}
|
||||
tokens.push(output.token);
|
||||
output = scanner.scan();
|
||||
@ -279,7 +279,7 @@ export function main() {
|
||||
try {
|
||||
tokenize(cssCode, false, CssLexerMode.STYLE_BLOCK);
|
||||
} catch (e) {
|
||||
capturedMessage = e.rawMessage;
|
||||
capturedMessage = getRawMessage(e);
|
||||
}
|
||||
|
||||
expect(capturedMessage).toMatch(/Unexpected character \[\>\] at column 0:7 in expression/g);
|
||||
@ -288,7 +288,7 @@ export function main() {
|
||||
try {
|
||||
tokenize(cssCode, false, CssLexerMode.SELECTOR);
|
||||
} catch (e) {
|
||||
capturedMessage = e.rawMessage;
|
||||
capturedMessage = getRawMessage(e);
|
||||
}
|
||||
|
||||
expect(capturedMessage).toEqual(null);
|
||||
|
@ -5,7 +5,6 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {SyntaxError} from '@angular/compiler';
|
||||
import {CompileDirectiveMetadata, CompileStylesheetMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '@angular/compiler/src/compile_metadata';
|
||||
import {CompilerConfig} from '@angular/compiler/src/config';
|
||||
import {DirectiveNormalizer} from '@angular/compiler/src/directive_normalizer';
|
||||
@ -31,23 +30,23 @@ export function main() {
|
||||
expect(() => normalizer.normalizeTemplate({
|
||||
componentType: SomeComp,
|
||||
moduleUrl: SOME_MODULE_URL,
|
||||
})).toThrowError(SyntaxError, 'No template specified for component SomeComp');
|
||||
})).toThrowError('No template specified for component SomeComp');
|
||||
}));
|
||||
it('should throw if template is not a string',
|
||||
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
|
||||
expect(
|
||||
() => normalizer.normalizeTemplate(
|
||||
{componentType: SomeComp, moduleUrl: SOME_MODULE_URL, template: <any>{}}))
|
||||
.toThrowError(
|
||||
SyntaxError, 'The template specified for component SomeComp is not a string');
|
||||
expect(() => normalizer.normalizeTemplate({
|
||||
componentType: SomeComp,
|
||||
moduleUrl: SOME_MODULE_URL,
|
||||
template: <any>{}
|
||||
})).toThrowError('The template specified for component SomeComp is not a string');
|
||||
}));
|
||||
it('should throw if templateUrl is not a string',
|
||||
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
|
||||
expect(
|
||||
() => normalizer.normalizeTemplate(
|
||||
{componentType: SomeComp, moduleUrl: SOME_MODULE_URL, templateUrl: <any>{}}))
|
||||
.toThrowError(
|
||||
SyntaxError, 'The templateUrl specified for component SomeComp is not a string');
|
||||
expect(() => normalizer.normalizeTemplate({
|
||||
componentType: SomeComp,
|
||||
moduleUrl: SOME_MODULE_URL,
|
||||
templateUrl: <any>{}
|
||||
})).toThrowError('The templateUrl specified for component SomeComp is not a string');
|
||||
}));
|
||||
});
|
||||
|
||||
|
@ -15,7 +15,6 @@ import {identifierName} from '../src/compile_metadata';
|
||||
import {stringify} from '../src/facade/lang';
|
||||
import {CompileMetadataResolver} from '../src/metadata_resolver';
|
||||
import {ResourceLoader} from '../src/resource_loader';
|
||||
import {SyntaxError} from '../src/util';
|
||||
import {MockResourceLoader} from '../testing/resource_loader_mock';
|
||||
import {MalformedStylesComponent} from './metadata_resolver_fixture';
|
||||
|
||||
@ -34,9 +33,8 @@ export function main() {
|
||||
}
|
||||
|
||||
expect(() => resolver.getDirectiveMetadata(ComponentWithEverythingInline))
|
||||
.toThrowError(SyntaxError, /Illegal state/);
|
||||
expect(() => resolver.getPipeMetadata(SomePipe))
|
||||
.toThrowError(SyntaxError, /Illegal state/);
|
||||
.toThrowError(/Illegal state/);
|
||||
expect(() => resolver.getPipeMetadata(SomePipe)).toThrowError(/Illegal state/);
|
||||
}));
|
||||
|
||||
it('should read metadata in sync for components with inline resources',
|
||||
@ -122,10 +120,10 @@ export function main() {
|
||||
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true))
|
||||
.toThrowError(
|
||||
SyntaxError, `moduleId should be a string in "ComponentWithInvalidModuleId". See` +
|
||||
` https://goo.gl/wIDDiL for more information.\n` +
|
||||
`If you're using Webpack you should inline the template and the styles, see` +
|
||||
` https://goo.gl/X2J8zc.`);
|
||||
`moduleId should be a string in "ComponentWithInvalidModuleId". See` +
|
||||
` https://goo.gl/wIDDiL for more information.\n` +
|
||||
`If you're using Webpack you should inline the template and the styles, see` +
|
||||
` https://goo.gl/X2J8zc.`);
|
||||
}));
|
||||
|
||||
|
||||
@ -146,7 +144,7 @@ export function main() {
|
||||
}
|
||||
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true))
|
||||
.toThrowError(SyntaxError, `Can't resolve all parameters for MyBrokenComp1: (?).`);
|
||||
.toThrowError(`Can't resolve all parameters for MyBrokenComp1: (?).`);
|
||||
}));
|
||||
it('should throw with descriptive error message when a directive is passed to imports',
|
||||
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
||||
@ -156,7 +154,6 @@ export function main() {
|
||||
expect(
|
||||
() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithImportedComponent, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Unexpected directive 'ComponentWithoutModuleId' imported by the module 'ModuleWithImportedComponent'`);
|
||||
}));
|
||||
|
||||
@ -170,7 +167,6 @@ export function main() {
|
||||
}
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithImportedPipe, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Unexpected pipe 'SomePipe' imported by the module 'ModuleWithImportedPipe'`);
|
||||
}));
|
||||
|
||||
@ -184,7 +180,6 @@ export function main() {
|
||||
}
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithDeclaredModule, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Unexpected module 'SomeModule' declared by the module 'ModuleWithDeclaredModule'`);
|
||||
}));
|
||||
|
||||
@ -195,7 +190,6 @@ export function main() {
|
||||
}
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithNullDeclared, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Unexpected value 'null' declared by the module 'ModuleWithNullDeclared'`);
|
||||
}));
|
||||
|
||||
@ -206,7 +200,6 @@ export function main() {
|
||||
}
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithNullImported, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Unexpected value 'null' imported by the module 'ModuleWithNullImported'`);
|
||||
}));
|
||||
|
||||
@ -218,8 +211,7 @@ export function main() {
|
||||
}
|
||||
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true))
|
||||
.toThrowError(
|
||||
SyntaxError, `Can't resolve all parameters for NonAnnotatedService: (?).`);
|
||||
.toThrowError(`Can't resolve all parameters for NonAnnotatedService: (?).`);
|
||||
}));
|
||||
|
||||
it('should throw with descriptive error message when encounter invalid provider',
|
||||
@ -229,8 +221,7 @@ export function main() {
|
||||
}
|
||||
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true))
|
||||
.toThrowError(
|
||||
SyntaxError, /Invalid provider for SimpleService. useClass cannot be undefined./);
|
||||
.toThrowError(/Invalid provider for SimpleService. useClass cannot be undefined./);
|
||||
}));
|
||||
|
||||
it('should throw with descriptive error message when provider is undefined',
|
||||
@ -240,7 +231,7 @@ export function main() {
|
||||
}
|
||||
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true))
|
||||
.toThrowError(SyntaxError, /Encountered undefined provider!/);
|
||||
.toThrowError(/Encountered undefined provider!/);
|
||||
}));
|
||||
|
||||
it('should throw with descriptive error message when one of providers is not present',
|
||||
@ -251,7 +242,6 @@ export function main() {
|
||||
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Invalid providers for "MyBrokenComp3" - only instances of Provider and Type are allowed, got: [SimpleService, ?null?, ...]`);
|
||||
}));
|
||||
|
||||
@ -263,7 +253,6 @@ export function main() {
|
||||
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(SomeModule, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Invalid viewProviders for "MyBrokenComp4" - only instances of Provider and Type are allowed, got: [?null?, ...]`);
|
||||
}));
|
||||
|
||||
@ -278,13 +267,11 @@ export function main() {
|
||||
|
||||
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithNullBootstrap, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Unexpected value 'null' used in the bootstrap property of module 'ModuleWithNullBootstrap'`);
|
||||
expect(
|
||||
() =>
|
||||
resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithUndefinedBootstrap, true))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Unexpected value 'undefined' used in the bootstrap property of module 'ModuleWithUndefinedBootstrap'`);
|
||||
}));
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {SyntaxError} from '@angular/compiler';
|
||||
import {CompileAnimationEntryMetadata, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, tokenReference} from '@angular/compiler/src/compile_metadata';
|
||||
import {DomElementSchemaRegistry} from '@angular/compiler/src/schema/dom_element_schema_registry';
|
||||
import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry';
|
||||
@ -374,7 +373,7 @@ export function main() {
|
||||
describe('errors', () => {
|
||||
it('should throw error when binding to an unknown property', () => {
|
||||
expect(() => parse('<my-component [invalidProp]="bar"></my-component>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
.toThrowError(`Template parse errors:
|
||||
Can't bind to 'invalidProp' since it isn't a known property of 'my-component'.
|
||||
1. If 'my-component' is an Angular component and it has 'invalidProp' input, then verify that it is part of this module.
|
||||
2. If 'my-component' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message.
|
||||
@ -382,16 +381,14 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'.
|
||||
});
|
||||
|
||||
it('should throw error when binding to an unknown element w/o bindings', () => {
|
||||
expect(() => parse('<unknown></unknown>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<unknown></unknown>', [])).toThrowError(`Template parse errors:
|
||||
'unknown' is not a known element:
|
||||
1. If 'unknown' is an Angular component, then verify that it is part of this module.
|
||||
2. If 'unknown' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->]<unknown></unknown>"): TestComp@0:0`);
|
||||
});
|
||||
|
||||
it('should throw error when binding to an unknown custom element w/o bindings', () => {
|
||||
expect(() => parse('<un-known></un-known>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<un-known></un-known>', [])).toThrowError(`Template parse errors:
|
||||
'un-known' is not a known element:
|
||||
1. If 'un-known' is an Angular component, then verify that it is part of this module.
|
||||
2. If 'un-known' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->]<un-known></un-known>"): TestComp@0:0`);
|
||||
@ -399,13 +396,13 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'.
|
||||
|
||||
it('should throw error when binding to an invalid property', () => {
|
||||
expect(() => parse('<my-component [onEvent]="bar"></my-component>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
.toThrowError(`Template parse errors:
|
||||
Binding to property 'onEvent' is disallowed for security reasons ("<my-component [ERROR ->][onEvent]="bar"></my-component>"): TestComp@0:14`);
|
||||
});
|
||||
|
||||
it('should throw error when binding to an invalid attribute', () => {
|
||||
expect(() => parse('<my-component [attr.onEvent]="bar"></my-component>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
.toThrowError(`Template parse errors:
|
||||
Binding to attribute 'onEvent' is disallowed for security reasons ("<my-component [ERROR ->][attr.onEvent]="bar"></my-component>"): TestComp@0:14`);
|
||||
});
|
||||
});
|
||||
@ -447,7 +444,6 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
|
||||
() => {
|
||||
expect(() => { parse('<div @someAnimation="value2">', [], [], []); })
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
/Assigning animation triggers via @prop="exp" attributes with an expression is invalid. Use property bindings \(e.g. \[@prop\]="exp"\) or use an attribute without a value \(e.g. @prop\) instead. \("<div \[ERROR ->\]@someAnimation="value2">"\): TestComp@0:5/);
|
||||
});
|
||||
|
||||
@ -482,7 +478,6 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
|
||||
|
||||
expect(() => { parse('<broken></broken>', [dirA]); })
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Template parse errors:\nValue of the host property binding "class.foo" needs to be a string representing an expression but got "null" (object) ("[ERROR ->]<broken></broken>"): TestComp@0:0, Directive DirA`);
|
||||
});
|
||||
|
||||
@ -498,7 +493,6 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
|
||||
|
||||
expect(() => { parse('<broken></broken>', [dirA]); })
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
`Template parse errors:\nValue of the host listener "click" needs to be a string representing an expression but got "null" (object) ("[ERROR ->]<broken></broken>"): TestComp@0:0, Directive DirA`);
|
||||
});
|
||||
|
||||
@ -962,8 +956,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
|
||||
const dirB = createDir('[dirB]', {providers: [provider1]});
|
||||
expect(() => parse('<div dirA dirB>', [dirA, dirB]))
|
||||
.toThrowError(
|
||||
SyntaxError, `Template parse errors:\n` +
|
||||
`Mixing multi and non multi provider is not possible for token service0 ("[ERROR ->]<div dirA dirB>"): TestComp@0:0`);
|
||||
`Template parse errors:\n` +
|
||||
`Mixing multi and non multi provider is not possible for token service0 ("[ERROR ->]<div dirA dirB>"): TestComp@0:0`);
|
||||
});
|
||||
|
||||
it('should sort providers by their DI order', () => {
|
||||
@ -1055,7 +1049,6 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
|
||||
const dirA = createDir('[dirA]', {deps: ['self:provider0']});
|
||||
expect(() => parse('<div dirA></div>', [dirA]))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
'Template parse errors:\nNo provider for provider0 ("[ERROR ->]<div dirA></div>"): TestComp@0:0');
|
||||
});
|
||||
|
||||
@ -1070,7 +1063,6 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
|
||||
const dirA = createDir('[dirA]', {deps: ['host:provider0']});
|
||||
expect(() => parse('<div dirA></div>', [dirA]))
|
||||
.toThrowError(
|
||||
SyntaxError,
|
||||
'Template parse errors:\nNo provider for provider0 ("[ERROR ->]<div dirA></div>"): TestComp@0:0');
|
||||
});
|
||||
|
||||
@ -1122,26 +1114,23 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
|
||||
});
|
||||
|
||||
it('should report references with values that dont match a directive as errors', () => {
|
||||
expect(() => parse('<div #a="dirA"></div>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<div #a="dirA"></div>', [])).toThrowError(`Template parse errors:
|
||||
There is no directive with "exportAs" set to "dirA" ("<div [ERROR ->]#a="dirA"></div>"): TestComp@0:5`);
|
||||
});
|
||||
|
||||
it('should report invalid reference names', () => {
|
||||
expect(() => parse('<div #a-b></div>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<div #a-b></div>', [])).toThrowError(`Template parse errors:
|
||||
"-" is not allowed in reference names ("<div [ERROR ->]#a-b></div>"): TestComp@0:5`);
|
||||
});
|
||||
|
||||
it('should report variables as errors', () => {
|
||||
expect(() => parse('<div let-a></div>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<div let-a></div>', [])).toThrowError(`Template parse errors:
|
||||
"let-" is only supported on template elements. ("<div [ERROR ->]let-a></div>"): TestComp@0:5`);
|
||||
});
|
||||
|
||||
it('should report duplicate reference names', () => {
|
||||
expect(() => parse('<div #a></div><div #a></div>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
.toThrowError(`Template parse errors:
|
||||
Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>"): TestComp@0:19`);
|
||||
|
||||
});
|
||||
@ -1513,8 +1502,8 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
|
||||
it('should report when ng-content has non WS content', () => {
|
||||
expect(() => parse('<ng-content>content</ng-content>', []))
|
||||
.toThrowError(
|
||||
SyntaxError, `Template parse errors:\n` +
|
||||
`<ng-content> element cannot have content. ("[ERROR ->]<ng-content>content</ng-content>"): TestComp@0:0`);
|
||||
`Template parse errors:\n` +
|
||||
`<ng-content> element cannot have content. ("[ERROR ->]<ng-content>content</ng-content>"): TestComp@0:0`);
|
||||
});
|
||||
|
||||
it('should treat *attr on a template element as valid',
|
||||
@ -1524,20 +1513,18 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
|
||||
() => { expect(() => parse('<template template="ngIf">', [])).not.toThrowError(); });
|
||||
|
||||
it('should report when mutliple *attrs are used on the same element', () => {
|
||||
expect(() => parse('<div *ngIf *ngFor>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<div *ngIf *ngFor>', [])).toThrowError(`Template parse errors:
|
||||
Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with * ("<div *ngIf [ERROR ->]*ngFor>"): TestComp@0:11`);
|
||||
});
|
||||
|
||||
it('should report when mix of template and *attrs are used on the same element', () => {
|
||||
expect(() => parse('<span template="ngIf" *ngFor>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
.toThrowError(`Template parse errors:
|
||||
Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with * ("<span template="ngIf" [ERROR ->]*ngFor>"): TestComp@0:22`);
|
||||
});
|
||||
|
||||
it('should report invalid property names', () => {
|
||||
expect(() => parse('<div [invalidProp]></div>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<div [invalidProp]></div>', [])).toThrowError(`Template parse errors:
|
||||
Can't bind to 'invalidProp' since it isn't a known property of 'div'. ("<div [ERROR ->][invalidProp]></div>"): TestComp@0:5`);
|
||||
});
|
||||
|
||||
@ -1550,13 +1537,12 @@ Can't bind to 'invalidProp' since it isn't a known property of 'div'. ("<div [ER
|
||||
host: {'[invalidProp]': 'someProp'}
|
||||
})
|
||||
.toSummary();
|
||||
expect(() => parse('<div></div>', [dirA])).toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<div></div>', [dirA])).toThrowError(`Template parse errors:
|
||||
Can't bind to 'invalidProp' since it isn't a known property of 'div'. ("[ERROR ->]<div></div>"): TestComp@0:0, Directive DirA`);
|
||||
});
|
||||
|
||||
it('should report errors in expressions', () => {
|
||||
expect(() => parse('<div [prop]="a b"></div>', []))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<div [prop]="a b"></div>', [])).toThrowError(`Template parse errors:
|
||||
Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [ERROR ->][prop]="a b"></div>"): TestComp@0:5`);
|
||||
});
|
||||
|
||||
@ -1594,10 +1580,10 @@ Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [
|
||||
.toSummary();
|
||||
expect(() => parse('<div>', [dirB, dirA]))
|
||||
.toThrowError(
|
||||
SyntaxError, `Template parse errors:\n` +
|
||||
`More than one component matched on this element.\n` +
|
||||
`Make sure that only one component's selector can match a given element.\n` +
|
||||
`Conflicting components: DirB,DirA ("[ERROR ->]<div>"): TestComp@0:0`);
|
||||
`Template parse errors:\n` +
|
||||
`More than one component matched on this element.\n` +
|
||||
`Make sure that only one component's selector can match a given element.\n` +
|
||||
`Conflicting components: DirB,DirA ("[ERROR ->]<div>"): TestComp@0:0`);
|
||||
});
|
||||
|
||||
it('should not allow components or element bindings nor dom events on explicit embedded templates',
|
||||
@ -1612,7 +1598,7 @@ Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [
|
||||
})
|
||||
.toSummary();
|
||||
expect(() => parse('<template [a]="b" (e)="f"></template>', [dirA]))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
.toThrowError(`Template parse errors:
|
||||
Event binding e not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("<template [a]="b" [ERROR ->](e)="f"></template>"): TestComp@0:18
|
||||
Components on an embedded template: DirA ("[ERROR ->]<template [a]="b" (e)="f"></template>"): TestComp@0:0
|
||||
Property binding a not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("[ERROR ->]<template [a]="b" (e)="f"></template>"): TestComp@0:0`);
|
||||
@ -1628,8 +1614,7 @@ Property binding a not used by any directive on an embedded template. Make sure
|
||||
template: new CompileTemplateMetadata({ngContentSelectors: []})
|
||||
})
|
||||
.toSummary();
|
||||
expect(() => parse('<div *a="b"></div>', [dirA]))
|
||||
.toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('<div *a="b"></div>', [dirA])).toThrowError(`Template parse errors:
|
||||
Components on an embedded template: DirA ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0
|
||||
Property binding a not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0`);
|
||||
});
|
||||
@ -1889,7 +1874,7 @@ Property binding a not used by any directive on an embedded template. Make sure
|
||||
});
|
||||
|
||||
it('should report pipes as error that have not been defined as dependencies', () => {
|
||||
expect(() => parse('{{a | test}}', [])).toThrowError(SyntaxError, `Template parse errors:
|
||||
expect(() => parse('{{a | test}}', [])).toThrowError(`Template parse errors:
|
||||
The pipe 'test' could not be found ("{{[ERROR ->]a | test}}"): TestComp@0:2`);
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user