@suss/adapter-ruby 0.5.3 → 0.5.4
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 +45 -12
- package/dist/index.d.cts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +45 -12
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -335,7 +335,7 @@ async function mixinChain(self, callName, lookup, active, present) {
|
|
|
335
335
|
return chain;
|
|
336
336
|
}
|
|
337
337
|
async function chainFor(qualifiedName, lookup, active) {
|
|
338
|
-
const blocks = await reachDefinition(qualifiedName, lookup);
|
|
338
|
+
const blocks = lookup.localDefinition?.(qualifiedName) ?? await reachDefinition(qualifiedName, lookup);
|
|
339
339
|
if (blocks === null) {
|
|
340
340
|
return [{ type: "unfollowed", name: qualifiedName }];
|
|
341
341
|
}
|
|
@@ -16003,7 +16003,7 @@ function createFileCache(parse3, readFile) {
|
|
|
16003
16003
|
}
|
|
16004
16004
|
};
|
|
16005
16005
|
}
|
|
16006
|
-
function fieldReadContext(pattern, cache, storage) {
|
|
16006
|
+
function fieldReadContext(pattern, cache, fileBlocks, storage) {
|
|
16007
16007
|
return {
|
|
16008
16008
|
pattern,
|
|
16009
16009
|
cache,
|
|
@@ -16012,10 +16012,17 @@ function fieldReadContext(pattern, cache, storage) {
|
|
|
16012
16012
|
root: pattern.root,
|
|
16013
16013
|
pathConvention: pattern.pathConvention,
|
|
16014
16014
|
ancestryRootClassNames: pattern.ancestryRootClassNames,
|
|
16015
|
-
parsedFile: (absPath) => cache.get(absPath)
|
|
16015
|
+
parsedFile: (absPath) => cache.get(absPath),
|
|
16016
|
+
localDefinition: (name) => sameFileBlocks(name, fileBlocks)
|
|
16016
16017
|
}
|
|
16017
16018
|
};
|
|
16018
16019
|
}
|
|
16020
|
+
function sameFileBlocks(name, fileBlocks) {
|
|
16021
|
+
const matches = fileBlocks.filter(
|
|
16022
|
+
(block) => block.info.qualifiedName === name
|
|
16023
|
+
);
|
|
16024
|
+
return matches.length === 0 ? null : matches;
|
|
16025
|
+
}
|
|
16019
16026
|
function typeContext(scope, pattern) {
|
|
16020
16027
|
return {
|
|
16021
16028
|
nesting: scope.nesting,
|
|
@@ -16027,39 +16034,65 @@ function typeContext(scope, pattern) {
|
|
|
16027
16034
|
}
|
|
16028
16035
|
async function discoverUnits(root, options) {
|
|
16029
16036
|
const classes = [];
|
|
16030
|
-
|
|
16037
|
+
walkDefinitions(root, (info) => classes.push(info));
|
|
16031
16038
|
const knownClasses = new Set(classes.map((info) => info.qualifiedName));
|
|
16039
|
+
const fileBlocks = classes.map((info) => ({
|
|
16040
|
+
info,
|
|
16041
|
+
knownClasses
|
|
16042
|
+
}));
|
|
16032
16043
|
const units = [];
|
|
16033
16044
|
for (const info of classes) {
|
|
16034
|
-
const ownBlocks =
|
|
16045
|
+
const ownBlocks = fileBlocks.filter(
|
|
16046
|
+
(block) => block.info.qualifiedName === info.qualifiedName
|
|
16047
|
+
);
|
|
16035
16048
|
for (const pack of options.packs) {
|
|
16036
16049
|
for (const pattern of pack.discovery) {
|
|
16037
16050
|
units.push(
|
|
16038
|
-
...await unitsFor(
|
|
16051
|
+
...await unitsFor(
|
|
16052
|
+
pattern,
|
|
16053
|
+
pack,
|
|
16054
|
+
info,
|
|
16055
|
+
ownBlocks,
|
|
16056
|
+
fileBlocks,
|
|
16057
|
+
options
|
|
16058
|
+
)
|
|
16039
16059
|
);
|
|
16040
16060
|
}
|
|
16041
16061
|
}
|
|
16042
16062
|
}
|
|
16043
16063
|
return units;
|
|
16044
16064
|
}
|
|
16045
|
-
function
|
|
16065
|
+
function reachesConfiguredBase(ancestry, self, pattern) {
|
|
16066
|
+
return ancestry.some(
|
|
16067
|
+
(entry) => entry.name !== self && pattern.baseClassNames.includes(entry.name)
|
|
16068
|
+
);
|
|
16069
|
+
}
|
|
16070
|
+
function unitsFor(pattern, pack, info, ownBlocks, fileBlocks, options) {
|
|
16046
16071
|
const table = {
|
|
16047
|
-
graphqlObjectFields: (p) => graphqlObjectFieldUnits(p, pack, info, ownBlocks, options)
|
|
16072
|
+
graphqlObjectFields: (p) => graphqlObjectFieldUnits(p, pack, info, ownBlocks, fileBlocks, options)
|
|
16048
16073
|
};
|
|
16049
16074
|
return (0, import_behavioral_ir.dispatchByType)(table, pattern);
|
|
16050
16075
|
}
|
|
16051
|
-
async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, options) {
|
|
16052
|
-
if (info.
|
|
16076
|
+
async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, fileBlocks, options) {
|
|
16077
|
+
if (info.bodyNode === null || pattern.baseClassNames.includes(info.qualifiedName)) {
|
|
16078
|
+
return [];
|
|
16079
|
+
}
|
|
16080
|
+
const ctx = fieldReadContext(
|
|
16081
|
+
pattern,
|
|
16082
|
+
options.cache,
|
|
16083
|
+
fileBlocks,
|
|
16084
|
+
options.storage
|
|
16085
|
+
);
|
|
16086
|
+
const ancestry = await ancestryOf(info.qualifiedName, ownBlocks, ctx.lookup);
|
|
16087
|
+
if (!reachesConfiguredBase(ancestry, info.qualifiedName, pattern)) {
|
|
16053
16088
|
return [];
|
|
16054
16089
|
}
|
|
16055
16090
|
const typeName = graphqlTypeNameFromQualified(
|
|
16056
16091
|
info.qualifiedName,
|
|
16057
16092
|
pattern.typeNameConvention
|
|
16058
16093
|
);
|
|
16059
|
-
const ctx = fieldReadContext(pattern, options.cache, options.storage);
|
|
16060
16094
|
const knownClasses = ownBlocks[0]?.knownClasses ?? /* @__PURE__ */ new Set();
|
|
16061
16095
|
const scope = { nesting: info.bodyNesting, knownClasses };
|
|
16062
|
-
const ancestry = await ancestryOf(info.qualifiedName, ownBlocks, ctx.lookup);
|
|
16063
16096
|
const declsByName = /* @__PURE__ */ new Map();
|
|
16064
16097
|
for (const stmt of bodyStatements(info.bodyNode)) {
|
|
16065
16098
|
const decl = await readFieldCall(stmt, scope, ctx, ancestry);
|
package/dist/index.d.cts
CHANGED
|
@@ -101,6 +101,12 @@ interface AncestorLookup {
|
|
|
101
101
|
*/
|
|
102
102
|
ancestryRootClassNames: readonly string[];
|
|
103
103
|
parsedFile(absPath: string): Promise<Node | null>;
|
|
104
|
+
/**
|
|
105
|
+
* The blocks the file being read defines under a name, consulted
|
|
106
|
+
* before the path convention, since a constant defined in the same
|
|
107
|
+
* file is visible without a file of its own.
|
|
108
|
+
*/
|
|
109
|
+
localDefinition?(qualifiedName: string): ReachedBody[] | null;
|
|
104
110
|
}
|
|
105
111
|
/**
|
|
106
112
|
* Every block a file defines under `qualifiedName`, or null when the
|
|
@@ -164,10 +170,10 @@ interface RbStoragePattern {
|
|
|
164
170
|
storageSystem: "postgres" | "mysql" | "sqlite";
|
|
165
171
|
}
|
|
166
172
|
type RubyDiscoveryPattern = GraphqlObjectFields;
|
|
167
|
-
/** A class
|
|
173
|
+
/** A class or module whose ancestry reaches one of `baseClassNames` declares GraphQL fields through DSL calls in its own body. */
|
|
168
174
|
interface GraphqlObjectFields {
|
|
169
175
|
type: "graphqlObjectFields";
|
|
170
|
-
/** The base
|
|
176
|
+
/** The base classes the library itself generates. The walk crosses a project's own intermediate bases on its own, so config only has to add a base with another name. */
|
|
171
177
|
baseClassNames: string[];
|
|
172
178
|
/** The directory a wiring keyword's referenced class is looked up under. That is the project's own layout, not the library's. */
|
|
173
179
|
root: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -101,6 +101,12 @@ interface AncestorLookup {
|
|
|
101
101
|
*/
|
|
102
102
|
ancestryRootClassNames: readonly string[];
|
|
103
103
|
parsedFile(absPath: string): Promise<Node | null>;
|
|
104
|
+
/**
|
|
105
|
+
* The blocks the file being read defines under a name, consulted
|
|
106
|
+
* before the path convention, since a constant defined in the same
|
|
107
|
+
* file is visible without a file of its own.
|
|
108
|
+
*/
|
|
109
|
+
localDefinition?(qualifiedName: string): ReachedBody[] | null;
|
|
104
110
|
}
|
|
105
111
|
/**
|
|
106
112
|
* Every block a file defines under `qualifiedName`, or null when the
|
|
@@ -164,10 +170,10 @@ interface RbStoragePattern {
|
|
|
164
170
|
storageSystem: "postgres" | "mysql" | "sqlite";
|
|
165
171
|
}
|
|
166
172
|
type RubyDiscoveryPattern = GraphqlObjectFields;
|
|
167
|
-
/** A class
|
|
173
|
+
/** A class or module whose ancestry reaches one of `baseClassNames` declares GraphQL fields through DSL calls in its own body. */
|
|
168
174
|
interface GraphqlObjectFields {
|
|
169
175
|
type: "graphqlObjectFields";
|
|
170
|
-
/** The base
|
|
176
|
+
/** The base classes the library itself generates. The walk crosses a project's own intermediate bases on its own, so config only has to add a base with another name. */
|
|
171
177
|
baseClassNames: string[];
|
|
172
178
|
/** The directory a wiring keyword's referenced class is looked up under. That is the project's own layout, not the library's. */
|
|
173
179
|
root: string;
|
package/dist/index.js
CHANGED
|
@@ -284,7 +284,7 @@ async function mixinChain(self, callName, lookup, active, present) {
|
|
|
284
284
|
return chain;
|
|
285
285
|
}
|
|
286
286
|
async function chainFor(qualifiedName, lookup, active) {
|
|
287
|
-
const blocks = await reachDefinition(qualifiedName, lookup);
|
|
287
|
+
const blocks = lookup.localDefinition?.(qualifiedName) ?? await reachDefinition(qualifiedName, lookup);
|
|
288
288
|
if (blocks === null) {
|
|
289
289
|
return [{ type: "unfollowed", name: qualifiedName }];
|
|
290
290
|
}
|
|
@@ -15952,7 +15952,7 @@ function createFileCache(parse3, readFile) {
|
|
|
15952
15952
|
}
|
|
15953
15953
|
};
|
|
15954
15954
|
}
|
|
15955
|
-
function fieldReadContext(pattern, cache, storage) {
|
|
15955
|
+
function fieldReadContext(pattern, cache, fileBlocks, storage) {
|
|
15956
15956
|
return {
|
|
15957
15957
|
pattern,
|
|
15958
15958
|
cache,
|
|
@@ -15961,10 +15961,17 @@ function fieldReadContext(pattern, cache, storage) {
|
|
|
15961
15961
|
root: pattern.root,
|
|
15962
15962
|
pathConvention: pattern.pathConvention,
|
|
15963
15963
|
ancestryRootClassNames: pattern.ancestryRootClassNames,
|
|
15964
|
-
parsedFile: (absPath) => cache.get(absPath)
|
|
15964
|
+
parsedFile: (absPath) => cache.get(absPath),
|
|
15965
|
+
localDefinition: (name) => sameFileBlocks(name, fileBlocks)
|
|
15965
15966
|
}
|
|
15966
15967
|
};
|
|
15967
15968
|
}
|
|
15969
|
+
function sameFileBlocks(name, fileBlocks) {
|
|
15970
|
+
const matches = fileBlocks.filter(
|
|
15971
|
+
(block) => block.info.qualifiedName === name
|
|
15972
|
+
);
|
|
15973
|
+
return matches.length === 0 ? null : matches;
|
|
15974
|
+
}
|
|
15968
15975
|
function typeContext(scope, pattern) {
|
|
15969
15976
|
return {
|
|
15970
15977
|
nesting: scope.nesting,
|
|
@@ -15976,39 +15983,65 @@ function typeContext(scope, pattern) {
|
|
|
15976
15983
|
}
|
|
15977
15984
|
async function discoverUnits(root, options) {
|
|
15978
15985
|
const classes = [];
|
|
15979
|
-
|
|
15986
|
+
walkDefinitions(root, (info) => classes.push(info));
|
|
15980
15987
|
const knownClasses = new Set(classes.map((info) => info.qualifiedName));
|
|
15988
|
+
const fileBlocks = classes.map((info) => ({
|
|
15989
|
+
info,
|
|
15990
|
+
knownClasses
|
|
15991
|
+
}));
|
|
15981
15992
|
const units = [];
|
|
15982
15993
|
for (const info of classes) {
|
|
15983
|
-
const ownBlocks =
|
|
15994
|
+
const ownBlocks = fileBlocks.filter(
|
|
15995
|
+
(block) => block.info.qualifiedName === info.qualifiedName
|
|
15996
|
+
);
|
|
15984
15997
|
for (const pack of options.packs) {
|
|
15985
15998
|
for (const pattern of pack.discovery) {
|
|
15986
15999
|
units.push(
|
|
15987
|
-
...await unitsFor(
|
|
16000
|
+
...await unitsFor(
|
|
16001
|
+
pattern,
|
|
16002
|
+
pack,
|
|
16003
|
+
info,
|
|
16004
|
+
ownBlocks,
|
|
16005
|
+
fileBlocks,
|
|
16006
|
+
options
|
|
16007
|
+
)
|
|
15988
16008
|
);
|
|
15989
16009
|
}
|
|
15990
16010
|
}
|
|
15991
16011
|
}
|
|
15992
16012
|
return units;
|
|
15993
16013
|
}
|
|
15994
|
-
function
|
|
16014
|
+
function reachesConfiguredBase(ancestry, self, pattern) {
|
|
16015
|
+
return ancestry.some(
|
|
16016
|
+
(entry) => entry.name !== self && pattern.baseClassNames.includes(entry.name)
|
|
16017
|
+
);
|
|
16018
|
+
}
|
|
16019
|
+
function unitsFor(pattern, pack, info, ownBlocks, fileBlocks, options) {
|
|
15995
16020
|
const table = {
|
|
15996
|
-
graphqlObjectFields: (p) => graphqlObjectFieldUnits(p, pack, info, ownBlocks, options)
|
|
16021
|
+
graphqlObjectFields: (p) => graphqlObjectFieldUnits(p, pack, info, ownBlocks, fileBlocks, options)
|
|
15997
16022
|
};
|
|
15998
16023
|
return dispatchByType(table, pattern);
|
|
15999
16024
|
}
|
|
16000
|
-
async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, options) {
|
|
16001
|
-
if (info.
|
|
16025
|
+
async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, fileBlocks, options) {
|
|
16026
|
+
if (info.bodyNode === null || pattern.baseClassNames.includes(info.qualifiedName)) {
|
|
16027
|
+
return [];
|
|
16028
|
+
}
|
|
16029
|
+
const ctx = fieldReadContext(
|
|
16030
|
+
pattern,
|
|
16031
|
+
options.cache,
|
|
16032
|
+
fileBlocks,
|
|
16033
|
+
options.storage
|
|
16034
|
+
);
|
|
16035
|
+
const ancestry = await ancestryOf(info.qualifiedName, ownBlocks, ctx.lookup);
|
|
16036
|
+
if (!reachesConfiguredBase(ancestry, info.qualifiedName, pattern)) {
|
|
16002
16037
|
return [];
|
|
16003
16038
|
}
|
|
16004
16039
|
const typeName = graphqlTypeNameFromQualified(
|
|
16005
16040
|
info.qualifiedName,
|
|
16006
16041
|
pattern.typeNameConvention
|
|
16007
16042
|
);
|
|
16008
|
-
const ctx = fieldReadContext(pattern, options.cache, options.storage);
|
|
16009
16043
|
const knownClasses = ownBlocks[0]?.knownClasses ?? /* @__PURE__ */ new Set();
|
|
16010
16044
|
const scope = { nesting: info.bodyNesting, knownClasses };
|
|
16011
|
-
const ancestry = await ancestryOf(info.qualifiedName, ownBlocks, ctx.lookup);
|
|
16012
16045
|
const declsByName = /* @__PURE__ */ new Map();
|
|
16013
16046
|
for (const stmt of bodyStatements(info.bodyNode)) {
|
|
16014
16047
|
const decl = await readFieldCall(stmt, scope, ctx, ancestry);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/adapter-ruby",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ruby language adapter for suss, parsing source with tree-sitter (WASM), resolving constant nesting with a lexical binder, and emitting raw extractions for the suss pipeline.",
|
|
6
6
|
"keywords": [
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@suss/behavioral-ir": "0.5.
|
|
51
|
-
"@suss/datalog": "0.5.
|
|
52
|
-
"@suss/extractor": "0.5.
|
|
50
|
+
"@suss/behavioral-ir": "0.5.4",
|
|
51
|
+
"@suss/datalog": "0.5.4",
|
|
52
|
+
"@suss/extractor": "0.5.4",
|
|
53
53
|
"web-tree-sitter": "^0.26.11"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|