-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support queries for multiple schemas in the same file #3411
base: main
Are you sure you want to change the base?
Changes from 2 commits
ecd29f8
b20c7ed
ffca1f7
bbc8a6e
196d830
5dcd471
5148707
63e82ba
12acf3e
935ae8a
6b9582c
b956407
d09f46d
80a3541
92f2c7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,10 @@ | |
SymbolKind, | ||
} from 'vscode-languageserver-types'; | ||
|
||
import { fileURLToPath } from 'node:url'; | ||
|
||
export const EXTENSION_NAME = 'languageService'; | ||
|
||
const KIND_TO_SYMBOL_KIND: { [key: string]: SymbolKind } = { | ||
[Kind.FIELD]: SymbolKind.Field, | ||
[Kind.OPERATION_DEFINITION]: SymbolKind.Class, | ||
|
@@ -96,11 +100,38 @@ | |
this._logger = logger; | ||
} | ||
|
||
getConfigForURI(uri: Uri) { | ||
const config = this._graphQLCache.getProjectForFile(uri); | ||
if (config) { | ||
return config; | ||
getAllProjectsForFile(uri: Uri) { | ||
const filePath = uri.startsWith('file:') ? fileURLToPath(uri) : uri; | ||
const projects = Object.values(this._graphQLConfig.projects).filter( | ||
project => project.match(filePath), | ||
); | ||
|
||
return projects.length > 0 | ||
? projects | ||
: // Fallback, this always finds at least 1 project | ||
[this._graphQLConfig.getProjectForFile(filePath)]; | ||
} | ||
|
||
getProjectForQuery( | ||
query: string, | ||
uri: Uri, | ||
projects?: GraphQLProjectConfig[], | ||
) { | ||
if (!query.startsWith('#graphql')) { | ||
// Query is not annotated with #graphql. | ||
// Skip suffix check and return the first project that matches the file. | ||
return projects?.[0] ?? this._graphQLConfig.getProjectForFile(uri); | ||
} | ||
frandiox marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return (projects || this.getAllProjectsForFile(uri)).find(project => { | ||
const ext = project.hasExtension(EXTENSION_NAME) | ||
? project.extension(EXTENSION_NAME) | ||
: null; | ||
|
||
const suffix = ext?.gqlTagOptions?.annotationSuffix; | ||
|
||
return query.startsWith(`#graphql${suffix ? ':' + suffix : ''}\n`); | ||
}); | ||
} | ||
|
||
public async getDiagnostics( | ||
|
@@ -111,7 +142,7 @@ | |
// Perform syntax diagnostics first, as this doesn't require | ||
// schema/fragment definitions, even the project configuration. | ||
let documentHasExtensions = false; | ||
const projectConfig = this.getConfigForURI(uri); | ||
const projectConfig = this.getProjectForQuery(document, uri); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you rename this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated! I've also resolved the new conflicts but fyi, there's a problem with |
||
// skip validation when there's nothing to validate, prevents noisy unexpected EOF errors | ||
if (!projectConfig || !document || document.trim().length < 2) { | ||
return []; | ||
|
@@ -218,7 +249,7 @@ | |
position: IPosition, | ||
filePath: Uri, | ||
): Promise<Array<CompletionItem>> { | ||
const projectConfig = this.getConfigForURI(filePath); | ||
const projectConfig = this.getProjectForQuery(query, filePath); | ||
if (!projectConfig) { | ||
return []; | ||
} | ||
|
@@ -255,7 +286,7 @@ | |
filePath: Uri, | ||
options?: HoverConfig, | ||
): Promise<Hover['contents']> { | ||
const projectConfig = this.getConfigForURI(filePath); | ||
const projectConfig = this.getProjectForQuery(query, filePath); | ||
if (!projectConfig) { | ||
return ''; | ||
} | ||
|
@@ -272,7 +303,7 @@ | |
position: IPosition, | ||
filePath: Uri, | ||
): Promise<DefinitionQueryResult | null> { | ||
const projectConfig = this.getConfigForURI(filePath); | ||
const projectConfig = this.getProjectForQuery(query, filePath); | ||
if (!projectConfig) { | ||
return null; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing an Uri that starts with the
file://
protocol doesn't work properly ingrahiQLConfig.getProjectForFile
. Internally that callsminimatch
and it always returns false.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes there was a breaking change in vscode some years ago, and there are a few places that we didn't handle this, thanks for the bugfix! I will come back around look at the implementations because they should all be passing a file url