Skip to content

Commit 6645bda

Browse files
Merge pull request #19 from protostuff/feature/reference-lookup
Reference lookup
2 parents 79accf0 + 53e4ee9 commit 6645bda

34 files changed

+641
-69
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ dependencies {
2424
compile 'org.antlr:antlr4-runtime:4.5.1'
2525
compile 'org.antlr:antlr4-jetbrains-adapter:1.0.0'
2626
compile 'com.google.guava:guava:19.0'
27-
compile 'io.protostuff:protostuff-parser:2.0.0-alpha17'
27+
compile 'io.protostuff:protostuff-parser:2.0.0-alpha21'
2828
}
2929

3030
apply plugin: 'idea'

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Available idea versions:
22
# https://www.jetbrains.com/intellij-repository/releases
33
# https://www.jetbrains.com/intellij-repository/snapshots
4-
version=0.3.1
4+
version=0.4.0
55
ideaVersion=145.258.11
66
# https://intellij-support.jetbrains.com/hc/en-us/articles/206544879-Selecting-the-JDK-version-the-IDE-will-run-under
77
# Java 8 is required to run IntelliJ IDEA starting from version 16

src/main/java/io/protostuff/jetbrains/plugin/ProtoParserDefinition.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public class ProtoParserDefinition implements ParserDefinition {
6565
PSIElementTypeFactory.defineLanguageIElementTypes(ProtoLanguage.INSTANCE,
6666
ProtoParser.tokenNames, ProtoParser.ruleNames);
6767
tokenTypes = PSIElementTypeFactory.getTokenIElementTypes(ProtoLanguage.INSTANCE);
68-
ID = tokenTypes.get(ProtoLexer.NAME);
68+
ID = tokenTypes.get(ProtoLexer.IDENT);
6969
FILE = new IFileElementType(ProtoLanguage.INSTANCE);
7070
COMMENTS = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, COMMENT, LINE_COMMENT);
7171
WHITESPACE = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, WS, NL);
@@ -116,7 +116,7 @@ public class ProtoParserDefinition implements ParserDefinition {
116116
ruleTypes = PSIElementTypeFactory.getRuleIElementTypes(ProtoLanguage.INSTANCE);
117117

118118
R_TYPE_REFERENCE = ruleTypes.get(ProtoParser.RULE_typeReference);
119-
R_NAME = ruleTypes.get(ProtoParser.RULE_name);
119+
R_NAME = ruleTypes.get(ProtoParser.RULE_ident);
120120
R_FIELD_MODIFIER = ruleTypes.get(ProtoParser.RULE_fieldModifier);
121121

122122
LCURLY = tokenTypes.get(ProtoLexer.LCURLY);
@@ -156,7 +156,8 @@ protected ParseTree parse(Parser parser, IElementType root) {
156156
return ((ProtoParser) parser).proto();
157157
}
158158
// let's hope it's an ID as needed by "rename function"
159-
return ((ProtoParser) parser).name();
159+
throw new UnsupportedOperationException();
160+
// return ((ProtoParser) parser).name();
160161
}
161162
};
162163
}
@@ -199,11 +200,15 @@ public PsiElement createElement(ASTNode node) {
199200
case ProtoParser.RULE_syntax:
200201
return new SyntaxNode(node);
201202
case ProtoParser.RULE_packageStatement:
202-
return new PackageNode(node);
203+
return new PackageStatement(node);
203204
case ProtoParser.RULE_importStatement:
204205
return new ImportNode(node);
206+
case ProtoParser.RULE_fileReference:
207+
return new FileReferenceNode(node);
205208
case ProtoParser.RULE_messageBlock:
206209
return new MessageNode(node);
210+
case ProtoParser.RULE_messageName:
211+
return new MessageNameNode(node);
207212
case ProtoParser.RULE_field:
208213
return new FieldNode(node);
209214
case ProtoParser.RULE_typeReference:
@@ -212,7 +217,7 @@ public PsiElement createElement(ASTNode node) {
212217
return new GroupNode(node);
213218
case ProtoParser.RULE_enumBlock:
214219
return new EnumNode(node);
215-
case ProtoParser.RULE_enumConstant:
220+
case ProtoParser.RULE_enumField:
216221
return new EnumConstantNode(node);
217222
case ProtoParser.RULE_serviceBlock:
218223
return new ServiceNode(node);

src/main/java/io/protostuff/jetbrains/plugin/formatter/BlockFactory.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class BlockFactory {
2828
register(rule(RULE_proto), FAIL_ROOT_NODE);
2929
register(rule(RULE_packageName), LeafBlock::new);
3030
register(rule(RULE_rpcType), LeafBlock::new);
31-
register(rule(RULE_name), LeafBlock::new);
31+
register(rule(RULE_ident), LeafBlock::new);
3232
register(rule(RULE_mapKey), LeafBlock::new);
3333
register(rule(RULE_mapValue), LeafBlock::new);
3434
register(rule(RULE_tag), LeafBlock::new);
@@ -55,7 +55,7 @@ class BlockFactory {
5555
register(rule(RULE_textFormatEntry), ParentBlock::new);
5656
register(rule(RULE_field), StatementBlock::new);
5757
register(rule(RULE_enumBlock), ParentBlock::new);
58-
register(rule(RULE_enumConstant), StatementBlock::new);
58+
register(rule(RULE_enumField), StatementBlock::new);
5959
register(rule(RULE_serviceBlock), ParentBlock::new);
6060
register(rule(RULE_rpcMethod), ParentBlock::new);
6161
register(rule(RULE_extendBlock), ParentBlock::new);
@@ -65,6 +65,17 @@ class BlockFactory {
6565
register(rule(RULE_oneofGroup), ParentBlock::new);
6666
register(rule(RULE_groupBlock), ParentBlock::new);
6767
register(rule(RULE_extensions), StatementBlock::new);
68+
69+
register(rule(RULE_enumName), LeafBlock::new);
70+
register(rule(RULE_enumFieldName), LeafBlock::new);
71+
register(rule(RULE_serviceName), LeafBlock::new);
72+
register(rule(RULE_rpcName), LeafBlock::new);
73+
register(rule(RULE_messageName), LeafBlock::new);
74+
register(rule(RULE_oneofName), LeafBlock::new);
75+
register(rule(RULE_groupName), LeafBlock::new);
76+
register(rule(RULE_fieldNameString), LeafBlock::new);
77+
register(rule(RULE_fullIdent), LeafBlock::new);
78+
register(rule(RULE_fileReference), LeafBlock::new);
6879
}
6980

7081
private static void register(IElementType elementType, Factory factory) {

src/main/java/io/protostuff/jetbrains/plugin/psi/EnumConstantNode.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
import com.intellij.lang.ASTNode;
44
import com.intellij.psi.PsiElement;
55
import com.intellij.psi.PsiNamedElement;
6-
import io.protostuff.jetbrains.plugin.ProtoParserDefinition;
6+
import io.protostuff.compiler.parser.ProtoParser;
77
import org.antlr.jetbrains.adapter.psi.IdentifierDefSubtree;
88
import org.antlr.jetbrains.adapter.psi.ScopeNode;
99
import org.jetbrains.annotations.NotNull;
1010
import org.jetbrains.annotations.Nullable;
1111

12+
import static io.protostuff.jetbrains.plugin.ProtoParserDefinition.rule;
13+
1214
/**
1315
* @author Kostiantyn Shchepanovskyi
1416
*/
@@ -17,7 +19,7 @@ public class EnumConstantNode
1719
implements ScopeNode {
1820

1921
public EnumConstantNode(@NotNull ASTNode node) {
20-
super(node, ProtoParserDefinition.R_NAME);
22+
super(node, rule(ProtoParser.RULE_enumFieldName));
2123
}
2224

2325
@Nullable

src/main/java/io/protostuff/jetbrains/plugin/psi/EnumNode.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.intellij.lang.ASTNode;
44
import com.intellij.psi.PsiElement;
55
import com.intellij.psi.PsiNamedElement;
6+
import io.protostuff.compiler.parser.ProtoParser;
67
import io.protostuff.jetbrains.plugin.ProtoParserDefinition;
78
import org.antlr.jetbrains.adapter.psi.IdentifierDefSubtree;
89
import org.antlr.jetbrains.adapter.psi.ScopeNode;
@@ -13,17 +14,10 @@
1314
* @author Kostiantyn Shchepanovskyi
1415
*/
1516
public class EnumNode
16-
extends IdentifierDefSubtree
17-
implements ScopeNode, KeywordsContainer {
17+
extends UserType {
1818

1919
public EnumNode(@NotNull ASTNode node) {
20-
super(node, ProtoParserDefinition.R_NAME);
21-
}
22-
23-
@Nullable
24-
@Override
25-
public PsiElement resolve(PsiNamedElement element) {
26-
return null;
20+
super(node, ProtoParserDefinition.rule(ProtoParser.RULE_enumName));
2721
}
2822

2923
}

src/main/java/io/protostuff/jetbrains/plugin/psi/FieldNode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.intellij.lang.ASTNode;
44
import com.intellij.psi.PsiElement;
5+
import io.protostuff.compiler.parser.ProtoParser;
56
import io.protostuff.jetbrains.plugin.ProtoParserDefinition;
67
import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode;
78
import org.antlr.jetbrains.adapter.psi.IdentifierDefSubtree;
@@ -18,7 +19,7 @@
1819
public class FieldNode extends IdentifierDefSubtree implements KeywordsContainer {
1920

2021
public FieldNode(@NotNull ASTNode node) {
21-
super(node, ProtoParserDefinition.R_NAME);
22+
super(node, ProtoParserDefinition.rule(ProtoParser.RULE_fieldName));
2223
}
2324

2425
@Override
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package io.protostuff.jetbrains.plugin.psi;
2+
3+
import com.intellij.lang.ASTNode;
4+
import com.intellij.openapi.module.Module;
5+
import com.intellij.openapi.module.ModuleManager;
6+
import com.intellij.openapi.module.ModuleUtilCore;
7+
import com.intellij.openapi.vfs.VirtualFile;
8+
import com.intellij.psi.PsiFile;
9+
import com.intellij.psi.PsiFileSystemItem;
10+
import com.intellij.psi.PsiManager;
11+
import com.intellij.psi.PsiReference;
12+
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FilePathReferenceProvider;
13+
import io.protostuff.compiler.parser.Util;
14+
import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode;
15+
import org.jetbrains.annotations.NotNull;
16+
import org.jetbrains.annotations.Nullable;
17+
18+
import java.util.Collection;
19+
20+
/**
21+
* @author Kostiantyn Shchepanovskyi
22+
*/
23+
public class FileReferenceNode extends ANTLRPsiNode {
24+
25+
private final FilePathReferenceProvider referenceProvider;
26+
27+
public FileReferenceNode(@NotNull ASTNode node) {
28+
super(node);
29+
referenceProvider = new FilePathReferenceProvider(true);
30+
}
31+
32+
@NotNull
33+
@Override
34+
public PsiReference[] getReferences() {
35+
String filename = getFilename();
36+
if (filename == null) {
37+
return new PsiReference[0];
38+
}
39+
Module module = ModuleUtilCore.findModuleForPsiElement(this);
40+
if (module != null) {
41+
referenceProvider.getReferencesByElement(this, filename, 1, true);
42+
}
43+
// fallback: if we are inside of a dependency, current module is null
44+
// in this case we try to resolve reference in all dependencies of all modules
45+
// (might be not fully correct, but better than nothing)
46+
ModuleManager moduleManager = ModuleManager.getInstance(getProject());
47+
Module[] modules = moduleManager.getModules();
48+
return referenceProvider.getReferencesByElement(this, filename, 1, true, modules);
49+
}
50+
51+
@Nullable
52+
public ProtoPsiFileRoot getTarget() {
53+
String filename = getFilename();
54+
if (filename == null) {
55+
return null;
56+
}
57+
Module module = ModuleUtilCore.findModuleForPsiElement(this);
58+
if (module != null) {
59+
return getTarget(filename, module);
60+
}
61+
// fallback: if we are inside of a dependency, current module is null
62+
// in this case we try to resolve reference in all dependencies of all modules
63+
// (might be not fully correct, but better than nothing)
64+
ModuleManager moduleManager = ModuleManager.getInstance(getProject());
65+
Module[] modules = moduleManager.getModules();
66+
for (Module m : modules) {
67+
ProtoPsiFileRoot target = getTarget(filename, m);
68+
if (target != null) {
69+
return target;
70+
}
71+
}
72+
return null;
73+
}
74+
75+
public ProtoPsiFileRoot getTarget(@NotNull String filename, @NotNull Module module) {
76+
Collection<PsiFileSystemItem> roots = FilePathReferenceProvider.getRoots(module, true);
77+
for (PsiFileSystemItem root : roots) {
78+
VirtualFile file = root.getVirtualFile().findFileByRelativePath(getFilename());
79+
if (file != null) {
80+
PsiManager psiManager = PsiManager.getInstance(getProject());
81+
PsiFile psiFile = psiManager.findFile(file);
82+
if (psiFile instanceof ProtoPsiFileRoot) {
83+
return (ProtoPsiFileRoot) psiFile;
84+
}
85+
}
86+
}
87+
return null;
88+
}
89+
90+
@Nullable
91+
private String getFilename() {
92+
String text = getText();
93+
if (text == null
94+
|| text.length() < 2
95+
|| !text.startsWith("\"")
96+
|| !text.endsWith("\"")) {
97+
return null;
98+
}
99+
return Util.removeFirstAndLastChar(text);
100+
}
101+
}

src/main/java/io/protostuff/jetbrains/plugin/psi/ImportNode.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package io.protostuff.jetbrains.plugin.psi;
22

33
import com.intellij.lang.ASTNode;
4+
import io.protostuff.compiler.parser.ProtoLexer;
5+
import io.protostuff.jetbrains.plugin.ProtoParserDefinition;
46
import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode;
57
import org.jetbrains.annotations.NotNull;
8+
import org.jetbrains.annotations.Nullable;
69

710
/**
811
* @author Kostiantyn Shchepanovskyi
@@ -13,4 +16,26 @@ public ImportNode(@NotNull ASTNode node) {
1316
super(node);
1417
}
1518

19+
@Nullable
20+
public ProtoPsiFileRoot getTarget() {
21+
FileReferenceNode fileReference = findChildByClass(FileReferenceNode.class);
22+
if (fileReference != null) {
23+
return fileReference.getTarget();
24+
}
25+
return null;
26+
}
27+
28+
@Nullable
29+
public ProtoRootNode getTargetProto() {
30+
ProtoPsiFileRoot fileRoot = getTarget();
31+
if (fileRoot != null) {
32+
return fileRoot.findChildByClass(ProtoRootNode.class);
33+
}
34+
return null;
35+
}
36+
37+
public boolean isPublic() {
38+
return findChildrenByType(ProtoParserDefinition.token(ProtoLexer.PUBLIC)) != null;
39+
}
40+
1641
}

src/main/java/io/protostuff/jetbrains/plugin/psi/PackageNode.java renamed to src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNameNode.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package io.protostuff.jetbrains.plugin.psi;
22

33
import com.intellij.lang.ASTNode;
4+
import com.intellij.psi.PsiReference;
5+
import io.protostuff.jetbrains.plugin.reference.TypeReference;
46
import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode;
57
import org.jetbrains.annotations.NotNull;
68

79
/**
810
* @author Kostiantyn Shchepanovskyi
911
*/
10-
public class PackageNode extends ANTLRPsiNode implements KeywordsContainer {
12+
public class MessageNameNode extends ANTLRPsiNode {
1113

12-
public PackageNode(@NotNull ASTNode node) {
14+
public MessageNameNode(@NotNull ASTNode node) {
1315
super(node);
1416
}
1517

0 commit comments

Comments
 (0)