@angular/language-service 11.2.0-rc.0 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundles/ivy.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v11.2.0-rc.0
2
+ * @license Angular v11.2.0
3
3
  * Copyright Google LLC All Rights Reserved.
4
4
  * License: MIT
5
5
  */
@@ -11665,6 +11665,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11665
11665
  return new Chain(this.span(start), this.sourceSpan(start), exprs);
11666
11666
  }
11667
11667
  parsePipe() {
11668
+ const start = this.inputIndex;
11668
11669
  let result = this.parseExpression();
11669
11670
  if (this.consumeOptionalOperator('|')) {
11670
11671
  if (this.parseAction) {
@@ -11700,7 +11701,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11700
11701
  // If there are additional expressions beyond the name, then the artificial end for the
11701
11702
  // name is no longer relevant.
11702
11703
  }
11703
- const { start } = result.span;
11704
11704
  result = new BindingPipe(this.span(start), this.sourceSpan(start, fullSpanEnd), result, nameId, args, nameSpan);
11705
11705
  } while (this.consumeOptionalOperator('|'));
11706
11706
  }
@@ -11732,26 +11732,27 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11732
11732
  }
11733
11733
  parseLogicalOr() {
11734
11734
  // '||'
11735
+ const start = this.inputIndex;
11735
11736
  let result = this.parseLogicalAnd();
11736
11737
  while (this.consumeOptionalOperator('||')) {
11737
11738
  const right = this.parseLogicalAnd();
11738
- const { start } = result.span;
11739
11739
  result = new Binary(this.span(start), this.sourceSpan(start), '||', result, right);
11740
11740
  }
11741
11741
  return result;
11742
11742
  }
11743
11743
  parseLogicalAnd() {
11744
11744
  // '&&'
11745
+ const start = this.inputIndex;
11745
11746
  let result = this.parseEquality();
11746
11747
  while (this.consumeOptionalOperator('&&')) {
11747
11748
  const right = this.parseEquality();
11748
- const { start } = result.span;
11749
11749
  result = new Binary(this.span(start), this.sourceSpan(start), '&&', result, right);
11750
11750
  }
11751
11751
  return result;
11752
11752
  }
11753
11753
  parseEquality() {
11754
11754
  // '==','!=','===','!=='
11755
+ const start = this.inputIndex;
11755
11756
  let result = this.parseRelational();
11756
11757
  while (this.next.type == TokenType$1.Operator) {
11757
11758
  const operator = this.next.strValue;
@@ -11762,7 +11763,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11762
11763
  case '!==':
11763
11764
  this.advance();
11764
11765
  const right = this.parseRelational();
11765
- const { start } = result.span;
11766
11766
  result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
11767
11767
  continue;
11768
11768
  }
@@ -11772,6 +11772,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11772
11772
  }
11773
11773
  parseRelational() {
11774
11774
  // '<', '>', '<=', '>='
11775
+ const start = this.inputIndex;
11775
11776
  let result = this.parseAdditive();
11776
11777
  while (this.next.type == TokenType$1.Operator) {
11777
11778
  const operator = this.next.strValue;
@@ -11782,7 +11783,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11782
11783
  case '>=':
11783
11784
  this.advance();
11784
11785
  const right = this.parseAdditive();
11785
- const { start } = result.span;
11786
11786
  result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
11787
11787
  continue;
11788
11788
  }
@@ -11792,6 +11792,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11792
11792
  }
11793
11793
  parseAdditive() {
11794
11794
  // '+', '-'
11795
+ const start = this.inputIndex;
11795
11796
  let result = this.parseMultiplicative();
11796
11797
  while (this.next.type == TokenType$1.Operator) {
11797
11798
  const operator = this.next.strValue;
@@ -11800,7 +11801,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11800
11801
  case '-':
11801
11802
  this.advance();
11802
11803
  let right = this.parseMultiplicative();
11803
- const { start } = result.span;
11804
11804
  result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
11805
11805
  continue;
11806
11806
  }
@@ -11810,6 +11810,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11810
11810
  }
11811
11811
  parseMultiplicative() {
11812
11812
  // '*', '%', '/'
11813
+ const start = this.inputIndex;
11813
11814
  let result = this.parsePrefix();
11814
11815
  while (this.next.type == TokenType$1.Operator) {
11815
11816
  const operator = this.next.strValue;
@@ -11819,7 +11820,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11819
11820
  case '/':
11820
11821
  this.advance();
11821
11822
  let right = this.parsePrefix();
11822
- const { start } = result.span;
11823
11823
  result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
11824
11824
  continue;
11825
11825
  }
@@ -11850,14 +11850,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11850
11850
  return this.parseCallChain();
11851
11851
  }
11852
11852
  parseCallChain() {
11853
+ const start = this.inputIndex;
11853
11854
  let result = this.parsePrimary();
11854
- const resultStart = result.span.start;
11855
11855
  while (true) {
11856
11856
  if (this.consumeOptionalCharacter($PERIOD)) {
11857
- result = this.parseAccessMemberOrMethodCall(result, false);
11857
+ result = this.parseAccessMemberOrMethodCall(result, start, false);
11858
11858
  }
11859
11859
  else if (this.consumeOptionalOperator('?.')) {
11860
- result = this.parseAccessMemberOrMethodCall(result, true);
11860
+ result = this.parseAccessMemberOrMethodCall(result, start, true);
11861
11861
  }
11862
11862
  else if (this.consumeOptionalCharacter($LBRACKET)) {
11863
11863
  this.withContext(ParseContextFlags.Writable, () => {
@@ -11870,11 +11870,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11870
11870
  this.expectCharacter($RBRACKET);
11871
11871
  if (this.consumeOptionalOperator('=')) {
11872
11872
  const value = this.parseConditional();
11873
- result = new KeyedWrite(this.span(resultStart), this.sourceSpan(resultStart), result, key, value);
11873
+ result = new KeyedWrite(this.span(start), this.sourceSpan(start), result, key, value);
11874
11874
  }
11875
11875
  else {
11876
- result =
11877
- new KeyedRead(this.span(resultStart), this.sourceSpan(resultStart), result, key);
11876
+ result = new KeyedRead(this.span(start), this.sourceSpan(start), result, key);
11878
11877
  }
11879
11878
  });
11880
11879
  }
@@ -11883,11 +11882,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11883
11882
  const args = this.parseCallArguments();
11884
11883
  this.rparensExpected--;
11885
11884
  this.expectCharacter($RPAREN);
11886
- result =
11887
- new FunctionCall(this.span(resultStart), this.sourceSpan(resultStart), result, args);
11885
+ result = new FunctionCall(this.span(start), this.sourceSpan(start), result, args);
11888
11886
  }
11889
11887
  else if (this.consumeOptionalOperator('!')) {
11890
- result = new NonNullAssert(this.span(resultStart), this.sourceSpan(resultStart), result);
11888
+ result = new NonNullAssert(this.span(start), this.sourceSpan(start), result);
11891
11889
  }
11892
11890
  else {
11893
11891
  return result;
@@ -11934,7 +11932,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11934
11932
  return this.parseLiteralMap();
11935
11933
  }
11936
11934
  else if (this.next.isIdentifier()) {
11937
- return this.parseAccessMemberOrMethodCall(new ImplicitReceiver(this.span(start), this.sourceSpan(start)), false);
11935
+ return this.parseAccessMemberOrMethodCall(new ImplicitReceiver(this.span(start), this.sourceSpan(start)), start, false);
11938
11936
  }
11939
11937
  else if (this.next.isNumber()) {
11940
11938
  const value = this.next.toNumber();
@@ -11986,8 +11984,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11986
11984
  }
11987
11985
  return new LiteralMap(this.span(start), this.sourceSpan(start), keys, values);
11988
11986
  }
11989
- parseAccessMemberOrMethodCall(receiver, isSafe = false) {
11990
- const start = receiver.span.start;
11987
+ parseAccessMemberOrMethodCall(receiver, start, isSafe = false) {
11991
11988
  const nameStart = this.inputIndex;
11992
11989
  const id = this.withContext(ParseContextFlags.Writable, () => {
11993
11990
  var _a;
@@ -13220,6 +13217,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
13220
13217
  else if (identifier.length === 0) {
13221
13218
  this.reportError(`Reference does not have a name`, sourceSpan);
13222
13219
  }
13220
+ else if (references.some(reference => reference.name === identifier)) {
13221
+ this.reportError(`Reference "#${identifier}" is defined more than once`, sourceSpan);
13222
+ }
13223
13223
  references.push(new Reference(identifier, value, sourceSpan, keySpan, valueSpan));
13224
13224
  }
13225
13225
  parseAssignmentEvent(name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan) {
@@ -17011,7 +17011,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
17011
17011
  * Use of this source code is governed by an MIT-style license that can be
17012
17012
  * found in the LICENSE file at https://angular.io/license
17013
17013
  */
17014
- const VERSION$1 = new Version('11.2.0-rc.0');
17014
+ const VERSION$1 = new Version('11.2.0');
17015
17015
 
17016
17016
  /**
17017
17017
  * @license
@@ -17668,7 +17668,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
17668
17668
  */
17669
17669
  function createDirectiveDefinitionMap(meta) {
17670
17670
  const definitionMap = new DefinitionMap();
17671
- definitionMap.set('version', literal('11.2.0-rc.0'));
17671
+ definitionMap.set('version', literal('11.2.0'));
17672
17672
  // e.g. `type: MyDirective`
17673
17673
  definitionMap.set('type', meta.internalType);
17674
17674
  // e.g. `selector: 'some-dir'`
@@ -21116,7 +21116,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21116
21116
  * Use of this source code is governed by an MIT-style license that can be
21117
21117
  * found in the LICENSE file at https://angular.io/license
21118
21118
  */
21119
- const VERSION$2 = new Version('11.2.0-rc.0');
21119
+ const VERSION$2 = new Version('11.2.0');
21120
21120
 
21121
21121
  /**
21122
21122
  * @license
@@ -21212,6 +21212,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21212
21212
  * has been discovered.
21213
21213
  */
21214
21214
  ErrorCode[ErrorCode["UNDECORATED_CLASS_USING_ANGULAR_FEATURES"] = 2007] = "UNDECORATED_CLASS_USING_ANGULAR_FEATURES";
21215
+ /**
21216
+ * Raised when an component cannot resolve an external resource, such as a template or a style
21217
+ * sheet.
21218
+ */
21219
+ ErrorCode[ErrorCode["COMPONENT_RESOURCE_NOT_FOUND"] = 2008] = "COMPONENT_RESOURCE_NOT_FOUND";
21215
21220
  ErrorCode[ErrorCode["SYMBOL_NOT_EXPORTED"] = 3001] = "SYMBOL_NOT_EXPORTED";
21216
21221
  ErrorCode[ErrorCode["SYMBOL_EXPORTED_UNDER_DIFFERENT_NAME"] = 3002] = "SYMBOL_EXPORTED_UNDER_DIFFERENT_NAME";
21217
21222
  ErrorCode[ErrorCode["CONFIG_FLAT_MODULE_NO_INDEX"] = 4001] = "CONFIG_FLAT_MODULE_NO_INDEX";
@@ -28558,31 +28563,35 @@ Either add the @Injectable() decorator to '${provider.node.name
28558
28563
  const meta = this._resolveLiteral(decorator);
28559
28564
  const component = reflectObjectLiteral(meta);
28560
28565
  const containingFile = node.getSourceFile().fileName;
28561
- // Convert a styleUrl string into a Promise to preload it.
28562
- const resolveStyleUrl = (styleUrl) => {
28563
- const resourceUrl = this.resourceLoader.resolve(styleUrl, containingFile);
28564
- const promise = this.resourceLoader.preload(resourceUrl);
28565
- return promise || Promise.resolve();
28566
+ const resolveStyleUrl = (styleUrl, nodeForError, resourceType) => {
28567
+ const resourceUrl = this._resolveResourceOrThrow(styleUrl, containingFile, nodeForError, resourceType);
28568
+ return this.resourceLoader.preload(resourceUrl);
28566
28569
  };
28567
28570
  // A Promise that waits for the template and all <link>ed styles within it to be preloaded.
28568
- const templateAndTemplateStyleResources = this._preloadAndParseTemplate(node, decorator, component, containingFile).then(template => {
28571
+ const templateAndTemplateStyleResources = this._preloadAndParseTemplate(node, decorator, component, containingFile)
28572
+ .then((template) => {
28569
28573
  if (template === null) {
28570
28574
  return undefined;
28571
28575
  }
28572
- else {
28573
- return Promise.all(template.styleUrls.map(resolveStyleUrl)).then(() => undefined);
28574
- }
28576
+ const nodeForError = getTemplateDeclarationNodeForError(template.declaration);
28577
+ return Promise
28578
+ .all(template.styleUrls.map(styleUrl => resolveStyleUrl(styleUrl, nodeForError, 1 /* StylesheetFromTemplate */)))
28579
+ .then(() => undefined);
28575
28580
  });
28576
28581
  // Extract all the styleUrls in the decorator.
28577
- const styleUrls = this._extractStyleUrls(component, []);
28578
- if (styleUrls === null) {
28582
+ const componentStyleUrls = this._extractComponentStyleUrls(component);
28583
+ if (componentStyleUrls === null) {
28579
28584
  // A fast path exists if there are no styleUrls, to just wait for
28580
28585
  // templateAndTemplateStyleResources.
28581
28586
  return templateAndTemplateStyleResources;
28582
28587
  }
28583
28588
  else {
28584
28589
  // Wait for both the template and all styleUrl resources to resolve.
28585
- return Promise.all([templateAndTemplateStyleResources, ...styleUrls.map(resolveStyleUrl)])
28590
+ return Promise
28591
+ .all([
28592
+ templateAndTemplateStyleResources,
28593
+ ...componentStyleUrls.map(styleUrl => resolveStyleUrl(styleUrl.url, styleUrl.nodeForError, 2 /* StylesheetFromDecorator */))
28594
+ ])
28586
28595
  .then(() => undefined);
28587
28596
  }
28588
28597
  }
@@ -28651,20 +28660,20 @@ Either add the @Injectable() decorator to '${provider.node.name
28651
28660
  // Figure out the set of styles. The ordering here is important: external resources (styleUrls)
28652
28661
  // precede inline styles, and styles defined in the template override styles defined in the
28653
28662
  // component.
28654
- let styles = null;
28663
+ let styles = [];
28655
28664
  const styleResources = this._extractStyleResources(component, containingFile);
28656
- const styleUrls = this._extractStyleUrls(component, template.styleUrls);
28657
- if (styleUrls !== null) {
28658
- if (styles === null) {
28659
- styles = [];
28660
- }
28661
- for (const styleUrl of styleUrls) {
28662
- const resourceUrl = this.resourceLoader.resolve(styleUrl, containingFile);
28663
- const resourceStr = this.resourceLoader.load(resourceUrl);
28664
- styles.push(resourceStr);
28665
- if (this.depTracker !== null) {
28666
- this.depTracker.addResourceDependency(node.getSourceFile(), absoluteFrom(resourceUrl));
28667
- }
28665
+ const styleUrls = [
28666
+ ...this._extractComponentStyleUrls(component), ...this._extractTemplateStyleUrls(template)
28667
+ ];
28668
+ for (const styleUrl of styleUrls) {
28669
+ const resourceType = styleUrl.source === 2 /* StylesheetFromDecorator */ ?
28670
+ 2 /* StylesheetFromDecorator */ :
28671
+ 1 /* StylesheetFromTemplate */;
28672
+ const resourceUrl = this._resolveResourceOrThrow(styleUrl.url, containingFile, styleUrl.nodeForError, resourceType);
28673
+ const resourceStr = this.resourceLoader.load(resourceUrl);
28674
+ styles.push(resourceStr);
28675
+ if (this.depTracker !== null) {
28676
+ this.depTracker.addResourceDependency(node.getSourceFile(), absoluteFrom(resourceUrl));
28668
28677
  }
28669
28678
  }
28670
28679
  let inlineStyles = null;
@@ -28672,21 +28681,11 @@ Either add the @Injectable() decorator to '${provider.node.name
28672
28681
  const litStyles = parseFieldArrayValue(component, 'styles', this.evaluator);
28673
28682
  if (litStyles !== null) {
28674
28683
  inlineStyles = [...litStyles];
28675
- if (styles === null) {
28676
- styles = litStyles;
28677
- }
28678
- else {
28679
- styles.push(...litStyles);
28680
- }
28684
+ styles.push(...litStyles);
28681
28685
  }
28682
28686
  }
28683
28687
  if (template.styles.length > 0) {
28684
- if (styles === null) {
28685
- styles = template.styles;
28686
- }
28687
- else {
28688
- styles.push(...template.styles);
28689
- }
28688
+ styles.push(...template.styles);
28690
28689
  }
28691
28690
  const encapsulation = this._resolveEnumValue(component, 'encapsulation', 'ViewEncapsulation') || 0;
28692
28691
  const changeDetection = this._resolveEnumValue(component, 'changeDetection', 'ChangeDetectionStrategy');
@@ -28702,7 +28701,7 @@ Either add the @Injectable() decorator to '${provider.node.name
28702
28701
  meta: Object.assign(Object.assign({}, metadata), { template: {
28703
28702
  nodes: template.nodes,
28704
28703
  ngContentSelectors: template.ngContentSelectors,
28705
- }, encapsulation, interpolation: (_a = template.interpolationConfig) !== null && _a !== void 0 ? _a : DEFAULT_INTERPOLATION_CONFIG, styles: styles || [],
28704
+ }, encapsulation, interpolation: (_a = template.interpolationConfig) !== null && _a !== void 0 ? _a : DEFAULT_INTERPOLATION_CONFIG, styles,
28706
28705
  // These will be replaced during the compilation step, after all `NgModule`s have been
28707
28706
  // analyzed and the full compilation scope for the component can be realized.
28708
28707
  animations, viewProviders: wrappedViewProviders, i18nUseExternalIds: this.i18nUseExternalIds, relativeContextFilePath }),
@@ -28893,7 +28892,10 @@ Either add the @Injectable() decorator to '${provider.node.name
28893
28892
  let styles = [];
28894
28893
  if (analysis.styleUrls !== null) {
28895
28894
  for (const styleUrl of analysis.styleUrls) {
28896
- const resolvedStyleUrl = this.resourceLoader.resolve(styleUrl, containingFile);
28895
+ const resourceType = styleUrl.source === 2 /* StylesheetFromDecorator */ ?
28896
+ 2 /* StylesheetFromDecorator */ :
28897
+ 1 /* StylesheetFromTemplate */;
28898
+ const resolvedStyleUrl = this._resolveResourceOrThrow(styleUrl.url, containingFile, styleUrl.nodeForError, resourceType);
28897
28899
  const styleText = this.resourceLoader.load(resolvedStyleUrl);
28898
28900
  styles.push(styleText);
28899
28901
  }
@@ -28966,16 +28968,45 @@ Either add the @Injectable() decorator to '${provider.node.name
28966
28968
  }
28967
28969
  return resolved;
28968
28970
  }
28969
- _extractStyleUrls(component, extraUrls) {
28971
+ _extractComponentStyleUrls(component) {
28970
28972
  if (!component.has('styleUrls')) {
28971
- return extraUrls.length > 0 ? extraUrls : null;
28973
+ return [];
28972
28974
  }
28973
- const styleUrlsExpr = component.get('styleUrls');
28974
- const styleUrls = this.evaluator.evaluate(styleUrlsExpr);
28975
- if (!Array.isArray(styleUrls) || !styleUrls.every(url => typeof url === 'string')) {
28976
- throw createValueHasWrongTypeError(styleUrlsExpr, styleUrls, 'styleUrls must be an array of strings');
28975
+ return this._extractStyleUrlsFromExpression(component.get('styleUrls'));
28976
+ }
28977
+ _extractStyleUrlsFromExpression(styleUrlsExpr) {
28978
+ const styleUrls = [];
28979
+ if (ts$1.isArrayLiteralExpression(styleUrlsExpr)) {
28980
+ for (const styleUrlExpr of styleUrlsExpr.elements) {
28981
+ if (ts$1.isSpreadElement(styleUrlExpr)) {
28982
+ styleUrls.push(...this._extractStyleUrlsFromExpression(styleUrlExpr.expression));
28983
+ }
28984
+ else {
28985
+ const styleUrl = this.evaluator.evaluate(styleUrlExpr);
28986
+ if (typeof styleUrl !== 'string') {
28987
+ throw createValueHasWrongTypeError(styleUrlExpr, styleUrl, 'styleUrl must be a string');
28988
+ }
28989
+ styleUrls.push({
28990
+ url: styleUrl,
28991
+ source: 2 /* StylesheetFromDecorator */,
28992
+ nodeForError: styleUrlExpr,
28993
+ });
28994
+ }
28995
+ }
28996
+ }
28997
+ else {
28998
+ const evaluatedStyleUrls = this.evaluator.evaluate(styleUrlsExpr);
28999
+ if (!isStringArray(evaluatedStyleUrls)) {
29000
+ throw createValueHasWrongTypeError(styleUrlsExpr, evaluatedStyleUrls, 'styleUrls must be an array of strings');
29001
+ }
29002
+ for (const styleUrl of evaluatedStyleUrls) {
29003
+ styleUrls.push({
29004
+ url: styleUrl,
29005
+ source: 2 /* StylesheetFromDecorator */,
29006
+ nodeForError: styleUrlsExpr,
29007
+ });
29008
+ }
28977
29009
  }
28978
- styleUrls.push(...extraUrls);
28979
29010
  return styleUrls;
28980
29011
  }
28981
29012
  _extractStyleResources(component, containingFile) {
@@ -28988,7 +29019,7 @@ Either add the @Injectable() decorator to '${provider.node.name
28988
29019
  const styleUrlsExpr = component.get('styleUrls');
28989
29020
  if (styleUrlsExpr !== undefined && ts$1.isArrayLiteralExpression(styleUrlsExpr)) {
28990
29021
  for (const expression of stringLiteralElements(styleUrlsExpr)) {
28991
- const resourceUrl = this.resourceLoader.resolve(expression.text, containingFile);
29022
+ const resourceUrl = this._resolveResourceOrThrow(expression.text, containingFile, expression, 2 /* StylesheetFromDecorator */);
28992
29023
  styles.add({ path: absoluteFrom(resourceUrl), expression });
28993
29024
  }
28994
29025
  }
@@ -29008,7 +29039,7 @@ Either add the @Injectable() decorator to '${provider.node.name
29008
29039
  if (typeof templateUrl !== 'string') {
29009
29040
  throw createValueHasWrongTypeError(templateUrlExpr, templateUrl, 'templateUrl must be a string');
29010
29041
  }
29011
- const resourceUrl = this.resourceLoader.resolve(templateUrl, containingFile);
29042
+ const resourceUrl = this._resolveResourceOrThrow(templateUrl, containingFile, templateUrlExpr, 0 /* Template */);
29012
29043
  const templatePromise = this.resourceLoader.preload(resourceUrl);
29013
29044
  // If the preload worked, then actually load and parse the template, and wait for any style
29014
29045
  // URLs to resolve.
@@ -29151,7 +29182,7 @@ Either add the @Injectable() decorator to '${provider.node.name
29151
29182
  if (typeof templateUrl !== 'string') {
29152
29183
  throw createValueHasWrongTypeError(templateUrlExpr, templateUrl, 'templateUrl must be a string');
29153
29184
  }
29154
- const resourceUrl = this.resourceLoader.resolve(templateUrl, containingFile);
29185
+ const resourceUrl = this._resolveResourceOrThrow(templateUrl, containingFile, templateUrlExpr, 0 /* Template */);
29155
29186
  return {
29156
29187
  isInline: false,
29157
29188
  interpolationConfig,
@@ -29199,6 +29230,38 @@ Either add the @Injectable() decorator to '${provider.node.name
29199
29230
  }
29200
29231
  this.cycleAnalyzer.recordSyntheticImport(origin, imported);
29201
29232
  }
29233
+ /**
29234
+ * Resolve the url of a resource relative to the file that contains the reference to it.
29235
+ *
29236
+ * Throws a FatalDiagnosticError when unable to resolve the file.
29237
+ */
29238
+ _resolveResourceOrThrow(file, basePath, nodeForError, resourceType) {
29239
+ try {
29240
+ return this.resourceLoader.resolve(file, basePath);
29241
+ }
29242
+ catch (e) {
29243
+ let errorText;
29244
+ switch (resourceType) {
29245
+ case 0 /* Template */:
29246
+ errorText = `Could not find template file '${file}'.`;
29247
+ break;
29248
+ case 1 /* StylesheetFromTemplate */:
29249
+ errorText = `Could not find stylesheet file '${file}' linked from the template.`;
29250
+ break;
29251
+ case 2 /* StylesheetFromDecorator */:
29252
+ errorText = `Could not find stylesheet file '${file}'.`;
29253
+ break;
29254
+ }
29255
+ throw new FatalDiagnosticError(ErrorCode.COMPONENT_RESOURCE_NOT_FOUND, nodeForError, errorText);
29256
+ }
29257
+ }
29258
+ _extractTemplateStyleUrls(template) {
29259
+ if (template.styleUrls === null) {
29260
+ return [];
29261
+ }
29262
+ const nodeForError = getTemplateDeclarationNodeForError(template.declaration);
29263
+ return template.styleUrls.map(url => ({ url, source: 1 /* StylesheetFromTemplate */, nodeForError }));
29264
+ }
29202
29265
  }
29203
29266
  function getTemplateRange(templateExpr) {
29204
29267
  const startPos = templateExpr.getStart() + 1;
@@ -29221,6 +29284,22 @@ Either add the @Injectable() decorator to '${provider.node.name
29221
29284
  return resourceUrl;
29222
29285
  }
29223
29286
  }
29287
+ /** Determines if the result of an evaluation is a string array. */
29288
+ function isStringArray(resolvedValue) {
29289
+ return Array.isArray(resolvedValue) && resolvedValue.every(elem => typeof elem === 'string');
29290
+ }
29291
+ /** Determines the node to use for debugging purposes for the given TemplateDeclaration. */
29292
+ function getTemplateDeclarationNodeForError(declaration) {
29293
+ // TODO(zarend): Change this to if/else when that is compatible with g3. This uses a switch
29294
+ // because if/else fails to compile on g3. That is because g3 compiles this in non-strict mode
29295
+ // where type inference does not work correctly.
29296
+ switch (declaration.isInline) {
29297
+ case true:
29298
+ return declaration.expression;
29299
+ case false:
29300
+ return declaration.templateUrlExpression;
29301
+ }
29302
+ }
29224
29303
 
29225
29304
  /**
29226
29305
  * @license
@@ -34061,8 +34140,6 @@ Either add the @Injectable() decorator to '${provider.node.name
34061
34140
  this.typeCtorStatements = [];
34062
34141
  this.pipeInsts = new Map();
34063
34142
  this.pipeInstStatements = [];
34064
- this.outputHelperIdent = null;
34065
- this.helperStatements = [];
34066
34143
  }
34067
34144
  /**
34068
34145
  * Get an expression referring to a type constructor for the given directive.
@@ -34122,85 +34199,6 @@ Either add the @Injectable() decorator to '${provider.node.name
34122
34199
  this.pipeInsts.set(ref.node, pipeInstId);
34123
34200
  return pipeInstId;
34124
34201
  }
34125
- /**
34126
- * Declares a helper function to be able to cast directive outputs of type `EventEmitter<T>` to
34127
- * have an accurate `subscribe()` method that properly carries over the generic type `T` into the
34128
- * listener function passed as argument to `subscribe`. This is done to work around a typing
34129
- * deficiency in `EventEmitter.subscribe`, where the listener function is typed as any.
34130
- */
34131
- declareOutputHelper() {
34132
- if (this.outputHelperIdent !== null) {
34133
- return this.outputHelperIdent;
34134
- }
34135
- const outputHelperIdent = ts$1.createIdentifier('_outputHelper');
34136
- const genericTypeDecl = ts$1.createTypeParameterDeclaration('T');
34137
- const genericTypeRef = ts$1.createTypeReferenceNode('T', /* typeParameters */ undefined);
34138
- const eventEmitter = this.referenceExternalType('@angular/core', 'EventEmitter', [new ExpressionType(new WrappedNodeExpr(genericTypeRef))]);
34139
- // Declare a type that has a `subscribe` method that carries over type `T` as parameter
34140
- // into the callback. The below code generates the following type literal:
34141
- // `{subscribe(cb: (event: T) => any): void;}`
34142
- const observableLike = ts$1.createTypeLiteralNode([ts$1.createMethodSignature(
34143
- /* typeParameters */ undefined,
34144
- /* parameters */ [ts$1.createParameter(
34145
- /* decorators */ undefined,
34146
- /* modifiers */ undefined,
34147
- /* dotDotDotToken */ undefined,
34148
- /* name */ 'cb',
34149
- /* questionToken */ undefined,
34150
- /* type */
34151
- ts$1.createFunctionTypeNode(
34152
- /* typeParameters */ undefined,
34153
- /* parameters */ [ts$1.createParameter(
34154
- /* decorators */ undefined,
34155
- /* modifiers */ undefined,
34156
- /* dotDotDotToken */ undefined,
34157
- /* name */ 'event',
34158
- /* questionToken */ undefined,
34159
- /* type */ genericTypeRef)],
34160
- /* type */ ts$1.createKeywordTypeNode(ts$1.SyntaxKind.AnyKeyword)))],
34161
- /* type */ ts$1.createKeywordTypeNode(ts$1.SyntaxKind.VoidKeyword),
34162
- /* name */ 'subscribe',
34163
- /* questionToken */ undefined)]);
34164
- // Declares the first signature of `_outputHelper` that matches arguments of type
34165
- // `EventEmitter`, to convert them into `observableLike` defined above. The following
34166
- // statement is generated:
34167
- // `declare function _outputHelper<T>(output: EventEmitter<T>): observableLike;`
34168
- this.helperStatements.push(ts$1.createFunctionDeclaration(
34169
- /* decorators */ undefined,
34170
- /* modifiers */ [ts$1.createModifier(ts$1.SyntaxKind.DeclareKeyword)],
34171
- /* asteriskToken */ undefined,
34172
- /* name */ outputHelperIdent,
34173
- /* typeParameters */ [genericTypeDecl],
34174
- /* parameters */ [ts$1.createParameter(
34175
- /* decorators */ undefined,
34176
- /* modifiers */ undefined,
34177
- /* dotDotDotToken */ undefined,
34178
- /* name */ 'output',
34179
- /* questionToken */ undefined,
34180
- /* type */ eventEmitter)],
34181
- /* type */ observableLike,
34182
- /* body */ undefined));
34183
- // Declares the second signature of `_outputHelper` that matches all other argument types,
34184
- // i.e. ensures type identity for output types other than `EventEmitter`. This corresponds
34185
- // with the following statement:
34186
- // `declare function _outputHelper<T>(output: T): T;`
34187
- this.helperStatements.push(ts$1.createFunctionDeclaration(
34188
- /* decorators */ undefined,
34189
- /* modifiers */ [ts$1.createModifier(ts$1.SyntaxKind.DeclareKeyword)],
34190
- /* asteriskToken */ undefined,
34191
- /* name */ outputHelperIdent,
34192
- /* typeParameters */ [genericTypeDecl],
34193
- /* parameters */ [ts$1.createParameter(
34194
- /* decorators */ undefined,
34195
- /* modifiers */ undefined,
34196
- /* dotDotDotToken */ undefined,
34197
- /* name */ 'output',
34198
- /* questionToken */ undefined,
34199
- /* type */ genericTypeRef)],
34200
- /* type */ genericTypeRef,
34201
- /* body */ undefined));
34202
- return this.outputHelperIdent = outputHelperIdent;
34203
- }
34204
34202
  /**
34205
34203
  * Generate a `ts.Expression` that references the given node.
34206
34204
  *
@@ -34242,7 +34240,6 @@ Either add the @Injectable() decorator to '${provider.node.name
34242
34240
  }
34243
34241
  getPreludeStatements() {
34244
34242
  return [
34245
- ...this.helperStatements,
34246
34243
  ...this.pipeInstStatements,
34247
34244
  ...this.typeCtorStatements,
34248
34245
  ];
@@ -35717,16 +35714,8 @@ Either add the @Injectable() decorator to '${provider.node.name
35717
35714
  // For strict checking of directive events, generate a call to the `subscribe` method
35718
35715
  // on the directive's output field to let type information flow into the handler function's
35719
35716
  // `$event` parameter.
35720
- //
35721
- // Note that the `EventEmitter<T>` type from '@angular/core' that is typically used for
35722
- // outputs has a typings deficiency in its `subscribe` method. The generic type `T` is not
35723
- // carried into the handler function, which is vital for inference of the type of `$event`.
35724
- // As a workaround, the directive's field is passed into a helper function that has a
35725
- // specially crafted set of signatures, to effectively cast `EventEmitter<T>` to something
35726
- // that has a `subscribe` method that properly carries the `T` into the handler function.
35727
35717
  const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 0 /* Infer */);
35728
- const outputHelper = ts$1.createCall(this.tcb.env.declareOutputHelper(), undefined, [outputField]);
35729
- const subscribeFn = ts$1.createPropertyAccess(outputHelper, 'subscribe');
35718
+ const subscribeFn = ts$1.createPropertyAccess(outputField, 'subscribe');
35730
35719
  const call = ts$1.createCall(subscribeFn, /* typeArguments */ undefined, [handler]);
35731
35720
  addParseSpanInfo(call, output.sourceSpan);
35732
35721
  this.scope.addStatement(ts$1.createExpressionStatement(call));
@@ -36634,9 +36623,6 @@ Either add the @Injectable() decorator to '${provider.node.name
36634
36623
  '\n\n';
36635
36624
  const printer = ts$1.createPrinter();
36636
36625
  source += '\n';
36637
- for (const stmt of this.helperStatements) {
36638
- source += printer.printNode(ts$1.EmitHint.Unspecified, stmt, this.contextFile) + '\n';
36639
- }
36640
36626
  for (const stmt of this.pipeInstStatements) {
36641
36627
  source += printer.printNode(ts$1.EmitHint.Unspecified, stmt, this.contextFile) + '\n';
36642
36628
  }
@@ -37248,7 +37234,7 @@ Either add the @Injectable() decorator to '${provider.node.name
37248
37234
  return null;
37249
37235
  }
37250
37236
  // Outputs in the TCB look like one of the two:
37251
- // * _outputHelper(_t1["outputField"]).subscribe(handler);
37237
+ // * _t1["outputField"].subscribe(handler);
37252
37238
  // * _t1.addEventListener(handler);
37253
37239
  // Even with strict null checks disabled, we still produce the access as a separate statement
37254
37240
  // so that it can be found here.
@@ -41051,7 +41037,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
41051
41037
  const definitions = [];
41052
41038
  for (const definitionMeta of definitionMetas) {
41053
41039
  // The `$event` of event handlers would point to the $event parameter in the shim file, as in
41054
- // `_outputHelper(_t3["x"]).subscribe(function ($event): any { $event }) ;`
41040
+ // `_t3["x"].subscribe(function ($event): any { $event }) ;`
41055
41041
  // If we wanted to return something for this, it would be more appropriate for something like
41056
41042
  // `getTypeDefinition`.
41057
41043
  if (isDollarEvent(definitionMeta.node)) {