@angular/language-service 13.0.0-rc.3 → 13.0.3

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v13.0.0-rc.3
2
+ * @license Angular v13.0.3
3
3
  * Copyright Google LLC All Rights Reserved.
4
4
  * License: MIT
5
5
  */
@@ -2690,229 +2690,146 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
2690
2690
  * Use of this source code is governed by an MIT-style license that can be
2691
2691
  * found in the LICENSE file at https://angular.io/license
2692
2692
  */
2693
- /**
2694
- * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently
2695
- * require the implementation of a visitor for Comments as they are only collected at
2696
- * the top-level of the R3 AST, and only if `Render3ParseOptions['collectCommentNodes']`
2697
- * is true.
2698
- */
2699
- class Comment$1 {
2700
- constructor(value, sourceSpan) {
2701
- this.value = value;
2702
- this.sourceSpan = sourceSpan;
2703
- }
2704
- visit(_visitor) {
2705
- throw new Error('visit() not implemented for Comment');
2706
- }
2707
- }
2708
- class Text$2 {
2709
- constructor(value, sourceSpan) {
2710
- this.value = value;
2711
- this.sourceSpan = sourceSpan;
2712
- }
2713
- visit(visitor) {
2714
- return visitor.visitText(this);
2715
- }
2716
- }
2717
- class BoundText {
2718
- constructor(value, sourceSpan, i18n) {
2719
- this.value = value;
2720
- this.sourceSpan = sourceSpan;
2721
- this.i18n = i18n;
2722
- }
2723
- visit(visitor) {
2724
- return visitor.visitBoundText(this);
2725
- }
2726
- }
2727
- /**
2728
- * Represents a text attribute in the template.
2729
- *
2730
- * `valueSpan` may not be present in cases where there is no value `<div a></div>`.
2731
- * `keySpan` may also not be present for synthetic attributes from ICU expansions.
2732
- */
2733
- class TextAttribute {
2734
- constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
2735
- this.name = name;
2736
- this.value = value;
2737
- this.sourceSpan = sourceSpan;
2738
- this.keySpan = keySpan;
2739
- this.valueSpan = valueSpan;
2740
- this.i18n = i18n;
2741
- }
2742
- visit(visitor) {
2743
- return visitor.visitTextAttribute(this);
2744
- }
2745
- }
2746
- class BoundAttribute {
2747
- constructor(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan, i18n) {
2748
- this.name = name;
2749
- this.type = type;
2750
- this.securityContext = securityContext;
2751
- this.value = value;
2752
- this.unit = unit;
2753
- this.sourceSpan = sourceSpan;
2754
- this.keySpan = keySpan;
2755
- this.valueSpan = valueSpan;
2756
- this.i18n = i18n;
2693
+ // https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
2694
+ const VERSION = 3;
2695
+ const JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,';
2696
+ class SourceMapGenerator {
2697
+ constructor(file = null) {
2698
+ this.file = file;
2699
+ this.sourcesContent = new Map();
2700
+ this.lines = [];
2701
+ this.lastCol0 = 0;
2702
+ this.hasMappings = false;
2757
2703
  }
2758
- static fromBoundElementProperty(prop, i18n) {
2759
- if (prop.keySpan === undefined) {
2760
- throw new Error(`Unexpected state: keySpan must be defined for bound attributes but was not for ${prop.name}: ${prop.sourceSpan}`);
2704
+ // The content is `null` when the content is expected to be loaded using the URL
2705
+ addSource(url, content = null) {
2706
+ if (!this.sourcesContent.has(url)) {
2707
+ this.sourcesContent.set(url, content);
2761
2708
  }
2762
- return new BoundAttribute(prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n);
2763
- }
2764
- visit(visitor) {
2765
- return visitor.visitBoundAttribute(this);
2709
+ return this;
2766
2710
  }
2767
- }
2768
- class BoundEvent {
2769
- constructor(name, type, handler, target, phase, sourceSpan, handlerSpan, keySpan) {
2770
- this.name = name;
2771
- this.type = type;
2772
- this.handler = handler;
2773
- this.target = target;
2774
- this.phase = phase;
2775
- this.sourceSpan = sourceSpan;
2776
- this.handlerSpan = handlerSpan;
2777
- this.keySpan = keySpan;
2711
+ addLine() {
2712
+ this.lines.push([]);
2713
+ this.lastCol0 = 0;
2714
+ return this;
2778
2715
  }
2779
- static fromParsedEvent(event) {
2780
- const target = event.type === 0 /* Regular */ ? event.targetOrPhase : null;
2781
- const phase = event.type === 1 /* Animation */ ? event.targetOrPhase : null;
2782
- if (event.keySpan === undefined) {
2783
- throw new Error(`Unexpected state: keySpan must be defined for bound event but was not for ${event.name}: ${event.sourceSpan}`);
2716
+ addMapping(col0, sourceUrl, sourceLine0, sourceCol0) {
2717
+ if (!this.currentLine) {
2718
+ throw new Error(`A line must be added before mappings can be added`);
2784
2719
  }
2785
- return new BoundEvent(event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan, event.keySpan);
2786
- }
2787
- visit(visitor) {
2788
- return visitor.visitBoundEvent(this);
2789
- }
2790
- }
2791
- class Element$1 {
2792
- constructor(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
2793
- this.name = name;
2794
- this.attributes = attributes;
2795
- this.inputs = inputs;
2796
- this.outputs = outputs;
2797
- this.children = children;
2798
- this.references = references;
2799
- this.sourceSpan = sourceSpan;
2800
- this.startSourceSpan = startSourceSpan;
2801
- this.endSourceSpan = endSourceSpan;
2802
- this.i18n = i18n;
2803
- }
2804
- visit(visitor) {
2805
- return visitor.visitElement(this);
2806
- }
2807
- }
2808
- class Template {
2809
- constructor(tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
2810
- this.tagName = tagName;
2811
- this.attributes = attributes;
2812
- this.inputs = inputs;
2813
- this.outputs = outputs;
2814
- this.templateAttrs = templateAttrs;
2815
- this.children = children;
2816
- this.references = references;
2817
- this.variables = variables;
2818
- this.sourceSpan = sourceSpan;
2819
- this.startSourceSpan = startSourceSpan;
2820
- this.endSourceSpan = endSourceSpan;
2821
- this.i18n = i18n;
2822
- }
2823
- visit(visitor) {
2824
- return visitor.visitTemplate(this);
2825
- }
2826
- }
2827
- class Content {
2828
- constructor(selector, attributes, sourceSpan, i18n) {
2829
- this.selector = selector;
2830
- this.attributes = attributes;
2831
- this.sourceSpan = sourceSpan;
2832
- this.i18n = i18n;
2833
- this.name = 'ng-content';
2834
- }
2835
- visit(visitor) {
2836
- return visitor.visitContent(this);
2837
- }
2838
- }
2839
- class Variable {
2840
- constructor(name, value, sourceSpan, keySpan, valueSpan) {
2841
- this.name = name;
2842
- this.value = value;
2843
- this.sourceSpan = sourceSpan;
2844
- this.keySpan = keySpan;
2845
- this.valueSpan = valueSpan;
2846
- }
2847
- visit(visitor) {
2848
- return visitor.visitVariable(this);
2849
- }
2850
- }
2851
- class Reference$1 {
2852
- constructor(name, value, sourceSpan, keySpan, valueSpan) {
2853
- this.name = name;
2854
- this.value = value;
2855
- this.sourceSpan = sourceSpan;
2856
- this.keySpan = keySpan;
2857
- this.valueSpan = valueSpan;
2720
+ if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) {
2721
+ throw new Error(`Unknown source file "${sourceUrl}"`);
2722
+ }
2723
+ if (col0 == null) {
2724
+ throw new Error(`The column in the generated code must be provided`);
2725
+ }
2726
+ if (col0 < this.lastCol0) {
2727
+ throw new Error(`Mapping should be added in output order`);
2728
+ }
2729
+ if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) {
2730
+ throw new Error(`The source location must be provided when a source url is provided`);
2731
+ }
2732
+ this.hasMappings = true;
2733
+ this.lastCol0 = col0;
2734
+ this.currentLine.push({ col0, sourceUrl, sourceLine0, sourceCol0 });
2735
+ return this;
2858
2736
  }
2859
- visit(visitor) {
2860
- return visitor.visitReference(this);
2737
+ /**
2738
+ * @internal strip this from published d.ts files due to
2739
+ * https://github.com/microsoft/TypeScript/issues/36216
2740
+ */
2741
+ get currentLine() {
2742
+ return this.lines.slice(-1)[0];
2861
2743
  }
2862
- }
2863
- class Icu$1 {
2864
- constructor(vars, placeholders, sourceSpan, i18n) {
2865
- this.vars = vars;
2866
- this.placeholders = placeholders;
2867
- this.sourceSpan = sourceSpan;
2868
- this.i18n = i18n;
2744
+ toJSON() {
2745
+ if (!this.hasMappings) {
2746
+ return null;
2747
+ }
2748
+ const sourcesIndex = new Map();
2749
+ const sources = [];
2750
+ const sourcesContent = [];
2751
+ Array.from(this.sourcesContent.keys()).forEach((url, i) => {
2752
+ sourcesIndex.set(url, i);
2753
+ sources.push(url);
2754
+ sourcesContent.push(this.sourcesContent.get(url) || null);
2755
+ });
2756
+ let mappings = '';
2757
+ let lastCol0 = 0;
2758
+ let lastSourceIndex = 0;
2759
+ let lastSourceLine0 = 0;
2760
+ let lastSourceCol0 = 0;
2761
+ this.lines.forEach(segments => {
2762
+ lastCol0 = 0;
2763
+ mappings += segments
2764
+ .map(segment => {
2765
+ // zero-based starting column of the line in the generated code
2766
+ let segAsStr = toBase64VLQ(segment.col0 - lastCol0);
2767
+ lastCol0 = segment.col0;
2768
+ if (segment.sourceUrl != null) {
2769
+ // zero-based index into the “sources” list
2770
+ segAsStr +=
2771
+ toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex);
2772
+ lastSourceIndex = sourcesIndex.get(segment.sourceUrl);
2773
+ // the zero-based starting line in the original source
2774
+ segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0);
2775
+ lastSourceLine0 = segment.sourceLine0;
2776
+ // the zero-based starting column in the original source
2777
+ segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0);
2778
+ lastSourceCol0 = segment.sourceCol0;
2779
+ }
2780
+ return segAsStr;
2781
+ })
2782
+ .join(',');
2783
+ mappings += ';';
2784
+ });
2785
+ mappings = mappings.slice(0, -1);
2786
+ return {
2787
+ 'file': this.file || '',
2788
+ 'version': VERSION,
2789
+ 'sourceRoot': '',
2790
+ 'sources': sources,
2791
+ 'sourcesContent': sourcesContent,
2792
+ 'mappings': mappings,
2793
+ };
2869
2794
  }
2870
- visit(visitor) {
2871
- return visitor.visitIcu(this);
2795
+ toJsComment() {
2796
+ return this.hasMappings ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0)) :
2797
+ '';
2872
2798
  }
2873
2799
  }
2874
- class RecursiveVisitor {
2875
- visitElement(element) {
2876
- visitAll$1(this, element.attributes);
2877
- visitAll$1(this, element.inputs);
2878
- visitAll$1(this, element.outputs);
2879
- visitAll$1(this, element.children);
2880
- visitAll$1(this, element.references);
2881
- }
2882
- visitTemplate(template) {
2883
- visitAll$1(this, template.attributes);
2884
- visitAll$1(this, template.inputs);
2885
- visitAll$1(this, template.outputs);
2886
- visitAll$1(this, template.children);
2887
- visitAll$1(this, template.references);
2888
- visitAll$1(this, template.variables);
2800
+ function toBase64String(value) {
2801
+ let b64 = '';
2802
+ const encoded = utf8Encode(value);
2803
+ for (let i = 0; i < encoded.length;) {
2804
+ const i1 = encoded[i++];
2805
+ const i2 = i < encoded.length ? encoded[i++] : null;
2806
+ const i3 = i < encoded.length ? encoded[i++] : null;
2807
+ b64 += toBase64Digit(i1 >> 2);
2808
+ b64 += toBase64Digit(((i1 & 3) << 4) | (i2 === null ? 0 : i2 >> 4));
2809
+ b64 += i2 === null ? '=' : toBase64Digit(((i2 & 15) << 2) | (i3 === null ? 0 : i3 >> 6));
2810
+ b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63);
2889
2811
  }
2890
- visitContent(content) { }
2891
- visitVariable(variable) { }
2892
- visitReference(reference) { }
2893
- visitTextAttribute(attribute) { }
2894
- visitBoundAttribute(attribute) { }
2895
- visitBoundEvent(attribute) { }
2896
- visitText(text) { }
2897
- visitBoundText(text) { }
2898
- visitIcu(icu) { }
2812
+ return b64;
2899
2813
  }
2900
- function visitAll$1(visitor, nodes) {
2901
- const result = [];
2902
- if (visitor.visit) {
2903
- for (const node of nodes) {
2904
- visitor.visit(node) || node.visit(visitor);
2905
- }
2906
- }
2907
- else {
2908
- for (const node of nodes) {
2909
- const newNode = node.visit(visitor);
2910
- if (newNode) {
2911
- result.push(newNode);
2912
- }
2814
+ function toBase64VLQ(value) {
2815
+ value = value < 0 ? ((-value) << 1) + 1 : value << 1;
2816
+ let out = '';
2817
+ do {
2818
+ let digit = value & 31;
2819
+ value = value >> 5;
2820
+ if (value > 0) {
2821
+ digit = digit | 32;
2913
2822
  }
2823
+ out += toBase64Digit(digit);
2824
+ } while (value > 0);
2825
+ return out;
2826
+ }
2827
+ const B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
2828
+ function toBase64Digit(value) {
2829
+ if (value < 0 || value >= 64) {
2830
+ throw new Error(`Can only encode value in the range [0, 63]`);
2914
2831
  }
2915
- return result;
2832
+ return B64_DIGITS[value];
2916
2833
  }
2917
2834
 
2918
2835
  /**
@@ -2922,614 +2839,551 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
2922
2839
  * Use of this source code is governed by an MIT-style license that can be
2923
2840
  * found in the LICENSE file at https://angular.io/license
2924
2841
  */
2925
- class Message {
2926
- /**
2927
- * @param nodes message AST
2928
- * @param placeholders maps placeholder names to static content and their source spans
2929
- * @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
2930
- * @param meaning
2931
- * @param description
2932
- * @param customId
2933
- */
2934
- constructor(nodes, placeholders, placeholderToMessage, meaning, description, customId) {
2935
- this.nodes = nodes;
2936
- this.placeholders = placeholders;
2937
- this.placeholderToMessage = placeholderToMessage;
2938
- this.meaning = meaning;
2939
- this.description = description;
2940
- this.customId = customId;
2941
- this.id = this.customId;
2942
- /** The ids to use if there are no custom id and if `i18nLegacyMessageIdFormat` is not empty */
2943
- this.legacyIds = [];
2944
- if (nodes.length) {
2945
- this.sources = [{
2946
- filePath: nodes[0].sourceSpan.start.file.url,
2947
- startLine: nodes[0].sourceSpan.start.line + 1,
2948
- startCol: nodes[0].sourceSpan.start.col + 1,
2949
- endLine: nodes[nodes.length - 1].sourceSpan.end.line + 1,
2950
- endCol: nodes[0].sourceSpan.start.col + 1
2951
- }];
2952
- }
2953
- else {
2954
- this.sources = [];
2955
- }
2842
+ const _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
2843
+ const _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
2844
+ const _INDENT_WITH = ' ';
2845
+ const CATCH_ERROR_VAR = variable('error', null, null);
2846
+ const CATCH_STACK_VAR = variable('stack', null, null);
2847
+ class _EmittedLine {
2848
+ constructor(indent) {
2849
+ this.indent = indent;
2850
+ this.partsLength = 0;
2851
+ this.parts = [];
2852
+ this.srcSpans = [];
2956
2853
  }
2957
2854
  }
2958
- class Text$1 {
2959
- constructor(value, sourceSpan) {
2960
- this.value = value;
2961
- this.sourceSpan = sourceSpan;
2962
- }
2963
- visit(visitor, context) {
2964
- return visitor.visitText(this, context);
2855
+ class EmitterVisitorContext {
2856
+ constructor(_indent) {
2857
+ this._indent = _indent;
2858
+ this._classes = [];
2859
+ this._preambleLineCount = 0;
2860
+ this._lines = [new _EmittedLine(_indent)];
2965
2861
  }
2966
- }
2967
- // TODO(vicb): do we really need this node (vs an array) ?
2968
- class Container {
2969
- constructor(children, sourceSpan) {
2970
- this.children = children;
2971
- this.sourceSpan = sourceSpan;
2862
+ static createRoot() {
2863
+ return new EmitterVisitorContext(0);
2972
2864
  }
2973
- visit(visitor, context) {
2974
- return visitor.visitContainer(this, context);
2865
+ /**
2866
+ * @internal strip this from published d.ts files due to
2867
+ * https://github.com/microsoft/TypeScript/issues/36216
2868
+ */
2869
+ get _currentLine() {
2870
+ return this._lines[this._lines.length - 1];
2975
2871
  }
2976
- }
2977
- class Icu {
2978
- constructor(expression, type, cases, sourceSpan) {
2979
- this.expression = expression;
2980
- this.type = type;
2981
- this.cases = cases;
2982
- this.sourceSpan = sourceSpan;
2872
+ println(from, lastPart = '') {
2873
+ this.print(from || null, lastPart, true);
2983
2874
  }
2984
- visit(visitor, context) {
2985
- return visitor.visitIcu(this, context);
2875
+ lineIsEmpty() {
2876
+ return this._currentLine.parts.length === 0;
2986
2877
  }
2987
- }
2988
- class TagPlaceholder {
2989
- constructor(tag, attrs, startName, closeName, children, isVoid,
2990
- // TODO sourceSpan should cover all (we need a startSourceSpan and endSourceSpan)
2991
- sourceSpan, startSourceSpan, endSourceSpan) {
2992
- this.tag = tag;
2993
- this.attrs = attrs;
2994
- this.startName = startName;
2995
- this.closeName = closeName;
2996
- this.children = children;
2997
- this.isVoid = isVoid;
2998
- this.sourceSpan = sourceSpan;
2999
- this.startSourceSpan = startSourceSpan;
3000
- this.endSourceSpan = endSourceSpan;
2878
+ lineLength() {
2879
+ return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;
3001
2880
  }
3002
- visit(visitor, context) {
3003
- return visitor.visitTagPlaceholder(this, context);
2881
+ print(from, part, newLine = false) {
2882
+ if (part.length > 0) {
2883
+ this._currentLine.parts.push(part);
2884
+ this._currentLine.partsLength += part.length;
2885
+ this._currentLine.srcSpans.push(from && from.sourceSpan || null);
2886
+ }
2887
+ if (newLine) {
2888
+ this._lines.push(new _EmittedLine(this._indent));
2889
+ }
3004
2890
  }
3005
- }
3006
- class Placeholder {
3007
- constructor(value, name, sourceSpan) {
3008
- this.value = value;
3009
- this.name = name;
3010
- this.sourceSpan = sourceSpan;
2891
+ removeEmptyLastLine() {
2892
+ if (this.lineIsEmpty()) {
2893
+ this._lines.pop();
2894
+ }
3011
2895
  }
3012
- visit(visitor, context) {
3013
- return visitor.visitPlaceholder(this, context);
2896
+ incIndent() {
2897
+ this._indent++;
2898
+ if (this.lineIsEmpty()) {
2899
+ this._currentLine.indent = this._indent;
2900
+ }
3014
2901
  }
3015
- }
3016
- class IcuPlaceholder {
3017
- constructor(value, name, sourceSpan) {
3018
- this.value = value;
3019
- this.name = name;
3020
- this.sourceSpan = sourceSpan;
2902
+ decIndent() {
2903
+ this._indent--;
2904
+ if (this.lineIsEmpty()) {
2905
+ this._currentLine.indent = this._indent;
2906
+ }
3021
2907
  }
3022
- visit(visitor, context) {
3023
- return visitor.visitIcuPlaceholder(this, context);
2908
+ pushClass(clazz) {
2909
+ this._classes.push(clazz);
3024
2910
  }
3025
- }
3026
-
3027
- /**
3028
- * @license
3029
- * Copyright Google LLC All Rights Reserved.
3030
- *
3031
- * Use of this source code is governed by an MIT-style license that can be
3032
- * found in the LICENSE file at https://angular.io/license
3033
- */
3034
- /**
3035
- * Represents a big integer using a buffer of its individual digits, with the least significant
3036
- * digit stored at the beginning of the array (little endian).
3037
- *
3038
- * For performance reasons, each instance is mutable. The addition operation can be done in-place
3039
- * to reduce memory pressure of allocation for the digits array.
3040
- */
3041
- class BigInteger {
3042
- /**
3043
- * Creates a big integer using its individual digits in little endian storage.
3044
- */
3045
- constructor(digits) {
3046
- this.digits = digits;
2911
+ popClass() {
2912
+ return this._classes.pop();
3047
2913
  }
3048
- static zero() {
3049
- return new BigInteger([0]);
2914
+ get currentClass() {
2915
+ return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null;
3050
2916
  }
3051
- static one() {
3052
- return new BigInteger([1]);
2917
+ toSource() {
2918
+ return this.sourceLines
2919
+ .map(l => l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : '')
2920
+ .join('\n');
3053
2921
  }
3054
- /**
3055
- * Creates a clone of this instance.
3056
- */
3057
- clone() {
3058
- return new BigInteger(this.digits.slice());
3059
- }
3060
- /**
3061
- * Returns a new big integer with the sum of `this` and `other` as its value. This does not mutate
3062
- * `this` but instead returns a new instance, unlike `addToSelf`.
3063
- */
3064
- add(other) {
3065
- const result = this.clone();
3066
- result.addToSelf(other);
3067
- return result;
3068
- }
3069
- /**
3070
- * Adds `other` to the instance itself, thereby mutating its value.
3071
- */
3072
- addToSelf(other) {
3073
- const maxNrOfDigits = Math.max(this.digits.length, other.digits.length);
3074
- let carry = 0;
3075
- for (let i = 0; i < maxNrOfDigits; i++) {
3076
- let digitSum = carry;
3077
- if (i < this.digits.length) {
3078
- digitSum += this.digits[i];
2922
+ toSourceMapGenerator(genFilePath, startsAtLine = 0) {
2923
+ const map = new SourceMapGenerator(genFilePath);
2924
+ let firstOffsetMapped = false;
2925
+ const mapFirstOffsetIfNeeded = () => {
2926
+ if (!firstOffsetMapped) {
2927
+ // Add a single space so that tools won't try to load the file from disk.
2928
+ // Note: We are using virtual urls like `ng:///`, so we have to
2929
+ // provide a content here.
2930
+ map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);
2931
+ firstOffsetMapped = true;
3079
2932
  }
3080
- if (i < other.digits.length) {
3081
- digitSum += other.digits[i];
2933
+ };
2934
+ for (let i = 0; i < startsAtLine; i++) {
2935
+ map.addLine();
2936
+ mapFirstOffsetIfNeeded();
2937
+ }
2938
+ this.sourceLines.forEach((line, lineIdx) => {
2939
+ map.addLine();
2940
+ const spans = line.srcSpans;
2941
+ const parts = line.parts;
2942
+ let col0 = line.indent * _INDENT_WITH.length;
2943
+ let spanIdx = 0;
2944
+ // skip leading parts without source spans
2945
+ while (spanIdx < spans.length && !spans[spanIdx]) {
2946
+ col0 += parts[spanIdx].length;
2947
+ spanIdx++;
3082
2948
  }
3083
- if (digitSum >= 10) {
3084
- this.digits[i] = digitSum - 10;
3085
- carry = 1;
2949
+ if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {
2950
+ firstOffsetMapped = true;
3086
2951
  }
3087
2952
  else {
3088
- this.digits[i] = digitSum;
3089
- carry = 0;
2953
+ mapFirstOffsetIfNeeded();
2954
+ }
2955
+ while (spanIdx < spans.length) {
2956
+ const span = spans[spanIdx];
2957
+ const source = span.start.file;
2958
+ const sourceLine = span.start.line;
2959
+ const sourceCol = span.start.col;
2960
+ map.addSource(source.url, source.content)
2961
+ .addMapping(col0, source.url, sourceLine, sourceCol);
2962
+ col0 += parts[spanIdx].length;
2963
+ spanIdx++;
2964
+ // assign parts without span or the same span to the previous segment
2965
+ while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) {
2966
+ col0 += parts[spanIdx].length;
2967
+ spanIdx++;
2968
+ }
2969
+ }
2970
+ });
2971
+ return map;
2972
+ }
2973
+ setPreambleLineCount(count) {
2974
+ return this._preambleLineCount = count;
2975
+ }
2976
+ spanOf(line, column) {
2977
+ const emittedLine = this._lines[line - this._preambleLineCount];
2978
+ if (emittedLine) {
2979
+ let columnsLeft = column - _createIndent(emittedLine.indent).length;
2980
+ for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {
2981
+ const part = emittedLine.parts[partIndex];
2982
+ if (part.length > columnsLeft) {
2983
+ return emittedLine.srcSpans[partIndex];
2984
+ }
2985
+ columnsLeft -= part.length;
3090
2986
  }
3091
2987
  }
3092
- // Apply a remaining carry if needed.
3093
- if (carry > 0) {
3094
- this.digits[maxNrOfDigits] = 1;
3095
- }
2988
+ return null;
3096
2989
  }
3097
2990
  /**
3098
- * Builds the decimal string representation of the big integer. As this is stored in
3099
- * little endian, the digits are concatenated in reverse order.
2991
+ * @internal strip this from published d.ts files due to
2992
+ * https://github.com/microsoft/TypeScript/issues/36216
3100
2993
  */
3101
- toString() {
3102
- let res = '';
3103
- for (let i = this.digits.length - 1; i >= 0; i--) {
3104
- res += this.digits[i];
2994
+ get sourceLines() {
2995
+ if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {
2996
+ return this._lines.slice(0, -1);
3105
2997
  }
3106
- return res;
2998
+ return this._lines;
3107
2999
  }
3108
3000
  }
3109
- /**
3110
- * Represents a big integer which is optimized for multiplication operations, as its power-of-twos
3111
- * are memoized. See `multiplyBy()` for details on the multiplication algorithm.
3112
- */
3113
- class BigIntForMultiplication {
3114
- constructor(value) {
3115
- this.powerOfTwos = [value];
3001
+ class AbstractEmitterVisitor {
3002
+ constructor(_escapeDollarInStrings) {
3003
+ this._escapeDollarInStrings = _escapeDollarInStrings;
3116
3004
  }
3117
- /**
3118
- * Returns the big integer itself.
3119
- */
3120
- getValue() {
3121
- return this.powerOfTwos[0];
3005
+ printLeadingComments(stmt, ctx) {
3006
+ if (stmt.leadingComments === undefined) {
3007
+ return;
3008
+ }
3009
+ for (const comment of stmt.leadingComments) {
3010
+ if (comment instanceof JSDocComment) {
3011
+ ctx.print(stmt, `/*${comment.toString()}*/`, comment.trailingNewline);
3012
+ }
3013
+ else {
3014
+ if (comment.multiline) {
3015
+ ctx.print(stmt, `/* ${comment.text} */`, comment.trailingNewline);
3016
+ }
3017
+ else {
3018
+ comment.text.split('\n').forEach((line) => {
3019
+ ctx.println(stmt, `// ${line}`);
3020
+ });
3021
+ }
3022
+ }
3023
+ }
3122
3024
  }
3123
- /**
3124
- * Computes the value for `num * b`, where `num` is a JS number and `b` is a big integer. The
3125
- * value for `b` is represented by a storage model that is optimized for this computation.
3126
- *
3127
- * This operation is implemented in N(log2(num)) by continuous halving of the number, where the
3128
- * least-significant bit (LSB) is tested in each iteration. If the bit is set, the bit's index is
3129
- * used as exponent into the power-of-two multiplication of `b`.
3130
- *
3131
- * As an example, consider the multiplication num=42, b=1337. In binary 42 is 0b00101010 and the
3132
- * algorithm unrolls into the following iterations:
3133
- *
3134
- * Iteration | num | LSB | b * 2^iter | Add? | product
3135
- * -----------|------------|------|------------|------|--------
3136
- * 0 | 0b00101010 | 0 | 1337 | No | 0
3137
- * 1 | 0b00010101 | 1 | 2674 | Yes | 2674
3138
- * 2 | 0b00001010 | 0 | 5348 | No | 2674
3139
- * 3 | 0b00000101 | 1 | 10696 | Yes | 13370
3140
- * 4 | 0b00000010 | 0 | 21392 | No | 13370
3141
- * 5 | 0b00000001 | 1 | 42784 | Yes | 56154
3142
- * 6 | 0b00000000 | 0 | 85568 | No | 56154
3143
- *
3144
- * The computed product of 56154 is indeed the correct result.
3145
- *
3146
- * The `BigIntForMultiplication` representation for a big integer provides memoized access to the
3147
- * power-of-two values to reduce the workload in computing those values.
3148
- */
3149
- multiplyBy(num) {
3150
- const product = BigInteger.zero();
3151
- this.multiplyByAndAddTo(num, product);
3152
- return product;
3025
+ visitExpressionStmt(stmt, ctx) {
3026
+ this.printLeadingComments(stmt, ctx);
3027
+ stmt.expr.visitExpression(this, ctx);
3028
+ ctx.println(stmt, ';');
3029
+ return null;
3153
3030
  }
3154
- /**
3155
- * See `multiplyBy()` for details. This function allows for the computed product to be added
3156
- * directly to the provided result big integer.
3157
- */
3158
- multiplyByAndAddTo(num, result) {
3159
- for (let exponent = 0; num !== 0; num = num >>> 1, exponent++) {
3160
- if (num & 1) {
3161
- const value = this.getMultipliedByPowerOfTwo(exponent);
3162
- result.addToSelf(value);
3031
+ visitReturnStmt(stmt, ctx) {
3032
+ this.printLeadingComments(stmt, ctx);
3033
+ ctx.print(stmt, `return `);
3034
+ stmt.value.visitExpression(this, ctx);
3035
+ ctx.println(stmt, ';');
3036
+ return null;
3037
+ }
3038
+ visitIfStmt(stmt, ctx) {
3039
+ this.printLeadingComments(stmt, ctx);
3040
+ ctx.print(stmt, `if (`);
3041
+ stmt.condition.visitExpression(this, ctx);
3042
+ ctx.print(stmt, `) {`);
3043
+ const hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0;
3044
+ if (stmt.trueCase.length <= 1 && !hasElseCase) {
3045
+ ctx.print(stmt, ` `);
3046
+ this.visitAllStatements(stmt.trueCase, ctx);
3047
+ ctx.removeEmptyLastLine();
3048
+ ctx.print(stmt, ` `);
3049
+ }
3050
+ else {
3051
+ ctx.println();
3052
+ ctx.incIndent();
3053
+ this.visitAllStatements(stmt.trueCase, ctx);
3054
+ ctx.decIndent();
3055
+ if (hasElseCase) {
3056
+ ctx.println(stmt, `} else {`);
3057
+ ctx.incIndent();
3058
+ this.visitAllStatements(stmt.falseCase, ctx);
3059
+ ctx.decIndent();
3163
3060
  }
3164
3061
  }
3062
+ ctx.println(stmt, `}`);
3063
+ return null;
3165
3064
  }
3166
- /**
3167
- * Computes and memoizes the big integer value for `this.number * 2^exponent`.
3168
- */
3169
- getMultipliedByPowerOfTwo(exponent) {
3170
- // Compute the powers up until the requested exponent, where each value is computed from its
3171
- // predecessor. This is simple as `this.number * 2^(exponent - 1)` only has to be doubled (i.e.
3172
- // added to itself) to reach `this.number * 2^exponent`.
3173
- for (let i = this.powerOfTwos.length; i <= exponent; i++) {
3174
- const previousPower = this.powerOfTwos[i - 1];
3175
- this.powerOfTwos[i] = previousPower.add(previousPower);
3065
+ visitThrowStmt(stmt, ctx) {
3066
+ this.printLeadingComments(stmt, ctx);
3067
+ ctx.print(stmt, `throw `);
3068
+ stmt.error.visitExpression(this, ctx);
3069
+ ctx.println(stmt, `;`);
3070
+ return null;
3071
+ }
3072
+ visitWriteVarExpr(expr, ctx) {
3073
+ const lineWasEmpty = ctx.lineIsEmpty();
3074
+ if (!lineWasEmpty) {
3075
+ ctx.print(expr, '(');
3176
3076
  }
3177
- return this.powerOfTwos[exponent];
3077
+ ctx.print(expr, `${expr.name} = `);
3078
+ expr.value.visitExpression(this, ctx);
3079
+ if (!lineWasEmpty) {
3080
+ ctx.print(expr, ')');
3081
+ }
3082
+ return null;
3178
3083
  }
3179
- }
3180
- /**
3181
- * Represents an exponentiation operation for the provided base, of which exponents are computed and
3182
- * memoized. The results are represented by a `BigIntForMultiplication` which is tailored for
3183
- * multiplication operations by memoizing the power-of-twos. This effectively results in a matrix
3184
- * representation that is lazily computed upon request.
3185
- */
3186
- class BigIntExponentiation {
3187
- constructor(base) {
3188
- this.base = base;
3189
- this.exponents = [new BigIntForMultiplication(BigInteger.one())];
3084
+ visitWriteKeyExpr(expr, ctx) {
3085
+ const lineWasEmpty = ctx.lineIsEmpty();
3086
+ if (!lineWasEmpty) {
3087
+ ctx.print(expr, '(');
3088
+ }
3089
+ expr.receiver.visitExpression(this, ctx);
3090
+ ctx.print(expr, `[`);
3091
+ expr.index.visitExpression(this, ctx);
3092
+ ctx.print(expr, `] = `);
3093
+ expr.value.visitExpression(this, ctx);
3094
+ if (!lineWasEmpty) {
3095
+ ctx.print(expr, ')');
3096
+ }
3097
+ return null;
3190
3098
  }
3191
- /**
3192
- * Compute the value for `this.base^exponent`, resulting in a big integer that is optimized for
3193
- * further multiplication operations.
3194
- */
3195
- toThePowerOf(exponent) {
3196
- // Compute the results up until the requested exponent, where every value is computed from its
3197
- // predecessor. This is because `this.base^(exponent - 1)` only has to be multiplied by `base`
3198
- // to reach `this.base^exponent`.
3199
- for (let i = this.exponents.length; i <= exponent; i++) {
3200
- const value = this.exponents[i - 1].multiplyBy(this.base);
3201
- this.exponents[i] = new BigIntForMultiplication(value);
3099
+ visitWritePropExpr(expr, ctx) {
3100
+ const lineWasEmpty = ctx.lineIsEmpty();
3101
+ if (!lineWasEmpty) {
3102
+ ctx.print(expr, '(');
3202
3103
  }
3203
- return this.exponents[exponent];
3104
+ expr.receiver.visitExpression(this, ctx);
3105
+ ctx.print(expr, `.${expr.name} = `);
3106
+ expr.value.visitExpression(this, ctx);
3107
+ if (!lineWasEmpty) {
3108
+ ctx.print(expr, ')');
3109
+ }
3110
+ return null;
3204
3111
  }
3205
- }
3206
-
3207
- /**
3208
- * @license
3209
- * Copyright Google LLC All Rights Reserved.
3210
- *
3211
- * Use of this source code is governed by an MIT-style license that can be
3212
- * found in the LICENSE file at https://angular.io/license
3213
- */
3214
- /**
3215
- * Compute the message id using the XLIFF1 digest.
3216
- */
3217
- function computeDigest(message) {
3218
- return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`);
3219
- }
3220
- /**
3221
- * Return the message id or compute it using the XLIFF2/XMB/$localize digest.
3222
- */
3223
- function decimalDigest(message) {
3224
- return message.id || computeDecimalDigest(message);
3225
- }
3226
- /**
3227
- * Compute the message id using the XLIFF2/XMB/$localize digest.
3228
- */
3229
- function computeDecimalDigest(message) {
3230
- const visitor = new _SerializerIgnoreIcuExpVisitor();
3231
- const parts = message.nodes.map(a => a.visit(visitor, null));
3232
- return computeMsgId(parts.join(''), message.meaning);
3233
- }
3234
- /**
3235
- * Serialize the i18n ast to something xml-like in order to generate an UID.
3236
- *
3237
- * The visitor is also used in the i18n parser tests
3238
- *
3239
- * @internal
3240
- */
3241
- class _SerializerVisitor {
3242
- visitText(text, context) {
3243
- return text.value;
3112
+ visitInvokeFunctionExpr(expr, ctx) {
3113
+ expr.fn.visitExpression(this, ctx);
3114
+ ctx.print(expr, `(`);
3115
+ this.visitAllExpressions(expr.args, ctx, ',');
3116
+ ctx.print(expr, `)`);
3117
+ return null;
3244
3118
  }
3245
- visitContainer(container, context) {
3246
- return `[${container.children.map(child => child.visit(this)).join(', ')}]`;
3119
+ visitTaggedTemplateExpr(expr, ctx) {
3120
+ expr.tag.visitExpression(this, ctx);
3121
+ ctx.print(expr, '`' + expr.template.elements[0].rawText);
3122
+ for (let i = 1; i < expr.template.elements.length; i++) {
3123
+ ctx.print(expr, '${');
3124
+ expr.template.expressions[i - 1].visitExpression(this, ctx);
3125
+ ctx.print(expr, `}${expr.template.elements[i].rawText}`);
3126
+ }
3127
+ ctx.print(expr, '`');
3128
+ return null;
3247
3129
  }
3248
- visitIcu(icu, context) {
3249
- const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
3250
- return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`;
3130
+ visitWrappedNodeExpr(ast, ctx) {
3131
+ throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');
3251
3132
  }
3252
- visitTagPlaceholder(ph, context) {
3253
- return ph.isVoid ?
3254
- `<ph tag name="${ph.startName}"/>` :
3255
- `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`;
3133
+ visitTypeofExpr(expr, ctx) {
3134
+ ctx.print(expr, 'typeof ');
3135
+ expr.expr.visitExpression(this, ctx);
3256
3136
  }
3257
- visitPlaceholder(ph, context) {
3258
- return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`;
3137
+ visitReadVarExpr(ast, ctx) {
3138
+ let varName = ast.name;
3139
+ if (ast.builtin != null) {
3140
+ switch (ast.builtin) {
3141
+ case BuiltinVar.Super:
3142
+ varName = 'super';
3143
+ break;
3144
+ case BuiltinVar.This:
3145
+ varName = 'this';
3146
+ break;
3147
+ case BuiltinVar.CatchError:
3148
+ varName = CATCH_ERROR_VAR.name;
3149
+ break;
3150
+ case BuiltinVar.CatchStack:
3151
+ varName = CATCH_STACK_VAR.name;
3152
+ break;
3153
+ default:
3154
+ throw new Error(`Unknown builtin variable ${ast.builtin}`);
3155
+ }
3156
+ }
3157
+ ctx.print(ast, varName);
3158
+ return null;
3259
3159
  }
3260
- visitIcuPlaceholder(ph, context) {
3261
- return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`;
3160
+ visitInstantiateExpr(ast, ctx) {
3161
+ ctx.print(ast, `new `);
3162
+ ast.classExpr.visitExpression(this, ctx);
3163
+ ctx.print(ast, `(`);
3164
+ this.visitAllExpressions(ast.args, ctx, ',');
3165
+ ctx.print(ast, `)`);
3166
+ return null;
3262
3167
  }
3263
- }
3264
- const serializerVisitor$2 = new _SerializerVisitor();
3265
- function serializeNodes(nodes) {
3266
- return nodes.map(a => a.visit(serializerVisitor$2, null));
3267
- }
3268
- /**
3269
- * Serialize the i18n ast to something xml-like in order to generate an UID.
3270
- *
3271
- * Ignore the ICU expressions so that message IDs stays identical if only the expression changes.
3272
- *
3273
- * @internal
3274
- */
3275
- class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor {
3276
- visitIcu(icu, context) {
3277
- let strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
3278
- // Do not take the expression into account
3279
- return `{${icu.type}, ${strCases.join(', ')}}`;
3168
+ visitLiteralExpr(ast, ctx) {
3169
+ const value = ast.value;
3170
+ if (typeof value === 'string') {
3171
+ ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings));
3172
+ }
3173
+ else {
3174
+ ctx.print(ast, `${value}`);
3175
+ }
3176
+ return null;
3280
3177
  }
3281
- }
3282
- /**
3283
- * Compute the SHA1 of the given string
3284
- *
3285
- * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
3286
- *
3287
- * WARNING: this function has not been designed not tested with security in mind.
3288
- * DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT.
3289
- */
3290
- function sha1(str) {
3291
- const utf8 = utf8Encode(str);
3292
- const words32 = bytesToWords32(utf8, Endian.Big);
3293
- const len = utf8.length * 8;
3294
- const w = newArray(80);
3295
- let a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476, e = 0xc3d2e1f0;
3296
- words32[len >> 5] |= 0x80 << (24 - len % 32);
3297
- words32[((len + 64 >> 9) << 4) + 15] = len;
3298
- for (let i = 0; i < words32.length; i += 16) {
3299
- const h0 = a, h1 = b, h2 = c, h3 = d, h4 = e;
3300
- for (let j = 0; j < 80; j++) {
3301
- if (j < 16) {
3302
- w[j] = words32[i + j];
3303
- }
3304
- else {
3305
- w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
3306
- }
3307
- const fkVal = fk(j, b, c, d);
3308
- const f = fkVal[0];
3309
- const k = fkVal[1];
3310
- const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32);
3311
- e = d;
3312
- d = c;
3313
- c = rol32(b, 30);
3314
- b = a;
3315
- a = temp;
3178
+ visitLocalizedString(ast, ctx) {
3179
+ const head = ast.serializeI18nHead();
3180
+ ctx.print(ast, '$localize `' + head.raw);
3181
+ for (let i = 1; i < ast.messageParts.length; i++) {
3182
+ ctx.print(ast, '${');
3183
+ ast.expressions[i - 1].visitExpression(this, ctx);
3184
+ ctx.print(ast, `}${ast.serializeI18nTemplatePart(i).raw}`);
3316
3185
  }
3317
- a = add32(a, h0);
3318
- b = add32(b, h1);
3319
- c = add32(c, h2);
3320
- d = add32(d, h3);
3321
- e = add32(e, h4);
3186
+ ctx.print(ast, '`');
3187
+ return null;
3322
3188
  }
3323
- return bytesToHexString(words32ToByteString([a, b, c, d, e]));
3324
- }
3325
- function fk(index, b, c, d) {
3326
- if (index < 20) {
3327
- return [(b & c) | (~b & d), 0x5a827999];
3189
+ visitConditionalExpr(ast, ctx) {
3190
+ ctx.print(ast, `(`);
3191
+ ast.condition.visitExpression(this, ctx);
3192
+ ctx.print(ast, '? ');
3193
+ ast.trueCase.visitExpression(this, ctx);
3194
+ ctx.print(ast, ': ');
3195
+ ast.falseCase.visitExpression(this, ctx);
3196
+ ctx.print(ast, `)`);
3197
+ return null;
3328
3198
  }
3329
- if (index < 40) {
3330
- return [b ^ c ^ d, 0x6ed9eba1];
3199
+ visitNotExpr(ast, ctx) {
3200
+ ctx.print(ast, '!');
3201
+ ast.condition.visitExpression(this, ctx);
3202
+ return null;
3331
3203
  }
3332
- if (index < 60) {
3333
- return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc];
3204
+ visitAssertNotNullExpr(ast, ctx) {
3205
+ ast.condition.visitExpression(this, ctx);
3206
+ return null;
3334
3207
  }
3335
- return [b ^ c ^ d, 0xca62c1d6];
3336
- }
3337
- /**
3338
- * Compute the fingerprint of the given string
3339
- *
3340
- * The output is 64 bit number encoded as a decimal string
3341
- *
3342
- * based on:
3343
- * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java
3344
- */
3345
- function fingerprint(str) {
3346
- const utf8 = utf8Encode(str);
3347
- let hi = hash32(utf8, 0);
3348
- let lo = hash32(utf8, 102072);
3349
- if (hi == 0 && (lo == 0 || lo == 1)) {
3350
- hi = hi ^ 0x130f9bef;
3351
- lo = lo ^ -0x6b5f56d8;
3208
+ visitUnaryOperatorExpr(ast, ctx) {
3209
+ let opStr;
3210
+ switch (ast.operator) {
3211
+ case UnaryOperator.Plus:
3212
+ opStr = '+';
3213
+ break;
3214
+ case UnaryOperator.Minus:
3215
+ opStr = '-';
3216
+ break;
3217
+ default:
3218
+ throw new Error(`Unknown operator ${ast.operator}`);
3219
+ }
3220
+ if (ast.parens)
3221
+ ctx.print(ast, `(`);
3222
+ ctx.print(ast, opStr);
3223
+ ast.expr.visitExpression(this, ctx);
3224
+ if (ast.parens)
3225
+ ctx.print(ast, `)`);
3226
+ return null;
3352
3227
  }
3353
- return [hi, lo];
3354
- }
3355
- function computeMsgId(msg, meaning = '') {
3356
- let msgFingerprint = fingerprint(msg);
3357
- if (meaning) {
3358
- const meaningFingerprint = fingerprint(meaning);
3359
- msgFingerprint = add64(rol64(msgFingerprint, 1), meaningFingerprint);
3228
+ visitBinaryOperatorExpr(ast, ctx) {
3229
+ let opStr;
3230
+ switch (ast.operator) {
3231
+ case BinaryOperator.Equals:
3232
+ opStr = '==';
3233
+ break;
3234
+ case BinaryOperator.Identical:
3235
+ opStr = '===';
3236
+ break;
3237
+ case BinaryOperator.NotEquals:
3238
+ opStr = '!=';
3239
+ break;
3240
+ case BinaryOperator.NotIdentical:
3241
+ opStr = '!==';
3242
+ break;
3243
+ case BinaryOperator.And:
3244
+ opStr = '&&';
3245
+ break;
3246
+ case BinaryOperator.BitwiseAnd:
3247
+ opStr = '&';
3248
+ break;
3249
+ case BinaryOperator.Or:
3250
+ opStr = '||';
3251
+ break;
3252
+ case BinaryOperator.Plus:
3253
+ opStr = '+';
3254
+ break;
3255
+ case BinaryOperator.Minus:
3256
+ opStr = '-';
3257
+ break;
3258
+ case BinaryOperator.Divide:
3259
+ opStr = '/';
3260
+ break;
3261
+ case BinaryOperator.Multiply:
3262
+ opStr = '*';
3263
+ break;
3264
+ case BinaryOperator.Modulo:
3265
+ opStr = '%';
3266
+ break;
3267
+ case BinaryOperator.Lower:
3268
+ opStr = '<';
3269
+ break;
3270
+ case BinaryOperator.LowerEquals:
3271
+ opStr = '<=';
3272
+ break;
3273
+ case BinaryOperator.Bigger:
3274
+ opStr = '>';
3275
+ break;
3276
+ case BinaryOperator.BiggerEquals:
3277
+ opStr = '>=';
3278
+ break;
3279
+ case BinaryOperator.NullishCoalesce:
3280
+ opStr = '??';
3281
+ break;
3282
+ default:
3283
+ throw new Error(`Unknown operator ${ast.operator}`);
3284
+ }
3285
+ if (ast.parens)
3286
+ ctx.print(ast, `(`);
3287
+ ast.lhs.visitExpression(this, ctx);
3288
+ ctx.print(ast, ` ${opStr} `);
3289
+ ast.rhs.visitExpression(this, ctx);
3290
+ if (ast.parens)
3291
+ ctx.print(ast, `)`);
3292
+ return null;
3360
3293
  }
3361
- const hi = msgFingerprint[0];
3362
- const lo = msgFingerprint[1];
3363
- return wordsToDecimalString(hi & 0x7fffffff, lo);
3364
- }
3365
- function hash32(bytes, c) {
3366
- let a = 0x9e3779b9, b = 0x9e3779b9;
3367
- let i;
3368
- const len = bytes.length;
3369
- for (i = 0; i + 12 <= len; i += 12) {
3370
- a = add32(a, wordAt(bytes, i, Endian.Little));
3371
- b = add32(b, wordAt(bytes, i + 4, Endian.Little));
3372
- c = add32(c, wordAt(bytes, i + 8, Endian.Little));
3373
- const res = mix(a, b, c);
3374
- a = res[0], b = res[1], c = res[2];
3294
+ visitReadPropExpr(ast, ctx) {
3295
+ ast.receiver.visitExpression(this, ctx);
3296
+ ctx.print(ast, `.`);
3297
+ ctx.print(ast, ast.name);
3298
+ return null;
3375
3299
  }
3376
- a = add32(a, wordAt(bytes, i, Endian.Little));
3377
- b = add32(b, wordAt(bytes, i + 4, Endian.Little));
3378
- // the first byte of c is reserved for the length
3379
- c = add32(c, len);
3380
- c = add32(c, wordAt(bytes, i + 8, Endian.Little) << 8);
3381
- return mix(a, b, c)[2];
3382
- }
3383
- // clang-format off
3384
- function mix(a, b, c) {
3385
- a = sub32(a, b);
3386
- a = sub32(a, c);
3387
- a ^= c >>> 13;
3388
- b = sub32(b, c);
3389
- b = sub32(b, a);
3390
- b ^= a << 8;
3391
- c = sub32(c, a);
3392
- c = sub32(c, b);
3393
- c ^= b >>> 13;
3394
- a = sub32(a, b);
3395
- a = sub32(a, c);
3396
- a ^= c >>> 12;
3397
- b = sub32(b, c);
3398
- b = sub32(b, a);
3399
- b ^= a << 16;
3400
- c = sub32(c, a);
3401
- c = sub32(c, b);
3402
- c ^= b >>> 5;
3403
- a = sub32(a, b);
3404
- a = sub32(a, c);
3405
- a ^= c >>> 3;
3406
- b = sub32(b, c);
3407
- b = sub32(b, a);
3408
- b ^= a << 10;
3409
- c = sub32(c, a);
3410
- c = sub32(c, b);
3411
- c ^= b >>> 15;
3412
- return [a, b, c];
3413
- }
3414
- // clang-format on
3415
- // Utils
3416
- var Endian;
3417
- (function (Endian) {
3418
- Endian[Endian["Little"] = 0] = "Little";
3419
- Endian[Endian["Big"] = 1] = "Big";
3420
- })(Endian || (Endian = {}));
3421
- function add32(a, b) {
3422
- return add32to64(a, b)[1];
3423
- }
3424
- function add32to64(a, b) {
3425
- const low = (a & 0xffff) + (b & 0xffff);
3426
- const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
3427
- return [high >>> 16, (high << 16) | (low & 0xffff)];
3428
- }
3429
- function add64(a, b) {
3430
- const ah = a[0], al = a[1];
3431
- const bh = b[0], bl = b[1];
3432
- const result = add32to64(al, bl);
3433
- const carry = result[0];
3434
- const l = result[1];
3435
- const h = add32(add32(ah, bh), carry);
3436
- return [h, l];
3437
- }
3438
- function sub32(a, b) {
3439
- const low = (a & 0xffff) - (b & 0xffff);
3440
- const high = (a >> 16) - (b >> 16) + (low >> 16);
3441
- return (high << 16) | (low & 0xffff);
3442
- }
3443
- // Rotate a 32b number left `count` position
3444
- function rol32(a, count) {
3445
- return (a << count) | (a >>> (32 - count));
3446
- }
3447
- // Rotate a 64b number left `count` position
3448
- function rol64(num, count) {
3449
- const hi = num[0], lo = num[1];
3450
- const h = (hi << count) | (lo >>> (32 - count));
3451
- const l = (lo << count) | (hi >>> (32 - count));
3452
- return [h, l];
3453
- }
3454
- function bytesToWords32(bytes, endian) {
3455
- const size = (bytes.length + 3) >>> 2;
3456
- const words32 = [];
3457
- for (let i = 0; i < size; i++) {
3458
- words32[i] = wordAt(bytes, i * 4, endian);
3300
+ visitReadKeyExpr(ast, ctx) {
3301
+ ast.receiver.visitExpression(this, ctx);
3302
+ ctx.print(ast, `[`);
3303
+ ast.index.visitExpression(this, ctx);
3304
+ ctx.print(ast, `]`);
3305
+ return null;
3459
3306
  }
3460
- return words32;
3461
- }
3462
- function byteAt(bytes, index) {
3463
- return index >= bytes.length ? 0 : bytes[index];
3464
- }
3465
- function wordAt(bytes, index, endian) {
3466
- let word = 0;
3467
- if (endian === Endian.Big) {
3468
- for (let i = 0; i < 4; i++) {
3469
- word += byteAt(bytes, index + i) << (24 - 8 * i);
3470
- }
3307
+ visitLiteralArrayExpr(ast, ctx) {
3308
+ ctx.print(ast, `[`);
3309
+ this.visitAllExpressions(ast.entries, ctx, ',');
3310
+ ctx.print(ast, `]`);
3311
+ return null;
3471
3312
  }
3472
- else {
3473
- for (let i = 0; i < 4; i++) {
3474
- word += byteAt(bytes, index + i) << 8 * i;
3313
+ visitLiteralMapExpr(ast, ctx) {
3314
+ ctx.print(ast, `{`);
3315
+ this.visitAllObjects(entry => {
3316
+ ctx.print(ast, `${escapeIdentifier(entry.key, this._escapeDollarInStrings, entry.quoted)}:`);
3317
+ entry.value.visitExpression(this, ctx);
3318
+ }, ast.entries, ctx, ',');
3319
+ ctx.print(ast, `}`);
3320
+ return null;
3321
+ }
3322
+ visitCommaExpr(ast, ctx) {
3323
+ ctx.print(ast, '(');
3324
+ this.visitAllExpressions(ast.parts, ctx, ',');
3325
+ ctx.print(ast, ')');
3326
+ return null;
3327
+ }
3328
+ visitAllExpressions(expressions, ctx, separator) {
3329
+ this.visitAllObjects(expr => expr.visitExpression(this, ctx), expressions, ctx, separator);
3330
+ }
3331
+ visitAllObjects(handler, expressions, ctx, separator) {
3332
+ let incrementedIndent = false;
3333
+ for (let i = 0; i < expressions.length; i++) {
3334
+ if (i > 0) {
3335
+ if (ctx.lineLength() > 80) {
3336
+ ctx.print(null, separator, true);
3337
+ if (!incrementedIndent) {
3338
+ // continuation are marked with double indent.
3339
+ ctx.incIndent();
3340
+ ctx.incIndent();
3341
+ incrementedIndent = true;
3342
+ }
3343
+ }
3344
+ else {
3345
+ ctx.print(null, separator, false);
3346
+ }
3347
+ }
3348
+ handler(expressions[i]);
3349
+ }
3350
+ if (incrementedIndent) {
3351
+ // continuation are marked with double indent.
3352
+ ctx.decIndent();
3353
+ ctx.decIndent();
3475
3354
  }
3476
3355
  }
3477
- return word;
3478
- }
3479
- function words32ToByteString(words32) {
3480
- return words32.reduce((bytes, word) => bytes.concat(word32ToByteString(word)), []);
3481
- }
3482
- function word32ToByteString(word) {
3483
- let bytes = [];
3484
- for (let i = 0; i < 4; i++) {
3485
- bytes.push((word >>> 8 * (3 - i)) & 0xff);
3356
+ visitAllStatements(statements, ctx) {
3357
+ statements.forEach((stmt) => stmt.visitStatement(this, ctx));
3486
3358
  }
3487
- return bytes;
3488
3359
  }
3489
- function bytesToHexString(bytes) {
3490
- let hex = '';
3491
- for (let i = 0; i < bytes.length; i++) {
3492
- const b = byteAt(bytes, i);
3493
- hex += (b >>> 4).toString(16) + (b & 0x0f).toString(16);
3360
+ function escapeIdentifier(input, escapeDollar, alwaysQuote = true) {
3361
+ if (input == null) {
3362
+ return null;
3494
3363
  }
3495
- return hex.toLowerCase();
3496
- }
3497
- /**
3498
- * Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized
3499
- * power-of-256 results with memoized power-of-two computations for efficient multiplication.
3500
- *
3501
- * For our purposes, this can be safely stored as a global without memory concerns. The reason is
3502
- * that we encode two words, so only need the 0th (for the low word) and 4th (for the high word)
3503
- * exponent.
3504
- */
3505
- const base256 = new BigIntExponentiation(256);
3506
- /**
3507
- * Represents two 32-bit words as a single decimal number. This requires a big integer storage
3508
- * model as JS numbers are not accurate enough to represent the 64-bit number.
3509
- *
3510
- * Based on https://www.danvk.org/hex2dec.html
3511
- */
3512
- function wordsToDecimalString(hi, lo) {
3513
- // Encode the four bytes in lo in the lower digits of the decimal number.
3514
- // Note: the multiplication results in lo itself but represented by a big integer using its
3515
- // decimal digits.
3516
- const decimal = base256.toThePowerOf(0).multiplyBy(lo);
3517
- // Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why
3518
- // this multiplication factor is applied.
3519
- base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal);
3520
- return decimal.toString();
3364
+ const body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, (...match) => {
3365
+ if (match[0] == '$') {
3366
+ return escapeDollar ? '\\$' : '$';
3367
+ }
3368
+ else if (match[0] == '\n') {
3369
+ return '\\n';
3370
+ }
3371
+ else if (match[0] == '\r') {
3372
+ return '\\r';
3373
+ }
3374
+ else {
3375
+ return `\\${match[0]}`;
3376
+ }
3377
+ });
3378
+ const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);
3379
+ return requiresQuotes ? `'${body}'` : body;
3521
3380
  }
3522
-
3523
- /**
3524
- * @license
3525
- * Copyright Google LLC All Rights Reserved.
3526
- *
3527
- * Use of this source code is governed by an MIT-style license that can be
3528
- * found in the LICENSE file at https://angular.io/license
3529
- */
3530
- // XMB/XTB placeholders can only contain A-Z, 0-9 and _
3531
- function toPublicName(internalName) {
3532
- return internalName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
3381
+ function _createIndent(count) {
3382
+ let res = '';
3383
+ for (let i = 0; i < count; i++) {
3384
+ res += _INDENT_WITH;
3385
+ }
3386
+ return res;
3533
3387
  }
3534
3388
 
3535
3389
  /**
@@ -3539,349 +3393,275 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
3539
3393
  * Use of this source code is governed by an MIT-style license that can be
3540
3394
  * found in the LICENSE file at https://angular.io/license
3541
3395
  */
3542
- /* Closure variables holding messages must be named `MSG_[A-Z0-9]+` */
3543
- const CLOSURE_TRANSLATION_VAR_PREFIX = 'MSG_';
3544
- /**
3545
- * Prefix for non-`goog.getMsg` i18n-related vars.
3546
- * Note: the prefix uses lowercase characters intentionally due to a Closure behavior that
3547
- * considers variables like `I18N_0` as constants and throws an error when their value changes.
3548
- */
3549
- const TRANSLATION_VAR_PREFIX = 'i18n_';
3550
- /** Name of the i18n attributes **/
3551
- const I18N_ATTR = 'i18n';
3552
- const I18N_ATTR_PREFIX = 'i18n-';
3553
- /** Prefix of var expressions used in ICUs */
3554
- const I18N_ICU_VAR_PREFIX = 'VAR_';
3555
- /** Prefix of ICU expressions for post processing */
3556
- const I18N_ICU_MAPPING_PREFIX = 'I18N_EXP_';
3557
- /** Placeholder wrapper for i18n expressions **/
3558
- const I18N_PLACEHOLDER_SYMBOL = '�';
3559
- function isI18nAttribute(name) {
3560
- return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
3561
- }
3562
- function isI18nRootNode(meta) {
3563
- return meta instanceof Message;
3396
+ function typeWithParameters(type, numParams) {
3397
+ if (numParams === 0) {
3398
+ return expressionType(type);
3399
+ }
3400
+ const params = [];
3401
+ for (let i = 0; i < numParams; i++) {
3402
+ params.push(DYNAMIC_TYPE);
3403
+ }
3404
+ return expressionType(type, undefined, params);
3564
3405
  }
3565
- function isSingleI18nIcu(meta) {
3566
- return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu;
3406
+ const ANIMATE_SYMBOL_PREFIX = '@';
3407
+ function prepareSyntheticPropertyName(name) {
3408
+ return `${ANIMATE_SYMBOL_PREFIX}${name}`;
3567
3409
  }
3568
- function hasI18nMeta(node) {
3569
- return !!node.i18n;
3410
+ function prepareSyntheticListenerName(name, phase) {
3411
+ return `${ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;
3570
3412
  }
3571
- function hasI18nAttrs(element) {
3572
- return element.attrs.some((attr) => isI18nAttribute(attr.name));
3413
+ function getSafePropertyAccessString(accessor, name) {
3414
+ const escapedName = escapeIdentifier(name, false, false);
3415
+ return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;
3573
3416
  }
3574
- function icuFromI18nMessage(message) {
3575
- return message.nodes[0];
3417
+ function prepareSyntheticListenerFunctionName(name, phase) {
3418
+ return `animation_${name}_${phase}`;
3576
3419
  }
3577
- function wrapI18nPlaceholder(content, contextId = 0) {
3578
- const blockId = contextId > 0 ? `:${contextId}` : '';
3579
- return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`;
3420
+ function jitOnlyGuardedExpression(expr) {
3421
+ return guardedExpression('ngJitMode', expr);
3580
3422
  }
3581
- function assembleI18nBoundString(strings, bindingStartIndex = 0, contextId = 0) {
3582
- if (!strings.length)
3583
- return '';
3584
- let acc = '';
3585
- const lastIdx = strings.length - 1;
3586
- for (let i = 0; i < lastIdx; i++) {
3587
- acc += `${strings[i]}${wrapI18nPlaceholder(bindingStartIndex + i, contextId)}`;
3588
- }
3589
- acc += strings[lastIdx];
3590
- return acc;
3423
+ function devOnlyGuardedExpression(expr) {
3424
+ return guardedExpression('ngDevMode', expr);
3591
3425
  }
3592
- function getSeqNumberGenerator(startsAt = 0) {
3593
- let current = startsAt;
3594
- return () => current++;
3426
+ function guardedExpression(guard, expr) {
3427
+ const guardExpr = new ExternalExpr({ name: guard, moduleName: null });
3428
+ const guardNotDefined = new BinaryOperatorExpr(BinaryOperator.Identical, new TypeofExpr(guardExpr), literal$1('undefined'));
3429
+ const guardUndefinedOrTrue = new BinaryOperatorExpr(BinaryOperator.Or, guardNotDefined, guardExpr, /* type */ undefined,
3430
+ /* sourceSpan */ undefined, true);
3431
+ return new BinaryOperatorExpr(BinaryOperator.And, guardUndefinedOrTrue, expr);
3595
3432
  }
3596
- function placeholdersToParams(placeholders) {
3597
- const params = {};
3598
- placeholders.forEach((values, key) => {
3599
- params[key] = literal$1(values.length > 1 ? `[${values.join('|')}]` : values[0]);
3600
- });
3601
- return params;
3433
+ function wrapReference(value) {
3434
+ const wrapped = new WrappedNodeExpr(value);
3435
+ return { value: wrapped, type: wrapped };
3602
3436
  }
3603
- function updatePlaceholderMap(map, name, ...values) {
3604
- const current = map.get(name) || [];
3605
- current.push(...values);
3606
- map.set(name, current);
3437
+ function refsToArray(refs, shouldForwardDeclare) {
3438
+ const values = literalArr(refs.map(ref => ref.value));
3439
+ return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
3607
3440
  }
3608
- function assembleBoundTextPlaceholders(meta, bindingStartIndex = 0, contextId = 0) {
3609
- const startIdx = bindingStartIndex;
3610
- const placeholders = new Map();
3611
- const node = meta instanceof Message ? meta.nodes.find(node => node instanceof Container) : meta;
3612
- if (node) {
3613
- node
3614
- .children
3615
- .filter((child) => child instanceof Placeholder)
3616
- .forEach((child, idx) => {
3617
- const content = wrapI18nPlaceholder(startIdx + idx, contextId);
3618
- updatePlaceholderMap(placeholders, child.name, content);
3619
- });
3620
- }
3621
- return placeholders;
3441
+ function createMayBeForwardRefExpression(expression, forwardRef) {
3442
+ return { expression, forwardRef };
3622
3443
  }
3623
3444
  /**
3624
- * Format the placeholder names in a map of placeholders to expressions.
3445
+ * Convert a `MaybeForwardRefExpression` to an `Expression`, possibly wrapping its expression in a
3446
+ * `forwardRef()` call.
3625
3447
  *
3626
- * The placeholder names are converted from "internal" format (e.g. `START_TAG_DIV_1`) to "external"
3627
- * format (e.g. `startTagDiv_1`).
3448
+ * If `MaybeForwardRefExpression.forwardRef` is `ForwardRefHandling.Unwrapped` then the expression
3449
+ * was originally wrapped in a `forwardRef()` call to prevent the value from being eagerly evaluated
3450
+ * in the code.
3628
3451
  *
3629
- * @param params A map of placeholder names to expressions.
3630
- * @param useCamelCase whether to camelCase the placeholder name when formatting.
3631
- * @returns A new map of formatted placeholder names to expressions.
3452
+ * See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and
3453
+ * `packages/compiler/src/jit_compiler_facade.ts` for more information.
3632
3454
  */
3633
- function i18nFormatPlaceholderNames(params = {}, useCamelCase) {
3634
- const _params = {};
3635
- if (params && Object.keys(params).length) {
3636
- Object.keys(params).forEach(key => _params[formatI18nPlaceholderName(key, useCamelCase)] = params[key]);
3455
+ function convertFromMaybeForwardRefExpression({ expression, forwardRef }) {
3456
+ switch (forwardRef) {
3457
+ case 0 /* None */:
3458
+ case 1 /* Wrapped */:
3459
+ return expression;
3460
+ case 2 /* Unwrapped */:
3461
+ return generateForwardRef(expression);
3637
3462
  }
3638
- return _params;
3639
3463
  }
3640
3464
  /**
3641
- * Converts internal placeholder names to public-facing format
3642
- * (for example to use in goog.getMsg call).
3643
- * Example: `START_TAG_DIV_1` is converted to `startTagDiv_1`.
3465
+ * Generate an expression that has the given `expr` wrapped in the following form:
3644
3466
  *
3645
- * @param name The placeholder name that should be formatted
3646
- * @returns Formatted placeholder name
3467
+ * ```
3468
+ * forwardRef(() => expr)
3469
+ * ```
3647
3470
  */
3648
- function formatI18nPlaceholderName(name, useCamelCase = true) {
3649
- const publicName = toPublicName(name);
3650
- if (!useCamelCase) {
3651
- return publicName;
3652
- }
3653
- const chunks = publicName.split('_');
3654
- if (chunks.length === 1) {
3655
- // if no "_" found - just lowercase the value
3656
- return name.toLowerCase();
3657
- }
3658
- let postfix;
3659
- // eject last element if it's a number
3660
- if (/^\d+$/.test(chunks[chunks.length - 1])) {
3661
- postfix = chunks.pop();
3662
- }
3663
- let raw = chunks.shift().toLowerCase();
3664
- if (chunks.length) {
3665
- raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join('');
3666
- }
3667
- return postfix ? `${raw}_${postfix}` : raw;
3471
+ function generateForwardRef(expr) {
3472
+ return importExpr(Identifiers$1.forwardRef).callFn([fn([], [new ReturnStatement(expr)])]);
3668
3473
  }
3474
+
3475
+ var R3FactoryDelegateType;
3476
+ (function (R3FactoryDelegateType) {
3477
+ R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
3478
+ R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function";
3479
+ })(R3FactoryDelegateType || (R3FactoryDelegateType = {}));
3480
+ var FactoryTarget$1;
3481
+ (function (FactoryTarget) {
3482
+ FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
3483
+ FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
3484
+ FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
3485
+ FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
3486
+ FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
3487
+ })(FactoryTarget$1 || (FactoryTarget$1 = {}));
3669
3488
  /**
3670
- * Generates a prefix for translation const name.
3671
- *
3672
- * @param extra Additional local prefix that should be injected into translation var name
3673
- * @returns Complete translation const prefix
3489
+ * Construct a factory function expression for the given `R3FactoryMetadata`.
3674
3490
  */
3675
- function getTranslationConstPrefix(extra) {
3676
- return `${CLOSURE_TRANSLATION_VAR_PREFIX}${extra}`.toUpperCase();
3677
- }
3678
- /**
3679
- * Generate AST to declare a variable. E.g. `var I18N_1;`.
3680
- * @param variable the name of the variable to declare.
3681
- */
3682
- function declareI18nVariable(variable) {
3683
- return new DeclareVarStmt(variable.name, undefined, INFERRED_TYPE, undefined, variable.sourceSpan);
3684
- }
3685
-
3686
- /**
3687
- * @license
3688
- * Copyright Google LLC All Rights Reserved.
3689
- *
3690
- * Use of this source code is governed by an MIT-style license that can be
3691
- * found in the LICENSE file at https://angular.io/license
3692
- */
3693
- /**
3694
- * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in
3695
- * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may
3696
- * bot work in some cases when object keys are mangled by minifier.
3697
- *
3698
- * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with
3699
- * inputs that contain potentially unsafe chars.
3700
- */
3701
- const UNSAFE_OBJECT_KEY_NAME_REGEXP = /[-.]/;
3702
- /** Name of the temporary to use during data binding */
3703
- const TEMPORARY_NAME = '_t';
3704
- /** Name of the context parameter passed into a template function */
3705
- const CONTEXT_NAME = 'ctx';
3706
- /** Name of the RenderFlag passed into a template function */
3707
- const RENDER_FLAGS = 'rf';
3708
- /** The prefix reference variables */
3709
- const REFERENCE_PREFIX = '_r';
3710
- /** The name of the implicit context reference */
3711
- const IMPLICIT_REFERENCE = '$implicit';
3712
- /** Non bindable attribute name **/
3713
- const NON_BINDABLE_ATTR = 'ngNonBindable';
3714
- /** Name for the variable keeping track of the context returned by `ɵɵrestoreView`. */
3715
- const RESTORED_VIEW_CONTEXT_NAME = 'restoredCtx';
3716
- /**
3717
- * Creates an allocator for a temporary variable.
3718
- *
3719
- * A variable declaration is added to the statements the first time the allocator is invoked.
3720
- */
3721
- function temporaryAllocator(statements, name) {
3722
- let temp = null;
3723
- return () => {
3724
- if (!temp) {
3725
- statements.push(new DeclareVarStmt(TEMPORARY_NAME, undefined, DYNAMIC_TYPE));
3726
- temp = variable(name);
3491
+ function compileFactoryFunction(meta) {
3492
+ const t = variable('t');
3493
+ let baseFactoryVar = null;
3494
+ // The type to instantiate via constructor invocation. If there is no delegated factory, meaning
3495
+ // this type is always created by constructor invocation, then this is the type-to-create
3496
+ // parameter provided by the user (t) if specified, or the current type if not. If there is a
3497
+ // delegated factory (which is used to create the current type) then this is only the type-to-
3498
+ // create parameter (t).
3499
+ const typeForCtor = !isDelegatedFactoryMetadata(meta) ?
3500
+ new BinaryOperatorExpr(BinaryOperator.Or, t, meta.internalType) :
3501
+ t;
3502
+ let ctorExpr = null;
3503
+ if (meta.deps !== null) {
3504
+ // There is a constructor (either explicitly or implicitly defined).
3505
+ if (meta.deps !== 'invalid') {
3506
+ ctorExpr = new InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));
3727
3507
  }
3728
- return temp;
3729
- };
3730
- }
3731
- function unsupported(feature) {
3732
- if (this) {
3733
- throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
3734
3508
  }
3735
- throw new Error(`Feature ${feature} is not supported yet`);
3736
- }
3737
- function invalid(arg) {
3738
- throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
3739
- }
3740
- function asLiteral(value) {
3741
- if (Array.isArray(value)) {
3742
- return literalArr(value.map(asLiteral));
3509
+ else {
3510
+ // There is no constructor, use the base class' factory to construct typeForCtor.
3511
+ baseFactoryVar = variable(`ɵ${meta.name}_BaseFactory`);
3512
+ ctorExpr = baseFactoryVar.callFn([typeForCtor]);
3743
3513
  }
3744
- return literal$1(value, INFERRED_TYPE);
3745
- }
3746
- function conditionallyCreateMapObjectLiteral(keys, keepDeclared) {
3747
- if (Object.getOwnPropertyNames(keys).length > 0) {
3748
- return mapToExpression(keys, keepDeclared);
3514
+ const body = [];
3515
+ let retExpr = null;
3516
+ function makeConditionalFactory(nonCtorExpr) {
3517
+ const r = variable('r');
3518
+ body.push(r.set(NULL_EXPR).toDeclStmt());
3519
+ const ctorStmt = ctorExpr !== null ? r.set(ctorExpr).toStmt() :
3520
+ importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt();
3521
+ body.push(ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()]));
3522
+ return r;
3749
3523
  }
3750
- return null;
3751
- }
3752
- function mapToExpression(map, keepDeclared) {
3753
- return literalMap(Object.getOwnPropertyNames(map).map(key => {
3754
- // canonical syntax: `dirProp: publicProp`
3755
- // if there is no `:`, use dirProp = elProp
3756
- const value = map[key];
3757
- let declaredName;
3758
- let publicName;
3759
- let minifiedName;
3760
- let needsDeclaredName;
3761
- if (Array.isArray(value)) {
3762
- [publicName, declaredName] = value;
3763
- minifiedName = key;
3764
- needsDeclaredName = publicName !== declaredName;
3765
- }
3766
- else {
3767
- [declaredName, publicName] = splitAtColon(key, [key, value]);
3768
- minifiedName = declaredName;
3769
- // Only include the declared name if extracted from the key, i.e. the key contains a colon.
3770
- // Otherwise the declared name should be omitted even if it is different from the public name,
3771
- // as it may have already been minified.
3772
- needsDeclaredName = publicName !== declaredName && key.includes(':');
3773
- }
3774
- return {
3775
- key: minifiedName,
3776
- // put quotes around keys that contain potentially unsafe characters
3777
- quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName),
3778
- value: (keepDeclared && needsDeclaredName) ?
3779
- literalArr([asLiteral(publicName), asLiteral(declaredName)]) :
3780
- asLiteral(publicName)
3781
- };
3782
- }));
3783
- }
3784
- /**
3785
- * Remove trailing null nodes as they are implied.
3786
- */
3787
- function trimTrailingNulls(parameters) {
3788
- while (isNull(parameters[parameters.length - 1])) {
3789
- parameters.pop();
3524
+ if (isDelegatedFactoryMetadata(meta)) {
3525
+ // This type is created with a delegated factory. If a type parameter is not specified, call
3526
+ // the factory instead.
3527
+ const delegateArgs = injectDependencies(meta.delegateDeps, meta.target);
3528
+ // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.
3529
+ const factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ?
3530
+ InstantiateExpr :
3531
+ InvokeFunctionExpr)(meta.delegate, delegateArgs);
3532
+ retExpr = makeConditionalFactory(factoryExpr);
3790
3533
  }
3791
- return parameters;
3792
- }
3793
- function getQueryPredicate(query, constantPool) {
3794
- if (Array.isArray(query.predicate)) {
3795
- let predicate = [];
3796
- query.predicate.forEach((selector) => {
3797
- // Each item in predicates array may contain strings with comma-separated refs
3798
- // (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
3799
- // as separate array entities
3800
- const selectors = selector.split(',').map(token => literal$1(token.trim()));
3801
- predicate.push(...selectors);
3802
- });
3803
- return constantPool.getConstLiteral(literalArr(predicate), true);
3534
+ else if (isExpressionFactoryMetadata(meta)) {
3535
+ // TODO(alxhub): decide whether to lower the value here or in the caller
3536
+ retExpr = makeConditionalFactory(meta.expression);
3804
3537
  }
3805
3538
  else {
3806
- return query.predicate;
3539
+ retExpr = ctorExpr;
3807
3540
  }
3808
- }
3809
- /**
3810
- * A representation for an object literal used during codegen of definition objects. The generic
3811
- * type `T` allows to reference a documented type of the generated structure, such that the
3812
- * property names that are set can be resolved to their documented declaration.
3813
- */
3814
- class DefinitionMap {
3815
- constructor() {
3816
- this.values = [];
3541
+ if (retExpr === null) {
3542
+ // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.
3543
+ body.push(importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt());
3817
3544
  }
3818
- set(key, value) {
3819
- if (value) {
3820
- this.values.push({ key: key, value, quoted: false });
3821
- }
3545
+ else if (baseFactoryVar !== null) {
3546
+ // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it.
3547
+ const getInheritedFactoryCall = importExpr(Identifiers$1.getInheritedFactory).callFn([meta.internalType]);
3548
+ // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))`
3549
+ const baseFactory = new BinaryOperatorExpr(BinaryOperator.Or, baseFactoryVar, baseFactoryVar.set(getInheritedFactoryCall));
3550
+ body.push(new ReturnStatement(baseFactory.callFn([typeForCtor])));
3822
3551
  }
3823
- toLiteralMap() {
3824
- return literalMap(this.values);
3552
+ else {
3553
+ // This is straightforward factory, just return it.
3554
+ body.push(new ReturnStatement(retExpr));
3555
+ }
3556
+ let factoryFn = fn([new FnParam('t', DYNAMIC_TYPE)], body, INFERRED_TYPE, undefined, `${meta.name}_Factory`);
3557
+ if (baseFactoryVar !== null) {
3558
+ // There is a base factory variable so wrap its declaration along with the factory function into
3559
+ // an IIFE.
3560
+ factoryFn = fn([], [
3561
+ new DeclareVarStmt(baseFactoryVar.name), new ReturnStatement(factoryFn)
3562
+ ]).callFn([], /* sourceSpan */ undefined, /* pure */ true);
3825
3563
  }
3564
+ return {
3565
+ expression: factoryFn,
3566
+ statements: [],
3567
+ type: createFactoryType(meta),
3568
+ };
3826
3569
  }
3827
- /**
3828
- * Extract a map of properties to values for a given element or template node, which can be used
3829
- * by the directive matching machinery.
3830
- *
3831
- * @param elOrTpl the element or template in question
3832
- * @return an object set up for directive matching. For attributes on the element/template, this
3833
- * object maps a property name to its (static) value. For any bindings, this map simply maps the
3834
- * property name to an empty string.
3835
- */
3836
- function getAttrsForDirectiveMatching(elOrTpl) {
3837
- const attributesMap = {};
3838
- if (elOrTpl instanceof Template && elOrTpl.tagName !== 'ng-template') {
3839
- elOrTpl.templateAttrs.forEach(a => attributesMap[a.name] = '');
3570
+ function createFactoryType(meta) {
3571
+ const ctorDepsType = meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : NONE_TYPE;
3572
+ return expressionType(importExpr(Identifiers$1.FactoryDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType]));
3573
+ }
3574
+ function injectDependencies(deps, target) {
3575
+ return deps.map((dep, index) => compileInjectDependency(dep, target, index));
3576
+ }
3577
+ function compileInjectDependency(dep, target, index) {
3578
+ // Interpret the dependency according to its resolved type.
3579
+ if (dep.token === null) {
3580
+ return importExpr(Identifiers$1.invalidFactoryDep).callFn([literal$1(index)]);
3581
+ }
3582
+ else if (dep.attributeNameType === null) {
3583
+ // Build up the injection flags according to the metadata.
3584
+ const flags = 0 /* Default */ | (dep.self ? 2 /* Self */ : 0) |
3585
+ (dep.skipSelf ? 4 /* SkipSelf */ : 0) | (dep.host ? 1 /* Host */ : 0) |
3586
+ (dep.optional ? 8 /* Optional */ : 0) |
3587
+ (target === FactoryTarget$1.Pipe ? 16 /* ForPipe */ : 0);
3588
+ // If this dependency is optional or otherwise has non-default flags, then additional
3589
+ // parameters describing how to inject the dependency must be passed to the inject function
3590
+ // that's being used.
3591
+ let flagsParam = (flags !== 0 /* Default */ || dep.optional) ? literal$1(flags) : null;
3592
+ // Build up the arguments to the injectFn call.
3593
+ const injectArgs = [dep.token];
3594
+ if (flagsParam) {
3595
+ injectArgs.push(flagsParam);
3596
+ }
3597
+ const injectFn = getInjectFn(target);
3598
+ return importExpr(injectFn).callFn(injectArgs);
3840
3599
  }
3841
3600
  else {
3842
- elOrTpl.attributes.forEach(a => {
3843
- if (!isI18nAttribute(a.name)) {
3844
- attributesMap[a.name] = a.value;
3845
- }
3846
- });
3847
- elOrTpl.inputs.forEach(i => {
3848
- attributesMap[i.name] = '';
3849
- });
3850
- elOrTpl.outputs.forEach(o => {
3851
- attributesMap[o.name] = '';
3852
- });
3601
+ // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()`
3602
+ // type dependency. For the generated JS we still want to use the `dep.token` value in case the
3603
+ // name given for the attribute is not a string literal. For example given `@Attribute(foo())`,
3604
+ // we want to generate `ɵɵinjectAttribute(foo())`.
3605
+ //
3606
+ // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate
3607
+ // typings.
3608
+ return importExpr(Identifiers$1.injectAttribute).callFn([dep.token]);
3853
3609
  }
3854
- return attributesMap;
3855
3610
  }
3856
- /** Returns a call expression to a chained instruction, e.g. `property(params[0])(params[1])`. */
3857
- function chainedInstruction(reference, calls, span) {
3858
- let expression = importExpr(reference, null, span);
3859
- if (calls.length > 0) {
3860
- for (let i = 0; i < calls.length; i++) {
3861
- expression = expression.callFn(calls[i], span);
3611
+ function createCtorDepsType(deps) {
3612
+ let hasTypes = false;
3613
+ const attributeTypes = deps.map(dep => {
3614
+ const type = createCtorDepType(dep);
3615
+ if (type !== null) {
3616
+ hasTypes = true;
3617
+ return type;
3618
+ }
3619
+ else {
3620
+ return literal$1(null);
3862
3621
  }
3622
+ });
3623
+ if (hasTypes) {
3624
+ return expressionType(literalArr(attributeTypes));
3863
3625
  }
3864
3626
  else {
3865
- // Add a blank invocation, in case the `calls` array is empty.
3866
- expression = expression.callFn([], span);
3627
+ return NONE_TYPE;
3867
3628
  }
3868
- return expression;
3869
3629
  }
3870
- /**
3871
- * Gets the number of arguments expected to be passed to a generated instruction in the case of
3872
- * interpolation instructions.
3873
- * @param interpolation An interpolation ast
3874
- */
3875
- function getInterpolationArgsLength(interpolation) {
3876
- const { expressions, strings } = interpolation;
3877
- if (expressions.length === 1 && strings.length === 2 && strings[0] === '' && strings[1] === '') {
3878
- // If the interpolation has one interpolated value, but the prefix and suffix are both empty
3879
- // strings, we only pass one argument, to a special instruction like `propertyInterpolate` or
3880
- // `textInterpolate`.
3881
- return 1;
3630
+ function createCtorDepType(dep) {
3631
+ const entries = [];
3632
+ if (dep.attributeNameType !== null) {
3633
+ entries.push({ key: 'attribute', value: dep.attributeNameType, quoted: false });
3882
3634
  }
3883
- else {
3884
- return expressions.length + strings.length;
3635
+ if (dep.optional) {
3636
+ entries.push({ key: 'optional', value: literal$1(true), quoted: false });
3637
+ }
3638
+ if (dep.host) {
3639
+ entries.push({ key: 'host', value: literal$1(true), quoted: false });
3640
+ }
3641
+ if (dep.self) {
3642
+ entries.push({ key: 'self', value: literal$1(true), quoted: false });
3643
+ }
3644
+ if (dep.skipSelf) {
3645
+ entries.push({ key: 'skipSelf', value: literal$1(true), quoted: false });
3646
+ }
3647
+ return entries.length > 0 ? literalMap(entries) : null;
3648
+ }
3649
+ function isDelegatedFactoryMetadata(meta) {
3650
+ return meta.delegateType !== undefined;
3651
+ }
3652
+ function isExpressionFactoryMetadata(meta) {
3653
+ return meta.expression !== undefined;
3654
+ }
3655
+ function getInjectFn(target) {
3656
+ switch (target) {
3657
+ case FactoryTarget$1.Component:
3658
+ case FactoryTarget$1.Directive:
3659
+ case FactoryTarget$1.Pipe:
3660
+ return Identifiers$1.directiveInject;
3661
+ case FactoryTarget$1.NgModule:
3662
+ case FactoryTarget$1.Injectable:
3663
+ default:
3664
+ return Identifiers$1.inject;
3885
3665
  }
3886
3666
  }
3887
3667
 
@@ -3893,232 +3673,228 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
3893
3673
  * found in the LICENSE file at https://angular.io/license
3894
3674
  */
3895
3675
  /**
3896
- * Creates an array literal expression from the given array, mapping all values to an expression
3897
- * using the provided mapping function. If the array is empty or null, then null is returned.
3898
- *
3899
- * @param values The array to transfer into literal array expression.
3900
- * @param mapper The logic to use for creating an expression for the array's values.
3901
- * @returns An array literal expression representing `values`, or null if `values` is empty or
3902
- * is itself null.
3676
+ * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently
3677
+ * require the implementation of a visitor for Comments as they are only collected at
3678
+ * the top-level of the R3 AST, and only if `Render3ParseOptions['collectCommentNodes']`
3679
+ * is true.
3903
3680
  */
3904
- function toOptionalLiteralArray(values, mapper) {
3905
- if (values === null || values.length === 0) {
3906
- return null;
3681
+ class Comment$1 {
3682
+ constructor(value, sourceSpan) {
3683
+ this.value = value;
3684
+ this.sourceSpan = sourceSpan;
3685
+ }
3686
+ visit(_visitor) {
3687
+ throw new Error('visit() not implemented for Comment');
3688
+ }
3689
+ }
3690
+ class Text$2 {
3691
+ constructor(value, sourceSpan) {
3692
+ this.value = value;
3693
+ this.sourceSpan = sourceSpan;
3694
+ }
3695
+ visit(visitor) {
3696
+ return visitor.visitText(this);
3697
+ }
3698
+ }
3699
+ class BoundText {
3700
+ constructor(value, sourceSpan, i18n) {
3701
+ this.value = value;
3702
+ this.sourceSpan = sourceSpan;
3703
+ this.i18n = i18n;
3704
+ }
3705
+ visit(visitor) {
3706
+ return visitor.visitBoundText(this);
3907
3707
  }
3908
- return literalArr(values.map(value => mapper(value)));
3909
3708
  }
3910
3709
  /**
3911
- * Creates an object literal expression from the given object, mapping all values to an expression
3912
- * using the provided mapping function. If the object has no keys, then null is returned.
3710
+ * Represents a text attribute in the template.
3913
3711
  *
3914
- * @param object The object to transfer into an object literal expression.
3915
- * @param mapper The logic to use for creating an expression for the object's values.
3916
- * @returns An object literal expression representing `object`, or null if `object` does not have
3917
- * any keys.
3712
+ * `valueSpan` may not be present in cases where there is no value `<div a></div>`.
3713
+ * `keySpan` may also not be present for synthetic attributes from ICU expansions.
3918
3714
  */
3919
- function toOptionalLiteralMap(object, mapper) {
3920
- const entries = Object.keys(object).map(key => {
3921
- const value = object[key];
3922
- return { key, value: mapper(value), quoted: true };
3923
- });
3924
- if (entries.length > 0) {
3925
- return literalMap(entries);
3715
+ class TextAttribute {
3716
+ constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
3717
+ this.name = name;
3718
+ this.value = value;
3719
+ this.sourceSpan = sourceSpan;
3720
+ this.keySpan = keySpan;
3721
+ this.valueSpan = valueSpan;
3722
+ this.i18n = i18n;
3926
3723
  }
3927
- else {
3928
- return null;
3724
+ visit(visitor) {
3725
+ return visitor.visitTextAttribute(this);
3929
3726
  }
3930
3727
  }
3931
- function compileDependencies(deps) {
3932
- if (deps === 'invalid') {
3933
- // The `deps` can be set to the string "invalid" by the `unwrapConstructorDependencies()`
3934
- // function, which tries to convert `ConstructorDeps` into `R3DependencyMetadata[]`.
3935
- return literal$1('invalid');
3728
+ class BoundAttribute {
3729
+ constructor(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan, i18n) {
3730
+ this.name = name;
3731
+ this.type = type;
3732
+ this.securityContext = securityContext;
3733
+ this.value = value;
3734
+ this.unit = unit;
3735
+ this.sourceSpan = sourceSpan;
3736
+ this.keySpan = keySpan;
3737
+ this.valueSpan = valueSpan;
3738
+ this.i18n = i18n;
3936
3739
  }
3937
- else if (deps === null) {
3938
- return literal$1(null);
3740
+ static fromBoundElementProperty(prop, i18n) {
3741
+ if (prop.keySpan === undefined) {
3742
+ throw new Error(`Unexpected state: keySpan must be defined for bound attributes but was not for ${prop.name}: ${prop.sourceSpan}`);
3743
+ }
3744
+ return new BoundAttribute(prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n);
3939
3745
  }
3940
- else {
3941
- return literalArr(deps.map(compileDependency));
3746
+ visit(visitor) {
3747
+ return visitor.visitBoundAttribute(this);
3942
3748
  }
3943
3749
  }
3944
- function compileDependency(dep) {
3945
- const depMeta = new DefinitionMap();
3946
- depMeta.set('token', dep.token);
3947
- if (dep.attributeNameType !== null) {
3948
- depMeta.set('attribute', literal$1(true));
3750
+ class BoundEvent {
3751
+ constructor(name, type, handler, target, phase, sourceSpan, handlerSpan, keySpan) {
3752
+ this.name = name;
3753
+ this.type = type;
3754
+ this.handler = handler;
3755
+ this.target = target;
3756
+ this.phase = phase;
3757
+ this.sourceSpan = sourceSpan;
3758
+ this.handlerSpan = handlerSpan;
3759
+ this.keySpan = keySpan;
3949
3760
  }
3950
- if (dep.host) {
3951
- depMeta.set('host', literal$1(true));
3761
+ static fromParsedEvent(event) {
3762
+ const target = event.type === 0 /* Regular */ ? event.targetOrPhase : null;
3763
+ const phase = event.type === 1 /* Animation */ ? event.targetOrPhase : null;
3764
+ if (event.keySpan === undefined) {
3765
+ throw new Error(`Unexpected state: keySpan must be defined for bound event but was not for ${event.name}: ${event.sourceSpan}`);
3766
+ }
3767
+ return new BoundEvent(event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan, event.keySpan);
3952
3768
  }
3953
- if (dep.optional) {
3954
- depMeta.set('optional', literal$1(true));
3769
+ visit(visitor) {
3770
+ return visitor.visitBoundEvent(this);
3955
3771
  }
3956
- if (dep.self) {
3957
- depMeta.set('self', literal$1(true));
3772
+ }
3773
+ class Element$1 {
3774
+ constructor(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3775
+ this.name = name;
3776
+ this.attributes = attributes;
3777
+ this.inputs = inputs;
3778
+ this.outputs = outputs;
3779
+ this.children = children;
3780
+ this.references = references;
3781
+ this.sourceSpan = sourceSpan;
3782
+ this.startSourceSpan = startSourceSpan;
3783
+ this.endSourceSpan = endSourceSpan;
3784
+ this.i18n = i18n;
3958
3785
  }
3959
- if (dep.skipSelf) {
3960
- depMeta.set('skipSelf', literal$1(true));
3786
+ visit(visitor) {
3787
+ return visitor.visitElement(this);
3961
3788
  }
3962
- return depMeta.toLiteralMap();
3963
3789
  }
3964
- /**
3965
- * Generate an expression that has the given `expr` wrapped in the following form:
3966
- *
3967
- * ```
3968
- * forwardRef(() => expr)
3969
- * ```
3970
- */
3971
- function generateForwardRef(expr) {
3972
- return importExpr(Identifiers$1.forwardRef).callFn([fn([], [new ReturnStatement(expr)])]);
3790
+ class Template {
3791
+ constructor(tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3792
+ this.tagName = tagName;
3793
+ this.attributes = attributes;
3794
+ this.inputs = inputs;
3795
+ this.outputs = outputs;
3796
+ this.templateAttrs = templateAttrs;
3797
+ this.children = children;
3798
+ this.references = references;
3799
+ this.variables = variables;
3800
+ this.sourceSpan = sourceSpan;
3801
+ this.startSourceSpan = startSourceSpan;
3802
+ this.endSourceSpan = endSourceSpan;
3803
+ this.i18n = i18n;
3804
+ }
3805
+ visit(visitor) {
3806
+ return visitor.visitTemplate(this);
3807
+ }
3973
3808
  }
3974
-
3975
- /**
3976
- * @license
3977
- * Copyright Google LLC All Rights Reserved.
3978
- *
3979
- * Use of this source code is governed by an MIT-style license that can be
3980
- * found in the LICENSE file at https://angular.io/license
3981
- */
3982
- // https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
3983
- const VERSION = 3;
3984
- const JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,';
3985
- class SourceMapGenerator {
3986
- constructor(file = null) {
3987
- this.file = file;
3988
- this.sourcesContent = new Map();
3989
- this.lines = [];
3990
- this.lastCol0 = 0;
3991
- this.hasMappings = false;
3809
+ class Content {
3810
+ constructor(selector, attributes, sourceSpan, i18n) {
3811
+ this.selector = selector;
3812
+ this.attributes = attributes;
3813
+ this.sourceSpan = sourceSpan;
3814
+ this.i18n = i18n;
3815
+ this.name = 'ng-content';
3992
3816
  }
3993
- // The content is `null` when the content is expected to be loaded using the URL
3994
- addSource(url, content = null) {
3995
- if (!this.sourcesContent.has(url)) {
3996
- this.sourcesContent.set(url, content);
3997
- }
3998
- return this;
3817
+ visit(visitor) {
3818
+ return visitor.visitContent(this);
3999
3819
  }
4000
- addLine() {
4001
- this.lines.push([]);
4002
- this.lastCol0 = 0;
4003
- return this;
3820
+ }
3821
+ class Variable {
3822
+ constructor(name, value, sourceSpan, keySpan, valueSpan) {
3823
+ this.name = name;
3824
+ this.value = value;
3825
+ this.sourceSpan = sourceSpan;
3826
+ this.keySpan = keySpan;
3827
+ this.valueSpan = valueSpan;
4004
3828
  }
4005
- addMapping(col0, sourceUrl, sourceLine0, sourceCol0) {
4006
- if (!this.currentLine) {
4007
- throw new Error(`A line must be added before mappings can be added`);
4008
- }
4009
- if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) {
4010
- throw new Error(`Unknown source file "${sourceUrl}"`);
4011
- }
4012
- if (col0 == null) {
4013
- throw new Error(`The column in the generated code must be provided`);
4014
- }
4015
- if (col0 < this.lastCol0) {
4016
- throw new Error(`Mapping should be added in output order`);
4017
- }
4018
- if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) {
4019
- throw new Error(`The source location must be provided when a source url is provided`);
4020
- }
4021
- this.hasMappings = true;
4022
- this.lastCol0 = col0;
4023
- this.currentLine.push({ col0, sourceUrl, sourceLine0, sourceCol0 });
4024
- return this;
3829
+ visit(visitor) {
3830
+ return visitor.visitVariable(this);
4025
3831
  }
4026
- /**
4027
- * @internal strip this from published d.ts files due to
4028
- * https://github.com/microsoft/TypeScript/issues/36216
4029
- */
4030
- get currentLine() {
4031
- return this.lines.slice(-1)[0];
3832
+ }
3833
+ class Reference$1 {
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;
4032
3840
  }
4033
- toJSON() {
4034
- if (!this.hasMappings) {
4035
- return null;
4036
- }
4037
- const sourcesIndex = new Map();
4038
- const sources = [];
4039
- const sourcesContent = [];
4040
- Array.from(this.sourcesContent.keys()).forEach((url, i) => {
4041
- sourcesIndex.set(url, i);
4042
- sources.push(url);
4043
- sourcesContent.push(this.sourcesContent.get(url) || null);
4044
- });
4045
- let mappings = '';
4046
- let lastCol0 = 0;
4047
- let lastSourceIndex = 0;
4048
- let lastSourceLine0 = 0;
4049
- let lastSourceCol0 = 0;
4050
- this.lines.forEach(segments => {
4051
- lastCol0 = 0;
4052
- mappings += segments
4053
- .map(segment => {
4054
- // zero-based starting column of the line in the generated code
4055
- let segAsStr = toBase64VLQ(segment.col0 - lastCol0);
4056
- lastCol0 = segment.col0;
4057
- if (segment.sourceUrl != null) {
4058
- // zero-based index into the “sources” list
4059
- segAsStr +=
4060
- toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex);
4061
- lastSourceIndex = sourcesIndex.get(segment.sourceUrl);
4062
- // the zero-based starting line in the original source
4063
- segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0);
4064
- lastSourceLine0 = segment.sourceLine0;
4065
- // the zero-based starting column in the original source
4066
- segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0);
4067
- lastSourceCol0 = segment.sourceCol0;
4068
- }
4069
- return segAsStr;
4070
- })
4071
- .join(',');
4072
- mappings += ';';
4073
- });
4074
- mappings = mappings.slice(0, -1);
4075
- return {
4076
- 'file': this.file || '',
4077
- 'version': VERSION,
4078
- 'sourceRoot': '',
4079
- 'sources': sources,
4080
- 'sourcesContent': sourcesContent,
4081
- 'mappings': mappings,
4082
- };
3841
+ visit(visitor) {
3842
+ return visitor.visitReference(this);
4083
3843
  }
4084
- toJsComment() {
4085
- return this.hasMappings ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0)) :
4086
- '';
3844
+ }
3845
+ class Icu$1 {
3846
+ constructor(vars, placeholders, sourceSpan, i18n) {
3847
+ this.vars = vars;
3848
+ this.placeholders = placeholders;
3849
+ this.sourceSpan = sourceSpan;
3850
+ this.i18n = i18n;
3851
+ }
3852
+ visit(visitor) {
3853
+ return visitor.visitIcu(this);
4087
3854
  }
4088
3855
  }
4089
- function toBase64String(value) {
4090
- let b64 = '';
4091
- const encoded = utf8Encode(value);
4092
- for (let i = 0; i < encoded.length;) {
4093
- const i1 = encoded[i++];
4094
- const i2 = i < encoded.length ? encoded[i++] : null;
4095
- const i3 = i < encoded.length ? encoded[i++] : null;
4096
- b64 += toBase64Digit(i1 >> 2);
4097
- b64 += toBase64Digit(((i1 & 3) << 4) | (i2 === null ? 0 : i2 >> 4));
4098
- b64 += i2 === null ? '=' : toBase64Digit(((i2 & 15) << 2) | (i3 === null ? 0 : i3 >> 6));
4099
- b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63);
3856
+ class RecursiveVisitor {
3857
+ visitElement(element) {
3858
+ visitAll$1(this, element.attributes);
3859
+ visitAll$1(this, element.inputs);
3860
+ visitAll$1(this, element.outputs);
3861
+ visitAll$1(this, element.children);
3862
+ visitAll$1(this, element.references);
4100
3863
  }
4101
- return b64;
3864
+ visitTemplate(template) {
3865
+ visitAll$1(this, template.attributes);
3866
+ visitAll$1(this, template.inputs);
3867
+ visitAll$1(this, template.outputs);
3868
+ visitAll$1(this, template.children);
3869
+ visitAll$1(this, template.references);
3870
+ visitAll$1(this, template.variables);
3871
+ }
3872
+ visitContent(content) { }
3873
+ visitVariable(variable) { }
3874
+ visitReference(reference) { }
3875
+ visitTextAttribute(attribute) { }
3876
+ visitBoundAttribute(attribute) { }
3877
+ visitBoundEvent(attribute) { }
3878
+ visitText(text) { }
3879
+ visitBoundText(text) { }
3880
+ visitIcu(icu) { }
4102
3881
  }
4103
- function toBase64VLQ(value) {
4104
- value = value < 0 ? ((-value) << 1) + 1 : value << 1;
4105
- let out = '';
4106
- do {
4107
- let digit = value & 31;
4108
- value = value >> 5;
4109
- if (value > 0) {
4110
- digit = digit | 32;
3882
+ function visitAll$1(visitor, nodes) {
3883
+ const result = [];
3884
+ if (visitor.visit) {
3885
+ for (const node of nodes) {
3886
+ visitor.visit(node) || node.visit(visitor);
4111
3887
  }
4112
- out += toBase64Digit(digit);
4113
- } while (value > 0);
4114
- return out;
4115
- }
4116
- const B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
4117
- function toBase64Digit(value) {
4118
- if (value < 0 || value >= 64) {
4119
- throw new Error(`Can only encode value in the range [0, 63]`);
4120
3888
  }
4121
- return B64_DIGITS[value];
3889
+ else {
3890
+ for (const node of nodes) {
3891
+ const newNode = node.visit(visitor);
3892
+ if (newNode) {
3893
+ result.push(newNode);
3894
+ }
3895
+ }
3896
+ }
3897
+ return result;
4122
3898
  }
4123
3899
 
4124
3900
  /**
@@ -4128,551 +3904,602 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4128
3904
  * Use of this source code is governed by an MIT-style license that can be
4129
3905
  * found in the LICENSE file at https://angular.io/license
4130
3906
  */
4131
- const _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
4132
- const _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
4133
- const _INDENT_WITH = ' ';
4134
- const CATCH_ERROR_VAR = variable('error', null, null);
4135
- const CATCH_STACK_VAR = variable('stack', null, null);
4136
- class _EmittedLine {
4137
- constructor(indent) {
4138
- this.indent = indent;
4139
- this.partsLength = 0;
4140
- this.parts = [];
4141
- this.srcSpans = [];
4142
- }
4143
- }
4144
- class EmitterVisitorContext {
4145
- constructor(_indent) {
4146
- this._indent = _indent;
4147
- this._classes = [];
4148
- this._preambleLineCount = 0;
4149
- this._lines = [new _EmittedLine(_indent)];
4150
- }
4151
- static createRoot() {
4152
- return new EmitterVisitorContext(0);
4153
- }
3907
+ class Message {
4154
3908
  /**
4155
- * @internal strip this from published d.ts files due to
4156
- * https://github.com/microsoft/TypeScript/issues/36216
3909
+ * @param nodes message AST
3910
+ * @param placeholders maps placeholder names to static content and their source spans
3911
+ * @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
3912
+ * @param meaning
3913
+ * @param description
3914
+ * @param customId
4157
3915
  */
4158
- get _currentLine() {
4159
- return this._lines[this._lines.length - 1];
3916
+ constructor(nodes, placeholders, placeholderToMessage, meaning, description, customId) {
3917
+ this.nodes = nodes;
3918
+ this.placeholders = placeholders;
3919
+ this.placeholderToMessage = placeholderToMessage;
3920
+ this.meaning = meaning;
3921
+ this.description = description;
3922
+ this.customId = customId;
3923
+ this.id = this.customId;
3924
+ /** The ids to use if there are no custom id and if `i18nLegacyMessageIdFormat` is not empty */
3925
+ this.legacyIds = [];
3926
+ if (nodes.length) {
3927
+ this.sources = [{
3928
+ filePath: nodes[0].sourceSpan.start.file.url,
3929
+ startLine: nodes[0].sourceSpan.start.line + 1,
3930
+ startCol: nodes[0].sourceSpan.start.col + 1,
3931
+ endLine: nodes[nodes.length - 1].sourceSpan.end.line + 1,
3932
+ endCol: nodes[0].sourceSpan.start.col + 1
3933
+ }];
3934
+ }
3935
+ else {
3936
+ this.sources = [];
3937
+ }
4160
3938
  }
4161
- println(from, lastPart = '') {
4162
- this.print(from || null, lastPart, true);
3939
+ }
3940
+ class Text$1 {
3941
+ constructor(value, sourceSpan) {
3942
+ this.value = value;
3943
+ this.sourceSpan = sourceSpan;
4163
3944
  }
4164
- lineIsEmpty() {
4165
- return this._currentLine.parts.length === 0;
3945
+ visit(visitor, context) {
3946
+ return visitor.visitText(this, context);
4166
3947
  }
4167
- lineLength() {
4168
- return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;
3948
+ }
3949
+ // TODO(vicb): do we really need this node (vs an array) ?
3950
+ class Container {
3951
+ constructor(children, sourceSpan) {
3952
+ this.children = children;
3953
+ this.sourceSpan = sourceSpan;
4169
3954
  }
4170
- print(from, part, newLine = false) {
4171
- if (part.length > 0) {
4172
- this._currentLine.parts.push(part);
4173
- this._currentLine.partsLength += part.length;
4174
- this._currentLine.srcSpans.push(from && from.sourceSpan || null);
4175
- }
4176
- if (newLine) {
4177
- this._lines.push(new _EmittedLine(this._indent));
4178
- }
3955
+ visit(visitor, context) {
3956
+ return visitor.visitContainer(this, context);
4179
3957
  }
4180
- removeEmptyLastLine() {
4181
- if (this.lineIsEmpty()) {
4182
- this._lines.pop();
4183
- }
3958
+ }
3959
+ class Icu {
3960
+ constructor(expression, type, cases, sourceSpan) {
3961
+ this.expression = expression;
3962
+ this.type = type;
3963
+ this.cases = cases;
3964
+ this.sourceSpan = sourceSpan;
4184
3965
  }
4185
- incIndent() {
4186
- this._indent++;
4187
- if (this.lineIsEmpty()) {
4188
- this._currentLine.indent = this._indent;
4189
- }
3966
+ visit(visitor, context) {
3967
+ return visitor.visitIcu(this, context);
4190
3968
  }
4191
- decIndent() {
4192
- this._indent--;
4193
- if (this.lineIsEmpty()) {
4194
- this._currentLine.indent = this._indent;
4195
- }
3969
+ }
3970
+ class TagPlaceholder {
3971
+ constructor(tag, attrs, startName, closeName, children, isVoid,
3972
+ // TODO sourceSpan should cover all (we need a startSourceSpan and endSourceSpan)
3973
+ sourceSpan, startSourceSpan, endSourceSpan) {
3974
+ this.tag = tag;
3975
+ this.attrs = attrs;
3976
+ this.startName = startName;
3977
+ this.closeName = closeName;
3978
+ this.children = children;
3979
+ this.isVoid = isVoid;
3980
+ this.sourceSpan = sourceSpan;
3981
+ this.startSourceSpan = startSourceSpan;
3982
+ this.endSourceSpan = endSourceSpan;
4196
3983
  }
4197
- pushClass(clazz) {
4198
- this._classes.push(clazz);
3984
+ visit(visitor, context) {
3985
+ return visitor.visitTagPlaceholder(this, context);
4199
3986
  }
4200
- popClass() {
4201
- return this._classes.pop();
3987
+ }
3988
+ class Placeholder {
3989
+ constructor(value, name, sourceSpan) {
3990
+ this.value = value;
3991
+ this.name = name;
3992
+ this.sourceSpan = sourceSpan;
4202
3993
  }
4203
- get currentClass() {
4204
- return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null;
3994
+ visit(visitor, context) {
3995
+ return visitor.visitPlaceholder(this, context);
4205
3996
  }
4206
- toSource() {
4207
- return this.sourceLines
4208
- .map(l => l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : '')
4209
- .join('\n');
3997
+ }
3998
+ class IcuPlaceholder {
3999
+ constructor(value, name, sourceSpan) {
4000
+ this.value = value;
4001
+ this.name = name;
4002
+ this.sourceSpan = sourceSpan;
4210
4003
  }
4211
- toSourceMapGenerator(genFilePath, startsAtLine = 0) {
4212
- const map = new SourceMapGenerator(genFilePath);
4213
- let firstOffsetMapped = false;
4214
- const mapFirstOffsetIfNeeded = () => {
4215
- if (!firstOffsetMapped) {
4216
- // Add a single space so that tools won't try to load the file from disk.
4217
- // Note: We are using virtual urls like `ng:///`, so we have to
4218
- // provide a content here.
4219
- map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);
4220
- firstOffsetMapped = true;
4221
- }
4222
- };
4223
- for (let i = 0; i < startsAtLine; i++) {
4224
- map.addLine();
4225
- mapFirstOffsetIfNeeded();
4226
- }
4227
- this.sourceLines.forEach((line, lineIdx) => {
4228
- map.addLine();
4229
- const spans = line.srcSpans;
4230
- const parts = line.parts;
4231
- let col0 = line.indent * _INDENT_WITH.length;
4232
- let spanIdx = 0;
4233
- // skip leading parts without source spans
4234
- while (spanIdx < spans.length && !spans[spanIdx]) {
4235
- col0 += parts[spanIdx].length;
4236
- spanIdx++;
4237
- }
4238
- if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {
4239
- firstOffsetMapped = true;
4240
- }
4241
- else {
4242
- mapFirstOffsetIfNeeded();
4243
- }
4244
- while (spanIdx < spans.length) {
4245
- const span = spans[spanIdx];
4246
- const source = span.start.file;
4247
- const sourceLine = span.start.line;
4248
- const sourceCol = span.start.col;
4249
- map.addSource(source.url, source.content)
4250
- .addMapping(col0, source.url, sourceLine, sourceCol);
4251
- col0 += parts[spanIdx].length;
4252
- spanIdx++;
4253
- // assign parts without span or the same span to the previous segment
4254
- while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) {
4255
- col0 += parts[spanIdx].length;
4256
- spanIdx++;
4257
- }
4258
- }
4259
- });
4260
- return map;
4004
+ visit(visitor, context) {
4005
+ return visitor.visitIcuPlaceholder(this, context);
4261
4006
  }
4262
- setPreambleLineCount(count) {
4263
- return this._preambleLineCount = count;
4007
+ }
4008
+
4009
+ /**
4010
+ * @license
4011
+ * Copyright Google LLC All Rights Reserved.
4012
+ *
4013
+ * Use of this source code is governed by an MIT-style license that can be
4014
+ * found in the LICENSE file at https://angular.io/license
4015
+ */
4016
+ /**
4017
+ * Represents a big integer using a buffer of its individual digits, with the least significant
4018
+ * digit stored at the beginning of the array (little endian).
4019
+ *
4020
+ * For performance reasons, each instance is mutable. The addition operation can be done in-place
4021
+ * to reduce memory pressure of allocation for the digits array.
4022
+ */
4023
+ class BigInteger {
4024
+ /**
4025
+ * Creates a big integer using its individual digits in little endian storage.
4026
+ */
4027
+ constructor(digits) {
4028
+ this.digits = digits;
4264
4029
  }
4265
- spanOf(line, column) {
4266
- const emittedLine = this._lines[line - this._preambleLineCount];
4267
- if (emittedLine) {
4268
- let columnsLeft = column - _createIndent(emittedLine.indent).length;
4269
- for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {
4270
- const part = emittedLine.parts[partIndex];
4271
- if (part.length > columnsLeft) {
4272
- return emittedLine.srcSpans[partIndex];
4273
- }
4274
- columnsLeft -= part.length;
4275
- }
4276
- }
4277
- return null;
4030
+ static zero() {
4031
+ return new BigInteger([0]);
4032
+ }
4033
+ static one() {
4034
+ return new BigInteger([1]);
4278
4035
  }
4279
4036
  /**
4280
- * @internal strip this from published d.ts files due to
4281
- * https://github.com/microsoft/TypeScript/issues/36216
4037
+ * Creates a clone of this instance.
4282
4038
  */
4283
- get sourceLines() {
4284
- if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {
4285
- return this._lines.slice(0, -1);
4286
- }
4287
- return this._lines;
4039
+ clone() {
4040
+ return new BigInteger(this.digits.slice());
4288
4041
  }
4289
- }
4290
- class AbstractEmitterVisitor {
4291
- constructor(_escapeDollarInStrings) {
4292
- this._escapeDollarInStrings = _escapeDollarInStrings;
4042
+ /**
4043
+ * Returns a new big integer with the sum of `this` and `other` as its value. This does not mutate
4044
+ * `this` but instead returns a new instance, unlike `addToSelf`.
4045
+ */
4046
+ add(other) {
4047
+ const result = this.clone();
4048
+ result.addToSelf(other);
4049
+ return result;
4293
4050
  }
4294
- printLeadingComments(stmt, ctx) {
4295
- if (stmt.leadingComments === undefined) {
4296
- return;
4297
- }
4298
- for (const comment of stmt.leadingComments) {
4299
- if (comment instanceof JSDocComment) {
4300
- ctx.print(stmt, `/*${comment.toString()}*/`, comment.trailingNewline);
4051
+ /**
4052
+ * Adds `other` to the instance itself, thereby mutating its value.
4053
+ */
4054
+ addToSelf(other) {
4055
+ const maxNrOfDigits = Math.max(this.digits.length, other.digits.length);
4056
+ let carry = 0;
4057
+ for (let i = 0; i < maxNrOfDigits; i++) {
4058
+ let digitSum = carry;
4059
+ if (i < this.digits.length) {
4060
+ digitSum += this.digits[i];
4301
4061
  }
4302
- else {
4303
- if (comment.multiline) {
4304
- ctx.print(stmt, `/* ${comment.text} */`, comment.trailingNewline);
4305
- }
4306
- else {
4307
- comment.text.split('\n').forEach((line) => {
4308
- ctx.println(stmt, `// ${line}`);
4309
- });
4310
- }
4062
+ if (i < other.digits.length) {
4063
+ digitSum += other.digits[i];
4311
4064
  }
4312
- }
4313
- }
4314
- visitExpressionStmt(stmt, ctx) {
4315
- this.printLeadingComments(stmt, ctx);
4316
- stmt.expr.visitExpression(this, ctx);
4317
- ctx.println(stmt, ';');
4318
- return null;
4319
- }
4320
- visitReturnStmt(stmt, ctx) {
4321
- this.printLeadingComments(stmt, ctx);
4322
- ctx.print(stmt, `return `);
4323
- stmt.value.visitExpression(this, ctx);
4324
- ctx.println(stmt, ';');
4325
- return null;
4326
- }
4327
- visitIfStmt(stmt, ctx) {
4328
- this.printLeadingComments(stmt, ctx);
4329
- ctx.print(stmt, `if (`);
4330
- stmt.condition.visitExpression(this, ctx);
4331
- ctx.print(stmt, `) {`);
4332
- const hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0;
4333
- if (stmt.trueCase.length <= 1 && !hasElseCase) {
4334
- ctx.print(stmt, ` `);
4335
- this.visitAllStatements(stmt.trueCase, ctx);
4336
- ctx.removeEmptyLastLine();
4337
- ctx.print(stmt, ` `);
4338
- }
4339
- else {
4340
- ctx.println();
4341
- ctx.incIndent();
4342
- this.visitAllStatements(stmt.trueCase, ctx);
4343
- ctx.decIndent();
4344
- if (hasElseCase) {
4345
- ctx.println(stmt, `} else {`);
4346
- ctx.incIndent();
4347
- this.visitAllStatements(stmt.falseCase, ctx);
4348
- ctx.decIndent();
4065
+ if (digitSum >= 10) {
4066
+ this.digits[i] = digitSum - 10;
4067
+ carry = 1;
4068
+ }
4069
+ else {
4070
+ this.digits[i] = digitSum;
4071
+ carry = 0;
4349
4072
  }
4350
4073
  }
4351
- ctx.println(stmt, `}`);
4352
- return null;
4353
- }
4354
- visitThrowStmt(stmt, ctx) {
4355
- this.printLeadingComments(stmt, ctx);
4356
- ctx.print(stmt, `throw `);
4357
- stmt.error.visitExpression(this, ctx);
4358
- ctx.println(stmt, `;`);
4359
- return null;
4360
- }
4361
- visitWriteVarExpr(expr, ctx) {
4362
- const lineWasEmpty = ctx.lineIsEmpty();
4363
- if (!lineWasEmpty) {
4364
- ctx.print(expr, '(');
4365
- }
4366
- ctx.print(expr, `${expr.name} = `);
4367
- expr.value.visitExpression(this, ctx);
4368
- if (!lineWasEmpty) {
4369
- ctx.print(expr, ')');
4370
- }
4371
- return null;
4372
- }
4373
- visitWriteKeyExpr(expr, ctx) {
4374
- const lineWasEmpty = ctx.lineIsEmpty();
4375
- if (!lineWasEmpty) {
4376
- ctx.print(expr, '(');
4377
- }
4378
- expr.receiver.visitExpression(this, ctx);
4379
- ctx.print(expr, `[`);
4380
- expr.index.visitExpression(this, ctx);
4381
- ctx.print(expr, `] = `);
4382
- expr.value.visitExpression(this, ctx);
4383
- if (!lineWasEmpty) {
4384
- ctx.print(expr, ')');
4074
+ // Apply a remaining carry if needed.
4075
+ if (carry > 0) {
4076
+ this.digits[maxNrOfDigits] = 1;
4385
4077
  }
4386
- return null;
4387
4078
  }
4388
- visitWritePropExpr(expr, ctx) {
4389
- const lineWasEmpty = ctx.lineIsEmpty();
4390
- if (!lineWasEmpty) {
4391
- ctx.print(expr, '(');
4392
- }
4393
- expr.receiver.visitExpression(this, ctx);
4394
- ctx.print(expr, `.${expr.name} = `);
4395
- expr.value.visitExpression(this, ctx);
4396
- if (!lineWasEmpty) {
4397
- ctx.print(expr, ')');
4079
+ /**
4080
+ * Builds the decimal string representation of the big integer. As this is stored in
4081
+ * little endian, the digits are concatenated in reverse order.
4082
+ */
4083
+ toString() {
4084
+ let res = '';
4085
+ for (let i = this.digits.length - 1; i >= 0; i--) {
4086
+ res += this.digits[i];
4398
4087
  }
4399
- return null;
4400
- }
4401
- visitInvokeFunctionExpr(expr, ctx) {
4402
- expr.fn.visitExpression(this, ctx);
4403
- ctx.print(expr, `(`);
4404
- this.visitAllExpressions(expr.args, ctx, ',');
4405
- ctx.print(expr, `)`);
4406
- return null;
4088
+ return res;
4407
4089
  }
4408
- visitTaggedTemplateExpr(expr, ctx) {
4409
- expr.tag.visitExpression(this, ctx);
4410
- ctx.print(expr, '`' + expr.template.elements[0].rawText);
4411
- for (let i = 1; i < expr.template.elements.length; i++) {
4412
- ctx.print(expr, '${');
4413
- expr.template.expressions[i - 1].visitExpression(this, ctx);
4414
- ctx.print(expr, `}${expr.template.elements[i].rawText}`);
4415
- }
4416
- ctx.print(expr, '`');
4417
- return null;
4090
+ }
4091
+ /**
4092
+ * Represents a big integer which is optimized for multiplication operations, as its power-of-twos
4093
+ * are memoized. See `multiplyBy()` for details on the multiplication algorithm.
4094
+ */
4095
+ class BigIntForMultiplication {
4096
+ constructor(value) {
4097
+ this.powerOfTwos = [value];
4418
4098
  }
4419
- visitWrappedNodeExpr(ast, ctx) {
4420
- throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');
4099
+ /**
4100
+ * Returns the big integer itself.
4101
+ */
4102
+ getValue() {
4103
+ return this.powerOfTwos[0];
4421
4104
  }
4422
- visitTypeofExpr(expr, ctx) {
4423
- ctx.print(expr, 'typeof ');
4424
- expr.expr.visitExpression(this, ctx);
4105
+ /**
4106
+ * Computes the value for `num * b`, where `num` is a JS number and `b` is a big integer. The
4107
+ * value for `b` is represented by a storage model that is optimized for this computation.
4108
+ *
4109
+ * This operation is implemented in N(log2(num)) by continuous halving of the number, where the
4110
+ * least-significant bit (LSB) is tested in each iteration. If the bit is set, the bit's index is
4111
+ * used as exponent into the power-of-two multiplication of `b`.
4112
+ *
4113
+ * As an example, consider the multiplication num=42, b=1337. In binary 42 is 0b00101010 and the
4114
+ * algorithm unrolls into the following iterations:
4115
+ *
4116
+ * Iteration | num | LSB | b * 2^iter | Add? | product
4117
+ * -----------|------------|------|------------|------|--------
4118
+ * 0 | 0b00101010 | 0 | 1337 | No | 0
4119
+ * 1 | 0b00010101 | 1 | 2674 | Yes | 2674
4120
+ * 2 | 0b00001010 | 0 | 5348 | No | 2674
4121
+ * 3 | 0b00000101 | 1 | 10696 | Yes | 13370
4122
+ * 4 | 0b00000010 | 0 | 21392 | No | 13370
4123
+ * 5 | 0b00000001 | 1 | 42784 | Yes | 56154
4124
+ * 6 | 0b00000000 | 0 | 85568 | No | 56154
4125
+ *
4126
+ * The computed product of 56154 is indeed the correct result.
4127
+ *
4128
+ * The `BigIntForMultiplication` representation for a big integer provides memoized access to the
4129
+ * power-of-two values to reduce the workload in computing those values.
4130
+ */
4131
+ multiplyBy(num) {
4132
+ const product = BigInteger.zero();
4133
+ this.multiplyByAndAddTo(num, product);
4134
+ return product;
4425
4135
  }
4426
- visitReadVarExpr(ast, ctx) {
4427
- let varName = ast.name;
4428
- if (ast.builtin != null) {
4429
- switch (ast.builtin) {
4430
- case BuiltinVar.Super:
4431
- varName = 'super';
4432
- break;
4433
- case BuiltinVar.This:
4434
- varName = 'this';
4435
- break;
4436
- case BuiltinVar.CatchError:
4437
- varName = CATCH_ERROR_VAR.name;
4438
- break;
4439
- case BuiltinVar.CatchStack:
4440
- varName = CATCH_STACK_VAR.name;
4441
- break;
4442
- default:
4443
- throw new Error(`Unknown builtin variable ${ast.builtin}`);
4136
+ /**
4137
+ * See `multiplyBy()` for details. This function allows for the computed product to be added
4138
+ * directly to the provided result big integer.
4139
+ */
4140
+ multiplyByAndAddTo(num, result) {
4141
+ for (let exponent = 0; num !== 0; num = num >>> 1, exponent++) {
4142
+ if (num & 1) {
4143
+ const value = this.getMultipliedByPowerOfTwo(exponent);
4144
+ result.addToSelf(value);
4444
4145
  }
4445
4146
  }
4446
- ctx.print(ast, varName);
4447
- return null;
4448
4147
  }
4449
- visitInstantiateExpr(ast, ctx) {
4450
- ctx.print(ast, `new `);
4451
- ast.classExpr.visitExpression(this, ctx);
4452
- ctx.print(ast, `(`);
4453
- this.visitAllExpressions(ast.args, ctx, ',');
4454
- ctx.print(ast, `)`);
4455
- return null;
4456
- }
4457
- visitLiteralExpr(ast, ctx) {
4458
- const value = ast.value;
4459
- if (typeof value === 'string') {
4460
- ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings));
4461
- }
4462
- else {
4463
- ctx.print(ast, `${value}`);
4464
- }
4465
- return null;
4466
- }
4467
- visitLocalizedString(ast, ctx) {
4468
- const head = ast.serializeI18nHead();
4469
- ctx.print(ast, '$localize `' + head.raw);
4470
- for (let i = 1; i < ast.messageParts.length; i++) {
4471
- ctx.print(ast, '${');
4472
- ast.expressions[i - 1].visitExpression(this, ctx);
4473
- ctx.print(ast, `}${ast.serializeI18nTemplatePart(i).raw}`);
4148
+ /**
4149
+ * Computes and memoizes the big integer value for `this.number * 2^exponent`.
4150
+ */
4151
+ getMultipliedByPowerOfTwo(exponent) {
4152
+ // Compute the powers up until the requested exponent, where each value is computed from its
4153
+ // predecessor. This is simple as `this.number * 2^(exponent - 1)` only has to be doubled (i.e.
4154
+ // added to itself) to reach `this.number * 2^exponent`.
4155
+ for (let i = this.powerOfTwos.length; i <= exponent; i++) {
4156
+ const previousPower = this.powerOfTwos[i - 1];
4157
+ this.powerOfTwos[i] = previousPower.add(previousPower);
4474
4158
  }
4475
- ctx.print(ast, '`');
4476
- return null;
4477
- }
4478
- visitConditionalExpr(ast, ctx) {
4479
- ctx.print(ast, `(`);
4480
- ast.condition.visitExpression(this, ctx);
4481
- ctx.print(ast, '? ');
4482
- ast.trueCase.visitExpression(this, ctx);
4483
- ctx.print(ast, ': ');
4484
- ast.falseCase.visitExpression(this, ctx);
4485
- ctx.print(ast, `)`);
4486
- return null;
4487
- }
4488
- visitNotExpr(ast, ctx) {
4489
- ctx.print(ast, '!');
4490
- ast.condition.visitExpression(this, ctx);
4491
- return null;
4492
- }
4493
- visitAssertNotNullExpr(ast, ctx) {
4494
- ast.condition.visitExpression(this, ctx);
4495
- return null;
4159
+ return this.powerOfTwos[exponent];
4496
4160
  }
4497
- visitUnaryOperatorExpr(ast, ctx) {
4498
- let opStr;
4499
- switch (ast.operator) {
4500
- case UnaryOperator.Plus:
4501
- opStr = '+';
4502
- break;
4503
- case UnaryOperator.Minus:
4504
- opStr = '-';
4505
- break;
4506
- default:
4507
- throw new Error(`Unknown operator ${ast.operator}`);
4508
- }
4509
- if (ast.parens)
4510
- ctx.print(ast, `(`);
4511
- ctx.print(ast, opStr);
4512
- ast.expr.visitExpression(this, ctx);
4513
- if (ast.parens)
4514
- ctx.print(ast, `)`);
4515
- return null;
4161
+ }
4162
+ /**
4163
+ * Represents an exponentiation operation for the provided base, of which exponents are computed and
4164
+ * memoized. The results are represented by a `BigIntForMultiplication` which is tailored for
4165
+ * multiplication operations by memoizing the power-of-twos. This effectively results in a matrix
4166
+ * representation that is lazily computed upon request.
4167
+ */
4168
+ class BigIntExponentiation {
4169
+ constructor(base) {
4170
+ this.base = base;
4171
+ this.exponents = [new BigIntForMultiplication(BigInteger.one())];
4516
4172
  }
4517
- visitBinaryOperatorExpr(ast, ctx) {
4518
- let opStr;
4519
- switch (ast.operator) {
4520
- case BinaryOperator.Equals:
4521
- opStr = '==';
4522
- break;
4523
- case BinaryOperator.Identical:
4524
- opStr = '===';
4525
- break;
4526
- case BinaryOperator.NotEquals:
4527
- opStr = '!=';
4528
- break;
4529
- case BinaryOperator.NotIdentical:
4530
- opStr = '!==';
4531
- break;
4532
- case BinaryOperator.And:
4533
- opStr = '&&';
4534
- break;
4535
- case BinaryOperator.BitwiseAnd:
4536
- opStr = '&';
4537
- break;
4538
- case BinaryOperator.Or:
4539
- opStr = '||';
4540
- break;
4541
- case BinaryOperator.Plus:
4542
- opStr = '+';
4543
- break;
4544
- case BinaryOperator.Minus:
4545
- opStr = '-';
4546
- break;
4547
- case BinaryOperator.Divide:
4548
- opStr = '/';
4549
- break;
4550
- case BinaryOperator.Multiply:
4551
- opStr = '*';
4552
- break;
4553
- case BinaryOperator.Modulo:
4554
- opStr = '%';
4555
- break;
4556
- case BinaryOperator.Lower:
4557
- opStr = '<';
4558
- break;
4559
- case BinaryOperator.LowerEquals:
4560
- opStr = '<=';
4561
- break;
4562
- case BinaryOperator.Bigger:
4563
- opStr = '>';
4564
- break;
4565
- case BinaryOperator.BiggerEquals:
4566
- opStr = '>=';
4567
- break;
4568
- case BinaryOperator.NullishCoalesce:
4569
- opStr = '??';
4570
- break;
4571
- default:
4572
- throw new Error(`Unknown operator ${ast.operator}`);
4173
+ /**
4174
+ * Compute the value for `this.base^exponent`, resulting in a big integer that is optimized for
4175
+ * further multiplication operations.
4176
+ */
4177
+ toThePowerOf(exponent) {
4178
+ // Compute the results up until the requested exponent, where every value is computed from its
4179
+ // predecessor. This is because `this.base^(exponent - 1)` only has to be multiplied by `base`
4180
+ // to reach `this.base^exponent`.
4181
+ for (let i = this.exponents.length; i <= exponent; i++) {
4182
+ const value = this.exponents[i - 1].multiplyBy(this.base);
4183
+ this.exponents[i] = new BigIntForMultiplication(value);
4573
4184
  }
4574
- if (ast.parens)
4575
- ctx.print(ast, `(`);
4576
- ast.lhs.visitExpression(this, ctx);
4577
- ctx.print(ast, ` ${opStr} `);
4578
- ast.rhs.visitExpression(this, ctx);
4579
- if (ast.parens)
4580
- ctx.print(ast, `)`);
4581
- return null;
4185
+ return this.exponents[exponent];
4582
4186
  }
4583
- visitReadPropExpr(ast, ctx) {
4584
- ast.receiver.visitExpression(this, ctx);
4585
- ctx.print(ast, `.`);
4586
- ctx.print(ast, ast.name);
4587
- return null;
4187
+ }
4188
+
4189
+ /**
4190
+ * @license
4191
+ * Copyright Google LLC All Rights Reserved.
4192
+ *
4193
+ * Use of this source code is governed by an MIT-style license that can be
4194
+ * found in the LICENSE file at https://angular.io/license
4195
+ */
4196
+ /**
4197
+ * Compute the message id using the XLIFF1 digest.
4198
+ */
4199
+ function computeDigest(message) {
4200
+ return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`);
4201
+ }
4202
+ /**
4203
+ * Return the message id or compute it using the XLIFF2/XMB/$localize digest.
4204
+ */
4205
+ function decimalDigest(message) {
4206
+ return message.id || computeDecimalDigest(message);
4207
+ }
4208
+ /**
4209
+ * Compute the message id using the XLIFF2/XMB/$localize digest.
4210
+ */
4211
+ function computeDecimalDigest(message) {
4212
+ const visitor = new _SerializerIgnoreIcuExpVisitor();
4213
+ const parts = message.nodes.map(a => a.visit(visitor, null));
4214
+ return computeMsgId(parts.join(''), message.meaning);
4215
+ }
4216
+ /**
4217
+ * Serialize the i18n ast to something xml-like in order to generate an UID.
4218
+ *
4219
+ * The visitor is also used in the i18n parser tests
4220
+ *
4221
+ * @internal
4222
+ */
4223
+ class _SerializerVisitor {
4224
+ visitText(text, context) {
4225
+ return text.value;
4588
4226
  }
4589
- visitReadKeyExpr(ast, ctx) {
4590
- ast.receiver.visitExpression(this, ctx);
4591
- ctx.print(ast, `[`);
4592
- ast.index.visitExpression(this, ctx);
4593
- ctx.print(ast, `]`);
4594
- return null;
4227
+ visitContainer(container, context) {
4228
+ return `[${container.children.map(child => child.visit(this)).join(', ')}]`;
4595
4229
  }
4596
- visitLiteralArrayExpr(ast, ctx) {
4597
- ctx.print(ast, `[`);
4598
- this.visitAllExpressions(ast.entries, ctx, ',');
4599
- ctx.print(ast, `]`);
4600
- return null;
4230
+ visitIcu(icu, context) {
4231
+ const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
4232
+ return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`;
4601
4233
  }
4602
- visitLiteralMapExpr(ast, ctx) {
4603
- ctx.print(ast, `{`);
4604
- this.visitAllObjects(entry => {
4605
- ctx.print(ast, `${escapeIdentifier(entry.key, this._escapeDollarInStrings, entry.quoted)}:`);
4606
- entry.value.visitExpression(this, ctx);
4607
- }, ast.entries, ctx, ',');
4608
- ctx.print(ast, `}`);
4609
- return null;
4234
+ visitTagPlaceholder(ph, context) {
4235
+ return ph.isVoid ?
4236
+ `<ph tag name="${ph.startName}"/>` :
4237
+ `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`;
4610
4238
  }
4611
- visitCommaExpr(ast, ctx) {
4612
- ctx.print(ast, '(');
4613
- this.visitAllExpressions(ast.parts, ctx, ',');
4614
- ctx.print(ast, ')');
4615
- return null;
4239
+ visitPlaceholder(ph, context) {
4240
+ return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`;
4616
4241
  }
4617
- visitAllExpressions(expressions, ctx, separator) {
4618
- this.visitAllObjects(expr => expr.visitExpression(this, ctx), expressions, ctx, separator);
4242
+ visitIcuPlaceholder(ph, context) {
4243
+ return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`;
4619
4244
  }
4620
- visitAllObjects(handler, expressions, ctx, separator) {
4621
- let incrementedIndent = false;
4622
- for (let i = 0; i < expressions.length; i++) {
4623
- if (i > 0) {
4624
- if (ctx.lineLength() > 80) {
4625
- ctx.print(null, separator, true);
4626
- if (!incrementedIndent) {
4627
- // continuation are marked with double indent.
4628
- ctx.incIndent();
4629
- ctx.incIndent();
4630
- incrementedIndent = true;
4631
- }
4632
- }
4633
- else {
4634
- ctx.print(null, separator, false);
4635
- }
4245
+ }
4246
+ const serializerVisitor$2 = new _SerializerVisitor();
4247
+ function serializeNodes(nodes) {
4248
+ return nodes.map(a => a.visit(serializerVisitor$2, null));
4249
+ }
4250
+ /**
4251
+ * Serialize the i18n ast to something xml-like in order to generate an UID.
4252
+ *
4253
+ * Ignore the ICU expressions so that message IDs stays identical if only the expression changes.
4254
+ *
4255
+ * @internal
4256
+ */
4257
+ class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor {
4258
+ visitIcu(icu, context) {
4259
+ let strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
4260
+ // Do not take the expression into account
4261
+ return `{${icu.type}, ${strCases.join(', ')}}`;
4262
+ }
4263
+ }
4264
+ /**
4265
+ * Compute the SHA1 of the given string
4266
+ *
4267
+ * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
4268
+ *
4269
+ * WARNING: this function has not been designed not tested with security in mind.
4270
+ * DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT.
4271
+ */
4272
+ function sha1(str) {
4273
+ const utf8 = utf8Encode(str);
4274
+ const words32 = bytesToWords32(utf8, Endian.Big);
4275
+ const len = utf8.length * 8;
4276
+ const w = newArray(80);
4277
+ let a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476, e = 0xc3d2e1f0;
4278
+ words32[len >> 5] |= 0x80 << (24 - len % 32);
4279
+ words32[((len + 64 >> 9) << 4) + 15] = len;
4280
+ for (let i = 0; i < words32.length; i += 16) {
4281
+ const h0 = a, h1 = b, h2 = c, h3 = d, h4 = e;
4282
+ for (let j = 0; j < 80; j++) {
4283
+ if (j < 16) {
4284
+ w[j] = words32[i + j];
4636
4285
  }
4637
- handler(expressions[i]);
4638
- }
4639
- if (incrementedIndent) {
4640
- // continuation are marked with double indent.
4641
- ctx.decIndent();
4642
- ctx.decIndent();
4286
+ else {
4287
+ w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
4288
+ }
4289
+ const fkVal = fk(j, b, c, d);
4290
+ const f = fkVal[0];
4291
+ const k = fkVal[1];
4292
+ const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32);
4293
+ e = d;
4294
+ d = c;
4295
+ c = rol32(b, 30);
4296
+ b = a;
4297
+ a = temp;
4643
4298
  }
4299
+ a = add32(a, h0);
4300
+ b = add32(b, h1);
4301
+ c = add32(c, h2);
4302
+ d = add32(d, h3);
4303
+ e = add32(e, h4);
4644
4304
  }
4645
- visitAllStatements(statements, ctx) {
4646
- statements.forEach((stmt) => stmt.visitStatement(this, ctx));
4305
+ return bytesToHexString(words32ToByteString([a, b, c, d, e]));
4306
+ }
4307
+ function fk(index, b, c, d) {
4308
+ if (index < 20) {
4309
+ return [(b & c) | (~b & d), 0x5a827999];
4310
+ }
4311
+ if (index < 40) {
4312
+ return [b ^ c ^ d, 0x6ed9eba1];
4313
+ }
4314
+ if (index < 60) {
4315
+ return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc];
4647
4316
  }
4317
+ return [b ^ c ^ d, 0xca62c1d6];
4648
4318
  }
4649
- function escapeIdentifier(input, escapeDollar, alwaysQuote = true) {
4650
- if (input == null) {
4651
- return null;
4319
+ /**
4320
+ * Compute the fingerprint of the given string
4321
+ *
4322
+ * The output is 64 bit number encoded as a decimal string
4323
+ *
4324
+ * based on:
4325
+ * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java
4326
+ */
4327
+ function fingerprint(str) {
4328
+ const utf8 = utf8Encode(str);
4329
+ let hi = hash32(utf8, 0);
4330
+ let lo = hash32(utf8, 102072);
4331
+ if (hi == 0 && (lo == 0 || lo == 1)) {
4332
+ hi = hi ^ 0x130f9bef;
4333
+ lo = lo ^ -0x6b5f56d8;
4652
4334
  }
4653
- const body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, (...match) => {
4654
- if (match[0] == '$') {
4655
- return escapeDollar ? '\\$' : '$';
4656
- }
4657
- else if (match[0] == '\n') {
4658
- return '\\n';
4659
- }
4660
- else if (match[0] == '\r') {
4661
- return '\\r';
4335
+ return [hi, lo];
4336
+ }
4337
+ function computeMsgId(msg, meaning = '') {
4338
+ let msgFingerprint = fingerprint(msg);
4339
+ if (meaning) {
4340
+ const meaningFingerprint = fingerprint(meaning);
4341
+ msgFingerprint = add64(rol64(msgFingerprint, 1), meaningFingerprint);
4342
+ }
4343
+ const hi = msgFingerprint[0];
4344
+ const lo = msgFingerprint[1];
4345
+ return wordsToDecimalString(hi & 0x7fffffff, lo);
4346
+ }
4347
+ function hash32(bytes, c) {
4348
+ let a = 0x9e3779b9, b = 0x9e3779b9;
4349
+ let i;
4350
+ const len = bytes.length;
4351
+ for (i = 0; i + 12 <= len; i += 12) {
4352
+ a = add32(a, wordAt(bytes, i, Endian.Little));
4353
+ b = add32(b, wordAt(bytes, i + 4, Endian.Little));
4354
+ c = add32(c, wordAt(bytes, i + 8, Endian.Little));
4355
+ const res = mix(a, b, c);
4356
+ a = res[0], b = res[1], c = res[2];
4357
+ }
4358
+ a = add32(a, wordAt(bytes, i, Endian.Little));
4359
+ b = add32(b, wordAt(bytes, i + 4, Endian.Little));
4360
+ // the first byte of c is reserved for the length
4361
+ c = add32(c, len);
4362
+ c = add32(c, wordAt(bytes, i + 8, Endian.Little) << 8);
4363
+ return mix(a, b, c)[2];
4364
+ }
4365
+ // clang-format off
4366
+ function mix(a, b, c) {
4367
+ a = sub32(a, b);
4368
+ a = sub32(a, c);
4369
+ a ^= c >>> 13;
4370
+ b = sub32(b, c);
4371
+ b = sub32(b, a);
4372
+ b ^= a << 8;
4373
+ c = sub32(c, a);
4374
+ c = sub32(c, b);
4375
+ c ^= b >>> 13;
4376
+ a = sub32(a, b);
4377
+ a = sub32(a, c);
4378
+ a ^= c >>> 12;
4379
+ b = sub32(b, c);
4380
+ b = sub32(b, a);
4381
+ b ^= a << 16;
4382
+ c = sub32(c, a);
4383
+ c = sub32(c, b);
4384
+ c ^= b >>> 5;
4385
+ a = sub32(a, b);
4386
+ a = sub32(a, c);
4387
+ a ^= c >>> 3;
4388
+ b = sub32(b, c);
4389
+ b = sub32(b, a);
4390
+ b ^= a << 10;
4391
+ c = sub32(c, a);
4392
+ c = sub32(c, b);
4393
+ c ^= b >>> 15;
4394
+ return [a, b, c];
4395
+ }
4396
+ // clang-format on
4397
+ // Utils
4398
+ var Endian;
4399
+ (function (Endian) {
4400
+ Endian[Endian["Little"] = 0] = "Little";
4401
+ Endian[Endian["Big"] = 1] = "Big";
4402
+ })(Endian || (Endian = {}));
4403
+ function add32(a, b) {
4404
+ return add32to64(a, b)[1];
4405
+ }
4406
+ function add32to64(a, b) {
4407
+ const low = (a & 0xffff) + (b & 0xffff);
4408
+ const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
4409
+ return [high >>> 16, (high << 16) | (low & 0xffff)];
4410
+ }
4411
+ function add64(a, b) {
4412
+ const ah = a[0], al = a[1];
4413
+ const bh = b[0], bl = b[1];
4414
+ const result = add32to64(al, bl);
4415
+ const carry = result[0];
4416
+ const l = result[1];
4417
+ const h = add32(add32(ah, bh), carry);
4418
+ return [h, l];
4419
+ }
4420
+ function sub32(a, b) {
4421
+ const low = (a & 0xffff) - (b & 0xffff);
4422
+ const high = (a >> 16) - (b >> 16) + (low >> 16);
4423
+ return (high << 16) | (low & 0xffff);
4424
+ }
4425
+ // Rotate a 32b number left `count` position
4426
+ function rol32(a, count) {
4427
+ return (a << count) | (a >>> (32 - count));
4428
+ }
4429
+ // Rotate a 64b number left `count` position
4430
+ function rol64(num, count) {
4431
+ const hi = num[0], lo = num[1];
4432
+ const h = (hi << count) | (lo >>> (32 - count));
4433
+ const l = (lo << count) | (hi >>> (32 - count));
4434
+ return [h, l];
4435
+ }
4436
+ function bytesToWords32(bytes, endian) {
4437
+ const size = (bytes.length + 3) >>> 2;
4438
+ const words32 = [];
4439
+ for (let i = 0; i < size; i++) {
4440
+ words32[i] = wordAt(bytes, i * 4, endian);
4441
+ }
4442
+ return words32;
4443
+ }
4444
+ function byteAt(bytes, index) {
4445
+ return index >= bytes.length ? 0 : bytes[index];
4446
+ }
4447
+ function wordAt(bytes, index, endian) {
4448
+ let word = 0;
4449
+ if (endian === Endian.Big) {
4450
+ for (let i = 0; i < 4; i++) {
4451
+ word += byteAt(bytes, index + i) << (24 - 8 * i);
4662
4452
  }
4663
- else {
4664
- return `\\${match[0]}`;
4453
+ }
4454
+ else {
4455
+ for (let i = 0; i < 4; i++) {
4456
+ word += byteAt(bytes, index + i) << 8 * i;
4665
4457
  }
4666
- });
4667
- const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);
4668
- return requiresQuotes ? `'${body}'` : body;
4458
+ }
4459
+ return word;
4669
4460
  }
4670
- function _createIndent(count) {
4671
- let res = '';
4672
- for (let i = 0; i < count; i++) {
4673
- res += _INDENT_WITH;
4461
+ function words32ToByteString(words32) {
4462
+ return words32.reduce((bytes, word) => bytes.concat(word32ToByteString(word)), []);
4463
+ }
4464
+ function word32ToByteString(word) {
4465
+ let bytes = [];
4466
+ for (let i = 0; i < 4; i++) {
4467
+ bytes.push((word >>> 8 * (3 - i)) & 0xff);
4674
4468
  }
4675
- return res;
4469
+ return bytes;
4470
+ }
4471
+ function bytesToHexString(bytes) {
4472
+ let hex = '';
4473
+ for (let i = 0; i < bytes.length; i++) {
4474
+ const b = byteAt(bytes, i);
4475
+ hex += (b >>> 4).toString(16) + (b & 0x0f).toString(16);
4476
+ }
4477
+ return hex.toLowerCase();
4478
+ }
4479
+ /**
4480
+ * Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized
4481
+ * power-of-256 results with memoized power-of-two computations for efficient multiplication.
4482
+ *
4483
+ * For our purposes, this can be safely stored as a global without memory concerns. The reason is
4484
+ * that we encode two words, so only need the 0th (for the low word) and 4th (for the high word)
4485
+ * exponent.
4486
+ */
4487
+ const base256 = new BigIntExponentiation(256);
4488
+ /**
4489
+ * Represents two 32-bit words as a single decimal number. This requires a big integer storage
4490
+ * model as JS numbers are not accurate enough to represent the 64-bit number.
4491
+ *
4492
+ * Based on https://www.danvk.org/hex2dec.html
4493
+ */
4494
+ function wordsToDecimalString(hi, lo) {
4495
+ // Encode the four bytes in lo in the lower digits of the decimal number.
4496
+ // Note: the multiplication results in lo itself but represented by a big integer using its
4497
+ // decimal digits.
4498
+ const decimal = base256.toThePowerOf(0).multiplyBy(lo);
4499
+ // Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why
4500
+ // this multiplication factor is applied.
4501
+ base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal);
4502
+ return decimal.toString();
4676
4503
  }
4677
4504
 
4678
4505
  /**
@@ -4682,242 +4509,368 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4682
4509
  * Use of this source code is governed by an MIT-style license that can be
4683
4510
  * found in the LICENSE file at https://angular.io/license
4684
4511
  */
4685
- function typeWithParameters(type, numParams) {
4686
- if (numParams === 0) {
4687
- return expressionType(type);
4688
- }
4689
- const params = [];
4690
- for (let i = 0; i < numParams; i++) {
4691
- params.push(DYNAMIC_TYPE);
4692
- }
4693
- return expressionType(type, undefined, params);
4512
+ // XMB/XTB placeholders can only contain A-Z, 0-9 and _
4513
+ function toPublicName(internalName) {
4514
+ return internalName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
4694
4515
  }
4695
- const ANIMATE_SYMBOL_PREFIX = '@';
4696
- function prepareSyntheticPropertyName(name) {
4697
- return `${ANIMATE_SYMBOL_PREFIX}${name}`;
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
+ /* Closure variables holding messages must be named `MSG_[A-Z0-9]+` */
4525
+ const CLOSURE_TRANSLATION_VAR_PREFIX = 'MSG_';
4526
+ /**
4527
+ * Prefix for non-`goog.getMsg` i18n-related vars.
4528
+ * Note: the prefix uses lowercase characters intentionally due to a Closure behavior that
4529
+ * considers variables like `I18N_0` as constants and throws an error when their value changes.
4530
+ */
4531
+ const TRANSLATION_VAR_PREFIX = 'i18n_';
4532
+ /** Name of the i18n attributes **/
4533
+ const I18N_ATTR = 'i18n';
4534
+ const I18N_ATTR_PREFIX = 'i18n-';
4535
+ /** Prefix of var expressions used in ICUs */
4536
+ const I18N_ICU_VAR_PREFIX = 'VAR_';
4537
+ /** Prefix of ICU expressions for post processing */
4538
+ const I18N_ICU_MAPPING_PREFIX = 'I18N_EXP_';
4539
+ /** Placeholder wrapper for i18n expressions **/
4540
+ const I18N_PLACEHOLDER_SYMBOL = '�';
4541
+ function isI18nAttribute(name) {
4542
+ return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
4698
4543
  }
4699
- function prepareSyntheticListenerName(name, phase) {
4700
- return `${ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;
4544
+ function isI18nRootNode(meta) {
4545
+ return meta instanceof Message;
4701
4546
  }
4702
- function getSafePropertyAccessString(accessor, name) {
4703
- const escapedName = escapeIdentifier(name, false, false);
4704
- return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;
4547
+ function isSingleI18nIcu(meta) {
4548
+ return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu;
4705
4549
  }
4706
- function prepareSyntheticListenerFunctionName(name, phase) {
4707
- return `animation_${name}_${phase}`;
4550
+ function hasI18nMeta(node) {
4551
+ return !!node.i18n;
4708
4552
  }
4709
- function jitOnlyGuardedExpression(expr) {
4710
- return guardedExpression('ngJitMode', expr);
4553
+ function hasI18nAttrs(element) {
4554
+ return element.attrs.some((attr) => isI18nAttribute(attr.name));
4711
4555
  }
4712
- function devOnlyGuardedExpression(expr) {
4713
- return guardedExpression('ngDevMode', expr);
4556
+ function icuFromI18nMessage(message) {
4557
+ return message.nodes[0];
4714
4558
  }
4715
- function guardedExpression(guard, expr) {
4716
- const guardExpr = new ExternalExpr({ name: guard, moduleName: null });
4717
- const guardNotDefined = new BinaryOperatorExpr(BinaryOperator.Identical, new TypeofExpr(guardExpr), literal$1('undefined'));
4718
- const guardUndefinedOrTrue = new BinaryOperatorExpr(BinaryOperator.Or, guardNotDefined, guardExpr, /* type */ undefined,
4719
- /* sourceSpan */ undefined, true);
4720
- return new BinaryOperatorExpr(BinaryOperator.And, guardUndefinedOrTrue, expr);
4559
+ function wrapI18nPlaceholder(content, contextId = 0) {
4560
+ const blockId = contextId > 0 ? `:${contextId}` : '';
4561
+ return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`;
4721
4562
  }
4722
- function wrapReference(value) {
4723
- const wrapped = new WrappedNodeExpr(value);
4724
- return { value: wrapped, type: wrapped };
4563
+ function assembleI18nBoundString(strings, bindingStartIndex = 0, contextId = 0) {
4564
+ if (!strings.length)
4565
+ return '';
4566
+ let acc = '';
4567
+ const lastIdx = strings.length - 1;
4568
+ for (let i = 0; i < lastIdx; i++) {
4569
+ acc += `${strings[i]}${wrapI18nPlaceholder(bindingStartIndex + i, contextId)}`;
4570
+ }
4571
+ acc += strings[lastIdx];
4572
+ return acc;
4725
4573
  }
4726
- function refsToArray(refs, shouldForwardDeclare) {
4727
- const values = literalArr(refs.map(ref => ref.value));
4728
- return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
4574
+ function getSeqNumberGenerator(startsAt = 0) {
4575
+ let current = startsAt;
4576
+ return () => current++;
4729
4577
  }
4730
-
4731
- var R3FactoryDelegateType;
4732
- (function (R3FactoryDelegateType) {
4733
- R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
4734
- R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function";
4735
- })(R3FactoryDelegateType || (R3FactoryDelegateType = {}));
4736
- var FactoryTarget$1;
4737
- (function (FactoryTarget) {
4738
- FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
4739
- FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
4740
- FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
4741
- FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
4742
- FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
4743
- })(FactoryTarget$1 || (FactoryTarget$1 = {}));
4744
- /**
4745
- * Construct a factory function expression for the given `R3FactoryMetadata`.
4746
- */
4747
- function compileFactoryFunction(meta) {
4748
- const t = variable('t');
4749
- let baseFactoryVar = null;
4750
- // The type to instantiate via constructor invocation. If there is no delegated factory, meaning
4751
- // this type is always created by constructor invocation, then this is the type-to-create
4752
- // parameter provided by the user (t) if specified, or the current type if not. If there is a
4753
- // delegated factory (which is used to create the current type) then this is only the type-to-
4754
- // create parameter (t).
4755
- const typeForCtor = !isDelegatedFactoryMetadata(meta) ?
4756
- new BinaryOperatorExpr(BinaryOperator.Or, t, meta.internalType) :
4757
- t;
4758
- let ctorExpr = null;
4759
- if (meta.deps !== null) {
4760
- // There is a constructor (either explicitly or implicitly defined).
4761
- if (meta.deps !== 'invalid') {
4762
- ctorExpr = new InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));
4763
- }
4764
- }
4765
- else {
4766
- // There is no constructor, use the base class' factory to construct typeForCtor.
4767
- baseFactoryVar = variable(`ɵ${meta.name}_BaseFactory`);
4768
- ctorExpr = baseFactoryVar.callFn([typeForCtor]);
4769
- }
4770
- const body = [];
4771
- let retExpr = null;
4772
- function makeConditionalFactory(nonCtorExpr) {
4773
- const r = variable('r');
4774
- body.push(r.set(NULL_EXPR).toDeclStmt());
4775
- const ctorStmt = ctorExpr !== null ? r.set(ctorExpr).toStmt() :
4776
- importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt();
4777
- body.push(ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()]));
4778
- return r;
4779
- }
4780
- if (isDelegatedFactoryMetadata(meta)) {
4781
- // This type is created with a delegated factory. If a type parameter is not specified, call
4782
- // the factory instead.
4783
- const delegateArgs = injectDependencies(meta.delegateDeps, meta.target);
4784
- // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.
4785
- const factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ?
4786
- InstantiateExpr :
4787
- InvokeFunctionExpr)(meta.delegate, delegateArgs);
4788
- retExpr = makeConditionalFactory(factoryExpr);
4789
- }
4790
- else if (isExpressionFactoryMetadata(meta)) {
4791
- // TODO(alxhub): decide whether to lower the value here or in the caller
4792
- retExpr = makeConditionalFactory(meta.expression);
4578
+ function placeholdersToParams(placeholders) {
4579
+ const params = {};
4580
+ placeholders.forEach((values, key) => {
4581
+ params[key] = literal$1(values.length > 1 ? `[${values.join('|')}]` : values[0]);
4582
+ });
4583
+ return params;
4584
+ }
4585
+ function updatePlaceholderMap(map, name, ...values) {
4586
+ const current = map.get(name) || [];
4587
+ current.push(...values);
4588
+ map.set(name, current);
4589
+ }
4590
+ function assembleBoundTextPlaceholders(meta, bindingStartIndex = 0, contextId = 0) {
4591
+ const startIdx = bindingStartIndex;
4592
+ const placeholders = new Map();
4593
+ const node = meta instanceof Message ? meta.nodes.find(node => node instanceof Container) : meta;
4594
+ if (node) {
4595
+ node
4596
+ .children
4597
+ .filter((child) => child instanceof Placeholder)
4598
+ .forEach((child, idx) => {
4599
+ const content = wrapI18nPlaceholder(startIdx + idx, contextId);
4600
+ updatePlaceholderMap(placeholders, child.name, content);
4601
+ });
4793
4602
  }
4794
- else {
4795
- retExpr = ctorExpr;
4603
+ return placeholders;
4604
+ }
4605
+ /**
4606
+ * Format the placeholder names in a map of placeholders to expressions.
4607
+ *
4608
+ * The placeholder names are converted from "internal" format (e.g. `START_TAG_DIV_1`) to "external"
4609
+ * format (e.g. `startTagDiv_1`).
4610
+ *
4611
+ * @param params A map of placeholder names to expressions.
4612
+ * @param useCamelCase whether to camelCase the placeholder name when formatting.
4613
+ * @returns A new map of formatted placeholder names to expressions.
4614
+ */
4615
+ function i18nFormatPlaceholderNames(params = {}, useCamelCase) {
4616
+ const _params = {};
4617
+ if (params && Object.keys(params).length) {
4618
+ Object.keys(params).forEach(key => _params[formatI18nPlaceholderName(key, useCamelCase)] = params[key]);
4796
4619
  }
4797
- if (retExpr === null) {
4798
- // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.
4799
- body.push(importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt());
4620
+ return _params;
4621
+ }
4622
+ /**
4623
+ * Converts internal placeholder names to public-facing format
4624
+ * (for example to use in goog.getMsg call).
4625
+ * Example: `START_TAG_DIV_1` is converted to `startTagDiv_1`.
4626
+ *
4627
+ * @param name The placeholder name that should be formatted
4628
+ * @returns Formatted placeholder name
4629
+ */
4630
+ function formatI18nPlaceholderName(name, useCamelCase = true) {
4631
+ const publicName = toPublicName(name);
4632
+ if (!useCamelCase) {
4633
+ return publicName;
4800
4634
  }
4801
- else if (baseFactoryVar !== null) {
4802
- // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it.
4803
- const getInheritedFactoryCall = importExpr(Identifiers$1.getInheritedFactory).callFn([meta.internalType]);
4804
- // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))`
4805
- const baseFactory = new BinaryOperatorExpr(BinaryOperator.Or, baseFactoryVar, baseFactoryVar.set(getInheritedFactoryCall));
4806
- body.push(new ReturnStatement(baseFactory.callFn([typeForCtor])));
4635
+ const chunks = publicName.split('_');
4636
+ if (chunks.length === 1) {
4637
+ // if no "_" found - just lowercase the value
4638
+ return name.toLowerCase();
4807
4639
  }
4808
- else {
4809
- // This is straightforward factory, just return it.
4810
- body.push(new ReturnStatement(retExpr));
4640
+ let postfix;
4641
+ // eject last element if it's a number
4642
+ if (/^\d+$/.test(chunks[chunks.length - 1])) {
4643
+ postfix = chunks.pop();
4811
4644
  }
4812
- let factoryFn = fn([new FnParam('t', DYNAMIC_TYPE)], body, INFERRED_TYPE, undefined, `${meta.name}_Factory`);
4813
- if (baseFactoryVar !== null) {
4814
- // There is a base factory variable so wrap its declaration along with the factory function into
4815
- // an IIFE.
4816
- factoryFn = fn([], [
4817
- new DeclareVarStmt(baseFactoryVar.name), new ReturnStatement(factoryFn)
4818
- ]).callFn([], /* sourceSpan */ undefined, /* pure */ true);
4645
+ let raw = chunks.shift().toLowerCase();
4646
+ if (chunks.length) {
4647
+ raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join('');
4819
4648
  }
4820
- return {
4821
- expression: factoryFn,
4822
- statements: [],
4823
- type: createFactoryType(meta),
4824
- };
4649
+ return postfix ? `${raw}_${postfix}` : raw;
4825
4650
  }
4826
- function createFactoryType(meta) {
4827
- const ctorDepsType = meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : NONE_TYPE;
4828
- return expressionType(importExpr(Identifiers$1.FactoryDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType]));
4651
+ /**
4652
+ * Generates a prefix for translation const name.
4653
+ *
4654
+ * @param extra Additional local prefix that should be injected into translation var name
4655
+ * @returns Complete translation const prefix
4656
+ */
4657
+ function getTranslationConstPrefix(extra) {
4658
+ return `${CLOSURE_TRANSLATION_VAR_PREFIX}${extra}`.toUpperCase();
4829
4659
  }
4830
- function injectDependencies(deps, target) {
4831
- return deps.map((dep, index) => compileInjectDependency(dep, target, index));
4660
+ /**
4661
+ * Generate AST to declare a variable. E.g. `var I18N_1;`.
4662
+ * @param variable the name of the variable to declare.
4663
+ */
4664
+ function declareI18nVariable(variable) {
4665
+ return new DeclareVarStmt(variable.name, undefined, INFERRED_TYPE, undefined, variable.sourceSpan);
4832
4666
  }
4833
- function compileInjectDependency(dep, target, index) {
4834
- // Interpret the dependency according to its resolved type.
4835
- if (dep.token === null) {
4836
- return importExpr(Identifiers$1.invalidFactoryDep).callFn([literal$1(index)]);
4837
- }
4838
- else if (dep.attributeNameType === null) {
4839
- // Build up the injection flags according to the metadata.
4840
- const flags = 0 /* Default */ | (dep.self ? 2 /* Self */ : 0) |
4841
- (dep.skipSelf ? 4 /* SkipSelf */ : 0) | (dep.host ? 1 /* Host */ : 0) |
4842
- (dep.optional ? 8 /* Optional */ : 0) |
4843
- (target === FactoryTarget$1.Pipe ? 16 /* ForPipe */ : 0);
4844
- // If this dependency is optional or otherwise has non-default flags, then additional
4845
- // parameters describing how to inject the dependency must be passed to the inject function
4846
- // that's being used.
4847
- let flagsParam = (flags !== 0 /* Default */ || dep.optional) ? literal$1(flags) : null;
4848
- // Build up the arguments to the injectFn call.
4849
- const injectArgs = [dep.token];
4850
- if (flagsParam) {
4851
- injectArgs.push(flagsParam);
4667
+
4668
+ /**
4669
+ * @license
4670
+ * Copyright Google LLC All Rights Reserved.
4671
+ *
4672
+ * Use of this source code is governed by an MIT-style license that can be
4673
+ * found in the LICENSE file at https://angular.io/license
4674
+ */
4675
+ /**
4676
+ * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in
4677
+ * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may
4678
+ * bot work in some cases when object keys are mangled by minifier.
4679
+ *
4680
+ * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with
4681
+ * inputs that contain potentially unsafe chars.
4682
+ */
4683
+ const UNSAFE_OBJECT_KEY_NAME_REGEXP = /[-.]/;
4684
+ /** Name of the temporary to use during data binding */
4685
+ const TEMPORARY_NAME = '_t';
4686
+ /** Name of the context parameter passed into a template function */
4687
+ const CONTEXT_NAME = 'ctx';
4688
+ /** Name of the RenderFlag passed into a template function */
4689
+ const RENDER_FLAGS = 'rf';
4690
+ /** The prefix reference variables */
4691
+ const REFERENCE_PREFIX = '_r';
4692
+ /** The name of the implicit context reference */
4693
+ const IMPLICIT_REFERENCE = '$implicit';
4694
+ /** Non bindable attribute name **/
4695
+ const NON_BINDABLE_ATTR = 'ngNonBindable';
4696
+ /** Name for the variable keeping track of the context returned by `ɵɵrestoreView`. */
4697
+ const RESTORED_VIEW_CONTEXT_NAME = 'restoredCtx';
4698
+ /**
4699
+ * Creates an allocator for a temporary variable.
4700
+ *
4701
+ * A variable declaration is added to the statements the first time the allocator is invoked.
4702
+ */
4703
+ function temporaryAllocator(statements, name) {
4704
+ let temp = null;
4705
+ return () => {
4706
+ if (!temp) {
4707
+ statements.push(new DeclareVarStmt(TEMPORARY_NAME, undefined, DYNAMIC_TYPE));
4708
+ temp = variable(name);
4852
4709
  }
4853
- const injectFn = getInjectFn(target);
4854
- return importExpr(injectFn).callFn(injectArgs);
4710
+ return temp;
4711
+ };
4712
+ }
4713
+ function unsupported(feature) {
4714
+ if (this) {
4715
+ throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
4855
4716
  }
4856
- else {
4857
- // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()`
4858
- // type dependency. For the generated JS we still want to use the `dep.token` value in case the
4859
- // name given for the attribute is not a string literal. For example given `@Attribute(foo())`,
4860
- // we want to generate `ɵɵinjectAttribute(foo())`.
4861
- //
4862
- // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate
4863
- // typings.
4864
- return importExpr(Identifiers$1.injectAttribute).callFn([dep.token]);
4717
+ throw new Error(`Feature ${feature} is not supported yet`);
4718
+ }
4719
+ function invalid(arg) {
4720
+ throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
4721
+ }
4722
+ function asLiteral(value) {
4723
+ if (Array.isArray(value)) {
4724
+ return literalArr(value.map(asLiteral));
4865
4725
  }
4726
+ return literal$1(value, INFERRED_TYPE);
4866
4727
  }
4867
- function createCtorDepsType(deps) {
4868
- let hasTypes = false;
4869
- const attributeTypes = deps.map(dep => {
4870
- const type = createCtorDepType(dep);
4871
- if (type !== null) {
4872
- hasTypes = true;
4873
- return type;
4728
+ function conditionallyCreateMapObjectLiteral(keys, keepDeclared) {
4729
+ if (Object.getOwnPropertyNames(keys).length > 0) {
4730
+ return mapToExpression(keys, keepDeclared);
4731
+ }
4732
+ return null;
4733
+ }
4734
+ function mapToExpression(map, keepDeclared) {
4735
+ return literalMap(Object.getOwnPropertyNames(map).map(key => {
4736
+ // canonical syntax: `dirProp: publicProp`
4737
+ // if there is no `:`, use dirProp = elProp
4738
+ const value = map[key];
4739
+ let declaredName;
4740
+ let publicName;
4741
+ let minifiedName;
4742
+ let needsDeclaredName;
4743
+ if (Array.isArray(value)) {
4744
+ [publicName, declaredName] = value;
4745
+ minifiedName = key;
4746
+ needsDeclaredName = publicName !== declaredName;
4874
4747
  }
4875
4748
  else {
4876
- return literal$1(null);
4749
+ [declaredName, publicName] = splitAtColon(key, [key, value]);
4750
+ minifiedName = declaredName;
4751
+ // Only include the declared name if extracted from the key, i.e. the key contains a colon.
4752
+ // Otherwise the declared name should be omitted even if it is different from the public name,
4753
+ // as it may have already been minified.
4754
+ needsDeclaredName = publicName !== declaredName && key.includes(':');
4877
4755
  }
4878
- });
4879
- if (hasTypes) {
4880
- return expressionType(literalArr(attributeTypes));
4756
+ return {
4757
+ key: minifiedName,
4758
+ // put quotes around keys that contain potentially unsafe characters
4759
+ quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName),
4760
+ value: (keepDeclared && needsDeclaredName) ?
4761
+ literalArr([asLiteral(publicName), asLiteral(declaredName)]) :
4762
+ asLiteral(publicName)
4763
+ };
4764
+ }));
4765
+ }
4766
+ /**
4767
+ * Remove trailing null nodes as they are implied.
4768
+ */
4769
+ function trimTrailingNulls(parameters) {
4770
+ while (isNull(parameters[parameters.length - 1])) {
4771
+ parameters.pop();
4772
+ }
4773
+ return parameters;
4774
+ }
4775
+ function getQueryPredicate(query, constantPool) {
4776
+ if (Array.isArray(query.predicate)) {
4777
+ let predicate = [];
4778
+ query.predicate.forEach((selector) => {
4779
+ // Each item in predicates array may contain strings with comma-separated refs
4780
+ // (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
4781
+ // as separate array entities
4782
+ const selectors = selector.split(',').map(token => literal$1(token.trim()));
4783
+ predicate.push(...selectors);
4784
+ });
4785
+ return constantPool.getConstLiteral(literalArr(predicate), true);
4881
4786
  }
4882
4787
  else {
4883
- return NONE_TYPE;
4788
+ // The original predicate may have been wrapped in a `forwardRef()` call.
4789
+ switch (query.predicate.forwardRef) {
4790
+ case 0 /* None */:
4791
+ case 2 /* Unwrapped */:
4792
+ return query.predicate.expression;
4793
+ case 1 /* Wrapped */:
4794
+ return importExpr(Identifiers$1.resolveForwardRef).callFn([query.predicate.expression]);
4795
+ }
4884
4796
  }
4885
4797
  }
4886
- function createCtorDepType(dep) {
4887
- const entries = [];
4888
- if (dep.attributeNameType !== null) {
4889
- entries.push({ key: 'attribute', value: dep.attributeNameType, quoted: false });
4798
+ /**
4799
+ * A representation for an object literal used during codegen of definition objects. The generic
4800
+ * type `T` allows to reference a documented type of the generated structure, such that the
4801
+ * property names that are set can be resolved to their documented declaration.
4802
+ */
4803
+ class DefinitionMap {
4804
+ constructor() {
4805
+ this.values = [];
4890
4806
  }
4891
- if (dep.optional) {
4892
- entries.push({ key: 'optional', value: literal$1(true), quoted: false });
4807
+ set(key, value) {
4808
+ if (value) {
4809
+ this.values.push({ key: key, value, quoted: false });
4810
+ }
4893
4811
  }
4894
- if (dep.host) {
4895
- entries.push({ key: 'host', value: literal$1(true), quoted: false });
4812
+ toLiteralMap() {
4813
+ return literalMap(this.values);
4896
4814
  }
4897
- if (dep.self) {
4898
- entries.push({ key: 'self', value: literal$1(true), quoted: false });
4815
+ }
4816
+ /**
4817
+ * Extract a map of properties to values for a given element or template node, which can be used
4818
+ * by the directive matching machinery.
4819
+ *
4820
+ * @param elOrTpl the element or template in question
4821
+ * @return an object set up for directive matching. For attributes on the element/template, this
4822
+ * object maps a property name to its (static) value. For any bindings, this map simply maps the
4823
+ * property name to an empty string.
4824
+ */
4825
+ function getAttrsForDirectiveMatching(elOrTpl) {
4826
+ const attributesMap = {};
4827
+ if (elOrTpl instanceof Template && elOrTpl.tagName !== 'ng-template') {
4828
+ elOrTpl.templateAttrs.forEach(a => attributesMap[a.name] = '');
4899
4829
  }
4900
- if (dep.skipSelf) {
4901
- entries.push({ key: 'skipSelf', value: literal$1(true), quoted: false });
4830
+ else {
4831
+ elOrTpl.attributes.forEach(a => {
4832
+ if (!isI18nAttribute(a.name)) {
4833
+ attributesMap[a.name] = a.value;
4834
+ }
4835
+ });
4836
+ elOrTpl.inputs.forEach(i => {
4837
+ attributesMap[i.name] = '';
4838
+ });
4839
+ elOrTpl.outputs.forEach(o => {
4840
+ attributesMap[o.name] = '';
4841
+ });
4902
4842
  }
4903
- return entries.length > 0 ? literalMap(entries) : null;
4904
- }
4905
- function isDelegatedFactoryMetadata(meta) {
4906
- return meta.delegateType !== undefined;
4843
+ return attributesMap;
4907
4844
  }
4908
- function isExpressionFactoryMetadata(meta) {
4909
- return meta.expression !== undefined;
4845
+ /** Returns a call expression to a chained instruction, e.g. `property(params[0])(params[1])`. */
4846
+ function chainedInstruction(reference, calls, span) {
4847
+ let expression = importExpr(reference, null, span);
4848
+ if (calls.length > 0) {
4849
+ for (let i = 0; i < calls.length; i++) {
4850
+ expression = expression.callFn(calls[i], span);
4851
+ }
4852
+ }
4853
+ else {
4854
+ // Add a blank invocation, in case the `calls` array is empty.
4855
+ expression = expression.callFn([], span);
4856
+ }
4857
+ return expression;
4910
4858
  }
4911
- function getInjectFn(target) {
4912
- switch (target) {
4913
- case FactoryTarget$1.Component:
4914
- case FactoryTarget$1.Directive:
4915
- case FactoryTarget$1.Pipe:
4916
- return Identifiers$1.directiveInject;
4917
- case FactoryTarget$1.NgModule:
4918
- case FactoryTarget$1.Injectable:
4919
- default:
4920
- return Identifiers$1.inject;
4859
+ /**
4860
+ * Gets the number of arguments expected to be passed to a generated instruction in the case of
4861
+ * interpolation instructions.
4862
+ * @param interpolation An interpolation ast
4863
+ */
4864
+ function getInterpolationArgsLength(interpolation) {
4865
+ const { expressions, strings } = interpolation;
4866
+ if (expressions.length === 1 && strings.length === 2 && strings[0] === '' && strings[1] === '') {
4867
+ // If the interpolation has one interpolated value, but the prefix and suffix are both empty
4868
+ // strings, we only pass one argument, to a special instruction like `propertyInterpolate` or
4869
+ // `textInterpolate`.
4870
+ return 1;
4871
+ }
4872
+ else {
4873
+ return expressions.length + strings.length;
4921
4874
  }
4922
4875
  }
4923
4876
 
@@ -4928,9 +4881,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4928
4881
  * Use of this source code is governed by an MIT-style license that can be
4929
4882
  * found in the LICENSE file at https://angular.io/license
4930
4883
  */
4931
- function createR3ProviderExpression(expression, isForwardRef) {
4932
- return { expression, isForwardRef };
4933
- }
4934
4884
  function compileInjectable(meta, resolveForwardRefs) {
4935
4885
  let result = null;
4936
4886
  const factoryMeta = {
@@ -5016,8 +4966,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
5016
4966
  injectableProps.set('factory', result.expression);
5017
4967
  // Only generate providedIn property if it has a non-null value
5018
4968
  if (meta.providedIn.expression.value !== null) {
5019
- injectableProps.set('providedIn', meta.providedIn.isForwardRef ? generateForwardRef(meta.providedIn.expression) :
5020
- meta.providedIn.expression);
4969
+ injectableProps.set('providedIn', convertFromMaybeForwardRefExpression(meta.providedIn));
5021
4970
  }
5022
4971
  const expression = importExpr(Identifiers$1.ɵɵdefineInjectable)
5023
4972
  .callFn([injectableProps.toLiteralMap()], undefined, true);
@@ -7431,6 +7380,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
7431
7380
  Statement: ${ast.uninterpretedExpression} located at ${ast.location}`);
7432
7381
  }
7433
7382
  visitCall(ast, mode) {
7383
+ const leftMostSafe = this.leftMostSafeNode(ast);
7384
+ if (leftMostSafe) {
7385
+ return this.convertSafeAccess(ast, leftMostSafe, mode);
7386
+ }
7434
7387
  const convertedArgs = this.visitAll(ast.args, _Mode.Expression);
7435
7388
  if (ast instanceof BuiltinFunctionCall) {
7436
7389
  return convertToStatementIfNeeded(mode, ast.converter(convertedArgs));
@@ -7445,10 +7398,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
7445
7398
  return convertToStatementIfNeeded(mode, convertedArgs[0]
7446
7399
  .cast(DYNAMIC_TYPE, this.convertSourceSpan(ast.span)));
7447
7400
  }
7448
- const leftMostSafe = this.leftMostSafeNode(ast);
7449
- if (leftMostSafe) {
7450
- return this.convertSafeAccess(ast, leftMostSafe, mode);
7451
- }
7452
7401
  const call = this._visit(receiver, _Mode.Expression)
7453
7402
  .callFn(convertedArgs, this.convertSourceSpan(ast.span));
7454
7403
  return convertToStatementIfNeeded(mode, call);
@@ -16920,7 +16869,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
16920
16869
  */
16921
16870
  _parseMetadata(meta) {
16922
16871
  return typeof meta === 'string' ? parseI18nMeta(meta) :
16923
- meta instanceof Message ? meta : {};
16872
+ meta instanceof Message ? meta :
16873
+ {};
16924
16874
  }
16925
16875
  /**
16926
16876
  * Generate (or restore) message id if not specified already.
@@ -16945,9 +16895,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
16945
16895
  // `packages/compiler/src/render3/view/template.ts`).
16946
16896
  // In that case we want to reuse the legacy message generated in the 1st pass (see
16947
16897
  // `setI18nRefs()`).
16948
- const previousMessage = meta instanceof Message ?
16949
- meta :
16950
- meta instanceof IcuPlaceholder ? meta.previousMessage : undefined;
16898
+ const previousMessage = meta instanceof Message ? meta :
16899
+ meta instanceof IcuPlaceholder ? meta.previousMessage :
16900
+ undefined;
16951
16901
  message.legacyIds = previousMessage ? previousMessage.legacyIds : [];
16952
16902
  }
16953
16903
  }
@@ -19780,8 +19730,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19780
19730
  function convertToR3QueryMetadata(facade) {
19781
19731
  return {
19782
19732
  ...facade,
19783
- predicate: Array.isArray(facade.predicate) ? facade.predicate :
19784
- new WrappedNodeExpr(facade.predicate),
19733
+ predicate: convertQueryPredicate(facade.predicate),
19785
19734
  read: facade.read ? new WrappedNodeExpr(facade.read) : null,
19786
19735
  static: facade.static,
19787
19736
  emitDistinctChangesOnly: facade.emitDistinctChangesOnly,
@@ -19791,14 +19740,20 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19791
19740
  return {
19792
19741
  propertyName: declaration.propertyName,
19793
19742
  first: declaration.first ?? false,
19794
- predicate: Array.isArray(declaration.predicate) ? declaration.predicate :
19795
- new WrappedNodeExpr(declaration.predicate),
19743
+ predicate: convertQueryPredicate(declaration.predicate),
19796
19744
  descendants: declaration.descendants ?? false,
19797
19745
  read: declaration.read ? new WrappedNodeExpr(declaration.read) : null,
19798
19746
  static: declaration.static ?? false,
19799
19747
  emitDistinctChangesOnly: declaration.emitDistinctChangesOnly ?? true,
19800
19748
  };
19801
19749
  }
19750
+ function convertQueryPredicate(predicate) {
19751
+ return Array.isArray(predicate) ?
19752
+ // The predicate is an array of strings so pass it through.
19753
+ predicate :
19754
+ // The predicate is a type - assume that we will need to unwrap any `forwardRef()` calls.
19755
+ createMayBeForwardRefExpression(new WrappedNodeExpr(predicate), 1 /* Wrapped */);
19756
+ }
19802
19757
  function convertDirectiveFacadeToMetadata(facade) {
19803
19758
  const inputsFromMetadata = parseInputOutputs(facade.inputs || []);
19804
19759
  const outputsFromMetadata = parseInputOutputs(facade.outputs || []);
@@ -19920,7 +19875,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19920
19875
  function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespaces, interpolation) {
19921
19876
  const interpolationConfig = interpolation ? InterpolationConfig.fromArray(interpolation) : DEFAULT_INTERPOLATION_CONFIG;
19922
19877
  // Parse the template and check for errors.
19923
- const parsed = parseTemplate(template, sourceMapUrl, { preserveWhitespaces: preserveWhitespaces, interpolationConfig });
19878
+ const parsed = parseTemplate(template, sourceMapUrl, { preserveWhitespaces, interpolationConfig });
19924
19879
  if (parsed.errors !== null) {
19925
19880
  const errors = parsed.errors.map(err => err.toString()).join(', ');
19926
19881
  throw new Error(`Errors during JIT compilation of template for ${typeName}: ${errors}`);
@@ -19933,11 +19888,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19933
19888
  * In JIT mode we do not want the compiler to wrap the expression in a `forwardRef()` call because,
19934
19889
  * if it is referencing a type that has not yet been defined, it will have already been wrapped in
19935
19890
  * a `forwardRef()` - either by the application developer or during partial-compilation. Thus we can
19936
- * set `isForwardRef` to `false`.
19891
+ * use `ForwardRefHandling.None`.
19937
19892
  */
19938
19893
  function convertToProviderExpression(obj, property) {
19939
19894
  if (obj.hasOwnProperty(property)) {
19940
- return createR3ProviderExpression(new WrappedNodeExpr(obj[property]), /* isForwardRef */ false);
19895
+ return createMayBeForwardRefExpression(new WrappedNodeExpr(obj[property]), 0 /* None */);
19941
19896
  }
19942
19897
  else {
19943
19898
  return undefined;
@@ -19952,11 +19907,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19952
19907
  }
19953
19908
  }
19954
19909
  function computeProvidedIn(providedIn) {
19955
- const expression = (providedIn == null || typeof providedIn === 'string') ?
19956
- new LiteralExpr(providedIn ?? null) :
19957
- new WrappedNodeExpr(providedIn);
19958
- // See `convertToProviderExpression()` for why `isForwardRef` is false.
19959
- return createR3ProviderExpression(expression, /* isForwardRef */ false);
19910
+ const expression = typeof providedIn === 'function' ? new WrappedNodeExpr(providedIn) :
19911
+ new LiteralExpr(providedIn ?? null);
19912
+ // See `convertToProviderExpression()` for why this uses `ForwardRefHandling.None`.
19913
+ return createMayBeForwardRefExpression(expression, 0 /* None */);
19960
19914
  }
19961
19915
  function convertR3DependencyMetadataArray(facades) {
19962
19916
  return facades == null ? null : facades.map(convertR3DependencyMetadata);
@@ -20062,7 +20016,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20062
20016
  * Use of this source code is governed by an MIT-style license that can be
20063
20017
  * found in the LICENSE file at https://angular.io/license
20064
20018
  */
20065
- new Version('13.0.0-rc.3');
20019
+ new Version('13.0.3');
20066
20020
 
20067
20021
  /**
20068
20022
  * @license
@@ -20691,7 +20645,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20691
20645
  function compileDeclareClassMetadata(metadata) {
20692
20646
  const definitionMap = new DefinitionMap();
20693
20647
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$6));
20694
- definitionMap.set('version', literal$1('13.0.0-rc.3'));
20648
+ definitionMap.set('version', literal$1('13.0.3'));
20695
20649
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
20696
20650
  definitionMap.set('type', metadata.type);
20697
20651
  definitionMap.set('decorators', metadata.decorators);
@@ -20700,6 +20654,83 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20700
20654
  return importExpr(Identifiers$1.declareClassMetadata).callFn([definitionMap.toLiteralMap()]);
20701
20655
  }
20702
20656
 
20657
+ /**
20658
+ * @license
20659
+ * Copyright Google LLC All Rights Reserved.
20660
+ *
20661
+ * Use of this source code is governed by an MIT-style license that can be
20662
+ * found in the LICENSE file at https://angular.io/license
20663
+ */
20664
+ /**
20665
+ * Creates an array literal expression from the given array, mapping all values to an expression
20666
+ * using the provided mapping function. If the array is empty or null, then null is returned.
20667
+ *
20668
+ * @param values The array to transfer into literal array expression.
20669
+ * @param mapper The logic to use for creating an expression for the array's values.
20670
+ * @returns An array literal expression representing `values`, or null if `values` is empty or
20671
+ * is itself null.
20672
+ */
20673
+ function toOptionalLiteralArray(values, mapper) {
20674
+ if (values === null || values.length === 0) {
20675
+ return null;
20676
+ }
20677
+ return literalArr(values.map(value => mapper(value)));
20678
+ }
20679
+ /**
20680
+ * Creates an object literal expression from the given object, mapping all values to an expression
20681
+ * using the provided mapping function. If the object has no keys, then null is returned.
20682
+ *
20683
+ * @param object The object to transfer into an object literal expression.
20684
+ * @param mapper The logic to use for creating an expression for the object's values.
20685
+ * @returns An object literal expression representing `object`, or null if `object` does not have
20686
+ * any keys.
20687
+ */
20688
+ function toOptionalLiteralMap(object, mapper) {
20689
+ const entries = Object.keys(object).map(key => {
20690
+ const value = object[key];
20691
+ return { key, value: mapper(value), quoted: true };
20692
+ });
20693
+ if (entries.length > 0) {
20694
+ return literalMap(entries);
20695
+ }
20696
+ else {
20697
+ return null;
20698
+ }
20699
+ }
20700
+ function compileDependencies(deps) {
20701
+ if (deps === 'invalid') {
20702
+ // The `deps` can be set to the string "invalid" by the `unwrapConstructorDependencies()`
20703
+ // function, which tries to convert `ConstructorDeps` into `R3DependencyMetadata[]`.
20704
+ return literal$1('invalid');
20705
+ }
20706
+ else if (deps === null) {
20707
+ return literal$1(null);
20708
+ }
20709
+ else {
20710
+ return literalArr(deps.map(compileDependency));
20711
+ }
20712
+ }
20713
+ function compileDependency(dep) {
20714
+ const depMeta = new DefinitionMap();
20715
+ depMeta.set('token', dep.token);
20716
+ if (dep.attributeNameType !== null) {
20717
+ depMeta.set('attribute', literal$1(true));
20718
+ }
20719
+ if (dep.host) {
20720
+ depMeta.set('host', literal$1(true));
20721
+ }
20722
+ if (dep.optional) {
20723
+ depMeta.set('optional', literal$1(true));
20724
+ }
20725
+ if (dep.self) {
20726
+ depMeta.set('self', literal$1(true));
20727
+ }
20728
+ if (dep.skipSelf) {
20729
+ depMeta.set('skipSelf', literal$1(true));
20730
+ }
20731
+ return depMeta.toLiteralMap();
20732
+ }
20733
+
20703
20734
  /**
20704
20735
  * @license
20705
20736
  * Copyright Google LLC All Rights Reserved.
@@ -20731,7 +20762,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20731
20762
  function createDirectiveDefinitionMap(meta) {
20732
20763
  const definitionMap = new DefinitionMap();
20733
20764
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$5));
20734
- definitionMap.set('version', literal$1('13.0.0-rc.3'));
20765
+ definitionMap.set('version', literal$1('13.0.3'));
20735
20766
  // e.g. `type: MyDirective`
20736
20767
  definitionMap.set('type', meta.internalType);
20737
20768
  // e.g. `selector: 'some-dir'`
@@ -20770,7 +20801,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20770
20801
  if (query.first) {
20771
20802
  meta.set('first', literal$1(true));
20772
20803
  }
20773
- meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) : query.predicate);
20804
+ meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) :
20805
+ convertFromMaybeForwardRefExpression(query.predicate));
20774
20806
  if (!query.emitDistinctChangesOnly) {
20775
20807
  // `emitDistinctChangesOnly` is special because we expect it to be `true`.
20776
20808
  // Therefore we explicitly emit the field, and explicitly place it only when it's `false`.
@@ -20948,7 +20980,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20948
20980
  function compileDeclareFactoryFunction(meta) {
20949
20981
  const definitionMap = new DefinitionMap();
20950
20982
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$4));
20951
- definitionMap.set('version', literal$1('13.0.0-rc.3'));
20983
+ definitionMap.set('version', literal$1('13.0.3'));
20952
20984
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
20953
20985
  definitionMap.set('type', meta.internalType);
20954
20986
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -20990,24 +21022,24 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20990
21022
  function createInjectableDefinitionMap(meta) {
20991
21023
  const definitionMap = new DefinitionMap();
20992
21024
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$3));
20993
- definitionMap.set('version', literal$1('13.0.0-rc.3'));
21025
+ definitionMap.set('version', literal$1('13.0.3'));
20994
21026
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
20995
21027
  definitionMap.set('type', meta.internalType);
20996
21028
  // Only generate providedIn property if it has a non-null value
20997
21029
  if (meta.providedIn !== undefined) {
20998
- const providedIn = convertFromProviderExpression(meta.providedIn);
21030
+ const providedIn = convertFromMaybeForwardRefExpression(meta.providedIn);
20999
21031
  if (providedIn.value !== null) {
21000
21032
  definitionMap.set('providedIn', providedIn);
21001
21033
  }
21002
21034
  }
21003
21035
  if (meta.useClass !== undefined) {
21004
- definitionMap.set('useClass', convertFromProviderExpression(meta.useClass));
21036
+ definitionMap.set('useClass', convertFromMaybeForwardRefExpression(meta.useClass));
21005
21037
  }
21006
21038
  if (meta.useExisting !== undefined) {
21007
- definitionMap.set('useExisting', convertFromProviderExpression(meta.useExisting));
21039
+ definitionMap.set('useExisting', convertFromMaybeForwardRefExpression(meta.useExisting));
21008
21040
  }
21009
21041
  if (meta.useValue !== undefined) {
21010
- definitionMap.set('useValue', convertFromProviderExpression(meta.useValue));
21042
+ definitionMap.set('useValue', convertFromMaybeForwardRefExpression(meta.useValue));
21011
21043
  }
21012
21044
  // Factories do not contain `ForwardRef`s since any types are already wrapped in a function call
21013
21045
  // so the types will not be eagerly evaluated. Therefore we do not need to process this expression
@@ -21020,27 +21052,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21020
21052
  }
21021
21053
  return definitionMap;
21022
21054
  }
21023
- /**
21024
- * Convert an `R3ProviderExpression` to an `Expression`, possibly wrapping its expression in a
21025
- * `forwardRef()` call.
21026
- *
21027
- * If `R3ProviderExpression.isForwardRef` is true then the expression was originally wrapped in a
21028
- * `forwardRef()` call to prevent the value from being eagerly evaluated in the code.
21029
- *
21030
- * Normally, the linker will statically process the code, putting the `expression` inside a factory
21031
- * function so the `forwardRef()` wrapper is not evaluated before it has been defined. But if the
21032
- * partial declaration is evaluated by the JIT compiler the `forwardRef()` call is still needed to
21033
- * prevent eager evaluation of the `expression`.
21034
- *
21035
- * So in partial declarations, expressions that could be forward-refs are wrapped in `forwardRef()`
21036
- * calls, and this is then unwrapped in the linker as necessary.
21037
- *
21038
- * See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and
21039
- * `packages/compiler/src/jit_compiler_facade.ts` for more information.
21040
- */
21041
- function convertFromProviderExpression({ expression, isForwardRef }) {
21042
- return isForwardRef ? generateForwardRef(expression) : expression;
21043
- }
21044
21055
 
21045
21056
  /**
21046
21057
  * @license
@@ -21069,7 +21080,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21069
21080
  function createInjectorDefinitionMap(meta) {
21070
21081
  const definitionMap = new DefinitionMap();
21071
21082
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$2));
21072
- definitionMap.set('version', literal$1('13.0.0-rc.3'));
21083
+ definitionMap.set('version', literal$1('13.0.3'));
21073
21084
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21074
21085
  definitionMap.set('type', meta.internalType);
21075
21086
  definitionMap.set('providers', meta.providers);
@@ -21106,7 +21117,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21106
21117
  function createNgModuleDefinitionMap(meta) {
21107
21118
  const definitionMap = new DefinitionMap();
21108
21119
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$1));
21109
- definitionMap.set('version', literal$1('13.0.0-rc.3'));
21120
+ definitionMap.set('version', literal$1('13.0.3'));
21110
21121
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21111
21122
  definitionMap.set('type', meta.internalType);
21112
21123
  // We only generate the keys in the metadata if the arrays contain values.
@@ -21164,7 +21175,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21164
21175
  function createPipeDefinitionMap(meta) {
21165
21176
  const definitionMap = new DefinitionMap();
21166
21177
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION));
21167
- definitionMap.set('version', literal$1('13.0.0-rc.3'));
21178
+ definitionMap.set('version', literal$1('13.0.3'));
21168
21179
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21169
21180
  // e.g. `type: MyPipe`
21170
21181
  definitionMap.set('type', meta.internalType);
@@ -21196,7 +21207,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21196
21207
  * Use of this source code is governed by an MIT-style license that can be
21197
21208
  * found in the LICENSE file at https://angular.io/license
21198
21209
  */
21199
- new Version('13.0.0-rc.3');
21210
+ new Version('13.0.3');
21200
21211
 
21201
21212
  /**
21202
21213
  * @license
@@ -24824,6 +24835,28 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
24824
24835
  return result;
24825
24836
  }
24826
24837
  }
24838
+ class StringConcatBuiltinFn extends KnownFn {
24839
+ constructor(lhs) {
24840
+ super();
24841
+ this.lhs = lhs;
24842
+ }
24843
+ evaluate(node, args) {
24844
+ let result = this.lhs;
24845
+ for (const arg of args) {
24846
+ const resolved = arg instanceof EnumValue ? arg.resolved : arg;
24847
+ if (typeof resolved === 'string' || typeof resolved === 'number' ||
24848
+ typeof resolved === 'boolean' || resolved == null) {
24849
+ // Cast to `any`, because `concat` will convert
24850
+ // anything to a string, but TS only allows strings.
24851
+ result = result.concat(resolved);
24852
+ }
24853
+ else {
24854
+ return DynamicValue.fromUnknown(node);
24855
+ }
24856
+ }
24857
+ return result;
24858
+ }
24859
+ }
24827
24860
  class ObjectAssignBuiltinFn extends KnownFn {
24828
24861
  evaluate(node, args) {
24829
24862
  if (args.length === 0) {
@@ -25329,6 +25362,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
25329
25362
  }
25330
25363
  return lhs[rhs];
25331
25364
  }
25365
+ else if (typeof lhs === 'string' && rhs === 'concat') {
25366
+ return new StringConcatBuiltinFn(lhs);
25367
+ }
25332
25368
  else if (lhs instanceof Reference) {
25333
25369
  const ref = lhs.node;
25334
25370
  if (this.host.isClass(ref)) {
@@ -29445,7 +29481,8 @@ Either add the @Injectable() decorator to '${provider.node.name
29445
29481
  throw new FatalDiagnosticError(ErrorCode.DECORATOR_ARITY_WRONG, exprNode, `@${name} must have arguments`);
29446
29482
  }
29447
29483
  const first = name === 'ViewChild' || name === 'ContentChild';
29448
- const node = tryUnwrapForwardRef(args[0], reflector) ?? args[0];
29484
+ const forwardReferenceTarget = tryUnwrapForwardRef(args[0], reflector);
29485
+ const node = forwardReferenceTarget ?? args[0];
29449
29486
  const arg = evaluator.evaluate(node);
29450
29487
  /** Whether or not this query should collect only static results (see view/api.ts) */
29451
29488
  let isStatic = false;
@@ -29453,7 +29490,7 @@ Either add the @Injectable() decorator to '${provider.node.name
29453
29490
  let predicate = null;
29454
29491
  if (arg instanceof Reference || arg instanceof DynamicValue) {
29455
29492
  // References and predicates that could not be evaluated statically are emitted as is.
29456
- predicate = new WrappedNodeExpr(node);
29493
+ predicate = createMayBeForwardRefExpression(new WrappedNodeExpr(node), forwardReferenceTarget !== null ? 2 /* Unwrapped */ : 0 /* None */);
29457
29494
  }
29458
29495
  else if (typeof arg === 'string') {
29459
29496
  predicate = [arg];
@@ -31519,7 +31556,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31519
31556
  type,
31520
31557
  typeArgumentCount,
31521
31558
  internalType,
31522
- providedIn: createR3ProviderExpression(new LiteralExpr(null), false),
31559
+ providedIn: createMayBeForwardRefExpression(new LiteralExpr(null), 0 /* None */),
31523
31560
  };
31524
31561
  }
31525
31562
  else if (decorator.args.length === 1) {
@@ -31534,7 +31571,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31534
31571
  const meta = reflectObjectLiteral(metaNode);
31535
31572
  const providedIn = meta.has('providedIn') ?
31536
31573
  getProviderExpression(meta.get('providedIn'), reflector) :
31537
- createR3ProviderExpression(new LiteralExpr(null), false);
31574
+ createMayBeForwardRefExpression(new LiteralExpr(null), 0 /* None */);
31538
31575
  let deps = undefined;
31539
31576
  if ((meta.has('useClass') || meta.has('useFactory')) && meta.has('deps')) {
31540
31577
  const depsExpr = meta.get('deps');
@@ -31573,7 +31610,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31573
31610
  */
31574
31611
  function getProviderExpression(expression, reflector) {
31575
31612
  const forwardRefValue = tryUnwrapForwardRef(expression, reflector);
31576
- return createR3ProviderExpression(new WrappedNodeExpr(forwardRefValue ?? expression), forwardRefValue !== null);
31613
+ return createMayBeForwardRefExpression(new WrappedNodeExpr(forwardRefValue ?? expression), forwardRefValue !== null ? 2 /* Unwrapped */ : 0 /* None */);
31577
31614
  }
31578
31615
  function extractInjectableCtorDeps(clazz, meta, decorator, reflector, isCore, strictCtorDeps) {
31579
31616
  if (decorator.args === null) {
@@ -34323,120 +34360,6 @@ Either add the @Injectable() decorator to '${provider.node.name
34323
34360
  }
34324
34361
  }
34325
34362
 
34326
- /**
34327
- * @license
34328
- * Copyright Google LLC All Rights Reserved.
34329
- *
34330
- * Use of this source code is governed by an MIT-style license that can be
34331
- * found in the LICENSE file at https://angular.io/license
34332
- */
34333
- const IVY_SWITCH_PRE_SUFFIX = '__PRE_R3__';
34334
- const IVY_SWITCH_POST_SUFFIX = '__POST_R3__';
34335
- function ivySwitchTransform(_) {
34336
- return flipIvySwitchInFile;
34337
- }
34338
- function flipIvySwitchInFile(sf) {
34339
- // To replace the statements array, it must be copied. This only needs to happen if a statement
34340
- // must actually be replaced within the array, so the newStatements array is lazily initialized.
34341
- let newStatements = undefined;
34342
- // Iterate over the statements in the file.
34343
- for (let i = 0; i < sf.statements.length; i++) {
34344
- const statement = sf.statements[i];
34345
- // Skip over everything that isn't a variable statement.
34346
- if (!ts__default["default"].isVariableStatement(statement) || !hasIvySwitches(statement)) {
34347
- continue;
34348
- }
34349
- // This statement needs to be replaced. Check if the newStatements array needs to be lazily
34350
- // initialized to a copy of the original statements.
34351
- if (newStatements === undefined) {
34352
- newStatements = [...sf.statements];
34353
- }
34354
- // Flip any switches in the VariableStatement. If there were any, a new statement will be
34355
- // returned; otherwise the old statement will be.
34356
- newStatements[i] = flipIvySwitchesInVariableStatement(statement, sf.statements);
34357
- }
34358
- // Only update the statements in the SourceFile if any have changed.
34359
- if (newStatements !== undefined) {
34360
- return ts__default["default"].updateSourceFileNode(sf, newStatements);
34361
- }
34362
- return sf;
34363
- }
34364
- /**
34365
- * Look for the ts.Identifier of a ts.Declaration with this name.
34366
- *
34367
- * The real identifier is needed (rather than fabricating one) as TypeScript decides how to
34368
- * reference this identifier based on information stored against its node in the AST, which a
34369
- * synthetic node would not have. In particular, since the post-switch variable is often exported,
34370
- * TypeScript needs to know this so it can write `exports.VAR` instead of just `VAR` when emitting
34371
- * code.
34372
- *
34373
- * Only variable, function, and class declarations are currently searched.
34374
- */
34375
- function findPostSwitchIdentifier(statements, name) {
34376
- for (const stmt of statements) {
34377
- if (ts__default["default"].isVariableStatement(stmt)) {
34378
- const decl = stmt.declarationList.declarations.find(decl => ts__default["default"].isIdentifier(decl.name) && decl.name.text === name);
34379
- if (decl !== undefined) {
34380
- return decl.name;
34381
- }
34382
- }
34383
- else if (ts__default["default"].isFunctionDeclaration(stmt) || ts__default["default"].isClassDeclaration(stmt)) {
34384
- if (stmt.name !== undefined && ts__default["default"].isIdentifier(stmt.name) && stmt.name.text === name) {
34385
- return stmt.name;
34386
- }
34387
- }
34388
- }
34389
- return null;
34390
- }
34391
- /**
34392
- * Flip any Ivy switches which are discovered in the given ts.VariableStatement.
34393
- */
34394
- function flipIvySwitchesInVariableStatement(stmt, statements) {
34395
- // Build a new list of variable declarations. Specific declarations that are initialized to a
34396
- // pre-switch identifier will be replaced with a declaration initialized to the post-switch
34397
- // identifier.
34398
- const newDeclarations = [...stmt.declarationList.declarations];
34399
- for (let i = 0; i < newDeclarations.length; i++) {
34400
- const decl = newDeclarations[i];
34401
- // Skip declarations that aren't initialized to an identifier.
34402
- if (decl.initializer === undefined || !ts__default["default"].isIdentifier(decl.initializer)) {
34403
- continue;
34404
- }
34405
- // Skip declarations that aren't Ivy switches.
34406
- if (!decl.initializer.text.endsWith(IVY_SWITCH_PRE_SUFFIX)) {
34407
- continue;
34408
- }
34409
- // Determine the name of the post-switch variable.
34410
- const postSwitchName = decl.initializer.text.replace(IVY_SWITCH_PRE_SUFFIX, IVY_SWITCH_POST_SUFFIX);
34411
- // Find the post-switch variable identifier. If one can't be found, it's an error. This is
34412
- // reported as a thrown error and not a diagnostic as transformers cannot output diagnostics.
34413
- const newIdentifier = findPostSwitchIdentifier(statements, postSwitchName);
34414
- if (newIdentifier === null) {
34415
- throw new Error(`Unable to find identifier ${postSwitchName} in ${stmt.getSourceFile().fileName} for the Ivy switch.`);
34416
- }
34417
- newDeclarations[i] = ts__default["default"].updateVariableDeclaration(
34418
- /* node */ decl,
34419
- /* name */ decl.name,
34420
- /* type */ decl.type,
34421
- /* initializer */ newIdentifier);
34422
- }
34423
- const newDeclList = ts__default["default"].updateVariableDeclarationList(
34424
- /* declarationList */ stmt.declarationList,
34425
- /* declarations */ newDeclarations);
34426
- const newStmt = ts__default["default"].updateVariableStatement(
34427
- /* statement */ stmt,
34428
- /* modifiers */ stmt.modifiers,
34429
- /* declarationList */ newDeclList);
34430
- return newStmt;
34431
- }
34432
- /**
34433
- * Check whether the given VariableStatement has any Ivy switch variables.
34434
- */
34435
- function hasIvySwitches(stmt) {
34436
- return stmt.declarationList.declarations.some(decl => decl.initializer !== undefined && ts__default["default"].isIdentifier(decl.initializer) &&
34437
- decl.initializer.text.endsWith(IVY_SWITCH_PRE_SUFFIX));
34438
- }
34439
-
34440
34363
  /**
34441
34364
  * @license
34442
34365
  * Copyright Google LLC All Rights Reserved.
@@ -37232,17 +37155,7 @@ Either add the @Injectable() decorator to '${provider.node.name
37232
37155
  const inputs = getBoundInputs(this.dir, this.node, this.tcb);
37233
37156
  for (const input of inputs) {
37234
37157
  // For bound inputs, the property is assigned the binding expression.
37235
- let expr = translateInput(input.attribute, this.tcb, this.scope);
37236
- if (!this.tcb.env.config.checkTypeOfInputBindings) {
37237
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
37238
- // before the assignment.
37239
- expr = tsCastToAny(expr);
37240
- }
37241
- else if (!this.tcb.env.config.strictNullInputBindings) {
37242
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
37243
- // wrapping the expression in a non-null assertion.
37244
- expr = ts__default["default"].createNonNullExpression(expr);
37245
- }
37158
+ const expr = widenBinding(translateInput(input.attribute, this.tcb, this.scope), this.tcb);
37246
37159
  let assignment = wrapForDiagnostics(expr);
37247
37160
  for (const fieldName of input.fieldNames) {
37248
37161
  let target;
@@ -37431,17 +37344,7 @@ Either add the @Injectable() decorator to '${provider.node.name
37431
37344
  // Skip this binding as it was claimed by a directive.
37432
37345
  continue;
37433
37346
  }
37434
- let expr = tcbExpression(binding.value, this.tcb, this.scope);
37435
- if (!this.tcb.env.config.checkTypeOfInputBindings) {
37436
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
37437
- // before the assignment.
37438
- expr = tsCastToAny(expr);
37439
- }
37440
- else if (!this.tcb.env.config.strictNullInputBindings) {
37441
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
37442
- // wrapping the expression in a non-null assertion.
37443
- expr = ts__default["default"].createNonNullExpression(expr);
37444
- }
37347
+ const expr = widenBinding(tcbExpression(binding.value, this.tcb, this.scope), this.tcb);
37445
37348
  if (this.tcb.env.config.checkTypeOfDomBindings && binding.type === 0 /* Property */) {
37446
37349
  if (binding.name !== 'style' && binding.name !== 'class') {
37447
37350
  if (elId === null) {
@@ -38255,17 +38158,7 @@ Either add the @Injectable() decorator to '${provider.node.name
38255
38158
  const propertyName = ts__default["default"].createStringLiteral(input.field);
38256
38159
  if (input.type === 'binding') {
38257
38160
  // For bound inputs, the property is assigned the binding expression.
38258
- let expr = input.expression;
38259
- if (!tcb.env.config.checkTypeOfInputBindings) {
38260
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
38261
- // before the assignment.
38262
- expr = tsCastToAny(expr);
38263
- }
38264
- else if (!tcb.env.config.strictNullInputBindings) {
38265
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
38266
- // wrapping the expression in a non-null assertion.
38267
- expr = ts__default["default"].createNonNullExpression(expr);
38268
- }
38161
+ const expr = widenBinding(input.expression, tcb);
38269
38162
  const assignment = ts__default["default"].createPropertyAssignment(propertyName, wrapForDiagnostics(expr));
38270
38163
  addParseSpanInfo(assignment, input.sourceSpan);
38271
38164
  return assignment;
@@ -38318,6 +38211,33 @@ Either add the @Injectable() decorator to '${provider.node.name
38318
38211
  return ts__default["default"].createStringLiteral(attr.value);
38319
38212
  }
38320
38213
  }
38214
+ /**
38215
+ * Potentially widens the type of `expr` according to the type-checking configuration.
38216
+ */
38217
+ function widenBinding(expr, tcb) {
38218
+ if (!tcb.env.config.checkTypeOfInputBindings) {
38219
+ // If checking the type of bindings is disabled, cast the resulting expression to 'any'
38220
+ // before the assignment.
38221
+ return tsCastToAny(expr);
38222
+ }
38223
+ else if (!tcb.env.config.strictNullInputBindings) {
38224
+ if (ts__default["default"].isObjectLiteralExpression(expr) || ts__default["default"].isArrayLiteralExpression(expr)) {
38225
+ // Object literals and array literals should not be wrapped in non-null assertions as that
38226
+ // would cause literals to be prematurely widened, resulting in type errors when assigning
38227
+ // into a literal type.
38228
+ return expr;
38229
+ }
38230
+ else {
38231
+ // If strict null checks are disabled, erase `null` and `undefined` from the type by
38232
+ // wrapping the expression in a non-null assertion.
38233
+ return ts__default["default"].createNonNullExpression(expr);
38234
+ }
38235
+ }
38236
+ else {
38237
+ // No widening is requested, use the expression as is.
38238
+ return expr;
38239
+ }
38240
+ }
38321
38241
  const EVENT_PARAMETER = '$event';
38322
38242
  /**
38323
38243
  * Creates an arrow function to be used as handler function for event bindings. The handler
@@ -40653,7 +40573,6 @@ Either add the @Injectable() decorator to '${provider.node.name
40653
40573
  if (this.adapter.factoryTracker !== null) {
40654
40574
  before.push(generatedFactoryTransform(this.adapter.factoryTracker.sourceInfo, importRewriter));
40655
40575
  }
40656
- before.push(ivySwitchTransform);
40657
40576
  return { transformers: { before, afterDeclarations } };
40658
40577
  }
40659
40578
  /**
@@ -41649,15 +41568,20 @@ https://angular.io/guide/ivy for more information.
41649
41568
  return undefined;
41650
41569
  }
41651
41570
  /**
41652
- * Given an attribute node, converts it to string form.
41571
+ * Given an attribute node, converts it to string form for use as a CSS selector.
41653
41572
  */
41654
- function toAttributeString(attribute) {
41573
+ function toAttributeCssSelector(attribute) {
41574
+ let selector;
41655
41575
  if (attribute instanceof BoundEvent || attribute instanceof BoundAttribute) {
41656
- return `[${attribute.name}]`;
41576
+ selector = `[${attribute.name}]`;
41657
41577
  }
41658
41578
  else {
41659
- return `[${attribute.name}=${attribute.valueSpan?.toString() ?? ''}]`;
41579
+ selector = `[${attribute.name}=${attribute.valueSpan?.toString() ?? ''}]`;
41660
41580
  }
41581
+ // Any dollar signs that appear in the attribute name and/or value need to be escaped because they
41582
+ // need to be taken as literal characters rather than special selector behavior of dollar signs in
41583
+ // CSS.
41584
+ return selector.replace('$', '\\$');
41661
41585
  }
41662
41586
  function getNodeName(node) {
41663
41587
  return node instanceof Template ? node.tagName : node.name;
@@ -41698,14 +41622,14 @@ https://angular.io/guide/ivy for more information.
41698
41622
  // TODO(atscott): Add unit tests for this and the one for attributes
41699
41623
  function getDirectiveMatchesForElementTag(element, directives) {
41700
41624
  const attributes = getAttributes(element);
41701
- const allAttrs = attributes.map(toAttributeString);
41625
+ const allAttrs = attributes.map(toAttributeCssSelector);
41702
41626
  const allDirectiveMatches = getDirectiveMatchesForSelector(directives, getNodeName(element) + allAttrs.join(''));
41703
41627
  const matchesWithoutElement = getDirectiveMatchesForSelector(directives, allAttrs.join(''));
41704
41628
  return difference(allDirectiveMatches, matchesWithoutElement);
41705
41629
  }
41706
41630
  function makeElementSelector(element) {
41707
41631
  const attributes = getAttributes(element);
41708
- const allAttrs = attributes.map(toAttributeString);
41632
+ const allAttrs = attributes.map(toAttributeCssSelector);
41709
41633
  return getNodeName(element) + allAttrs.join('');
41710
41634
  }
41711
41635
  /**
@@ -41721,9 +41645,9 @@ https://angular.io/guide/ivy for more information.
41721
41645
  */
41722
41646
  function getDirectiveMatchesForAttribute(name, hostNode, directives) {
41723
41647
  const attributes = getAttributes(hostNode);
41724
- const allAttrs = attributes.map(toAttributeString);
41648
+ const allAttrs = attributes.map(toAttributeCssSelector);
41725
41649
  const allDirectiveMatches = getDirectiveMatchesForSelector(directives, getNodeName(hostNode) + allAttrs.join(''));
41726
- const attrsExcludingName = attributes.filter(a => a.name !== name).map(toAttributeString);
41650
+ const attrsExcludingName = attributes.filter(a => a.name !== name).map(toAttributeCssSelector);
41727
41651
  const matchesWithoutAttr = getDirectiveMatchesForSelector(directives, getNodeName(hostNode) + attrsExcludingName.join(''));
41728
41652
  return difference(allDirectiveMatches, matchesWithoutAttr);
41729
41653
  }
@@ -41732,18 +41656,25 @@ https://angular.io/guide/ivy for more information.
41732
41656
  * for the selector.
41733
41657
  */
41734
41658
  function getDirectiveMatchesForSelector(directives, selector) {
41735
- const selectors = CssSelector.parse(selector);
41736
- if (selectors.length === 0) {
41659
+ try {
41660
+ const selectors = CssSelector.parse(selector);
41661
+ if (selectors.length === 0) {
41662
+ return new Set();
41663
+ }
41664
+ return new Set(directives.filter((dir) => {
41665
+ if (dir.selector === null) {
41666
+ return false;
41667
+ }
41668
+ const matcher = new SelectorMatcher();
41669
+ matcher.addSelectables(CssSelector.parse(dir.selector));
41670
+ return selectors.some(selector => matcher.match(selector, null));
41671
+ }));
41672
+ }
41673
+ catch {
41674
+ // An invalid selector may throw an error. There would be no directive matches for an invalid
41675
+ // selector.
41737
41676
  return new Set();
41738
41677
  }
41739
- return new Set(directives.filter((dir) => {
41740
- if (dir.selector === null) {
41741
- return false;
41742
- }
41743
- const matcher = new SelectorMatcher();
41744
- matcher.addSelectables(CssSelector.parse(dir.selector));
41745
- return selectors.some(selector => matcher.match(selector, null));
41746
- }));
41747
41678
  }
41748
41679
  /**
41749
41680
  * Returns a new `ts.SymbolDisplayPart` array which has the alias imports from the tcb filtered
@@ -45348,7 +45279,7 @@ https://angular.io/guide/ivy for more information.
45348
45279
  if (scriptInfo.scriptKind === ts__namespace.ScriptKind.External) {
45349
45280
  // script info for typecheck file is marked as external, see
45350
45281
  // getOrCreateTypeCheckScriptInfo() in
45351
- // packages/language-service/ivy/language_service.ts
45282
+ // packages/language-service/src/language_service.ts
45352
45283
  typecheckFiles.push(scriptInfo.fileName);
45353
45284
  }
45354
45285
  }