@angular/language-service 12.2.11 → 12.2.15

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 v12.2.11
2
+ * @license Angular v12.2.15
3
3
  * Copyright Google LLC All Rights Reserved.
4
4
  * License: MIT
5
5
  */
@@ -2687,846 +2687,994 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
2687
2687
  * Use of this source code is governed by an MIT-style license that can be
2688
2688
  * found in the LICENSE file at https://angular.io/license
2689
2689
  */
2690
- /**
2691
- * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently
2692
- * require the implementation of a visitor for Comments as they are only collected at
2693
- * the top-level of the R3 AST, and only if `Render3ParseOptions['collectCommentNodes']`
2694
- * is true.
2695
- */
2696
- class Comment {
2697
- constructor(value, sourceSpan) {
2698
- this.value = value;
2699
- this.sourceSpan = sourceSpan;
2690
+ // https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
2691
+ const VERSION = 3;
2692
+ const JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,';
2693
+ class SourceMapGenerator {
2694
+ constructor(file = null) {
2695
+ this.file = file;
2696
+ this.sourcesContent = new Map();
2697
+ this.lines = [];
2698
+ this.lastCol0 = 0;
2699
+ this.hasMappings = false;
2700
2700
  }
2701
- visit(_visitor) {
2702
- throw new Error('visit() not implemented for Comment');
2701
+ // The content is `null` when the content is expected to be loaded using the URL
2702
+ addSource(url, content = null) {
2703
+ if (!this.sourcesContent.has(url)) {
2704
+ this.sourcesContent.set(url, content);
2705
+ }
2706
+ return this;
2703
2707
  }
2704
- }
2705
- class Text {
2706
- constructor(value, sourceSpan) {
2707
- this.value = value;
2708
- this.sourceSpan = sourceSpan;
2708
+ addLine() {
2709
+ this.lines.push([]);
2710
+ this.lastCol0 = 0;
2711
+ return this;
2709
2712
  }
2710
- visit(visitor) {
2711
- return visitor.visitText(this);
2713
+ addMapping(col0, sourceUrl, sourceLine0, sourceCol0) {
2714
+ if (!this.currentLine) {
2715
+ throw new Error(`A line must be added before mappings can be added`);
2716
+ }
2717
+ if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) {
2718
+ throw new Error(`Unknown source file "${sourceUrl}"`);
2719
+ }
2720
+ if (col0 == null) {
2721
+ throw new Error(`The column in the generated code must be provided`);
2722
+ }
2723
+ if (col0 < this.lastCol0) {
2724
+ throw new Error(`Mapping should be added in output order`);
2725
+ }
2726
+ if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) {
2727
+ throw new Error(`The source location must be provided when a source url is provided`);
2728
+ }
2729
+ this.hasMappings = true;
2730
+ this.lastCol0 = col0;
2731
+ this.currentLine.push({ col0, sourceUrl, sourceLine0, sourceCol0 });
2732
+ return this;
2733
+ }
2734
+ /**
2735
+ * @internal strip this from published d.ts files due to
2736
+ * https://github.com/microsoft/TypeScript/issues/36216
2737
+ */
2738
+ get currentLine() {
2739
+ return this.lines.slice(-1)[0];
2740
+ }
2741
+ toJSON() {
2742
+ if (!this.hasMappings) {
2743
+ return null;
2744
+ }
2745
+ const sourcesIndex = new Map();
2746
+ const sources = [];
2747
+ const sourcesContent = [];
2748
+ Array.from(this.sourcesContent.keys()).forEach((url, i) => {
2749
+ sourcesIndex.set(url, i);
2750
+ sources.push(url);
2751
+ sourcesContent.push(this.sourcesContent.get(url) || null);
2752
+ });
2753
+ let mappings = '';
2754
+ let lastCol0 = 0;
2755
+ let lastSourceIndex = 0;
2756
+ let lastSourceLine0 = 0;
2757
+ let lastSourceCol0 = 0;
2758
+ this.lines.forEach(segments => {
2759
+ lastCol0 = 0;
2760
+ mappings += segments
2761
+ .map(segment => {
2762
+ // zero-based starting column of the line in the generated code
2763
+ let segAsStr = toBase64VLQ(segment.col0 - lastCol0);
2764
+ lastCol0 = segment.col0;
2765
+ if (segment.sourceUrl != null) {
2766
+ // zero-based index into the “sources” list
2767
+ segAsStr +=
2768
+ toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex);
2769
+ lastSourceIndex = sourcesIndex.get(segment.sourceUrl);
2770
+ // the zero-based starting line in the original source
2771
+ segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0);
2772
+ lastSourceLine0 = segment.sourceLine0;
2773
+ // the zero-based starting column in the original source
2774
+ segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0);
2775
+ lastSourceCol0 = segment.sourceCol0;
2776
+ }
2777
+ return segAsStr;
2778
+ })
2779
+ .join(',');
2780
+ mappings += ';';
2781
+ });
2782
+ mappings = mappings.slice(0, -1);
2783
+ return {
2784
+ 'file': this.file || '',
2785
+ 'version': VERSION,
2786
+ 'sourceRoot': '',
2787
+ 'sources': sources,
2788
+ 'sourcesContent': sourcesContent,
2789
+ 'mappings': mappings,
2790
+ };
2791
+ }
2792
+ toJsComment() {
2793
+ return this.hasMappings ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0)) :
2794
+ '';
2712
2795
  }
2713
2796
  }
2714
- class BoundText {
2715
- constructor(value, sourceSpan, i18n) {
2716
- this.value = value;
2717
- this.sourceSpan = sourceSpan;
2718
- this.i18n = i18n;
2797
+ function toBase64String(value) {
2798
+ let b64 = '';
2799
+ const encoded = utf8Encode(value);
2800
+ for (let i = 0; i < encoded.length;) {
2801
+ const i1 = encoded[i++];
2802
+ const i2 = i < encoded.length ? encoded[i++] : null;
2803
+ const i3 = i < encoded.length ? encoded[i++] : null;
2804
+ b64 += toBase64Digit(i1 >> 2);
2805
+ b64 += toBase64Digit(((i1 & 3) << 4) | (i2 === null ? 0 : i2 >> 4));
2806
+ b64 += i2 === null ? '=' : toBase64Digit(((i2 & 15) << 2) | (i3 === null ? 0 : i3 >> 6));
2807
+ b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63);
2719
2808
  }
2720
- visit(visitor) {
2721
- return visitor.visitBoundText(this);
2809
+ return b64;
2810
+ }
2811
+ function toBase64VLQ(value) {
2812
+ value = value < 0 ? ((-value) << 1) + 1 : value << 1;
2813
+ let out = '';
2814
+ do {
2815
+ let digit = value & 31;
2816
+ value = value >> 5;
2817
+ if (value > 0) {
2818
+ digit = digit | 32;
2819
+ }
2820
+ out += toBase64Digit(digit);
2821
+ } while (value > 0);
2822
+ return out;
2823
+ }
2824
+ const B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
2825
+ function toBase64Digit(value) {
2826
+ if (value < 0 || value >= 64) {
2827
+ throw new Error(`Can only encode value in the range [0, 63]`);
2722
2828
  }
2829
+ return B64_DIGITS[value];
2723
2830
  }
2831
+
2724
2832
  /**
2725
- * Represents a text attribute in the template.
2833
+ * @license
2834
+ * Copyright Google LLC All Rights Reserved.
2726
2835
  *
2727
- * `valueSpan` may not be present in cases where there is no value `<div a></div>`.
2728
- * `keySpan` may also not be present for synthetic attributes from ICU expansions.
2836
+ * Use of this source code is governed by an MIT-style license that can be
2837
+ * found in the LICENSE file at https://angular.io/license
2729
2838
  */
2730
- class TextAttribute {
2731
- constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
2732
- this.name = name;
2733
- this.value = value;
2734
- this.sourceSpan = sourceSpan;
2735
- this.keySpan = keySpan;
2736
- this.valueSpan = valueSpan;
2737
- this.i18n = i18n;
2738
- }
2739
- visit(visitor) {
2740
- return visitor.visitTextAttribute(this);
2839
+ const _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
2840
+ const _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
2841
+ const _INDENT_WITH = ' ';
2842
+ const CATCH_ERROR_VAR$1 = variable('error', null, null);
2843
+ const CATCH_STACK_VAR$1 = variable('stack', null, null);
2844
+ class _EmittedLine {
2845
+ constructor(indent) {
2846
+ this.indent = indent;
2847
+ this.partsLength = 0;
2848
+ this.parts = [];
2849
+ this.srcSpans = [];
2741
2850
  }
2742
2851
  }
2743
- class BoundAttribute {
2744
- constructor(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan, i18n) {
2745
- this.name = name;
2746
- this.type = type;
2747
- this.securityContext = securityContext;
2748
- this.value = value;
2749
- this.unit = unit;
2750
- this.sourceSpan = sourceSpan;
2751
- this.keySpan = keySpan;
2752
- this.valueSpan = valueSpan;
2753
- this.i18n = i18n;
2852
+ class EmitterVisitorContext {
2853
+ constructor(_indent) {
2854
+ this._indent = _indent;
2855
+ this._classes = [];
2856
+ this._preambleLineCount = 0;
2857
+ this._lines = [new _EmittedLine(_indent)];
2754
2858
  }
2755
- static fromBoundElementProperty(prop, i18n) {
2756
- if (prop.keySpan === undefined) {
2757
- throw new Error(`Unexpected state: keySpan must be defined for bound attributes but was not for ${prop.name}: ${prop.sourceSpan}`);
2758
- }
2759
- return new BoundAttribute(prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n);
2859
+ static createRoot() {
2860
+ return new EmitterVisitorContext(0);
2760
2861
  }
2761
- visit(visitor) {
2762
- return visitor.visitBoundAttribute(this);
2862
+ /**
2863
+ * @internal strip this from published d.ts files due to
2864
+ * https://github.com/microsoft/TypeScript/issues/36216
2865
+ */
2866
+ get _currentLine() {
2867
+ return this._lines[this._lines.length - 1];
2763
2868
  }
2764
- }
2765
- class BoundEvent {
2766
- constructor(name, type, handler, target, phase, sourceSpan, handlerSpan, keySpan) {
2767
- this.name = name;
2768
- this.type = type;
2769
- this.handler = handler;
2770
- this.target = target;
2771
- this.phase = phase;
2772
- this.sourceSpan = sourceSpan;
2773
- this.handlerSpan = handlerSpan;
2774
- this.keySpan = keySpan;
2869
+ println(from, lastPart = '') {
2870
+ this.print(from || null, lastPart, true);
2775
2871
  }
2776
- static fromParsedEvent(event) {
2777
- const target = event.type === 0 /* Regular */ ? event.targetOrPhase : null;
2778
- const phase = event.type === 1 /* Animation */ ? event.targetOrPhase : null;
2779
- if (event.keySpan === undefined) {
2780
- throw new Error(`Unexpected state: keySpan must be defined for bound event but was not for ${event.name}: ${event.sourceSpan}`);
2781
- }
2782
- return new BoundEvent(event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan, event.keySpan);
2872
+ lineIsEmpty() {
2873
+ return this._currentLine.parts.length === 0;
2783
2874
  }
2784
- visit(visitor) {
2785
- return visitor.visitBoundEvent(this);
2875
+ lineLength() {
2876
+ return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;
2786
2877
  }
2787
- }
2788
- class Element {
2789
- constructor(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
2790
- this.name = name;
2791
- this.attributes = attributes;
2792
- this.inputs = inputs;
2793
- this.outputs = outputs;
2794
- this.children = children;
2795
- this.references = references;
2796
- this.sourceSpan = sourceSpan;
2797
- this.startSourceSpan = startSourceSpan;
2798
- this.endSourceSpan = endSourceSpan;
2799
- this.i18n = i18n;
2800
- }
2801
- visit(visitor) {
2802
- return visitor.visitElement(this);
2803
- }
2804
- }
2805
- class Template {
2806
- constructor(tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
2807
- this.tagName = tagName;
2808
- this.attributes = attributes;
2809
- this.inputs = inputs;
2810
- this.outputs = outputs;
2811
- this.templateAttrs = templateAttrs;
2812
- this.children = children;
2813
- this.references = references;
2814
- this.variables = variables;
2815
- this.sourceSpan = sourceSpan;
2816
- this.startSourceSpan = startSourceSpan;
2817
- this.endSourceSpan = endSourceSpan;
2818
- this.i18n = i18n;
2819
- }
2820
- visit(visitor) {
2821
- return visitor.visitTemplate(this);
2822
- }
2823
- }
2824
- class Content {
2825
- constructor(selector, attributes, sourceSpan, i18n) {
2826
- this.selector = selector;
2827
- this.attributes = attributes;
2828
- this.sourceSpan = sourceSpan;
2829
- this.i18n = i18n;
2830
- this.name = 'ng-content';
2831
- }
2832
- visit(visitor) {
2833
- return visitor.visitContent(this);
2834
- }
2835
- }
2836
- class Variable {
2837
- constructor(name, value, sourceSpan, keySpan, valueSpan) {
2838
- this.name = name;
2839
- this.value = value;
2840
- this.sourceSpan = sourceSpan;
2841
- this.keySpan = keySpan;
2842
- this.valueSpan = valueSpan;
2878
+ print(from, part, newLine = false) {
2879
+ if (part.length > 0) {
2880
+ this._currentLine.parts.push(part);
2881
+ this._currentLine.partsLength += part.length;
2882
+ this._currentLine.srcSpans.push(from && from.sourceSpan || null);
2883
+ }
2884
+ if (newLine) {
2885
+ this._lines.push(new _EmittedLine(this._indent));
2886
+ }
2843
2887
  }
2844
- visit(visitor) {
2845
- return visitor.visitVariable(this);
2888
+ removeEmptyLastLine() {
2889
+ if (this.lineIsEmpty()) {
2890
+ this._lines.pop();
2891
+ }
2846
2892
  }
2847
- }
2848
- class Reference {
2849
- constructor(name, value, sourceSpan, keySpan, valueSpan) {
2850
- this.name = name;
2851
- this.value = value;
2852
- this.sourceSpan = sourceSpan;
2853
- this.keySpan = keySpan;
2854
- this.valueSpan = valueSpan;
2893
+ incIndent() {
2894
+ this._indent++;
2895
+ if (this.lineIsEmpty()) {
2896
+ this._currentLine.indent = this._indent;
2897
+ }
2855
2898
  }
2856
- visit(visitor) {
2857
- return visitor.visitReference(this);
2899
+ decIndent() {
2900
+ this._indent--;
2901
+ if (this.lineIsEmpty()) {
2902
+ this._currentLine.indent = this._indent;
2903
+ }
2858
2904
  }
2859
- }
2860
- class Icu {
2861
- constructor(vars, placeholders, sourceSpan, i18n) {
2862
- this.vars = vars;
2863
- this.placeholders = placeholders;
2864
- this.sourceSpan = sourceSpan;
2865
- this.i18n = i18n;
2905
+ pushClass(clazz) {
2906
+ this._classes.push(clazz);
2866
2907
  }
2867
- visit(visitor) {
2868
- return visitor.visitIcu(this);
2908
+ popClass() {
2909
+ return this._classes.pop();
2869
2910
  }
2870
- }
2871
- class RecursiveVisitor {
2872
- visitElement(element) {
2873
- visitAll(this, element.attributes);
2874
- visitAll(this, element.inputs);
2875
- visitAll(this, element.outputs);
2876
- visitAll(this, element.children);
2877
- visitAll(this, element.references);
2911
+ get currentClass() {
2912
+ return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null;
2878
2913
  }
2879
- visitTemplate(template) {
2880
- visitAll(this, template.attributes);
2881
- visitAll(this, template.inputs);
2882
- visitAll(this, template.outputs);
2883
- visitAll(this, template.children);
2884
- visitAll(this, template.references);
2885
- visitAll(this, template.variables);
2914
+ toSource() {
2915
+ return this.sourceLines
2916
+ .map(l => l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : '')
2917
+ .join('\n');
2886
2918
  }
2887
- visitContent(content) { }
2888
- visitVariable(variable) { }
2889
- visitReference(reference) { }
2890
- visitTextAttribute(attribute) { }
2891
- visitBoundAttribute(attribute) { }
2892
- visitBoundEvent(attribute) { }
2893
- visitText(text) { }
2894
- visitBoundText(text) { }
2895
- visitIcu(icu) { }
2896
- }
2897
- function visitAll(visitor, nodes) {
2898
- const result = [];
2899
- if (visitor.visit) {
2900
- for (const node of nodes) {
2901
- const newNode = visitor.visit(node) || node.visit(visitor);
2919
+ toSourceMapGenerator(genFilePath, startsAtLine = 0) {
2920
+ const map = new SourceMapGenerator(genFilePath);
2921
+ let firstOffsetMapped = false;
2922
+ const mapFirstOffsetIfNeeded = () => {
2923
+ if (!firstOffsetMapped) {
2924
+ // Add a single space so that tools won't try to load the file from disk.
2925
+ // Note: We are using virtual urls like `ng:///`, so we have to
2926
+ // provide a content here.
2927
+ map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);
2928
+ firstOffsetMapped = true;
2929
+ }
2930
+ };
2931
+ for (let i = 0; i < startsAtLine; i++) {
2932
+ map.addLine();
2933
+ mapFirstOffsetIfNeeded();
2902
2934
  }
2935
+ this.sourceLines.forEach((line, lineIdx) => {
2936
+ map.addLine();
2937
+ const spans = line.srcSpans;
2938
+ const parts = line.parts;
2939
+ let col0 = line.indent * _INDENT_WITH.length;
2940
+ let spanIdx = 0;
2941
+ // skip leading parts without source spans
2942
+ while (spanIdx < spans.length && !spans[spanIdx]) {
2943
+ col0 += parts[spanIdx].length;
2944
+ spanIdx++;
2945
+ }
2946
+ if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {
2947
+ firstOffsetMapped = true;
2948
+ }
2949
+ else {
2950
+ mapFirstOffsetIfNeeded();
2951
+ }
2952
+ while (spanIdx < spans.length) {
2953
+ const span = spans[spanIdx];
2954
+ const source = span.start.file;
2955
+ const sourceLine = span.start.line;
2956
+ const sourceCol = span.start.col;
2957
+ map.addSource(source.url, source.content)
2958
+ .addMapping(col0, source.url, sourceLine, sourceCol);
2959
+ col0 += parts[spanIdx].length;
2960
+ spanIdx++;
2961
+ // assign parts without span or the same span to the previous segment
2962
+ while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) {
2963
+ col0 += parts[spanIdx].length;
2964
+ spanIdx++;
2965
+ }
2966
+ }
2967
+ });
2968
+ return map;
2903
2969
  }
2904
- else {
2905
- for (const node of nodes) {
2906
- const newNode = node.visit(visitor);
2907
- if (newNode) {
2908
- result.push(newNode);
2970
+ setPreambleLineCount(count) {
2971
+ return this._preambleLineCount = count;
2972
+ }
2973
+ spanOf(line, column) {
2974
+ const emittedLine = this._lines[line - this._preambleLineCount];
2975
+ if (emittedLine) {
2976
+ let columnsLeft = column - _createIndent(emittedLine.indent).length;
2977
+ for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {
2978
+ const part = emittedLine.parts[partIndex];
2979
+ if (part.length > columnsLeft) {
2980
+ return emittedLine.srcSpans[partIndex];
2981
+ }
2982
+ columnsLeft -= part.length;
2909
2983
  }
2910
2984
  }
2985
+ return null;
2911
2986
  }
2912
- return result;
2913
- }
2914
-
2915
- /**
2916
- * @license
2917
- * Copyright Google LLC All Rights Reserved.
2918
- *
2919
- * Use of this source code is governed by an MIT-style license that can be
2920
- * found in the LICENSE file at https://angular.io/license
2921
- */
2922
- class Message {
2923
2987
  /**
2924
- * @param nodes message AST
2925
- * @param placeholders maps placeholder names to static content and their source spans
2926
- * @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
2927
- * @param meaning
2928
- * @param description
2929
- * @param customId
2988
+ * @internal strip this from published d.ts files due to
2989
+ * https://github.com/microsoft/TypeScript/issues/36216
2930
2990
  */
2931
- constructor(nodes, placeholders, placeholderToMessage, meaning, description, customId) {
2932
- this.nodes = nodes;
2933
- this.placeholders = placeholders;
2934
- this.placeholderToMessage = placeholderToMessage;
2935
- this.meaning = meaning;
2936
- this.description = description;
2937
- this.customId = customId;
2938
- this.id = this.customId;
2939
- /** The ids to use if there are no custom id and if `i18nLegacyMessageIdFormat` is not empty */
2940
- this.legacyIds = [];
2941
- if (nodes.length) {
2942
- this.sources = [{
2943
- filePath: nodes[0].sourceSpan.start.file.url,
2944
- startLine: nodes[0].sourceSpan.start.line + 1,
2945
- startCol: nodes[0].sourceSpan.start.col + 1,
2946
- endLine: nodes[nodes.length - 1].sourceSpan.end.line + 1,
2947
- endCol: nodes[0].sourceSpan.start.col + 1
2948
- }];
2949
- }
2950
- else {
2951
- this.sources = [];
2991
+ get sourceLines() {
2992
+ if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {
2993
+ return this._lines.slice(0, -1);
2952
2994
  }
2995
+ return this._lines;
2953
2996
  }
2954
2997
  }
2955
- class Text$1 {
2956
- constructor(value, sourceSpan) {
2957
- this.value = value;
2958
- this.sourceSpan = sourceSpan;
2959
- }
2960
- visit(visitor, context) {
2961
- return visitor.visitText(this, context);
2998
+ class AbstractEmitterVisitor {
2999
+ constructor(_escapeDollarInStrings) {
3000
+ this._escapeDollarInStrings = _escapeDollarInStrings;
2962
3001
  }
2963
- }
2964
- // TODO(vicb): do we really need this node (vs an array) ?
2965
- class Container {
2966
- constructor(children, sourceSpan) {
2967
- this.children = children;
2968
- this.sourceSpan = sourceSpan;
3002
+ printLeadingComments(stmt, ctx) {
3003
+ if (stmt.leadingComments === undefined) {
3004
+ return;
3005
+ }
3006
+ for (const comment of stmt.leadingComments) {
3007
+ if (comment instanceof JSDocComment) {
3008
+ ctx.print(stmt, `/*${comment.toString()}*/`, comment.trailingNewline);
3009
+ }
3010
+ else {
3011
+ if (comment.multiline) {
3012
+ ctx.print(stmt, `/* ${comment.text} */`, comment.trailingNewline);
3013
+ }
3014
+ else {
3015
+ comment.text.split('\n').forEach((line) => {
3016
+ ctx.println(stmt, `// ${line}`);
3017
+ });
3018
+ }
3019
+ }
3020
+ }
2969
3021
  }
2970
- visit(visitor, context) {
2971
- return visitor.visitContainer(this, context);
3022
+ visitExpressionStmt(stmt, ctx) {
3023
+ this.printLeadingComments(stmt, ctx);
3024
+ stmt.expr.visitExpression(this, ctx);
3025
+ ctx.println(stmt, ';');
3026
+ return null;
2972
3027
  }
2973
- }
2974
- class Icu$1 {
2975
- constructor(expression, type, cases, sourceSpan) {
2976
- this.expression = expression;
2977
- this.type = type;
2978
- this.cases = cases;
2979
- this.sourceSpan = sourceSpan;
3028
+ visitReturnStmt(stmt, ctx) {
3029
+ this.printLeadingComments(stmt, ctx);
3030
+ ctx.print(stmt, `return `);
3031
+ stmt.value.visitExpression(this, ctx);
3032
+ ctx.println(stmt, ';');
3033
+ return null;
2980
3034
  }
2981
- visit(visitor, context) {
2982
- return visitor.visitIcu(this, context);
3035
+ visitIfStmt(stmt, ctx) {
3036
+ this.printLeadingComments(stmt, ctx);
3037
+ ctx.print(stmt, `if (`);
3038
+ stmt.condition.visitExpression(this, ctx);
3039
+ ctx.print(stmt, `) {`);
3040
+ const hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0;
3041
+ if (stmt.trueCase.length <= 1 && !hasElseCase) {
3042
+ ctx.print(stmt, ` `);
3043
+ this.visitAllStatements(stmt.trueCase, ctx);
3044
+ ctx.removeEmptyLastLine();
3045
+ ctx.print(stmt, ` `);
3046
+ }
3047
+ else {
3048
+ ctx.println();
3049
+ ctx.incIndent();
3050
+ this.visitAllStatements(stmt.trueCase, ctx);
3051
+ ctx.decIndent();
3052
+ if (hasElseCase) {
3053
+ ctx.println(stmt, `} else {`);
3054
+ ctx.incIndent();
3055
+ this.visitAllStatements(stmt.falseCase, ctx);
3056
+ ctx.decIndent();
3057
+ }
3058
+ }
3059
+ ctx.println(stmt, `}`);
3060
+ return null;
2983
3061
  }
2984
- }
2985
- class TagPlaceholder {
2986
- constructor(tag, attrs, startName, closeName, children, isVoid,
2987
- // TODO sourceSpan should cover all (we need a startSourceSpan and endSourceSpan)
2988
- sourceSpan, startSourceSpan, endSourceSpan) {
2989
- this.tag = tag;
2990
- this.attrs = attrs;
2991
- this.startName = startName;
2992
- this.closeName = closeName;
2993
- this.children = children;
2994
- this.isVoid = isVoid;
2995
- this.sourceSpan = sourceSpan;
2996
- this.startSourceSpan = startSourceSpan;
2997
- this.endSourceSpan = endSourceSpan;
3062
+ visitThrowStmt(stmt, ctx) {
3063
+ this.printLeadingComments(stmt, ctx);
3064
+ ctx.print(stmt, `throw `);
3065
+ stmt.error.visitExpression(this, ctx);
3066
+ ctx.println(stmt, `;`);
3067
+ return null;
2998
3068
  }
2999
- visit(visitor, context) {
3000
- return visitor.visitTagPlaceholder(this, context);
3069
+ visitWriteVarExpr(expr, ctx) {
3070
+ const lineWasEmpty = ctx.lineIsEmpty();
3071
+ if (!lineWasEmpty) {
3072
+ ctx.print(expr, '(');
3073
+ }
3074
+ ctx.print(expr, `${expr.name} = `);
3075
+ expr.value.visitExpression(this, ctx);
3076
+ if (!lineWasEmpty) {
3077
+ ctx.print(expr, ')');
3078
+ }
3079
+ return null;
3001
3080
  }
3002
- }
3003
- class Placeholder {
3004
- constructor(value, name, sourceSpan) {
3005
- this.value = value;
3006
- this.name = name;
3007
- this.sourceSpan = sourceSpan;
3081
+ visitWriteKeyExpr(expr, ctx) {
3082
+ const lineWasEmpty = ctx.lineIsEmpty();
3083
+ if (!lineWasEmpty) {
3084
+ ctx.print(expr, '(');
3085
+ }
3086
+ expr.receiver.visitExpression(this, ctx);
3087
+ ctx.print(expr, `[`);
3088
+ expr.index.visitExpression(this, ctx);
3089
+ ctx.print(expr, `] = `);
3090
+ expr.value.visitExpression(this, ctx);
3091
+ if (!lineWasEmpty) {
3092
+ ctx.print(expr, ')');
3093
+ }
3094
+ return null;
3008
3095
  }
3009
- visit(visitor, context) {
3010
- return visitor.visitPlaceholder(this, context);
3096
+ visitWritePropExpr(expr, ctx) {
3097
+ const lineWasEmpty = ctx.lineIsEmpty();
3098
+ if (!lineWasEmpty) {
3099
+ ctx.print(expr, '(');
3100
+ }
3101
+ expr.receiver.visitExpression(this, ctx);
3102
+ ctx.print(expr, `.${expr.name} = `);
3103
+ expr.value.visitExpression(this, ctx);
3104
+ if (!lineWasEmpty) {
3105
+ ctx.print(expr, ')');
3106
+ }
3107
+ return null;
3011
3108
  }
3012
- }
3013
- class IcuPlaceholder {
3014
- constructor(value, name, sourceSpan) {
3015
- this.value = value;
3016
- this.name = name;
3017
- this.sourceSpan = sourceSpan;
3109
+ visitInvokeMethodExpr(expr, ctx) {
3110
+ expr.receiver.visitExpression(this, ctx);
3111
+ let name = expr.name;
3112
+ if (expr.builtin != null) {
3113
+ name = this.getBuiltinMethodName(expr.builtin);
3114
+ if (name == null) {
3115
+ // some builtins just mean to skip the call.
3116
+ return null;
3117
+ }
3118
+ }
3119
+ ctx.print(expr, `.${name}(`);
3120
+ this.visitAllExpressions(expr.args, ctx, `,`);
3121
+ ctx.print(expr, `)`);
3122
+ return null;
3018
3123
  }
3019
- visit(visitor, context) {
3020
- return visitor.visitIcuPlaceholder(this, context);
3124
+ visitInvokeFunctionExpr(expr, ctx) {
3125
+ expr.fn.visitExpression(this, ctx);
3126
+ ctx.print(expr, `(`);
3127
+ this.visitAllExpressions(expr.args, ctx, ',');
3128
+ ctx.print(expr, `)`);
3129
+ return null;
3021
3130
  }
3022
- }
3023
-
3024
- /**
3025
- * @license
3026
- * Copyright Google LLC All Rights Reserved.
3027
- *
3028
- * Use of this source code is governed by an MIT-style license that can be
3029
- * found in the LICENSE file at https://angular.io/license
3030
- */
3031
- /**
3032
- * Represents a big integer using a buffer of its individual digits, with the least significant
3033
- * digit stored at the beginning of the array (little endian).
3034
- *
3035
- * For performance reasons, each instance is mutable. The addition operation can be done in-place
3036
- * to reduce memory pressure of allocation for the digits array.
3037
- */
3038
- class BigInteger {
3039
- /**
3040
- * Creates a big integer using its individual digits in little endian storage.
3041
- */
3042
- constructor(digits) {
3043
- this.digits = digits;
3131
+ visitTaggedTemplateExpr(expr, ctx) {
3132
+ expr.tag.visitExpression(this, ctx);
3133
+ ctx.print(expr, '`' + expr.template.elements[0].rawText);
3134
+ for (let i = 1; i < expr.template.elements.length; i++) {
3135
+ ctx.print(expr, '${');
3136
+ expr.template.expressions[i - 1].visitExpression(this, ctx);
3137
+ ctx.print(expr, `}${expr.template.elements[i].rawText}`);
3138
+ }
3139
+ ctx.print(expr, '`');
3140
+ return null;
3044
3141
  }
3045
- static zero() {
3046
- return new BigInteger([0]);
3142
+ visitWrappedNodeExpr(ast, ctx) {
3143
+ throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');
3047
3144
  }
3048
- static one() {
3049
- return new BigInteger([1]);
3145
+ visitTypeofExpr(expr, ctx) {
3146
+ ctx.print(expr, 'typeof ');
3147
+ expr.expr.visitExpression(this, ctx);
3050
3148
  }
3051
- /**
3052
- * Creates a clone of this instance.
3053
- */
3054
- clone() {
3055
- return new BigInteger(this.digits.slice());
3149
+ visitReadVarExpr(ast, ctx) {
3150
+ let varName = ast.name;
3151
+ if (ast.builtin != null) {
3152
+ switch (ast.builtin) {
3153
+ case BuiltinVar.Super:
3154
+ varName = 'super';
3155
+ break;
3156
+ case BuiltinVar.This:
3157
+ varName = 'this';
3158
+ break;
3159
+ case BuiltinVar.CatchError:
3160
+ varName = CATCH_ERROR_VAR$1.name;
3161
+ break;
3162
+ case BuiltinVar.CatchStack:
3163
+ varName = CATCH_STACK_VAR$1.name;
3164
+ break;
3165
+ default:
3166
+ throw new Error(`Unknown builtin variable ${ast.builtin}`);
3167
+ }
3168
+ }
3169
+ ctx.print(ast, varName);
3170
+ return null;
3056
3171
  }
3057
- /**
3058
- * Returns a new big integer with the sum of `this` and `other` as its value. This does not mutate
3059
- * `this` but instead returns a new instance, unlike `addToSelf`.
3060
- */
3061
- add(other) {
3062
- const result = this.clone();
3063
- result.addToSelf(other);
3064
- return result;
3172
+ visitInstantiateExpr(ast, ctx) {
3173
+ ctx.print(ast, `new `);
3174
+ ast.classExpr.visitExpression(this, ctx);
3175
+ ctx.print(ast, `(`);
3176
+ this.visitAllExpressions(ast.args, ctx, ',');
3177
+ ctx.print(ast, `)`);
3178
+ return null;
3065
3179
  }
3066
- /**
3067
- * Adds `other` to the instance itself, thereby mutating its value.
3068
- */
3069
- addToSelf(other) {
3070
- const maxNrOfDigits = Math.max(this.digits.length, other.digits.length);
3071
- let carry = 0;
3072
- for (let i = 0; i < maxNrOfDigits; i++) {
3073
- let digitSum = carry;
3074
- if (i < this.digits.length) {
3075
- digitSum += this.digits[i];
3076
- }
3077
- if (i < other.digits.length) {
3078
- digitSum += other.digits[i];
3079
- }
3080
- if (digitSum >= 10) {
3081
- this.digits[i] = digitSum - 10;
3082
- carry = 1;
3083
- }
3084
- else {
3085
- this.digits[i] = digitSum;
3086
- carry = 0;
3087
- }
3180
+ visitLiteralExpr(ast, ctx) {
3181
+ const value = ast.value;
3182
+ if (typeof value === 'string') {
3183
+ ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings));
3088
3184
  }
3089
- // Apply a remaining carry if needed.
3090
- if (carry > 0) {
3091
- this.digits[maxNrOfDigits] = 1;
3185
+ else {
3186
+ ctx.print(ast, `${value}`);
3092
3187
  }
3188
+ return null;
3093
3189
  }
3094
- /**
3095
- * Builds the decimal string representation of the big integer. As this is stored in
3096
- * little endian, the digits are concatenated in reverse order.
3097
- */
3098
- toString() {
3099
- let res = '';
3100
- for (let i = this.digits.length - 1; i >= 0; i--) {
3101
- res += this.digits[i];
3190
+ visitLocalizedString(ast, ctx) {
3191
+ const head = ast.serializeI18nHead();
3192
+ ctx.print(ast, '$localize `' + head.raw);
3193
+ for (let i = 1; i < ast.messageParts.length; i++) {
3194
+ ctx.print(ast, '${');
3195
+ ast.expressions[i - 1].visitExpression(this, ctx);
3196
+ ctx.print(ast, `}${ast.serializeI18nTemplatePart(i).raw}`);
3102
3197
  }
3103
- return res;
3198
+ ctx.print(ast, '`');
3199
+ return null;
3104
3200
  }
3105
- }
3106
- /**
3107
- * Represents a big integer which is optimized for multiplication operations, as its power-of-twos
3108
- * are memoized. See `multiplyBy()` for details on the multiplication algorithm.
3109
- */
3110
- class BigIntForMultiplication {
3111
- constructor(value) {
3112
- this.powerOfTwos = [value];
3201
+ visitConditionalExpr(ast, ctx) {
3202
+ ctx.print(ast, `(`);
3203
+ ast.condition.visitExpression(this, ctx);
3204
+ ctx.print(ast, '? ');
3205
+ ast.trueCase.visitExpression(this, ctx);
3206
+ ctx.print(ast, ': ');
3207
+ ast.falseCase.visitExpression(this, ctx);
3208
+ ctx.print(ast, `)`);
3209
+ return null;
3113
3210
  }
3114
- /**
3115
- * Returns the big integer itself.
3116
- */
3117
- getValue() {
3118
- return this.powerOfTwos[0];
3211
+ visitNotExpr(ast, ctx) {
3212
+ ctx.print(ast, '!');
3213
+ ast.condition.visitExpression(this, ctx);
3214
+ return null;
3119
3215
  }
3120
- /**
3121
- * Computes the value for `num * b`, where `num` is a JS number and `b` is a big integer. The
3122
- * value for `b` is represented by a storage model that is optimized for this computation.
3123
- *
3124
- * This operation is implemented in N(log2(num)) by continuous halving of the number, where the
3125
- * least-significant bit (LSB) is tested in each iteration. If the bit is set, the bit's index is
3126
- * used as exponent into the power-of-two multiplication of `b`.
3127
- *
3128
- * As an example, consider the multiplication num=42, b=1337. In binary 42 is 0b00101010 and the
3129
- * algorithm unrolls into the following iterations:
3130
- *
3131
- * Iteration | num | LSB | b * 2^iter | Add? | product
3132
- * -----------|------------|------|------------|------|--------
3133
- * 0 | 0b00101010 | 0 | 1337 | No | 0
3134
- * 1 | 0b00010101 | 1 | 2674 | Yes | 2674
3135
- * 2 | 0b00001010 | 0 | 5348 | No | 2674
3136
- * 3 | 0b00000101 | 1 | 10696 | Yes | 13370
3137
- * 4 | 0b00000010 | 0 | 21392 | No | 13370
3138
- * 5 | 0b00000001 | 1 | 42784 | Yes | 56154
3139
- * 6 | 0b00000000 | 0 | 85568 | No | 56154
3140
- *
3141
- * The computed product of 56154 is indeed the correct result.
3142
- *
3143
- * The `BigIntForMultiplication` representation for a big integer provides memoized access to the
3144
- * power-of-two values to reduce the workload in computing those values.
3145
- */
3146
- multiplyBy(num) {
3147
- const product = BigInteger.zero();
3148
- this.multiplyByAndAddTo(num, product);
3149
- return product;
3216
+ visitAssertNotNullExpr(ast, ctx) {
3217
+ ast.condition.visitExpression(this, ctx);
3218
+ return null;
3150
3219
  }
3151
- /**
3152
- * See `multiplyBy()` for details. This function allows for the computed product to be added
3153
- * directly to the provided result big integer.
3154
- */
3155
- multiplyByAndAddTo(num, result) {
3156
- for (let exponent = 0; num !== 0; num = num >>> 1, exponent++) {
3157
- if (num & 1) {
3158
- const value = this.getMultipliedByPowerOfTwo(exponent);
3159
- result.addToSelf(value);
3160
- }
3220
+ visitUnaryOperatorExpr(ast, ctx) {
3221
+ let opStr;
3222
+ switch (ast.operator) {
3223
+ case UnaryOperator.Plus:
3224
+ opStr = '+';
3225
+ break;
3226
+ case UnaryOperator.Minus:
3227
+ opStr = '-';
3228
+ break;
3229
+ default:
3230
+ throw new Error(`Unknown operator ${ast.operator}`);
3161
3231
  }
3232
+ if (ast.parens)
3233
+ ctx.print(ast, `(`);
3234
+ ctx.print(ast, opStr);
3235
+ ast.expr.visitExpression(this, ctx);
3236
+ if (ast.parens)
3237
+ ctx.print(ast, `)`);
3238
+ return null;
3162
3239
  }
3163
- /**
3164
- * Computes and memoizes the big integer value for `this.number * 2^exponent`.
3165
- */
3166
- getMultipliedByPowerOfTwo(exponent) {
3167
- // Compute the powers up until the requested exponent, where each value is computed from its
3168
- // predecessor. This is simple as `this.number * 2^(exponent - 1)` only has to be doubled (i.e.
3169
- // added to itself) to reach `this.number * 2^exponent`.
3170
- for (let i = this.powerOfTwos.length; i <= exponent; i++) {
3171
- const previousPower = this.powerOfTwos[i - 1];
3172
- this.powerOfTwos[i] = previousPower.add(previousPower);
3240
+ visitBinaryOperatorExpr(ast, ctx) {
3241
+ let opStr;
3242
+ switch (ast.operator) {
3243
+ case BinaryOperator.Equals:
3244
+ opStr = '==';
3245
+ break;
3246
+ case BinaryOperator.Identical:
3247
+ opStr = '===';
3248
+ break;
3249
+ case BinaryOperator.NotEquals:
3250
+ opStr = '!=';
3251
+ break;
3252
+ case BinaryOperator.NotIdentical:
3253
+ opStr = '!==';
3254
+ break;
3255
+ case BinaryOperator.And:
3256
+ opStr = '&&';
3257
+ break;
3258
+ case BinaryOperator.BitwiseAnd:
3259
+ opStr = '&';
3260
+ break;
3261
+ case BinaryOperator.Or:
3262
+ opStr = '||';
3263
+ break;
3264
+ case BinaryOperator.Plus:
3265
+ opStr = '+';
3266
+ break;
3267
+ case BinaryOperator.Minus:
3268
+ opStr = '-';
3269
+ break;
3270
+ case BinaryOperator.Divide:
3271
+ opStr = '/';
3272
+ break;
3273
+ case BinaryOperator.Multiply:
3274
+ opStr = '*';
3275
+ break;
3276
+ case BinaryOperator.Modulo:
3277
+ opStr = '%';
3278
+ break;
3279
+ case BinaryOperator.Lower:
3280
+ opStr = '<';
3281
+ break;
3282
+ case BinaryOperator.LowerEquals:
3283
+ opStr = '<=';
3284
+ break;
3285
+ case BinaryOperator.Bigger:
3286
+ opStr = '>';
3287
+ break;
3288
+ case BinaryOperator.BiggerEquals:
3289
+ opStr = '>=';
3290
+ break;
3291
+ case BinaryOperator.NullishCoalesce:
3292
+ opStr = '??';
3293
+ break;
3294
+ default:
3295
+ throw new Error(`Unknown operator ${ast.operator}`);
3173
3296
  }
3174
- return this.powerOfTwos[exponent];
3297
+ if (ast.parens)
3298
+ ctx.print(ast, `(`);
3299
+ ast.lhs.visitExpression(this, ctx);
3300
+ ctx.print(ast, ` ${opStr} `);
3301
+ ast.rhs.visitExpression(this, ctx);
3302
+ if (ast.parens)
3303
+ ctx.print(ast, `)`);
3304
+ return null;
3175
3305
  }
3176
- }
3177
- /**
3178
- * Represents an exponentiation operation for the provided base, of which exponents are computed and
3179
- * memoized. The results are represented by a `BigIntForMultiplication` which is tailored for
3180
- * multiplication operations by memoizing the power-of-twos. This effectively results in a matrix
3181
- * representation that is lazily computed upon request.
3182
- */
3183
- class BigIntExponentiation {
3184
- constructor(base) {
3185
- this.base = base;
3186
- this.exponents = [new BigIntForMultiplication(BigInteger.one())];
3306
+ visitReadPropExpr(ast, ctx) {
3307
+ ast.receiver.visitExpression(this, ctx);
3308
+ ctx.print(ast, `.`);
3309
+ ctx.print(ast, ast.name);
3310
+ return null;
3187
3311
  }
3188
- /**
3189
- * Compute the value for `this.base^exponent`, resulting in a big integer that is optimized for
3190
- * further multiplication operations.
3191
- */
3192
- toThePowerOf(exponent) {
3193
- // Compute the results up until the requested exponent, where every value is computed from its
3194
- // predecessor. This is because `this.base^(exponent - 1)` only has to be multiplied by `base`
3195
- // to reach `this.base^exponent`.
3196
- for (let i = this.exponents.length; i <= exponent; i++) {
3197
- const value = this.exponents[i - 1].multiplyBy(this.base);
3198
- this.exponents[i] = new BigIntForMultiplication(value);
3199
- }
3200
- return this.exponents[exponent];
3312
+ visitReadKeyExpr(ast, ctx) {
3313
+ ast.receiver.visitExpression(this, ctx);
3314
+ ctx.print(ast, `[`);
3315
+ ast.index.visitExpression(this, ctx);
3316
+ ctx.print(ast, `]`);
3317
+ return null;
3201
3318
  }
3202
- }
3203
-
3204
- /**
3205
- * @license
3206
- * Copyright Google LLC All Rights Reserved.
3207
- *
3208
- * Use of this source code is governed by an MIT-style license that can be
3209
- * found in the LICENSE file at https://angular.io/license
3210
- */
3211
- /**
3212
- * Compute the message id using the XLIFF1 digest.
3213
- */
3214
- function computeDigest(message) {
3215
- return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`);
3216
- }
3217
- /**
3218
- * Return the message id or compute it using the XLIFF2/XMB/$localize digest.
3219
- */
3220
- function decimalDigest(message) {
3221
- return message.id || computeDecimalDigest(message);
3222
- }
3223
- /**
3224
- * Compute the message id using the XLIFF2/XMB/$localize digest.
3225
- */
3226
- function computeDecimalDigest(message) {
3227
- const visitor = new _SerializerIgnoreIcuExpVisitor();
3228
- const parts = message.nodes.map(a => a.visit(visitor, null));
3229
- return computeMsgId(parts.join(''), message.meaning);
3230
- }
3231
- /**
3232
- * Serialize the i18n ast to something xml-like in order to generate an UID.
3233
- *
3234
- * The visitor is also used in the i18n parser tests
3235
- *
3236
- * @internal
3237
- */
3238
- class _SerializerVisitor {
3239
- visitText(text, context) {
3240
- return text.value;
3319
+ visitLiteralArrayExpr(ast, ctx) {
3320
+ ctx.print(ast, `[`);
3321
+ this.visitAllExpressions(ast.entries, ctx, ',');
3322
+ ctx.print(ast, `]`);
3323
+ return null;
3241
3324
  }
3242
- visitContainer(container, context) {
3243
- return `[${container.children.map(child => child.visit(this)).join(', ')}]`;
3325
+ visitLiteralMapExpr(ast, ctx) {
3326
+ ctx.print(ast, `{`);
3327
+ this.visitAllObjects(entry => {
3328
+ ctx.print(ast, `${escapeIdentifier(entry.key, this._escapeDollarInStrings, entry.quoted)}:`);
3329
+ entry.value.visitExpression(this, ctx);
3330
+ }, ast.entries, ctx, ',');
3331
+ ctx.print(ast, `}`);
3332
+ return null;
3244
3333
  }
3245
- visitIcu(icu, context) {
3246
- const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
3247
- return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`;
3334
+ visitCommaExpr(ast, ctx) {
3335
+ ctx.print(ast, '(');
3336
+ this.visitAllExpressions(ast.parts, ctx, ',');
3337
+ ctx.print(ast, ')');
3338
+ return null;
3248
3339
  }
3249
- visitTagPlaceholder(ph, context) {
3250
- return ph.isVoid ?
3251
- `<ph tag name="${ph.startName}"/>` :
3252
- `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`;
3340
+ visitAllExpressions(expressions, ctx, separator) {
3341
+ this.visitAllObjects(expr => expr.visitExpression(this, ctx), expressions, ctx, separator);
3253
3342
  }
3254
- visitPlaceholder(ph, context) {
3255
- return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`;
3343
+ visitAllObjects(handler, expressions, ctx, separator) {
3344
+ let incrementedIndent = false;
3345
+ for (let i = 0; i < expressions.length; i++) {
3346
+ if (i > 0) {
3347
+ if (ctx.lineLength() > 80) {
3348
+ ctx.print(null, separator, true);
3349
+ if (!incrementedIndent) {
3350
+ // continuation are marked with double indent.
3351
+ ctx.incIndent();
3352
+ ctx.incIndent();
3353
+ incrementedIndent = true;
3354
+ }
3355
+ }
3356
+ else {
3357
+ ctx.print(null, separator, false);
3358
+ }
3359
+ }
3360
+ handler(expressions[i]);
3361
+ }
3362
+ if (incrementedIndent) {
3363
+ // continuation are marked with double indent.
3364
+ ctx.decIndent();
3365
+ ctx.decIndent();
3366
+ }
3256
3367
  }
3257
- visitIcuPlaceholder(ph, context) {
3258
- return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`;
3368
+ visitAllStatements(statements, ctx) {
3369
+ statements.forEach((stmt) => stmt.visitStatement(this, ctx));
3259
3370
  }
3260
3371
  }
3261
- const serializerVisitor = new _SerializerVisitor();
3262
- function serializeNodes(nodes) {
3263
- return nodes.map(a => a.visit(serializerVisitor, null));
3372
+ function escapeIdentifier(input, escapeDollar, alwaysQuote = true) {
3373
+ if (input == null) {
3374
+ return null;
3375
+ }
3376
+ const body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, (...match) => {
3377
+ if (match[0] == '$') {
3378
+ return escapeDollar ? '\\$' : '$';
3379
+ }
3380
+ else if (match[0] == '\n') {
3381
+ return '\\n';
3382
+ }
3383
+ else if (match[0] == '\r') {
3384
+ return '\\r';
3385
+ }
3386
+ else {
3387
+ return `\\${match[0]}`;
3388
+ }
3389
+ });
3390
+ const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);
3391
+ return requiresQuotes ? `'${body}'` : body;
3264
3392
  }
3265
- /**
3266
- * Serialize the i18n ast to something xml-like in order to generate an UID.
3267
- *
3268
- * Ignore the ICU expressions so that message IDs stays identical if only the expression changes.
3269
- *
3270
- * @internal
3271
- */
3272
- class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor {
3273
- visitIcu(icu, context) {
3274
- let strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
3275
- // Do not take the expression into account
3276
- return `{${icu.type}, ${strCases.join(', ')}}`;
3393
+ function _createIndent(count) {
3394
+ let res = '';
3395
+ for (let i = 0; i < count; i++) {
3396
+ res += _INDENT_WITH;
3277
3397
  }
3398
+ return res;
3278
3399
  }
3400
+
3279
3401
  /**
3280
- * Compute the SHA1 of the given string
3281
- *
3282
- * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
3402
+ * @license
3403
+ * Copyright Google LLC All Rights Reserved.
3283
3404
  *
3284
- * WARNING: this function has not been designed not tested with security in mind.
3285
- * DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT.
3405
+ * Use of this source code is governed by an MIT-style license that can be
3406
+ * found in the LICENSE file at https://angular.io/license
3286
3407
  */
3287
- function sha1(str) {
3288
- const utf8 = utf8Encode(str);
3289
- const words32 = bytesToWords32(utf8, Endian.Big);
3290
- const len = utf8.length * 8;
3291
- const w = newArray(80);
3292
- let a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476, e = 0xc3d2e1f0;
3293
- words32[len >> 5] |= 0x80 << (24 - len % 32);
3294
- words32[((len + 64 >> 9) << 4) + 15] = len;
3295
- for (let i = 0; i < words32.length; i += 16) {
3296
- const h0 = a, h1 = b, h2 = c, h3 = d, h4 = e;
3297
- for (let j = 0; j < 80; j++) {
3298
- if (j < 16) {
3299
- w[j] = words32[i + j];
3300
- }
3301
- else {
3302
- w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
3303
- }
3304
- const fkVal = fk(j, b, c, d);
3305
- const f = fkVal[0];
3306
- const k = fkVal[1];
3307
- const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32);
3308
- e = d;
3309
- d = c;
3310
- c = rol32(b, 30);
3311
- b = a;
3312
- a = temp;
3313
- }
3314
- a = add32(a, h0);
3315
- b = add32(b, h1);
3316
- c = add32(c, h2);
3317
- d = add32(d, h3);
3318
- e = add32(e, h4);
3319
- }
3320
- return bytesToHexString(words32ToByteString([a, b, c, d, e]));
3321
- }
3322
- function fk(index, b, c, d) {
3323
- if (index < 20) {
3324
- return [(b & c) | (~b & d), 0x5a827999];
3325
- }
3326
- if (index < 40) {
3327
- return [b ^ c ^ d, 0x6ed9eba1];
3408
+ function typeWithParameters(type, numParams) {
3409
+ if (numParams === 0) {
3410
+ return expressionType(type);
3328
3411
  }
3329
- if (index < 60) {
3330
- return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc];
3412
+ const params = [];
3413
+ for (let i = 0; i < numParams; i++) {
3414
+ params.push(DYNAMIC_TYPE);
3331
3415
  }
3332
- return [b ^ c ^ d, 0xca62c1d6];
3416
+ return expressionType(type, undefined, params);
3417
+ }
3418
+ const ANIMATE_SYMBOL_PREFIX = '@';
3419
+ function prepareSyntheticPropertyName(name) {
3420
+ return `${ANIMATE_SYMBOL_PREFIX}${name}`;
3421
+ }
3422
+ function prepareSyntheticListenerName(name, phase) {
3423
+ return `${ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;
3424
+ }
3425
+ function getSafePropertyAccessString(accessor, name) {
3426
+ const escapedName = escapeIdentifier(name, false, false);
3427
+ return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;
3428
+ }
3429
+ function prepareSyntheticListenerFunctionName(name, phase) {
3430
+ return `animation_${name}_${phase}`;
3431
+ }
3432
+ function jitOnlyGuardedExpression(expr) {
3433
+ return guardedExpression('ngJitMode', expr);
3434
+ }
3435
+ function devOnlyGuardedExpression(expr) {
3436
+ return guardedExpression('ngDevMode', expr);
3437
+ }
3438
+ function guardedExpression(guard, expr) {
3439
+ const guardExpr = new ExternalExpr({ name: guard, moduleName: null });
3440
+ const guardNotDefined = new BinaryOperatorExpr(BinaryOperator.Identical, new TypeofExpr(guardExpr), literal('undefined'));
3441
+ const guardUndefinedOrTrue = new BinaryOperatorExpr(BinaryOperator.Or, guardNotDefined, guardExpr, /* type */ undefined,
3442
+ /* sourceSpan */ undefined, true);
3443
+ return new BinaryOperatorExpr(BinaryOperator.And, guardUndefinedOrTrue, expr);
3444
+ }
3445
+ function wrapReference(value) {
3446
+ const wrapped = new WrappedNodeExpr(value);
3447
+ return { value: wrapped, type: wrapped };
3448
+ }
3449
+ function refsToArray(refs, shouldForwardDeclare) {
3450
+ const values = literalArr(refs.map(ref => ref.value));
3451
+ return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
3452
+ }
3453
+ function createMayBeForwardRefExpression(expression, forwardRef) {
3454
+ return { expression, forwardRef };
3333
3455
  }
3334
3456
  /**
3335
- * Compute the fingerprint of the given string
3457
+ * Convert a `MaybeForwardRefExpression` to an `Expression`, possibly wrapping its expression in a
3458
+ * `forwardRef()` call.
3336
3459
  *
3337
- * The output is 64 bit number encoded as a decimal string
3460
+ * If `MaybeForwardRefExpression.forwardRef` is `ForwardRefHandling.Unwrapped` then the expression
3461
+ * was originally wrapped in a `forwardRef()` call to prevent the value from being eagerly evaluated
3462
+ * in the code.
3338
3463
  *
3339
- * based on:
3340
- * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java
3464
+ * See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and
3465
+ * `packages/compiler/src/jit_compiler_facade.ts` for more information.
3341
3466
  */
3342
- function fingerprint(str) {
3343
- const utf8 = utf8Encode(str);
3344
- let hi = hash32(utf8, 0);
3345
- let lo = hash32(utf8, 102072);
3346
- if (hi == 0 && (lo == 0 || lo == 1)) {
3347
- hi = hi ^ 0x130f9bef;
3348
- lo = lo ^ -0x6b5f56d8;
3467
+ function convertFromMaybeForwardRefExpression({ expression, forwardRef }) {
3468
+ switch (forwardRef) {
3469
+ case 0 /* None */:
3470
+ case 1 /* Wrapped */:
3471
+ return expression;
3472
+ case 2 /* Unwrapped */:
3473
+ return generateForwardRef(expression);
3349
3474
  }
3350
- return [hi, lo];
3351
3475
  }
3352
- function computeMsgId(msg, meaning = '') {
3353
- let msgFingerprint = fingerprint(msg);
3354
- if (meaning) {
3355
- const meaningFingerprint = fingerprint(meaning);
3356
- msgFingerprint = add64(rol64(msgFingerprint, 1), meaningFingerprint);
3357
- }
3358
- const hi = msgFingerprint[0];
3359
- const lo = msgFingerprint[1];
3360
- return wordsToDecimalString(hi & 0x7fffffff, lo);
3476
+ /**
3477
+ * Generate an expression that has the given `expr` wrapped in the following form:
3478
+ *
3479
+ * ```
3480
+ * forwardRef(() => expr)
3481
+ * ```
3482
+ */
3483
+ function generateForwardRef(expr) {
3484
+ return importExpr(Identifiers.forwardRef).callFn([fn([], [new ReturnStatement(expr)])]);
3361
3485
  }
3362
- function hash32(bytes, c) {
3363
- let a = 0x9e3779b9, b = 0x9e3779b9;
3364
- let i;
3365
- const len = bytes.length;
3366
- for (i = 0; i + 12 <= len; i += 12) {
3367
- a = add32(a, wordAt(bytes, i, Endian.Little));
3368
- b = add32(b, wordAt(bytes, i + 4, Endian.Little));
3369
- c = add32(c, wordAt(bytes, i + 8, Endian.Little));
3370
- const res = mix(a, b, c);
3371
- a = res[0], b = res[1], c = res[2];
3486
+
3487
+ var R3FactoryDelegateType;
3488
+ (function (R3FactoryDelegateType) {
3489
+ R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
3490
+ R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function";
3491
+ })(R3FactoryDelegateType || (R3FactoryDelegateType = {}));
3492
+ var FactoryTarget;
3493
+ (function (FactoryTarget) {
3494
+ FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
3495
+ FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
3496
+ FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
3497
+ FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
3498
+ FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
3499
+ })(FactoryTarget || (FactoryTarget = {}));
3500
+ /**
3501
+ * Construct a factory function expression for the given `R3FactoryMetadata`.
3502
+ */
3503
+ function compileFactoryFunction(meta) {
3504
+ const t = variable('t');
3505
+ let baseFactoryVar = null;
3506
+ // The type to instantiate via constructor invocation. If there is no delegated factory, meaning
3507
+ // this type is always created by constructor invocation, then this is the type-to-create
3508
+ // parameter provided by the user (t) if specified, or the current type if not. If there is a
3509
+ // delegated factory (which is used to create the current type) then this is only the type-to-
3510
+ // create parameter (t).
3511
+ const typeForCtor = !isDelegatedFactoryMetadata(meta) ?
3512
+ new BinaryOperatorExpr(BinaryOperator.Or, t, meta.internalType) :
3513
+ t;
3514
+ let ctorExpr = null;
3515
+ if (meta.deps !== null) {
3516
+ // There is a constructor (either explicitly or implicitly defined).
3517
+ if (meta.deps !== 'invalid') {
3518
+ ctorExpr = new InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));
3519
+ }
3372
3520
  }
3373
- a = add32(a, wordAt(bytes, i, Endian.Little));
3374
- b = add32(b, wordAt(bytes, i + 4, Endian.Little));
3375
- // the first byte of c is reserved for the length
3376
- c = add32(c, len);
3377
- c = add32(c, wordAt(bytes, i + 8, Endian.Little) << 8);
3378
- return mix(a, b, c)[2];
3379
- }
3380
- // clang-format off
3381
- function mix(a, b, c) {
3382
- a = sub32(a, b);
3383
- a = sub32(a, c);
3384
- a ^= c >>> 13;
3385
- b = sub32(b, c);
3386
- b = sub32(b, a);
3387
- b ^= a << 8;
3388
- c = sub32(c, a);
3389
- c = sub32(c, b);
3390
- c ^= b >>> 13;
3391
- a = sub32(a, b);
3392
- a = sub32(a, c);
3393
- a ^= c >>> 12;
3394
- b = sub32(b, c);
3395
- b = sub32(b, a);
3396
- b ^= a << 16;
3397
- c = sub32(c, a);
3398
- c = sub32(c, b);
3399
- c ^= b >>> 5;
3400
- a = sub32(a, b);
3401
- a = sub32(a, c);
3402
- a ^= c >>> 3;
3403
- b = sub32(b, c);
3404
- b = sub32(b, a);
3405
- b ^= a << 10;
3406
- c = sub32(c, a);
3407
- c = sub32(c, b);
3408
- c ^= b >>> 15;
3409
- return [a, b, c];
3410
- }
3411
- // clang-format on
3412
- // Utils
3413
- var Endian;
3414
- (function (Endian) {
3415
- Endian[Endian["Little"] = 0] = "Little";
3416
- Endian[Endian["Big"] = 1] = "Big";
3417
- })(Endian || (Endian = {}));
3418
- function add32(a, b) {
3419
- return add32to64(a, b)[1];
3420
- }
3421
- function add32to64(a, b) {
3422
- const low = (a & 0xffff) + (b & 0xffff);
3423
- const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
3424
- return [high >>> 16, (high << 16) | (low & 0xffff)];
3425
- }
3426
- function add64(a, b) {
3427
- const ah = a[0], al = a[1];
3428
- const bh = b[0], bl = b[1];
3429
- const result = add32to64(al, bl);
3430
- const carry = result[0];
3431
- const l = result[1];
3432
- const h = add32(add32(ah, bh), carry);
3433
- return [h, l];
3434
- }
3435
- function sub32(a, b) {
3436
- const low = (a & 0xffff) - (b & 0xffff);
3437
- const high = (a >> 16) - (b >> 16) + (low >> 16);
3438
- return (high << 16) | (low & 0xffff);
3521
+ else {
3522
+ // There is no constructor, use the base class' factory to construct typeForCtor.
3523
+ baseFactoryVar = variable(`ɵ${meta.name}_BaseFactory`);
3524
+ ctorExpr = baseFactoryVar.callFn([typeForCtor]);
3525
+ }
3526
+ const body = [];
3527
+ let retExpr = null;
3528
+ function makeConditionalFactory(nonCtorExpr) {
3529
+ const r = variable('r');
3530
+ body.push(r.set(NULL_EXPR).toDeclStmt());
3531
+ const ctorStmt = ctorExpr !== null ? r.set(ctorExpr).toStmt() :
3532
+ importExpr(Identifiers.invalidFactory).callFn([]).toStmt();
3533
+ body.push(ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()]));
3534
+ return r;
3535
+ }
3536
+ if (isDelegatedFactoryMetadata(meta)) {
3537
+ // This type is created with a delegated factory. If a type parameter is not specified, call
3538
+ // the factory instead.
3539
+ const delegateArgs = injectDependencies(meta.delegateDeps, meta.target);
3540
+ // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.
3541
+ const factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ?
3542
+ InstantiateExpr :
3543
+ InvokeFunctionExpr)(meta.delegate, delegateArgs);
3544
+ retExpr = makeConditionalFactory(factoryExpr);
3545
+ }
3546
+ else if (isExpressionFactoryMetadata(meta)) {
3547
+ // TODO(alxhub): decide whether to lower the value here or in the caller
3548
+ retExpr = makeConditionalFactory(meta.expression);
3549
+ }
3550
+ else {
3551
+ retExpr = ctorExpr;
3552
+ }
3553
+ if (retExpr === null) {
3554
+ // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.
3555
+ body.push(importExpr(Identifiers.invalidFactory).callFn([]).toStmt());
3556
+ }
3557
+ else if (baseFactoryVar !== null) {
3558
+ // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it.
3559
+ const getInheritedFactoryCall = importExpr(Identifiers.getInheritedFactory).callFn([meta.internalType]);
3560
+ // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))`
3561
+ const baseFactory = new BinaryOperatorExpr(BinaryOperator.Or, baseFactoryVar, baseFactoryVar.set(getInheritedFactoryCall));
3562
+ body.push(new ReturnStatement(baseFactory.callFn([typeForCtor])));
3563
+ }
3564
+ else {
3565
+ // This is straightforward factory, just return it.
3566
+ body.push(new ReturnStatement(retExpr));
3567
+ }
3568
+ let factoryFn = fn([new FnParam('t', DYNAMIC_TYPE)], body, INFERRED_TYPE, undefined, `${meta.name}_Factory`);
3569
+ if (baseFactoryVar !== null) {
3570
+ // There is a base factory variable so wrap its declaration along with the factory function into
3571
+ // an IIFE.
3572
+ factoryFn = fn([], [
3573
+ new DeclareVarStmt(baseFactoryVar.name), new ReturnStatement(factoryFn)
3574
+ ]).callFn([], /* sourceSpan */ undefined, /* pure */ true);
3575
+ }
3576
+ return {
3577
+ expression: factoryFn,
3578
+ statements: [],
3579
+ type: createFactoryType(meta),
3580
+ };
3439
3581
  }
3440
- // Rotate a 32b number left `count` position
3441
- function rol32(a, count) {
3442
- return (a << count) | (a >>> (32 - count));
3582
+ function createFactoryType(meta) {
3583
+ const ctorDepsType = meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : NONE_TYPE;
3584
+ return expressionType(importExpr(Identifiers.FactoryDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType]));
3443
3585
  }
3444
- // Rotate a 64b number left `count` position
3445
- function rol64(num, count) {
3446
- const hi = num[0], lo = num[1];
3447
- const h = (hi << count) | (lo >>> (32 - count));
3448
- const l = (lo << count) | (hi >>> (32 - count));
3449
- return [h, l];
3586
+ function injectDependencies(deps, target) {
3587
+ return deps.map((dep, index) => compileInjectDependency(dep, target, index));
3450
3588
  }
3451
- function bytesToWords32(bytes, endian) {
3452
- const size = (bytes.length + 3) >>> 2;
3453
- const words32 = [];
3454
- for (let i = 0; i < size; i++) {
3455
- words32[i] = wordAt(bytes, i * 4, endian);
3589
+ function compileInjectDependency(dep, target, index) {
3590
+ // Interpret the dependency according to its resolved type.
3591
+ if (dep.token === null) {
3592
+ return importExpr(Identifiers.invalidFactoryDep).callFn([literal(index)]);
3456
3593
  }
3457
- return words32;
3458
- }
3459
- function byteAt(bytes, index) {
3460
- return index >= bytes.length ? 0 : bytes[index];
3461
- }
3462
- function wordAt(bytes, index, endian) {
3463
- let word = 0;
3464
- if (endian === Endian.Big) {
3465
- for (let i = 0; i < 4; i++) {
3466
- word += byteAt(bytes, index + i) << (24 - 8 * i);
3594
+ else if (dep.attributeNameType === null) {
3595
+ // Build up the injection flags according to the metadata.
3596
+ const flags = 0 /* Default */ | (dep.self ? 2 /* Self */ : 0) |
3597
+ (dep.skipSelf ? 4 /* SkipSelf */ : 0) | (dep.host ? 1 /* Host */ : 0) |
3598
+ (dep.optional ? 8 /* Optional */ : 0) |
3599
+ (target === FactoryTarget.Pipe ? 16 /* ForPipe */ : 0);
3600
+ // If this dependency is optional or otherwise has non-default flags, then additional
3601
+ // parameters describing how to inject the dependency must be passed to the inject function
3602
+ // that's being used.
3603
+ let flagsParam = (flags !== 0 /* Default */ || dep.optional) ? literal(flags) : null;
3604
+ // Build up the arguments to the injectFn call.
3605
+ const injectArgs = [dep.token];
3606
+ if (flagsParam) {
3607
+ injectArgs.push(flagsParam);
3467
3608
  }
3609
+ const injectFn = getInjectFn(target);
3610
+ return importExpr(injectFn).callFn(injectArgs);
3468
3611
  }
3469
3612
  else {
3470
- for (let i = 0; i < 4; i++) {
3471
- word += byteAt(bytes, index + i) << 8 * i;
3472
- }
3613
+ // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()`
3614
+ // type dependency. For the generated JS we still want to use the `dep.token` value in case the
3615
+ // name given for the attribute is not a string literal. For example given `@Attribute(foo())`,
3616
+ // we want to generate `ɵɵinjectAttribute(foo())`.
3617
+ //
3618
+ // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate
3619
+ // typings.
3620
+ return importExpr(Identifiers.injectAttribute).callFn([dep.token]);
3473
3621
  }
3474
- return word;
3475
- }
3476
- function words32ToByteString(words32) {
3477
- return words32.reduce((bytes, word) => bytes.concat(word32ToByteString(word)), []);
3478
3622
  }
3479
- function word32ToByteString(word) {
3480
- let bytes = [];
3481
- for (let i = 0; i < 4; i++) {
3482
- bytes.push((word >>> 8 * (3 - i)) & 0xff);
3623
+ function createCtorDepsType(deps) {
3624
+ let hasTypes = false;
3625
+ const attributeTypes = deps.map(dep => {
3626
+ const type = createCtorDepType(dep);
3627
+ if (type !== null) {
3628
+ hasTypes = true;
3629
+ return type;
3630
+ }
3631
+ else {
3632
+ return literal(null);
3633
+ }
3634
+ });
3635
+ if (hasTypes) {
3636
+ return expressionType(literalArr(attributeTypes));
3483
3637
  }
3484
- return bytes;
3485
- }
3486
- function bytesToHexString(bytes) {
3487
- let hex = '';
3488
- for (let i = 0; i < bytes.length; i++) {
3489
- const b = byteAt(bytes, i);
3490
- hex += (b >>> 4).toString(16) + (b & 0x0f).toString(16);
3638
+ else {
3639
+ return NONE_TYPE;
3491
3640
  }
3492
- return hex.toLowerCase();
3493
3641
  }
3494
- /**
3495
- * Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized
3496
- * power-of-256 results with memoized power-of-two computations for efficient multiplication.
3497
- *
3498
- * For our purposes, this can be safely stored as a global without memory concerns. The reason is
3499
- * that we encode two words, so only need the 0th (for the low word) and 4th (for the high word)
3500
- * exponent.
3501
- */
3502
- const base256 = new BigIntExponentiation(256);
3503
- /**
3504
- * Represents two 32-bit words as a single decimal number. This requires a big integer storage
3505
- * model as JS numbers are not accurate enough to represent the 64-bit number.
3506
- *
3507
- * Based on https://www.danvk.org/hex2dec.html
3508
- */
3509
- function wordsToDecimalString(hi, lo) {
3510
- // Encode the four bytes in lo in the lower digits of the decimal number.
3511
- // Note: the multiplication results in lo itself but represented by a big integer using its
3512
- // decimal digits.
3513
- const decimal = base256.toThePowerOf(0).multiplyBy(lo);
3514
- // Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why
3515
- // this multiplication factor is applied.
3516
- base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal);
3517
- return decimal.toString();
3642
+ function createCtorDepType(dep) {
3643
+ const entries = [];
3644
+ if (dep.attributeNameType !== null) {
3645
+ entries.push({ key: 'attribute', value: dep.attributeNameType, quoted: false });
3646
+ }
3647
+ if (dep.optional) {
3648
+ entries.push({ key: 'optional', value: literal(true), quoted: false });
3649
+ }
3650
+ if (dep.host) {
3651
+ entries.push({ key: 'host', value: literal(true), quoted: false });
3652
+ }
3653
+ if (dep.self) {
3654
+ entries.push({ key: 'self', value: literal(true), quoted: false });
3655
+ }
3656
+ if (dep.skipSelf) {
3657
+ entries.push({ key: 'skipSelf', value: literal(true), quoted: false });
3658
+ }
3659
+ return entries.length > 0 ? literalMap(entries) : null;
3518
3660
  }
3519
-
3520
- /**
3521
- * @license
3522
- * Copyright Google LLC All Rights Reserved.
3523
- *
3524
- * Use of this source code is governed by an MIT-style license that can be
3525
- * found in the LICENSE file at https://angular.io/license
3526
- */
3527
- // XMB/XTB placeholders can only contain A-Z, 0-9 and _
3528
- function toPublicName(internalName) {
3529
- return internalName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
3661
+ function isDelegatedFactoryMetadata(meta) {
3662
+ return meta.delegateType !== undefined;
3663
+ }
3664
+ function isExpressionFactoryMetadata(meta) {
3665
+ return meta.expression !== undefined;
3666
+ }
3667
+ function getInjectFn(target) {
3668
+ switch (target) {
3669
+ case FactoryTarget.Component:
3670
+ case FactoryTarget.Directive:
3671
+ case FactoryTarget.Pipe:
3672
+ return Identifiers.directiveInject;
3673
+ case FactoryTarget.NgModule:
3674
+ case FactoryTarget.Injectable:
3675
+ default:
3676
+ return Identifiers.inject;
3677
+ }
3530
3678
  }
3531
3679
 
3532
3680
  /**
@@ -3536,350 +3684,229 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
3536
3684
  * Use of this source code is governed by an MIT-style license that can be
3537
3685
  * found in the LICENSE file at https://angular.io/license
3538
3686
  */
3539
- /* Closure variables holding messages must be named `MSG_[A-Z0-9]+` */
3540
- const CLOSURE_TRANSLATION_VAR_PREFIX = 'MSG_';
3541
3687
  /**
3542
- * Prefix for non-`goog.getMsg` i18n-related vars.
3543
- * Note: the prefix uses lowercase characters intentionally due to a Closure behavior that
3544
- * considers variables like `I18N_0` as constants and throws an error when their value changes.
3688
+ * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently
3689
+ * require the implementation of a visitor for Comments as they are only collected at
3690
+ * the top-level of the R3 AST, and only if `Render3ParseOptions['collectCommentNodes']`
3691
+ * is true.
3545
3692
  */
3546
- const TRANSLATION_VAR_PREFIX = 'i18n_';
3547
- /** Name of the i18n attributes **/
3548
- const I18N_ATTR = 'i18n';
3549
- const I18N_ATTR_PREFIX = 'i18n-';
3550
- /** Prefix of var expressions used in ICUs */
3551
- const I18N_ICU_VAR_PREFIX = 'VAR_';
3552
- /** Prefix of ICU expressions for post processing */
3553
- const I18N_ICU_MAPPING_PREFIX = 'I18N_EXP_';
3554
- /** Placeholder wrapper for i18n expressions **/
3555
- const I18N_PLACEHOLDER_SYMBOL = '�';
3556
- function isI18nAttribute(name) {
3557
- return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
3558
- }
3559
- function isI18nRootNode(meta) {
3560
- return meta instanceof Message;
3561
- }
3562
- function isSingleI18nIcu(meta) {
3563
- return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu$1;
3564
- }
3565
- function hasI18nMeta(node) {
3566
- return !!node.i18n;
3567
- }
3568
- function hasI18nAttrs(element) {
3569
- return element.attrs.some((attr) => isI18nAttribute(attr.name));
3570
- }
3571
- function icuFromI18nMessage(message) {
3572
- return message.nodes[0];
3573
- }
3574
- function wrapI18nPlaceholder(content, contextId = 0) {
3575
- const blockId = contextId > 0 ? `:${contextId}` : '';
3576
- return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`;
3577
- }
3578
- function assembleI18nBoundString(strings, bindingStartIndex = 0, contextId = 0) {
3579
- if (!strings.length)
3580
- return '';
3581
- let acc = '';
3582
- const lastIdx = strings.length - 1;
3583
- for (let i = 0; i < lastIdx; i++) {
3584
- acc += `${strings[i]}${wrapI18nPlaceholder(bindingStartIndex + i, contextId)}`;
3693
+ class Comment {
3694
+ constructor(value, sourceSpan) {
3695
+ this.value = value;
3696
+ this.sourceSpan = sourceSpan;
3697
+ }
3698
+ visit(_visitor) {
3699
+ throw new Error('visit() not implemented for Comment');
3585
3700
  }
3586
- acc += strings[lastIdx];
3587
- return acc;
3588
- }
3589
- function getSeqNumberGenerator(startsAt = 0) {
3590
- let current = startsAt;
3591
- return () => current++;
3592
- }
3593
- function placeholdersToParams(placeholders) {
3594
- const params = {};
3595
- placeholders.forEach((values, key) => {
3596
- params[key] = literal(values.length > 1 ? `[${values.join('|')}]` : values[0]);
3597
- });
3598
- return params;
3599
- }
3600
- function updatePlaceholderMap(map, name, ...values) {
3601
- const current = map.get(name) || [];
3602
- current.push(...values);
3603
- map.set(name, current);
3604
3701
  }
3605
- function assembleBoundTextPlaceholders(meta, bindingStartIndex = 0, contextId = 0) {
3606
- const startIdx = bindingStartIndex;
3607
- const placeholders = new Map();
3608
- const node = meta instanceof Message ? meta.nodes.find(node => node instanceof Container) : meta;
3609
- if (node) {
3610
- node
3611
- .children
3612
- .filter((child) => child instanceof Placeholder)
3613
- .forEach((child, idx) => {
3614
- const content = wrapI18nPlaceholder(startIdx + idx, contextId);
3615
- updatePlaceholderMap(placeholders, child.name, content);
3616
- });
3702
+ class Text {
3703
+ constructor(value, sourceSpan) {
3704
+ this.value = value;
3705
+ this.sourceSpan = sourceSpan;
3706
+ }
3707
+ visit(visitor) {
3708
+ return visitor.visitText(this);
3617
3709
  }
3618
- return placeholders;
3619
3710
  }
3620
- /**
3621
- * Format the placeholder names in a map of placeholders to expressions.
3622
- *
3623
- * The placeholder names are converted from "internal" format (e.g. `START_TAG_DIV_1`) to "external"
3624
- * format (e.g. `startTagDiv_1`).
3625
- *
3626
- * @param params A map of placeholder names to expressions.
3627
- * @param useCamelCase whether to camelCase the placeholder name when formatting.
3628
- * @returns A new map of formatted placeholder names to expressions.
3629
- */
3630
- function i18nFormatPlaceholderNames(params = {}, useCamelCase) {
3631
- const _params = {};
3632
- if (params && Object.keys(params).length) {
3633
- Object.keys(params).forEach(key => _params[formatI18nPlaceholderName(key, useCamelCase)] = params[key]);
3711
+ class BoundText {
3712
+ constructor(value, sourceSpan, i18n) {
3713
+ this.value = value;
3714
+ this.sourceSpan = sourceSpan;
3715
+ this.i18n = i18n;
3716
+ }
3717
+ visit(visitor) {
3718
+ return visitor.visitBoundText(this);
3634
3719
  }
3635
- return _params;
3636
3720
  }
3637
3721
  /**
3638
- * Converts internal placeholder names to public-facing format
3639
- * (for example to use in goog.getMsg call).
3640
- * Example: `START_TAG_DIV_1` is converted to `startTagDiv_1`.
3722
+ * Represents a text attribute in the template.
3641
3723
  *
3642
- * @param name The placeholder name that should be formatted
3643
- * @returns Formatted placeholder name
3724
+ * `valueSpan` may not be present in cases where there is no value `<div a></div>`.
3725
+ * `keySpan` may also not be present for synthetic attributes from ICU expansions.
3644
3726
  */
3645
- function formatI18nPlaceholderName(name, useCamelCase = true) {
3646
- const publicName = toPublicName(name);
3647
- if (!useCamelCase) {
3648
- return publicName;
3727
+ class TextAttribute {
3728
+ constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
3729
+ this.name = name;
3730
+ this.value = value;
3731
+ this.sourceSpan = sourceSpan;
3732
+ this.keySpan = keySpan;
3733
+ this.valueSpan = valueSpan;
3734
+ this.i18n = i18n;
3649
3735
  }
3650
- const chunks = publicName.split('_');
3651
- if (chunks.length === 1) {
3652
- // if no "_" found - just lowercase the value
3653
- return name.toLowerCase();
3736
+ visit(visitor) {
3737
+ return visitor.visitTextAttribute(this);
3654
3738
  }
3655
- let postfix;
3656
- // eject last element if it's a number
3657
- if (/^\d+$/.test(chunks[chunks.length - 1])) {
3658
- postfix = chunks.pop();
3739
+ }
3740
+ class BoundAttribute {
3741
+ constructor(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan, i18n) {
3742
+ this.name = name;
3743
+ this.type = type;
3744
+ this.securityContext = securityContext;
3745
+ this.value = value;
3746
+ this.unit = unit;
3747
+ this.sourceSpan = sourceSpan;
3748
+ this.keySpan = keySpan;
3749
+ this.valueSpan = valueSpan;
3750
+ this.i18n = i18n;
3659
3751
  }
3660
- let raw = chunks.shift().toLowerCase();
3661
- if (chunks.length) {
3662
- raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join('');
3752
+ static fromBoundElementProperty(prop, i18n) {
3753
+ if (prop.keySpan === undefined) {
3754
+ throw new Error(`Unexpected state: keySpan must be defined for bound attributes but was not for ${prop.name}: ${prop.sourceSpan}`);
3755
+ }
3756
+ return new BoundAttribute(prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n);
3757
+ }
3758
+ visit(visitor) {
3759
+ return visitor.visitBoundAttribute(this);
3663
3760
  }
3664
- return postfix ? `${raw}_${postfix}` : raw;
3665
- }
3666
- /**
3667
- * Generates a prefix for translation const name.
3668
- *
3669
- * @param extra Additional local prefix that should be injected into translation var name
3670
- * @returns Complete translation const prefix
3671
- */
3672
- function getTranslationConstPrefix(extra) {
3673
- return `${CLOSURE_TRANSLATION_VAR_PREFIX}${extra}`.toUpperCase();
3674
3761
  }
3675
- /**
3676
- * Generate AST to declare a variable. E.g. `var I18N_1;`.
3677
- * @param variable the name of the variable to declare.
3678
- */
3679
- function declareI18nVariable(variable) {
3680
- return new DeclareVarStmt(variable.name, undefined, INFERRED_TYPE, undefined, variable.sourceSpan);
3681
- }
3682
-
3683
- /**
3684
- * @license
3685
- * Copyright Google LLC All Rights Reserved.
3686
- *
3687
- * Use of this source code is governed by an MIT-style license that can be
3688
- * found in the LICENSE file at https://angular.io/license
3689
- */
3690
- /**
3691
- * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in
3692
- * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may
3693
- * bot work in some cases when object keys are mangled by minifier.
3694
- *
3695
- * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with
3696
- * inputs that contain potentially unsafe chars.
3697
- */
3698
- const UNSAFE_OBJECT_KEY_NAME_REGEXP = /[-.]/;
3699
- /** Name of the temporary to use during data binding */
3700
- const TEMPORARY_NAME = '_t';
3701
- /** Name of the context parameter passed into a template function */
3702
- const CONTEXT_NAME = 'ctx';
3703
- /** Name of the RenderFlag passed into a template function */
3704
- const RENDER_FLAGS = 'rf';
3705
- /** The prefix reference variables */
3706
- const REFERENCE_PREFIX = '_r';
3707
- /** The name of the implicit context reference */
3708
- const IMPLICIT_REFERENCE = '$implicit';
3709
- /** Non bindable attribute name **/
3710
- const NON_BINDABLE_ATTR = 'ngNonBindable';
3711
- /** Name for the variable keeping track of the context returned by `ɵɵrestoreView`. */
3712
- const RESTORED_VIEW_CONTEXT_NAME = 'restoredCtx';
3713
- /**
3714
- * Creates an allocator for a temporary variable.
3715
- *
3716
- * A variable declaration is added to the statements the first time the allocator is invoked.
3717
- */
3718
- function temporaryAllocator(statements, name) {
3719
- let temp = null;
3720
- return () => {
3721
- if (!temp) {
3722
- statements.push(new DeclareVarStmt(TEMPORARY_NAME, undefined, DYNAMIC_TYPE));
3723
- temp = variable(name);
3762
+ class BoundEvent {
3763
+ constructor(name, type, handler, target, phase, sourceSpan, handlerSpan, keySpan) {
3764
+ this.name = name;
3765
+ this.type = type;
3766
+ this.handler = handler;
3767
+ this.target = target;
3768
+ this.phase = phase;
3769
+ this.sourceSpan = sourceSpan;
3770
+ this.handlerSpan = handlerSpan;
3771
+ this.keySpan = keySpan;
3772
+ }
3773
+ static fromParsedEvent(event) {
3774
+ const target = event.type === 0 /* Regular */ ? event.targetOrPhase : null;
3775
+ const phase = event.type === 1 /* Animation */ ? event.targetOrPhase : null;
3776
+ if (event.keySpan === undefined) {
3777
+ throw new Error(`Unexpected state: keySpan must be defined for bound event but was not for ${event.name}: ${event.sourceSpan}`);
3724
3778
  }
3725
- return temp;
3726
- };
3727
- }
3728
- function unsupported(feature) {
3729
- if (this) {
3730
- throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
3779
+ return new BoundEvent(event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan, event.keySpan);
3731
3780
  }
3732
- throw new Error(`Feature ${feature} is not supported yet`);
3733
- }
3734
- function invalid$1(arg) {
3735
- throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
3736
- }
3737
- function asLiteral(value) {
3738
- if (Array.isArray(value)) {
3739
- return literalArr(value.map(asLiteral));
3781
+ visit(visitor) {
3782
+ return visitor.visitBoundEvent(this);
3740
3783
  }
3741
- return literal(value, INFERRED_TYPE);
3742
3784
  }
3743
- function conditionallyCreateMapObjectLiteral(keys, keepDeclared) {
3744
- if (Object.getOwnPropertyNames(keys).length > 0) {
3745
- return mapToExpression(keys, keepDeclared);
3785
+ class Element {
3786
+ constructor(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3787
+ this.name = name;
3788
+ this.attributes = attributes;
3789
+ this.inputs = inputs;
3790
+ this.outputs = outputs;
3791
+ this.children = children;
3792
+ this.references = references;
3793
+ this.sourceSpan = sourceSpan;
3794
+ this.startSourceSpan = startSourceSpan;
3795
+ this.endSourceSpan = endSourceSpan;
3796
+ this.i18n = i18n;
3746
3797
  }
3747
- return null;
3748
- }
3749
- function mapToExpression(map, keepDeclared) {
3750
- return literalMap(Object.getOwnPropertyNames(map).map(key => {
3751
- // canonical syntax: `dirProp: publicProp`
3752
- // if there is no `:`, use dirProp = elProp
3753
- const value = map[key];
3754
- let declaredName;
3755
- let publicName;
3756
- let minifiedName;
3757
- let needsDeclaredName;
3758
- if (Array.isArray(value)) {
3759
- [publicName, declaredName] = value;
3760
- minifiedName = key;
3761
- needsDeclaredName = publicName !== declaredName;
3762
- }
3763
- else {
3764
- [declaredName, publicName] = splitAtColon(key, [key, value]);
3765
- minifiedName = declaredName;
3766
- // Only include the declared name if extracted from the key, i.e. the key contains a colon.
3767
- // Otherwise the declared name should be omitted even if it is different from the public name,
3768
- // as it may have already been minified.
3769
- needsDeclaredName = publicName !== declaredName && key.includes(':');
3770
- }
3771
- return {
3772
- key: minifiedName,
3773
- // put quotes around keys that contain potentially unsafe characters
3774
- quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName),
3775
- value: (keepDeclared && needsDeclaredName) ?
3776
- literalArr([asLiteral(publicName), asLiteral(declaredName)]) :
3777
- asLiteral(publicName)
3778
- };
3779
- }));
3780
- }
3781
- /**
3782
- * Remove trailing null nodes as they are implied.
3783
- */
3784
- function trimTrailingNulls(parameters) {
3785
- while (isNull(parameters[parameters.length - 1])) {
3786
- parameters.pop();
3798
+ visit(visitor) {
3799
+ return visitor.visitElement(this);
3787
3800
  }
3788
- return parameters;
3789
3801
  }
3790
- function getQueryPredicate(query, constantPool) {
3791
- if (Array.isArray(query.predicate)) {
3792
- let predicate = [];
3793
- query.predicate.forEach((selector) => {
3794
- // Each item in predicates array may contain strings with comma-separated refs
3795
- // (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
3796
- // as separate array entities
3797
- const selectors = selector.split(',').map(token => literal(token.trim()));
3798
- predicate.push(...selectors);
3799
- });
3800
- return constantPool.getConstLiteral(literalArr(predicate), true);
3802
+ class Template {
3803
+ constructor(tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3804
+ this.tagName = tagName;
3805
+ this.attributes = attributes;
3806
+ this.inputs = inputs;
3807
+ this.outputs = outputs;
3808
+ this.templateAttrs = templateAttrs;
3809
+ this.children = children;
3810
+ this.references = references;
3811
+ this.variables = variables;
3812
+ this.sourceSpan = sourceSpan;
3813
+ this.startSourceSpan = startSourceSpan;
3814
+ this.endSourceSpan = endSourceSpan;
3815
+ this.i18n = i18n;
3801
3816
  }
3802
- else {
3803
- return query.predicate;
3817
+ visit(visitor) {
3818
+ return visitor.visitTemplate(this);
3804
3819
  }
3805
3820
  }
3806
- /**
3807
- * A representation for an object literal used during codegen of definition objects. The generic
3808
- * type `T` allows to reference a documented type of the generated structure, such that the
3809
- * property names that are set can be resolved to their documented declaration.
3810
- */
3811
- class DefinitionMap {
3812
- constructor() {
3813
- this.values = [];
3821
+ class Content {
3822
+ constructor(selector, attributes, sourceSpan, i18n) {
3823
+ this.selector = selector;
3824
+ this.attributes = attributes;
3825
+ this.sourceSpan = sourceSpan;
3826
+ this.i18n = i18n;
3827
+ this.name = 'ng-content';
3814
3828
  }
3815
- set(key, value) {
3816
- if (value) {
3817
- this.values.push({ key: key, value, quoted: false });
3818
- }
3829
+ visit(visitor) {
3830
+ return visitor.visitContent(this);
3819
3831
  }
3820
- toLiteralMap() {
3821
- return literalMap(this.values);
3832
+ }
3833
+ class Variable {
3834
+ constructor(name, value, sourceSpan, keySpan, valueSpan) {
3835
+ this.name = name;
3836
+ this.value = value;
3837
+ this.sourceSpan = sourceSpan;
3838
+ this.keySpan = keySpan;
3839
+ this.valueSpan = valueSpan;
3840
+ }
3841
+ visit(visitor) {
3842
+ return visitor.visitVariable(this);
3822
3843
  }
3823
3844
  }
3824
- /**
3825
- * Extract a map of properties to values for a given element or template node, which can be used
3826
- * by the directive matching machinery.
3827
- *
3828
- * @param elOrTpl the element or template in question
3829
- * @return an object set up for directive matching. For attributes on the element/template, this
3830
- * object maps a property name to its (static) value. For any bindings, this map simply maps the
3831
- * property name to an empty string.
3832
- */
3833
- function getAttrsForDirectiveMatching(elOrTpl) {
3834
- const attributesMap = {};
3835
- if (elOrTpl instanceof Template && elOrTpl.tagName !== 'ng-template') {
3836
- elOrTpl.templateAttrs.forEach(a => attributesMap[a.name] = '');
3845
+ class Reference {
3846
+ constructor(name, value, sourceSpan, keySpan, valueSpan) {
3847
+ this.name = name;
3848
+ this.value = value;
3849
+ this.sourceSpan = sourceSpan;
3850
+ this.keySpan = keySpan;
3851
+ this.valueSpan = valueSpan;
3837
3852
  }
3838
- else {
3839
- elOrTpl.attributes.forEach(a => {
3840
- if (!isI18nAttribute(a.name)) {
3841
- attributesMap[a.name] = a.value;
3842
- }
3843
- });
3844
- elOrTpl.inputs.forEach(i => {
3845
- attributesMap[i.name] = '';
3846
- });
3847
- elOrTpl.outputs.forEach(o => {
3848
- attributesMap[o.name] = '';
3849
- });
3853
+ visit(visitor) {
3854
+ return visitor.visitReference(this);
3850
3855
  }
3851
- return attributesMap;
3852
3856
  }
3853
- /** Returns a call expression to a chained instruction, e.g. `property(params[0])(params[1])`. */
3854
- function chainedInstruction(reference, calls, span) {
3855
- let expression = importExpr(reference, null, span);
3856
- if (calls.length > 0) {
3857
- for (let i = 0; i < calls.length; i++) {
3858
- expression = expression.callFn(calls[i], span);
3859
- }
3857
+ class Icu {
3858
+ constructor(vars, placeholders, sourceSpan, i18n) {
3859
+ this.vars = vars;
3860
+ this.placeholders = placeholders;
3861
+ this.sourceSpan = sourceSpan;
3862
+ this.i18n = i18n;
3860
3863
  }
3861
- else {
3862
- // Add a blank invocation, in case the `calls` array is empty.
3863
- expression = expression.callFn([], span);
3864
+ visit(visitor) {
3865
+ return visitor.visitIcu(this);
3864
3866
  }
3865
- return expression;
3866
3867
  }
3867
- /**
3868
- * Gets the number of arguments expected to be passed to a generated instruction in the case of
3869
- * interpolation instructions.
3870
- * @param interpolation An interpolation ast
3871
- */
3872
- function getInterpolationArgsLength(interpolation) {
3873
- const { expressions, strings } = interpolation;
3874
- if (expressions.length === 1 && strings.length === 2 && strings[0] === '' && strings[1] === '') {
3875
- // If the interpolation has one interpolated value, but the prefix and suffix are both empty
3876
- // strings, we only pass one argument, to a special instruction like `propertyInterpolate` or
3877
- // `textInterpolate`.
3878
- return 1;
3868
+ class RecursiveVisitor {
3869
+ visitElement(element) {
3870
+ visitAll(this, element.attributes);
3871
+ visitAll(this, element.inputs);
3872
+ visitAll(this, element.outputs);
3873
+ visitAll(this, element.children);
3874
+ visitAll(this, element.references);
3875
+ }
3876
+ visitTemplate(template) {
3877
+ visitAll(this, template.attributes);
3878
+ visitAll(this, template.inputs);
3879
+ visitAll(this, template.outputs);
3880
+ visitAll(this, template.children);
3881
+ visitAll(this, template.references);
3882
+ visitAll(this, template.variables);
3883
+ }
3884
+ visitContent(content) { }
3885
+ visitVariable(variable) { }
3886
+ visitReference(reference) { }
3887
+ visitTextAttribute(attribute) { }
3888
+ visitBoundAttribute(attribute) { }
3889
+ visitBoundEvent(attribute) { }
3890
+ visitText(text) { }
3891
+ visitBoundText(text) { }
3892
+ visitIcu(icu) { }
3893
+ }
3894
+ function visitAll(visitor, nodes) {
3895
+ const result = [];
3896
+ if (visitor.visit) {
3897
+ for (const node of nodes) {
3898
+ const newNode = visitor.visit(node) || node.visit(visitor);
3899
+ }
3879
3900
  }
3880
3901
  else {
3881
- return expressions.length + strings.length;
3902
+ for (const node of nodes) {
3903
+ const newNode = node.visit(visitor);
3904
+ if (newNode) {
3905
+ result.push(newNode);
3906
+ }
3907
+ }
3882
3908
  }
3909
+ return result;
3883
3910
  }
3884
3911
 
3885
3912
  /**
@@ -3889,84 +3916,106 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
3889
3916
  * Use of this source code is governed by an MIT-style license that can be
3890
3917
  * found in the LICENSE file at https://angular.io/license
3891
3918
  */
3892
- /**
3893
- * Creates an array literal expression from the given array, mapping all values to an expression
3894
- * using the provided mapping function. If the array is empty or null, then null is returned.
3895
- *
3896
- * @param values The array to transfer into literal array expression.
3897
- * @param mapper The logic to use for creating an expression for the array's values.
3898
- * @returns An array literal expression representing `values`, or null if `values` is empty or
3899
- * is itself null.
3900
- */
3901
- function toOptionalLiteralArray(values, mapper) {
3902
- if (values === null || values.length === 0) {
3903
- return null;
3919
+ class Message {
3920
+ /**
3921
+ * @param nodes message AST
3922
+ * @param placeholders maps placeholder names to static content and their source spans
3923
+ * @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
3924
+ * @param meaning
3925
+ * @param description
3926
+ * @param customId
3927
+ */
3928
+ constructor(nodes, placeholders, placeholderToMessage, meaning, description, customId) {
3929
+ this.nodes = nodes;
3930
+ this.placeholders = placeholders;
3931
+ this.placeholderToMessage = placeholderToMessage;
3932
+ this.meaning = meaning;
3933
+ this.description = description;
3934
+ this.customId = customId;
3935
+ this.id = this.customId;
3936
+ /** The ids to use if there are no custom id and if `i18nLegacyMessageIdFormat` is not empty */
3937
+ this.legacyIds = [];
3938
+ if (nodes.length) {
3939
+ this.sources = [{
3940
+ filePath: nodes[0].sourceSpan.start.file.url,
3941
+ startLine: nodes[0].sourceSpan.start.line + 1,
3942
+ startCol: nodes[0].sourceSpan.start.col + 1,
3943
+ endLine: nodes[nodes.length - 1].sourceSpan.end.line + 1,
3944
+ endCol: nodes[0].sourceSpan.start.col + 1
3945
+ }];
3946
+ }
3947
+ else {
3948
+ this.sources = [];
3949
+ }
3904
3950
  }
3905
- return literalArr(values.map(value => mapper(value)));
3906
3951
  }
3907
- /**
3908
- * Creates an object literal expression from the given object, mapping all values to an expression
3909
- * using the provided mapping function. If the object has no keys, then null is returned.
3910
- *
3911
- * @param object The object to transfer into an object literal expression.
3912
- * @param mapper The logic to use for creating an expression for the object's values.
3913
- * @returns An object literal expression representing `object`, or null if `object` does not have
3914
- * any keys.
3915
- */
3916
- function toOptionalLiteralMap(object, mapper) {
3917
- const entries = Object.keys(object).map(key => {
3918
- const value = object[key];
3919
- return { key, value: mapper(value), quoted: true };
3920
- });
3921
- if (entries.length > 0) {
3922
- return literalMap(entries);
3952
+ class Text$1 {
3953
+ constructor(value, sourceSpan) {
3954
+ this.value = value;
3955
+ this.sourceSpan = sourceSpan;
3923
3956
  }
3924
- else {
3925
- return null;
3957
+ visit(visitor, context) {
3958
+ return visitor.visitText(this, context);
3926
3959
  }
3927
3960
  }
3928
- function compileDependencies(deps) {
3929
- if (deps === 'invalid') {
3930
- // The `deps` can be set to the string "invalid" by the `unwrapConstructorDependencies()`
3931
- // function, which tries to convert `ConstructorDeps` into `R3DependencyMetadata[]`.
3932
- return literal('invalid');
3933
- }
3934
- else if (deps === null) {
3935
- return literal(null);
3961
+ // TODO(vicb): do we really need this node (vs an array) ?
3962
+ class Container {
3963
+ constructor(children, sourceSpan) {
3964
+ this.children = children;
3965
+ this.sourceSpan = sourceSpan;
3936
3966
  }
3937
- else {
3938
- return literalArr(deps.map(compileDependency));
3967
+ visit(visitor, context) {
3968
+ return visitor.visitContainer(this, context);
3939
3969
  }
3940
3970
  }
3941
- function compileDependency(dep) {
3942
- const depMeta = new DefinitionMap();
3943
- depMeta.set('token', dep.token);
3944
- if (dep.attributeNameType !== null) {
3945
- depMeta.set('attribute', literal(true));
3971
+ class Icu$1 {
3972
+ constructor(expression, type, cases, sourceSpan) {
3973
+ this.expression = expression;
3974
+ this.type = type;
3975
+ this.cases = cases;
3976
+ this.sourceSpan = sourceSpan;
3946
3977
  }
3947
- if (dep.host) {
3948
- depMeta.set('host', literal(true));
3978
+ visit(visitor, context) {
3979
+ return visitor.visitIcu(this, context);
3949
3980
  }
3950
- if (dep.optional) {
3951
- depMeta.set('optional', literal(true));
3981
+ }
3982
+ class TagPlaceholder {
3983
+ constructor(tag, attrs, startName, closeName, children, isVoid,
3984
+ // TODO sourceSpan should cover all (we need a startSourceSpan and endSourceSpan)
3985
+ sourceSpan, startSourceSpan, endSourceSpan) {
3986
+ this.tag = tag;
3987
+ this.attrs = attrs;
3988
+ this.startName = startName;
3989
+ this.closeName = closeName;
3990
+ this.children = children;
3991
+ this.isVoid = isVoid;
3992
+ this.sourceSpan = sourceSpan;
3993
+ this.startSourceSpan = startSourceSpan;
3994
+ this.endSourceSpan = endSourceSpan;
3952
3995
  }
3953
- if (dep.self) {
3954
- depMeta.set('self', literal(true));
3996
+ visit(visitor, context) {
3997
+ return visitor.visitTagPlaceholder(this, context);
3955
3998
  }
3956
- if (dep.skipSelf) {
3957
- depMeta.set('skipSelf', literal(true));
3999
+ }
4000
+ class Placeholder {
4001
+ constructor(value, name, sourceSpan) {
4002
+ this.value = value;
4003
+ this.name = name;
4004
+ this.sourceSpan = sourceSpan;
4005
+ }
4006
+ visit(visitor, context) {
4007
+ return visitor.visitPlaceholder(this, context);
3958
4008
  }
3959
- return depMeta.toLiteralMap();
3960
4009
  }
3961
- /**
3962
- * Generate an expression that has the given `expr` wrapped in the following form:
3963
- *
3964
- * ```
3965
- * forwardRef(() => expr)
3966
- * ```
3967
- */
3968
- function generateForwardRef(expr) {
3969
- return importExpr(Identifiers.forwardRef).callFn([fn([], [new ReturnStatement(expr)])]);
4010
+ class IcuPlaceholder {
4011
+ constructor(value, name, sourceSpan) {
4012
+ this.value = value;
4013
+ this.name = name;
4014
+ this.sourceSpan = sourceSpan;
4015
+ }
4016
+ visit(visitor, context) {
4017
+ return visitor.visitIcuPlaceholder(this, context);
4018
+ }
3970
4019
  }
3971
4020
 
3972
4021
  /**
@@ -3976,146 +4025,177 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
3976
4025
  * Use of this source code is governed by an MIT-style license that can be
3977
4026
  * found in the LICENSE file at https://angular.io/license
3978
4027
  */
3979
- // https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
3980
- const VERSION = 3;
3981
- const JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,';
3982
- class SourceMapGenerator {
3983
- constructor(file = null) {
3984
- this.file = file;
3985
- this.sourcesContent = new Map();
3986
- this.lines = [];
3987
- this.lastCol0 = 0;
3988
- this.hasMappings = false;
3989
- }
3990
- // The content is `null` when the content is expected to be loaded using the URL
3991
- addSource(url, content = null) {
3992
- if (!this.sourcesContent.has(url)) {
3993
- this.sourcesContent.set(url, content);
3994
- }
3995
- return this;
4028
+ /**
4029
+ * Represents a big integer using a buffer of its individual digits, with the least significant
4030
+ * digit stored at the beginning of the array (little endian).
4031
+ *
4032
+ * For performance reasons, each instance is mutable. The addition operation can be done in-place
4033
+ * to reduce memory pressure of allocation for the digits array.
4034
+ */
4035
+ class BigInteger {
4036
+ /**
4037
+ * Creates a big integer using its individual digits in little endian storage.
4038
+ */
4039
+ constructor(digits) {
4040
+ this.digits = digits;
3996
4041
  }
3997
- addLine() {
3998
- this.lines.push([]);
3999
- this.lastCol0 = 0;
4000
- return this;
4042
+ static zero() {
4043
+ return new BigInteger([0]);
4001
4044
  }
4002
- addMapping(col0, sourceUrl, sourceLine0, sourceCol0) {
4003
- if (!this.currentLine) {
4004
- throw new Error(`A line must be added before mappings can be added`);
4005
- }
4006
- if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) {
4007
- throw new Error(`Unknown source file "${sourceUrl}"`);
4008
- }
4009
- if (col0 == null) {
4010
- throw new Error(`The column in the generated code must be provided`);
4011
- }
4012
- if (col0 < this.lastCol0) {
4013
- throw new Error(`Mapping should be added in output order`);
4014
- }
4015
- if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) {
4016
- throw new Error(`The source location must be provided when a source url is provided`);
4017
- }
4018
- this.hasMappings = true;
4019
- this.lastCol0 = col0;
4020
- this.currentLine.push({ col0, sourceUrl, sourceLine0, sourceCol0 });
4021
- return this;
4045
+ static one() {
4046
+ return new BigInteger([1]);
4022
4047
  }
4023
4048
  /**
4024
- * @internal strip this from published d.ts files due to
4025
- * https://github.com/microsoft/TypeScript/issues/36216
4049
+ * Creates a clone of this instance.
4026
4050
  */
4027
- get currentLine() {
4028
- return this.lines.slice(-1)[0];
4051
+ clone() {
4052
+ return new BigInteger(this.digits.slice());
4029
4053
  }
4030
- toJSON() {
4031
- if (!this.hasMappings) {
4032
- return null;
4054
+ /**
4055
+ * Returns a new big integer with the sum of `this` and `other` as its value. This does not mutate
4056
+ * `this` but instead returns a new instance, unlike `addToSelf`.
4057
+ */
4058
+ add(other) {
4059
+ const result = this.clone();
4060
+ result.addToSelf(other);
4061
+ return result;
4062
+ }
4063
+ /**
4064
+ * Adds `other` to the instance itself, thereby mutating its value.
4065
+ */
4066
+ addToSelf(other) {
4067
+ const maxNrOfDigits = Math.max(this.digits.length, other.digits.length);
4068
+ let carry = 0;
4069
+ for (let i = 0; i < maxNrOfDigits; i++) {
4070
+ let digitSum = carry;
4071
+ if (i < this.digits.length) {
4072
+ digitSum += this.digits[i];
4073
+ }
4074
+ if (i < other.digits.length) {
4075
+ digitSum += other.digits[i];
4076
+ }
4077
+ if (digitSum >= 10) {
4078
+ this.digits[i] = digitSum - 10;
4079
+ carry = 1;
4080
+ }
4081
+ else {
4082
+ this.digits[i] = digitSum;
4083
+ carry = 0;
4084
+ }
4085
+ }
4086
+ // Apply a remaining carry if needed.
4087
+ if (carry > 0) {
4088
+ this.digits[maxNrOfDigits] = 1;
4033
4089
  }
4034
- const sourcesIndex = new Map();
4035
- const sources = [];
4036
- const sourcesContent = [];
4037
- Array.from(this.sourcesContent.keys()).forEach((url, i) => {
4038
- sourcesIndex.set(url, i);
4039
- sources.push(url);
4040
- sourcesContent.push(this.sourcesContent.get(url) || null);
4041
- });
4042
- let mappings = '';
4043
- let lastCol0 = 0;
4044
- let lastSourceIndex = 0;
4045
- let lastSourceLine0 = 0;
4046
- let lastSourceCol0 = 0;
4047
- this.lines.forEach(segments => {
4048
- lastCol0 = 0;
4049
- mappings += segments
4050
- .map(segment => {
4051
- // zero-based starting column of the line in the generated code
4052
- let segAsStr = toBase64VLQ(segment.col0 - lastCol0);
4053
- lastCol0 = segment.col0;
4054
- if (segment.sourceUrl != null) {
4055
- // zero-based index into the “sources” list
4056
- segAsStr +=
4057
- toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex);
4058
- lastSourceIndex = sourcesIndex.get(segment.sourceUrl);
4059
- // the zero-based starting line in the original source
4060
- segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0);
4061
- lastSourceLine0 = segment.sourceLine0;
4062
- // the zero-based starting column in the original source
4063
- segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0);
4064
- lastSourceCol0 = segment.sourceCol0;
4065
- }
4066
- return segAsStr;
4067
- })
4068
- .join(',');
4069
- mappings += ';';
4070
- });
4071
- mappings = mappings.slice(0, -1);
4072
- return {
4073
- 'file': this.file || '',
4074
- 'version': VERSION,
4075
- 'sourceRoot': '',
4076
- 'sources': sources,
4077
- 'sourcesContent': sourcesContent,
4078
- 'mappings': mappings,
4079
- };
4080
4090
  }
4081
- toJsComment() {
4082
- return this.hasMappings ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0)) :
4083
- '';
4091
+ /**
4092
+ * Builds the decimal string representation of the big integer. As this is stored in
4093
+ * little endian, the digits are concatenated in reverse order.
4094
+ */
4095
+ toString() {
4096
+ let res = '';
4097
+ for (let i = this.digits.length - 1; i >= 0; i--) {
4098
+ res += this.digits[i];
4099
+ }
4100
+ return res;
4084
4101
  }
4085
4102
  }
4086
- function toBase64String(value) {
4087
- let b64 = '';
4088
- const encoded = utf8Encode(value);
4089
- for (let i = 0; i < encoded.length;) {
4090
- const i1 = encoded[i++];
4091
- const i2 = i < encoded.length ? encoded[i++] : null;
4092
- const i3 = i < encoded.length ? encoded[i++] : null;
4093
- b64 += toBase64Digit(i1 >> 2);
4094
- b64 += toBase64Digit(((i1 & 3) << 4) | (i2 === null ? 0 : i2 >> 4));
4095
- b64 += i2 === null ? '=' : toBase64Digit(((i2 & 15) << 2) | (i3 === null ? 0 : i3 >> 6));
4096
- b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63);
4103
+ /**
4104
+ * Represents a big integer which is optimized for multiplication operations, as its power-of-twos
4105
+ * are memoized. See `multiplyBy()` for details on the multiplication algorithm.
4106
+ */
4107
+ class BigIntForMultiplication {
4108
+ constructor(value) {
4109
+ this.powerOfTwos = [value];
4097
4110
  }
4098
- return b64;
4099
- }
4100
- function toBase64VLQ(value) {
4101
- value = value < 0 ? ((-value) << 1) + 1 : value << 1;
4102
- let out = '';
4103
- do {
4104
- let digit = value & 31;
4105
- value = value >> 5;
4106
- if (value > 0) {
4107
- digit = digit | 32;
4111
+ /**
4112
+ * Returns the big integer itself.
4113
+ */
4114
+ getValue() {
4115
+ return this.powerOfTwos[0];
4116
+ }
4117
+ /**
4118
+ * Computes the value for `num * b`, where `num` is a JS number and `b` is a big integer. The
4119
+ * value for `b` is represented by a storage model that is optimized for this computation.
4120
+ *
4121
+ * This operation is implemented in N(log2(num)) by continuous halving of the number, where the
4122
+ * least-significant bit (LSB) is tested in each iteration. If the bit is set, the bit's index is
4123
+ * used as exponent into the power-of-two multiplication of `b`.
4124
+ *
4125
+ * As an example, consider the multiplication num=42, b=1337. In binary 42 is 0b00101010 and the
4126
+ * algorithm unrolls into the following iterations:
4127
+ *
4128
+ * Iteration | num | LSB | b * 2^iter | Add? | product
4129
+ * -----------|------------|------|------------|------|--------
4130
+ * 0 | 0b00101010 | 0 | 1337 | No | 0
4131
+ * 1 | 0b00010101 | 1 | 2674 | Yes | 2674
4132
+ * 2 | 0b00001010 | 0 | 5348 | No | 2674
4133
+ * 3 | 0b00000101 | 1 | 10696 | Yes | 13370
4134
+ * 4 | 0b00000010 | 0 | 21392 | No | 13370
4135
+ * 5 | 0b00000001 | 1 | 42784 | Yes | 56154
4136
+ * 6 | 0b00000000 | 0 | 85568 | No | 56154
4137
+ *
4138
+ * The computed product of 56154 is indeed the correct result.
4139
+ *
4140
+ * The `BigIntForMultiplication` representation for a big integer provides memoized access to the
4141
+ * power-of-two values to reduce the workload in computing those values.
4142
+ */
4143
+ multiplyBy(num) {
4144
+ const product = BigInteger.zero();
4145
+ this.multiplyByAndAddTo(num, product);
4146
+ return product;
4147
+ }
4148
+ /**
4149
+ * See `multiplyBy()` for details. This function allows for the computed product to be added
4150
+ * directly to the provided result big integer.
4151
+ */
4152
+ multiplyByAndAddTo(num, result) {
4153
+ for (let exponent = 0; num !== 0; num = num >>> 1, exponent++) {
4154
+ if (num & 1) {
4155
+ const value = this.getMultipliedByPowerOfTwo(exponent);
4156
+ result.addToSelf(value);
4157
+ }
4108
4158
  }
4109
- out += toBase64Digit(digit);
4110
- } while (value > 0);
4111
- return out;
4159
+ }
4160
+ /**
4161
+ * Computes and memoizes the big integer value for `this.number * 2^exponent`.
4162
+ */
4163
+ getMultipliedByPowerOfTwo(exponent) {
4164
+ // Compute the powers up until the requested exponent, where each value is computed from its
4165
+ // predecessor. This is simple as `this.number * 2^(exponent - 1)` only has to be doubled (i.e.
4166
+ // added to itself) to reach `this.number * 2^exponent`.
4167
+ for (let i = this.powerOfTwos.length; i <= exponent; i++) {
4168
+ const previousPower = this.powerOfTwos[i - 1];
4169
+ this.powerOfTwos[i] = previousPower.add(previousPower);
4170
+ }
4171
+ return this.powerOfTwos[exponent];
4172
+ }
4112
4173
  }
4113
- const B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
4114
- function toBase64Digit(value) {
4115
- if (value < 0 || value >= 64) {
4116
- throw new Error(`Can only encode value in the range [0, 63]`);
4174
+ /**
4175
+ * Represents an exponentiation operation for the provided base, of which exponents are computed and
4176
+ * memoized. The results are represented by a `BigIntForMultiplication` which is tailored for
4177
+ * multiplication operations by memoizing the power-of-twos. This effectively results in a matrix
4178
+ * representation that is lazily computed upon request.
4179
+ */
4180
+ class BigIntExponentiation {
4181
+ constructor(base) {
4182
+ this.base = base;
4183
+ this.exponents = [new BigIntForMultiplication(BigInteger.one())];
4184
+ }
4185
+ /**
4186
+ * Compute the value for `this.base^exponent`, resulting in a big integer that is optimized for
4187
+ * further multiplication operations.
4188
+ */
4189
+ toThePowerOf(exponent) {
4190
+ // Compute the results up until the requested exponent, where every value is computed from its
4191
+ // predecessor. This is because `this.base^(exponent - 1)` only has to be multiplied by `base`
4192
+ // to reach `this.base^exponent`.
4193
+ for (let i = this.exponents.length; i <= exponent; i++) {
4194
+ const value = this.exponents[i - 1].multiplyBy(this.base);
4195
+ this.exponents[i] = new BigIntForMultiplication(value);
4196
+ }
4197
+ return this.exponents[exponent];
4117
4198
  }
4118
- return B64_DIGITS[value];
4119
4199
  }
4120
4200
 
4121
4201
  /**
@@ -4125,566 +4205,476 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4125
4205
  * Use of this source code is governed by an MIT-style license that can be
4126
4206
  * found in the LICENSE file at https://angular.io/license
4127
4207
  */
4128
- const _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
4129
- const _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
4130
- const _INDENT_WITH = ' ';
4131
- const CATCH_ERROR_VAR$1 = variable('error', null, null);
4132
- const CATCH_STACK_VAR$1 = variable('stack', null, null);
4133
- class _EmittedLine {
4134
- constructor(indent) {
4135
- this.indent = indent;
4136
- this.partsLength = 0;
4137
- this.parts = [];
4138
- this.srcSpans = [];
4139
- }
4208
+ /**
4209
+ * Compute the message id using the XLIFF1 digest.
4210
+ */
4211
+ function computeDigest(message) {
4212
+ return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`);
4140
4213
  }
4141
- class EmitterVisitorContext {
4142
- constructor(_indent) {
4143
- this._indent = _indent;
4144
- this._classes = [];
4145
- this._preambleLineCount = 0;
4146
- this._lines = [new _EmittedLine(_indent)];
4147
- }
4148
- static createRoot() {
4149
- return new EmitterVisitorContext(0);
4150
- }
4151
- /**
4152
- * @internal strip this from published d.ts files due to
4153
- * https://github.com/microsoft/TypeScript/issues/36216
4154
- */
4155
- get _currentLine() {
4156
- return this._lines[this._lines.length - 1];
4157
- }
4158
- println(from, lastPart = '') {
4159
- this.print(from || null, lastPart, true);
4160
- }
4161
- lineIsEmpty() {
4162
- return this._currentLine.parts.length === 0;
4163
- }
4164
- lineLength() {
4165
- return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;
4166
- }
4167
- print(from, part, newLine = false) {
4168
- if (part.length > 0) {
4169
- this._currentLine.parts.push(part);
4170
- this._currentLine.partsLength += part.length;
4171
- this._currentLine.srcSpans.push(from && from.sourceSpan || null);
4172
- }
4173
- if (newLine) {
4174
- this._lines.push(new _EmittedLine(this._indent));
4175
- }
4176
- }
4177
- removeEmptyLastLine() {
4178
- if (this.lineIsEmpty()) {
4179
- this._lines.pop();
4180
- }
4214
+ /**
4215
+ * Return the message id or compute it using the XLIFF2/XMB/$localize digest.
4216
+ */
4217
+ function decimalDigest(message) {
4218
+ return message.id || computeDecimalDigest(message);
4219
+ }
4220
+ /**
4221
+ * Compute the message id using the XLIFF2/XMB/$localize digest.
4222
+ */
4223
+ function computeDecimalDigest(message) {
4224
+ const visitor = new _SerializerIgnoreIcuExpVisitor();
4225
+ const parts = message.nodes.map(a => a.visit(visitor, null));
4226
+ return computeMsgId(parts.join(''), message.meaning);
4227
+ }
4228
+ /**
4229
+ * Serialize the i18n ast to something xml-like in order to generate an UID.
4230
+ *
4231
+ * The visitor is also used in the i18n parser tests
4232
+ *
4233
+ * @internal
4234
+ */
4235
+ class _SerializerVisitor {
4236
+ visitText(text, context) {
4237
+ return text.value;
4181
4238
  }
4182
- incIndent() {
4183
- this._indent++;
4184
- if (this.lineIsEmpty()) {
4185
- this._currentLine.indent = this._indent;
4186
- }
4239
+ visitContainer(container, context) {
4240
+ return `[${container.children.map(child => child.visit(this)).join(', ')}]`;
4187
4241
  }
4188
- decIndent() {
4189
- this._indent--;
4190
- if (this.lineIsEmpty()) {
4191
- this._currentLine.indent = this._indent;
4192
- }
4242
+ visitIcu(icu, context) {
4243
+ const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
4244
+ return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`;
4193
4245
  }
4194
- pushClass(clazz) {
4195
- this._classes.push(clazz);
4246
+ visitTagPlaceholder(ph, context) {
4247
+ return ph.isVoid ?
4248
+ `<ph tag name="${ph.startName}"/>` :
4249
+ `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`;
4196
4250
  }
4197
- popClass() {
4198
- return this._classes.pop();
4251
+ visitPlaceholder(ph, context) {
4252
+ return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`;
4199
4253
  }
4200
- get currentClass() {
4201
- return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null;
4254
+ visitIcuPlaceholder(ph, context) {
4255
+ return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`;
4202
4256
  }
4203
- toSource() {
4204
- return this.sourceLines
4205
- .map(l => l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : '')
4206
- .join('\n');
4257
+ }
4258
+ const serializerVisitor = new _SerializerVisitor();
4259
+ function serializeNodes(nodes) {
4260
+ return nodes.map(a => a.visit(serializerVisitor, null));
4261
+ }
4262
+ /**
4263
+ * Serialize the i18n ast to something xml-like in order to generate an UID.
4264
+ *
4265
+ * Ignore the ICU expressions so that message IDs stays identical if only the expression changes.
4266
+ *
4267
+ * @internal
4268
+ */
4269
+ class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor {
4270
+ visitIcu(icu, context) {
4271
+ let strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
4272
+ // Do not take the expression into account
4273
+ return `{${icu.type}, ${strCases.join(', ')}}`;
4207
4274
  }
4208
- toSourceMapGenerator(genFilePath, startsAtLine = 0) {
4209
- const map = new SourceMapGenerator(genFilePath);
4210
- let firstOffsetMapped = false;
4211
- const mapFirstOffsetIfNeeded = () => {
4212
- if (!firstOffsetMapped) {
4213
- // Add a single space so that tools won't try to load the file from disk.
4214
- // Note: We are using virtual urls like `ng:///`, so we have to
4215
- // provide a content here.
4216
- map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);
4217
- firstOffsetMapped = true;
4218
- }
4219
- };
4220
- for (let i = 0; i < startsAtLine; i++) {
4221
- map.addLine();
4222
- mapFirstOffsetIfNeeded();
4223
- }
4224
- this.sourceLines.forEach((line, lineIdx) => {
4225
- map.addLine();
4226
- const spans = line.srcSpans;
4227
- const parts = line.parts;
4228
- let col0 = line.indent * _INDENT_WITH.length;
4229
- let spanIdx = 0;
4230
- // skip leading parts without source spans
4231
- while (spanIdx < spans.length && !spans[spanIdx]) {
4232
- col0 += parts[spanIdx].length;
4233
- spanIdx++;
4234
- }
4235
- if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {
4236
- firstOffsetMapped = true;
4275
+ }
4276
+ /**
4277
+ * Compute the SHA1 of the given string
4278
+ *
4279
+ * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
4280
+ *
4281
+ * WARNING: this function has not been designed not tested with security in mind.
4282
+ * DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT.
4283
+ */
4284
+ function sha1(str) {
4285
+ const utf8 = utf8Encode(str);
4286
+ const words32 = bytesToWords32(utf8, Endian.Big);
4287
+ const len = utf8.length * 8;
4288
+ const w = newArray(80);
4289
+ let a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476, e = 0xc3d2e1f0;
4290
+ words32[len >> 5] |= 0x80 << (24 - len % 32);
4291
+ words32[((len + 64 >> 9) << 4) + 15] = len;
4292
+ for (let i = 0; i < words32.length; i += 16) {
4293
+ const h0 = a, h1 = b, h2 = c, h3 = d, h4 = e;
4294
+ for (let j = 0; j < 80; j++) {
4295
+ if (j < 16) {
4296
+ w[j] = words32[i + j];
4237
4297
  }
4238
4298
  else {
4239
- mapFirstOffsetIfNeeded();
4240
- }
4241
- while (spanIdx < spans.length) {
4242
- const span = spans[spanIdx];
4243
- const source = span.start.file;
4244
- const sourceLine = span.start.line;
4245
- const sourceCol = span.start.col;
4246
- map.addSource(source.url, source.content)
4247
- .addMapping(col0, source.url, sourceLine, sourceCol);
4248
- col0 += parts[spanIdx].length;
4249
- spanIdx++;
4250
- // assign parts without span or the same span to the previous segment
4251
- while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) {
4252
- col0 += parts[spanIdx].length;
4253
- spanIdx++;
4254
- }
4255
- }
4256
- });
4257
- return map;
4258
- }
4259
- setPreambleLineCount(count) {
4260
- return this._preambleLineCount = count;
4261
- }
4262
- spanOf(line, column) {
4263
- const emittedLine = this._lines[line - this._preambleLineCount];
4264
- if (emittedLine) {
4265
- let columnsLeft = column - _createIndent(emittedLine.indent).length;
4266
- for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {
4267
- const part = emittedLine.parts[partIndex];
4268
- if (part.length > columnsLeft) {
4269
- return emittedLine.srcSpans[partIndex];
4270
- }
4271
- columnsLeft -= part.length;
4299
+ w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
4272
4300
  }
4301
+ const fkVal = fk(j, b, c, d);
4302
+ const f = fkVal[0];
4303
+ const k = fkVal[1];
4304
+ const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32);
4305
+ e = d;
4306
+ d = c;
4307
+ c = rol32(b, 30);
4308
+ b = a;
4309
+ a = temp;
4273
4310
  }
4274
- return null;
4275
- }
4276
- /**
4277
- * @internal strip this from published d.ts files due to
4278
- * https://github.com/microsoft/TypeScript/issues/36216
4279
- */
4280
- get sourceLines() {
4281
- if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {
4282
- return this._lines.slice(0, -1);
4283
- }
4284
- return this._lines;
4311
+ a = add32(a, h0);
4312
+ b = add32(b, h1);
4313
+ c = add32(c, h2);
4314
+ d = add32(d, h3);
4315
+ e = add32(e, h4);
4285
4316
  }
4317
+ return bytesToHexString(words32ToByteString([a, b, c, d, e]));
4286
4318
  }
4287
- class AbstractEmitterVisitor {
4288
- constructor(_escapeDollarInStrings) {
4289
- this._escapeDollarInStrings = _escapeDollarInStrings;
4290
- }
4291
- printLeadingComments(stmt, ctx) {
4292
- if (stmt.leadingComments === undefined) {
4293
- return;
4294
- }
4295
- for (const comment of stmt.leadingComments) {
4296
- if (comment instanceof JSDocComment) {
4297
- ctx.print(stmt, `/*${comment.toString()}*/`, comment.trailingNewline);
4298
- }
4299
- else {
4300
- if (comment.multiline) {
4301
- ctx.print(stmt, `/* ${comment.text} */`, comment.trailingNewline);
4302
- }
4303
- else {
4304
- comment.text.split('\n').forEach((line) => {
4305
- ctx.println(stmt, `// ${line}`);
4306
- });
4307
- }
4308
- }
4309
- }
4319
+ function fk(index, b, c, d) {
4320
+ if (index < 20) {
4321
+ return [(b & c) | (~b & d), 0x5a827999];
4310
4322
  }
4311
- visitExpressionStmt(stmt, ctx) {
4312
- this.printLeadingComments(stmt, ctx);
4313
- stmt.expr.visitExpression(this, ctx);
4314
- ctx.println(stmt, ';');
4315
- return null;
4323
+ if (index < 40) {
4324
+ return [b ^ c ^ d, 0x6ed9eba1];
4316
4325
  }
4317
- visitReturnStmt(stmt, ctx) {
4318
- this.printLeadingComments(stmt, ctx);
4319
- ctx.print(stmt, `return `);
4320
- stmt.value.visitExpression(this, ctx);
4321
- ctx.println(stmt, ';');
4322
- return null;
4326
+ if (index < 60) {
4327
+ return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc];
4323
4328
  }
4324
- visitIfStmt(stmt, ctx) {
4325
- this.printLeadingComments(stmt, ctx);
4326
- ctx.print(stmt, `if (`);
4327
- stmt.condition.visitExpression(this, ctx);
4328
- ctx.print(stmt, `) {`);
4329
- const hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0;
4330
- if (stmt.trueCase.length <= 1 && !hasElseCase) {
4331
- ctx.print(stmt, ` `);
4332
- this.visitAllStatements(stmt.trueCase, ctx);
4333
- ctx.removeEmptyLastLine();
4334
- ctx.print(stmt, ` `);
4335
- }
4336
- else {
4337
- ctx.println();
4338
- ctx.incIndent();
4339
- this.visitAllStatements(stmt.trueCase, ctx);
4340
- ctx.decIndent();
4341
- if (hasElseCase) {
4342
- ctx.println(stmt, `} else {`);
4343
- ctx.incIndent();
4344
- this.visitAllStatements(stmt.falseCase, ctx);
4345
- ctx.decIndent();
4346
- }
4347
- }
4348
- ctx.println(stmt, `}`);
4349
- return null;
4350
- }
4351
- visitThrowStmt(stmt, ctx) {
4352
- this.printLeadingComments(stmt, ctx);
4353
- ctx.print(stmt, `throw `);
4354
- stmt.error.visitExpression(this, ctx);
4355
- ctx.println(stmt, `;`);
4356
- return null;
4357
- }
4358
- visitWriteVarExpr(expr, ctx) {
4359
- const lineWasEmpty = ctx.lineIsEmpty();
4360
- if (!lineWasEmpty) {
4361
- ctx.print(expr, '(');
4362
- }
4363
- ctx.print(expr, `${expr.name} = `);
4364
- expr.value.visitExpression(this, ctx);
4365
- if (!lineWasEmpty) {
4366
- ctx.print(expr, ')');
4367
- }
4368
- return null;
4369
- }
4370
- visitWriteKeyExpr(expr, ctx) {
4371
- const lineWasEmpty = ctx.lineIsEmpty();
4372
- if (!lineWasEmpty) {
4373
- ctx.print(expr, '(');
4374
- }
4375
- expr.receiver.visitExpression(this, ctx);
4376
- ctx.print(expr, `[`);
4377
- expr.index.visitExpression(this, ctx);
4378
- ctx.print(expr, `] = `);
4379
- expr.value.visitExpression(this, ctx);
4380
- if (!lineWasEmpty) {
4381
- ctx.print(expr, ')');
4382
- }
4383
- return null;
4384
- }
4385
- visitWritePropExpr(expr, ctx) {
4386
- const lineWasEmpty = ctx.lineIsEmpty();
4387
- if (!lineWasEmpty) {
4388
- ctx.print(expr, '(');
4389
- }
4390
- expr.receiver.visitExpression(this, ctx);
4391
- ctx.print(expr, `.${expr.name} = `);
4392
- expr.value.visitExpression(this, ctx);
4393
- if (!lineWasEmpty) {
4394
- ctx.print(expr, ')');
4395
- }
4396
- return null;
4397
- }
4398
- visitInvokeMethodExpr(expr, ctx) {
4399
- expr.receiver.visitExpression(this, ctx);
4400
- let name = expr.name;
4401
- if (expr.builtin != null) {
4402
- name = this.getBuiltinMethodName(expr.builtin);
4403
- if (name == null) {
4404
- // some builtins just mean to skip the call.
4405
- return null;
4406
- }
4407
- }
4408
- ctx.print(expr, `.${name}(`);
4409
- this.visitAllExpressions(expr.args, ctx, `,`);
4410
- ctx.print(expr, `)`);
4411
- return null;
4412
- }
4413
- visitInvokeFunctionExpr(expr, ctx) {
4414
- expr.fn.visitExpression(this, ctx);
4415
- ctx.print(expr, `(`);
4416
- this.visitAllExpressions(expr.args, ctx, ',');
4417
- ctx.print(expr, `)`);
4418
- return null;
4419
- }
4420
- visitTaggedTemplateExpr(expr, ctx) {
4421
- expr.tag.visitExpression(this, ctx);
4422
- ctx.print(expr, '`' + expr.template.elements[0].rawText);
4423
- for (let i = 1; i < expr.template.elements.length; i++) {
4424
- ctx.print(expr, '${');
4425
- expr.template.expressions[i - 1].visitExpression(this, ctx);
4426
- ctx.print(expr, `}${expr.template.elements[i].rawText}`);
4427
- }
4428
- ctx.print(expr, '`');
4429
- return null;
4430
- }
4431
- visitWrappedNodeExpr(ast, ctx) {
4432
- throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');
4433
- }
4434
- visitTypeofExpr(expr, ctx) {
4435
- ctx.print(expr, 'typeof ');
4436
- expr.expr.visitExpression(this, ctx);
4437
- }
4438
- visitReadVarExpr(ast, ctx) {
4439
- let varName = ast.name;
4440
- if (ast.builtin != null) {
4441
- switch (ast.builtin) {
4442
- case BuiltinVar.Super:
4443
- varName = 'super';
4444
- break;
4445
- case BuiltinVar.This:
4446
- varName = 'this';
4447
- break;
4448
- case BuiltinVar.CatchError:
4449
- varName = CATCH_ERROR_VAR$1.name;
4450
- break;
4451
- case BuiltinVar.CatchStack:
4452
- varName = CATCH_STACK_VAR$1.name;
4453
- break;
4454
- default:
4455
- throw new Error(`Unknown builtin variable ${ast.builtin}`);
4456
- }
4457
- }
4458
- ctx.print(ast, varName);
4459
- return null;
4460
- }
4461
- visitInstantiateExpr(ast, ctx) {
4462
- ctx.print(ast, `new `);
4463
- ast.classExpr.visitExpression(this, ctx);
4464
- ctx.print(ast, `(`);
4465
- this.visitAllExpressions(ast.args, ctx, ',');
4466
- ctx.print(ast, `)`);
4467
- return null;
4468
- }
4469
- visitLiteralExpr(ast, ctx) {
4470
- const value = ast.value;
4471
- if (typeof value === 'string') {
4472
- ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings));
4473
- }
4474
- else {
4475
- ctx.print(ast, `${value}`);
4476
- }
4477
- return null;
4478
- }
4479
- visitLocalizedString(ast, ctx) {
4480
- const head = ast.serializeI18nHead();
4481
- ctx.print(ast, '$localize `' + head.raw);
4482
- for (let i = 1; i < ast.messageParts.length; i++) {
4483
- ctx.print(ast, '${');
4484
- ast.expressions[i - 1].visitExpression(this, ctx);
4485
- ctx.print(ast, `}${ast.serializeI18nTemplatePart(i).raw}`);
4486
- }
4487
- ctx.print(ast, '`');
4488
- return null;
4489
- }
4490
- visitConditionalExpr(ast, ctx) {
4491
- ctx.print(ast, `(`);
4492
- ast.condition.visitExpression(this, ctx);
4493
- ctx.print(ast, '? ');
4494
- ast.trueCase.visitExpression(this, ctx);
4495
- ctx.print(ast, ': ');
4496
- ast.falseCase.visitExpression(this, ctx);
4497
- ctx.print(ast, `)`);
4498
- return null;
4499
- }
4500
- visitNotExpr(ast, ctx) {
4501
- ctx.print(ast, '!');
4502
- ast.condition.visitExpression(this, ctx);
4503
- return null;
4504
- }
4505
- visitAssertNotNullExpr(ast, ctx) {
4506
- ast.condition.visitExpression(this, ctx);
4507
- return null;
4508
- }
4509
- visitUnaryOperatorExpr(ast, ctx) {
4510
- let opStr;
4511
- switch (ast.operator) {
4512
- case UnaryOperator.Plus:
4513
- opStr = '+';
4514
- break;
4515
- case UnaryOperator.Minus:
4516
- opStr = '-';
4517
- break;
4518
- default:
4519
- throw new Error(`Unknown operator ${ast.operator}`);
4520
- }
4521
- if (ast.parens)
4522
- ctx.print(ast, `(`);
4523
- ctx.print(ast, opStr);
4524
- ast.expr.visitExpression(this, ctx);
4525
- if (ast.parens)
4526
- ctx.print(ast, `)`);
4527
- return null;
4528
- }
4529
- visitBinaryOperatorExpr(ast, ctx) {
4530
- let opStr;
4531
- switch (ast.operator) {
4532
- case BinaryOperator.Equals:
4533
- opStr = '==';
4534
- break;
4535
- case BinaryOperator.Identical:
4536
- opStr = '===';
4537
- break;
4538
- case BinaryOperator.NotEquals:
4539
- opStr = '!=';
4540
- break;
4541
- case BinaryOperator.NotIdentical:
4542
- opStr = '!==';
4543
- break;
4544
- case BinaryOperator.And:
4545
- opStr = '&&';
4546
- break;
4547
- case BinaryOperator.BitwiseAnd:
4548
- opStr = '&';
4549
- break;
4550
- case BinaryOperator.Or:
4551
- opStr = '||';
4552
- break;
4553
- case BinaryOperator.Plus:
4554
- opStr = '+';
4555
- break;
4556
- case BinaryOperator.Minus:
4557
- opStr = '-';
4558
- break;
4559
- case BinaryOperator.Divide:
4560
- opStr = '/';
4561
- break;
4562
- case BinaryOperator.Multiply:
4563
- opStr = '*';
4564
- break;
4565
- case BinaryOperator.Modulo:
4566
- opStr = '%';
4567
- break;
4568
- case BinaryOperator.Lower:
4569
- opStr = '<';
4570
- break;
4571
- case BinaryOperator.LowerEquals:
4572
- opStr = '<=';
4573
- break;
4574
- case BinaryOperator.Bigger:
4575
- opStr = '>';
4576
- break;
4577
- case BinaryOperator.BiggerEquals:
4578
- opStr = '>=';
4579
- break;
4580
- case BinaryOperator.NullishCoalesce:
4581
- opStr = '??';
4582
- break;
4583
- default:
4584
- throw new Error(`Unknown operator ${ast.operator}`);
4585
- }
4586
- if (ast.parens)
4587
- ctx.print(ast, `(`);
4588
- ast.lhs.visitExpression(this, ctx);
4589
- ctx.print(ast, ` ${opStr} `);
4590
- ast.rhs.visitExpression(this, ctx);
4591
- if (ast.parens)
4592
- ctx.print(ast, `)`);
4593
- return null;
4594
- }
4595
- visitReadPropExpr(ast, ctx) {
4596
- ast.receiver.visitExpression(this, ctx);
4597
- ctx.print(ast, `.`);
4598
- ctx.print(ast, ast.name);
4599
- return null;
4600
- }
4601
- visitReadKeyExpr(ast, ctx) {
4602
- ast.receiver.visitExpression(this, ctx);
4603
- ctx.print(ast, `[`);
4604
- ast.index.visitExpression(this, ctx);
4605
- ctx.print(ast, `]`);
4606
- return null;
4607
- }
4608
- visitLiteralArrayExpr(ast, ctx) {
4609
- ctx.print(ast, `[`);
4610
- this.visitAllExpressions(ast.entries, ctx, ',');
4611
- ctx.print(ast, `]`);
4612
- return null;
4329
+ return [b ^ c ^ d, 0xca62c1d6];
4330
+ }
4331
+ /**
4332
+ * Compute the fingerprint of the given string
4333
+ *
4334
+ * The output is 64 bit number encoded as a decimal string
4335
+ *
4336
+ * based on:
4337
+ * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java
4338
+ */
4339
+ function fingerprint(str) {
4340
+ const utf8 = utf8Encode(str);
4341
+ let hi = hash32(utf8, 0);
4342
+ let lo = hash32(utf8, 102072);
4343
+ if (hi == 0 && (lo == 0 || lo == 1)) {
4344
+ hi = hi ^ 0x130f9bef;
4345
+ lo = lo ^ -0x6b5f56d8;
4613
4346
  }
4614
- visitLiteralMapExpr(ast, ctx) {
4615
- ctx.print(ast, `{`);
4616
- this.visitAllObjects(entry => {
4617
- ctx.print(ast, `${escapeIdentifier(entry.key, this._escapeDollarInStrings, entry.quoted)}:`);
4618
- entry.value.visitExpression(this, ctx);
4619
- }, ast.entries, ctx, ',');
4620
- ctx.print(ast, `}`);
4621
- return null;
4347
+ return [hi, lo];
4348
+ }
4349
+ function computeMsgId(msg, meaning = '') {
4350
+ let msgFingerprint = fingerprint(msg);
4351
+ if (meaning) {
4352
+ const meaningFingerprint = fingerprint(meaning);
4353
+ msgFingerprint = add64(rol64(msgFingerprint, 1), meaningFingerprint);
4622
4354
  }
4623
- visitCommaExpr(ast, ctx) {
4624
- ctx.print(ast, '(');
4625
- this.visitAllExpressions(ast.parts, ctx, ',');
4626
- ctx.print(ast, ')');
4627
- return null;
4355
+ const hi = msgFingerprint[0];
4356
+ const lo = msgFingerprint[1];
4357
+ return wordsToDecimalString(hi & 0x7fffffff, lo);
4358
+ }
4359
+ function hash32(bytes, c) {
4360
+ let a = 0x9e3779b9, b = 0x9e3779b9;
4361
+ let i;
4362
+ const len = bytes.length;
4363
+ for (i = 0; i + 12 <= len; i += 12) {
4364
+ a = add32(a, wordAt(bytes, i, Endian.Little));
4365
+ b = add32(b, wordAt(bytes, i + 4, Endian.Little));
4366
+ c = add32(c, wordAt(bytes, i + 8, Endian.Little));
4367
+ const res = mix(a, b, c);
4368
+ a = res[0], b = res[1], c = res[2];
4628
4369
  }
4629
- visitAllExpressions(expressions, ctx, separator) {
4630
- this.visitAllObjects(expr => expr.visitExpression(this, ctx), expressions, ctx, separator);
4370
+ a = add32(a, wordAt(bytes, i, Endian.Little));
4371
+ b = add32(b, wordAt(bytes, i + 4, Endian.Little));
4372
+ // the first byte of c is reserved for the length
4373
+ c = add32(c, len);
4374
+ c = add32(c, wordAt(bytes, i + 8, Endian.Little) << 8);
4375
+ return mix(a, b, c)[2];
4376
+ }
4377
+ // clang-format off
4378
+ function mix(a, b, c) {
4379
+ a = sub32(a, b);
4380
+ a = sub32(a, c);
4381
+ a ^= c >>> 13;
4382
+ b = sub32(b, c);
4383
+ b = sub32(b, a);
4384
+ b ^= a << 8;
4385
+ c = sub32(c, a);
4386
+ c = sub32(c, b);
4387
+ c ^= b >>> 13;
4388
+ a = sub32(a, b);
4389
+ a = sub32(a, c);
4390
+ a ^= c >>> 12;
4391
+ b = sub32(b, c);
4392
+ b = sub32(b, a);
4393
+ b ^= a << 16;
4394
+ c = sub32(c, a);
4395
+ c = sub32(c, b);
4396
+ c ^= b >>> 5;
4397
+ a = sub32(a, b);
4398
+ a = sub32(a, c);
4399
+ a ^= c >>> 3;
4400
+ b = sub32(b, c);
4401
+ b = sub32(b, a);
4402
+ b ^= a << 10;
4403
+ c = sub32(c, a);
4404
+ c = sub32(c, b);
4405
+ c ^= b >>> 15;
4406
+ return [a, b, c];
4407
+ }
4408
+ // clang-format on
4409
+ // Utils
4410
+ var Endian;
4411
+ (function (Endian) {
4412
+ Endian[Endian["Little"] = 0] = "Little";
4413
+ Endian[Endian["Big"] = 1] = "Big";
4414
+ })(Endian || (Endian = {}));
4415
+ function add32(a, b) {
4416
+ return add32to64(a, b)[1];
4417
+ }
4418
+ function add32to64(a, b) {
4419
+ const low = (a & 0xffff) + (b & 0xffff);
4420
+ const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
4421
+ return [high >>> 16, (high << 16) | (low & 0xffff)];
4422
+ }
4423
+ function add64(a, b) {
4424
+ const ah = a[0], al = a[1];
4425
+ const bh = b[0], bl = b[1];
4426
+ const result = add32to64(al, bl);
4427
+ const carry = result[0];
4428
+ const l = result[1];
4429
+ const h = add32(add32(ah, bh), carry);
4430
+ return [h, l];
4431
+ }
4432
+ function sub32(a, b) {
4433
+ const low = (a & 0xffff) - (b & 0xffff);
4434
+ const high = (a >> 16) - (b >> 16) + (low >> 16);
4435
+ return (high << 16) | (low & 0xffff);
4436
+ }
4437
+ // Rotate a 32b number left `count` position
4438
+ function rol32(a, count) {
4439
+ return (a << count) | (a >>> (32 - count));
4440
+ }
4441
+ // Rotate a 64b number left `count` position
4442
+ function rol64(num, count) {
4443
+ const hi = num[0], lo = num[1];
4444
+ const h = (hi << count) | (lo >>> (32 - count));
4445
+ const l = (lo << count) | (hi >>> (32 - count));
4446
+ return [h, l];
4447
+ }
4448
+ function bytesToWords32(bytes, endian) {
4449
+ const size = (bytes.length + 3) >>> 2;
4450
+ const words32 = [];
4451
+ for (let i = 0; i < size; i++) {
4452
+ words32[i] = wordAt(bytes, i * 4, endian);
4631
4453
  }
4632
- visitAllObjects(handler, expressions, ctx, separator) {
4633
- let incrementedIndent = false;
4634
- for (let i = 0; i < expressions.length; i++) {
4635
- if (i > 0) {
4636
- if (ctx.lineLength() > 80) {
4637
- ctx.print(null, separator, true);
4638
- if (!incrementedIndent) {
4639
- // continuation are marked with double indent.
4640
- ctx.incIndent();
4641
- ctx.incIndent();
4642
- incrementedIndent = true;
4643
- }
4644
- }
4645
- else {
4646
- ctx.print(null, separator, false);
4647
- }
4648
- }
4649
- handler(expressions[i]);
4454
+ return words32;
4455
+ }
4456
+ function byteAt(bytes, index) {
4457
+ return index >= bytes.length ? 0 : bytes[index];
4458
+ }
4459
+ function wordAt(bytes, index, endian) {
4460
+ let word = 0;
4461
+ if (endian === Endian.Big) {
4462
+ for (let i = 0; i < 4; i++) {
4463
+ word += byteAt(bytes, index + i) << (24 - 8 * i);
4650
4464
  }
4651
- if (incrementedIndent) {
4652
- // continuation are marked with double indent.
4653
- ctx.decIndent();
4654
- ctx.decIndent();
4465
+ }
4466
+ else {
4467
+ for (let i = 0; i < 4; i++) {
4468
+ word += byteAt(bytes, index + i) << 8 * i;
4655
4469
  }
4656
4470
  }
4657
- visitAllStatements(statements, ctx) {
4658
- statements.forEach((stmt) => stmt.visitStatement(this, ctx));
4471
+ return word;
4472
+ }
4473
+ function words32ToByteString(words32) {
4474
+ return words32.reduce((bytes, word) => bytes.concat(word32ToByteString(word)), []);
4475
+ }
4476
+ function word32ToByteString(word) {
4477
+ let bytes = [];
4478
+ for (let i = 0; i < 4; i++) {
4479
+ bytes.push((word >>> 8 * (3 - i)) & 0xff);
4659
4480
  }
4481
+ return bytes;
4660
4482
  }
4661
- function escapeIdentifier(input, escapeDollar, alwaysQuote = true) {
4662
- if (input == null) {
4663
- return null;
4483
+ function bytesToHexString(bytes) {
4484
+ let hex = '';
4485
+ for (let i = 0; i < bytes.length; i++) {
4486
+ const b = byteAt(bytes, i);
4487
+ hex += (b >>> 4).toString(16) + (b & 0x0f).toString(16);
4664
4488
  }
4665
- const body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, (...match) => {
4666
- if (match[0] == '$') {
4667
- return escapeDollar ? '\\$' : '$';
4668
- }
4669
- else if (match[0] == '\n') {
4670
- return '\\n';
4671
- }
4672
- else if (match[0] == '\r') {
4673
- return '\\r';
4674
- }
4675
- else {
4676
- return `\\${match[0]}`;
4677
- }
4489
+ return hex.toLowerCase();
4490
+ }
4491
+ /**
4492
+ * Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized
4493
+ * power-of-256 results with memoized power-of-two computations for efficient multiplication.
4494
+ *
4495
+ * For our purposes, this can be safely stored as a global without memory concerns. The reason is
4496
+ * that we encode two words, so only need the 0th (for the low word) and 4th (for the high word)
4497
+ * exponent.
4498
+ */
4499
+ const base256 = new BigIntExponentiation(256);
4500
+ /**
4501
+ * Represents two 32-bit words as a single decimal number. This requires a big integer storage
4502
+ * model as JS numbers are not accurate enough to represent the 64-bit number.
4503
+ *
4504
+ * Based on https://www.danvk.org/hex2dec.html
4505
+ */
4506
+ function wordsToDecimalString(hi, lo) {
4507
+ // Encode the four bytes in lo in the lower digits of the decimal number.
4508
+ // Note: the multiplication results in lo itself but represented by a big integer using its
4509
+ // decimal digits.
4510
+ const decimal = base256.toThePowerOf(0).multiplyBy(lo);
4511
+ // Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why
4512
+ // this multiplication factor is applied.
4513
+ base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal);
4514
+ return decimal.toString();
4515
+ }
4516
+
4517
+ /**
4518
+ * @license
4519
+ * Copyright Google LLC All Rights Reserved.
4520
+ *
4521
+ * Use of this source code is governed by an MIT-style license that can be
4522
+ * found in the LICENSE file at https://angular.io/license
4523
+ */
4524
+ // XMB/XTB placeholders can only contain A-Z, 0-9 and _
4525
+ function toPublicName(internalName) {
4526
+ return internalName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
4527
+ }
4528
+
4529
+ /**
4530
+ * @license
4531
+ * Copyright Google LLC All Rights Reserved.
4532
+ *
4533
+ * Use of this source code is governed by an MIT-style license that can be
4534
+ * found in the LICENSE file at https://angular.io/license
4535
+ */
4536
+ /* Closure variables holding messages must be named `MSG_[A-Z0-9]+` */
4537
+ const CLOSURE_TRANSLATION_VAR_PREFIX = 'MSG_';
4538
+ /**
4539
+ * Prefix for non-`goog.getMsg` i18n-related vars.
4540
+ * Note: the prefix uses lowercase characters intentionally due to a Closure behavior that
4541
+ * considers variables like `I18N_0` as constants and throws an error when their value changes.
4542
+ */
4543
+ const TRANSLATION_VAR_PREFIX = 'i18n_';
4544
+ /** Name of the i18n attributes **/
4545
+ const I18N_ATTR = 'i18n';
4546
+ const I18N_ATTR_PREFIX = 'i18n-';
4547
+ /** Prefix of var expressions used in ICUs */
4548
+ const I18N_ICU_VAR_PREFIX = 'VAR_';
4549
+ /** Prefix of ICU expressions for post processing */
4550
+ const I18N_ICU_MAPPING_PREFIX = 'I18N_EXP_';
4551
+ /** Placeholder wrapper for i18n expressions **/
4552
+ const I18N_PLACEHOLDER_SYMBOL = '�';
4553
+ function isI18nAttribute(name) {
4554
+ return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
4555
+ }
4556
+ function isI18nRootNode(meta) {
4557
+ return meta instanceof Message;
4558
+ }
4559
+ function isSingleI18nIcu(meta) {
4560
+ return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu$1;
4561
+ }
4562
+ function hasI18nMeta(node) {
4563
+ return !!node.i18n;
4564
+ }
4565
+ function hasI18nAttrs(element) {
4566
+ return element.attrs.some((attr) => isI18nAttribute(attr.name));
4567
+ }
4568
+ function icuFromI18nMessage(message) {
4569
+ return message.nodes[0];
4570
+ }
4571
+ function wrapI18nPlaceholder(content, contextId = 0) {
4572
+ const blockId = contextId > 0 ? `:${contextId}` : '';
4573
+ return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`;
4574
+ }
4575
+ function assembleI18nBoundString(strings, bindingStartIndex = 0, contextId = 0) {
4576
+ if (!strings.length)
4577
+ return '';
4578
+ let acc = '';
4579
+ const lastIdx = strings.length - 1;
4580
+ for (let i = 0; i < lastIdx; i++) {
4581
+ acc += `${strings[i]}${wrapI18nPlaceholder(bindingStartIndex + i, contextId)}`;
4582
+ }
4583
+ acc += strings[lastIdx];
4584
+ return acc;
4585
+ }
4586
+ function getSeqNumberGenerator(startsAt = 0) {
4587
+ let current = startsAt;
4588
+ return () => current++;
4589
+ }
4590
+ function placeholdersToParams(placeholders) {
4591
+ const params = {};
4592
+ placeholders.forEach((values, key) => {
4593
+ params[key] = literal(values.length > 1 ? `[${values.join('|')}]` : values[0]);
4678
4594
  });
4679
- const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);
4680
- return requiresQuotes ? `'${body}'` : body;
4595
+ return params;
4681
4596
  }
4682
- function _createIndent(count) {
4683
- let res = '';
4684
- for (let i = 0; i < count; i++) {
4685
- res += _INDENT_WITH;
4597
+ function updatePlaceholderMap(map, name, ...values) {
4598
+ const current = map.get(name) || [];
4599
+ current.push(...values);
4600
+ map.set(name, current);
4601
+ }
4602
+ function assembleBoundTextPlaceholders(meta, bindingStartIndex = 0, contextId = 0) {
4603
+ const startIdx = bindingStartIndex;
4604
+ const placeholders = new Map();
4605
+ const node = meta instanceof Message ? meta.nodes.find(node => node instanceof Container) : meta;
4606
+ if (node) {
4607
+ node
4608
+ .children
4609
+ .filter((child) => child instanceof Placeholder)
4610
+ .forEach((child, idx) => {
4611
+ const content = wrapI18nPlaceholder(startIdx + idx, contextId);
4612
+ updatePlaceholderMap(placeholders, child.name, content);
4613
+ });
4686
4614
  }
4687
- return res;
4615
+ return placeholders;
4616
+ }
4617
+ /**
4618
+ * Format the placeholder names in a map of placeholders to expressions.
4619
+ *
4620
+ * The placeholder names are converted from "internal" format (e.g. `START_TAG_DIV_1`) to "external"
4621
+ * format (e.g. `startTagDiv_1`).
4622
+ *
4623
+ * @param params A map of placeholder names to expressions.
4624
+ * @param useCamelCase whether to camelCase the placeholder name when formatting.
4625
+ * @returns A new map of formatted placeholder names to expressions.
4626
+ */
4627
+ function i18nFormatPlaceholderNames(params = {}, useCamelCase) {
4628
+ const _params = {};
4629
+ if (params && Object.keys(params).length) {
4630
+ Object.keys(params).forEach(key => _params[formatI18nPlaceholderName(key, useCamelCase)] = params[key]);
4631
+ }
4632
+ return _params;
4633
+ }
4634
+ /**
4635
+ * Converts internal placeholder names to public-facing format
4636
+ * (for example to use in goog.getMsg call).
4637
+ * Example: `START_TAG_DIV_1` is converted to `startTagDiv_1`.
4638
+ *
4639
+ * @param name The placeholder name that should be formatted
4640
+ * @returns Formatted placeholder name
4641
+ */
4642
+ function formatI18nPlaceholderName(name, useCamelCase = true) {
4643
+ const publicName = toPublicName(name);
4644
+ if (!useCamelCase) {
4645
+ return publicName;
4646
+ }
4647
+ const chunks = publicName.split('_');
4648
+ if (chunks.length === 1) {
4649
+ // if no "_" found - just lowercase the value
4650
+ return name.toLowerCase();
4651
+ }
4652
+ let postfix;
4653
+ // eject last element if it's a number
4654
+ if (/^\d+$/.test(chunks[chunks.length - 1])) {
4655
+ postfix = chunks.pop();
4656
+ }
4657
+ let raw = chunks.shift().toLowerCase();
4658
+ if (chunks.length) {
4659
+ raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join('');
4660
+ }
4661
+ return postfix ? `${raw}_${postfix}` : raw;
4662
+ }
4663
+ /**
4664
+ * Generates a prefix for translation const name.
4665
+ *
4666
+ * @param extra Additional local prefix that should be injected into translation var name
4667
+ * @returns Complete translation const prefix
4668
+ */
4669
+ function getTranslationConstPrefix(extra) {
4670
+ return `${CLOSURE_TRANSLATION_VAR_PREFIX}${extra}`.toUpperCase();
4671
+ }
4672
+ /**
4673
+ * Generate AST to declare a variable. E.g. `var I18N_1;`.
4674
+ * @param variable the name of the variable to declare.
4675
+ */
4676
+ function declareI18nVariable(variable) {
4677
+ return new DeclareVarStmt(variable.name, undefined, INFERRED_TYPE, undefined, variable.sourceSpan);
4688
4678
  }
4689
4679
 
4690
4680
  /**
@@ -4694,242 +4684,205 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4694
4684
  * Use of this source code is governed by an MIT-style license that can be
4695
4685
  * found in the LICENSE file at https://angular.io/license
4696
4686
  */
4697
- function typeWithParameters(type, numParams) {
4698
- if (numParams === 0) {
4699
- return expressionType(type);
4700
- }
4701
- const params = [];
4702
- for (let i = 0; i < numParams; i++) {
4703
- params.push(DYNAMIC_TYPE);
4704
- }
4705
- return expressionType(type, undefined, params);
4706
- }
4707
- const ANIMATE_SYMBOL_PREFIX = '@';
4708
- function prepareSyntheticPropertyName(name) {
4709
- return `${ANIMATE_SYMBOL_PREFIX}${name}`;
4710
- }
4711
- function prepareSyntheticListenerName(name, phase) {
4712
- return `${ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;
4713
- }
4714
- function getSafePropertyAccessString(accessor, name) {
4715
- const escapedName = escapeIdentifier(name, false, false);
4716
- return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;
4717
- }
4718
- function prepareSyntheticListenerFunctionName(name, phase) {
4719
- return `animation_${name}_${phase}`;
4720
- }
4721
- function jitOnlyGuardedExpression(expr) {
4722
- return guardedExpression('ngJitMode', expr);
4723
- }
4724
- function devOnlyGuardedExpression(expr) {
4725
- return guardedExpression('ngDevMode', expr);
4726
- }
4727
- function guardedExpression(guard, expr) {
4728
- const guardExpr = new ExternalExpr({ name: guard, moduleName: null });
4729
- const guardNotDefined = new BinaryOperatorExpr(BinaryOperator.Identical, new TypeofExpr(guardExpr), literal('undefined'));
4730
- const guardUndefinedOrTrue = new BinaryOperatorExpr(BinaryOperator.Or, guardNotDefined, guardExpr, /* type */ undefined,
4731
- /* sourceSpan */ undefined, true);
4732
- return new BinaryOperatorExpr(BinaryOperator.And, guardUndefinedOrTrue, expr);
4733
- }
4734
- function wrapReference(value) {
4735
- const wrapped = new WrappedNodeExpr(value);
4736
- return { value: wrapped, type: wrapped };
4737
- }
4738
- function refsToArray(refs, shouldForwardDeclare) {
4739
- const values = literalArr(refs.map(ref => ref.value));
4740
- return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
4741
- }
4742
-
4743
- var R3FactoryDelegateType;
4744
- (function (R3FactoryDelegateType) {
4745
- R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
4746
- R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function";
4747
- })(R3FactoryDelegateType || (R3FactoryDelegateType = {}));
4748
- var FactoryTarget;
4749
- (function (FactoryTarget) {
4750
- FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
4751
- FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
4752
- FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
4753
- FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
4754
- FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
4755
- })(FactoryTarget || (FactoryTarget = {}));
4756
4687
  /**
4757
- * Construct a factory function expression for the given `R3FactoryMetadata`.
4688
+ * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in
4689
+ * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may
4690
+ * bot work in some cases when object keys are mangled by minifier.
4691
+ *
4692
+ * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with
4693
+ * inputs that contain potentially unsafe chars.
4758
4694
  */
4759
- function compileFactoryFunction(meta) {
4760
- const t = variable('t');
4761
- let baseFactoryVar = null;
4762
- // The type to instantiate via constructor invocation. If there is no delegated factory, meaning
4763
- // this type is always created by constructor invocation, then this is the type-to-create
4764
- // parameter provided by the user (t) if specified, or the current type if not. If there is a
4765
- // delegated factory (which is used to create the current type) then this is only the type-to-
4766
- // create parameter (t).
4767
- const typeForCtor = !isDelegatedFactoryMetadata(meta) ?
4768
- new BinaryOperatorExpr(BinaryOperator.Or, t, meta.internalType) :
4769
- t;
4770
- let ctorExpr = null;
4771
- if (meta.deps !== null) {
4772
- // There is a constructor (either explicitly or implicitly defined).
4773
- if (meta.deps !== 'invalid') {
4774
- ctorExpr = new InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));
4695
+ const UNSAFE_OBJECT_KEY_NAME_REGEXP = /[-.]/;
4696
+ /** Name of the temporary to use during data binding */
4697
+ const TEMPORARY_NAME = '_t';
4698
+ /** Name of the context parameter passed into a template function */
4699
+ const CONTEXT_NAME = 'ctx';
4700
+ /** Name of the RenderFlag passed into a template function */
4701
+ const RENDER_FLAGS = 'rf';
4702
+ /** The prefix reference variables */
4703
+ const REFERENCE_PREFIX = '_r';
4704
+ /** The name of the implicit context reference */
4705
+ const IMPLICIT_REFERENCE = '$implicit';
4706
+ /** Non bindable attribute name **/
4707
+ const NON_BINDABLE_ATTR = 'ngNonBindable';
4708
+ /** Name for the variable keeping track of the context returned by `ɵɵrestoreView`. */
4709
+ const RESTORED_VIEW_CONTEXT_NAME = 'restoredCtx';
4710
+ /**
4711
+ * Creates an allocator for a temporary variable.
4712
+ *
4713
+ * A variable declaration is added to the statements the first time the allocator is invoked.
4714
+ */
4715
+ function temporaryAllocator(statements, name) {
4716
+ let temp = null;
4717
+ return () => {
4718
+ if (!temp) {
4719
+ statements.push(new DeclareVarStmt(TEMPORARY_NAME, undefined, DYNAMIC_TYPE));
4720
+ temp = variable(name);
4775
4721
  }
4776
- }
4777
- else {
4778
- // There is no constructor, use the base class' factory to construct typeForCtor.
4779
- baseFactoryVar = variable(`ɵ${meta.name}_BaseFactory`);
4780
- ctorExpr = baseFactoryVar.callFn([typeForCtor]);
4781
- }
4782
- const body = [];
4783
- let retExpr = null;
4784
- function makeConditionalFactory(nonCtorExpr) {
4785
- const r = variable('r');
4786
- body.push(r.set(NULL_EXPR).toDeclStmt());
4787
- const ctorStmt = ctorExpr !== null ? r.set(ctorExpr).toStmt() :
4788
- importExpr(Identifiers.invalidFactory).callFn([]).toStmt();
4789
- body.push(ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()]));
4790
- return r;
4791
- }
4792
- if (isDelegatedFactoryMetadata(meta)) {
4793
- // This type is created with a delegated factory. If a type parameter is not specified, call
4794
- // the factory instead.
4795
- const delegateArgs = injectDependencies(meta.delegateDeps, meta.target);
4796
- // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.
4797
- const factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ?
4798
- InstantiateExpr :
4799
- InvokeFunctionExpr)(meta.delegate, delegateArgs);
4800
- retExpr = makeConditionalFactory(factoryExpr);
4801
- }
4802
- else if (isExpressionFactoryMetadata(meta)) {
4803
- // TODO(alxhub): decide whether to lower the value here or in the caller
4804
- retExpr = makeConditionalFactory(meta.expression);
4805
- }
4806
- else {
4807
- retExpr = ctorExpr;
4808
- }
4809
- if (retExpr === null) {
4810
- // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.
4811
- body.push(importExpr(Identifiers.invalidFactory).callFn([]).toStmt());
4812
- }
4813
- else if (baseFactoryVar !== null) {
4814
- // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it.
4815
- const getInheritedFactoryCall = importExpr(Identifiers.getInheritedFactory).callFn([meta.internalType]);
4816
- // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))`
4817
- const baseFactory = new BinaryOperatorExpr(BinaryOperator.Or, baseFactoryVar, baseFactoryVar.set(getInheritedFactoryCall));
4818
- body.push(new ReturnStatement(baseFactory.callFn([typeForCtor])));
4819
- }
4820
- else {
4821
- // This is straightforward factory, just return it.
4822
- body.push(new ReturnStatement(retExpr));
4823
- }
4824
- let factoryFn = fn([new FnParam('t', DYNAMIC_TYPE)], body, INFERRED_TYPE, undefined, `${meta.name}_Factory`);
4825
- if (baseFactoryVar !== null) {
4826
- // There is a base factory variable so wrap its declaration along with the factory function into
4827
- // an IIFE.
4828
- factoryFn = fn([], [
4829
- new DeclareVarStmt(baseFactoryVar.name), new ReturnStatement(factoryFn)
4830
- ]).callFn([], /* sourceSpan */ undefined, /* pure */ true);
4831
- }
4832
- return {
4833
- expression: factoryFn,
4834
- statements: [],
4835
- type: createFactoryType(meta),
4722
+ return temp;
4836
4723
  };
4837
4724
  }
4838
- function createFactoryType(meta) {
4839
- const ctorDepsType = meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : NONE_TYPE;
4840
- return expressionType(importExpr(Identifiers.FactoryDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType]));
4725
+ function unsupported(feature) {
4726
+ if (this) {
4727
+ throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
4728
+ }
4729
+ throw new Error(`Feature ${feature} is not supported yet`);
4841
4730
  }
4842
- function injectDependencies(deps, target) {
4843
- return deps.map((dep, index) => compileInjectDependency(dep, target, index));
4731
+ function invalid$1(arg) {
4732
+ throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
4844
4733
  }
4845
- function compileInjectDependency(dep, target, index) {
4846
- // Interpret the dependency according to its resolved type.
4847
- if (dep.token === null) {
4848
- return importExpr(Identifiers.invalidFactoryDep).callFn([literal(index)]);
4734
+ function asLiteral(value) {
4735
+ if (Array.isArray(value)) {
4736
+ return literalArr(value.map(asLiteral));
4849
4737
  }
4850
- else if (dep.attributeNameType === null) {
4851
- // Build up the injection flags according to the metadata.
4852
- const flags = 0 /* Default */ | (dep.self ? 2 /* Self */ : 0) |
4853
- (dep.skipSelf ? 4 /* SkipSelf */ : 0) | (dep.host ? 1 /* Host */ : 0) |
4854
- (dep.optional ? 8 /* Optional */ : 0) |
4855
- (target === FactoryTarget.Pipe ? 16 /* ForPipe */ : 0);
4856
- // If this dependency is optional or otherwise has non-default flags, then additional
4857
- // parameters describing how to inject the dependency must be passed to the inject function
4858
- // that's being used.
4859
- let flagsParam = (flags !== 0 /* Default */ || dep.optional) ? literal(flags) : null;
4860
- // Build up the arguments to the injectFn call.
4861
- const injectArgs = [dep.token];
4862
- if (flagsParam) {
4863
- injectArgs.push(flagsParam);
4864
- }
4865
- const injectFn = getInjectFn(target);
4866
- return importExpr(injectFn).callFn(injectArgs);
4738
+ return literal(value, INFERRED_TYPE);
4739
+ }
4740
+ function conditionallyCreateMapObjectLiteral(keys, keepDeclared) {
4741
+ if (Object.getOwnPropertyNames(keys).length > 0) {
4742
+ return mapToExpression(keys, keepDeclared);
4867
4743
  }
4868
- else {
4869
- // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()`
4870
- // type dependency. For the generated JS we still want to use the `dep.token` value in case the
4871
- // name given for the attribute is not a string literal. For example given `@Attribute(foo())`,
4872
- // we want to generate `ɵɵinjectAttribute(foo())`.
4873
- //
4874
- // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate
4875
- // typings.
4876
- return importExpr(Identifiers.injectAttribute).callFn([dep.token]);
4744
+ return null;
4745
+ }
4746
+ function mapToExpression(map, keepDeclared) {
4747
+ return literalMap(Object.getOwnPropertyNames(map).map(key => {
4748
+ // canonical syntax: `dirProp: publicProp`
4749
+ // if there is no `:`, use dirProp = elProp
4750
+ const value = map[key];
4751
+ let declaredName;
4752
+ let publicName;
4753
+ let minifiedName;
4754
+ let needsDeclaredName;
4755
+ if (Array.isArray(value)) {
4756
+ [publicName, declaredName] = value;
4757
+ minifiedName = key;
4758
+ needsDeclaredName = publicName !== declaredName;
4759
+ }
4760
+ else {
4761
+ [declaredName, publicName] = splitAtColon(key, [key, value]);
4762
+ minifiedName = declaredName;
4763
+ // Only include the declared name if extracted from the key, i.e. the key contains a colon.
4764
+ // Otherwise the declared name should be omitted even if it is different from the public name,
4765
+ // as it may have already been minified.
4766
+ needsDeclaredName = publicName !== declaredName && key.includes(':');
4767
+ }
4768
+ return {
4769
+ key: minifiedName,
4770
+ // put quotes around keys that contain potentially unsafe characters
4771
+ quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName),
4772
+ value: (keepDeclared && needsDeclaredName) ?
4773
+ literalArr([asLiteral(publicName), asLiteral(declaredName)]) :
4774
+ asLiteral(publicName)
4775
+ };
4776
+ }));
4777
+ }
4778
+ /**
4779
+ * Remove trailing null nodes as they are implied.
4780
+ */
4781
+ function trimTrailingNulls(parameters) {
4782
+ while (isNull(parameters[parameters.length - 1])) {
4783
+ parameters.pop();
4877
4784
  }
4785
+ return parameters;
4878
4786
  }
4879
- function createCtorDepsType(deps) {
4880
- let hasTypes = false;
4881
- const attributeTypes = deps.map(dep => {
4882
- const type = createCtorDepType(dep);
4883
- if (type !== null) {
4884
- hasTypes = true;
4885
- return type;
4886
- }
4887
- else {
4888
- return literal(null);
4889
- }
4890
- });
4891
- if (hasTypes) {
4892
- return expressionType(literalArr(attributeTypes));
4787
+ function getQueryPredicate(query, constantPool) {
4788
+ if (Array.isArray(query.predicate)) {
4789
+ let predicate = [];
4790
+ query.predicate.forEach((selector) => {
4791
+ // Each item in predicates array may contain strings with comma-separated refs
4792
+ // (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
4793
+ // as separate array entities
4794
+ const selectors = selector.split(',').map(token => literal(token.trim()));
4795
+ predicate.push(...selectors);
4796
+ });
4797
+ return constantPool.getConstLiteral(literalArr(predicate), true);
4893
4798
  }
4894
4799
  else {
4895
- return NONE_TYPE;
4800
+ // The original predicate may have been wrapped in a `forwardRef()` call.
4801
+ switch (query.predicate.forwardRef) {
4802
+ case 0 /* None */:
4803
+ case 2 /* Unwrapped */:
4804
+ return query.predicate.expression;
4805
+ case 1 /* Wrapped */:
4806
+ return importExpr(Identifiers.resolveForwardRef).callFn([query.predicate.expression]);
4807
+ }
4896
4808
  }
4897
4809
  }
4898
- function createCtorDepType(dep) {
4899
- const entries = [];
4900
- if (dep.attributeNameType !== null) {
4901
- entries.push({ key: 'attribute', value: dep.attributeNameType, quoted: false });
4810
+ /**
4811
+ * A representation for an object literal used during codegen of definition objects. The generic
4812
+ * type `T` allows to reference a documented type of the generated structure, such that the
4813
+ * property names that are set can be resolved to their documented declaration.
4814
+ */
4815
+ class DefinitionMap {
4816
+ constructor() {
4817
+ this.values = [];
4902
4818
  }
4903
- if (dep.optional) {
4904
- entries.push({ key: 'optional', value: literal(true), quoted: false });
4819
+ set(key, value) {
4820
+ if (value) {
4821
+ this.values.push({ key: key, value, quoted: false });
4822
+ }
4905
4823
  }
4906
- if (dep.host) {
4907
- entries.push({ key: 'host', value: literal(true), quoted: false });
4824
+ toLiteralMap() {
4825
+ return literalMap(this.values);
4908
4826
  }
4909
- if (dep.self) {
4910
- entries.push({ key: 'self', value: literal(true), quoted: false });
4827
+ }
4828
+ /**
4829
+ * Extract a map of properties to values for a given element or template node, which can be used
4830
+ * by the directive matching machinery.
4831
+ *
4832
+ * @param elOrTpl the element or template in question
4833
+ * @return an object set up for directive matching. For attributes on the element/template, this
4834
+ * object maps a property name to its (static) value. For any bindings, this map simply maps the
4835
+ * property name to an empty string.
4836
+ */
4837
+ function getAttrsForDirectiveMatching(elOrTpl) {
4838
+ const attributesMap = {};
4839
+ if (elOrTpl instanceof Template && elOrTpl.tagName !== 'ng-template') {
4840
+ elOrTpl.templateAttrs.forEach(a => attributesMap[a.name] = '');
4911
4841
  }
4912
- if (dep.skipSelf) {
4913
- entries.push({ key: 'skipSelf', value: literal(true), quoted: false });
4842
+ else {
4843
+ elOrTpl.attributes.forEach(a => {
4844
+ if (!isI18nAttribute(a.name)) {
4845
+ attributesMap[a.name] = a.value;
4846
+ }
4847
+ });
4848
+ elOrTpl.inputs.forEach(i => {
4849
+ attributesMap[i.name] = '';
4850
+ });
4851
+ elOrTpl.outputs.forEach(o => {
4852
+ attributesMap[o.name] = '';
4853
+ });
4914
4854
  }
4915
- return entries.length > 0 ? literalMap(entries) : null;
4916
- }
4917
- function isDelegatedFactoryMetadata(meta) {
4918
- return meta.delegateType !== undefined;
4855
+ return attributesMap;
4919
4856
  }
4920
- function isExpressionFactoryMetadata(meta) {
4921
- return meta.expression !== undefined;
4857
+ /** Returns a call expression to a chained instruction, e.g. `property(params[0])(params[1])`. */
4858
+ function chainedInstruction(reference, calls, span) {
4859
+ let expression = importExpr(reference, null, span);
4860
+ if (calls.length > 0) {
4861
+ for (let i = 0; i < calls.length; i++) {
4862
+ expression = expression.callFn(calls[i], span);
4863
+ }
4864
+ }
4865
+ else {
4866
+ // Add a blank invocation, in case the `calls` array is empty.
4867
+ expression = expression.callFn([], span);
4868
+ }
4869
+ return expression;
4922
4870
  }
4923
- function getInjectFn(target) {
4924
- switch (target) {
4925
- case FactoryTarget.Component:
4926
- case FactoryTarget.Directive:
4927
- case FactoryTarget.Pipe:
4928
- return Identifiers.directiveInject;
4929
- case FactoryTarget.NgModule:
4930
- case FactoryTarget.Injectable:
4931
- default:
4932
- return Identifiers.inject;
4871
+ /**
4872
+ * Gets the number of arguments expected to be passed to a generated instruction in the case of
4873
+ * interpolation instructions.
4874
+ * @param interpolation An interpolation ast
4875
+ */
4876
+ function getInterpolationArgsLength(interpolation) {
4877
+ const { expressions, strings } = interpolation;
4878
+ if (expressions.length === 1 && strings.length === 2 && strings[0] === '' && strings[1] === '') {
4879
+ // If the interpolation has one interpolated value, but the prefix and suffix are both empty
4880
+ // strings, we only pass one argument, to a special instruction like `propertyInterpolate` or
4881
+ // `textInterpolate`.
4882
+ return 1;
4883
+ }
4884
+ else {
4885
+ return expressions.length + strings.length;
4933
4886
  }
4934
4887
  }
4935
4888
 
@@ -4940,9 +4893,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4940
4893
  * Use of this source code is governed by an MIT-style license that can be
4941
4894
  * found in the LICENSE file at https://angular.io/license
4942
4895
  */
4943
- function createR3ProviderExpression(expression, isForwardRef) {
4944
- return { expression, isForwardRef };
4945
- }
4946
4896
  function compileInjectable(meta, resolveForwardRefs) {
4947
4897
  let result = null;
4948
4898
  const factoryMeta = {
@@ -5012,8 +4962,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
5012
4962
  injectableProps.set('factory', result.expression);
5013
4963
  // Only generate providedIn property if it has a non-null value
5014
4964
  if (meta.providedIn.expression.value !== null) {
5015
- injectableProps.set('providedIn', meta.providedIn.isForwardRef ? generateForwardRef(meta.providedIn.expression) :
5016
- meta.providedIn.expression);
4965
+ injectableProps.set('providedIn', convertFromMaybeForwardRefExpression(meta.providedIn));
5017
4966
  }
5018
4967
  const expression = importExpr(Identifiers.ɵɵdefineInjectable)
5019
4968
  .callFn([injectableProps.toLiteralMap()], undefined, true);
@@ -19817,22 +19766,27 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19817
19766
  const USE_VALUE = Object.keys({ useValue: null })[0];
19818
19767
  const USE_EXISTING = Object.keys({ useExisting: null })[0];
19819
19768
  function convertToR3QueryMetadata(facade) {
19820
- return Object.assign(Object.assign({}, facade), { predicate: Array.isArray(facade.predicate) ? facade.predicate :
19821
- new WrappedNodeExpr(facade.predicate), read: facade.read ? new WrappedNodeExpr(facade.read) : null, static: facade.static, emitDistinctChangesOnly: facade.emitDistinctChangesOnly });
19769
+ return Object.assign(Object.assign({}, facade), { predicate: convertQueryPredicate(facade.predicate), read: facade.read ? new WrappedNodeExpr(facade.read) : null, static: facade.static, emitDistinctChangesOnly: facade.emitDistinctChangesOnly });
19822
19770
  }
19823
19771
  function convertQueryDeclarationToMetadata(declaration) {
19824
19772
  var _a, _b, _c, _d;
19825
19773
  return {
19826
19774
  propertyName: declaration.propertyName,
19827
19775
  first: (_a = declaration.first) !== null && _a !== void 0 ? _a : false,
19828
- predicate: Array.isArray(declaration.predicate) ? declaration.predicate :
19829
- new WrappedNodeExpr(declaration.predicate),
19776
+ predicate: convertQueryPredicate(declaration.predicate),
19830
19777
  descendants: (_b = declaration.descendants) !== null && _b !== void 0 ? _b : false,
19831
19778
  read: declaration.read ? new WrappedNodeExpr(declaration.read) : null,
19832
19779
  static: (_c = declaration.static) !== null && _c !== void 0 ? _c : false,
19833
19780
  emitDistinctChangesOnly: (_d = declaration.emitDistinctChangesOnly) !== null && _d !== void 0 ? _d : true,
19834
19781
  };
19835
19782
  }
19783
+ function convertQueryPredicate(predicate) {
19784
+ return Array.isArray(predicate) ?
19785
+ // The predicate is an array of strings so pass it through.
19786
+ predicate :
19787
+ // The predicate is a type - assume that we will need to unwrap any `forwardRef()` calls.
19788
+ createMayBeForwardRefExpression(new WrappedNodeExpr(predicate), 1 /* Wrapped */);
19789
+ }
19836
19790
  function convertDirectiveFacadeToMetadata(facade) {
19837
19791
  const inputsFromMetadata = parseInputOutputs(facade.inputs || []);
19838
19792
  const outputsFromMetadata = parseInputOutputs(facade.outputs || []);
@@ -19943,11 +19897,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19943
19897
  * In JIT mode we do not want the compiler to wrap the expression in a `forwardRef()` call because,
19944
19898
  * if it is referencing a type that has not yet been defined, it will have already been wrapped in
19945
19899
  * a `forwardRef()` - either by the application developer or during partial-compilation. Thus we can
19946
- * set `isForwardRef` to `false`.
19900
+ * use `ForwardRefHandling.None`.
19947
19901
  */
19948
19902
  function convertToProviderExpression(obj, property) {
19949
19903
  if (obj.hasOwnProperty(property)) {
19950
- return createR3ProviderExpression(new WrappedNodeExpr(obj[property]), /* isForwardRef */ false);
19904
+ return createMayBeForwardRefExpression(new WrappedNodeExpr(obj[property]), 0 /* None */);
19951
19905
  }
19952
19906
  else {
19953
19907
  return undefined;
@@ -19966,7 +19920,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19966
19920
  new LiteralExpr(providedIn !== null && providedIn !== void 0 ? providedIn : null) :
19967
19921
  new WrappedNodeExpr(providedIn);
19968
19922
  // See `convertToProviderExpression()` for why `isForwardRef` is false.
19969
- return createR3ProviderExpression(expression, /* isForwardRef */ false);
19923
+ return createMayBeForwardRefExpression(expression, 0 /* None */);
19970
19924
  }
19971
19925
  function convertR3DependencyMetadataArray(facades) {
19972
19926
  return facades == null ? null : facades.map(convertR3DependencyMetadata);
@@ -20074,7 +20028,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20074
20028
  * Use of this source code is governed by an MIT-style license that can be
20075
20029
  * found in the LICENSE file at https://angular.io/license
20076
20030
  */
20077
- const VERSION$1 = new Version('12.2.11');
20031
+ const VERSION$1 = new Version('12.2.15');
20078
20032
 
20079
20033
  /**
20080
20034
  * @license
@@ -20713,7 +20667,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20713
20667
  function compileDeclareClassMetadata(metadata) {
20714
20668
  const definitionMap = new DefinitionMap();
20715
20669
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
20716
- definitionMap.set('version', literal('12.2.11'));
20670
+ definitionMap.set('version', literal('12.2.15'));
20717
20671
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20718
20672
  definitionMap.set('type', metadata.type);
20719
20673
  definitionMap.set('decorators', metadata.decorators);
@@ -20722,6 +20676,83 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20722
20676
  return importExpr(Identifiers.declareClassMetadata).callFn([definitionMap.toLiteralMap()]);
20723
20677
  }
20724
20678
 
20679
+ /**
20680
+ * @license
20681
+ * Copyright Google LLC All Rights Reserved.
20682
+ *
20683
+ * Use of this source code is governed by an MIT-style license that can be
20684
+ * found in the LICENSE file at https://angular.io/license
20685
+ */
20686
+ /**
20687
+ * Creates an array literal expression from the given array, mapping all values to an expression
20688
+ * using the provided mapping function. If the array is empty or null, then null is returned.
20689
+ *
20690
+ * @param values The array to transfer into literal array expression.
20691
+ * @param mapper The logic to use for creating an expression for the array's values.
20692
+ * @returns An array literal expression representing `values`, or null if `values` is empty or
20693
+ * is itself null.
20694
+ */
20695
+ function toOptionalLiteralArray(values, mapper) {
20696
+ if (values === null || values.length === 0) {
20697
+ return null;
20698
+ }
20699
+ return literalArr(values.map(value => mapper(value)));
20700
+ }
20701
+ /**
20702
+ * Creates an object literal expression from the given object, mapping all values to an expression
20703
+ * using the provided mapping function. If the object has no keys, then null is returned.
20704
+ *
20705
+ * @param object The object to transfer into an object literal expression.
20706
+ * @param mapper The logic to use for creating an expression for the object's values.
20707
+ * @returns An object literal expression representing `object`, or null if `object` does not have
20708
+ * any keys.
20709
+ */
20710
+ function toOptionalLiteralMap(object, mapper) {
20711
+ const entries = Object.keys(object).map(key => {
20712
+ const value = object[key];
20713
+ return { key, value: mapper(value), quoted: true };
20714
+ });
20715
+ if (entries.length > 0) {
20716
+ return literalMap(entries);
20717
+ }
20718
+ else {
20719
+ return null;
20720
+ }
20721
+ }
20722
+ function compileDependencies(deps) {
20723
+ if (deps === 'invalid') {
20724
+ // The `deps` can be set to the string "invalid" by the `unwrapConstructorDependencies()`
20725
+ // function, which tries to convert `ConstructorDeps` into `R3DependencyMetadata[]`.
20726
+ return literal('invalid');
20727
+ }
20728
+ else if (deps === null) {
20729
+ return literal(null);
20730
+ }
20731
+ else {
20732
+ return literalArr(deps.map(compileDependency));
20733
+ }
20734
+ }
20735
+ function compileDependency(dep) {
20736
+ const depMeta = new DefinitionMap();
20737
+ depMeta.set('token', dep.token);
20738
+ if (dep.attributeNameType !== null) {
20739
+ depMeta.set('attribute', literal(true));
20740
+ }
20741
+ if (dep.host) {
20742
+ depMeta.set('host', literal(true));
20743
+ }
20744
+ if (dep.optional) {
20745
+ depMeta.set('optional', literal(true));
20746
+ }
20747
+ if (dep.self) {
20748
+ depMeta.set('self', literal(true));
20749
+ }
20750
+ if (dep.skipSelf) {
20751
+ depMeta.set('skipSelf', literal(true));
20752
+ }
20753
+ return depMeta.toLiteralMap();
20754
+ }
20755
+
20725
20756
  /**
20726
20757
  * @license
20727
20758
  * Copyright Google LLC All Rights Reserved.
@@ -20753,7 +20784,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20753
20784
  function createDirectiveDefinitionMap(meta) {
20754
20785
  const definitionMap = new DefinitionMap();
20755
20786
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
20756
- definitionMap.set('version', literal('12.2.11'));
20787
+ definitionMap.set('version', literal('12.2.15'));
20757
20788
  // e.g. `type: MyDirective`
20758
20789
  definitionMap.set('type', meta.internalType);
20759
20790
  // e.g. `selector: 'some-dir'`
@@ -20792,7 +20823,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20792
20823
  if (query.first) {
20793
20824
  meta.set('first', literal(true));
20794
20825
  }
20795
- meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) : query.predicate);
20826
+ meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) :
20827
+ convertFromMaybeForwardRefExpression(query.predicate));
20796
20828
  if (!query.emitDistinctChangesOnly) {
20797
20829
  // `emitDistinctChangesOnly` is special because we expect it to be `true`.
20798
20830
  // Therefore we explicitly emit the field, and explicitly place it only when it's `false`.
@@ -20970,7 +21002,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20970
21002
  function compileDeclareFactoryFunction(meta) {
20971
21003
  const definitionMap = new DefinitionMap();
20972
21004
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
20973
- definitionMap.set('version', literal('12.2.11'));
21005
+ definitionMap.set('version', literal('12.2.15'));
20974
21006
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20975
21007
  definitionMap.set('type', meta.internalType);
20976
21008
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -21012,24 +21044,24 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21012
21044
  function createInjectableDefinitionMap(meta) {
21013
21045
  const definitionMap = new DefinitionMap();
21014
21046
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
21015
- definitionMap.set('version', literal('12.2.11'));
21047
+ definitionMap.set('version', literal('12.2.15'));
21016
21048
  definitionMap.set('ngImport', importExpr(Identifiers.core));
21017
21049
  definitionMap.set('type', meta.internalType);
21018
21050
  // Only generate providedIn property if it has a non-null value
21019
21051
  if (meta.providedIn !== undefined) {
21020
- const providedIn = convertFromProviderExpression(meta.providedIn);
21052
+ const providedIn = convertFromMaybeForwardRefExpression(meta.providedIn);
21021
21053
  if (providedIn.value !== null) {
21022
21054
  definitionMap.set('providedIn', providedIn);
21023
21055
  }
21024
21056
  }
21025
21057
  if (meta.useClass !== undefined) {
21026
- definitionMap.set('useClass', convertFromProviderExpression(meta.useClass));
21058
+ definitionMap.set('useClass', convertFromMaybeForwardRefExpression(meta.useClass));
21027
21059
  }
21028
21060
  if (meta.useExisting !== undefined) {
21029
- definitionMap.set('useExisting', convertFromProviderExpression(meta.useExisting));
21061
+ definitionMap.set('useExisting', convertFromMaybeForwardRefExpression(meta.useExisting));
21030
21062
  }
21031
21063
  if (meta.useValue !== undefined) {
21032
- definitionMap.set('useValue', convertFromProviderExpression(meta.useValue));
21064
+ definitionMap.set('useValue', convertFromMaybeForwardRefExpression(meta.useValue));
21033
21065
  }
21034
21066
  // Factories do not contain `ForwardRef`s since any types are already wrapped in a function call
21035
21067
  // so the types will not be eagerly evaluated. Therefore we do not need to process this expression
@@ -21042,27 +21074,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21042
21074
  }
21043
21075
  return definitionMap;
21044
21076
  }
21045
- /**
21046
- * Convert an `R3ProviderExpression` to an `Expression`, possibly wrapping its expression in a
21047
- * `forwardRef()` call.
21048
- *
21049
- * If `R3ProviderExpression.isForwardRef` is true then the expression was originally wrapped in a
21050
- * `forwardRef()` call to prevent the value from being eagerly evaluated in the code.
21051
- *
21052
- * Normally, the linker will statically process the code, putting the `expression` inside a factory
21053
- * function so the `forwardRef()` wrapper is not evaluated before it has been defined. But if the
21054
- * partial declaration is evaluated by the JIT compiler the `forwardRef()` call is still needed to
21055
- * prevent eager evaluation of the `expression`.
21056
- *
21057
- * So in partial declarations, expressions that could be forward-refs are wrapped in `forwardRef()`
21058
- * calls, and this is then unwrapped in the linker as necessary.
21059
- *
21060
- * See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and
21061
- * `packages/compiler/src/jit_compiler_facade.ts` for more information.
21062
- */
21063
- function convertFromProviderExpression({ expression, isForwardRef }) {
21064
- return isForwardRef ? generateForwardRef(expression) : expression;
21065
- }
21066
21077
 
21067
21078
  /**
21068
21079
  * @license
@@ -21091,7 +21102,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21091
21102
  function createInjectorDefinitionMap(meta) {
21092
21103
  const definitionMap = new DefinitionMap();
21093
21104
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
21094
- definitionMap.set('version', literal('12.2.11'));
21105
+ definitionMap.set('version', literal('12.2.15'));
21095
21106
  definitionMap.set('ngImport', importExpr(Identifiers.core));
21096
21107
  definitionMap.set('type', meta.internalType);
21097
21108
  definitionMap.set('providers', meta.providers);
@@ -21128,7 +21139,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21128
21139
  function createNgModuleDefinitionMap(meta) {
21129
21140
  const definitionMap = new DefinitionMap();
21130
21141
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
21131
- definitionMap.set('version', literal('12.2.11'));
21142
+ definitionMap.set('version', literal('12.2.15'));
21132
21143
  definitionMap.set('ngImport', importExpr(Identifiers.core));
21133
21144
  definitionMap.set('type', meta.internalType);
21134
21145
  // We only generate the keys in the metadata if the arrays contain values.
@@ -21186,7 +21197,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21186
21197
  function createPipeDefinitionMap(meta) {
21187
21198
  const definitionMap = new DefinitionMap();
21188
21199
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
21189
- definitionMap.set('version', literal('12.2.11'));
21200
+ definitionMap.set('version', literal('12.2.15'));
21190
21201
  definitionMap.set('ngImport', importExpr(Identifiers.core));
21191
21202
  // e.g. `type: MyPipe`
21192
21203
  definitionMap.set('type', meta.internalType);
@@ -21218,7 +21229,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21218
21229
  * Use of this source code is governed by an MIT-style license that can be
21219
21230
  * found in the LICENSE file at https://angular.io/license
21220
21231
  */
21221
- const VERSION$2 = new Version('12.2.11');
21232
+ const VERSION$2 = new Version('12.2.15');
21222
21233
 
21223
21234
  /**
21224
21235
  * @license
@@ -21468,15 +21479,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21468
21479
  */
21469
21480
  ErrorCode[ErrorCode["SUGGEST_SUBOPTIMAL_TYPE_INFERENCE"] = 10002] = "SUGGEST_SUBOPTIMAL_TYPE_INFERENCE";
21470
21481
  })(ErrorCode || (ErrorCode = {}));
21482
+
21471
21483
  /**
21472
- * @internal
21473
- * Base URL for the error details page.
21474
- * Keep this value in sync with a similar const in
21475
- * `packages/core/src/render3/error_code.ts`.
21484
+ * @license
21485
+ * Copyright Google LLC All Rights Reserved.
21486
+ *
21487
+ * Use of this source code is governed by an MIT-style license that can be
21488
+ * found in the LICENSE file at https://angular.io/license
21476
21489
  */
21477
- const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';
21478
21490
  /**
21479
- * @internal
21480
21491
  * Contains a set of error messages that have detailed guides at angular.io.
21481
21492
  * Full list of available error guides can be found at https://angular.io/errors
21482
21493
  */
@@ -21489,8 +21500,13 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21489
21500
  ErrorCode.MISSING_REFERENCE_TARGET,
21490
21501
  ErrorCode.COMPONENT_INVALID_SHADOW_DOM_SELECTOR,
21491
21502
  ]);
21503
+
21492
21504
  /**
21493
- * @internal
21505
+ * @license
21506
+ * Copyright Google LLC All Rights Reserved.
21507
+ *
21508
+ * Use of this source code is governed by an MIT-style license that can be
21509
+ * found in the LICENSE file at https://angular.io/license
21494
21510
  */
21495
21511
  function ngErrorCode(code) {
21496
21512
  return parseInt('-99' + code);
@@ -21542,6 +21558,22 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21542
21558
  };
21543
21559
  }
21544
21560
 
21561
+ /**
21562
+ * @license
21563
+ * Copyright Google LLC All Rights Reserved.
21564
+ *
21565
+ * Use of this source code is governed by an MIT-style license that can be
21566
+ * found in the LICENSE file at https://angular.io/license
21567
+ */
21568
+ /**
21569
+ * Base URL for the error details page.
21570
+ *
21571
+ * Keep the files below in sync:
21572
+ * - packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.ts
21573
+ * - packages/core/src/render3/error_details_base_url.ts
21574
+ */
21575
+ const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';
21576
+
21545
21577
  /**
21546
21578
  * @license
21547
21579
  * Copyright Google LLC All Rights Reserved.
@@ -29444,12 +29476,12 @@ Either add the @Injectable() decorator to '${provider.node.name
29444
29476
  };
29445
29477
  }
29446
29478
  function extractQueryMetadata(exprNode, name, args, propertyName, reflector, evaluator) {
29447
- var _a;
29448
29479
  if (args.length === 0) {
29449
29480
  throw new FatalDiagnosticError(ErrorCode.DECORATOR_ARITY_WRONG, exprNode, `@${name} must have arguments`);
29450
29481
  }
29451
29482
  const first = name === 'ViewChild' || name === 'ContentChild';
29452
- const node = (_a = tryUnwrapForwardRef(args[0], reflector)) !== null && _a !== void 0 ? _a : args[0];
29483
+ const forwardReferenceTarget = tryUnwrapForwardRef(args[0], reflector);
29484
+ const node = forwardReferenceTarget !== null && forwardReferenceTarget !== void 0 ? forwardReferenceTarget : args[0];
29453
29485
  const arg = evaluator.evaluate(node);
29454
29486
  /** Whether or not this query should collect only static results (see view/api.ts) */
29455
29487
  let isStatic = false;
@@ -29457,7 +29489,7 @@ Either add the @Injectable() decorator to '${provider.node.name
29457
29489
  let predicate = null;
29458
29490
  if (arg instanceof Reference$1 || arg instanceof DynamicValue) {
29459
29491
  // References and predicates that could not be evaluated statically are emitted as is.
29460
- predicate = new WrappedNodeExpr(node);
29492
+ predicate = createMayBeForwardRefExpression(new WrappedNodeExpr(node), forwardReferenceTarget !== null ? 2 /* Unwrapped */ : 0 /* None */);
29461
29493
  }
29462
29494
  else if (typeof arg === 'string') {
29463
29495
  predicate = [arg];
@@ -31463,7 +31495,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31463
31495
  type,
31464
31496
  typeArgumentCount,
31465
31497
  internalType,
31466
- providedIn: createR3ProviderExpression(new LiteralExpr(null), false),
31498
+ providedIn: createMayBeForwardRefExpression(new LiteralExpr(null), 0 /* None */),
31467
31499
  };
31468
31500
  }
31469
31501
  else if (decorator.args.length === 1) {
@@ -31478,7 +31510,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31478
31510
  const meta = reflectObjectLiteral(metaNode);
31479
31511
  const providedIn = meta.has('providedIn') ?
31480
31512
  getProviderExpression(meta.get('providedIn'), reflector) :
31481
- createR3ProviderExpression(new LiteralExpr(null), false);
31513
+ createMayBeForwardRefExpression(new LiteralExpr(null), 0 /* None */);
31482
31514
  let deps = undefined;
31483
31515
  if ((meta.has('useClass') || meta.has('useFactory')) && meta.has('deps')) {
31484
31516
  const depsExpr = meta.get('deps');
@@ -31517,7 +31549,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31517
31549
  */
31518
31550
  function getProviderExpression(expression, reflector) {
31519
31551
  const forwardRefValue = tryUnwrapForwardRef(expression, reflector);
31520
- return createR3ProviderExpression(new WrappedNodeExpr(forwardRefValue !== null && forwardRefValue !== void 0 ? forwardRefValue : expression), forwardRefValue !== null);
31552
+ return createMayBeForwardRefExpression(new WrappedNodeExpr(forwardRefValue !== null && forwardRefValue !== void 0 ? forwardRefValue : expression), forwardRefValue !== null ? 2 /* Unwrapped */ : 0 /* None */);
31521
31553
  }
31522
31554
  function extractInjectableCtorDeps(clazz, meta, decorator, reflector, isCore, strictCtorDeps) {
31523
31555
  if (decorator.args === null) {