@suss/adapter-typescript 0.33.0 → 0.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +78 -33
- package/dist/index.d.cts +21 -16
- package/dist/index.d.ts +21 -16
- package/dist/index.js +78 -33
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -2681,8 +2681,8 @@ var ResolutionStore = class {
|
|
|
2681
2681
|
lastQueryWalked = [];
|
|
2682
2682
|
/** See `environmentSiteFiles`; null until the first env question. */
|
|
2683
2683
|
envSiteFiles = null;
|
|
2684
|
-
|
|
2685
|
-
|
|
2684
|
+
/** See `environmentAnswers`; null until the first env question. */
|
|
2685
|
+
envAnswers = null;
|
|
2686
2686
|
declarations = /* @__PURE__ */ new Map();
|
|
2687
2687
|
graph = new ModuleGraph();
|
|
2688
2688
|
/** See `notePossibleCallers`. */
|
|
@@ -2908,10 +2908,8 @@ var ResolutionStore = class {
|
|
|
2908
2908
|
* a pack spells it, a name declared as that, or a parameter some
|
|
2909
2909
|
* caller hands one to, however many calls deep.
|
|
2910
2910
|
*
|
|
2911
|
-
* A parameter
|
|
2912
|
-
*
|
|
2913
|
-
* imports this one, so a value that is not one is answered from what
|
|
2914
|
-
* the store already has.
|
|
2911
|
+
* A parameter's answer depends on its callers, so it comes from the
|
|
2912
|
+
* parameters the environment reaches, worked out once per run.
|
|
2915
2913
|
*/
|
|
2916
2914
|
isEnvironmentValue(value) {
|
|
2917
2915
|
const target = factKeyOf(value);
|
|
@@ -2919,17 +2917,14 @@ var ResolutionStore = class {
|
|
|
2919
2917
|
this.derive();
|
|
2920
2918
|
return {
|
|
2921
2919
|
environment: this.hasAnswer("wantedEnvironmentValue", target),
|
|
2922
|
-
|
|
2920
|
+
parameters: this.answersFor("wantedRefersToParam", nodeId(target))
|
|
2923
2921
|
};
|
|
2924
2922
|
});
|
|
2925
|
-
if (first.environment ||
|
|
2923
|
+
if (first.environment || first.parameters.length === 0) {
|
|
2926
2924
|
return first.environment;
|
|
2927
2925
|
}
|
|
2928
|
-
this.
|
|
2929
|
-
return
|
|
2930
|
-
this.derive();
|
|
2931
|
-
return this.hasAnswer("wantedEnvironmentValue", target);
|
|
2932
|
-
});
|
|
2926
|
+
const { receivers } = this.environmentAnswers(target.getProject());
|
|
2927
|
+
return first.parameters.some((parameter) => receivers.has(parameter));
|
|
2933
2928
|
}
|
|
2934
2929
|
hasAnswer(relation, target) {
|
|
2935
2930
|
return this.answersFor(relation, nodeId(target)).length > 0;
|
|
@@ -2939,28 +2934,69 @@ var ResolutionStore = class {
|
|
|
2939
2934
|
* from, for a reader standing at a call. One question covers the
|
|
2940
2935
|
* whole project: a project has a handful of environment reads and
|
|
2941
2936
|
* thousands of parameters, and with the read bound the rules run from
|
|
2942
|
-
* each callee to its callers.
|
|
2943
|
-
*
|
|
2944
|
-
* `definedIn` is the callee's own file, read into the store before
|
|
2945
|
-
* the question so a helper nothing had extracted yet is among the
|
|
2946
|
-
* facts the rules run over.
|
|
2937
|
+
* each callee to its callers. The facts README says which files that
|
|
2938
|
+
* reads and why it is asked once.
|
|
2947
2939
|
*/
|
|
2948
|
-
envNamers(
|
|
2949
|
-
|
|
2940
|
+
envNamers(project) {
|
|
2941
|
+
return this.environmentAnswers(project).namers;
|
|
2942
|
+
}
|
|
2943
|
+
environmentAnswers(project) {
|
|
2944
|
+
if (this.envAnswers !== null) {
|
|
2945
|
+
return this.envAnswers;
|
|
2946
|
+
}
|
|
2947
|
+
const siteFiles = this.environmentSiteFiles(project);
|
|
2950
2948
|
if (siteFiles.length === 0) {
|
|
2951
|
-
|
|
2949
|
+
this.envAnswers = { namers: NO_NAMERS, receivers: /* @__PURE__ */ new Set() };
|
|
2950
|
+
return this.envAnswers;
|
|
2952
2951
|
}
|
|
2953
|
-
this.
|
|
2954
|
-
|
|
2955
|
-
|
|
2952
|
+
const helpers = this.followEnvironment(siteFiles).byParameter;
|
|
2953
|
+
for (const helperFile of this.filesOf(helpers)) {
|
|
2954
|
+
this.readPossibleCallersOf(helperFile);
|
|
2956
2955
|
}
|
|
2957
|
-
const
|
|
2956
|
+
const { byParameter, receivers } = this.followEnvironment(siteFiles);
|
|
2958
2957
|
const siteFilePaths = new Set(siteFiles.map((one) => one.getFilePath()));
|
|
2959
|
-
this.
|
|
2960
|
-
|
|
2958
|
+
this.envAnswers = {
|
|
2959
|
+
namers: {
|
|
2960
|
+
sitesNaming: (parameter) => this.sitesNamedBy(byParameter, siteFilePaths, parameter)
|
|
2961
|
+
},
|
|
2962
|
+
receivers
|
|
2961
2963
|
};
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
+
return this.envAnswers;
|
|
2965
|
+
}
|
|
2966
|
+
/**
|
|
2967
|
+
* Ask until every call handing the environment on has had its callee
|
|
2968
|
+
* read, one hop a round, so the answer covers each parameter it lands in.
|
|
2969
|
+
*/
|
|
2970
|
+
followEnvironment(seeds) {
|
|
2971
|
+
const followed = /* @__PURE__ */ new Set();
|
|
2972
|
+
for (; ; ) {
|
|
2973
|
+
const asked = this.askEnvironment(seeds);
|
|
2974
|
+
const next = asked.passingCalls.filter((call) => !followed.has(call));
|
|
2975
|
+
if (next.length === 0) {
|
|
2976
|
+
return asked;
|
|
2977
|
+
}
|
|
2978
|
+
for (const callId of next) {
|
|
2979
|
+
followed.add(callId);
|
|
2980
|
+
this.readCalleeOf(callId);
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
readCalleeOf(callId) {
|
|
2985
|
+
const call = this.table.byId.get(callId);
|
|
2986
|
+
if (call !== void 0 && (import_ts_morph8.Node.isCallExpression(call) || import_ts_morph8.Node.isNewExpression(call))) {
|
|
2987
|
+
this.resolveCallableSources(call.getExpression());
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
/** The files the parameters an answer is keyed by are declared in. */
|
|
2991
|
+
filesOf(byParameter) {
|
|
2992
|
+
const files = /* @__PURE__ */ new Set();
|
|
2993
|
+
for (const parameterId of byParameter.keys()) {
|
|
2994
|
+
const parameter = this.table.byId.get(parameterId);
|
|
2995
|
+
if (parameter !== void 0) {
|
|
2996
|
+
files.add(parameter.getSourceFile());
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
return files;
|
|
2964
3000
|
}
|
|
2965
3001
|
sitesNamedBy(answered, siteFilePaths, parameter) {
|
|
2966
3002
|
const key = nodeId(parameter);
|
|
@@ -2975,15 +3011,18 @@ var ResolutionStore = class {
|
|
|
2975
3011
|
}
|
|
2976
3012
|
/**
|
|
2977
3013
|
* Seed every expression that spells the environment, derive, and take
|
|
2978
|
-
* the sites
|
|
2979
|
-
*
|
|
3014
|
+
* back the read sites per parameter and the parameters the object is
|
|
3015
|
+
* handed to. The question is dropped afterwards, so a later ask over a
|
|
3016
|
+
* larger fact set derives it again.
|
|
2980
3017
|
*
|
|
2981
3018
|
* The reads themselves cannot be the seed: one written through a
|
|
2982
3019
|
* parameter is off an object a scan of the source has no way to pick
|
|
2983
3020
|
* out, and the whole point of asking is to find those.
|
|
2984
3021
|
*/
|
|
2985
|
-
|
|
3022
|
+
askEnvironment(seeds) {
|
|
2986
3023
|
const byParameter = /* @__PURE__ */ new Map();
|
|
3024
|
+
const receivers = /* @__PURE__ */ new Set();
|
|
3025
|
+
const passingCalls = [];
|
|
2987
3026
|
try {
|
|
2988
3027
|
for (const [object] of this.db.facts("environmentObject")) {
|
|
2989
3028
|
this.wantKey("wantedEnvObject", String(object));
|
|
@@ -2999,10 +3038,16 @@ var ResolutionStore = class {
|
|
|
2999
3038
|
sites.push(node);
|
|
3000
3039
|
byParameter.set(String(parameter), sites);
|
|
3001
3040
|
}
|
|
3041
|
+
for (const [parameter] of this.db.facts("wantedEnvParameter")) {
|
|
3042
|
+
receivers.add(String(parameter));
|
|
3043
|
+
}
|
|
3044
|
+
for (const [call] of this.db.facts("wantedEnvPassingCall")) {
|
|
3045
|
+
passingCalls.push(String(call));
|
|
3046
|
+
}
|
|
3002
3047
|
} finally {
|
|
3003
3048
|
this.forgetQuery();
|
|
3004
3049
|
}
|
|
3005
|
-
return byParameter;
|
|
3050
|
+
return { byParameter, receivers, passingCalls };
|
|
3006
3051
|
}
|
|
3007
3052
|
/**
|
|
3008
3053
|
* The project's files that hand the environment object somewhere,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SourceFile, Node, FunctionDeclaration, FunctionExpression, ArrowFunction, MethodDeclaration, Symbol, CallExpression, PropertyAccessExpression, TaggedTemplateExpression,
|
|
1
|
+
import { SourceFile, Node, Project, FunctionDeclaration, FunctionExpression, ArrowFunction, MethodDeclaration, Symbol, CallExpression, PropertyAccessExpression, TaggedTemplateExpression, ImportDeclaration, ArrayLiteralExpression, ObjectLiteralExpression, ObjectLiteralElementLike, Expression, NewExpression, Identifier } from 'ts-morph';
|
|
2
2
|
import { TransparentWrapper, RawCondition, DiscoveryPattern, TerminalPattern, InputMappingPattern, EffectArg, CallOps, LanguageAdapter, PatternPack, ExtractorOptions, TimingReport, CacheDiagnostic, ExtractionReport, InvocationRecognizer, AccessRecognizer, RawCodeStructure, RawTerminal, RawBranch, configuredCallOption, RawDeclaredContract, ContractPattern, AstCapableOps, ResponsePropertyMapping } from '@suss/extractor';
|
|
3
3
|
export { EmptyStage, ExtractionReport, PackFunnel, Timer, TimingReport, computeContentHash } from '@suss/extractor';
|
|
4
4
|
import { MessageBusSemantics, DeployableUnit, UnfollowedCall, WrapperReference, BehavioralSummary, BoundaryBinding, Predicate, TypeShape, ValueRef } from '@suss/behavioral-ir';
|
|
@@ -86,8 +86,8 @@ declare class ResolutionStore {
|
|
|
86
86
|
private lastQueryWalked;
|
|
87
87
|
/** See `environmentSiteFiles`; null until the first env question. */
|
|
88
88
|
private envSiteFiles;
|
|
89
|
-
|
|
90
|
-
private
|
|
89
|
+
/** See `environmentAnswers`; null until the first env question. */
|
|
90
|
+
private envAnswers;
|
|
91
91
|
private readonly declarations;
|
|
92
92
|
private readonly graph;
|
|
93
93
|
/** See `notePossibleCallers`. */
|
|
@@ -171,10 +171,8 @@ declare class ResolutionStore {
|
|
|
171
171
|
* a pack spells it, a name declared as that, or a parameter some
|
|
172
172
|
* caller hands one to, however many calls deep.
|
|
173
173
|
*
|
|
174
|
-
* A parameter
|
|
175
|
-
*
|
|
176
|
-
* imports this one, so a value that is not one is answered from what
|
|
177
|
-
* the store already has.
|
|
174
|
+
* A parameter's answer depends on its callers, so it comes from the
|
|
175
|
+
* parameters the environment reaches, worked out once per run.
|
|
178
176
|
*/
|
|
179
177
|
isEnvironmentValue(value: Node): boolean;
|
|
180
178
|
private hasAnswer;
|
|
@@ -183,24 +181,31 @@ declare class ResolutionStore {
|
|
|
183
181
|
* from, for a reader standing at a call. One question covers the
|
|
184
182
|
* whole project: a project has a handful of environment reads and
|
|
185
183
|
* thousands of parameters, and with the read bound the rules run from
|
|
186
|
-
* each callee to its callers.
|
|
187
|
-
*
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
* each callee to its callers. The facts README says which files that
|
|
185
|
+
* reads and why it is asked once.
|
|
186
|
+
*/
|
|
187
|
+
envNamers(project: Project): EnvironmentNamers;
|
|
188
|
+
private environmentAnswers;
|
|
189
|
+
/**
|
|
190
|
+
* Ask until every call handing the environment on has had its callee
|
|
191
|
+
* read, one hop a round, so the answer covers each parameter it lands in.
|
|
191
192
|
*/
|
|
192
|
-
|
|
193
|
+
private followEnvironment;
|
|
194
|
+
private readCalleeOf;
|
|
195
|
+
/** The files the parameters an answer is keyed by are declared in. */
|
|
196
|
+
private filesOf;
|
|
193
197
|
private sitesNamedBy;
|
|
194
198
|
/**
|
|
195
199
|
* Seed every expression that spells the environment, derive, and take
|
|
196
|
-
* the sites
|
|
197
|
-
*
|
|
200
|
+
* back the read sites per parameter and the parameters the object is
|
|
201
|
+
* handed to. The question is dropped afterwards, so a later ask over a
|
|
202
|
+
* larger fact set derives it again.
|
|
198
203
|
*
|
|
199
204
|
* The reads themselves cannot be the seed: one written through a
|
|
200
205
|
* parameter is off an object a scan of the source has no way to pick
|
|
201
206
|
* out, and the whole point of asking is to find those.
|
|
202
207
|
*/
|
|
203
|
-
private
|
|
208
|
+
private askEnvironment;
|
|
204
209
|
/**
|
|
205
210
|
* The project's files that hand the environment object somewhere,
|
|
206
211
|
* read into the store. Which files those are cannot depend on what a
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SourceFile, Node, FunctionDeclaration, FunctionExpression, ArrowFunction, MethodDeclaration, Symbol, CallExpression, PropertyAccessExpression, TaggedTemplateExpression,
|
|
1
|
+
import { SourceFile, Node, Project, FunctionDeclaration, FunctionExpression, ArrowFunction, MethodDeclaration, Symbol, CallExpression, PropertyAccessExpression, TaggedTemplateExpression, ImportDeclaration, ArrayLiteralExpression, ObjectLiteralExpression, ObjectLiteralElementLike, Expression, NewExpression, Identifier } from 'ts-morph';
|
|
2
2
|
import { TransparentWrapper, RawCondition, DiscoveryPattern, TerminalPattern, InputMappingPattern, EffectArg, CallOps, LanguageAdapter, PatternPack, ExtractorOptions, TimingReport, CacheDiagnostic, ExtractionReport, InvocationRecognizer, AccessRecognizer, RawCodeStructure, RawTerminal, RawBranch, configuredCallOption, RawDeclaredContract, ContractPattern, AstCapableOps, ResponsePropertyMapping } from '@suss/extractor';
|
|
3
3
|
export { EmptyStage, ExtractionReport, PackFunnel, Timer, TimingReport, computeContentHash } from '@suss/extractor';
|
|
4
4
|
import { MessageBusSemantics, DeployableUnit, UnfollowedCall, WrapperReference, BehavioralSummary, BoundaryBinding, Predicate, TypeShape, ValueRef } from '@suss/behavioral-ir';
|
|
@@ -86,8 +86,8 @@ declare class ResolutionStore {
|
|
|
86
86
|
private lastQueryWalked;
|
|
87
87
|
/** See `environmentSiteFiles`; null until the first env question. */
|
|
88
88
|
private envSiteFiles;
|
|
89
|
-
|
|
90
|
-
private
|
|
89
|
+
/** See `environmentAnswers`; null until the first env question. */
|
|
90
|
+
private envAnswers;
|
|
91
91
|
private readonly declarations;
|
|
92
92
|
private readonly graph;
|
|
93
93
|
/** See `notePossibleCallers`. */
|
|
@@ -171,10 +171,8 @@ declare class ResolutionStore {
|
|
|
171
171
|
* a pack spells it, a name declared as that, or a parameter some
|
|
172
172
|
* caller hands one to, however many calls deep.
|
|
173
173
|
*
|
|
174
|
-
* A parameter
|
|
175
|
-
*
|
|
176
|
-
* imports this one, so a value that is not one is answered from what
|
|
177
|
-
* the store already has.
|
|
174
|
+
* A parameter's answer depends on its callers, so it comes from the
|
|
175
|
+
* parameters the environment reaches, worked out once per run.
|
|
178
176
|
*/
|
|
179
177
|
isEnvironmentValue(value: Node): boolean;
|
|
180
178
|
private hasAnswer;
|
|
@@ -183,24 +181,31 @@ declare class ResolutionStore {
|
|
|
183
181
|
* from, for a reader standing at a call. One question covers the
|
|
184
182
|
* whole project: a project has a handful of environment reads and
|
|
185
183
|
* thousands of parameters, and with the read bound the rules run from
|
|
186
|
-
* each callee to its callers.
|
|
187
|
-
*
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
* each callee to its callers. The facts README says which files that
|
|
185
|
+
* reads and why it is asked once.
|
|
186
|
+
*/
|
|
187
|
+
envNamers(project: Project): EnvironmentNamers;
|
|
188
|
+
private environmentAnswers;
|
|
189
|
+
/**
|
|
190
|
+
* Ask until every call handing the environment on has had its callee
|
|
191
|
+
* read, one hop a round, so the answer covers each parameter it lands in.
|
|
191
192
|
*/
|
|
192
|
-
|
|
193
|
+
private followEnvironment;
|
|
194
|
+
private readCalleeOf;
|
|
195
|
+
/** The files the parameters an answer is keyed by are declared in. */
|
|
196
|
+
private filesOf;
|
|
193
197
|
private sitesNamedBy;
|
|
194
198
|
/**
|
|
195
199
|
* Seed every expression that spells the environment, derive, and take
|
|
196
|
-
* the sites
|
|
197
|
-
*
|
|
200
|
+
* back the read sites per parameter and the parameters the object is
|
|
201
|
+
* handed to. The question is dropped afterwards, so a later ask over a
|
|
202
|
+
* larger fact set derives it again.
|
|
198
203
|
*
|
|
199
204
|
* The reads themselves cannot be the seed: one written through a
|
|
200
205
|
* parameter is off an object a scan of the source has no way to pick
|
|
201
206
|
* out, and the whole point of asking is to find those.
|
|
202
207
|
*/
|
|
203
|
-
private
|
|
208
|
+
private askEnvironment;
|
|
204
209
|
/**
|
|
205
210
|
* The project's files that hand the environment object somewhere,
|
|
206
211
|
* read into the store. Which files those are cannot depend on what a
|
package/dist/index.js
CHANGED
|
@@ -2635,8 +2635,8 @@ var ResolutionStore = class {
|
|
|
2635
2635
|
lastQueryWalked = [];
|
|
2636
2636
|
/** See `environmentSiteFiles`; null until the first env question. */
|
|
2637
2637
|
envSiteFiles = null;
|
|
2638
|
-
|
|
2639
|
-
|
|
2638
|
+
/** See `environmentAnswers`; null until the first env question. */
|
|
2639
|
+
envAnswers = null;
|
|
2640
2640
|
declarations = /* @__PURE__ */ new Map();
|
|
2641
2641
|
graph = new ModuleGraph();
|
|
2642
2642
|
/** See `notePossibleCallers`. */
|
|
@@ -2862,10 +2862,8 @@ var ResolutionStore = class {
|
|
|
2862
2862
|
* a pack spells it, a name declared as that, or a parameter some
|
|
2863
2863
|
* caller hands one to, however many calls deep.
|
|
2864
2864
|
*
|
|
2865
|
-
* A parameter
|
|
2866
|
-
*
|
|
2867
|
-
* imports this one, so a value that is not one is answered from what
|
|
2868
|
-
* the store already has.
|
|
2865
|
+
* A parameter's answer depends on its callers, so it comes from the
|
|
2866
|
+
* parameters the environment reaches, worked out once per run.
|
|
2869
2867
|
*/
|
|
2870
2868
|
isEnvironmentValue(value) {
|
|
2871
2869
|
const target = factKeyOf(value);
|
|
@@ -2873,17 +2871,14 @@ var ResolutionStore = class {
|
|
|
2873
2871
|
this.derive();
|
|
2874
2872
|
return {
|
|
2875
2873
|
environment: this.hasAnswer("wantedEnvironmentValue", target),
|
|
2876
|
-
|
|
2874
|
+
parameters: this.answersFor("wantedRefersToParam", nodeId(target))
|
|
2877
2875
|
};
|
|
2878
2876
|
});
|
|
2879
|
-
if (first.environment ||
|
|
2877
|
+
if (first.environment || first.parameters.length === 0) {
|
|
2880
2878
|
return first.environment;
|
|
2881
2879
|
}
|
|
2882
|
-
this.
|
|
2883
|
-
return
|
|
2884
|
-
this.derive();
|
|
2885
|
-
return this.hasAnswer("wantedEnvironmentValue", target);
|
|
2886
|
-
});
|
|
2880
|
+
const { receivers } = this.environmentAnswers(target.getProject());
|
|
2881
|
+
return first.parameters.some((parameter) => receivers.has(parameter));
|
|
2887
2882
|
}
|
|
2888
2883
|
hasAnswer(relation, target) {
|
|
2889
2884
|
return this.answersFor(relation, nodeId(target)).length > 0;
|
|
@@ -2893,28 +2888,69 @@ var ResolutionStore = class {
|
|
|
2893
2888
|
* from, for a reader standing at a call. One question covers the
|
|
2894
2889
|
* whole project: a project has a handful of environment reads and
|
|
2895
2890
|
* thousands of parameters, and with the read bound the rules run from
|
|
2896
|
-
* each callee to its callers.
|
|
2897
|
-
*
|
|
2898
|
-
* `definedIn` is the callee's own file, read into the store before
|
|
2899
|
-
* the question so a helper nothing had extracted yet is among the
|
|
2900
|
-
* facts the rules run over.
|
|
2891
|
+
* each callee to its callers. The facts README says which files that
|
|
2892
|
+
* reads and why it is asked once.
|
|
2901
2893
|
*/
|
|
2902
|
-
envNamers(
|
|
2903
|
-
|
|
2894
|
+
envNamers(project) {
|
|
2895
|
+
return this.environmentAnswers(project).namers;
|
|
2896
|
+
}
|
|
2897
|
+
environmentAnswers(project) {
|
|
2898
|
+
if (this.envAnswers !== null) {
|
|
2899
|
+
return this.envAnswers;
|
|
2900
|
+
}
|
|
2901
|
+
const siteFiles = this.environmentSiteFiles(project);
|
|
2904
2902
|
if (siteFiles.length === 0) {
|
|
2905
|
-
|
|
2903
|
+
this.envAnswers = { namers: NO_NAMERS, receivers: /* @__PURE__ */ new Set() };
|
|
2904
|
+
return this.envAnswers;
|
|
2906
2905
|
}
|
|
2907
|
-
this.
|
|
2908
|
-
|
|
2909
|
-
|
|
2906
|
+
const helpers = this.followEnvironment(siteFiles).byParameter;
|
|
2907
|
+
for (const helperFile of this.filesOf(helpers)) {
|
|
2908
|
+
this.readPossibleCallersOf(helperFile);
|
|
2910
2909
|
}
|
|
2911
|
-
const
|
|
2910
|
+
const { byParameter, receivers } = this.followEnvironment(siteFiles);
|
|
2912
2911
|
const siteFilePaths = new Set(siteFiles.map((one) => one.getFilePath()));
|
|
2913
|
-
this.
|
|
2914
|
-
|
|
2912
|
+
this.envAnswers = {
|
|
2913
|
+
namers: {
|
|
2914
|
+
sitesNaming: (parameter) => this.sitesNamedBy(byParameter, siteFilePaths, parameter)
|
|
2915
|
+
},
|
|
2916
|
+
receivers
|
|
2915
2917
|
};
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
+
return this.envAnswers;
|
|
2919
|
+
}
|
|
2920
|
+
/**
|
|
2921
|
+
* Ask until every call handing the environment on has had its callee
|
|
2922
|
+
* read, one hop a round, so the answer covers each parameter it lands in.
|
|
2923
|
+
*/
|
|
2924
|
+
followEnvironment(seeds) {
|
|
2925
|
+
const followed = /* @__PURE__ */ new Set();
|
|
2926
|
+
for (; ; ) {
|
|
2927
|
+
const asked = this.askEnvironment(seeds);
|
|
2928
|
+
const next = asked.passingCalls.filter((call) => !followed.has(call));
|
|
2929
|
+
if (next.length === 0) {
|
|
2930
|
+
return asked;
|
|
2931
|
+
}
|
|
2932
|
+
for (const callId of next) {
|
|
2933
|
+
followed.add(callId);
|
|
2934
|
+
this.readCalleeOf(callId);
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
readCalleeOf(callId) {
|
|
2939
|
+
const call = this.table.byId.get(callId);
|
|
2940
|
+
if (call !== void 0 && (Node7.isCallExpression(call) || Node7.isNewExpression(call))) {
|
|
2941
|
+
this.resolveCallableSources(call.getExpression());
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
/** The files the parameters an answer is keyed by are declared in. */
|
|
2945
|
+
filesOf(byParameter) {
|
|
2946
|
+
const files = /* @__PURE__ */ new Set();
|
|
2947
|
+
for (const parameterId of byParameter.keys()) {
|
|
2948
|
+
const parameter = this.table.byId.get(parameterId);
|
|
2949
|
+
if (parameter !== void 0) {
|
|
2950
|
+
files.add(parameter.getSourceFile());
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
return files;
|
|
2918
2954
|
}
|
|
2919
2955
|
sitesNamedBy(answered, siteFilePaths, parameter) {
|
|
2920
2956
|
const key = nodeId(parameter);
|
|
@@ -2929,15 +2965,18 @@ var ResolutionStore = class {
|
|
|
2929
2965
|
}
|
|
2930
2966
|
/**
|
|
2931
2967
|
* Seed every expression that spells the environment, derive, and take
|
|
2932
|
-
* the sites
|
|
2933
|
-
*
|
|
2968
|
+
* back the read sites per parameter and the parameters the object is
|
|
2969
|
+
* handed to. The question is dropped afterwards, so a later ask over a
|
|
2970
|
+
* larger fact set derives it again.
|
|
2934
2971
|
*
|
|
2935
2972
|
* The reads themselves cannot be the seed: one written through a
|
|
2936
2973
|
* parameter is off an object a scan of the source has no way to pick
|
|
2937
2974
|
* out, and the whole point of asking is to find those.
|
|
2938
2975
|
*/
|
|
2939
|
-
|
|
2976
|
+
askEnvironment(seeds) {
|
|
2940
2977
|
const byParameter = /* @__PURE__ */ new Map();
|
|
2978
|
+
const receivers = /* @__PURE__ */ new Set();
|
|
2979
|
+
const passingCalls = [];
|
|
2941
2980
|
try {
|
|
2942
2981
|
for (const [object] of this.db.facts("environmentObject")) {
|
|
2943
2982
|
this.wantKey("wantedEnvObject", String(object));
|
|
@@ -2953,10 +2992,16 @@ var ResolutionStore = class {
|
|
|
2953
2992
|
sites.push(node);
|
|
2954
2993
|
byParameter.set(String(parameter), sites);
|
|
2955
2994
|
}
|
|
2995
|
+
for (const [parameter] of this.db.facts("wantedEnvParameter")) {
|
|
2996
|
+
receivers.add(String(parameter));
|
|
2997
|
+
}
|
|
2998
|
+
for (const [call] of this.db.facts("wantedEnvPassingCall")) {
|
|
2999
|
+
passingCalls.push(String(call));
|
|
3000
|
+
}
|
|
2956
3001
|
} finally {
|
|
2957
3002
|
this.forgetQuery();
|
|
2958
3003
|
}
|
|
2959
|
-
return byParameter;
|
|
3004
|
+
return { byParameter, receivers, passingCalls };
|
|
2960
3005
|
}
|
|
2961
3006
|
/**
|
|
2962
3007
|
* The project's files that hand the environment object somewhere,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/adapter-typescript",
|
|
3
|
-
"version": "0.33.
|
|
3
|
+
"version": "0.33.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Read a TypeScript or JavaScript codebase with suss and check what each handler returns against every caller, spec and template it can see.",
|
|
6
6
|
"keywords": [
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"typecheck": "tsc --noEmit"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@suss/behavioral-ir": "0.33.
|
|
52
|
-
"@suss/datalog": "0.33.
|
|
53
|
-
"@suss/extractor": "0.33.
|
|
54
|
-
"@suss/resolution": "0.33.
|
|
55
|
-
"@suss/values": "0.33.
|
|
51
|
+
"@suss/behavioral-ir": "0.33.1",
|
|
52
|
+
"@suss/datalog": "0.33.1",
|
|
53
|
+
"@suss/extractor": "0.33.1",
|
|
54
|
+
"@suss/resolution": "0.33.1",
|
|
55
|
+
"@suss/values": "0.33.1",
|
|
56
56
|
"graphql": "^16.8.0",
|
|
57
57
|
"picomatch": "^4.0.4",
|
|
58
58
|
"ts-morph": "^23.0.0",
|