arkanalyzer 1.0.18 → 1.0.19
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/lib/callgraph/pointerAnalysis/Pag.d.ts +3 -2
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +5 -3
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +4 -4
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +5 -4
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +2 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +11 -9
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts +8 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.js +27 -3
- package/lib/callgraph/pointerAnalysis/PtsDS.d.ts +30 -6
- package/lib/callgraph/pointerAnalysis/PtsDS.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PtsDS.js +86 -5
- package/lib/core/base/Stmt.d.ts +3 -0
- package/lib/core/base/Stmt.d.ts.map +1 -1
- package/lib/core/base/Stmt.js +34 -0
- package/lib/core/base/TypeExpr.d.ts +72 -0
- package/lib/core/base/TypeExpr.d.ts.map +1 -0
- package/lib/core/base/TypeExpr.js +155 -0
- package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkIRTransformer.js +4 -0
- package/lib/core/common/ArkValueTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkValueTransformer.js +23 -8
- package/lib/core/common/IRInference.d.ts +5 -1
- package/lib/core/common/IRInference.d.ts.map +1 -1
- package/lib/core/common/IRInference.js +65 -0
- package/lib/core/common/ModelUtils.d.ts +3 -1
- package/lib/core/common/ModelUtils.d.ts.map +1 -1
- package/lib/core/common/ModelUtils.js +18 -0
- package/lib/core/common/TypeInference.d.ts +5 -0
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +56 -7
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.js +52 -4
- package/lib/save/source/SourceTransformer.d.ts +2 -0
- package/lib/save/source/SourceTransformer.d.ts.map +1 -1
- package/lib/save/source/SourceTransformer.js +43 -5
- package/lib/utils/SparseBitVector.d.ts +11 -2
- package/lib/utils/SparseBitVector.d.ts.map +1 -1
- package/lib/utils/SparseBitVector.js +70 -3
- package/package.json +1 -1
|
@@ -56,6 +56,7 @@ const Const_1 = require("./Const");
|
|
|
56
56
|
const ValueUtil_1 = require("./ValueUtil");
|
|
57
57
|
const ArkImport_1 = require("../model/ArkImport");
|
|
58
58
|
const IRInference_1 = require("./IRInference");
|
|
59
|
+
const TypeExpr_1 = require("../base/TypeExpr");
|
|
59
60
|
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'TypeInference');
|
|
60
61
|
class TypeInference {
|
|
61
62
|
static inferTypeInArkField(arkField) {
|
|
@@ -65,6 +66,7 @@ class TypeInference {
|
|
|
65
66
|
const method = (_a = arkClass.getMethodWithName(Const_1.INSTANCE_INIT_METHOD_NAME)) !== null && _a !== void 0 ? _a : arkClass.getMethodWithName(TSConst_1.CONSTRUCTOR_NAME);
|
|
66
67
|
for (const stmt of stmts) {
|
|
67
68
|
if (method) {
|
|
69
|
+
this.resolveTypeExprsInStmt(stmt, method);
|
|
68
70
|
this.resolveExprsInStmt(stmt, method);
|
|
69
71
|
this.resolveFieldRefsInStmt(stmt, method);
|
|
70
72
|
this.resolveArkAssignStmt(stmt, method);
|
|
@@ -156,10 +158,7 @@ class TypeInference {
|
|
|
156
158
|
}
|
|
157
159
|
signatures.forEach(s => {
|
|
158
160
|
s.getMethodSubSignature().getParameters().forEach(p => {
|
|
159
|
-
|
|
160
|
-
if (type) {
|
|
161
|
-
p.setType(type);
|
|
162
|
-
}
|
|
161
|
+
this.inferParameterType(p, arkMethod);
|
|
163
162
|
});
|
|
164
163
|
this.inferSignatureReturnType(s, arkMethod);
|
|
165
164
|
});
|
|
@@ -170,6 +169,7 @@ class TypeInference {
|
|
|
170
169
|
const cfg = body.getCfg();
|
|
171
170
|
for (const block of cfg.getBlocks()) {
|
|
172
171
|
for (const stmt of block.getStmts()) {
|
|
172
|
+
this.resolveTypeExprsInStmt(stmt, arkMethod);
|
|
173
173
|
this.resolveExprsInStmt(stmt, arkMethod);
|
|
174
174
|
this.resolveFieldRefsInStmt(stmt, arkMethod);
|
|
175
175
|
this.resolveArkAssignStmt(stmt, arkMethod);
|
|
@@ -208,6 +208,14 @@ class TypeInference {
|
|
|
208
208
|
stmt.getAliasType().setOriginalType(stmt.getAliasTypeExpr().getType());
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* infer value type for TypeExprs in stmt which specify the type such as TypeQueryExpr
|
|
213
|
+
*/
|
|
214
|
+
static resolveTypeExprsInStmt(stmt, arkMethod) {
|
|
215
|
+
for (let typeExpr of stmt.getTypeExprs()) {
|
|
216
|
+
typeExpr.inferType(arkMethod);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
211
219
|
/**
|
|
212
220
|
* infer type for fieldRefs in stmt.
|
|
213
221
|
*/
|
|
@@ -284,14 +292,23 @@ class TypeInference {
|
|
|
284
292
|
if (rightType) {
|
|
285
293
|
this.setValueType(rightOp, rightType);
|
|
286
294
|
}
|
|
295
|
+
else {
|
|
296
|
+
if (rightOp instanceof Local_1.Local) {
|
|
297
|
+
IRInference_1.IRInference.inferLocal(rightOp, arkMethod);
|
|
298
|
+
rightType = rightOp.getType();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
287
301
|
}
|
|
288
302
|
const leftOp = stmt.getLeftOp();
|
|
289
303
|
let leftType = leftOp.getType();
|
|
290
304
|
if (this.isUnclearType(leftType)) {
|
|
291
|
-
|
|
292
|
-
if (!
|
|
305
|
+
const newLeftType = this.inferUnclearedType(leftType, arkClass);
|
|
306
|
+
if (!newLeftType && !this.isUnclearType(rightType)) {
|
|
293
307
|
leftType = rightType;
|
|
294
308
|
}
|
|
309
|
+
else if (newLeftType) {
|
|
310
|
+
leftType = newLeftType;
|
|
311
|
+
}
|
|
295
312
|
}
|
|
296
313
|
if (leftType && !this.isUnclearType(leftType)) {
|
|
297
314
|
this.setValueType(leftOp, leftType);
|
|
@@ -331,7 +348,13 @@ class TypeInference {
|
|
|
331
348
|
return this.hasUnclearReferenceType(type.getBaseType());
|
|
332
349
|
}
|
|
333
350
|
else if (type instanceof Type_1.AliasType) {
|
|
334
|
-
return this.
|
|
351
|
+
return this.isUnclearType(type.getOriginalType());
|
|
352
|
+
}
|
|
353
|
+
else if (type instanceof TypeExpr_1.KeyofTypeExpr) {
|
|
354
|
+
return this.isUnclearType(type.getOpType());
|
|
355
|
+
}
|
|
356
|
+
else if (type instanceof TypeExpr_1.TypeQueryExpr) {
|
|
357
|
+
return this.isUnclearType(type.getType());
|
|
335
358
|
}
|
|
336
359
|
return false;
|
|
337
360
|
}
|
|
@@ -349,6 +372,12 @@ class TypeInference {
|
|
|
349
372
|
else if (type instanceof Type_1.AliasType) {
|
|
350
373
|
return this.hasUnclearReferenceType(type.getOriginalType());
|
|
351
374
|
}
|
|
375
|
+
else if (type instanceof TypeExpr_1.KeyofTypeExpr) {
|
|
376
|
+
return this.hasUnclearReferenceType(type.getOpType());
|
|
377
|
+
}
|
|
378
|
+
else if (type instanceof TypeExpr_1.TypeQueryExpr) {
|
|
379
|
+
return this.hasUnclearReferenceType(type.getType());
|
|
380
|
+
}
|
|
352
381
|
return false;
|
|
353
382
|
}
|
|
354
383
|
static inferSimpleTypeInStmt(stmt) {
|
|
@@ -399,6 +428,18 @@ class TypeInference {
|
|
|
399
428
|
}
|
|
400
429
|
return value.getType();
|
|
401
430
|
}
|
|
431
|
+
static inferParameterType(param, arkMethod) {
|
|
432
|
+
let pType = param.getType();
|
|
433
|
+
const type = TypeInference.inferUnclearedType(pType, arkMethod.getDeclaringArkClass());
|
|
434
|
+
if (type) {
|
|
435
|
+
param.setType(type);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
if (pType instanceof TypeExpr_1.AbstractTypeExpr) {
|
|
439
|
+
pType.inferType(arkMethod);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
402
443
|
static inferSignatureReturnType(oldSignature, arkMethod) {
|
|
403
444
|
if (oldSignature.getMethodSubSignature().getMethodName() === TSConst_1.CONSTRUCTOR_NAME) {
|
|
404
445
|
const newReturnType = new Type_1.ClassType(oldSignature.getDeclaringClassSignature());
|
|
@@ -409,6 +450,14 @@ class TypeInference {
|
|
|
409
450
|
if (!this.isUnclearType(currReturnType)) {
|
|
410
451
|
return;
|
|
411
452
|
}
|
|
453
|
+
if (currReturnType instanceof TypeExpr_1.AbstractTypeExpr) {
|
|
454
|
+
currReturnType.inferType(arkMethod);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
if (currReturnType instanceof Type_1.ArrayType && currReturnType.getBaseType() instanceof TypeExpr_1.AbstractTypeExpr) {
|
|
458
|
+
currReturnType.getBaseType().inferType(arkMethod);
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
412
461
|
const newReturnType = this.inferUnclearedType(currReturnType, arkMethod.getDeclaringArkClass());
|
|
413
462
|
if (newReturnType) {
|
|
414
463
|
oldSignature.getMethodSubSignature().setReturnType(newReturnType);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builderUtils.d.ts","sourceRoot":"","sources":["../../../../src/core/model/builder/builderUtils.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EACH,SAAS,EAIT,WAAW,EAGX,IAAI,EAIP,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAGH,eAAe,EAElB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"builderUtils.d.ts","sourceRoot":"","sources":["../../../../src/core/model/builder/builderUtils.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EACH,SAAS,EAIT,WAAW,EAGX,IAAI,EAIP,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAGH,eAAe,EAElB,MAAM,oBAAoB,CAAC;AAc5B,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,GAAG,MAAM,CAUlE;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,EAAE,CAAC,wBAAwB,GAAG,MAAM,CAYxF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,CAUxF;AA2BD,wBAAgB,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,MAAM,CAUpD;AAED,wBAAgB,oBAAoB,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBxG;AAED,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,EAAE,CAAC,SAAS,CAAC,wBAAwB,CAAC,EACtD,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,EAAE,CAmB/G;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,WAAW,EAAE,SAAS,GAAG,QAAQ,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,qBA4GvI;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,IAAI,CA8ChG;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,QAM3F;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,GAAG,EAAE,CAAC,wBAAwB,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,EAC9E,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CA0F9E;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,QA8CjD"}
|
|
@@ -54,6 +54,11 @@ const ArkClassBuilder_1 = require("./ArkClassBuilder");
|
|
|
54
54
|
const Builtin_1 = require("../../common/Builtin");
|
|
55
55
|
const ArkBaseModel_1 = require("../ArkBaseModel");
|
|
56
56
|
const ArkValueTransformer_1 = require("../../common/ArkValueTransformer");
|
|
57
|
+
const TypeExpr_1 = require("../../base/TypeExpr");
|
|
58
|
+
const TSConst_1 = require("../../common/TSConst");
|
|
59
|
+
const ArkSignatureBuilder_1 = require("./ArkSignatureBuilder");
|
|
60
|
+
const Ref_1 = require("../../base/Ref");
|
|
61
|
+
const Local_1 = require("../../base/Local");
|
|
57
62
|
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'builderUtils');
|
|
58
63
|
function handleQualifiedName(node) {
|
|
59
64
|
let right = node.right.text;
|
|
@@ -434,6 +439,9 @@ function tsNode2Type(typeNode, sourceFile, arkInstance) {
|
|
|
434
439
|
else if (ohos_typescript_1.default.isTypeOperatorNode(typeNode)) {
|
|
435
440
|
return buildTypeFromTypeOperator(typeNode, sourceFile, arkInstance);
|
|
436
441
|
}
|
|
442
|
+
else if (ohos_typescript_1.default.isTypeQueryNode(typeNode)) {
|
|
443
|
+
return buildTypeFromTypeQuery(typeNode, sourceFile, arkInstance);
|
|
444
|
+
}
|
|
437
445
|
else if (typeNode.kind === ohos_typescript_1.default.SyntaxKind.ObjectKeyword) {
|
|
438
446
|
return new Type_1.ClassType(Builtin_1.Builtin.OBJECT_CLASS_SIGNATURE);
|
|
439
447
|
}
|
|
@@ -491,20 +499,60 @@ function buildTypeFromPreStr(preStr) {
|
|
|
491
499
|
}
|
|
492
500
|
exports.buildTypeFromPreStr = buildTypeFromPreStr;
|
|
493
501
|
function buildTypeFromTypeOperator(typeOperatorNode, sourceFile, arkInstance) {
|
|
502
|
+
const typeNode = typeOperatorNode.type;
|
|
503
|
+
let type = tsNode2Type(typeNode, sourceFile, arkInstance);
|
|
494
504
|
switch (typeOperatorNode.operator) {
|
|
495
505
|
case (ohos_typescript_1.default.SyntaxKind.ReadonlyKeyword): {
|
|
496
|
-
const typeNode = typeOperatorNode.type;
|
|
497
|
-
let type = tsNode2Type(typeNode, sourceFile, arkInstance);
|
|
498
506
|
if (type instanceof Type_1.ArrayType || type instanceof Type_1.TupleType) {
|
|
499
507
|
type.setReadonlyFlag(true);
|
|
500
508
|
}
|
|
501
509
|
return type;
|
|
502
510
|
}
|
|
503
|
-
case (ohos_typescript_1.default.SyntaxKind.UniqueKeyword):
|
|
504
|
-
return Type_1.UnknownType.getInstance();
|
|
505
511
|
case (ohos_typescript_1.default.SyntaxKind.KeyOfKeyword):
|
|
512
|
+
return new TypeExpr_1.KeyofTypeExpr(type);
|
|
513
|
+
case (ohos_typescript_1.default.SyntaxKind.UniqueKeyword):
|
|
506
514
|
return Type_1.UnknownType.getInstance();
|
|
507
515
|
default:
|
|
508
516
|
return Type_1.UnknownType.getInstance();
|
|
509
517
|
}
|
|
510
518
|
}
|
|
519
|
+
function buildTypeFromTypeQuery(typeQueryNode, sourceFile, arkInstance) {
|
|
520
|
+
var _a, _b, _c, _d, _e, _f;
|
|
521
|
+
const exprNameNode = typeQueryNode.exprName;
|
|
522
|
+
let opValue;
|
|
523
|
+
if (ohos_typescript_1.default.isQualifiedName(exprNameNode)) {
|
|
524
|
+
if (exprNameNode.left.getText(sourceFile) === TSConst_1.THIS_NAME) {
|
|
525
|
+
const fieldName = exprNameNode.right.getText(sourceFile);
|
|
526
|
+
if (arkInstance instanceof ArkMethod_1.ArkMethod) {
|
|
527
|
+
const fieldSignature = (_b = (_a = arkInstance.getDeclaringArkClass().getFieldWithName(fieldName)) === null || _a === void 0 ? void 0 : _a.getSignature()) !== null && _b !== void 0 ? _b : ArkSignatureBuilder_1.ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName);
|
|
528
|
+
const baseLocal = (_d = (_c = arkInstance.getBody()) === null || _c === void 0 ? void 0 : _c.getLocals().get(TSConst_1.THIS_NAME)) !== null && _d !== void 0 ? _d : new Local_1.Local(TSConst_1.THIS_NAME, new Type_1.ClassType(arkInstance.getDeclaringArkClass().getSignature(), arkInstance.getDeclaringArkClass().getGenericsTypes()));
|
|
529
|
+
opValue = new Ref_1.ArkInstanceFieldRef(baseLocal, fieldSignature);
|
|
530
|
+
}
|
|
531
|
+
else if (arkInstance instanceof ArkClass_1.ArkClass) {
|
|
532
|
+
const fieldSignature = (_f = (_e = arkInstance.getFieldWithName(fieldName)) === null || _e === void 0 ? void 0 : _e.getSignature()) !== null && _f !== void 0 ? _f : ArkSignatureBuilder_1.ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName);
|
|
533
|
+
const baseLocal = new Local_1.Local(TSConst_1.THIS_NAME, new Type_1.ClassType(arkInstance.getSignature(), arkInstance.getGenericsTypes()));
|
|
534
|
+
opValue = new Ref_1.ArkInstanceFieldRef(baseLocal, fieldSignature);
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
const fieldSignature = arkInstance.getSignature();
|
|
538
|
+
const baseLocal = new Local_1.Local(TSConst_1.THIS_NAME, new Type_1.ClassType(arkInstance.getDeclaringArkClass().getSignature(), arkInstance.getDeclaringArkClass().getGenericsTypes()));
|
|
539
|
+
opValue = new Ref_1.ArkInstanceFieldRef(baseLocal, fieldSignature);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
const exprName = exprNameNode.getText(sourceFile);
|
|
544
|
+
opValue = new Local_1.Local(exprName, Type_1.UnknownType.getInstance());
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
const exprName = exprNameNode.escapedText.toString();
|
|
549
|
+
opValue = new Local_1.Local(exprName, Type_1.UnknownType.getInstance());
|
|
550
|
+
}
|
|
551
|
+
let expr = new TypeExpr_1.TypeQueryExpr(opValue);
|
|
552
|
+
if (typeQueryNode.typeArguments) {
|
|
553
|
+
for (const typeArgument of typeQueryNode.typeArguments) {
|
|
554
|
+
expr.addGenericType(tsNode2Type(typeArgument, sourceFile, arkInstance));
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return expr;
|
|
558
|
+
}
|
|
@@ -39,6 +39,8 @@ export declare class SourceTransformer {
|
|
|
39
39
|
private arrayType2string;
|
|
40
40
|
private tupleType2string;
|
|
41
41
|
private aliasType2string;
|
|
42
|
+
private keyofTypeExpr2string;
|
|
43
|
+
private typeQueryExpr2string;
|
|
42
44
|
private unclearReferenceType2string;
|
|
43
45
|
private classType2string;
|
|
44
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SourceTransformer.d.ts","sourceRoot":"","sources":["../../../src/save/source/SourceTransformer.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAMH,qBAAqB,EAKrB,mBAAmB,EAKtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAiB,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,OAAO,EAGH,SAAS,EAQT,IAAI,EAKP,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAmE,MAAM,qBAAqB,CAAC;AACnH,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AASnD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"SourceTransformer.d.ts","sourceRoot":"","sources":["../../../src/save/source/SourceTransformer.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAMH,qBAAqB,EAKrB,mBAAmB,EAKtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAiB,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,OAAO,EAGH,SAAS,EAQT,IAAI,EAKP,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAmE,MAAM,qBAAqB,CAAC;AACnH,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AASnD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAS7D,MAAM,WAAW,kBAAkB;IAC/B,UAAU,IAAI,OAAO,CAAC;IAEtB,wBAAwB,IAAI,YAAY,GAAG,SAAS,CAAC;IAErD,SAAS,CAAC,SAAS,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IAExD,QAAQ,CAAC,SAAS,EAAE,cAAc,GAAG,QAAQ,GAAG,IAAI,CAAC;IAErD,UAAU,IAAI,aAAa,CAAC;IAE5B,cAAc,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IAEpC,iBAAiB,IAAI,OAAO,CAAC;CAChC;AAED,qBAAa,iBAAiB;IAC1B,SAAS,CAAC,OAAO,EAAE,kBAAkB,CAAC;gBAE1B,OAAO,EAAE,kBAAkB;IAIvC,OAAO,CAAC,uBAAuB;IAM/B,OAAO,CAAC,sBAAsB;IAKvB,0BAA0B,CAAC,UAAU,EAAE,qBAAqB,GAAG,MAAM;IAkBrE,wBAAwB,CAAC,UAAU,EAAE,mBAAmB,GAAG,MAAM;IA0DxE,OAAO,CAAC,oBAAoB;IAYrB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,GAAE,MAAa,GAAG,MAAM;WASvD,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAQpD,OAAO,CAAC,YAAY;IA2Db,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM;IA8BvC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;IAiDtD,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM;IAW9C,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IA+DvC,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,2BAA2B;IAQnC,OAAO,CAAC,gBAAgB;CAkB3B"}
|
|
@@ -42,6 +42,7 @@ const Constant_1 = require("../../core/base/Constant");
|
|
|
42
42
|
const Expr_1 = require("../../core/base/Expr");
|
|
43
43
|
const Local_1 = require("../../core/base/Local");
|
|
44
44
|
const ArkClass_1 = require("../../core/model/ArkClass");
|
|
45
|
+
const ArkMethod_1 = require("../../core/model/ArkMethod");
|
|
45
46
|
const logger_1 = __importStar(require("../../utils/logger"));
|
|
46
47
|
const PrinterUtils_1 = require("../base/PrinterUtils");
|
|
47
48
|
const SourceMethod_1 = require("./SourceMethod");
|
|
@@ -51,6 +52,12 @@ const Ref_1 = require("../../core/base/Ref");
|
|
|
51
52
|
const EtsConst_1 = require("../../core/common/EtsConst");
|
|
52
53
|
const Const_1 = require("../../core/common/Const");
|
|
53
54
|
const Stmt_1 = require("../../core/base/Stmt");
|
|
55
|
+
const ArkNamespace_1 = require("../../core/model/ArkNamespace");
|
|
56
|
+
const TypeExpr_1 = require("../../core/base/TypeExpr");
|
|
57
|
+
const ArkBaseModel_1 = require("../../core/model/ArkBaseModel");
|
|
58
|
+
const ArkField_1 = require("../../core/model/ArkField");
|
|
59
|
+
const ArkExport_1 = require("../../core/model/ArkExport");
|
|
60
|
+
const ArkImport_1 = require("../../core/model/ArkImport");
|
|
54
61
|
const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'SourceTransformer');
|
|
55
62
|
class SourceTransformer {
|
|
56
63
|
constructor(context) {
|
|
@@ -278,7 +285,7 @@ class SourceTransformer {
|
|
|
278
285
|
if (type instanceof Type_1.LiteralType) {
|
|
279
286
|
return this.literalType2string(type);
|
|
280
287
|
}
|
|
281
|
-
if (type instanceof Type_1.PrimitiveType) {
|
|
288
|
+
if (type instanceof Type_1.PrimitiveType || type instanceof Type_1.GenericType) {
|
|
282
289
|
return type.getName();
|
|
283
290
|
}
|
|
284
291
|
if (type instanceof Type_1.UnionType || type instanceof Type_1.IntersectionType) {
|
|
@@ -309,12 +316,15 @@ class SourceTransformer {
|
|
|
309
316
|
if (type instanceof Type_1.UnclearReferenceType) {
|
|
310
317
|
return this.unclearReferenceType2string(type);
|
|
311
318
|
}
|
|
312
|
-
if (type instanceof Type_1.GenericType) {
|
|
313
|
-
return type.getName();
|
|
314
|
-
}
|
|
315
319
|
if (type instanceof Type_1.AliasType) {
|
|
316
320
|
return this.aliasType2string(type);
|
|
317
321
|
}
|
|
322
|
+
if (type instanceof TypeExpr_1.KeyofTypeExpr) {
|
|
323
|
+
return this.keyofTypeExpr2string(type);
|
|
324
|
+
}
|
|
325
|
+
if (type instanceof TypeExpr_1.TypeQueryExpr) {
|
|
326
|
+
return this.typeQueryExpr2string(type);
|
|
327
|
+
}
|
|
318
328
|
if (!type) {
|
|
319
329
|
return 'any';
|
|
320
330
|
}
|
|
@@ -352,7 +362,7 @@ class SourceTransformer {
|
|
|
352
362
|
dimensions.push('[]');
|
|
353
363
|
}
|
|
354
364
|
let baseType = type.getBaseType();
|
|
355
|
-
if (baseType instanceof Type_1.UnionType || baseType instanceof Type_1.IntersectionType) {
|
|
365
|
+
if (baseType instanceof Type_1.UnionType || baseType instanceof Type_1.IntersectionType || baseType instanceof TypeExpr_1.AbstractTypeExpr) {
|
|
356
366
|
return `${readonly}(${this.typeToString(baseType)})${dimensions.join('')}`;
|
|
357
367
|
}
|
|
358
368
|
return `${readonly}${this.typeToString(baseType)}${dimensions.join('')}`;
|
|
@@ -379,6 +389,34 @@ class SourceTransformer {
|
|
|
379
389
|
}
|
|
380
390
|
return type.getName();
|
|
381
391
|
}
|
|
392
|
+
keyofTypeExpr2string(type) {
|
|
393
|
+
if (type.getOpType() instanceof Type_1.UnionType || type.getOpType() instanceof Type_1.IntersectionType) {
|
|
394
|
+
return `keyof (${this.typeToString(type.getOpType())})`;
|
|
395
|
+
}
|
|
396
|
+
return `keyof ${this.typeToString(type.getOpType())}`;
|
|
397
|
+
}
|
|
398
|
+
typeQueryExpr2string(type) {
|
|
399
|
+
const gTypes = type.getGenerateTypes();
|
|
400
|
+
const genericStr = this.genericTypesToString(gTypes);
|
|
401
|
+
const opValue = type.getOpValue();
|
|
402
|
+
if (opValue instanceof ArkBaseModel_1.ArkBaseModel) {
|
|
403
|
+
if (opValue instanceof ArkClass_1.ArkClass || opValue instanceof ArkMethod_1.ArkMethod || opValue instanceof ArkNamespace_1.ArkNamespace || opValue instanceof ArkField_1.ArkField) {
|
|
404
|
+
return `typeof ${opValue.getName()}${genericStr}`;
|
|
405
|
+
}
|
|
406
|
+
else if (opValue instanceof ArkExport_1.ExportInfo) {
|
|
407
|
+
return `typeof ${opValue.getExportClauseName()}${genericStr}`;
|
|
408
|
+
}
|
|
409
|
+
else if (opValue instanceof ArkImport_1.ImportInfo) {
|
|
410
|
+
return `typeof ${opValue.getImportClauseName()}${genericStr}`;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
return `typeof *invalid*`;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
return `typeof ${this.valueToString(opValue)}${genericStr}`;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
382
420
|
unclearReferenceType2string(type) {
|
|
383
421
|
let genericTypes = type.getGenericTypes();
|
|
384
422
|
if (genericTypes.length > 0) {
|
|
@@ -38,9 +38,12 @@ declare class SparseBitVectorElement {
|
|
|
38
38
|
private bits;
|
|
39
39
|
constructor(elementSize?: number);
|
|
40
40
|
word(idx: number): number;
|
|
41
|
+
clone(): Word;
|
|
41
42
|
get elementSize(): number;
|
|
43
|
+
get bitWordNum(): number;
|
|
42
44
|
isEmpty(): boolean;
|
|
43
45
|
set(bitIdx: number): void;
|
|
46
|
+
setWord(word: Word): void;
|
|
44
47
|
reset(bitIdx: number): void;
|
|
45
48
|
test(bitIdx: number): boolean;
|
|
46
49
|
test_and_set(bitIdx: number): boolean;
|
|
@@ -50,6 +53,7 @@ declare class SparseBitVectorElement {
|
|
|
50
53
|
equals(rhs: SparseBitVectorElement): boolean;
|
|
51
54
|
unionWith(other: SparseBitVectorElement): boolean;
|
|
52
55
|
intersectWith(other: SparseBitVectorElement): boolean;
|
|
56
|
+
subtractWith(rhs: SparseBitVectorElement): boolean;
|
|
53
57
|
countBitsV2(word: number): number;
|
|
54
58
|
countBits(word: number): number;
|
|
55
59
|
isZero(): boolean;
|
|
@@ -65,10 +69,12 @@ export declare class SparseBitVector {
|
|
|
65
69
|
test(bitIdx: number): boolean;
|
|
66
70
|
testAndSet(bitIdx: number): boolean;
|
|
67
71
|
reset(bitIdx: number): void;
|
|
72
|
+
clear(): void;
|
|
73
|
+
clone(): SparseBitVector;
|
|
68
74
|
findFirst(): number;
|
|
69
75
|
count(): number;
|
|
70
76
|
isEmpty(): boolean;
|
|
71
|
-
[Symbol.iterator]():
|
|
77
|
+
[Symbol.iterator](): IterableIterator<number>;
|
|
72
78
|
/**
|
|
73
79
|
* Check if this SparseBitVector is equal to another SparseBitVector.
|
|
74
80
|
*/
|
|
@@ -84,8 +90,11 @@ export declare class SparseBitVector {
|
|
|
84
90
|
*/
|
|
85
91
|
intersectWith(rhs: SparseBitVector): boolean;
|
|
86
92
|
/**
|
|
87
|
-
*
|
|
93
|
+
* Subtract another SparseBitVector from this one.
|
|
94
|
+
* This operation modifies the current SparseBitVector in place.
|
|
95
|
+
* Return True if the current SparseBitVector was modified, false otherwise.
|
|
88
96
|
*/
|
|
97
|
+
subtractWith(rhs: SparseBitVector): boolean;
|
|
89
98
|
toString(): string;
|
|
90
99
|
}
|
|
91
100
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SparseBitVector.d.ts","sourceRoot":"","sources":["../../src/utils/SparseBitVector.ts"],"names":[],"mappings":"AAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC;AAE/B,cAAM,sBAAsB;IACxB,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,IAAI,CAAO;gBAEP,WAAW,GAAE,MAAY;IAMrC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAIzB,IAAI,WAAW,IAAI,MAAM,CAExB;IAGD,OAAO,IAAI,OAAO;IAKlB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"SparseBitVector.d.ts","sourceRoot":"","sources":["../../src/utils/SparseBitVector.ts"],"names":[],"mappings":"AAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC;AAE/B,cAAM,sBAAsB;IACxB,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,IAAI,CAAO;gBAEP,WAAW,GAAE,MAAY;IAMrC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAIzB,KAAK,IAAI,IAAI;IAIb,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAGD,OAAO,IAAI,OAAO;IAKlB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMzB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAKzB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAO3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAO7B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAUrC,KAAK,IAAI,MAAM;IASf,SAAS,IAAI,MAAM;IAUnB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAuBhC,MAAM,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO;IAW5C,SAAS,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO;IAajD,aAAa,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO;IAarD,YAAY,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO;IAiBlD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAUjC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAgB/B,MAAM,IAAI,OAAO;IAUjB,OAAO,CAAC,kBAAkB;CAwB7B;AAED,qBAAa,eAAe;IACxB,OAAO,CAAC,YAAY,CAAS;IAG7B,OAAO,CAAC,QAAQ,CAAkD;gBAEtD,YAAY,GAAE,MAAY;IAItC,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAE/C;IAGD,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAWzB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAO7B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAUnC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAY3B,KAAK,IAAI,IAAI;IAKb,KAAK,IAAI,eAAe;IAaxB,SAAS,IAAI,MAAM;IAYnB,KAAK,IAAI,MAAM;IASf,OAAO,IAAI,OAAO;IAIlB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAsC7C;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAcrC;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAwBxC;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAoC5C;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IA2B3C,QAAQ,IAAI,MAAM;CAIrB"}
|
|
@@ -25,9 +25,15 @@ class SparseBitVectorElement {
|
|
|
25
25
|
word(idx) {
|
|
26
26
|
return this.bits[idx];
|
|
27
27
|
}
|
|
28
|
+
clone() {
|
|
29
|
+
return new Uint32Array(this.bits);
|
|
30
|
+
}
|
|
28
31
|
get elementSize() {
|
|
29
32
|
return this.ELEMENT_SIZE;
|
|
30
33
|
}
|
|
34
|
+
get bitWordNum() {
|
|
35
|
+
return this.BITWORDS_NUM;
|
|
36
|
+
}
|
|
31
37
|
// Check if the element is empty (all bits are zero)
|
|
32
38
|
isEmpty() {
|
|
33
39
|
return this.isZero();
|
|
@@ -38,6 +44,9 @@ class SparseBitVectorElement {
|
|
|
38
44
|
const bitOffset = bitIdx % BITWORD_SIZE;
|
|
39
45
|
this.bits[wordIndex] |= (1 << bitOffset);
|
|
40
46
|
}
|
|
47
|
+
setWord(word) {
|
|
48
|
+
this.bits = word;
|
|
49
|
+
}
|
|
41
50
|
// Reset a bit at the given index
|
|
42
51
|
reset(bitIdx) {
|
|
43
52
|
const wordIndex = Math.floor(bitIdx / BITWORD_SIZE);
|
|
@@ -128,6 +137,20 @@ class SparseBitVectorElement {
|
|
|
128
137
|
}
|
|
129
138
|
return changed;
|
|
130
139
|
}
|
|
140
|
+
// Subtract another SparseBitVectorElement from this one.
|
|
141
|
+
subtractWith(rhs) {
|
|
142
|
+
let changed = false;
|
|
143
|
+
// Perform subtraction: this = this & ~rhs
|
|
144
|
+
for (let i = 0; i < this.bits.length; i++) {
|
|
145
|
+
const oldWord = this.bits[i];
|
|
146
|
+
this.bits[i] &= ~rhs.bits[i];
|
|
147
|
+
// If any bit was changed, mark as changed
|
|
148
|
+
if (this.bits[i] !== oldWord) {
|
|
149
|
+
changed = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return changed;
|
|
153
|
+
}
|
|
131
154
|
// Count the number of set bits in a word
|
|
132
155
|
countBitsV2(word) {
|
|
133
156
|
let count = 0;
|
|
@@ -230,6 +253,20 @@ class SparseBitVector {
|
|
|
230
253
|
}
|
|
231
254
|
}
|
|
232
255
|
}
|
|
256
|
+
// Clear all elements
|
|
257
|
+
clear() {
|
|
258
|
+
this.elements.clear();
|
|
259
|
+
}
|
|
260
|
+
// Clone, return a deep copied object
|
|
261
|
+
clone() {
|
|
262
|
+
const newVector = new SparseBitVector(this.elementSize);
|
|
263
|
+
for (const [idx, element] of this.elements) {
|
|
264
|
+
const newElement = new SparseBitVectorElement(this.elementSize);
|
|
265
|
+
newElement.setWord(element.clone());
|
|
266
|
+
newVector.elems.set(idx, newElement);
|
|
267
|
+
}
|
|
268
|
+
return newVector;
|
|
269
|
+
}
|
|
233
270
|
// Find the first set bit in the vector
|
|
234
271
|
findFirst() {
|
|
235
272
|
if (this.elements.size === 0)
|
|
@@ -264,7 +301,10 @@ class SparseBitVector {
|
|
|
264
301
|
return {
|
|
265
302
|
next() {
|
|
266
303
|
return { value: undefined, done: true };
|
|
267
|
-
}
|
|
304
|
+
},
|
|
305
|
+
[Symbol.iterator]() {
|
|
306
|
+
return this; // Make the iterator itself iterable
|
|
307
|
+
},
|
|
268
308
|
};
|
|
269
309
|
}
|
|
270
310
|
let bitIndex = element[1].findFirst();
|
|
@@ -283,7 +323,10 @@ class SparseBitVector {
|
|
|
283
323
|
return { value: v, done: false };
|
|
284
324
|
}
|
|
285
325
|
return { value: undefined, done: true };
|
|
286
|
-
}
|
|
326
|
+
},
|
|
327
|
+
[Symbol.iterator]() {
|
|
328
|
+
return this; // Make the iterator itself iterable
|
|
329
|
+
},
|
|
287
330
|
};
|
|
288
331
|
}
|
|
289
332
|
/**
|
|
@@ -367,8 +410,32 @@ class SparseBitVector {
|
|
|
367
410
|
return changed;
|
|
368
411
|
}
|
|
369
412
|
/**
|
|
370
|
-
*
|
|
413
|
+
* Subtract another SparseBitVector from this one.
|
|
414
|
+
* This operation modifies the current SparseBitVector in place.
|
|
415
|
+
* Return True if the current SparseBitVector was modified, false otherwise.
|
|
371
416
|
*/
|
|
417
|
+
subtractWith(rhs) {
|
|
418
|
+
if (this.elementSize !== rhs.elementSize || this.isEmpty() || rhs.isEmpty()) {
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
let needDeleteIdx = new Set();
|
|
422
|
+
let changed = false;
|
|
423
|
+
for (const [elementIndex, element] of this.elements) {
|
|
424
|
+
const rhsElement = rhs.elements.get(elementIndex);
|
|
425
|
+
if (rhsElement) {
|
|
426
|
+
changed = element.subtractWith(rhsElement) || changed;
|
|
427
|
+
if (element.isEmpty()) {
|
|
428
|
+
needDeleteIdx.add(elementIndex);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
if (needDeleteIdx.size > 0) {
|
|
433
|
+
needDeleteIdx.forEach(idx => this.elements.delete(idx));
|
|
434
|
+
changed = true;
|
|
435
|
+
}
|
|
436
|
+
return changed;
|
|
437
|
+
}
|
|
438
|
+
// Dump as string
|
|
372
439
|
toString() {
|
|
373
440
|
let ar = [...this];
|
|
374
441
|
return ar.toString();
|