@angular/core 20.1.0-rc.0 → 20.2.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.d.d.ts +1 -1
- package/chrome_dev_tools_performance.d.d.ts +1 -1
- package/discovery.d.d.ts +1 -1
- package/event_dispatcher.d.d.ts +1 -1
- package/fesm2022/attribute.mjs +1 -1
- package/fesm2022/core.mjs +3 -3
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/debug_node.mjs +7 -5
- package/fesm2022/debug_node.mjs.map +1 -1
- package/fesm2022/not_found.mjs +1 -1
- package/fesm2022/primitives/di.mjs +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/resource.mjs +1 -1
- package/fesm2022/root_effect_scheduler.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/signal.mjs +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/fesm2022/untracked.mjs +1 -1
- package/fesm2022/weak_ref.mjs +1 -1
- package/graph.d.d.ts +1 -1
- package/index.d.ts +2 -2
- package/package.json +2 -2
- package/primitives/di/index.d.ts +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/bundles/{apply_import_manager-DEMoyu96.cjs → apply_import_manager-B0fYYMpr.cjs} +3 -3
- package/schematics/bundles/{checker-CwuJOWZI.cjs → checker-DLInMAS3.cjs} +382 -1109
- package/schematics/bundles/cleanup-unused-imports.cjs +6 -5
- package/schematics/bundles/{compiler_host-B1N_OYoF.cjs → compiler_host-Doj9KVJf.cjs} +2 -2
- package/schematics/bundles/control-flow-migration.cjs +3 -3
- package/schematics/bundles/document-core.cjs +6 -5
- package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
- package/schematics/bundles/{index-CmuNlSML.cjs → index-BmuUS1AB.cjs} +930 -54
- package/schematics/bundles/{index-DPxKO2pR.cjs → index-Bp8sCiq1.cjs} +5 -4
- package/schematics/bundles/inject-flags.cjs +6 -5
- package/schematics/bundles/inject-migration.cjs +3 -3
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-Da3yLjVM.cjs → migrate_ts_type_references-CmZ0155c.cjs} +6 -5
- package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +7 -6
- package/schematics/bundles/{project_paths-86Qe1BQQ.cjs → project_paths-D2SJWT7x.cjs} +39 -3
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +1 -1
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/route-lazy-loading.cjs +3 -3
- package/schematics/bundles/self-closing-tags-migration.cjs +5 -4
- package/schematics/bundles/signal-input-migration.cjs +8 -7
- package/schematics/bundles/signal-queries-migration.cjs +8 -7
- package/schematics/bundles/signals.cjs +8 -7
- package/schematics/bundles/standalone-migration.cjs +4 -4
- package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
- package/schematics/bundles/test-bed-get.cjs +5 -4
- package/signal.d.d.ts +1 -1
- package/testing/index.d.ts +1 -1
- package/weak_ref.d.d.ts +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.
|
|
3
|
+
* @license Angular v20.2.0-next.0
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
var checker = require('./checker-
|
|
9
|
+
var checker = require('./checker-DLInMAS3.cjs');
|
|
10
10
|
var ts = require('typescript');
|
|
11
11
|
var p = require('path');
|
|
12
12
|
require('os');
|
|
@@ -891,7 +891,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
|
|
|
891
891
|
function compileDeclareClassMetadata(metadata) {
|
|
892
892
|
const definitionMap = new checker.DefinitionMap();
|
|
893
893
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
894
|
-
definitionMap.set('version', checker.literal('20.
|
|
894
|
+
definitionMap.set('version', checker.literal('20.2.0-next.0'));
|
|
895
895
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
896
896
|
definitionMap.set('type', metadata.type);
|
|
897
897
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -909,7 +909,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
|
|
|
909
909
|
callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? checker.literal(null));
|
|
910
910
|
callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? checker.literal(null));
|
|
911
911
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
|
|
912
|
-
definitionMap.set('version', checker.literal('20.
|
|
912
|
+
definitionMap.set('version', checker.literal('20.2.0-next.0'));
|
|
913
913
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
914
914
|
definitionMap.set('type', metadata.type);
|
|
915
915
|
definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
|
|
@@ -1004,7 +1004,7 @@ function createDirectiveDefinitionMap(meta) {
|
|
|
1004
1004
|
const definitionMap = new checker.DefinitionMap();
|
|
1005
1005
|
const minVersion = getMinimumVersionForPartialOutput(meta);
|
|
1006
1006
|
definitionMap.set('minVersion', checker.literal(minVersion));
|
|
1007
|
-
definitionMap.set('version', checker.literal('20.
|
|
1007
|
+
definitionMap.set('version', checker.literal('20.2.0-next.0'));
|
|
1008
1008
|
// e.g. `type: MyDirective`
|
|
1009
1009
|
definitionMap.set('type', meta.type.value);
|
|
1010
1010
|
if (meta.isStandalone !== undefined) {
|
|
@@ -1420,7 +1420,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
|
|
|
1420
1420
|
function compileDeclareFactoryFunction(meta) {
|
|
1421
1421
|
const definitionMap = new checker.DefinitionMap();
|
|
1422
1422
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
1423
|
-
definitionMap.set('version', checker.literal('20.
|
|
1423
|
+
definitionMap.set('version', checker.literal('20.2.0-next.0'));
|
|
1424
1424
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1425
1425
|
definitionMap.set('type', meta.type.value);
|
|
1426
1426
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -1455,7 +1455,7 @@ function compileDeclareInjectableFromMetadata(meta) {
|
|
|
1455
1455
|
function createInjectableDefinitionMap(meta) {
|
|
1456
1456
|
const definitionMap = new checker.DefinitionMap();
|
|
1457
1457
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
1458
|
-
definitionMap.set('version', checker.literal('20.
|
|
1458
|
+
definitionMap.set('version', checker.literal('20.2.0-next.0'));
|
|
1459
1459
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1460
1460
|
definitionMap.set('type', meta.type.value);
|
|
1461
1461
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -1506,7 +1506,7 @@ function compileDeclareInjectorFromMetadata(meta) {
|
|
|
1506
1506
|
function createInjectorDefinitionMap(meta) {
|
|
1507
1507
|
const definitionMap = new checker.DefinitionMap();
|
|
1508
1508
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
1509
|
-
definitionMap.set('version', checker.literal('20.
|
|
1509
|
+
definitionMap.set('version', checker.literal('20.2.0-next.0'));
|
|
1510
1510
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1511
1511
|
definitionMap.set('type', meta.type.value);
|
|
1512
1512
|
definitionMap.set('providers', meta.providers);
|
|
@@ -1539,7 +1539,7 @@ function createNgModuleDefinitionMap(meta) {
|
|
|
1539
1539
|
throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
|
|
1540
1540
|
}
|
|
1541
1541
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
1542
|
-
definitionMap.set('version', checker.literal('20.
|
|
1542
|
+
definitionMap.set('version', checker.literal('20.2.0-next.0'));
|
|
1543
1543
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1544
1544
|
definitionMap.set('type', meta.type.value);
|
|
1545
1545
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -1590,7 +1590,7 @@ function compileDeclarePipeFromMetadata(meta) {
|
|
|
1590
1590
|
function createPipeDefinitionMap(meta) {
|
|
1591
1591
|
const definitionMap = new checker.DefinitionMap();
|
|
1592
1592
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
1593
|
-
definitionMap.set('version', checker.literal('20.
|
|
1593
|
+
definitionMap.set('version', checker.literal('20.2.0-next.0'));
|
|
1594
1594
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1595
1595
|
// e.g. `type: MyPipe`
|
|
1596
1596
|
definitionMap.set('type', meta.type.value);
|
|
@@ -2996,6 +2996,790 @@ function resolveOutput(bindingName) {
|
|
|
2996
2996
|
return bindingName;
|
|
2997
2997
|
}
|
|
2998
2998
|
|
|
2999
|
+
class ArraySliceBuiltinFn extends checker.KnownFn {
|
|
3000
|
+
lhs;
|
|
3001
|
+
constructor(lhs) {
|
|
3002
|
+
super();
|
|
3003
|
+
this.lhs = lhs;
|
|
3004
|
+
}
|
|
3005
|
+
evaluate(node, args) {
|
|
3006
|
+
if (args.length === 0) {
|
|
3007
|
+
return this.lhs;
|
|
3008
|
+
}
|
|
3009
|
+
else {
|
|
3010
|
+
return checker.DynamicValue.fromUnknown(node);
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
class ArrayConcatBuiltinFn extends checker.KnownFn {
|
|
3015
|
+
lhs;
|
|
3016
|
+
constructor(lhs) {
|
|
3017
|
+
super();
|
|
3018
|
+
this.lhs = lhs;
|
|
3019
|
+
}
|
|
3020
|
+
evaluate(node, args) {
|
|
3021
|
+
const result = [...this.lhs];
|
|
3022
|
+
for (const arg of args) {
|
|
3023
|
+
if (arg instanceof checker.DynamicValue) {
|
|
3024
|
+
result.push(checker.DynamicValue.fromDynamicInput(node, arg));
|
|
3025
|
+
}
|
|
3026
|
+
else if (Array.isArray(arg)) {
|
|
3027
|
+
result.push(...arg);
|
|
3028
|
+
}
|
|
3029
|
+
else {
|
|
3030
|
+
result.push(arg);
|
|
3031
|
+
}
|
|
3032
|
+
}
|
|
3033
|
+
return result;
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
class StringConcatBuiltinFn extends checker.KnownFn {
|
|
3037
|
+
lhs;
|
|
3038
|
+
constructor(lhs) {
|
|
3039
|
+
super();
|
|
3040
|
+
this.lhs = lhs;
|
|
3041
|
+
}
|
|
3042
|
+
evaluate(node, args) {
|
|
3043
|
+
let result = this.lhs;
|
|
3044
|
+
for (const arg of args) {
|
|
3045
|
+
const resolved = arg instanceof checker.EnumValue ? arg.resolved : arg;
|
|
3046
|
+
if (typeof resolved === 'string' ||
|
|
3047
|
+
typeof resolved === 'number' ||
|
|
3048
|
+
typeof resolved === 'boolean' ||
|
|
3049
|
+
resolved == null) {
|
|
3050
|
+
// Cast to `any`, because `concat` will convert
|
|
3051
|
+
// anything to a string, but TS only allows strings.
|
|
3052
|
+
result = result.concat(resolved);
|
|
3053
|
+
}
|
|
3054
|
+
else {
|
|
3055
|
+
return checker.DynamicValue.fromUnknown(node);
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
return result;
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
|
|
3062
|
+
/**
|
|
3063
|
+
* A value produced which originated in a `ForeignFunctionResolver` and doesn't come from the
|
|
3064
|
+
* template itself.
|
|
3065
|
+
*
|
|
3066
|
+
* Synthetic values cannot be further evaluated, and attempts to do so produce `DynamicValue`s
|
|
3067
|
+
* instead.
|
|
3068
|
+
*/
|
|
3069
|
+
class SyntheticValue {
|
|
3070
|
+
value;
|
|
3071
|
+
constructor(value) {
|
|
3072
|
+
this.value = value;
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
|
|
3076
|
+
function literalBinaryOp(op) {
|
|
3077
|
+
return { op, literal: true };
|
|
3078
|
+
}
|
|
3079
|
+
function referenceBinaryOp(op) {
|
|
3080
|
+
return { op, literal: false };
|
|
3081
|
+
}
|
|
3082
|
+
class StaticInterpreter {
|
|
3083
|
+
host;
|
|
3084
|
+
checker;
|
|
3085
|
+
dependencyTracker;
|
|
3086
|
+
BINARY_OPERATORS = new Map([
|
|
3087
|
+
[ts.SyntaxKind.PlusToken, literalBinaryOp((a, b) => a + b)],
|
|
3088
|
+
[ts.SyntaxKind.MinusToken, literalBinaryOp((a, b) => a - b)],
|
|
3089
|
+
[ts.SyntaxKind.AsteriskToken, literalBinaryOp((a, b) => a * b)],
|
|
3090
|
+
[ts.SyntaxKind.SlashToken, literalBinaryOp((a, b) => a / b)],
|
|
3091
|
+
[ts.SyntaxKind.PercentToken, literalBinaryOp((a, b) => a % b)],
|
|
3092
|
+
[ts.SyntaxKind.AmpersandToken, literalBinaryOp((a, b) => a & b)],
|
|
3093
|
+
[ts.SyntaxKind.BarToken, literalBinaryOp((a, b) => a | b)],
|
|
3094
|
+
[ts.SyntaxKind.CaretToken, literalBinaryOp((a, b) => a ^ b)],
|
|
3095
|
+
[ts.SyntaxKind.LessThanToken, literalBinaryOp((a, b) => a < b)],
|
|
3096
|
+
[ts.SyntaxKind.LessThanEqualsToken, literalBinaryOp((a, b) => a <= b)],
|
|
3097
|
+
[ts.SyntaxKind.GreaterThanToken, literalBinaryOp((a, b) => a > b)],
|
|
3098
|
+
[ts.SyntaxKind.GreaterThanEqualsToken, literalBinaryOp((a, b) => a >= b)],
|
|
3099
|
+
[ts.SyntaxKind.EqualsEqualsToken, literalBinaryOp((a, b) => a == b)],
|
|
3100
|
+
[ts.SyntaxKind.EqualsEqualsEqualsToken, literalBinaryOp((a, b) => a === b)],
|
|
3101
|
+
[ts.SyntaxKind.ExclamationEqualsToken, literalBinaryOp((a, b) => a != b)],
|
|
3102
|
+
[ts.SyntaxKind.ExclamationEqualsEqualsToken, literalBinaryOp((a, b) => a !== b)],
|
|
3103
|
+
[ts.SyntaxKind.LessThanLessThanToken, literalBinaryOp((a, b) => a << b)],
|
|
3104
|
+
[ts.SyntaxKind.GreaterThanGreaterThanToken, literalBinaryOp((a, b) => a >> b)],
|
|
3105
|
+
[ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken, literalBinaryOp((a, b) => a >>> b)],
|
|
3106
|
+
[ts.SyntaxKind.AsteriskAsteriskToken, literalBinaryOp((a, b) => Math.pow(a, b))],
|
|
3107
|
+
[ts.SyntaxKind.AmpersandAmpersandToken, referenceBinaryOp((a, b) => a && b)],
|
|
3108
|
+
[ts.SyntaxKind.BarBarToken, referenceBinaryOp((a, b) => a || b)],
|
|
3109
|
+
]);
|
|
3110
|
+
UNARY_OPERATORS = new Map([
|
|
3111
|
+
[ts.SyntaxKind.TildeToken, (a) => ~a],
|
|
3112
|
+
[ts.SyntaxKind.MinusToken, (a) => -a],
|
|
3113
|
+
[ts.SyntaxKind.PlusToken, (a) => +a],
|
|
3114
|
+
[ts.SyntaxKind.ExclamationToken, (a) => !a],
|
|
3115
|
+
]);
|
|
3116
|
+
constructor(host, checker, dependencyTracker) {
|
|
3117
|
+
this.host = host;
|
|
3118
|
+
this.checker = checker;
|
|
3119
|
+
this.dependencyTracker = dependencyTracker;
|
|
3120
|
+
}
|
|
3121
|
+
visit(node, context) {
|
|
3122
|
+
return this.visitExpression(node, context);
|
|
3123
|
+
}
|
|
3124
|
+
visitExpression(node, context) {
|
|
3125
|
+
let result;
|
|
3126
|
+
if (node.kind === ts.SyntaxKind.TrueKeyword) {
|
|
3127
|
+
return true;
|
|
3128
|
+
}
|
|
3129
|
+
else if (node.kind === ts.SyntaxKind.FalseKeyword) {
|
|
3130
|
+
return false;
|
|
3131
|
+
}
|
|
3132
|
+
else if (node.kind === ts.SyntaxKind.NullKeyword) {
|
|
3133
|
+
return null;
|
|
3134
|
+
}
|
|
3135
|
+
else if (ts.isStringLiteral(node)) {
|
|
3136
|
+
return node.text;
|
|
3137
|
+
}
|
|
3138
|
+
else if (ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
3139
|
+
return node.text;
|
|
3140
|
+
}
|
|
3141
|
+
else if (ts.isTemplateExpression(node)) {
|
|
3142
|
+
result = this.visitTemplateExpression(node, context);
|
|
3143
|
+
}
|
|
3144
|
+
else if (ts.isNumericLiteral(node)) {
|
|
3145
|
+
return parseFloat(node.text);
|
|
3146
|
+
}
|
|
3147
|
+
else if (ts.isObjectLiteralExpression(node)) {
|
|
3148
|
+
result = this.visitObjectLiteralExpression(node, context);
|
|
3149
|
+
}
|
|
3150
|
+
else if (ts.isIdentifier(node)) {
|
|
3151
|
+
result = this.visitIdentifier(node, context);
|
|
3152
|
+
}
|
|
3153
|
+
else if (ts.isPropertyAccessExpression(node)) {
|
|
3154
|
+
result = this.visitPropertyAccessExpression(node, context);
|
|
3155
|
+
}
|
|
3156
|
+
else if (ts.isCallExpression(node)) {
|
|
3157
|
+
result = this.visitCallExpression(node, context);
|
|
3158
|
+
}
|
|
3159
|
+
else if (ts.isConditionalExpression(node)) {
|
|
3160
|
+
result = this.visitConditionalExpression(node, context);
|
|
3161
|
+
}
|
|
3162
|
+
else if (ts.isPrefixUnaryExpression(node)) {
|
|
3163
|
+
result = this.visitPrefixUnaryExpression(node, context);
|
|
3164
|
+
}
|
|
3165
|
+
else if (ts.isBinaryExpression(node)) {
|
|
3166
|
+
result = this.visitBinaryExpression(node, context);
|
|
3167
|
+
}
|
|
3168
|
+
else if (ts.isArrayLiteralExpression(node)) {
|
|
3169
|
+
result = this.visitArrayLiteralExpression(node, context);
|
|
3170
|
+
}
|
|
3171
|
+
else if (ts.isParenthesizedExpression(node)) {
|
|
3172
|
+
result = this.visitParenthesizedExpression(node, context);
|
|
3173
|
+
}
|
|
3174
|
+
else if (ts.isElementAccessExpression(node)) {
|
|
3175
|
+
result = this.visitElementAccessExpression(node, context);
|
|
3176
|
+
}
|
|
3177
|
+
else if (ts.isAsExpression(node)) {
|
|
3178
|
+
result = this.visitExpression(node.expression, context);
|
|
3179
|
+
}
|
|
3180
|
+
else if (ts.isNonNullExpression(node)) {
|
|
3181
|
+
result = this.visitExpression(node.expression, context);
|
|
3182
|
+
}
|
|
3183
|
+
else if (this.host.isClass(node)) {
|
|
3184
|
+
result = this.visitDeclaration(node, context);
|
|
3185
|
+
}
|
|
3186
|
+
else {
|
|
3187
|
+
return checker.DynamicValue.fromUnsupportedSyntax(node);
|
|
3188
|
+
}
|
|
3189
|
+
if (result instanceof checker.DynamicValue && result.node !== node) {
|
|
3190
|
+
return checker.DynamicValue.fromDynamicInput(node, result);
|
|
3191
|
+
}
|
|
3192
|
+
return result;
|
|
3193
|
+
}
|
|
3194
|
+
visitArrayLiteralExpression(node, context) {
|
|
3195
|
+
const array = [];
|
|
3196
|
+
for (let i = 0; i < node.elements.length; i++) {
|
|
3197
|
+
const element = node.elements[i];
|
|
3198
|
+
if (ts.isSpreadElement(element)) {
|
|
3199
|
+
array.push(...this.visitSpreadElement(element, context));
|
|
3200
|
+
}
|
|
3201
|
+
else {
|
|
3202
|
+
array.push(this.visitExpression(element, context));
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
return array;
|
|
3206
|
+
}
|
|
3207
|
+
visitObjectLiteralExpression(node, context) {
|
|
3208
|
+
const map = new Map();
|
|
3209
|
+
for (let i = 0; i < node.properties.length; i++) {
|
|
3210
|
+
const property = node.properties[i];
|
|
3211
|
+
if (ts.isPropertyAssignment(property)) {
|
|
3212
|
+
const name = this.stringNameFromPropertyName(property.name, context);
|
|
3213
|
+
// Check whether the name can be determined statically.
|
|
3214
|
+
if (name === undefined) {
|
|
3215
|
+
return checker.DynamicValue.fromDynamicInput(node, checker.DynamicValue.fromDynamicString(property.name));
|
|
3216
|
+
}
|
|
3217
|
+
map.set(name, this.visitExpression(property.initializer, context));
|
|
3218
|
+
}
|
|
3219
|
+
else if (ts.isShorthandPropertyAssignment(property)) {
|
|
3220
|
+
const symbol = this.checker.getShorthandAssignmentValueSymbol(property);
|
|
3221
|
+
if (symbol === undefined || symbol.valueDeclaration === undefined) {
|
|
3222
|
+
map.set(property.name.text, checker.DynamicValue.fromUnknown(property));
|
|
3223
|
+
}
|
|
3224
|
+
else {
|
|
3225
|
+
map.set(property.name.text, this.visitDeclaration(symbol.valueDeclaration, context));
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
else if (ts.isSpreadAssignment(property)) {
|
|
3229
|
+
const spread = this.visitExpression(property.expression, context);
|
|
3230
|
+
if (spread instanceof checker.DynamicValue) {
|
|
3231
|
+
return checker.DynamicValue.fromDynamicInput(node, spread);
|
|
3232
|
+
}
|
|
3233
|
+
else if (spread instanceof Map) {
|
|
3234
|
+
spread.forEach((value, key) => map.set(key, value));
|
|
3235
|
+
}
|
|
3236
|
+
else if (spread instanceof checker.ResolvedModule) {
|
|
3237
|
+
spread.getExports().forEach((value, key) => map.set(key, value));
|
|
3238
|
+
}
|
|
3239
|
+
else {
|
|
3240
|
+
return checker.DynamicValue.fromDynamicInput(node, checker.DynamicValue.fromInvalidExpressionType(property, spread));
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
else {
|
|
3244
|
+
return checker.DynamicValue.fromUnknown(node);
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
return map;
|
|
3248
|
+
}
|
|
3249
|
+
visitTemplateExpression(node, context) {
|
|
3250
|
+
const pieces = [node.head.text];
|
|
3251
|
+
for (let i = 0; i < node.templateSpans.length; i++) {
|
|
3252
|
+
const span = node.templateSpans[i];
|
|
3253
|
+
const value = literal(this.visit(span.expression, context), () => checker.DynamicValue.fromDynamicString(span.expression));
|
|
3254
|
+
if (value instanceof checker.DynamicValue) {
|
|
3255
|
+
return checker.DynamicValue.fromDynamicInput(node, value);
|
|
3256
|
+
}
|
|
3257
|
+
pieces.push(`${value}`, span.literal.text);
|
|
3258
|
+
}
|
|
3259
|
+
return pieces.join('');
|
|
3260
|
+
}
|
|
3261
|
+
visitIdentifier(node, context) {
|
|
3262
|
+
const decl = this.host.getDeclarationOfIdentifier(node);
|
|
3263
|
+
if (decl === null) {
|
|
3264
|
+
if (ts.identifierToKeywordKind(node) === ts.SyntaxKind.UndefinedKeyword) {
|
|
3265
|
+
return undefined;
|
|
3266
|
+
}
|
|
3267
|
+
else {
|
|
3268
|
+
// Check if the symbol here is imported.
|
|
3269
|
+
if (this.dependencyTracker !== null && this.host.getImportOfIdentifier(node) !== null) {
|
|
3270
|
+
// It was, but no declaration for the node could be found. This means that the dependency
|
|
3271
|
+
// graph for the current file cannot be properly updated to account for this (broken)
|
|
3272
|
+
// import. Instead, the originating file is reported as failing dependency analysis,
|
|
3273
|
+
// ensuring that future compilations will always attempt to re-resolve the previously
|
|
3274
|
+
// broken identifier.
|
|
3275
|
+
this.dependencyTracker.recordDependencyAnalysisFailure(context.originatingFile);
|
|
3276
|
+
}
|
|
3277
|
+
return checker.DynamicValue.fromUnknownIdentifier(node);
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
const declContext = { ...context, ...joinModuleContext(context, node, decl) };
|
|
3281
|
+
const result = this.visitDeclaration(decl.node, declContext);
|
|
3282
|
+
if (result instanceof checker.Reference) {
|
|
3283
|
+
// Only record identifiers to non-synthetic references. Synthetic references may not have the
|
|
3284
|
+
// same value at runtime as they do at compile time, so it's not legal to refer to them by the
|
|
3285
|
+
// identifier here.
|
|
3286
|
+
if (!result.synthetic) {
|
|
3287
|
+
result.addIdentifier(node);
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
else if (result instanceof checker.DynamicValue) {
|
|
3291
|
+
return checker.DynamicValue.fromDynamicInput(node, result);
|
|
3292
|
+
}
|
|
3293
|
+
return result;
|
|
3294
|
+
}
|
|
3295
|
+
visitDeclaration(node, context) {
|
|
3296
|
+
if (this.dependencyTracker !== null) {
|
|
3297
|
+
this.dependencyTracker.addDependency(context.originatingFile, node.getSourceFile());
|
|
3298
|
+
}
|
|
3299
|
+
if (this.host.isClass(node)) {
|
|
3300
|
+
return this.getReference(node, context);
|
|
3301
|
+
}
|
|
3302
|
+
else if (ts.isVariableDeclaration(node)) {
|
|
3303
|
+
return this.visitVariableDeclaration(node, context);
|
|
3304
|
+
}
|
|
3305
|
+
else if (ts.isParameter(node) && context.scope.has(node)) {
|
|
3306
|
+
return context.scope.get(node);
|
|
3307
|
+
}
|
|
3308
|
+
else if (ts.isExportAssignment(node)) {
|
|
3309
|
+
return this.visitExpression(node.expression, context);
|
|
3310
|
+
}
|
|
3311
|
+
else if (ts.isEnumDeclaration(node)) {
|
|
3312
|
+
return this.visitEnumDeclaration(node, context);
|
|
3313
|
+
}
|
|
3314
|
+
else if (ts.isSourceFile(node)) {
|
|
3315
|
+
return this.visitSourceFile(node, context);
|
|
3316
|
+
}
|
|
3317
|
+
else if (ts.isBindingElement(node)) {
|
|
3318
|
+
return this.visitBindingElement(node, context);
|
|
3319
|
+
}
|
|
3320
|
+
else {
|
|
3321
|
+
return this.getReference(node, context);
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
visitVariableDeclaration(node, context) {
|
|
3325
|
+
const value = this.host.getVariableValue(node);
|
|
3326
|
+
if (value !== null) {
|
|
3327
|
+
return this.visitExpression(value, context);
|
|
3328
|
+
}
|
|
3329
|
+
else if (isVariableDeclarationDeclared(node)) {
|
|
3330
|
+
// If the declaration has a literal type that can be statically reduced to a value, resolve to
|
|
3331
|
+
// that value. If not, the historical behavior for variable declarations is to return a
|
|
3332
|
+
// `Reference` to the variable, as the consumer could use it in a context where knowing its
|
|
3333
|
+
// static value is not necessary.
|
|
3334
|
+
//
|
|
3335
|
+
// Arguably, since the value cannot be statically determined, we should return a
|
|
3336
|
+
// `DynamicValue`. This returns a `Reference` because it's the same behavior as before
|
|
3337
|
+
// `visitType` was introduced.
|
|
3338
|
+
//
|
|
3339
|
+
// TODO(zarend): investigate switching to a `DynamicValue` and verify this won't break any
|
|
3340
|
+
// use cases, especially in ngcc
|
|
3341
|
+
if (node.type !== undefined) {
|
|
3342
|
+
const evaluatedType = this.visitType(node.type, context);
|
|
3343
|
+
if (!(evaluatedType instanceof checker.DynamicValue)) {
|
|
3344
|
+
return evaluatedType;
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
return this.getReference(node, context);
|
|
3348
|
+
}
|
|
3349
|
+
else {
|
|
3350
|
+
return undefined;
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3353
|
+
visitEnumDeclaration(node, context) {
|
|
3354
|
+
const enumRef = this.getReference(node, context);
|
|
3355
|
+
const map = new Map();
|
|
3356
|
+
node.members.forEach((member, index) => {
|
|
3357
|
+
const name = this.stringNameFromPropertyName(member.name, context);
|
|
3358
|
+
if (name !== undefined) {
|
|
3359
|
+
const resolved = member.initializer ? this.visit(member.initializer, context) : index;
|
|
3360
|
+
map.set(name, new checker.EnumValue(enumRef, name, resolved));
|
|
3361
|
+
}
|
|
3362
|
+
});
|
|
3363
|
+
return map;
|
|
3364
|
+
}
|
|
3365
|
+
visitElementAccessExpression(node, context) {
|
|
3366
|
+
const lhs = this.visitExpression(node.expression, context);
|
|
3367
|
+
if (lhs instanceof checker.DynamicValue) {
|
|
3368
|
+
return checker.DynamicValue.fromDynamicInput(node, lhs);
|
|
3369
|
+
}
|
|
3370
|
+
const rhs = this.visitExpression(node.argumentExpression, context);
|
|
3371
|
+
if (rhs instanceof checker.DynamicValue) {
|
|
3372
|
+
return checker.DynamicValue.fromDynamicInput(node, rhs);
|
|
3373
|
+
}
|
|
3374
|
+
if (typeof rhs !== 'string' && typeof rhs !== 'number') {
|
|
3375
|
+
return checker.DynamicValue.fromInvalidExpressionType(node, rhs);
|
|
3376
|
+
}
|
|
3377
|
+
return this.accessHelper(node, lhs, rhs, context);
|
|
3378
|
+
}
|
|
3379
|
+
visitPropertyAccessExpression(node, context) {
|
|
3380
|
+
const lhs = this.visitExpression(node.expression, context);
|
|
3381
|
+
const rhs = node.name.text;
|
|
3382
|
+
// TODO: handle reference to class declaration.
|
|
3383
|
+
if (lhs instanceof checker.DynamicValue) {
|
|
3384
|
+
return checker.DynamicValue.fromDynamicInput(node, lhs);
|
|
3385
|
+
}
|
|
3386
|
+
return this.accessHelper(node, lhs, rhs, context);
|
|
3387
|
+
}
|
|
3388
|
+
visitSourceFile(node, context) {
|
|
3389
|
+
const declarations = this.host.getExportsOfModule(node);
|
|
3390
|
+
if (declarations === null) {
|
|
3391
|
+
return checker.DynamicValue.fromUnknown(node);
|
|
3392
|
+
}
|
|
3393
|
+
return new checker.ResolvedModule(declarations, (decl) => {
|
|
3394
|
+
const declContext = {
|
|
3395
|
+
...context,
|
|
3396
|
+
...joinModuleContext(context, node, decl),
|
|
3397
|
+
};
|
|
3398
|
+
// Visit both concrete and inline declarations.
|
|
3399
|
+
return this.visitDeclaration(decl.node, declContext);
|
|
3400
|
+
});
|
|
3401
|
+
}
|
|
3402
|
+
accessHelper(node, lhs, rhs, context) {
|
|
3403
|
+
const strIndex = `${rhs}`;
|
|
3404
|
+
if (lhs instanceof Map) {
|
|
3405
|
+
if (lhs.has(strIndex)) {
|
|
3406
|
+
return lhs.get(strIndex);
|
|
3407
|
+
}
|
|
3408
|
+
else {
|
|
3409
|
+
return undefined;
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
else if (lhs instanceof checker.ResolvedModule) {
|
|
3413
|
+
return lhs.getExport(strIndex);
|
|
3414
|
+
}
|
|
3415
|
+
else if (Array.isArray(lhs)) {
|
|
3416
|
+
if (rhs === 'length') {
|
|
3417
|
+
return lhs.length;
|
|
3418
|
+
}
|
|
3419
|
+
else if (rhs === 'slice') {
|
|
3420
|
+
return new ArraySliceBuiltinFn(lhs);
|
|
3421
|
+
}
|
|
3422
|
+
else if (rhs === 'concat') {
|
|
3423
|
+
return new ArrayConcatBuiltinFn(lhs);
|
|
3424
|
+
}
|
|
3425
|
+
if (typeof rhs !== 'number' || !Number.isInteger(rhs)) {
|
|
3426
|
+
return checker.DynamicValue.fromInvalidExpressionType(node, rhs);
|
|
3427
|
+
}
|
|
3428
|
+
return lhs[rhs];
|
|
3429
|
+
}
|
|
3430
|
+
else if (typeof lhs === 'string' && rhs === 'concat') {
|
|
3431
|
+
return new StringConcatBuiltinFn(lhs);
|
|
3432
|
+
}
|
|
3433
|
+
else if (lhs instanceof checker.Reference) {
|
|
3434
|
+
const ref = lhs.node;
|
|
3435
|
+
if (this.host.isClass(ref)) {
|
|
3436
|
+
const module = owningModule(context, lhs.bestGuessOwningModule);
|
|
3437
|
+
let value = undefined;
|
|
3438
|
+
const member = this.host
|
|
3439
|
+
.getMembersOfClass(ref)
|
|
3440
|
+
.find((member) => member.isStatic && member.name === strIndex);
|
|
3441
|
+
if (member !== undefined) {
|
|
3442
|
+
if (member.value !== null) {
|
|
3443
|
+
value = this.visitExpression(member.value, context);
|
|
3444
|
+
}
|
|
3445
|
+
else if (member.implementation !== null) {
|
|
3446
|
+
value = new checker.Reference(member.implementation, module);
|
|
3447
|
+
}
|
|
3448
|
+
else if (member.node) {
|
|
3449
|
+
value = new checker.Reference(member.node, module);
|
|
3450
|
+
}
|
|
3451
|
+
}
|
|
3452
|
+
return value;
|
|
3453
|
+
}
|
|
3454
|
+
else if (checker.isDeclaration(ref)) {
|
|
3455
|
+
return checker.DynamicValue.fromDynamicInput(node, checker.DynamicValue.fromExternalReference(ref, lhs));
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
else if (lhs instanceof checker.DynamicValue) {
|
|
3459
|
+
return checker.DynamicValue.fromDynamicInput(node, lhs);
|
|
3460
|
+
}
|
|
3461
|
+
else if (lhs instanceof SyntheticValue) {
|
|
3462
|
+
return checker.DynamicValue.fromSyntheticInput(node, lhs);
|
|
3463
|
+
}
|
|
3464
|
+
return checker.DynamicValue.fromUnknown(node);
|
|
3465
|
+
}
|
|
3466
|
+
visitCallExpression(node, context) {
|
|
3467
|
+
const lhs = this.visitExpression(node.expression, context);
|
|
3468
|
+
if (lhs instanceof checker.DynamicValue) {
|
|
3469
|
+
return checker.DynamicValue.fromDynamicInput(node, lhs);
|
|
3470
|
+
}
|
|
3471
|
+
// If the call refers to a builtin function, attempt to evaluate the function.
|
|
3472
|
+
if (lhs instanceof checker.KnownFn) {
|
|
3473
|
+
return lhs.evaluate(node, this.evaluateFunctionArguments(node, context));
|
|
3474
|
+
}
|
|
3475
|
+
if (!(lhs instanceof checker.Reference)) {
|
|
3476
|
+
return checker.DynamicValue.fromInvalidExpressionType(node.expression, lhs);
|
|
3477
|
+
}
|
|
3478
|
+
const fn = this.host.getDefinitionOfFunction(lhs.node);
|
|
3479
|
+
if (fn === null) {
|
|
3480
|
+
return checker.DynamicValue.fromInvalidExpressionType(node.expression, lhs);
|
|
3481
|
+
}
|
|
3482
|
+
if (!isFunctionOrMethodReference(lhs)) {
|
|
3483
|
+
return checker.DynamicValue.fromInvalidExpressionType(node.expression, lhs);
|
|
3484
|
+
}
|
|
3485
|
+
const resolveFfrExpr = (expr) => {
|
|
3486
|
+
let contextExtension = {};
|
|
3487
|
+
// TODO(alxhub): the condition `fn.body === null` here is vestigial - we probably _do_ want to
|
|
3488
|
+
// change the context like this even for non-null function bodies. But, this is being
|
|
3489
|
+
// redesigned as a refactoring with no behavior changes so that should be done as a follow-up.
|
|
3490
|
+
if (fn.body === null &&
|
|
3491
|
+
expr.getSourceFile() !== node.expression.getSourceFile() &&
|
|
3492
|
+
lhs.bestGuessOwningModule !== null) {
|
|
3493
|
+
contextExtension = {
|
|
3494
|
+
absoluteModuleName: lhs.bestGuessOwningModule.specifier,
|
|
3495
|
+
resolutionContext: lhs.bestGuessOwningModule.resolutionContext,
|
|
3496
|
+
};
|
|
3497
|
+
}
|
|
3498
|
+
return this.visitFfrExpression(expr, { ...context, ...contextExtension });
|
|
3499
|
+
};
|
|
3500
|
+
// If the function is foreign (declared through a d.ts file), attempt to resolve it with the
|
|
3501
|
+
// foreignFunctionResolver, if one is specified.
|
|
3502
|
+
if (fn.body === null && context.foreignFunctionResolver !== undefined) {
|
|
3503
|
+
const unresolvable = checker.DynamicValue.fromDynamicInput(node, checker.DynamicValue.fromExternalReference(node.expression, lhs));
|
|
3504
|
+
return context.foreignFunctionResolver(lhs, node, resolveFfrExpr, unresolvable);
|
|
3505
|
+
}
|
|
3506
|
+
const res = this.visitFunctionBody(node, fn, context);
|
|
3507
|
+
// If the result of attempting to resolve the function body was a DynamicValue, attempt to use
|
|
3508
|
+
// the foreignFunctionResolver if one is present. This could still potentially yield a usable
|
|
3509
|
+
// value.
|
|
3510
|
+
if (res instanceof checker.DynamicValue && context.foreignFunctionResolver !== undefined) {
|
|
3511
|
+
const unresolvable = checker.DynamicValue.fromComplexFunctionCall(node, fn);
|
|
3512
|
+
return context.foreignFunctionResolver(lhs, node, resolveFfrExpr, unresolvable);
|
|
3513
|
+
}
|
|
3514
|
+
return res;
|
|
3515
|
+
}
|
|
3516
|
+
/**
|
|
3517
|
+
* Visit an expression which was extracted from a foreign-function resolver.
|
|
3518
|
+
*
|
|
3519
|
+
* This will process the result and ensure it's correct for FFR-resolved values, including marking
|
|
3520
|
+
* `Reference`s as synthetic.
|
|
3521
|
+
*/
|
|
3522
|
+
visitFfrExpression(expr, context) {
|
|
3523
|
+
const res = this.visitExpression(expr, context);
|
|
3524
|
+
if (res instanceof checker.Reference) {
|
|
3525
|
+
// This Reference was created synthetically, via a foreign function resolver. The real
|
|
3526
|
+
// runtime value of the function expression may be different than the foreign function
|
|
3527
|
+
// resolved value, so mark the Reference as synthetic to avoid it being misinterpreted.
|
|
3528
|
+
res.synthetic = true;
|
|
3529
|
+
}
|
|
3530
|
+
return res;
|
|
3531
|
+
}
|
|
3532
|
+
visitFunctionBody(node, fn, context) {
|
|
3533
|
+
if (fn.body === null) {
|
|
3534
|
+
return checker.DynamicValue.fromUnknown(node);
|
|
3535
|
+
}
|
|
3536
|
+
else if (fn.body.length !== 1 || !ts.isReturnStatement(fn.body[0])) {
|
|
3537
|
+
return checker.DynamicValue.fromComplexFunctionCall(node, fn);
|
|
3538
|
+
}
|
|
3539
|
+
const ret = fn.body[0];
|
|
3540
|
+
const args = this.evaluateFunctionArguments(node, context);
|
|
3541
|
+
const newScope = new Map();
|
|
3542
|
+
const calleeContext = { ...context, scope: newScope };
|
|
3543
|
+
fn.parameters.forEach((param, index) => {
|
|
3544
|
+
let arg = args[index];
|
|
3545
|
+
if (param.node.dotDotDotToken !== undefined) {
|
|
3546
|
+
arg = args.slice(index);
|
|
3547
|
+
}
|
|
3548
|
+
if (arg === undefined && param.initializer !== null) {
|
|
3549
|
+
arg = this.visitExpression(param.initializer, calleeContext);
|
|
3550
|
+
}
|
|
3551
|
+
newScope.set(param.node, arg);
|
|
3552
|
+
});
|
|
3553
|
+
return ret.expression !== undefined
|
|
3554
|
+
? this.visitExpression(ret.expression, calleeContext)
|
|
3555
|
+
: undefined;
|
|
3556
|
+
}
|
|
3557
|
+
visitConditionalExpression(node, context) {
|
|
3558
|
+
const condition = this.visitExpression(node.condition, context);
|
|
3559
|
+
if (condition instanceof checker.DynamicValue) {
|
|
3560
|
+
return checker.DynamicValue.fromDynamicInput(node, condition);
|
|
3561
|
+
}
|
|
3562
|
+
if (condition) {
|
|
3563
|
+
return this.visitExpression(node.whenTrue, context);
|
|
3564
|
+
}
|
|
3565
|
+
else {
|
|
3566
|
+
return this.visitExpression(node.whenFalse, context);
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
visitPrefixUnaryExpression(node, context) {
|
|
3570
|
+
const operatorKind = node.operator;
|
|
3571
|
+
if (!this.UNARY_OPERATORS.has(operatorKind)) {
|
|
3572
|
+
return checker.DynamicValue.fromUnsupportedSyntax(node);
|
|
3573
|
+
}
|
|
3574
|
+
const op = this.UNARY_OPERATORS.get(operatorKind);
|
|
3575
|
+
const value = this.visitExpression(node.operand, context);
|
|
3576
|
+
if (value instanceof checker.DynamicValue) {
|
|
3577
|
+
return checker.DynamicValue.fromDynamicInput(node, value);
|
|
3578
|
+
}
|
|
3579
|
+
else {
|
|
3580
|
+
return op(value);
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
visitBinaryExpression(node, context) {
|
|
3584
|
+
const tokenKind = node.operatorToken.kind;
|
|
3585
|
+
if (!this.BINARY_OPERATORS.has(tokenKind)) {
|
|
3586
|
+
return checker.DynamicValue.fromUnsupportedSyntax(node);
|
|
3587
|
+
}
|
|
3588
|
+
const opRecord = this.BINARY_OPERATORS.get(tokenKind);
|
|
3589
|
+
let lhs, rhs;
|
|
3590
|
+
if (opRecord.literal) {
|
|
3591
|
+
lhs = literal(this.visitExpression(node.left, context), (value) => checker.DynamicValue.fromInvalidExpressionType(node.left, value));
|
|
3592
|
+
rhs = literal(this.visitExpression(node.right, context), (value) => checker.DynamicValue.fromInvalidExpressionType(node.right, value));
|
|
3593
|
+
}
|
|
3594
|
+
else {
|
|
3595
|
+
lhs = this.visitExpression(node.left, context);
|
|
3596
|
+
rhs = this.visitExpression(node.right, context);
|
|
3597
|
+
}
|
|
3598
|
+
if (lhs instanceof checker.DynamicValue) {
|
|
3599
|
+
return checker.DynamicValue.fromDynamicInput(node, lhs);
|
|
3600
|
+
}
|
|
3601
|
+
else if (rhs instanceof checker.DynamicValue) {
|
|
3602
|
+
return checker.DynamicValue.fromDynamicInput(node, rhs);
|
|
3603
|
+
}
|
|
3604
|
+
else {
|
|
3605
|
+
return opRecord.op(lhs, rhs);
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
visitParenthesizedExpression(node, context) {
|
|
3609
|
+
return this.visitExpression(node.expression, context);
|
|
3610
|
+
}
|
|
3611
|
+
evaluateFunctionArguments(node, context) {
|
|
3612
|
+
const args = [];
|
|
3613
|
+
for (const arg of node.arguments) {
|
|
3614
|
+
if (ts.isSpreadElement(arg)) {
|
|
3615
|
+
args.push(...this.visitSpreadElement(arg, context));
|
|
3616
|
+
}
|
|
3617
|
+
else {
|
|
3618
|
+
args.push(this.visitExpression(arg, context));
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
return args;
|
|
3622
|
+
}
|
|
3623
|
+
visitSpreadElement(node, context) {
|
|
3624
|
+
const spread = this.visitExpression(node.expression, context);
|
|
3625
|
+
if (spread instanceof checker.DynamicValue) {
|
|
3626
|
+
return [checker.DynamicValue.fromDynamicInput(node, spread)];
|
|
3627
|
+
}
|
|
3628
|
+
else if (!Array.isArray(spread)) {
|
|
3629
|
+
return [checker.DynamicValue.fromInvalidExpressionType(node, spread)];
|
|
3630
|
+
}
|
|
3631
|
+
else {
|
|
3632
|
+
return spread;
|
|
3633
|
+
}
|
|
3634
|
+
}
|
|
3635
|
+
visitBindingElement(node, context) {
|
|
3636
|
+
const path = [];
|
|
3637
|
+
let closestDeclaration = node;
|
|
3638
|
+
while (ts.isBindingElement(closestDeclaration) ||
|
|
3639
|
+
ts.isArrayBindingPattern(closestDeclaration) ||
|
|
3640
|
+
ts.isObjectBindingPattern(closestDeclaration)) {
|
|
3641
|
+
if (ts.isBindingElement(closestDeclaration)) {
|
|
3642
|
+
path.unshift(closestDeclaration);
|
|
3643
|
+
}
|
|
3644
|
+
closestDeclaration = closestDeclaration.parent;
|
|
3645
|
+
}
|
|
3646
|
+
if (!ts.isVariableDeclaration(closestDeclaration) ||
|
|
3647
|
+
closestDeclaration.initializer === undefined) {
|
|
3648
|
+
return checker.DynamicValue.fromUnknown(node);
|
|
3649
|
+
}
|
|
3650
|
+
let value = this.visit(closestDeclaration.initializer, context);
|
|
3651
|
+
for (const element of path) {
|
|
3652
|
+
let key;
|
|
3653
|
+
if (ts.isArrayBindingPattern(element.parent)) {
|
|
3654
|
+
key = element.parent.elements.indexOf(element);
|
|
3655
|
+
}
|
|
3656
|
+
else {
|
|
3657
|
+
const name = element.propertyName || element.name;
|
|
3658
|
+
if (ts.isIdentifier(name)) {
|
|
3659
|
+
key = name.text;
|
|
3660
|
+
}
|
|
3661
|
+
else {
|
|
3662
|
+
return checker.DynamicValue.fromUnknown(element);
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
value = this.accessHelper(element, value, key, context);
|
|
3666
|
+
if (value instanceof checker.DynamicValue) {
|
|
3667
|
+
return value;
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
return value;
|
|
3671
|
+
}
|
|
3672
|
+
stringNameFromPropertyName(node, context) {
|
|
3673
|
+
if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node)) {
|
|
3674
|
+
return node.text;
|
|
3675
|
+
}
|
|
3676
|
+
else if (ts.isComputedPropertyName(node)) {
|
|
3677
|
+
const literal = this.visitExpression(node.expression, context);
|
|
3678
|
+
return typeof literal === 'string' ? literal : undefined;
|
|
3679
|
+
}
|
|
3680
|
+
else {
|
|
3681
|
+
return undefined;
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
getReference(node, context) {
|
|
3685
|
+
return new checker.Reference(node, owningModule(context));
|
|
3686
|
+
}
|
|
3687
|
+
visitType(node, context) {
|
|
3688
|
+
if (ts.isLiteralTypeNode(node)) {
|
|
3689
|
+
return this.visitExpression(node.literal, context);
|
|
3690
|
+
}
|
|
3691
|
+
else if (ts.isTupleTypeNode(node)) {
|
|
3692
|
+
return this.visitTupleType(node, context);
|
|
3693
|
+
}
|
|
3694
|
+
else if (ts.isNamedTupleMember(node)) {
|
|
3695
|
+
return this.visitType(node.type, context);
|
|
3696
|
+
}
|
|
3697
|
+
else if (ts.isTypeOperatorNode(node) && node.operator === ts.SyntaxKind.ReadonlyKeyword) {
|
|
3698
|
+
return this.visitType(node.type, context);
|
|
3699
|
+
}
|
|
3700
|
+
else if (ts.isTypeQueryNode(node)) {
|
|
3701
|
+
return this.visitTypeQuery(node, context);
|
|
3702
|
+
}
|
|
3703
|
+
return checker.DynamicValue.fromDynamicType(node);
|
|
3704
|
+
}
|
|
3705
|
+
visitTupleType(node, context) {
|
|
3706
|
+
const res = [];
|
|
3707
|
+
for (const elem of node.elements) {
|
|
3708
|
+
res.push(this.visitType(elem, context));
|
|
3709
|
+
}
|
|
3710
|
+
return res;
|
|
3711
|
+
}
|
|
3712
|
+
visitTypeQuery(node, context) {
|
|
3713
|
+
if (!ts.isIdentifier(node.exprName)) {
|
|
3714
|
+
return checker.DynamicValue.fromUnknown(node);
|
|
3715
|
+
}
|
|
3716
|
+
const decl = this.host.getDeclarationOfIdentifier(node.exprName);
|
|
3717
|
+
if (decl === null) {
|
|
3718
|
+
return checker.DynamicValue.fromUnknownIdentifier(node.exprName);
|
|
3719
|
+
}
|
|
3720
|
+
const declContext = { ...context, ...joinModuleContext(context, node, decl) };
|
|
3721
|
+
return this.visitDeclaration(decl.node, declContext);
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
function isFunctionOrMethodReference(ref) {
|
|
3725
|
+
return (ts.isFunctionDeclaration(ref.node) ||
|
|
3726
|
+
ts.isMethodDeclaration(ref.node) ||
|
|
3727
|
+
ts.isFunctionExpression(ref.node));
|
|
3728
|
+
}
|
|
3729
|
+
function literal(value, reject) {
|
|
3730
|
+
if (value instanceof checker.EnumValue) {
|
|
3731
|
+
value = value.resolved;
|
|
3732
|
+
}
|
|
3733
|
+
if (value instanceof checker.DynamicValue ||
|
|
3734
|
+
value === null ||
|
|
3735
|
+
value === undefined ||
|
|
3736
|
+
typeof value === 'string' ||
|
|
3737
|
+
typeof value === 'number' ||
|
|
3738
|
+
typeof value === 'boolean') {
|
|
3739
|
+
return value;
|
|
3740
|
+
}
|
|
3741
|
+
return reject(value);
|
|
3742
|
+
}
|
|
3743
|
+
function isVariableDeclarationDeclared(node) {
|
|
3744
|
+
if (node.parent === undefined || !ts.isVariableDeclarationList(node.parent)) {
|
|
3745
|
+
return false;
|
|
3746
|
+
}
|
|
3747
|
+
const declList = node.parent;
|
|
3748
|
+
if (declList.parent === undefined || !ts.isVariableStatement(declList.parent)) {
|
|
3749
|
+
return false;
|
|
3750
|
+
}
|
|
3751
|
+
const varStmt = declList.parent;
|
|
3752
|
+
const modifiers = ts.getModifiers(varStmt);
|
|
3753
|
+
return (modifiers !== undefined && modifiers.some((mod) => mod.kind === ts.SyntaxKind.DeclareKeyword));
|
|
3754
|
+
}
|
|
3755
|
+
const EMPTY = {};
|
|
3756
|
+
function joinModuleContext(existing, node, decl) {
|
|
3757
|
+
if (typeof decl.viaModule === 'string' && decl.viaModule !== existing.absoluteModuleName) {
|
|
3758
|
+
return {
|
|
3759
|
+
absoluteModuleName: decl.viaModule,
|
|
3760
|
+
resolutionContext: node.getSourceFile().fileName,
|
|
3761
|
+
};
|
|
3762
|
+
}
|
|
3763
|
+
else {
|
|
3764
|
+
return EMPTY;
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
function owningModule(context, override = null) {
|
|
3768
|
+
let specifier = context.absoluteModuleName;
|
|
3769
|
+
if (override !== null) {
|
|
3770
|
+
specifier = override.specifier;
|
|
3771
|
+
}
|
|
3772
|
+
if (specifier !== null) {
|
|
3773
|
+
return {
|
|
3774
|
+
specifier,
|
|
3775
|
+
resolutionContext: context.resolutionContext,
|
|
3776
|
+
};
|
|
3777
|
+
}
|
|
3778
|
+
else {
|
|
3779
|
+
return null;
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
|
|
2999
3783
|
class PartialEvaluator {
|
|
3000
3784
|
host;
|
|
3001
3785
|
checker;
|
|
@@ -3006,7 +3790,7 @@ class PartialEvaluator {
|
|
|
3006
3790
|
this.dependencyTracker = dependencyTracker;
|
|
3007
3791
|
}
|
|
3008
3792
|
evaluate(expr, foreignFunctionResolver) {
|
|
3009
|
-
const interpreter = new
|
|
3793
|
+
const interpreter = new StaticInterpreter(this.host, this.checker, this.dependencyTracker);
|
|
3010
3794
|
const sourceFile = expr.getSourceFile();
|
|
3011
3795
|
return interpreter.visit(expr, {
|
|
3012
3796
|
originatingFile: sourceFile,
|
|
@@ -7413,7 +8197,7 @@ function createModuleWithProvidersResolver(reflector, isCore) {
|
|
|
7413
8197
|
if (!(ngModule instanceof checker.Reference) || !checker.isNamedClassDeclaration(ngModule.node)) {
|
|
7414
8198
|
return unresolvable;
|
|
7415
8199
|
}
|
|
7416
|
-
return new
|
|
8200
|
+
return new SyntheticValue({
|
|
7417
8201
|
ngModule: ngModule,
|
|
7418
8202
|
mwpCall: callExpr,
|
|
7419
8203
|
});
|
|
@@ -8168,7 +8952,7 @@ class NgModuleDecoratorHandler {
|
|
|
8168
8952
|
let entry = resolvedList[idx];
|
|
8169
8953
|
// Unwrap ModuleWithProviders for modules that are locally declared (and thus static
|
|
8170
8954
|
// resolution was able to descend into the function and return an object literal, a Map).
|
|
8171
|
-
if (entry instanceof
|
|
8955
|
+
if (entry instanceof SyntheticValue && isResolvedModuleWithProviders(entry)) {
|
|
8172
8956
|
entry = entry.value.ngModule;
|
|
8173
8957
|
hasModuleWithProviders = true;
|
|
8174
8958
|
}
|
|
@@ -8858,7 +9642,7 @@ function validateAndFlattenComponentImports(imports, expr, isDeferred) {
|
|
|
8858
9642
|
}
|
|
8859
9643
|
else if (isLikelyModuleWithProviders(ref)) {
|
|
8860
9644
|
let origin = expr;
|
|
8861
|
-
if (ref instanceof
|
|
9645
|
+
if (ref instanceof SyntheticValue) {
|
|
8862
9646
|
// The `ModuleWithProviders` type originated from a foreign function declaration, in which
|
|
8863
9647
|
// case the original foreign call is available which is used to get a more accurate origin
|
|
8864
9648
|
// node that points at the specific call expression.
|
|
@@ -8901,7 +9685,7 @@ function validateAndFlattenComponentImports(imports, expr, isDeferred) {
|
|
|
8901
9685
|
* key is considered a `ModuleWithProviders`.
|
|
8902
9686
|
*/
|
|
8903
9687
|
function isLikelyModuleWithProviders(value) {
|
|
8904
|
-
if (value instanceof
|
|
9688
|
+
if (value instanceof SyntheticValue && isResolvedModuleWithProviders(value)) {
|
|
8905
9689
|
// This is a `ModuleWithProviders` as extracted from a foreign function call.
|
|
8906
9690
|
return true;
|
|
8907
9691
|
}
|
|
@@ -11537,7 +12321,7 @@ class PipeDecoratorHandler {
|
|
|
11537
12321
|
* @description
|
|
11538
12322
|
* Entry point for all public APIs of the compiler-cli package.
|
|
11539
12323
|
*/
|
|
11540
|
-
new checker.Version('20.
|
|
12324
|
+
new checker.Version('20.2.0-next.0');
|
|
11541
12325
|
|
|
11542
12326
|
/**
|
|
11543
12327
|
* Whether a given decorator should be treated as an Angular decorator.
|
|
@@ -13444,11 +14228,18 @@ function extractLiteralPropertiesAsEnumMembers(declaration) {
|
|
|
13444
14228
|
|
|
13445
14229
|
/** Extracts an API documentation entry for an Angular decorator. */
|
|
13446
14230
|
function extractorDecorator(declaration, typeChecker) {
|
|
13447
|
-
const documentedNode = getDecoratorJsDocNode(declaration);
|
|
14231
|
+
const documentedNode = getDecoratorJsDocNode(declaration, typeChecker);
|
|
13448
14232
|
const decoratorType = getDecoratorType(declaration);
|
|
13449
14233
|
if (!decoratorType) {
|
|
13450
14234
|
throw new Error(`"${declaration.name.getText()} is not a decorator."`);
|
|
13451
14235
|
}
|
|
14236
|
+
const members = getDecoratorProperties(declaration, typeChecker);
|
|
14237
|
+
let signatures = [];
|
|
14238
|
+
if (!members) {
|
|
14239
|
+
const decoratorInterface = getDecoratorDeclaration(declaration, typeChecker);
|
|
14240
|
+
const callSignatures = decoratorInterface.members.filter(ts.isCallSignatureDeclaration);
|
|
14241
|
+
signatures = getDecoratorSignatures(callSignatures, typeChecker);
|
|
14242
|
+
}
|
|
13452
14243
|
return {
|
|
13453
14244
|
name: declaration.name.getText(),
|
|
13454
14245
|
decoratorType: decoratorType,
|
|
@@ -13456,7 +14247,8 @@ function extractorDecorator(declaration, typeChecker) {
|
|
|
13456
14247
|
rawComment: extractRawJsDoc(documentedNode),
|
|
13457
14248
|
description: extractJsDocDescription(documentedNode),
|
|
13458
14249
|
jsdocTags: extractJsDocTags(documentedNode),
|
|
13459
|
-
members
|
|
14250
|
+
members,
|
|
14251
|
+
signatures,
|
|
13460
14252
|
};
|
|
13461
14253
|
}
|
|
13462
14254
|
/** Gets whether the given variable declaration is an Angular decorator declaration. */
|
|
@@ -13483,35 +14275,77 @@ function getDecoratorType(declaration) {
|
|
|
13483
14275
|
return DecoratorType.Parameter;
|
|
13484
14276
|
return undefined;
|
|
13485
14277
|
}
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
const
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
const
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
});
|
|
13495
|
-
if (!optionsDeclaration) {
|
|
13496
|
-
throw new Error(`Decorator "${name}" has no corresponding options interface.`);
|
|
14278
|
+
function getDecoratorDeclaration(declaration, typeChecker) {
|
|
14279
|
+
const decoratorName = declaration.name.getText();
|
|
14280
|
+
const decoratorDeclaration = declaration;
|
|
14281
|
+
const decoratorType = typeChecker.getTypeAtLocation(decoratorDeclaration);
|
|
14282
|
+
const aliasDeclaration = decoratorType.getSymbol().getDeclarations()[0];
|
|
14283
|
+
const decoratorInterface = aliasDeclaration;
|
|
14284
|
+
if (!decoratorInterface || !ts.isInterfaceDeclaration(decoratorInterface)) {
|
|
14285
|
+
throw new Error(`No decorator interface found for "${decoratorName}".`);
|
|
13497
14286
|
}
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
14287
|
+
return decoratorInterface;
|
|
14288
|
+
}
|
|
14289
|
+
/**
|
|
14290
|
+
* @returns Interface properties for decorators that are akin to interfaces eg. @Component
|
|
14291
|
+
* else return null for decorators that are akin to functions eg. @Inject
|
|
14292
|
+
*/
|
|
14293
|
+
function getDecoratorProperties(declaration, typeChecker) {
|
|
14294
|
+
// Some decorators like Component, Directive are basically interchangeable with a interface declaration.
|
|
14295
|
+
// We want to acount for that and treat them a such.
|
|
14296
|
+
// To determine which type of decorator we have, we check the type of the first parameter of its call signature
|
|
14297
|
+
const decoratorCallSig = getDecoratorJsDocNode(declaration, typeChecker);
|
|
14298
|
+
const decoratorFirstParam = decoratorCallSig.parameters[0];
|
|
14299
|
+
const firstParamType = typeChecker.getTypeAtLocation(decoratorFirstParam);
|
|
14300
|
+
let firstParamTypeDecl;
|
|
14301
|
+
if (firstParamType.isUnion()) {
|
|
14302
|
+
// If the first param is a union, we need to get the first type
|
|
14303
|
+
// This happens for example when the decorator param is optional (eg @Directive())
|
|
14304
|
+
const firstParamTypeUnion = firstParamType.types.find((t) => (t.flags & ts.TypeFlags.Undefined) === 0);
|
|
14305
|
+
firstParamTypeDecl = firstParamTypeUnion?.getSymbol()?.getDeclarations()[0];
|
|
13505
14306
|
}
|
|
13506
14307
|
else {
|
|
13507
|
-
|
|
14308
|
+
firstParamTypeDecl = firstParamType.getSymbol()?.getDeclarations()[0];
|
|
13508
14309
|
}
|
|
13509
|
-
if (!
|
|
13510
|
-
|
|
14310
|
+
if (!firstParamTypeDecl || !ts.isInterfaceDeclaration(firstParamTypeDecl)) {
|
|
14311
|
+
// At this point we either have on first param, eg for decorators without parameters
|
|
14312
|
+
// or we have a decorator that isn't akin to an interface
|
|
14313
|
+
// We will threat them as functions (in another function) and return null here
|
|
14314
|
+
return null;
|
|
13511
14315
|
}
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
14316
|
+
const interfaceDeclaration = firstParamTypeDecl;
|
|
14317
|
+
return extractInterface(interfaceDeclaration, typeChecker).members;
|
|
14318
|
+
}
|
|
14319
|
+
function getDecoratorSignatures(callSignatures, typeChecker) {
|
|
14320
|
+
return callSignatures.map((signatureDecl) => {
|
|
14321
|
+
return {
|
|
14322
|
+
parameters: extractParams(signatureDecl.parameters, typeChecker),
|
|
14323
|
+
jsdocTags: extractJsDocTags(signatureDecl),
|
|
14324
|
+
};
|
|
14325
|
+
});
|
|
14326
|
+
}
|
|
14327
|
+
function extractParams(params, typeChecker) {
|
|
14328
|
+
return params.map((param) => ({
|
|
14329
|
+
name: param.name.getText(),
|
|
14330
|
+
description: extractJsDocDescription(param),
|
|
14331
|
+
type: getParamTypeString(param, typeChecker),
|
|
14332
|
+
isOptional: !!(param.questionToken || param.initializer),
|
|
14333
|
+
isRestParam: !!param.dotDotDotToken,
|
|
14334
|
+
}));
|
|
14335
|
+
}
|
|
14336
|
+
/**
|
|
14337
|
+
* Find the the interface usually suffixed with "Decorator" that describes the decorator.
|
|
14338
|
+
*/
|
|
14339
|
+
function getDecoratorInterface(declaration, typeChecker) {
|
|
14340
|
+
const name = declaration.name.getText();
|
|
14341
|
+
const symbol = typeChecker.getSymbolAtLocation(declaration.name);
|
|
14342
|
+
const decoratorType = typeChecker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);
|
|
14343
|
+
// This is the interface xxxxDecorator
|
|
14344
|
+
const decoratorInterface = decoratorType.getSymbol()?.getDeclarations()[0];
|
|
14345
|
+
if (!decoratorInterface || !ts.isInterfaceDeclaration(decoratorInterface)) {
|
|
14346
|
+
throw new Error(`No decorator interface found for "${name}".`);
|
|
14347
|
+
}
|
|
14348
|
+
return decoratorInterface;
|
|
13515
14349
|
}
|
|
13516
14350
|
/**
|
|
13517
14351
|
* Gets the call signature node that has the decorator's public JsDoc block.
|
|
@@ -13523,26 +14357,68 @@ function getDecoratorOptions(declaration, typeChecker) {
|
|
|
13523
14357
|
*
|
|
13524
14358
|
* For the description and JsDoc tags, we need the interface suffixed with "Decorator".
|
|
13525
14359
|
*/
|
|
13526
|
-
function getDecoratorJsDocNode(declaration) {
|
|
14360
|
+
function getDecoratorJsDocNode(declaration, typeChecker) {
|
|
13527
14361
|
const name = declaration.name.getText();
|
|
13528
|
-
|
|
13529
|
-
// suffixed with "Decorator".
|
|
13530
|
-
const decoratorInterface = declaration.getSourceFile().statements.find((s) => {
|
|
13531
|
-
return ts.isInterfaceDeclaration(s) && s.name.getText() === `${name}Decorator`;
|
|
13532
|
-
});
|
|
13533
|
-
if (!decoratorInterface || !ts.isInterfaceDeclaration(decoratorInterface)) {
|
|
13534
|
-
throw new Error(`No interface "${name}Decorator" found.`);
|
|
13535
|
-
}
|
|
14362
|
+
const decoratorInterface = getDecoratorInterface(declaration, typeChecker);
|
|
13536
14363
|
// The public-facing JsDoc for each decorator is on one of its interface's call signatures.
|
|
13537
|
-
const callSignature = decoratorInterface.members
|
|
14364
|
+
const callSignature = decoratorInterface.members
|
|
14365
|
+
.filter((node) => {
|
|
13538
14366
|
// The description block lives on one of the call signatures for this interface.
|
|
13539
14367
|
return ts.isCallSignatureDeclaration(node) && extractRawJsDoc(node);
|
|
13540
|
-
})
|
|
14368
|
+
})
|
|
14369
|
+
.at(-1); // Get the last one, as it is the most complete
|
|
13541
14370
|
if (!callSignature || !ts.isCallSignatureDeclaration(callSignature)) {
|
|
13542
14371
|
throw new Error(`No call signature with JsDoc on "${name}Decorator"`);
|
|
13543
14372
|
}
|
|
13544
14373
|
return callSignature;
|
|
13545
14374
|
}
|
|
14375
|
+
/**
|
|
14376
|
+
* Advanced function to generate the type string (as single line) for a parameter.
|
|
14377
|
+
* Interfaces in unions are expanded.
|
|
14378
|
+
*/
|
|
14379
|
+
function getParamTypeString(paramNode, typeChecker) {
|
|
14380
|
+
const type = typeChecker.getTypeAtLocation(paramNode);
|
|
14381
|
+
const printer = ts.createPrinter({ removeComments: true });
|
|
14382
|
+
const sourceFile = paramNode.getSourceFile();
|
|
14383
|
+
const replace = [];
|
|
14384
|
+
if (type.isUnion()) {
|
|
14385
|
+
// The parameter can be a union, this includes optional parameters whiceh are a union of the type and undefined.
|
|
14386
|
+
for (const subType of type.types) {
|
|
14387
|
+
const decl = subType.getSymbol()?.getDeclarations()?.[0];
|
|
14388
|
+
// We only care to expand interfaces
|
|
14389
|
+
if (decl && ts.isInterfaceDeclaration(decl) && decl.name.text !== 'Function') {
|
|
14390
|
+
// the Function type is actually an interface but we don't want to expand it
|
|
14391
|
+
replace.push({
|
|
14392
|
+
initial: subType.symbol.name,
|
|
14393
|
+
replacedWith: expandType(decl, sourceFile, printer),
|
|
14394
|
+
});
|
|
14395
|
+
}
|
|
14396
|
+
}
|
|
14397
|
+
}
|
|
14398
|
+
// Using a print here instead of typeToString as it doesn't return optional props as a union of undefined
|
|
14399
|
+
let result = printer
|
|
14400
|
+
.printNode(ts.EmitHint.Unspecified, paramNode, sourceFile)
|
|
14401
|
+
// Removing the parameter name, the conditional question mark and the colon (e.g. opts?: {foo: string})
|
|
14402
|
+
.replace(new RegExp(`${paramNode.name.getText()}\\??\: `), '')
|
|
14403
|
+
// Remove extra spaces/line breaks
|
|
14404
|
+
.replaceAll(/\s+/g, ' ');
|
|
14405
|
+
// Replace the types we expanded
|
|
14406
|
+
for (const { initial, replacedWith } of replace) {
|
|
14407
|
+
result = result.replace(initial, replacedWith);
|
|
14408
|
+
}
|
|
14409
|
+
return result;
|
|
14410
|
+
}
|
|
14411
|
+
/**
|
|
14412
|
+
* @return a given interface declaration as single line string
|
|
14413
|
+
*/
|
|
14414
|
+
function expandType(decl, sourceFile, printer) {
|
|
14415
|
+
const props = decl.members
|
|
14416
|
+
// printer will return each member with a semicolon at the end
|
|
14417
|
+
.map((member) => printer.printNode(ts.EmitHint.Unspecified, member, sourceFile))
|
|
14418
|
+
.join(' ')
|
|
14419
|
+
.replaceAll(/\s+/g, ' '); // Remove extra spaces/line breaks
|
|
14420
|
+
return `{${props}}`;
|
|
14421
|
+
}
|
|
13546
14422
|
|
|
13547
14423
|
/** Extracts documentation entry for an enum. */
|
|
13548
14424
|
function extractEnum(declaration, typeChecker) {
|
|
@@ -19402,7 +20278,7 @@ var semver = /*@__PURE__*/getDefaultExportFromCjs(semverExports);
|
|
|
19402
20278
|
* @param minVersion Minimum required version for the feature.
|
|
19403
20279
|
*/
|
|
19404
20280
|
function coreVersionSupportsFeature(coreVersion, minVersion) {
|
|
19405
|
-
// A version of `20.
|
|
20281
|
+
// A version of `20.2.0-next.0` usually means that core is at head so it supports
|
|
19406
20282
|
// all features. Use string interpolation prevent the placeholder from being replaced
|
|
19407
20283
|
// with the current version during build time.
|
|
19408
20284
|
if (coreVersion === `0.0.0-${'PLACEHOLDER'}`) {
|