Skip to content
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

Adding Language Support for Go #391

Merged
merged 15 commits into from
Dec 17, 2021
1 change: 1 addition & 0 deletions src/languages/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const supportedLanguageIds = [
"clojure",
"cpp",
"csharp",
"go",
"html",
"java",
"javascript",
Expand Down
2 changes: 2 additions & 0 deletions src/languages/getNodeMatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { patternMatchers as typescript } from "./typescript";
import java from "./java";
import { patternMatchers as html } from "./html";
import python from "./python";
import go from "./go";
import { UnsupportedLanguageError } from "../errors";
import { SupportedLanguageId } from "./constants";

Expand Down Expand Up @@ -50,6 +51,7 @@ const languageMatchers: Record<
cpp,
csharp,
clojure,
go,
html,
java,
javascript: typescript,
Expand Down
6 changes: 2 additions & 4 deletions src/languages/getTextFragmentExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import { stringTextFragmentExtractor as htmlStringTextFragmentExtractor } from "
import { UnsupportedLanguageError } from "../errors";
import { Range } from "vscode";
import { SupportedLanguageId } from "./constants";
import {
getNodeInternalRange,
getNodeRange,
} from "../util/nodeSelectors";
import { getNodeInternalRange, getNodeRange } from "../util/nodeSelectors";
import { getNodeMatcher } from "./getNodeMatcher";
import { notSupported } from "../util/nodeMatchers";

Expand Down Expand Up @@ -126,6 +123,7 @@ const textFragmentExtractors: Record<
),
cpp: constructDefaultTextFragmentExtractor("cpp"),
csharp: constructDefaultTextFragmentExtractor("csharp"),
go: constructDefaultTextFragmentExtractor("go"),
html: constructDefaultTextFragmentExtractor(
"html",
htmlStringTextFragmentExtractor
Expand Down
80 changes: 80 additions & 0 deletions src/languages/go.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
createPatternMatchers,
argumentMatcher,
leadingMatcher,
conditionMatcher,
trailingMatcher,
childAtIndexMatcher,
cascadingMatcher,
patternMatcher,
} from "../util/nodeMatchers";
import {
NodeMatcherAlternative,
ScopeType,
SelectionWithEditor,
} from "../typings/Types";
import { getNodeRange } from "../util/nodeSelectors";
import { SyntaxNode } from "web-tree-sitter";

// Generated by the following command:
// `curl https://raw.githubusercontent.com/tree-sitter/tree-sitter-go/master/src/node-types.json | jq '[.[] | select(.type == "_statement" or .type == "_simple_statement") | .subtypes[].type]'`
const STATEMENT_TYPES = [
"_expression",
"assignment_statement",
"dec_statement",
"inc_statement",
"send_statement",
"short_var_declaration",
"_simple_statement",
"break_statement",
"const_declaration",
"continue_statement",
"defer_statement",
"empty_statement",
"expression_switch_statement",
"fallthrough_statement",
"for_statement",
"go_statement",
"goto_statement",
"if_statement",
"labeled_statement",
"return_statement",
"select_statement",
"type_declaration",
"type_switch_statement",
"var_declaration"
];

const nodeMatchers: Partial<Record<ScopeType, NodeMatcherAlternative>> = {
map: "composite_literal",
list: ["composite_literal", "slice_type", "array_type"],
statement: STATEMENT_TYPES,
string: ["interpreted_string_literal", "raw_string_literal"],
ifStatement: "if_statement",
functionCall: "call_expression",
comment: "comment",
namedFunction: ["function_declaration", "method_declaration"],
type: [
"pointer_type",
"qualified_type",
"type_identifier",
"function_declaration[result]",
"method_declaration[result]",
],
functionName: ["function_declaration[name]", "method_declaration[name]"],
anonymousFunction: "func_literal",
condition: conditionMatcher("*[condition]"),
argumentOrParameter: cascadingMatcher(
argumentMatcher("argument_list", "parameter_list"),
patternMatcher("parameter_declaration"),
patternMatcher("argument_declaration")
),
collectionItem: ["keyed_element", "element"],
collectionKey: childAtIndexMatcher(["keyed_element"], 0),
value: cascadingMatcher(
childAtIndexMatcher(["keyed_element"], 1),
patternMatcher("return_statement.expression_list!")
)
};

export default createPatternMatchers(nodeMatchers);
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/chuckArg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 0
spokenForm: chuck arg
action: remove
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: "func add(x, y int) int {\n\t return add(x, add(1, 2))\n}"
selections:
- anchor: {line: 1, character: 13}
active: {line: 1, character: 13}
marks: {}
finalState:
documentContents: "func add(x, y int) int {\n\t return add(add(1, 2))\n}"
selections:
- anchor: {line: 1, character: 13}
active: {line: 1, character: 13}
thatMark:
- anchor: {line: 1, character: 13}
active: {line: 1, character: 13}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: outside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/chuckArg2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 0
spokenForm: chuck arg
action: remove
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: "func add(x, y int) int {\n\t return add(add(1, 2))\n}"
selections:
- anchor: {line: 1, character: 13}
active: {line: 1, character: 13}
marks: {}
finalState:
documentContents: "func add(x, y int) int {\n\t return add()\n}"
selections:
- anchor: {line: 1, character: 13}
active: {line: 1, character: 13}
thatMark:
- anchor: {line: 1, character: 13}
active: {line: 1, character: 13}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: outside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/chuckValue.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 0
spokenForm: chuck value
action: remove
targets:
- type: primitive
modifier: {type: containingScope, scopeType: value, includeSiblings: false}
initialState:
documentContents: " return true"
selections:
- anchor: {line: 0, character: 5}
active: {line: 0, character: 5}
marks: {}
finalState:
documentContents: " return"
selections:
- anchor: {line: 0, character: 5}
active: {line: 0, character: 5}
thatMark:
- anchor: {line: 0, character: 7}
active: {line: 0, character: 7}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: outside, modifier: {type: containingScope, scopeType: value, includeSiblings: false}, isImplicit: false}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 1
spokenForm: clear condition
action: clearAndSetSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: condition, includeSiblings: false}
initialState:
documentContents: "if true {\n\treturn true\n}"
selections:
- anchor: {line: 1, character: 1}
active: {line: 1, character: 1}
marks: {}
finalState:
documentContents: "if {\n\treturn true\n}"
selections:
- anchor: {line: 0, character: 3}
active: {line: 0, character: 3}
thatMark:
- anchor: {line: 0, character: 3}
active: {line: 0, character: 3}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: condition, includeSiblings: false}, isImplicit: false}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/clearIfState.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 0
spokenForm: clear if state
action: clearAndSetSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: ifStatement, includeSiblings: false}
initialState:
documentContents: "if true {\n\treturn true\n}"
selections:
- anchor: {line: 1, character: 12}
active: {line: 1, character: 12}
marks: {}
finalState:
documentContents: ""
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
thatMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: ifStatement, includeSiblings: false}}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/clearPair.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 1
spokenForm: clear pair
action: clearAndSetSelection
targets:
- type: primitive
modifier: {type: surroundingPair, delimiter: any}
initialState:
documentContents: "\"(hello)\""
selections:
- anchor: {line: 0, character: 6}
active: {line: 0, character: 6}
marks: {}
finalState:
documentContents: "\"\""
selections:
- anchor: {line: 0, character: 1}
active: {line: 0, character: 1}
thatMark:
- anchor: {line: 0, character: 1}
active: {line: 0, character: 1}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: surroundingPair, delimiter: any}, isImplicit: false}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/clearState.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 0
spokenForm: clear state
action: clearAndSetSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: statement, includeSiblings: false}
initialState:
documentContents: "if true {\n\t\n}"
pokey marked this conversation as resolved.
Show resolved Hide resolved
selections:
- anchor: {line: 1, character: 1}
active: {line: 1, character: 1}
marks: {}
finalState:
documentContents: ""
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
thatMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: statement, includeSiblings: false}}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/takeArg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another minor one for the future; not worth rewriting your tests, but we generally try to use "clear" for modifier tests so that the test case is easier to read; don't have to count character indices 😅. Not a big deal because in the future we'll have a better format for modifier tests that doesn't depend on which action you run

command:
version: 0
spokenForm: take arg
action: setSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: "func add(x int, y int) int {\n\treturn x + y\n}"
selections:
- anchor: {line: 0, character: 11}
active: {line: 0, character: 11}
marks: {}
finalState:
documentContents: "func add(x int, y int) int {\n\treturn x + y\n}"
selections:
- anchor: {line: 0, character: 9}
active: {line: 0, character: 14}
thatMark:
- anchor: {line: 0, character: 9}
active: {line: 0, character: 14}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/takeArg2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 0
spokenForm: take arg
action: setSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: "func add(x int, y int) int {\n\treturn x + y\n}"
selections:
- anchor: {line: 0, character: 19}
active: {line: 0, character: 19}
marks: {}
finalState:
documentContents: "func add(x int, y int) int {\n\treturn x + y\n}"
selections:
- anchor: {line: 0, character: 16}
active: {line: 0, character: 21}
thatMark:
- anchor: {line: 0, character: 16}
active: {line: 0, character: 21}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/takeArg3.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 0
spokenForm: take arg
action: setSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}
initialState:
documentContents: "func add(x int, y int) int {\n\treturn add(x, y)\n}"
selections:
- anchor: {line: 1, character: 13}
active: {line: 1, character: 13}
marks: {}
finalState:
documentContents: "func add(x int, y int) int {\n\treturn add(x, y)\n}"
selections:
- anchor: {line: 1, character: 12}
active: {line: 1, character: 13}
thatMark:
- anchor: {line: 1, character: 12}
active: {line: 1, character: 13}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: argumentOrParameter, includeSiblings: false}}]
23 changes: 23 additions & 0 deletions src/test/suite/fixtures/recorded/languages/go/takeCall.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
languageId: go
command:
version: 0
spokenForm: take call
action: setSelection
targets:
- type: primitive
modifier: {type: containingScope, scopeType: functionCall, includeSiblings: false}
initialState:
documentContents: add(1, 2)
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
marks: {}
finalState:
documentContents: add(1, 2)
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 9}
thatMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 9}
fullTargets: [{type: primitive, mark: {type: cursor}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: containingScope, scopeType: functionCall, includeSiblings: false}}]
Loading