Skip to content

Commit 746eb99

Browse files
committed
Merge branch 'issue-35-arguments' into Endpoint
# Conflicts: # resources/META-INF/plugin.xml # src/main/com/intellij/lang/jsgraphql/schema/ide/project/JSGraphQLSchemaLanguageProjectService.java
2 parents 512ceeb + 66a18de commit 746eb99

20 files changed

+787
-207
lines changed

resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
<lang.quoteHandler language="GraphQL Schema" implementationClass="com.intellij.lang.jsgraphql.ide.editor.JSGraphQLQuoteHandler" />
133133
<lang.quoteHandler language="GraphQL Endpoint" implementationClass="com.intellij.lang.jsgraphql.endpoint.ide.editor.JSGraphQLEndpointQuoteHandler" />
134134
<enterHandlerDelegate implementation="com.intellij.lang.jsgraphql.ide.formatter.JSGraphQLEnterHandlerDelegate" />
135+
<enterHandlerDelegate implementation="com.intellij.lang.jsgraphql.ide.formatter.JSGraphQLEnterInEmptyListHandler"/>
135136
<langCodeStyleSettingsProvider implementation="com.intellij.lang.jsgraphql.ide.formatter.JSGraphQLLanguageCodeStyleSettingsProvider"/>
136137
<codeStyleSettingsProvider implementation="com.intellij.lang.jsgraphql.ide.formatter.JSGraphQLCodeStyleSettingsProvider" />
137138

src/main/com/intellij/lang/jsgraphql/ide/documentation/JSGraphQLDocumentationProvider.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.intellij.lang.jsgraphql.languageservice.JSGraphQLNodeLanguageServiceClient;
1515
import com.intellij.lang.jsgraphql.languageservice.api.TokenDocumentationResponse;
1616
import com.intellij.lang.jsgraphql.languageservice.api.TypeDocumentationResponse;
17+
import com.intellij.lang.jsgraphql.psi.JSGraphQLAttributePsiElement;
1718
import com.intellij.lang.jsgraphql.psi.JSGraphQLFragmentDefinitionPsiElement;
1819
import com.intellij.lang.jsgraphql.psi.JSGraphQLNamedPropertyPsiElement;
1920
import com.intellij.lang.jsgraphql.psi.JSGraphQLNamedPsiElement;
@@ -24,10 +25,12 @@
2425
import com.intellij.openapi.editor.colors.EditorColorsManager;
2526
import com.intellij.openapi.editor.colors.EditorColorsScheme;
2627
import com.intellij.openapi.project.Project;
28+
import com.intellij.psi.PsiComment;
2729
import com.intellij.psi.PsiElement;
2830
import com.intellij.psi.PsiFile;
2931
import com.intellij.psi.PsiManager;
3032
import com.intellij.psi.PsiReference;
33+
import com.intellij.psi.PsiWhiteSpace;
3134
import com.intellij.psi.util.PsiTreeUtil;
3235
import com.intellij.ui.GuiUtils;
3336
import com.intellij.util.containers.ContainerUtil;
@@ -197,6 +200,27 @@ private String createQuickNavigateDocumentation(PsiElement element, boolean full
197200
doc += "</code>";
198201
return getDocTemplate(fullDocumentation).replace("${body}", doc);
199202
}
203+
} else if(element instanceof JSGraphQLAttributePsiElement) {
204+
String doc = "";
205+
PsiElement prevLeaf = PsiTreeUtil.prevLeaf(element);
206+
String documentation = "";
207+
while (prevLeaf instanceof PsiWhiteSpace || prevLeaf instanceof PsiComment) {
208+
documentation = StringUtils.removeStart(prevLeaf.getText(), "# ") + documentation;
209+
prevLeaf = PsiTreeUtil.prevLeaf(prevLeaf);
210+
}
211+
documentation = documentation.trim();
212+
if(StringUtils.isNotBlank(documentation)) {
213+
doc += "<div style=\"margin-bottom: 4px\">" + StringEscapeUtils.escapeHtml(documentation) + "</div>";
214+
}
215+
doc += "<code>" + element.getText();
216+
PsiElement nextLeaf = PsiTreeUtil.nextLeaf(element);
217+
// include the attribute type (stopping at newline, ",", and ")")
218+
while(nextLeaf != null && !nextLeaf.getText().contains("\n") && !nextLeaf.getText().contains(",") && !nextLeaf.getText().contains(")")) {
219+
doc += nextLeaf.getText();
220+
nextLeaf = PsiTreeUtil.nextLeaf(nextLeaf);
221+
}
222+
doc += "</code>";
223+
return getDocTemplate(fullDocumentation).replace("${body}", doc);
200224
}
201225

202226
}

src/main/com/intellij/lang/jsgraphql/ide/editor/JSGraphQLFoldingBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public class JSGraphQLFoldingBuilder implements FoldingBuilder {
2424
@Nullable
2525
@Override
2626
public String getPlaceholderText(@NotNull ASTNode node) {
27+
final ASTNode first = node.getFirstChildNode();
28+
final ASTNode last = node.getLastChildNode();
29+
if (first != null && last != null) {
30+
return first.getText() + "..." + last.getText();
31+
}
2732
return "{...}";
2833
}
2934

src/main/com/intellij/lang/jsgraphql/ide/findUsages/JSGraphQLFindUsagesProvider.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@
99

1010
import com.intellij.lang.cacheBuilder.WordsScanner;
1111
import com.intellij.lang.findUsages.FindUsagesProvider;
12+
import com.intellij.lang.jsgraphql.JSGraphQLKeywords;
13+
import com.intellij.lang.jsgraphql.psi.JSGraphQLAttributePsiElement;
1214
import com.intellij.lang.jsgraphql.psi.JSGraphQLNamedPropertyPsiElement;
1315
import com.intellij.lang.jsgraphql.psi.JSGraphQLNamedPsiElement;
1416
import com.intellij.lang.jsgraphql.psi.JSGraphQLNamedTypePsiElement;
17+
import com.intellij.lang.jsgraphql.psi.JSGraphQLPsiElement;
1518
import com.intellij.lang.jsgraphql.schema.psi.JSGraphQLSchemaFile;
1619
import com.intellij.openapi.util.text.StringUtil;
1720
import com.intellij.psi.PsiElement;
1821
import com.intellij.psi.PsiNamedElement;
22+
import com.intellij.psi.util.PsiTreeUtil;
23+
1924
import org.jetbrains.annotations.NotNull;
2025
import org.jetbrains.annotations.Nullable;
2126

@@ -52,6 +57,22 @@ public String getType(@NotNull PsiElement element) {
5257
final boolean atom = element.getContainingFile() instanceof JSGraphQLSchemaFile || ((JSGraphQLNamedTypePsiElement) element).isAtom();
5358
return atom ? "type" : "definition";
5459
}
60+
if(element instanceof JSGraphQLAttributePsiElement) {
61+
JSGraphQLPsiElement parent = PsiTreeUtil.getParentOfType(element, JSGraphQLPsiElement.class);
62+
while (parent != null) {
63+
final JSGraphQLPsiElement ancestor = PsiTreeUtil.getParentOfType(parent, JSGraphQLPsiElement.class);
64+
if(ancestor == null) {
65+
break;
66+
}
67+
parent = ancestor;
68+
}
69+
if(parent != null && JSGraphQLKeywords.INPUT.equals(parent.getKeyword())) {
70+
// field of an input type
71+
return "input field";
72+
}
73+
// field argument
74+
return "argument";
75+
}
5576
return "unknown";
5677
}
5778

src/main/com/intellij/lang/jsgraphql/ide/formatter/JSGraphQLBlock.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.intellij.openapi.util.TextRange;
2020
import com.intellij.psi.TokenType;
2121
import com.intellij.psi.formatter.common.AbstractBlock;
22+
import com.intellij.psi.tree.IElementType;
2223
import org.jetbrains.annotations.NotNull;
2324
import org.jetbrains.annotations.Nullable;
2425

@@ -40,6 +41,15 @@ public class JSGraphQLBlock extends AbstractBlock {
4041
EXTEND_DEF_KIND
4142
);
4243

44+
private static final Set<IElementType> NO_INDENT_ELEMENT_TYPES = Sets.newHashSet(
45+
JSGraphQLTokenTypes.LBRACE,
46+
JSGraphQLTokenTypes.RBRACE,
47+
JSGraphQLTokenTypes.LBRACKET,
48+
JSGraphQLTokenTypes.RBRACKET,
49+
JSGraphQLTokenTypes.LPAREN,
50+
JSGraphQLTokenTypes.RPAREN
51+
);
52+
4353
@Nullable
4454
private JSGraphQLBlock parent;
4555
private SpacingBuilder spacingBuilder;
@@ -104,18 +114,31 @@ private JSGraphQLElementType getAstNode(JSGraphQLBlock block) {
104114
@Override
105115
public Indent getIndent() {
106116

107-
if (myNode.getElementType() == JSGraphQLTokenTypes.RBRACE || myNode.getElementType() == JSGraphQLTokenTypes.LBRACE) {
117+
if (NO_INDENT_ELEMENT_TYPES.contains(myNode.getElementType())) {
108118
return Indent.getNoneIndent();
109119
}
110120

111121
if(parent != null) {
112122
JSGraphQLElementType astNode = getAstNode(parent);
113123
if (astNode != null) {
114-
if (JSGraphQLElementType.SELECTION_SET_KIND.equals(astNode.getKind())) {
124+
final String kind = astNode.getKind();
125+
if (JSGraphQLElementType.SELECTION_SET_KIND.equals(kind)) {
115126
// this block is inside a selection set: '{ ... }', so indent it
116127
return Indent.getNormalIndent();
117128
}
118-
if(JSGraphQLElementType.SCHEMA_DEF_KIND.equals(astNode.getKind())) {
129+
if (JSGraphQLElementType.ARGUMENTS_KIND.equals(kind)) {
130+
// this block is inside a () arguments list, so indent it
131+
return Indent.getNormalIndent();
132+
}
133+
if (JSGraphQLElementType.OBJECT_VALUE_KIND.equals(kind)) {
134+
// this block is inside a {} object value, so indent it
135+
return Indent.getNormalIndent();
136+
}
137+
if (JSGraphQLElementType.LIST_VALUE_KIND.equals(kind)) {
138+
// this block is inside a [] list value, so indent it
139+
return Indent.getNormalIndent();
140+
}
141+
if(JSGraphQLElementType.SCHEMA_DEF_KIND.equals(kind)) {
119142
// inside schema {}
120143
if(myNode.getText().equals(JSGraphQLKeywords.QUERY) || myNode.getText().equals(JSGraphQLKeywords.MUTATION) || myNode.getText().equals(JSGraphQLKeywords.SUBSCRIPTION)) {
121144
return Indent.getNormalIndent();
@@ -124,7 +147,7 @@ public Indent getIndent() {
124147
return Indent.getNormalIndent();
125148
}
126149
}
127-
if(myNode.getElementType() != JSGraphQLTokenTypes.KEYWORD && INDENT_PARENT_KINDS.contains(astNode.getKind())) {
150+
if(myNode.getElementType() != JSGraphQLTokenTypes.KEYWORD && INDENT_PARENT_KINDS.contains(kind)) {
128151
// properties inside schema definitions
129152
return Indent.getNormalIndent();
130153
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright (c) 2015-present, Jim Kynde Meyer
3+
* All rights reserved.
4+
* <p>
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
package com.intellij.lang.jsgraphql.ide.formatter;
9+
10+
import com.intellij.codeInsight.editorActions.enter.EnterBetweenBracesHandler;
11+
import com.intellij.lang.jsgraphql.JSGraphQLLanguage;
12+
import com.intellij.openapi.actionSystem.DataContext;
13+
import com.intellij.openapi.editor.Editor;
14+
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
15+
import com.intellij.openapi.util.Ref;
16+
import com.intellij.psi.PsiFile;
17+
import org.jetbrains.annotations.NotNull;
18+
19+
/**
20+
* Adds a new indented line when pressing enter between [] in an empty GraphQL list
21+
*/
22+
public class JSGraphQLEnterInEmptyListHandler extends EnterBetweenBracesHandler {
23+
24+
@Override
25+
public Result preprocessEnter(@NotNull PsiFile file,
26+
@NotNull Editor editor,
27+
@NotNull Ref<Integer> caretOffsetRef,
28+
@NotNull Ref<Integer> caretAdvance,
29+
@NotNull DataContext dataContext,
30+
EditorActionHandler originalHandler) {
31+
if (!file.getLanguage().is(JSGraphQLLanguage.INSTANCE)) {
32+
return Result.Continue;
33+
}
34+
return super.preprocessEnter(file, editor, caretOffsetRef, caretAdvance, dataContext, originalHandler);
35+
}
36+
37+
@Override
38+
protected boolean isBracePair(char c1, char c2) {
39+
return c1 == '[' && c2 == ']';
40+
}
41+
42+
}

0 commit comments

Comments
 (0)