Skip to content

Commit 02154d1

Browse files
authored
[IJ Plugin] Add support for the Apollo LSP via Rover (#6274)
* Add support for the Apollo LSP via Rover * Check the Rover version * Add "Beta" indicator to Rover panel * Update doc * Fix bundle * Improve Readme wording
1 parent 21c1371 commit 02154d1

34 files changed

+1923
-42
lines changed

.idea/runConfigurations/Run_IntelliJ_plugin.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gradle/libraries.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,4 @@ kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref
201201
android-application = { id = "com.android.application", version.ref = "android-plugin" }
202202
android-application-max = { id = "com.android.application", version.ref = "android-plugin-max" }
203203
android-library = { id = "com.android.library", version.ref = "android-plugin" }
204+
grammarkit = { id = "org.jetbrains.grammarkit", version = "2022.3.2.2" }

gradle/repositories.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ listOf(pluginManagement.repositories, dependencyResolutionManagement.repositorie
3333

3434
// For org.jetbrains.intellij.platform
3535
includeModule("org.jetbrains.intellij.platform", "intellij-platform-gradle-plugin")
36+
37+
// For org.jetbrains.grammarkit
38+
includeModule("org.jetbrains.grammarkit", "org.jetbrains.grammarkit.gradle.plugin")
39+
includeModule("org.jetbrains.intellij.plugins", "gradle-grammarkit-plugin")
3640
}
3741
}
3842
}

intellij-plugin/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ This plugin for Android Studio and IntelliJ helps you work with the
1818
- Apollo Android 2.x → Apollo Kotlin 3.x
1919
- Apollo Kotlin 3.x → Apollo Kotlin 4.x
2020
- `compat` codegen → `operationBased` codegen
21+
- Integration with [Rover](https://www.apollographql.com/docs/rover) for a rich schema editing experience
2122
- More to come!
2223

2324
## Compatibility

intellij-plugin/build.gradle.kts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ plugins {
1919
id("org.jetbrains.kotlin.jvm")
2020
id("org.jetbrains.intellij.platform")
2121
alias(libs.plugins.apollo.published)
22+
alias(libs.plugins.grammarkit)
2223
}
2324

2425
commonSetup()
@@ -91,6 +92,12 @@ tasks {
9192
}
9293
inputs.files(apolloDependencies)
9394
}
95+
96+
generateLexer {
97+
purgeOldFiles.set(true)
98+
sourceFile.set(file("src/main/grammars/ApolloGraphQLLexer.flex"))
99+
targetOutputDir.set(file("src/main/java/com/apollographql/ijplugin/psi"))
100+
}
94101
}
95102

96103
val mockJdkRoot = layout.buildDirectory.asFile.get().resolve("mockJDK")

intellij-plugin/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pluginSinceBuild=242
1313
# Upper bound: it's mandatory set it, and the plugin must be tested with this version
1414
pluginUntilBuild=243.*
1515
# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
16-
platformType=IC
16+
platformType=IU
1717
# Corresponds to AS Ladybug 2024.2.1 -> https://plugins.jetbrains.com/docs/intellij/android-studio-releases-list.html
1818
# and https://developer.android.com/studio/archive (more up to date)
1919
# See also https://plugins.jetbrains.com/docs/intellij/android-studio.html
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*
2+
* Copyright (c) 2016-2024 Apollo Graph, Inc. (Formerly Meteor Development Group, Inc.)
3+
* Copyright (c) 2015-present, Jim Kynde Meyer
4+
* All rights reserved.
5+
*
6+
* This source code is licensed under the MIT license found in the
7+
* LICENSE file in the root directory of this source tree.
8+
*/
9+
package com.apollographql.ijplugin.psi;
10+
11+
import java.util.Stack;
12+
13+
import com.intellij.lexer.FlexLexer;
14+
import com.intellij.psi.tree.IElementType;
15+
16+
import static com.intellij.psi.TokenType.BAD_CHARACTER;
17+
import static com.intellij.psi.TokenType.WHITE_SPACE;
18+
import static com.apollographql.ijplugin.psi.ApolloGraphQLElementTypes.*;
19+
20+
%%
21+
22+
%{
23+
24+
private static final class State {
25+
final int lBraceCount;
26+
final int state;
27+
28+
public State(int state, int lBraceCount) {
29+
this.state = state;
30+
this.lBraceCount = lBraceCount;
31+
}
32+
33+
@Override
34+
public String toString() {
35+
return "yystate = " + state + (lBraceCount == 0 ? "" : "lBraceCount = " + lBraceCount);
36+
}
37+
}
38+
39+
protected final Stack<State> myStateStack = new Stack<State>();
40+
protected int myLeftBraceCount;
41+
42+
private void pushState(int state) {
43+
myStateStack.push(new State(yystate(), myLeftBraceCount));
44+
myLeftBraceCount = 0;
45+
yybegin(state);
46+
}
47+
48+
private void popState() {
49+
State state = myStateStack.pop();
50+
myLeftBraceCount = state.lBraceCount;
51+
yybegin(state.state);
52+
}
53+
54+
public ApolloGraphQLLexer() {
55+
this((java.io.Reader)null);
56+
}
57+
%}
58+
59+
%public
60+
%class ApolloGraphQLLexer
61+
%implements FlexLexer
62+
%function advance
63+
%type IElementType
64+
%unicode
65+
66+
UNICODE_BOM = \uFEFF
67+
WHITESPACE_CHAR = [ \t]
68+
LINE_TERMINATOR = \n | (\r\n?)
69+
WHITESPACE = ({WHITESPACE_CHAR} | {LINE_TERMINATOR})+
70+
EOL_COMMENT = "#" .*
71+
NAME = [_A-Za-z][_0-9A-Za-z]*
72+
VARIABLE = \${NAME}
73+
74+
QUOTED_STRING_ESCAPE= \\[^\r\n]
75+
QUOTED_STRING_BODY = ([^\\\"\r\n] | {QUOTED_STRING_ESCAPE})+
76+
77+
THREE_QUO = (\"\"\")
78+
ONE_TWO_QUO = (\"\"?)
79+
BLOCK_STRING_ESCAPE = (\\({THREE_QUO} | [^\\\"\r\n\t ]))
80+
BLOCK_STRING_CHAR = [^\\\"\r\n\t ]
81+
BLOCK_STRING_BODY = {BLOCK_STRING_CHAR}+
82+
83+
DIGIT = [0-9]
84+
NON_ZERO_DIGIT = [1-9]
85+
INTEGER_PART = -? (0 | {NON_ZERO_DIGIT} {DIGIT}*)
86+
FRACTIONAL_PART = "." {DIGIT}+
87+
EXPONENT_PART = [eE] [+-]? {DIGIT}+
88+
89+
NUMBER = {INTEGER_PART}
90+
FLOAT = {INTEGER_PART} {FRACTIONAL_PART} | {INTEGER_PART} {EXPONENT_PART} | {INTEGER_PART} {FRACTIONAL_PART} {EXPONENT_PART}
91+
92+
%eof{
93+
myLeftBraceCount = 0;
94+
myStateStack.clear();
95+
%eof}
96+
97+
%state QUOTED_STRING BLOCK_STRING VARIABLE_OR_TEMPLATE TEMPLATE
98+
99+
%%
100+
101+
<YYINITIAL> {
102+
// Ignored tokens
103+
{UNICODE_BOM} |
104+
{WHITESPACE} { return WHITE_SPACE; }
105+
{EOL_COMMENT} { return EOL_COMMENT; }
106+
"," { return WHITE_SPACE; }
107+
108+
// Punctuators
109+
"!" { return BANG; }
110+
"$" { pushState(VARIABLE_OR_TEMPLATE); return DOLLAR; }
111+
"(" { return PAREN_L; }
112+
")" { return PAREN_R; }
113+
"..." { return SPREAD; }
114+
":" { return COLON; }
115+
"=" { return EQUALS; }
116+
"@" { return AT; }
117+
"[" { return BRACKET_L; }
118+
"]" { return BRACKET_R; }
119+
"{" { return BRACE_L; }
120+
"|" { return PIPE; }
121+
"}" { return BRACE_R; }
122+
"&" { return AMP; }
123+
124+
// keywords
125+
"query" { return QUERY_KEYWORD; }
126+
"mutation" { return MUTATION_KEYWORD; }
127+
"subscription" { return SUBSCRIPTION_KEYWORD; }
128+
"fragment" { return FRAGMENT_KEYWORD; }
129+
"on" { return ON_KEYWORD; }
130+
"schema" { return SCHEMA_KEYWORD; }
131+
"type" { return TYPE_KEYWORD; }
132+
"scalar" { return SCALAR_KEYWORD; }
133+
"interface" { return INTERFACE_KEYWORD; }
134+
"implements" { return IMPLEMENTS_KEYWORD; }
135+
"enum" { return ENUM_KEYWORD; }
136+
"union" { return UNION_KEYWORD; }
137+
"extend" { return EXTEND_KEYWORD; }
138+
"input" { return INPUT_KEYWORD; }
139+
"directive" { return DIRECTIVE_KEYWORD; }
140+
"repeatable" { return REPEATABLE_KEYWORD; }
141+
142+
// string and number literals
143+
\" { pushState(QUOTED_STRING); return OPEN_QUOTE; }
144+
{THREE_QUO} { pushState(BLOCK_STRING); return OPEN_TRIPLE_QUOTE; }
145+
{NUMBER} { return NUMBER; }
146+
{FLOAT} { return FLOAT; }
147+
148+
// identifiers
149+
{NAME} { return NAME; }
150+
{VARIABLE} { return VARIABLE_NAME; }
151+
152+
[^] { return BAD_CHARACTER; }
153+
}
154+
155+
<VARIABLE_OR_TEMPLATE> {
156+
"{" { pushState(TEMPLATE); return BRACE_L; }
157+
{NAME} { popState(); return NAME; }
158+
[^] { popState(); return BAD_CHARACTER; }
159+
}
160+
161+
<QUOTED_STRING> {
162+
{QUOTED_STRING_BODY} { return REGULAR_STRING_PART; }
163+
\" { popState(); return CLOSING_QUOTE; }
164+
[^] { popState(); return BAD_CHARACTER; }
165+
}
166+
167+
<BLOCK_STRING> {
168+
{WHITESPACE} { return WHITE_SPACE; }
169+
{BLOCK_STRING_ESCAPE} { return REGULAR_STRING_PART; }
170+
{ONE_TWO_QUO} / [^\"] { return REGULAR_STRING_PART; }
171+
{BLOCK_STRING_BODY} { return REGULAR_STRING_PART; }
172+
{THREE_QUO} { popState(); return CLOSING_TRIPLE_QUOTE; }
173+
[^] { return REGULAR_STRING_PART; }
174+
}
175+
176+
<TEMPLATE> {
177+
"{" { myLeftBraceCount++; return TEMPLATE_CHAR; }
178+
"}" { if (myLeftBraceCount == 0) { popState(); popState(); return BRACE_R; } myLeftBraceCount--; return TEMPLATE_CHAR; }
179+
[^\{\}]+ { return TEMPLATE_CHAR; }
180+
}

0 commit comments

Comments
 (0)