Skip to content

Commit 128ac4a

Browse files
committed
fix a few more things related to type cacheing
1 parent c35a156 commit 128ac4a

File tree

3 files changed

+113
-38
lines changed

3 files changed

+113
-38
lines changed

packages/graphql-language-service-server/src/GraphQLCache.ts

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -433,11 +433,11 @@ export class GraphQLCache implements GraphQLCacheInterface {
433433
};
434434

435435
async updateFragmentDefinition(
436-
rootDir: Uri,
436+
projectCacheKey: Uri,
437437
filePath: Uri,
438438
contents: Array<CachedContent>,
439439
): Promise<void> {
440-
const cache = this._fragmentDefinitionsCache.get(rootDir);
440+
const cache = this._fragmentDefinitionsCache.get(projectCacheKey);
441441
const asts = contents.map(({ query }) => {
442442
try {
443443
return {
@@ -455,29 +455,44 @@ export class GraphQLCache implements GraphQLCacheInterface {
455455
cache.delete(key);
456456
}
457457
}
458-
for (const { ast, query } of asts) {
459-
if (!ast) {
460-
continue;
461-
}
462-
for (const definition of ast.definitions) {
463-
if (definition.kind === Kind.FRAGMENT_DEFINITION) {
464-
cache.set(definition.name.value, {
465-
filePath,
466-
content: query,
467-
definition,
468-
});
469-
}
458+
this._setFragmentCache(asts, cache, filePath);
459+
} else {
460+
const newFragmentCache = this._setFragmentCache(
461+
asts,
462+
new Map(),
463+
filePath,
464+
);
465+
this._fragmentDefinitionsCache.set(projectCacheKey, newFragmentCache);
466+
}
467+
}
468+
_setFragmentCache(
469+
asts: { ast: DocumentNode | null; query: string }[],
470+
fragmentCache: Map<string, FragmentInfo>,
471+
filePath: string | undefined,
472+
) {
473+
for (const { ast, query } of asts) {
474+
if (!ast) {
475+
continue;
476+
}
477+
for (const definition of ast.definitions) {
478+
if (definition.kind === Kind.FRAGMENT_DEFINITION) {
479+
fragmentCache.set(definition.name.value, {
480+
filePath,
481+
content: query,
482+
definition,
483+
});
470484
}
471485
}
472486
}
487+
return fragmentCache;
473488
}
474489

475490
async updateObjectTypeDefinition(
476-
rootDir: Uri,
491+
projectCacheKey: Uri,
477492
filePath: Uri,
478493
contents: Array<CachedContent>,
479494
): Promise<void> {
480-
const cache = this._typeDefinitionsCache.get(rootDir);
495+
const cache = this._typeDefinitionsCache.get(projectCacheKey);
481496
const asts = contents.map(({ query }) => {
482497
try {
483498
return {
@@ -495,21 +510,32 @@ export class GraphQLCache implements GraphQLCacheInterface {
495510
cache.delete(key);
496511
}
497512
}
498-
for (const { ast, query } of asts) {
499-
if (!ast) {
500-
continue;
501-
}
502-
for (const definition of ast.definitions) {
503-
if (isTypeDefinitionNode(definition)) {
504-
cache.set(definition.name.value, {
505-
filePath,
506-
content: query,
507-
definition,
508-
});
509-
}
513+
this._setDefinitionCache(asts, cache, filePath);
514+
} else {
515+
const newTypeCache = this._setDefinitionCache(asts, new Map(), filePath);
516+
this._typeDefinitionsCache.set(projectCacheKey, newTypeCache);
517+
}
518+
}
519+
_setDefinitionCache(
520+
asts: { ast: DocumentNode | null; query: string }[],
521+
typeCache: Map<string, ObjectTypeInfo>,
522+
filePath: string | undefined,
523+
) {
524+
for (const { ast, query } of asts) {
525+
if (!ast) {
526+
continue;
527+
}
528+
for (const definition of ast.definitions) {
529+
if (isTypeDefinitionNode(definition)) {
530+
typeCache.set(definition.name.value, {
531+
filePath,
532+
content: query,
533+
definition,
534+
});
510535
}
511536
}
512537
}
538+
return typeCache;
513539
}
514540

515541
_extendSchema(

packages/graphql-language-service-server/src/MessageProcessor.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -926,12 +926,18 @@ export class MessageProcessor {
926926
return Array.from(this._textDocumentCache);
927927
}
928928

929-
private async _cacheSchemaText(uri: string, text: string, version: number) {
929+
private async _cacheSchemaText(
930+
uri: string,
931+
text: string,
932+
version: number,
933+
project?: GraphQLProjectConfig,
934+
) {
930935
try {
931936
const contents = this._parser(text, uri);
937+
// console.log(uri, contents);
932938
if (contents.length > 0) {
933939
await this._invalidateCache({ version, uri }, uri, contents);
934-
await this._updateObjectTypeDefinition(uri, contents);
940+
await this._updateObjectTypeDefinition(uri, contents, project);
935941
}
936942
} catch (err) {
937943
this._logger.error(String(err));
@@ -1058,10 +1064,10 @@ export class MessageProcessor {
10581064
schemaText = `# This is an automatically generated representation of your schema.\n# Any changes to this file will be overwritten and will not be\n# reflected in the resulting GraphQL schema\n\n${schemaText}`;
10591065

10601066
const cachedSchemaDoc = this._getCachedDocument(uri);
1061-
1067+
this._graphQLCache._schemaMap.set(project.name, schema);
10621068
if (!cachedSchemaDoc) {
10631069
await writeFile(fsPath, schemaText, 'utf8');
1064-
await this._cacheSchemaText(uri, schemaText, 1);
1070+
await this._cacheSchemaText(uri, schemaText, 0, project);
10651071
}
10661072
// do we have a change in the getSchema result? if so, update schema cache
10671073
if (cachedSchemaDoc) {
@@ -1070,6 +1076,7 @@ export class MessageProcessor {
10701076
uri,
10711077
schemaText,
10721078
cachedSchemaDoc.version++,
1079+
project,
10731080
);
10741081
}
10751082
}
@@ -1206,11 +1213,12 @@ export class MessageProcessor {
12061213
private async _updateObjectTypeDefinition(
12071214
uri: Uri,
12081215
contents: CachedContent[],
1216+
project?: GraphQLProjectConfig,
12091217
): Promise<void> {
1210-
const project = await this._graphQLCache.getProjectForFile(uri);
1211-
if (project) {
1212-
const cacheKey = this._graphQLCache._cacheKeyForProject(project);
1213-
1218+
const resolvedProject =
1219+
project ?? (await this._graphQLCache.getProjectForFile(uri));
1220+
if (resolvedProject) {
1221+
const cacheKey = this._graphQLCache._cacheKeyForProject(resolvedProject);
12141222
await this._graphQLCache.updateObjectTypeDefinition(
12151223
cacheKey,
12161224
uri,

packages/graphql-language-service-server/src/__tests__/MessageProcessor.spec.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { FileChangeType } from 'vscode-languageserver';
66
import { serializeRange } from './__utils__/utils';
77
import { readFile } from 'node:fs/promises';
88
import { existsSync } from 'node:fs';
9+
import { URI } from 'vscode-uri';
910

1011
const defaultFiles = [
1112
['query.graphql', 'query { bar ...B }'],
@@ -133,8 +134,8 @@ describe('project with simple config and graphql files', () => {
133134
character: 0,
134135
},
135136
end: {
136-
line: 0,
137-
character: 25,
137+
line: 2,
138+
character: 1,
138139
},
139140
});
140141
// change the file to make the fragment invalid
@@ -268,5 +269,45 @@ describe('project with simple config and graphql files', () => {
268269
character: 1,
269270
},
270271
});
272+
273+
// TODO: super weird, the type definition cache isn't built until _after_ the first definitions request (for that file?)...
274+
// this may be a bug just on init, or perhaps every definitions request is outdated???
275+
// local schema file should be used for definitions
276+
277+
const typeDefinitions = await project.lsp.handleDefinitionRequest({
278+
textDocument: { uri: project.uri('fragments.graphql') },
279+
position: { character: 15, line: 0 },
280+
});
281+
282+
// TODO: these should return a type definition from the schema
283+
//
284+
expect(typeDefinitions[0].uri).toEqual(URI.parse(genSchemaPath).toString());
285+
286+
expect(serializeRange(typeDefinitions[0].range)).toEqual({
287+
start: {
288+
line: 10,
289+
character: 0,
290+
},
291+
end: {
292+
line: 98,
293+
character: 1,
294+
},
295+
});
296+
297+
const schemaDefs = await project.lsp.handleDefinitionRequest({
298+
textDocument: { uri: URI.parse(genSchemaPath).toString() },
299+
position: { character: 20, line: 17 },
300+
});
301+
expect(schemaDefs[0].uri).toEqual(URI.parse(genSchemaPath).toString());
302+
expect(serializeRange(schemaDefs[0].range)).toEqual({
303+
start: {
304+
line: 100,
305+
character: 0,
306+
},
307+
end: {
308+
line: 108,
309+
character: 1,
310+
},
311+
});
271312
});
272313
});

0 commit comments

Comments
 (0)