Skip to content
This repository has been archived by the owner on Sep 2, 2020. It is now read-only.

Commit

Permalink
add directive autocompletion support for schema IDL (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
asiandrummer committed Mar 16, 2017
1 parent 432deee commit 6a4c783
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ schema {
}

directive @test(testArg: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
directive @onArg on ARGUMENT_DEFINITION
directive @onAllDefs on SCHEMA
| SCALAR
| OBJECT
| FIELD_DEFINITION
| INTERFACE
| UNION
| ENUM_VALUE
| INPUT_OBJECT
| ARGUMENT_DEFINITION
| INPUT_FIELD_DEFINITION

enum Episode {
NEWHOPE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,21 @@ describe('getAutocompleteSuggestions', () => {
{label: 'secretBackstory', detail: 'String'},
]);
});

it('provides correct directive suggestions on definitions', () =>
expect(testSuggestions(
'type Type @', new Position(0, 11),
)).to.deep.equal([
{label: 'onAllDefs'},
]),
);

it('provides correct directive suggestions on args definitions', () =>
expect(testSuggestions(
'type Type { field(arg: String @', new Position(0, 31),
)).to.deep.equal([
{label: 'onAllDefs'},
{label: 'onArg'},
]),
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ export function getAutocompleteSuggestions(
schema: GraphQLSchema,
queryText: string,
cursor: Position,
contextToken?: ContextToken,
): Array<CompletionItem> {
const token = getTokenAtPosition(queryText, cursor);
const token = contextToken || getTokenAtPosition(queryText, cursor);

const state = token.state.kind === 'Invalid' ?
token.state.prevState :
Expand Down Expand Up @@ -334,9 +335,8 @@ function getSuggestionsForDirective(
schema: GraphQLSchema,
): Array<CompletionItem> {
if (state.prevState && state.prevState.kind) {
const stateKind = state.prevState.kind;
const directives = schema.getDirectives().filter(
directive => canUseDirective(stateKind, directive),
directive => canUseDirective(state.prevState, directive),
);
return hintList(token, directives.map(directive => ({
label: directive.name,
Expand Down Expand Up @@ -422,7 +422,14 @@ function runOnlineParser(
};
}

function canUseDirective(kind: string, directive: GraphQLDirective): boolean {
function canUseDirective(
state: $PropertyType<State, 'prevState'>,
directive: GraphQLDirective,
): boolean {
if (!state || !state.kind) {
return false;
}
const kind = state.kind;
const locations = directive.locations;
switch (kind) {
case 'Query':
Expand All @@ -440,6 +447,34 @@ function canUseDirective(kind: string, directive: GraphQLDirective): boolean {
return locations.indexOf('FRAGMENT_SPREAD') !== -1;
case 'InlineFragment':
return locations.indexOf('INLINE_FRAGMENT') !== -1;
// Schema Definitions
case 'SchemaDef':
return locations.indexOf('SCHEMA') !== -1;
case 'ScalarDef':
return locations.indexOf('SCALAR') !== -1;
case 'ObjectTypeDef':
return locations.indexOf('OBJECT') !== -1;
case 'FieldDef':
return locations.indexOf('FIELD_DEFINITION') !== -1;
case 'InterfaceDef':
return locations.indexOf('INTERFACE') !== -1;
case 'UnionDef':
return locations.indexOf('UNION') !== -1;
case 'EnumDef':
return locations.indexOf('ENUM') !== -1;
case 'EnumValue':
return locations.indexOf('ENUM_VALUE') !== -1;
case 'InputDef':
return locations.indexOf('INPUT_OBJECT') !== -1;
case 'InputValueDef':
const prevStateKind = state.prevState && state.prevState.kind;
switch (prevStateKind) {
case 'ArgumentsDef':
return locations.indexOf('ARGUMENT_DEFINITION') !== -1;
case 'InputDef':
return locations.indexOf('INPUT_FIELD_DEFINITION') !== -1;
}
}
return false;
}
Expand Down

0 comments on commit 6a4c783

Please sign in to comment.