@markw65/monkeyc-optimizer 1.1.4 → 1.1.5
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/README.md +6 -0
- package/build/api.cjs +138 -43
- package/build/optimizer.cjs +138 -44
- package/build/src/optimizer-types.d.ts +1 -0
- package/build/src/type-flow.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -636,3 +636,9 @@ Bug Fixes
|
|
|
636
636
|
- Code cleanup
|
|
637
637
|
- refactor some of the type code for better type safety
|
|
638
638
|
- turn on the eslint rule eqeqeq and fix all the issues
|
|
639
|
+
|
|
640
|
+
### 1.1.5
|
|
641
|
+
|
|
642
|
+
- Bug fixes
|
|
643
|
+
- Always evaluate a constant's initializer to determine its type
|
|
644
|
+
- Fix a bug refining the object type based on the properties it accesses that could lose the type of the object.
|
package/build/api.cjs
CHANGED
|
@@ -3022,45 +3022,115 @@ function printBlockState(block, state, indent = "") {
|
|
|
3022
3022
|
console.log(`${indent} - ${typeStateEntry(value, key)}${value.equivSet ? " " + tsEquivs(state, key) : ""}`);
|
|
3023
3023
|
});
|
|
3024
3024
|
}
|
|
3025
|
-
|
|
3025
|
+
/*
|
|
3026
|
+
* We have an object, and a MemberExpression object.<name>
|
|
3027
|
+
* - decls are the StateNodes associated with the known type
|
|
3028
|
+
* of object.
|
|
3029
|
+
* - possible are all the StateNodes that declare <name>
|
|
3030
|
+
*
|
|
3031
|
+
* We want to find all the elements of possible which are
|
|
3032
|
+
* "compatible" with decls, which tells us the set of things
|
|
3033
|
+
* that object.<name> could correspond to, and also what that
|
|
3034
|
+
* tells us about object.
|
|
3035
|
+
*
|
|
3036
|
+
* The return value is two arrays of StateNode. The first
|
|
3037
|
+
* gives the refined type of object, and the second is the
|
|
3038
|
+
* array of StateNodes that could declare <name>
|
|
3039
|
+
*/
|
|
3040
|
+
function filterDecls(decls, possible, name) {
|
|
3026
3041
|
if (!possible)
|
|
3027
|
-
return null;
|
|
3028
|
-
|
|
3042
|
+
return [null, null];
|
|
3043
|
+
const result = decls.reduce((cur, decl) => {
|
|
3029
3044
|
const found = possible.reduce((flag, poss) => {
|
|
3030
3045
|
if (decl === poss ||
|
|
3031
|
-
(poss.type === "ClassDeclaration" &&
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
cur
|
|
3046
|
+
(poss.type === "ClassDeclaration" && (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(poss)?.has(decl))) {
|
|
3047
|
+
// poss extends decl, so decl must actually be a poss
|
|
3048
|
+
// eg we know obj is an Object, and we call obj.toNumber
|
|
3049
|
+
// so possible includes all the classes that declare toNumber
|
|
3050
|
+
// so we can refine obj's type to the union of those types
|
|
3051
|
+
if (!cur[0]) {
|
|
3052
|
+
cur = [new Set(), new Set()];
|
|
3053
|
+
}
|
|
3054
|
+
cur[0].add(poss);
|
|
3055
|
+
cur[1].add(poss);
|
|
3056
|
+
return true;
|
|
3057
|
+
}
|
|
3058
|
+
else if (decl.type === "ClassDeclaration" &&
|
|
3059
|
+
(0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(decl)?.has(poss)) {
|
|
3060
|
+
// decl extends poss, so decl remains unchanged
|
|
3061
|
+
// eg we know obj is Menu2, we call obj.toString
|
|
3062
|
+
// Menu2 doesn't define toString, but Object does
|
|
3063
|
+
// so poss is Object. But we still know that
|
|
3064
|
+
// obj is Menu2
|
|
3065
|
+
if (!cur[0]) {
|
|
3066
|
+
cur = [new Set(), new Set()];
|
|
3067
|
+
}
|
|
3068
|
+
cur[0].add(decl);
|
|
3069
|
+
cur[1].add(poss);
|
|
3038
3070
|
return true;
|
|
3039
3071
|
}
|
|
3040
3072
|
return flag;
|
|
3041
3073
|
}, false);
|
|
3042
3074
|
if (!found) {
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3075
|
+
// If we didn't find the property in any of the
|
|
3076
|
+
// standard places, the runtime might still find
|
|
3077
|
+
// it by searching up the Module stack (and up
|
|
3078
|
+
// the module stack from any super classes)
|
|
3079
|
+
//
|
|
3080
|
+
// eg
|
|
3081
|
+
//
|
|
3082
|
+
// obj = Application.getApp();
|
|
3083
|
+
// obj.Properties.whatever
|
|
3084
|
+
//
|
|
3085
|
+
// Properties doesn't exist on AppBase, but AppBase
|
|
3086
|
+
// is declared in Application, and Application
|
|
3087
|
+
// does declare Properties. So Application.Properties
|
|
3088
|
+
// is (one of) the declarations we should find; but we
|
|
3089
|
+
// must not refine obj's type to include Application.
|
|
3090
|
+
let d = [decl];
|
|
3091
|
+
do {
|
|
3092
|
+
d.forEach((d) => {
|
|
3093
|
+
const stack = d.stack;
|
|
3094
|
+
possible.forEach((poss) => {
|
|
3095
|
+
for (let i = stack.length; i--;) {
|
|
3096
|
+
const sn = stack[i];
|
|
3097
|
+
if (sn.decls === poss.decls) {
|
|
3098
|
+
if (!cur[0]) {
|
|
3099
|
+
cur = [new Set(), new Set()];
|
|
3100
|
+
}
|
|
3101
|
+
cur[0].add(decl);
|
|
3102
|
+
cur[1].add(poss);
|
|
3103
|
+
break;
|
|
3104
|
+
}
|
|
3105
|
+
if ((0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(sn.decls, name)) {
|
|
3106
|
+
break;
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
});
|
|
3110
|
+
});
|
|
3111
|
+
d = d.flatMap((d) => {
|
|
3112
|
+
if (d.type !== "ClassDeclaration" ||
|
|
3113
|
+
!d.superClass ||
|
|
3114
|
+
d.superClass === true) {
|
|
3115
|
+
return [];
|
|
3116
|
+
}
|
|
3117
|
+
return d.superClass;
|
|
3118
|
+
});
|
|
3119
|
+
} while (d.length);
|
|
3053
3120
|
}
|
|
3054
3121
|
return cur;
|
|
3055
|
-
}, null);
|
|
3122
|
+
}, [null, null]);
|
|
3123
|
+
if (!result[0])
|
|
3124
|
+
return [null, null];
|
|
3125
|
+
return [Array.from(result[0]), Array.from(result[1])];
|
|
3056
3126
|
}
|
|
3057
3127
|
function findObjectDeclsByProperty(state, object, next) {
|
|
3058
3128
|
const decls = (0,_type_flow_types__WEBPACK_IMPORTED_MODULE_11__/* .getStateNodeDeclsFromType */ .iX)(state, object);
|
|
3059
3129
|
if (!decls)
|
|
3060
|
-
return null;
|
|
3130
|
+
return [null, null];
|
|
3061
3131
|
const possibleDecls = (0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(state.allDeclarations, next.property.name) &&
|
|
3062
3132
|
state.allDeclarations[next.property.name];
|
|
3063
|
-
return filterDecls(decls, possibleDecls);
|
|
3133
|
+
return filterDecls(decls, possibleDecls, next.property.name);
|
|
3064
3134
|
}
|
|
3065
3135
|
function refineObjectTypeByDecls(istate, object, trueDecls) {
|
|
3066
3136
|
const refinedType = typeFromTypeStateNodes(istate.state, trueDecls);
|
|
@@ -3076,13 +3146,13 @@ function findNextObjectType(istate, trueDecls, next) {
|
|
|
3076
3146
|
}, { type: 0 /* TypeTag.Never */ });
|
|
3077
3147
|
}
|
|
3078
3148
|
function resolveDottedMember(istate, object, next) {
|
|
3079
|
-
const
|
|
3080
|
-
if (!
|
|
3149
|
+
const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, object, next);
|
|
3150
|
+
if (!objDecls)
|
|
3081
3151
|
return null;
|
|
3082
|
-
const property = findNextObjectType(istate,
|
|
3152
|
+
const property = findNextObjectType(istate, trueDecls, next);
|
|
3083
3153
|
if (!property)
|
|
3084
3154
|
return null;
|
|
3085
|
-
const type = refineObjectTypeByDecls(istate, object,
|
|
3155
|
+
const type = refineObjectTypeByDecls(istate, object, objDecls);
|
|
3086
3156
|
const mayThrow = !subtypeOf(object, type);
|
|
3087
3157
|
return { mayThrow, object: type, property };
|
|
3088
3158
|
}
|
|
@@ -3119,11 +3189,11 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
|
|
|
3119
3189
|
next = value.obj[me.property.name];
|
|
3120
3190
|
}
|
|
3121
3191
|
else {
|
|
3122
|
-
const trueDecls = findObjectDeclsByProperty(istate.state, cur, me);
|
|
3123
|
-
if (!
|
|
3192
|
+
const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, cur, me);
|
|
3193
|
+
if (!objDecls) {
|
|
3124
3194
|
return null;
|
|
3125
3195
|
}
|
|
3126
|
-
cur = refineObjectTypeByDecls(istate, cur,
|
|
3196
|
+
cur = refineObjectTypeByDecls(istate, cur, objDecls);
|
|
3127
3197
|
next = findNextObjectType(istate, trueDecls, me);
|
|
3128
3198
|
}
|
|
3129
3199
|
}
|
|
@@ -5288,9 +5358,9 @@ function getLhsConstraint(istate, node) {
|
|
|
5288
5358
|
}
|
|
5289
5359
|
const object = istate.typeMap.get(node.object);
|
|
5290
5360
|
if (object && !node.computed) {
|
|
5291
|
-
const
|
|
5292
|
-
if (
|
|
5293
|
-
lookupDefs = lookupNext(istate.state, [{ parent: null, results:
|
|
5361
|
+
const [, trueDecls] = findObjectDeclsByProperty(istate.state, object, node);
|
|
5362
|
+
if (trueDecls) {
|
|
5363
|
+
lookupDefs = lookupNext(istate.state, [{ parent: null, results: trueDecls }], "decls", node.property);
|
|
5294
5364
|
}
|
|
5295
5365
|
}
|
|
5296
5366
|
}
|
|
@@ -6643,6 +6713,8 @@ function printBlockTrailer(block) {
|
|
|
6643
6713
|
/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_4__);
|
|
6644
6714
|
/* harmony import */ var _interp__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7161);
|
|
6645
6715
|
/* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(757);
|
|
6716
|
+
/* harmony import */ var _intersection_type__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(6973);
|
|
6717
|
+
|
|
6646
6718
|
|
|
6647
6719
|
|
|
6648
6720
|
|
|
@@ -6866,24 +6938,47 @@ function typeFromTypeStateNode(state, sn, classVsObj) {
|
|
|
6866
6938
|
sn.resolvedType = result;
|
|
6867
6939
|
return result;
|
|
6868
6940
|
}
|
|
6869
|
-
case "VariableDeclarator":
|
|
6941
|
+
case "VariableDeclarator": {
|
|
6942
|
+
if (sn.resolvedType)
|
|
6943
|
+
return sn.resolvedType;
|
|
6944
|
+
let declared = null;
|
|
6945
|
+
if (sn.node.id.type === "BinaryExpression") {
|
|
6946
|
+
declared = typeFromTypespec(state, sn.node.id.right, sn.stack);
|
|
6947
|
+
}
|
|
6870
6948
|
if (sn.node.kind === "const" && sn.node.init) {
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
return
|
|
6949
|
+
if (hasProperty(sn, "resolvedType")) {
|
|
6950
|
+
// The constant is defined recursively
|
|
6951
|
+
return declared ?? { type: 524287 /* TypeTag.Any */ };
|
|
6952
|
+
}
|
|
6953
|
+
// set the marker in case the constant appears in its
|
|
6954
|
+
// own initializer.
|
|
6955
|
+
sn.resolvedType = undefined;
|
|
6956
|
+
const stack = state.stack;
|
|
6957
|
+
let resolved;
|
|
6958
|
+
try {
|
|
6959
|
+
state.stack = sn.stack;
|
|
6960
|
+
resolved = evaluateExpr(state, sn.node.init).value;
|
|
6961
|
+
}
|
|
6962
|
+
finally {
|
|
6963
|
+
state.stack = stack;
|
|
6874
6964
|
}
|
|
6875
|
-
|
|
6876
|
-
|
|
6965
|
+
if (resolved.type === 0 /* TypeTag.Never */) {
|
|
6966
|
+
resolved = declared ?? { type: 524287 /* TypeTag.Any */ };
|
|
6877
6967
|
}
|
|
6878
|
-
if (
|
|
6879
|
-
|
|
6880
|
-
|
|
6968
|
+
else if (declared) {
|
|
6969
|
+
resolved = intersection(resolved, declared);
|
|
6970
|
+
if (resolved.type === 0 /* TypeTag.Never */) {
|
|
6971
|
+
resolved = declared;
|
|
6972
|
+
}
|
|
6881
6973
|
}
|
|
6974
|
+
sn.resolvedType = resolved;
|
|
6975
|
+
return resolved;
|
|
6882
6976
|
}
|
|
6883
6977
|
if (sn.node.id.type === "BinaryExpression") {
|
|
6884
6978
|
return typeFromTypespec(state, sn.node.id.right, sn.stack);
|
|
6885
6979
|
}
|
|
6886
6980
|
return { type: 524287 /* TypeTag.Any */ };
|
|
6981
|
+
}
|
|
6887
6982
|
}
|
|
6888
6983
|
throw new Error(`Internal error: Unexpected StateNodeDecl.type: ${sn.type}`);
|
|
6889
6984
|
}
|
|
@@ -8602,7 +8697,7 @@ function visitReferences(state, ast, name, defn, callback, includeDefs = false,
|
|
|
8602
8697
|
const objectType = typeMap.get(node.object);
|
|
8603
8698
|
if (!objectType)
|
|
8604
8699
|
return results;
|
|
8605
|
-
const decls = (0,type_flow/* findObjectDeclsByProperty */.nK)(state, objectType, node);
|
|
8700
|
+
const [, decls] = (0,type_flow/* findObjectDeclsByProperty */.nK)(state, objectType, node);
|
|
8606
8701
|
if (decls) {
|
|
8607
8702
|
const next = (0,external_api_cjs_.lookupNext)(state, [{ parent: null, results: decls }], "decls", node.property);
|
|
8608
8703
|
if (next) {
|
package/build/optimizer.cjs
CHANGED
|
@@ -9257,6 +9257,7 @@ function widenType(t) {
|
|
|
9257
9257
|
|
|
9258
9258
|
|
|
9259
9259
|
|
|
9260
|
+
|
|
9260
9261
|
function typeTagName(tag) {
|
|
9261
9262
|
switch (tag) {
|
|
9262
9263
|
case 0 /* TypeTag.Never */:
|
|
@@ -9473,24 +9474,47 @@ function typeFromTypeStateNode(state, sn, classVsObj) {
|
|
|
9473
9474
|
sn.resolvedType = result;
|
|
9474
9475
|
return result;
|
|
9475
9476
|
}
|
|
9476
|
-
case "VariableDeclarator":
|
|
9477
|
+
case "VariableDeclarator": {
|
|
9478
|
+
if (sn.resolvedType)
|
|
9479
|
+
return sn.resolvedType;
|
|
9480
|
+
let declared = null;
|
|
9481
|
+
if (sn.node.id.type === "BinaryExpression") {
|
|
9482
|
+
declared = typeFromTypespec(state, sn.node.id.right, sn.stack);
|
|
9483
|
+
}
|
|
9477
9484
|
if (sn.node.kind === "const" && sn.node.init) {
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
return
|
|
9485
|
+
if (hasProperty(sn, "resolvedType")) {
|
|
9486
|
+
// The constant is defined recursively
|
|
9487
|
+
return declared ?? { type: 524287 /* TypeTag.Any */ };
|
|
9481
9488
|
}
|
|
9482
|
-
|
|
9483
|
-
|
|
9489
|
+
// set the marker in case the constant appears in its
|
|
9490
|
+
// own initializer.
|
|
9491
|
+
sn.resolvedType = undefined;
|
|
9492
|
+
const stack = state.stack;
|
|
9493
|
+
let resolved;
|
|
9494
|
+
try {
|
|
9495
|
+
state.stack = sn.stack;
|
|
9496
|
+
resolved = evaluateExpr(state, sn.node.init).value;
|
|
9484
9497
|
}
|
|
9485
|
-
|
|
9486
|
-
|
|
9487
|
-
return evaluateExpr(state, sn.node.init).value;
|
|
9498
|
+
finally {
|
|
9499
|
+
state.stack = stack;
|
|
9488
9500
|
}
|
|
9501
|
+
if (resolved.type === 0 /* TypeTag.Never */) {
|
|
9502
|
+
resolved = declared ?? { type: 524287 /* TypeTag.Any */ };
|
|
9503
|
+
}
|
|
9504
|
+
else if (declared) {
|
|
9505
|
+
resolved = intersection(resolved, declared);
|
|
9506
|
+
if (resolved.type === 0 /* TypeTag.Never */) {
|
|
9507
|
+
resolved = declared;
|
|
9508
|
+
}
|
|
9509
|
+
}
|
|
9510
|
+
sn.resolvedType = resolved;
|
|
9511
|
+
return resolved;
|
|
9489
9512
|
}
|
|
9490
9513
|
if (sn.node.id.type === "BinaryExpression") {
|
|
9491
9514
|
return typeFromTypespec(state, sn.node.id.right, sn.stack);
|
|
9492
9515
|
}
|
|
9493
9516
|
return { type: 524287 /* TypeTag.Any */ };
|
|
9517
|
+
}
|
|
9494
9518
|
}
|
|
9495
9519
|
throw new Error(`Internal error: Unexpected StateNodeDecl.type: ${sn.type}`);
|
|
9496
9520
|
}
|
|
@@ -11203,9 +11227,9 @@ function getLhsConstraint(istate, node) {
|
|
|
11203
11227
|
}
|
|
11204
11228
|
const object = istate.typeMap.get(node.object);
|
|
11205
11229
|
if (object && !node.computed) {
|
|
11206
|
-
const
|
|
11207
|
-
if (
|
|
11208
|
-
lookupDefs = (0,external_api_cjs_namespaceObject.lookupNext)(istate.state, [{ parent: null, results:
|
|
11230
|
+
const [, trueDecls] = findObjectDeclsByProperty(istate.state, object, node);
|
|
11231
|
+
if (trueDecls) {
|
|
11232
|
+
lookupDefs = (0,external_api_cjs_namespaceObject.lookupNext)(istate.state, [{ parent: null, results: trueDecls }], "decls", node.property);
|
|
11209
11233
|
}
|
|
11210
11234
|
}
|
|
11211
11235
|
}
|
|
@@ -12009,45 +12033,115 @@ function printBlockState(block, state, indent = "") {
|
|
|
12009
12033
|
console.log(`${indent} - ${typeStateEntry(value, key)}${value.equivSet ? " " + tsEquivs(state, key) : ""}`);
|
|
12010
12034
|
});
|
|
12011
12035
|
}
|
|
12012
|
-
|
|
12036
|
+
/*
|
|
12037
|
+
* We have an object, and a MemberExpression object.<name>
|
|
12038
|
+
* - decls are the StateNodes associated with the known type
|
|
12039
|
+
* of object.
|
|
12040
|
+
* - possible are all the StateNodes that declare <name>
|
|
12041
|
+
*
|
|
12042
|
+
* We want to find all the elements of possible which are
|
|
12043
|
+
* "compatible" with decls, which tells us the set of things
|
|
12044
|
+
* that object.<name> could correspond to, and also what that
|
|
12045
|
+
* tells us about object.
|
|
12046
|
+
*
|
|
12047
|
+
* The return value is two arrays of StateNode. The first
|
|
12048
|
+
* gives the refined type of object, and the second is the
|
|
12049
|
+
* array of StateNodes that could declare <name>
|
|
12050
|
+
*/
|
|
12051
|
+
function filterDecls(decls, possible, name) {
|
|
12013
12052
|
if (!possible)
|
|
12014
|
-
return null;
|
|
12015
|
-
|
|
12053
|
+
return [null, null];
|
|
12054
|
+
const result = decls.reduce((cur, decl) => {
|
|
12016
12055
|
const found = possible.reduce((flag, poss) => {
|
|
12017
12056
|
if (decl === poss ||
|
|
12018
|
-
(poss.type === "ClassDeclaration" &&
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
cur
|
|
12057
|
+
(poss.type === "ClassDeclaration" && (0,external_api_cjs_namespaceObject.getSuperClasses)(poss)?.has(decl))) {
|
|
12058
|
+
// poss extends decl, so decl must actually be a poss
|
|
12059
|
+
// eg we know obj is an Object, and we call obj.toNumber
|
|
12060
|
+
// so possible includes all the classes that declare toNumber
|
|
12061
|
+
// so we can refine obj's type to the union of those types
|
|
12062
|
+
if (!cur[0]) {
|
|
12063
|
+
cur = [new Set(), new Set()];
|
|
12064
|
+
}
|
|
12065
|
+
cur[0].add(poss);
|
|
12066
|
+
cur[1].add(poss);
|
|
12067
|
+
return true;
|
|
12068
|
+
}
|
|
12069
|
+
else if (decl.type === "ClassDeclaration" &&
|
|
12070
|
+
(0,external_api_cjs_namespaceObject.getSuperClasses)(decl)?.has(poss)) {
|
|
12071
|
+
// decl extends poss, so decl remains unchanged
|
|
12072
|
+
// eg we know obj is Menu2, we call obj.toString
|
|
12073
|
+
// Menu2 doesn't define toString, but Object does
|
|
12074
|
+
// so poss is Object. But we still know that
|
|
12075
|
+
// obj is Menu2
|
|
12076
|
+
if (!cur[0]) {
|
|
12077
|
+
cur = [new Set(), new Set()];
|
|
12078
|
+
}
|
|
12079
|
+
cur[0].add(decl);
|
|
12080
|
+
cur[1].add(poss);
|
|
12025
12081
|
return true;
|
|
12026
12082
|
}
|
|
12027
12083
|
return flag;
|
|
12028
12084
|
}, false);
|
|
12029
12085
|
if (!found) {
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
|
|
12039
|
-
|
|
12086
|
+
// If we didn't find the property in any of the
|
|
12087
|
+
// standard places, the runtime might still find
|
|
12088
|
+
// it by searching up the Module stack (and up
|
|
12089
|
+
// the module stack from any super classes)
|
|
12090
|
+
//
|
|
12091
|
+
// eg
|
|
12092
|
+
//
|
|
12093
|
+
// obj = Application.getApp();
|
|
12094
|
+
// obj.Properties.whatever
|
|
12095
|
+
//
|
|
12096
|
+
// Properties doesn't exist on AppBase, but AppBase
|
|
12097
|
+
// is declared in Application, and Application
|
|
12098
|
+
// does declare Properties. So Application.Properties
|
|
12099
|
+
// is (one of) the declarations we should find; but we
|
|
12100
|
+
// must not refine obj's type to include Application.
|
|
12101
|
+
let d = [decl];
|
|
12102
|
+
do {
|
|
12103
|
+
d.forEach((d) => {
|
|
12104
|
+
const stack = d.stack;
|
|
12105
|
+
possible.forEach((poss) => {
|
|
12106
|
+
for (let i = stack.length; i--;) {
|
|
12107
|
+
const sn = stack[i];
|
|
12108
|
+
if (sn.decls === poss.decls) {
|
|
12109
|
+
if (!cur[0]) {
|
|
12110
|
+
cur = [new Set(), new Set()];
|
|
12111
|
+
}
|
|
12112
|
+
cur[0].add(decl);
|
|
12113
|
+
cur[1].add(poss);
|
|
12114
|
+
break;
|
|
12115
|
+
}
|
|
12116
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(sn.decls, name)) {
|
|
12117
|
+
break;
|
|
12118
|
+
}
|
|
12119
|
+
}
|
|
12120
|
+
});
|
|
12121
|
+
});
|
|
12122
|
+
d = d.flatMap((d) => {
|
|
12123
|
+
if (d.type !== "ClassDeclaration" ||
|
|
12124
|
+
!d.superClass ||
|
|
12125
|
+
d.superClass === true) {
|
|
12126
|
+
return [];
|
|
12127
|
+
}
|
|
12128
|
+
return d.superClass;
|
|
12129
|
+
});
|
|
12130
|
+
} while (d.length);
|
|
12040
12131
|
}
|
|
12041
12132
|
return cur;
|
|
12042
|
-
}, null);
|
|
12133
|
+
}, [null, null]);
|
|
12134
|
+
if (!result[0])
|
|
12135
|
+
return [null, null];
|
|
12136
|
+
return [Array.from(result[0]), Array.from(result[1])];
|
|
12043
12137
|
}
|
|
12044
12138
|
function findObjectDeclsByProperty(state, object, next) {
|
|
12045
12139
|
const decls = getStateNodeDeclsFromType(state, object);
|
|
12046
12140
|
if (!decls)
|
|
12047
|
-
return null;
|
|
12141
|
+
return [null, null];
|
|
12048
12142
|
const possibleDecls = (0,external_api_cjs_namespaceObject.hasProperty)(state.allDeclarations, next.property.name) &&
|
|
12049
12143
|
state.allDeclarations[next.property.name];
|
|
12050
|
-
return filterDecls(decls, possibleDecls);
|
|
12144
|
+
return filterDecls(decls, possibleDecls, next.property.name);
|
|
12051
12145
|
}
|
|
12052
12146
|
function refineObjectTypeByDecls(istate, object, trueDecls) {
|
|
12053
12147
|
const refinedType = typeFromTypeStateNodes(istate.state, trueDecls);
|
|
@@ -12063,13 +12157,13 @@ function findNextObjectType(istate, trueDecls, next) {
|
|
|
12063
12157
|
}, { type: 0 /* TypeTag.Never */ });
|
|
12064
12158
|
}
|
|
12065
12159
|
function resolveDottedMember(istate, object, next) {
|
|
12066
|
-
const
|
|
12067
|
-
if (!
|
|
12160
|
+
const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, object, next);
|
|
12161
|
+
if (!objDecls)
|
|
12068
12162
|
return null;
|
|
12069
|
-
const property = findNextObjectType(istate,
|
|
12163
|
+
const property = findNextObjectType(istate, trueDecls, next);
|
|
12070
12164
|
if (!property)
|
|
12071
12165
|
return null;
|
|
12072
|
-
const type = refineObjectTypeByDecls(istate, object,
|
|
12166
|
+
const type = refineObjectTypeByDecls(istate, object, objDecls);
|
|
12073
12167
|
const mayThrow = !subtypeOf(object, type);
|
|
12074
12168
|
return { mayThrow, object: type, property };
|
|
12075
12169
|
}
|
|
@@ -12106,11 +12200,11 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
|
|
|
12106
12200
|
next = value.obj[me.property.name];
|
|
12107
12201
|
}
|
|
12108
12202
|
else {
|
|
12109
|
-
const trueDecls = findObjectDeclsByProperty(istate.state, cur, me);
|
|
12110
|
-
if (!
|
|
12203
|
+
const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, cur, me);
|
|
12204
|
+
if (!objDecls) {
|
|
12111
12205
|
return null;
|
|
12112
12206
|
}
|
|
12113
|
-
cur = refineObjectTypeByDecls(istate, cur,
|
|
12207
|
+
cur = refineObjectTypeByDecls(istate, cur, objDecls);
|
|
12114
12208
|
next = findNextObjectType(istate, trueDecls, me);
|
|
12115
12209
|
}
|
|
12116
12210
|
}
|
|
@@ -15231,7 +15325,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
|
|
|
15231
15325
|
// the oldest optimized file, we don't need to regenerate
|
|
15232
15326
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
15233
15327
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
15234
|
-
if (source_time < opt_time &&
|
|
15328
|
+
if (source_time < opt_time && 1674683508654 < opt_time) {
|
|
15235
15329
|
return { hasTests, diagnostics: prevDiagnostics };
|
|
15236
15330
|
}
|
|
15237
15331
|
}
|
|
@@ -15258,7 +15352,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
|
|
|
15258
15352
|
return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
|
|
15259
15353
|
hasTests,
|
|
15260
15354
|
diagnostics,
|
|
15261
|
-
optimizerVersion: "1.1.
|
|
15355
|
+
optimizerVersion: "1.1.5",
|
|
15262
15356
|
...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
|
|
15263
15357
|
}))
|
|
15264
15358
|
.then(() => ({ hasTests, diagnostics }));
|
|
@@ -129,6 +129,7 @@ export interface VariableStateNode extends BaseStateNode {
|
|
|
129
129
|
fullName: string;
|
|
130
130
|
stack: ProgramStateStack;
|
|
131
131
|
used?: true;
|
|
132
|
+
resolvedType?: ExactOrUnion | undefined;
|
|
132
133
|
}
|
|
133
134
|
export interface EnumStateNode extends BaseStateNode {
|
|
134
135
|
type: "EnumDeclaration";
|
package/build/src/type-flow.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { InterpState } from "./type-flow/interp";
|
|
|
4
4
|
import { ExactOrUnion } from "./type-flow/types";
|
|
5
5
|
export declare const missingNullWorkaround = true;
|
|
6
6
|
export declare function buildTypeInfo(state: ProgramStateAnalysis, func: FunctionStateNode, optimizeEquivalencies: boolean): InterpState | undefined;
|
|
7
|
-
export declare function findObjectDeclsByProperty(state: ProgramStateAnalysis, object: ExactOrUnion, next: mctree.DottedMemberExpression): StateNode[] | null;
|
|
7
|
+
export declare function findObjectDeclsByProperty(state: ProgramStateAnalysis, object: ExactOrUnion, next: mctree.DottedMemberExpression): [StateNode[], StateNode[]] | readonly [null, null];
|
|
8
8
|
export declare function resolveDottedMember(istate: InterpState, object: ExactOrUnion, next: mctree.DottedMemberExpression): {
|
|
9
9
|
mayThrow: boolean;
|
|
10
10
|
object: ExactOrUnion;
|
package/package.json
CHANGED