@angular/language-service 13.0.0 → 13.0.1

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
2
+ * @license Angular v13.0.1
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,765 @@ 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 = [];
3907
+ class Message {
3908
+ /**
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
3915
+ */
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
+ }
4142
3938
  }
4143
3939
  }
4144
- class EmitterVisitorContext {
4145
- constructor(_indent) {
4146
- this._indent = _indent;
4147
- this._classes = [];
4148
- this._preambleLineCount = 0;
4149
- this._lines = [new _EmittedLine(_indent)];
3940
+ class Text$1 {
3941
+ constructor(value, sourceSpan) {
3942
+ this.value = value;
3943
+ this.sourceSpan = sourceSpan;
4150
3944
  }
4151
- static createRoot() {
4152
- return new EmitterVisitorContext(0);
3945
+ visit(visitor, context) {
3946
+ return visitor.visitText(this, context);
4153
3947
  }
4154
- /**
4155
- * @internal strip this from published d.ts files due to
4156
- * https://github.com/microsoft/TypeScript/issues/36216
4157
- */
4158
- get _currentLine() {
4159
- return this._lines[this._lines.length - 1];
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;
4160
3954
  }
4161
- println(from, lastPart = '') {
4162
- this.print(from || null, lastPart, true);
3955
+ visit(visitor, context) {
3956
+ return visitor.visitContainer(this, context);
4163
3957
  }
4164
- lineIsEmpty() {
4165
- return this._currentLine.parts.length === 0;
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;
4166
3965
  }
4167
- lineLength() {
4168
- return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;
3966
+ visit(visitor, context) {
3967
+ return visitor.visitIcu(this, context);
4169
3968
  }
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
- }
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;
4179
3983
  }
4180
- removeEmptyLastLine() {
4181
- if (this.lineIsEmpty()) {
4182
- this._lines.pop();
4183
- }
3984
+ visit(visitor, context) {
3985
+ return visitor.visitTagPlaceholder(this, context);
4184
3986
  }
4185
- incIndent() {
4186
- this._indent++;
4187
- if (this.lineIsEmpty()) {
4188
- this._currentLine.indent = this._indent;
4189
- }
3987
+ }
3988
+ class Placeholder {
3989
+ constructor(value, name, sourceSpan) {
3990
+ this.value = value;
3991
+ this.name = name;
3992
+ this.sourceSpan = sourceSpan;
4190
3993
  }
4191
- decIndent() {
4192
- this._indent--;
4193
- if (this.lineIsEmpty()) {
4194
- this._currentLine.indent = this._indent;
4195
- }
3994
+ visit(visitor, context) {
3995
+ return visitor.visitPlaceholder(this, context);
4196
3996
  }
4197
- pushClass(clazz) {
4198
- this._classes.push(clazz);
3997
+ }
3998
+ class IcuPlaceholder {
3999
+ constructor(value, name, sourceSpan) {
4000
+ this.value = value;
4001
+ this.name = name;
4002
+ this.sourceSpan = sourceSpan;
4199
4003
  }
4200
- popClass() {
4201
- return this._classes.pop();
4004
+ visit(visitor, context) {
4005
+ return visitor.visitIcuPlaceholder(this, context);
4202
4006
  }
4203
- get currentClass() {
4204
- return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null;
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;
4205
4029
  }
4206
- toSource() {
4207
- return this.sourceLines
4208
- .map(l => l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : '')
4209
- .join('\n');
4030
+ static zero() {
4031
+ return new BigInteger([0]);
4210
4032
  }
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;
4033
+ static one() {
4034
+ return new BigInteger([1]);
4035
+ }
4036
+ /**
4037
+ * Creates a clone of this instance.
4038
+ */
4039
+ clone() {
4040
+ return new BigInteger(this.digits.slice());
4041
+ }
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;
4050
+ }
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];
4221
4061
  }
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++;
4062
+ if (i < other.digits.length) {
4063
+ digitSum += other.digits[i];
4237
4064
  }
4238
- if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {
4239
- firstOffsetMapped = true;
4065
+ if (digitSum >= 10) {
4066
+ this.digits[i] = digitSum - 10;
4067
+ carry = 1;
4240
4068
  }
4241
4069
  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;
4261
- }
4262
- setPreambleLineCount(count) {
4263
- return this._preambleLineCount = count;
4264
- }
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;
4070
+ this.digits[i] = digitSum;
4071
+ carry = 0;
4275
4072
  }
4276
4073
  }
4277
- return null;
4074
+ // Apply a remaining carry if needed.
4075
+ if (carry > 0) {
4076
+ this.digits[maxNrOfDigits] = 1;
4077
+ }
4278
4078
  }
4279
4079
  /**
4280
- * @internal strip this from published d.ts files due to
4281
- * https://github.com/microsoft/TypeScript/issues/36216
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.
4282
4082
  */
4283
- get sourceLines() {
4284
- if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {
4285
- return this._lines.slice(0, -1);
4083
+ toString() {
4084
+ let res = '';
4085
+ for (let i = this.digits.length - 1; i >= 0; i--) {
4086
+ res += this.digits[i];
4286
4087
  }
4287
- return this._lines;
4088
+ return res;
4288
4089
  }
4289
4090
  }
4290
- class AbstractEmitterVisitor {
4291
- constructor(_escapeDollarInStrings) {
4292
- this._escapeDollarInStrings = _escapeDollarInStrings;
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];
4293
4098
  }
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);
4301
- }
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
- }
4311
- }
4312
- }
4313
- }
4314
- visitExpressionStmt(stmt, ctx) {
4315
- this.printLeadingComments(stmt, ctx);
4316
- stmt.expr.visitExpression(this, ctx);
4317
- ctx.println(stmt, ';');
4318
- return null;
4099
+ /**
4100
+ * Returns the big integer itself.
4101
+ */
4102
+ getValue() {
4103
+ return this.powerOfTwos[0];
4319
4104
  }
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;
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;
4326
4135
  }
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();
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);
4349
4145
  }
4350
4146
  }
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
4147
  }
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, ')');
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);
4370
4158
  }
4371
- return null;
4159
+ return this.powerOfTwos[exponent];
4372
4160
  }
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, ')');
4385
- }
4386
- 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())];
4387
4172
  }
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, ')');
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);
4398
4184
  }
4399
- return null;
4185
+ return this.exponents[exponent];
4400
4186
  }
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;
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;
4407
4226
  }
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;
4227
+ visitContainer(container, context) {
4228
+ return `[${container.children.map(child => child.visit(this)).join(', ')}]`;
4418
4229
  }
4419
- visitWrappedNodeExpr(ast, ctx) {
4420
- throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');
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(', ')}}`;
4421
4233
  }
4422
- visitTypeofExpr(expr, ctx) {
4423
- ctx.print(expr, 'typeof ');
4424
- expr.expr.visitExpression(this, ctx);
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}">`;
4425
4238
  }
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}`);
4444
- }
4445
- }
4446
- ctx.print(ast, varName);
4447
- return null;
4239
+ visitPlaceholder(ph, context) {
4240
+ return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`;
4448
4241
  }
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;
4242
+ visitIcuPlaceholder(ph, context) {
4243
+ return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`;
4456
4244
  }
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;
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(', ')}}`;
4466
4262
  }
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}`);
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];
4285
+ }
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;
4474
4298
  }
4475
- ctx.print(ast, '`');
4476
- return null;
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);
4477
4304
  }
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;
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];
4487
4310
  }
4488
- visitNotExpr(ast, ctx) {
4489
- ctx.print(ast, '!');
4490
- ast.condition.visitExpression(this, ctx);
4491
- return null;
4311
+ if (index < 40) {
4312
+ return [b ^ c ^ d, 0x6ed9eba1];
4492
4313
  }
4493
- visitAssertNotNullExpr(ast, ctx) {
4494
- ast.condition.visitExpression(this, ctx);
4495
- return null;
4314
+ if (index < 60) {
4315
+ return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc];
4496
4316
  }
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;
4317
+ return [b ^ c ^ d, 0xca62c1d6];
4318
+ }
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;
4516
4334
  }
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}`);
4573
- }
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;
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);
4582
4342
  }
4583
- visitReadPropExpr(ast, ctx) {
4584
- ast.receiver.visitExpression(this, ctx);
4585
- ctx.print(ast, `.`);
4586
- ctx.print(ast, ast.name);
4587
- return null;
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];
4588
4357
  }
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;
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);
4595
4441
  }
4596
- visitLiteralArrayExpr(ast, ctx) {
4597
- ctx.print(ast, `[`);
4598
- this.visitAllExpressions(ast.entries, ctx, ',');
4599
- ctx.print(ast, `]`);
4600
- return null;
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);
4452
+ }
4601
4453
  }
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;
4454
+ else {
4455
+ for (let i = 0; i < 4; i++) {
4456
+ word += byteAt(bytes, index + i) << 8 * i;
4457
+ }
4610
4458
  }
4611
- visitCommaExpr(ast, ctx) {
4612
- ctx.print(ast, '(');
4613
- this.visitAllExpressions(ast.parts, ctx, ',');
4614
- ctx.print(ast, ')');
4615
- return null;
4459
+ return word;
4460
+ }
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);
4616
4468
  }
4617
- visitAllExpressions(expressions, ctx, separator) {
4618
- this.visitAllObjects(expr => expr.visitExpression(this, ctx), expressions, ctx, separator);
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);
4619
4476
  }
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
- }
4636
- }
4637
- handler(expressions[i]);
4638
- }
4639
- if (incrementedIndent) {
4640
- // continuation are marked with double indent.
4641
- ctx.decIndent();
4642
- ctx.decIndent();
4643
- }
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();
4503
+ }
4504
+
4505
+ /**
4506
+ * @license
4507
+ * Copyright Google LLC All Rights Reserved.
4508
+ *
4509
+ * Use of this source code is governed by an MIT-style license that can be
4510
+ * found in the LICENSE file at https://angular.io/license
4511
+ */
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, '_');
4515
+ }
4516
+
4517
+ /**
4518
+ * @license
4519
+ * Copyright Google LLC All Rights Reserved.
4520
+ *
4521
+ * Use of this source code is governed by an MIT-style license that can be
4522
+ * found in the LICENSE file at https://angular.io/license
4523
+ */
4524
+ /* 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);
4543
+ }
4544
+ function isI18nRootNode(meta) {
4545
+ return meta instanceof Message;
4546
+ }
4547
+ function isSingleI18nIcu(meta) {
4548
+ return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu;
4549
+ }
4550
+ function hasI18nMeta(node) {
4551
+ return !!node.i18n;
4552
+ }
4553
+ function hasI18nAttrs(element) {
4554
+ return element.attrs.some((attr) => isI18nAttribute(attr.name));
4555
+ }
4556
+ function icuFromI18nMessage(message) {
4557
+ return message.nodes[0];
4558
+ }
4559
+ function wrapI18nPlaceholder(content, contextId = 0) {
4560
+ const blockId = contextId > 0 ? `:${contextId}` : '';
4561
+ return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`;
4562
+ }
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)}`;
4644
4570
  }
4645
- visitAllStatements(statements, ctx) {
4646
- statements.forEach((stmt) => stmt.visitStatement(this, ctx));
4571
+ acc += strings[lastIdx];
4572
+ return acc;
4573
+ }
4574
+ function getSeqNumberGenerator(startsAt = 0) {
4575
+ let current = startsAt;
4576
+ return () => current++;
4577
+ }
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
+ });
4647
4602
  }
4603
+ return placeholders;
4648
4604
  }
4649
- function escapeIdentifier(input, escapeDollar, alwaysQuote = true) {
4650
- if (input == null) {
4651
- return null;
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]);
4652
4619
  }
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';
4662
- }
4663
- else {
4664
- return `\\${match[0]}`;
4665
- }
4666
- });
4667
- const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);
4668
- return requiresQuotes ? `'${body}'` : body;
4620
+ return _params;
4669
4621
  }
4670
- function _createIndent(count) {
4671
- let res = '';
4672
- for (let i = 0; i < count; i++) {
4673
- res += _INDENT_WITH;
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;
4634
+ }
4635
+ const chunks = publicName.split('_');
4636
+ if (chunks.length === 1) {
4637
+ // if no "_" found - just lowercase the value
4638
+ return name.toLowerCase();
4639
+ }
4640
+ let postfix;
4641
+ // eject last element if it's a number
4642
+ if (/^\d+$/.test(chunks[chunks.length - 1])) {
4643
+ postfix = chunks.pop();
4674
4644
  }
4675
- return res;
4645
+ let raw = chunks.shift().toLowerCase();
4646
+ if (chunks.length) {
4647
+ raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join('');
4648
+ }
4649
+ return postfix ? `${raw}_${postfix}` : raw;
4650
+ }
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();
4659
+ }
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);
4676
4666
  }
4677
4667
 
4678
4668
  /**
@@ -4682,242 +4672,205 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4682
4672
  * Use of this source code is governed by an MIT-style license that can be
4683
4673
  * found in the LICENSE file at https://angular.io/license
4684
4674
  */
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);
4694
- }
4695
- const ANIMATE_SYMBOL_PREFIX = '@';
4696
- function prepareSyntheticPropertyName(name) {
4697
- return `${ANIMATE_SYMBOL_PREFIX}${name}`;
4698
- }
4699
- function prepareSyntheticListenerName(name, phase) {
4700
- return `${ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;
4701
- }
4702
- function getSafePropertyAccessString(accessor, name) {
4703
- const escapedName = escapeIdentifier(name, false, false);
4704
- return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;
4705
- }
4706
- function prepareSyntheticListenerFunctionName(name, phase) {
4707
- return `animation_${name}_${phase}`;
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);
4709
+ }
4710
+ return temp;
4711
+ };
4708
4712
  }
4709
- function jitOnlyGuardedExpression(expr) {
4710
- return guardedExpression('ngJitMode', expr);
4713
+ function unsupported(feature) {
4714
+ if (this) {
4715
+ throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
4716
+ }
4717
+ throw new Error(`Feature ${feature} is not supported yet`);
4711
4718
  }
4712
- function devOnlyGuardedExpression(expr) {
4713
- return guardedExpression('ngDevMode', expr);
4719
+ function invalid(arg) {
4720
+ throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
4714
4721
  }
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);
4722
+ function asLiteral(value) {
4723
+ if (Array.isArray(value)) {
4724
+ return literalArr(value.map(asLiteral));
4725
+ }
4726
+ return literal$1(value, INFERRED_TYPE);
4721
4727
  }
4722
- function wrapReference(value) {
4723
- const wrapped = new WrappedNodeExpr(value);
4724
- return { value: wrapped, type: wrapped };
4728
+ function conditionallyCreateMapObjectLiteral(keys, keepDeclared) {
4729
+ if (Object.getOwnPropertyNames(keys).length > 0) {
4730
+ return mapToExpression(keys, keepDeclared);
4731
+ }
4732
+ return null;
4725
4733
  }
4726
- function refsToArray(refs, shouldForwardDeclare) {
4727
- const values = literalArr(refs.map(ref => ref.value));
4728
- return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
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;
4747
+ }
4748
+ else {
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(':');
4755
+ }
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
+ }));
4729
4765
  }
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
4766
  /**
4745
- * Construct a factory function expression for the given `R3FactoryMetadata`.
4767
+ * Remove trailing null nodes as they are implied.
4746
4768
  */
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);
4769
+ function trimTrailingNulls(parameters) {
4770
+ while (isNull(parameters[parameters.length - 1])) {
4771
+ parameters.pop();
4789
4772
  }
4790
- else if (isExpressionFactoryMetadata(meta)) {
4791
- // TODO(alxhub): decide whether to lower the value here or in the caller
4792
- retExpr = makeConditionalFactory(meta.expression);
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);
4793
4786
  }
4794
4787
  else {
4795
- retExpr = ctorExpr;
4796
- }
4797
- if (retExpr === null) {
4798
- // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.
4799
- body.push(importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt());
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
+ }
4800
4796
  }
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])));
4797
+ }
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 = [];
4807
4806
  }
4808
- else {
4809
- // This is straightforward factory, just return it.
4810
- body.push(new ReturnStatement(retExpr));
4807
+ set(key, value) {
4808
+ if (value) {
4809
+ this.values.push({ key: key, value, quoted: false });
4810
+ }
4811
4811
  }
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);
4812
+ toLiteralMap() {
4813
+ return literalMap(this.values);
4819
4814
  }
4820
- return {
4821
- expression: factoryFn,
4822
- statements: [],
4823
- type: createFactoryType(meta),
4824
- };
4825
- }
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]));
4829
- }
4830
- function injectDependencies(deps, target) {
4831
- return deps.map((dep, index) => compileInjectDependency(dep, target, index));
4832
4815
  }
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);
4852
- }
4853
- const injectFn = getInjectFn(target);
4854
- return importExpr(injectFn).callFn(injectArgs);
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] = '');
4855
4829
  }
4856
4830
  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]);
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
+ });
4865
4842
  }
4843
+ return attributesMap;
4866
4844
  }
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;
4874
- }
4875
- else {
4876
- return literal$1(null);
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);
4877
4851
  }
4878
- });
4879
- if (hasTypes) {
4880
- return expressionType(literalArr(attributeTypes));
4881
4852
  }
4882
4853
  else {
4883
- return NONE_TYPE;
4854
+ // Add a blank invocation, in case the `calls` array is empty.
4855
+ expression = expression.callFn([], span);
4884
4856
  }
4857
+ return expression;
4885
4858
  }
4886
- function createCtorDepType(dep) {
4887
- const entries = [];
4888
- if (dep.attributeNameType !== null) {
4889
- entries.push({ key: 'attribute', value: dep.attributeNameType, quoted: false });
4890
- }
4891
- if (dep.optional) {
4892
- entries.push({ key: 'optional', value: literal$1(true), quoted: false });
4893
- }
4894
- if (dep.host) {
4895
- entries.push({ key: 'host', value: literal$1(true), quoted: false });
4896
- }
4897
- if (dep.self) {
4898
- entries.push({ key: 'self', value: literal$1(true), quoted: false });
4899
- }
4900
- if (dep.skipSelf) {
4901
- entries.push({ key: 'skipSelf', value: literal$1(true), quoted: false });
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;
4902
4871
  }
4903
- return entries.length > 0 ? literalMap(entries) : null;
4904
- }
4905
- function isDelegatedFactoryMetadata(meta) {
4906
- return meta.delegateType !== undefined;
4907
- }
4908
- function isExpressionFactoryMetadata(meta) {
4909
- return meta.expression !== undefined;
4910
- }
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;
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);
@@ -19780,8 +19729,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19780
19729
  function convertToR3QueryMetadata(facade) {
19781
19730
  return {
19782
19731
  ...facade,
19783
- predicate: Array.isArray(facade.predicate) ? facade.predicate :
19784
- new WrappedNodeExpr(facade.predicate),
19732
+ predicate: convertQueryPredicate(facade.predicate),
19785
19733
  read: facade.read ? new WrappedNodeExpr(facade.read) : null,
19786
19734
  static: facade.static,
19787
19735
  emitDistinctChangesOnly: facade.emitDistinctChangesOnly,
@@ -19791,14 +19739,20 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19791
19739
  return {
19792
19740
  propertyName: declaration.propertyName,
19793
19741
  first: declaration.first ?? false,
19794
- predicate: Array.isArray(declaration.predicate) ? declaration.predicate :
19795
- new WrappedNodeExpr(declaration.predicate),
19742
+ predicate: convertQueryPredicate(declaration.predicate),
19796
19743
  descendants: declaration.descendants ?? false,
19797
19744
  read: declaration.read ? new WrappedNodeExpr(declaration.read) : null,
19798
19745
  static: declaration.static ?? false,
19799
19746
  emitDistinctChangesOnly: declaration.emitDistinctChangesOnly ?? true,
19800
19747
  };
19801
19748
  }
19749
+ function convertQueryPredicate(predicate) {
19750
+ return Array.isArray(predicate) ?
19751
+ // The predicate is an array of strings so pass it through.
19752
+ predicate :
19753
+ // The predicate is a type - assume that we will need to unwrap any `forwardRef()` calls.
19754
+ createMayBeForwardRefExpression(new WrappedNodeExpr(predicate), 1 /* Wrapped */);
19755
+ }
19802
19756
  function convertDirectiveFacadeToMetadata(facade) {
19803
19757
  const inputsFromMetadata = parseInputOutputs(facade.inputs || []);
19804
19758
  const outputsFromMetadata = parseInputOutputs(facade.outputs || []);
@@ -19920,7 +19874,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19920
19874
  function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespaces, interpolation) {
19921
19875
  const interpolationConfig = interpolation ? InterpolationConfig.fromArray(interpolation) : DEFAULT_INTERPOLATION_CONFIG;
19922
19876
  // Parse the template and check for errors.
19923
- const parsed = parseTemplate(template, sourceMapUrl, { preserveWhitespaces: preserveWhitespaces, interpolationConfig });
19877
+ const parsed = parseTemplate(template, sourceMapUrl, { preserveWhitespaces, interpolationConfig });
19924
19878
  if (parsed.errors !== null) {
19925
19879
  const errors = parsed.errors.map(err => err.toString()).join(', ');
19926
19880
  throw new Error(`Errors during JIT compilation of template for ${typeName}: ${errors}`);
@@ -19933,11 +19887,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19933
19887
  * In JIT mode we do not want the compiler to wrap the expression in a `forwardRef()` call because,
19934
19888
  * if it is referencing a type that has not yet been defined, it will have already been wrapped in
19935
19889
  * a `forwardRef()` - either by the application developer or during partial-compilation. Thus we can
19936
- * set `isForwardRef` to `false`.
19890
+ * use `ForwardRefHandling.None`.
19937
19891
  */
19938
19892
  function convertToProviderExpression(obj, property) {
19939
19893
  if (obj.hasOwnProperty(property)) {
19940
- return createR3ProviderExpression(new WrappedNodeExpr(obj[property]), /* isForwardRef */ false);
19894
+ return createMayBeForwardRefExpression(new WrappedNodeExpr(obj[property]), 0 /* None */);
19941
19895
  }
19942
19896
  else {
19943
19897
  return undefined;
@@ -19952,11 +19906,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19952
19906
  }
19953
19907
  }
19954
19908
  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);
19909
+ const expression = typeof providedIn === 'function' ? new WrappedNodeExpr(providedIn) :
19910
+ new LiteralExpr(providedIn ?? null);
19911
+ // See `convertToProviderExpression()` for why this uses `ForwardRefHandling.None`.
19912
+ return createMayBeForwardRefExpression(expression, 0 /* None */);
19960
19913
  }
19961
19914
  function convertR3DependencyMetadataArray(facades) {
19962
19915
  return facades == null ? null : facades.map(convertR3DependencyMetadata);
@@ -20062,7 +20015,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20062
20015
  * Use of this source code is governed by an MIT-style license that can be
20063
20016
  * found in the LICENSE file at https://angular.io/license
20064
20017
  */
20065
- new Version('13.0.0');
20018
+ new Version('13.0.1');
20066
20019
 
20067
20020
  /**
20068
20021
  * @license
@@ -20691,7 +20644,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20691
20644
  function compileDeclareClassMetadata(metadata) {
20692
20645
  const definitionMap = new DefinitionMap();
20693
20646
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$6));
20694
- definitionMap.set('version', literal$1('13.0.0'));
20647
+ definitionMap.set('version', literal$1('13.0.1'));
20695
20648
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
20696
20649
  definitionMap.set('type', metadata.type);
20697
20650
  definitionMap.set('decorators', metadata.decorators);
@@ -20700,6 +20653,83 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20700
20653
  return importExpr(Identifiers$1.declareClassMetadata).callFn([definitionMap.toLiteralMap()]);
20701
20654
  }
20702
20655
 
20656
+ /**
20657
+ * @license
20658
+ * Copyright Google LLC All Rights Reserved.
20659
+ *
20660
+ * Use of this source code is governed by an MIT-style license that can be
20661
+ * found in the LICENSE file at https://angular.io/license
20662
+ */
20663
+ /**
20664
+ * Creates an array literal expression from the given array, mapping all values to an expression
20665
+ * using the provided mapping function. If the array is empty or null, then null is returned.
20666
+ *
20667
+ * @param values The array to transfer into literal array expression.
20668
+ * @param mapper The logic to use for creating an expression for the array's values.
20669
+ * @returns An array literal expression representing `values`, or null if `values` is empty or
20670
+ * is itself null.
20671
+ */
20672
+ function toOptionalLiteralArray(values, mapper) {
20673
+ if (values === null || values.length === 0) {
20674
+ return null;
20675
+ }
20676
+ return literalArr(values.map(value => mapper(value)));
20677
+ }
20678
+ /**
20679
+ * Creates an object literal expression from the given object, mapping all values to an expression
20680
+ * using the provided mapping function. If the object has no keys, then null is returned.
20681
+ *
20682
+ * @param object The object to transfer into an object literal expression.
20683
+ * @param mapper The logic to use for creating an expression for the object's values.
20684
+ * @returns An object literal expression representing `object`, or null if `object` does not have
20685
+ * any keys.
20686
+ */
20687
+ function toOptionalLiteralMap(object, mapper) {
20688
+ const entries = Object.keys(object).map(key => {
20689
+ const value = object[key];
20690
+ return { key, value: mapper(value), quoted: true };
20691
+ });
20692
+ if (entries.length > 0) {
20693
+ return literalMap(entries);
20694
+ }
20695
+ else {
20696
+ return null;
20697
+ }
20698
+ }
20699
+ function compileDependencies(deps) {
20700
+ if (deps === 'invalid') {
20701
+ // The `deps` can be set to the string "invalid" by the `unwrapConstructorDependencies()`
20702
+ // function, which tries to convert `ConstructorDeps` into `R3DependencyMetadata[]`.
20703
+ return literal$1('invalid');
20704
+ }
20705
+ else if (deps === null) {
20706
+ return literal$1(null);
20707
+ }
20708
+ else {
20709
+ return literalArr(deps.map(compileDependency));
20710
+ }
20711
+ }
20712
+ function compileDependency(dep) {
20713
+ const depMeta = new DefinitionMap();
20714
+ depMeta.set('token', dep.token);
20715
+ if (dep.attributeNameType !== null) {
20716
+ depMeta.set('attribute', literal$1(true));
20717
+ }
20718
+ if (dep.host) {
20719
+ depMeta.set('host', literal$1(true));
20720
+ }
20721
+ if (dep.optional) {
20722
+ depMeta.set('optional', literal$1(true));
20723
+ }
20724
+ if (dep.self) {
20725
+ depMeta.set('self', literal$1(true));
20726
+ }
20727
+ if (dep.skipSelf) {
20728
+ depMeta.set('skipSelf', literal$1(true));
20729
+ }
20730
+ return depMeta.toLiteralMap();
20731
+ }
20732
+
20703
20733
  /**
20704
20734
  * @license
20705
20735
  * Copyright Google LLC All Rights Reserved.
@@ -20731,7 +20761,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20731
20761
  function createDirectiveDefinitionMap(meta) {
20732
20762
  const definitionMap = new DefinitionMap();
20733
20763
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$5));
20734
- definitionMap.set('version', literal$1('13.0.0'));
20764
+ definitionMap.set('version', literal$1('13.0.1'));
20735
20765
  // e.g. `type: MyDirective`
20736
20766
  definitionMap.set('type', meta.internalType);
20737
20767
  // e.g. `selector: 'some-dir'`
@@ -20770,7 +20800,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20770
20800
  if (query.first) {
20771
20801
  meta.set('first', literal$1(true));
20772
20802
  }
20773
- meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) : query.predicate);
20803
+ meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) :
20804
+ convertFromMaybeForwardRefExpression(query.predicate));
20774
20805
  if (!query.emitDistinctChangesOnly) {
20775
20806
  // `emitDistinctChangesOnly` is special because we expect it to be `true`.
20776
20807
  // Therefore we explicitly emit the field, and explicitly place it only when it's `false`.
@@ -20948,7 +20979,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20948
20979
  function compileDeclareFactoryFunction(meta) {
20949
20980
  const definitionMap = new DefinitionMap();
20950
20981
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$4));
20951
- definitionMap.set('version', literal$1('13.0.0'));
20982
+ definitionMap.set('version', literal$1('13.0.1'));
20952
20983
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
20953
20984
  definitionMap.set('type', meta.internalType);
20954
20985
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -20990,24 +21021,24 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20990
21021
  function createInjectableDefinitionMap(meta) {
20991
21022
  const definitionMap = new DefinitionMap();
20992
21023
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$3));
20993
- definitionMap.set('version', literal$1('13.0.0'));
21024
+ definitionMap.set('version', literal$1('13.0.1'));
20994
21025
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
20995
21026
  definitionMap.set('type', meta.internalType);
20996
21027
  // Only generate providedIn property if it has a non-null value
20997
21028
  if (meta.providedIn !== undefined) {
20998
- const providedIn = convertFromProviderExpression(meta.providedIn);
21029
+ const providedIn = convertFromMaybeForwardRefExpression(meta.providedIn);
20999
21030
  if (providedIn.value !== null) {
21000
21031
  definitionMap.set('providedIn', providedIn);
21001
21032
  }
21002
21033
  }
21003
21034
  if (meta.useClass !== undefined) {
21004
- definitionMap.set('useClass', convertFromProviderExpression(meta.useClass));
21035
+ definitionMap.set('useClass', convertFromMaybeForwardRefExpression(meta.useClass));
21005
21036
  }
21006
21037
  if (meta.useExisting !== undefined) {
21007
- definitionMap.set('useExisting', convertFromProviderExpression(meta.useExisting));
21038
+ definitionMap.set('useExisting', convertFromMaybeForwardRefExpression(meta.useExisting));
21008
21039
  }
21009
21040
  if (meta.useValue !== undefined) {
21010
- definitionMap.set('useValue', convertFromProviderExpression(meta.useValue));
21041
+ definitionMap.set('useValue', convertFromMaybeForwardRefExpression(meta.useValue));
21011
21042
  }
21012
21043
  // Factories do not contain `ForwardRef`s since any types are already wrapped in a function call
21013
21044
  // so the types will not be eagerly evaluated. Therefore we do not need to process this expression
@@ -21020,27 +21051,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21020
21051
  }
21021
21052
  return definitionMap;
21022
21053
  }
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
21054
 
21045
21055
  /**
21046
21056
  * @license
@@ -21069,7 +21079,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21069
21079
  function createInjectorDefinitionMap(meta) {
21070
21080
  const definitionMap = new DefinitionMap();
21071
21081
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$2));
21072
- definitionMap.set('version', literal$1('13.0.0'));
21082
+ definitionMap.set('version', literal$1('13.0.1'));
21073
21083
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21074
21084
  definitionMap.set('type', meta.internalType);
21075
21085
  definitionMap.set('providers', meta.providers);
@@ -21106,7 +21116,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21106
21116
  function createNgModuleDefinitionMap(meta) {
21107
21117
  const definitionMap = new DefinitionMap();
21108
21118
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$1));
21109
- definitionMap.set('version', literal$1('13.0.0'));
21119
+ definitionMap.set('version', literal$1('13.0.1'));
21110
21120
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21111
21121
  definitionMap.set('type', meta.internalType);
21112
21122
  // We only generate the keys in the metadata if the arrays contain values.
@@ -21164,7 +21174,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21164
21174
  function createPipeDefinitionMap(meta) {
21165
21175
  const definitionMap = new DefinitionMap();
21166
21176
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION));
21167
- definitionMap.set('version', literal$1('13.0.0'));
21177
+ definitionMap.set('version', literal$1('13.0.1'));
21168
21178
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21169
21179
  // e.g. `type: MyPipe`
21170
21180
  definitionMap.set('type', meta.internalType);
@@ -21196,7 +21206,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21196
21206
  * Use of this source code is governed by an MIT-style license that can be
21197
21207
  * found in the LICENSE file at https://angular.io/license
21198
21208
  */
21199
- new Version('13.0.0');
21209
+ new Version('13.0.1');
21200
21210
 
21201
21211
  /**
21202
21212
  * @license
@@ -29445,7 +29455,8 @@ Either add the @Injectable() decorator to '${provider.node.name
29445
29455
  throw new FatalDiagnosticError(ErrorCode.DECORATOR_ARITY_WRONG, exprNode, `@${name} must have arguments`);
29446
29456
  }
29447
29457
  const first = name === 'ViewChild' || name === 'ContentChild';
29448
- const node = tryUnwrapForwardRef(args[0], reflector) ?? args[0];
29458
+ const forwardReferenceTarget = tryUnwrapForwardRef(args[0], reflector);
29459
+ const node = forwardReferenceTarget ?? args[0];
29449
29460
  const arg = evaluator.evaluate(node);
29450
29461
  /** Whether or not this query should collect only static results (see view/api.ts) */
29451
29462
  let isStatic = false;
@@ -29453,7 +29464,7 @@ Either add the @Injectable() decorator to '${provider.node.name
29453
29464
  let predicate = null;
29454
29465
  if (arg instanceof Reference || arg instanceof DynamicValue) {
29455
29466
  // References and predicates that could not be evaluated statically are emitted as is.
29456
- predicate = new WrappedNodeExpr(node);
29467
+ predicate = createMayBeForwardRefExpression(new WrappedNodeExpr(node), forwardReferenceTarget !== null ? 2 /* Unwrapped */ : 0 /* None */);
29457
29468
  }
29458
29469
  else if (typeof arg === 'string') {
29459
29470
  predicate = [arg];
@@ -31519,7 +31530,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31519
31530
  type,
31520
31531
  typeArgumentCount,
31521
31532
  internalType,
31522
- providedIn: createR3ProviderExpression(new LiteralExpr(null), false),
31533
+ providedIn: createMayBeForwardRefExpression(new LiteralExpr(null), 0 /* None */),
31523
31534
  };
31524
31535
  }
31525
31536
  else if (decorator.args.length === 1) {
@@ -31534,7 +31545,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31534
31545
  const meta = reflectObjectLiteral(metaNode);
31535
31546
  const providedIn = meta.has('providedIn') ?
31536
31547
  getProviderExpression(meta.get('providedIn'), reflector) :
31537
- createR3ProviderExpression(new LiteralExpr(null), false);
31548
+ createMayBeForwardRefExpression(new LiteralExpr(null), 0 /* None */);
31538
31549
  let deps = undefined;
31539
31550
  if ((meta.has('useClass') || meta.has('useFactory')) && meta.has('deps')) {
31540
31551
  const depsExpr = meta.get('deps');
@@ -31573,7 +31584,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31573
31584
  */
31574
31585
  function getProviderExpression(expression, reflector) {
31575
31586
  const forwardRefValue = tryUnwrapForwardRef(expression, reflector);
31576
- return createR3ProviderExpression(new WrappedNodeExpr(forwardRefValue ?? expression), forwardRefValue !== null);
31587
+ return createMayBeForwardRefExpression(new WrappedNodeExpr(forwardRefValue ?? expression), forwardRefValue !== null ? 2 /* Unwrapped */ : 0 /* None */);
31577
31588
  }
31578
31589
  function extractInjectableCtorDeps(clazz, meta, decorator, reflector, isCore, strictCtorDeps) {
31579
31590
  if (decorator.args === null) {
@@ -37232,17 +37243,7 @@ Either add the @Injectable() decorator to '${provider.node.name
37232
37243
  const inputs = getBoundInputs(this.dir, this.node, this.tcb);
37233
37244
  for (const input of inputs) {
37234
37245
  // 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
- }
37246
+ const expr = widenBinding(translateInput(input.attribute, this.tcb, this.scope), this.tcb);
37246
37247
  let assignment = wrapForDiagnostics(expr);
37247
37248
  for (const fieldName of input.fieldNames) {
37248
37249
  let target;
@@ -37431,17 +37432,7 @@ Either add the @Injectable() decorator to '${provider.node.name
37431
37432
  // Skip this binding as it was claimed by a directive.
37432
37433
  continue;
37433
37434
  }
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
- }
37435
+ const expr = widenBinding(tcbExpression(binding.value, this.tcb, this.scope), this.tcb);
37445
37436
  if (this.tcb.env.config.checkTypeOfDomBindings && binding.type === 0 /* Property */) {
37446
37437
  if (binding.name !== 'style' && binding.name !== 'class') {
37447
37438
  if (elId === null) {
@@ -38255,17 +38246,7 @@ Either add the @Injectable() decorator to '${provider.node.name
38255
38246
  const propertyName = ts__default["default"].createStringLiteral(input.field);
38256
38247
  if (input.type === 'binding') {
38257
38248
  // 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
- }
38249
+ const expr = widenBinding(input.expression, tcb);
38269
38250
  const assignment = ts__default["default"].createPropertyAssignment(propertyName, wrapForDiagnostics(expr));
38270
38251
  addParseSpanInfo(assignment, input.sourceSpan);
38271
38252
  return assignment;
@@ -38318,6 +38299,33 @@ Either add the @Injectable() decorator to '${provider.node.name
38318
38299
  return ts__default["default"].createStringLiteral(attr.value);
38319
38300
  }
38320
38301
  }
38302
+ /**
38303
+ * Potentially widens the type of `expr` according to the type-checking configuration.
38304
+ */
38305
+ function widenBinding(expr, tcb) {
38306
+ if (!tcb.env.config.checkTypeOfInputBindings) {
38307
+ // If checking the type of bindings is disabled, cast the resulting expression to 'any'
38308
+ // before the assignment.
38309
+ return tsCastToAny(expr);
38310
+ }
38311
+ else if (!tcb.env.config.strictNullInputBindings) {
38312
+ if (ts__default["default"].isObjectLiteralExpression(expr) || ts__default["default"].isArrayLiteralExpression(expr)) {
38313
+ // Object literals and array literals should not be wrapped in non-null assertions as that
38314
+ // would cause literals to be prematurely widened, resulting in type errors when assigning
38315
+ // into a literal type.
38316
+ return expr;
38317
+ }
38318
+ else {
38319
+ // If strict null checks are disabled, erase `null` and `undefined` from the type by
38320
+ // wrapping the expression in a non-null assertion.
38321
+ return ts__default["default"].createNonNullExpression(expr);
38322
+ }
38323
+ }
38324
+ else {
38325
+ // No widening is requested, use the expression as is.
38326
+ return expr;
38327
+ }
38328
+ }
38321
38329
  const EVENT_PARAMETER = '$event';
38322
38330
  /**
38323
38331
  * Creates an arrow function to be used as handler function for event bindings. The handler
@@ -45348,7 +45356,7 @@ https://angular.io/guide/ivy for more information.
45348
45356
  if (scriptInfo.scriptKind === ts__namespace.ScriptKind.External) {
45349
45357
  // script info for typecheck file is marked as external, see
45350
45358
  // getOrCreateTypeCheckScriptInfo() in
45351
- // packages/language-service/ivy/language_service.ts
45359
+ // packages/language-service/src/language_service.ts
45352
45360
  typecheckFiles.push(scriptInfo.fileName);
45353
45361
  }
45354
45362
  }