Skip to content

Commit 62493b8

Browse files
committed
feat: add first method definitions
1 parent e928c5a commit 62493b8

File tree

10 files changed

+195
-42
lines changed

10 files changed

+195
-42
lines changed

src/providers/AppsyncSignatureHelpProvider.ts

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,55 @@
1-
import { SignatureHelpProvider, TextDocument, Position, CancellationToken, SignatureHelp, MarkdownString } from "vscode";
1+
import { SignatureHelpProvider, TextDocument, Position, CancellationToken, SignatureHelp, MarkdownString, SignatureInformation, CompletionItemKind } from "vscode";
2+
3+
import allTypes from "./allTypes";
24

35
export class AppsyncSignatureHelpProvider implements SignatureHelpProvider {
6+
_methodReference: Record<string, Array<SignatureInformation>> = {};
7+
constructor() {
8+
allTypes.forEach((itemSettings) => {
9+
itemSettings.prefixes.forEach(prefix => {
10+
itemSettings.properties.filter(prop => prop.kind === CompletionItemKind.Method)
11+
.forEach(prop => {
12+
prop.names.forEach(name => {
13+
this._methodReference[`${prefix}${name}`] = prop.signatures?.map(sig => {
14+
sig.documentation = sig.documentation ?? prop.documentation;
15+
sig.label = sig.label ?? `${name}()`;
16+
return sig;
17+
}) ?? [
18+
{
19+
label: `${name}()`,
20+
documentation: new MarkdownString(prop.documentation),
21+
parameters: []
22+
}
23+
];
24+
});
25+
});
26+
});
27+
});
28+
}
29+
430
public async provideSignatureHelp(
531
document: TextDocument, position: Position, token: CancellationToken):
632
Promise<SignatureHelp | undefined> {
733

834
let linePrefix = document.lineAt(position).text.substr(0, position.character);
35+
let methodName = linePrefix.substring(0, linePrefix.lastIndexOf("("));
36+
let commaCount = linePrefix.substring(methodName.length).split(",").length - 1;
937

1038
if (token.isCancellationRequested || linePrefix.endsWith(")")) { return undefined; }
1139

40+
41+
const methodRef = Object.entries(this._methodReference).find(([key]) => methodName.endsWith(key))?.[1];
42+
43+
if (!methodRef) {
44+
return undefined;
45+
}
46+
1247
const result = new SignatureHelp();
1348

14-
result.signatures = [
15-
{
16-
label: "someMethod(firstParam)",
17-
documentation: linePrefix,
18-
parameters: [
19-
{
20-
label: "firstParam",
21-
documentation: new MarkdownString("Something")
22-
}
23-
]
24-
}
25-
];
26-
27-
result.activeSignature = 0;
28-
result.activeParameter = 0;
49+
result.signatures = methodRef;
50+
51+
result.activeSignature = Math.max(0, methodRef.findIndex(value => value.parameters.length > commaCount));
52+
result.activeParameter = commaCount;
2953

3054
return result;
3155
}

src/providers/allTypes.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
import context from "./context";
3+
import util from "./util";
4+
5+
export default [
6+
...context,
7+
...util
8+
];

src/providers/context/arguments.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { AutocompleteData } from "../dataTypes";
2+
import map from "../standard/map";
3+
4+
export default [{
5+
prefixes: ['$ctx.args.', '$context.args.', '$ctx.arguments.', '$context.arguments.'],
6+
properties: [
7+
...map
8+
]
9+
}] as Array<AutocompleteData.CompletionItemSettings>;

src/providers/context/index.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,26 @@
22
import { AutocompleteData } from '../dataTypes';
33
import identity from "./identity";
44
import info from "./info";
5+
import args from './arguments';
6+
import source from './source';
7+
import stash from './stash';
58

6-
export default [{
7-
prefixes: ['$ctx.', '$context.'],
8-
properties: [
9-
{ names: ["arguments"], documentation: "A map that contains all GraphQL arguments for this field." },
10-
{ names: ["identity"], documentation: "An object that contains information about the caller." },
11-
{ names: ["source"], documentation: "A map that contains the resolution of the parent field." },
12-
{ names: ["stash"], documentation: "The stash is a map that is made available inside each resolver and function mapping template. The same stash instance lives through a single resolver execution. This means that you can use the stash to pass arbitrary data across request and response mapping templates, and across functions in a pipeline resolver. The stash exposes the same methods as the Java Map data structure." },
13-
{ names: ["result"], documentation: "A container for the results of this resolver. This field is only available to response mapping templates." },
14-
{ names: ["prev.result"], documentation: "It represents the result of whatever previous operation was executed in a pipeline resolver. If the previous operation was the pipeline resolver request mapping template, then `$ctx.prev.result` represents the output of the evaluation of the template, and is made available to the first function in the pipeline. If the previous operation was the first function, then `$ctx.prev.result` represents the output of the first function, and is made available to the second function in the pipeline. If the previous operation was the last function, then `$ctx.prev.result` represents the output of the first function, and is made available to the pipeline resolver response mapping template." },
15-
{ names: ["info"], documentation: "An object that contains information about the GraphQL request." }
16-
]
17-
},
18-
...identity,
19-
...info
9+
export default [
10+
{
11+
prefixes: ['$ctx.', '$context.'],
12+
properties: [
13+
{ names: ["arguments", "args"], documentation: "A map that contains all GraphQL arguments for this field." },
14+
{ names: ["identity"], documentation: "An object that contains information about the caller." },
15+
{ names: ["source"], documentation: "A map that contains the resolution of the parent field." },
16+
{ names: ["stash"], documentation: "The stash is a map that is made available inside each resolver and function mapping template. The same stash instance lives through a single resolver execution. This means that you can use the stash to pass arbitrary data across request and response mapping templates, and across functions in a pipeline resolver. The stash exposes the same methods as the Java Map data structure." },
17+
{ names: ["result"], documentation: "A container for the results of this resolver. This field is only available to response mapping templates." },
18+
{ names: ["prev.result"], documentation: "It represents the result of whatever previous operation was executed in a pipeline resolver. If the previous operation was the pipeline resolver request mapping template, then `$ctx.prev.result` represents the output of the evaluation of the template, and is made available to the first function in the pipeline. If the previous operation was the first function, then `$ctx.prev.result` represents the output of the first function, and is made available to the second function in the pipeline. If the previous operation was the last function, then `$ctx.prev.result` represents the output of the first function, and is made available to the pipeline resolver response mapping template." },
19+
{ names: ["info"], documentation: "An object that contains information about the GraphQL request." }
20+
]
21+
},
22+
...identity,
23+
...info,
24+
...args,
25+
...source,
26+
...stash,
2027
] as Array<AutocompleteData.CompletionItemSettings>;

src/providers/context/source.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { AutocompleteData } from "../dataTypes";
2+
import map from "../standard/map";
3+
4+
export default [{
5+
prefixes: ['$ctx.source.', '$context.source.'],
6+
properties: [
7+
...map
8+
]
9+
}] as Array<AutocompleteData.CompletionItemSettings>;

src/providers/context/stash.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { AutocompleteData } from "../dataTypes";
2+
import map from "../standard/map";
3+
4+
export default [{
5+
prefixes: ['$ctx.stash.', '$context.stash.'],
6+
properties: [
7+
...map
8+
]
9+
}] as Array<AutocompleteData.CompletionItemSettings>;

src/providers/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as vscode from "vscode";
2-
import context from "./context";
3-
import util from "./util";
2+
import allTypes from "./allTypes";
43
import { AutocompleteData } from "./dataTypes";
54
import { AppsyncSignatureHelpProvider } from "./AppsyncSignatureHelpProvider";
65

@@ -66,6 +65,5 @@ export default (ctx: vscode.ExtensionContext) => {
6665
'$' // triggered whenever a '$' is being typed
6766
);
6867

69-
context.forEach(register);
70-
util.forEach(register);
68+
allTypes.forEach(register);
7169
};

src/providers/map.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/providers/standard/map.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { AutocompleteData } from '../dataTypes';
2+
import { CompletionItemKind } from 'vscode';
3+
4+
/**
5+
* Methods defined by the Java [Map](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html) class
6+
*/
7+
export default [
8+
{
9+
names: ["clear"], kind: CompletionItemKind.Method, documentation: "Removes all of the mappings from this map (optional operation)."
10+
},
11+
{
12+
names: ["containsKey"], kind: CompletionItemKind.Method, documentation: "Returns true if this map contains a mapping for the specified key.",
13+
signatures: [
14+
{
15+
label: 'boolean containsKey(Object key)',
16+
parameters: [
17+
{ label: 'key', documentation: 'key whose presence in this map is to be tested' }
18+
]
19+
}
20+
]
21+
},
22+
{ names: ["containsValue"], kind: CompletionItemKind.Method, documentation: "Returns true if this map maps one or more keys to the specified value." },
23+
{ names: ["entrySet"], kind: CompletionItemKind.Method, documentation: "Returns a Set view of the mappings contained in this map." },
24+
{ names: ["get"], kind: CompletionItemKind.Method, documentation: "Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key." },
25+
{ names: ["getOrDefault"], kind: CompletionItemKind.Method, documentation: "Returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key." },
26+
{ names: ["isEmpty"], kind: CompletionItemKind.Method, documentation: "Returns true if this map contains no key-value mappings." },
27+
{ names: ["keySet"], kind: CompletionItemKind.Method, documentation: "Returns a Set view of the keys contained in this map." },
28+
{ names: ["merge"], kind: CompletionItemKind.Method, documentation: "If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value." },
29+
{ names: ["put"], kind: CompletionItemKind.Method, documentation: "Associates the specified value with the specified key in this map (optional operation)." },
30+
{ names: ["putAll"], kind: CompletionItemKind.Method, documentation: "Copies all of the mappings from the specified map to this map (optional operation)." },
31+
{ names: ["putIfAbsent"], kind: CompletionItemKind.Method, documentation: "If the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value." },
32+
{ names: ["replace"], kind: CompletionItemKind.Method, documentation: "Replaces the entry for the specified key only if it is currently mapped to some value." },
33+
{ names: ["replaceAll"], kind: CompletionItemKind.Method, documentation: "Replaces each entry's value with the result of invoking the given function on that entry until all entries have been processed or the function throws an exception." },
34+
{ names: ["size"], kind: CompletionItemKind.Method, documentation: "Returns the number of key-value mappings in this map." },
35+
{ names: ["values"], kind: CompletionItemKind.Method, documentation: "Returns a Collection view of the values contained in this map." },
36+
] as Array<AutocompleteData.Item>;

src/providers/util/index.ts

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
import { AutocompleteData } from '../dataTypes';
3-
import { CompletionItemKind } from "vscode";
3+
import { CompletionItemKind, MarkdownString } from "vscode";
44
import time from "./time";
55
import list from "./list";
66
import map from "./map";
@@ -19,7 +19,66 @@ export default [{
1919
{ names: ["toJson"], kind: CompletionItemKind.Method, documentation: 'Takes an object and returns a “stringified” JSON representation of that object.' },
2020
{ names: ["autoId"], kind: CompletionItemKind.Method, documentation: 'Returns a 128-bit randomly generated UUID.' },
2121
{ names: ["unauthorized"], kind: CompletionItemKind.Method, documentation: 'Throws Unauthorized for the field being resolved. This can be used in request or response mapping templates to decide if the caller should be allowed to resolve the field.' },
22-
{ names: ["error"], kind: CompletionItemKind.Method, documentation: 'Throws a custom error. This can be used in request or response mapping templates if the template detects an error with the request or with the invocation result.' },
22+
{
23+
names: ["error"], kind: CompletionItemKind.Method, documentation: 'Throws a custom error. This can be used in request or response mapping templates if the template detects an error with the request or with the invocation result.',
24+
signatures: [
25+
{
26+
label: "error(String error)",
27+
documentation: "Throws a custom error. This can be used in request or response mapping templates if the template detects an error with the request or with the invocation result.",
28+
parameters: [
29+
{
30+
label: "String error"
31+
}
32+
]
33+
},
34+
{
35+
label: "error(String error, String errorType)",
36+
documentation: new MarkdownString("Throws a custom error. This can be used in request or response mapping templates if the template detects an error with the request or with the invocation result. Additionally, an `errorType` can be specified."),
37+
parameters: [
38+
{
39+
label: "String error"
40+
},
41+
{
42+
label: "String errorType"
43+
}
44+
]
45+
},
46+
{
47+
label: "error(String error, String errorType, Object data)",
48+
documentation: new MarkdownString("Throws a custom error. This can be used in request or response mapping templates if the template detects an error with the request or with the invocation result. Additionally, an `errorType` and a `data` field can be specified. The `data` value will be added to the corresponding error block inside `errors` in the GraphQL response. **Note**: `data` will be filtered based on the query selection set."),
49+
parameters: [
50+
{
51+
label: "String error"
52+
},
53+
{
54+
label: "String errorType"
55+
},
56+
{
57+
label: "Object data"
58+
}
59+
]
60+
},
61+
{
62+
label: "error(String error, String errorType, Object data, Object errorInfo)",
63+
documentation: new MarkdownString("Throws a custom error. This can be used in request or response mapping templates if the template detects an error with the request or with the invocation result. Additionally, an `errorType` field, a `data` field, and a `errorInfo` field can be specified. The data value will be added to the corresponding error block inside errors in the GraphQL response. **Note**: `data` will be filtered based on the query selection set. The `errorInfo` value will be added to the corresponding `error` block inside `errors` in the GraphQL response. **Note**: `errorInfo` will NOT be filtered based on the query selection set."),
64+
parameters: [
65+
{
66+
label: "String error"
67+
},
68+
{
69+
label: "String errorType"
70+
},
71+
{
72+
label: "Object data"
73+
},
74+
{
75+
label: "Object errorInfo"
76+
}
77+
]
78+
}
79+
]
80+
81+
},
2382
{ names: ["appendError"], kind: CompletionItemKind.Method, documentation: 'Appends a custom error. This can be used in request or response mapping templates if the template detects an error with the request or with the invocation result. Unlike `$util.error(String)`, the template evaluation will not be interrupted, so that data can be returned to the caller.' },
2483
{ names: ["validate"], kind: CompletionItemKind.Method, documentation: 'If the condition is false, throw a CustomTemplateException with the specified message.' },
2584
{ names: ["isNull"], kind: CompletionItemKind.Method, documentation: 'Returns true if the supplied object is null.' },

0 commit comments

Comments
 (0)