1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ import { absoluteFrom } from '@angular/compiler-cli/src/ngtsc/file_system' ;
9
+ import { TemplateTypeChecker } from '@angular/compiler-cli/src/ngtsc/typecheck/api' ;
10
+ import { ExpressionIdentifier , hasExpressionIdentifier } from '@angular/compiler-cli/src/ngtsc/typecheck/src/comments' ;
11
+ import * as ts from 'typescript' ;
12
+
13
+ import { findTightestNode } from './ts_utils' ;
14
+ import { getTemplateLocationFromShimLocation , toTextSpan } from './utils' ;
15
+
16
+
17
+ /**
18
+ * Converts a given `ts.DocumentSpan` in a shim file to its equivalent `ts.DocumentSpan` in the
19
+ * template.
20
+ *
21
+ * You can optionally provide a `requiredNodeText` that ensures the equivalent template node's text
22
+ * matches. If it does not, this function will return `null`.
23
+ */
24
+ export function convertToTemplateDocumentSpan < T extends ts . DocumentSpan > (
25
+ shimDocumentSpan : T , templateTypeChecker : TemplateTypeChecker , program : ts . Program ,
26
+ requiredNodeText ?: string ) : T | null {
27
+ const sf = program . getSourceFile ( shimDocumentSpan . fileName ) ;
28
+ if ( sf === undefined ) {
29
+ return null ;
30
+ }
31
+ const tcbNode = findTightestNode ( sf , shimDocumentSpan . textSpan . start ) ;
32
+ if ( tcbNode === undefined ||
33
+ hasExpressionIdentifier ( sf , tcbNode , ExpressionIdentifier . EVENT_PARAMETER ) ) {
34
+ // If the reference result is the $event parameter in the subscribe/addEventListener
35
+ // function in the TCB, we want to filter this result out of the references. We really only
36
+ // want to return references to the parameter in the template itself.
37
+ return null ;
38
+ }
39
+ // TODO(atscott): Determine how to consistently resolve paths. i.e. with the project
40
+ // serverHost or LSParseConfigHost in the adapter. We should have a better defined way to
41
+ // normalize paths.
42
+ const mapping = getTemplateLocationFromShimLocation (
43
+ templateTypeChecker , absoluteFrom ( shimDocumentSpan . fileName ) ,
44
+ shimDocumentSpan . textSpan . start ) ;
45
+ if ( mapping === null ) {
46
+ return null ;
47
+ }
48
+
49
+ const { span, templateUrl} = mapping ;
50
+ if ( requiredNodeText !== undefined && span . toString ( ) !== requiredNodeText ) {
51
+ return null ;
52
+ }
53
+
54
+ return {
55
+ ...shimDocumentSpan ,
56
+ fileName : templateUrl ,
57
+ textSpan : toTextSpan ( span ) ,
58
+ // Specifically clear other text span values because we do not have enough knowledge to
59
+ // convert these to spans in the template.
60
+ contextSpan : undefined ,
61
+ originalContextSpan : undefined ,
62
+ originalTextSpan : undefined ,
63
+ } ;
64
+ }
0 commit comments