diff --git a/build.gradle b/build.gradle index f870c86..832ff28 100644 --- a/build.gradle +++ b/build.gradle @@ -45,12 +45,12 @@ intellij { // plugins 'properties' downloadSources = false publish { - username = project.hasProperty('jetbrainsUser') \ - ? project.property('jetbrainsUser') \ - : System.getenv('JETBRAINS_USER') - password = project.hasProperty('jetbrainsPassword') \ - ? project.property('jetbrainsPassword') \ - : System.getenv('JETBRAINS_PASSWORD') + username = project.hasProperty('jetbrainsUser') \ + ? project.property('jetbrainsUser') \ + : System.getenv('JETBRAINS_USER') + password = project.hasProperty('jetbrainsPassword') \ + ? project.property('jetbrainsPassword') \ + : System.getenv('JETBRAINS_PASSWORD') pluginId = '8277' } } diff --git a/src/main/java/io/protostuff/jetbrains/plugin/ProtoFindUsagesProvider.java b/src/main/java/io/protostuff/jetbrains/plugin/ProtoFindUsagesProvider.java new file mode 100644 index 0000000..4d2fdb2 --- /dev/null +++ b/src/main/java/io/protostuff/jetbrains/plugin/ProtoFindUsagesProvider.java @@ -0,0 +1,78 @@ +package io.protostuff.jetbrains.plugin; + +import com.intellij.lang.cacheBuilder.DefaultWordsScanner; +import com.intellij.lang.cacheBuilder.WordsScanner; +import com.intellij.lang.findUsages.FindUsagesProvider; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; +import com.intellij.psi.tree.TokenSet; +import io.protostuff.compiler.parser.ProtoLexer; +import io.protostuff.jetbrains.plugin.psi.EnumNode; +import io.protostuff.jetbrains.plugin.psi.MessageNode; +import io.protostuff.jetbrains.plugin.psi.UserType; +import org.antlr.jetbrains.adapter.lexer.PSIElementTypeFactory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Kostiantyn Shchepanovskyi + */ +public class ProtoFindUsagesProvider implements FindUsagesProvider { + + @Nullable + @Override + public WordsScanner getWordsScanner() { + + return new DefaultWordsScanner(new ProtoLexerAdapter(), + ProtoParserDefinition.IDENTIFIER_TOKEN_SET, + ProtoParserDefinition.COMMENT_TOKEN_SET, + ProtoParserDefinition.LITERAL_TOKEN_SET); + } + + @Override + public boolean canFindUsagesFor(@NotNull PsiElement psiElement) { + return psiElement instanceof UserType; + } + + @Nullable + @Override + public String getHelpId(@NotNull PsiElement psiElement) { + return null; + } + + @NotNull + @Override + public String getType(@NotNull PsiElement element) { + if (element instanceof MessageNode) { + return "message"; + } + if (element instanceof EnumNode) { + return "enum"; + } + return ""; + } + + @NotNull + @Override + public String getDescriptiveName(@NotNull PsiElement element) { + if (element instanceof UserType) { + UserType type = (UserType) element; + return type.getFullName(); + } + return ""; + } + + @NotNull + @Override + public String getNodeText(@NotNull PsiElement element, boolean useFullName) { + if (element instanceof UserType) { + UserType type = (UserType) element; + if (useFullName) { + return type.getFullName(); + } + //noinspection ConstantConditions + return type.getName(); + } + return ""; + } +} diff --git a/src/main/java/io/protostuff/jetbrains/plugin/ProtoLexerAdapter.java b/src/main/java/io/protostuff/jetbrains/plugin/ProtoLexerAdapter.java new file mode 100644 index 0000000..f31df1b --- /dev/null +++ b/src/main/java/io/protostuff/jetbrains/plugin/ProtoLexerAdapter.java @@ -0,0 +1,16 @@ +package io.protostuff.jetbrains.plugin; + +import com.intellij.lang.Language; +import io.protostuff.compiler.parser.ProtoLexer; +import org.antlr.jetbrains.adapter.lexer.ANTLRLexerAdaptor; +import org.antlr.v4.runtime.Lexer; + +/** + * @author Kostiantyn Shchepanovskyi + */ +public class ProtoLexerAdapter extends ANTLRLexerAdaptor { + + public ProtoLexerAdapter() { + super(ProtoLanguage.INSTANCE, new ProtoLexer(null)); + } +} diff --git a/src/main/java/io/protostuff/jetbrains/plugin/ProtoParserDefinition.java b/src/main/java/io/protostuff/jetbrains/plugin/ProtoParserDefinition.java index 103f314..6fcc02c 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/ProtoParserDefinition.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/ProtoParserDefinition.java @@ -33,109 +33,178 @@ */ public class ProtoParserDefinition implements ParserDefinition { - public static final TokenIElementType ID; - public static final TokenSet KEYWORDS; + static { + PSIElementTypeFactory.defineLanguageIElementTypes(ProtoLanguage.INSTANCE, + ProtoParser.tokenNames, ProtoParser.ruleNames); + } - // tokens + private static final List TOKEN_TYPES = PSIElementTypeFactory.getTokenIElementTypes(ProtoLanguage.INSTANCE); + private static final List RULE_TYPES = PSIElementTypeFactory.getRuleIElementTypes(ProtoLanguage.INSTANCE); - public static final TokenIElementType LCURLY; - public static final TokenIElementType RCURLY; - public static final TokenIElementType LPAREN; - public static final TokenIElementType RPAREN; - public static final TokenIElementType LSQUARE; - public static final TokenIElementType RSQUARE; - public static final TokenIElementType LT; - public static final TokenIElementType GT; - public static final TokenIElementType ASSIGN; + public static final TokenIElementType ID = TOKEN_TYPES.get(ProtoLexer.IDENT); - // Rules - public static final IElementType R_TYPE_REFERENCE; - public static final IElementType R_NAME; - public static final IElementType R_FIELD_MODIFIER; - private static final IFileElementType FILE; - private static final TokenSet COMMENTS; - public static final TokenSet WHITESPACE; + public static final TokenSet KEYWORDS = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, + ProtoLexer.PACKAGE, + ProtoLexer.SYNTAX, + ProtoLexer.IMPORT, + ProtoLexer.PUBLIC, + ProtoLexer.OPTION, + ProtoLexer.MESSAGE, + ProtoLexer.GROUP, + ProtoLexer.OPTIONAL, + ProtoLexer.REQUIRED, + ProtoLexer.REPEATED, + ProtoLexer.ONEOF, + ProtoLexer.EXTEND, + ProtoLexer.EXTENSIONS, + ProtoLexer.RESERVED, + ProtoLexer.TO, + ProtoLexer.MAX, + ProtoLexer.ENUM, + ProtoLexer.SERVICE, + ProtoLexer.RPC, + ProtoLexer.STREAM, + ProtoLexer.RETURNS, + ProtoLexer.MAP, + ProtoLexer.BOOLEAN_VALUE, + ProtoLexer.DOUBLE, + ProtoLexer.FLOAT, + ProtoLexer.INT32, + ProtoLexer.INT64, + ProtoLexer.UINT32, + ProtoLexer.UINT64, + ProtoLexer.SINT32, + ProtoLexer.SINT64, + ProtoLexer.FIXED32, + ProtoLexer.FIXED64, + ProtoLexer.SFIXED32, + ProtoLexer.SFIXED64, + ProtoLexer.BOOL, + ProtoLexer.STRING, + ProtoLexer.BYTES + ); - private static final TokenSet STRING; + // keywords also can be identifiers + public static final TokenSet IDENTIFIER_TOKEN_SET = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, + ProtoLexer.IDENT, + ProtoLexer.PACKAGE, + ProtoLexer.SYNTAX, + ProtoLexer.IMPORT, + ProtoLexer.PUBLIC, + ProtoLexer.OPTION, + ProtoLexer.MESSAGE, + ProtoLexer.GROUP, + ProtoLexer.OPTIONAL, + ProtoLexer.REQUIRED, + ProtoLexer.REPEATED, + ProtoLexer.ONEOF, + ProtoLexer.EXTEND, + ProtoLexer.EXTENSIONS, + ProtoLexer.RESERVED, + ProtoLexer.TO, + ProtoLexer.MAX, + ProtoLexer.ENUM, + ProtoLexer.SERVICE, + ProtoLexer.RPC, + ProtoLexer.STREAM, + ProtoLexer.RETURNS, + ProtoLexer.MAP, + ProtoLexer.BOOLEAN_VALUE, + ProtoLexer.DOUBLE, + ProtoLexer.FLOAT, + ProtoLexer.INT32, + ProtoLexer.INT64, + ProtoLexer.UINT32, + ProtoLexer.UINT64, + ProtoLexer.SINT32, + ProtoLexer.SINT64, + ProtoLexer.FIXED32, + ProtoLexer.FIXED64, + ProtoLexer.SFIXED32, + ProtoLexer.SFIXED64, + ProtoLexer.BOOL, + ProtoLexer.STRING, + ProtoLexer.BYTES + ); - private static List tokenTypes; - private static List ruleTypes; - - static { - PSIElementTypeFactory.defineLanguageIElementTypes(ProtoLanguage.INSTANCE, - ProtoParser.tokenNames, ProtoParser.ruleNames); - tokenTypes = PSIElementTypeFactory.getTokenIElementTypes(ProtoLanguage.INSTANCE); - ID = tokenTypes.get(ProtoLexer.IDENT); - FILE = new IFileElementType(ProtoLanguage.INSTANCE); - COMMENTS = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, COMMENT, LINE_COMMENT); - WHITESPACE = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, WS, NL); - STRING = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, STRING_VALUE); + public static final TokenSet COMMENT_TOKEN_SET = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, + ProtoLexer.COMMENT, + ProtoLexer.LINE_COMMENT + ); + public static final TokenSet LITERAL_TOKEN_SET = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, + ProtoLexer.STRING_VALUE, + ProtoLexer.FLOAT_VALUE, + ProtoLexer.INTEGER_VALUE, + ProtoLexer.IDENT, + ProtoLexer.PACKAGE, + ProtoLexer.SYNTAX, + ProtoLexer.IMPORT, + ProtoLexer.PUBLIC, + ProtoLexer.OPTION, + ProtoLexer.MESSAGE, + ProtoLexer.GROUP, + ProtoLexer.OPTIONAL, + ProtoLexer.REQUIRED, + ProtoLexer.REPEATED, + ProtoLexer.ONEOF, + ProtoLexer.EXTEND, + ProtoLexer.EXTENSIONS, + ProtoLexer.RESERVED, + ProtoLexer.TO, + ProtoLexer.MAX, + ProtoLexer.ENUM, + ProtoLexer.SERVICE, + ProtoLexer.RPC, + ProtoLexer.STREAM, + ProtoLexer.RETURNS, + ProtoLexer.MAP, + ProtoLexer.BOOLEAN_VALUE, + ProtoLexer.DOUBLE, + ProtoLexer.FLOAT, + ProtoLexer.INT32, + ProtoLexer.INT64, + ProtoLexer.UINT32, + ProtoLexer.UINT64, + ProtoLexer.SINT32, + ProtoLexer.SINT64, + ProtoLexer.FIXED32, + ProtoLexer.FIXED64, + ProtoLexer.SFIXED32, + ProtoLexer.SFIXED64, + ProtoLexer.BOOL, + ProtoLexer.STRING, + ProtoLexer.BYTES + ); - KEYWORDS = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, - ProtoLexer.PACKAGE, - ProtoLexer.SYNTAX, - ProtoLexer.IMPORT, - ProtoLexer.PUBLIC, - ProtoLexer.OPTION, - ProtoLexer.MESSAGE, - ProtoLexer.GROUP, - ProtoLexer.OPTIONAL, - ProtoLexer.REQUIRED, - ProtoLexer.REPEATED, - ProtoLexer.ONEOF, - ProtoLexer.EXTEND, - ProtoLexer.EXTENSIONS, - ProtoLexer.RESERVED, - ProtoLexer.TO, - ProtoLexer.MAX, - ProtoLexer.ENUM, - ProtoLexer.SERVICE, - ProtoLexer.RPC, - ProtoLexer.STREAM, - ProtoLexer.RETURNS, - ProtoLexer.MAP, - ProtoLexer.BOOLEAN_VALUE, - ProtoLexer.DOUBLE, - ProtoLexer.FLOAT, - ProtoLexer.INT32, - ProtoLexer.INT64, - ProtoLexer.UINT32, - ProtoLexer.UINT64, - ProtoLexer.SINT32, - ProtoLexer.SINT64, - ProtoLexer.FIXED32, - ProtoLexer.FIXED64, - ProtoLexer.SFIXED32, - ProtoLexer.SFIXED64, - ProtoLexer.BOOL, - ProtoLexer.STRING, - ProtoLexer.BYTES - ); + // tokens - ruleTypes = PSIElementTypeFactory.getRuleIElementTypes(ProtoLanguage.INSTANCE); + public static final TokenIElementType LCURLY = TOKEN_TYPES.get(ProtoLexer.LCURLY); + public static final TokenIElementType RCURLY = TOKEN_TYPES.get(ProtoLexer.RCURLY); + public static final TokenIElementType LPAREN = TOKEN_TYPES.get(ProtoLexer.LPAREN); + public static final TokenIElementType RPAREN = TOKEN_TYPES.get(ProtoLexer.RPAREN); + public static final TokenIElementType LSQUARE = TOKEN_TYPES.get(ProtoLexer.LSQUARE); + public static final TokenIElementType RSQUARE = TOKEN_TYPES.get(ProtoLexer.RSQUARE); + public static final TokenIElementType LT = TOKEN_TYPES.get(ProtoLexer.LT); + public static final TokenIElementType GT = TOKEN_TYPES.get(ProtoLexer.GT); + public static final TokenIElementType ASSIGN = TOKEN_TYPES.get(ProtoLexer.ASSIGN); - R_TYPE_REFERENCE = ruleTypes.get(ProtoParser.RULE_typeReference); - R_NAME = ruleTypes.get(ProtoParser.RULE_ident); - R_FIELD_MODIFIER = ruleTypes.get(ProtoParser.RULE_fieldModifier); + // Rules + public static final IElementType R_TYPE_REFERENCE = RULE_TYPES.get(ProtoParser.RULE_typeReference); + public static final IElementType R_NAME = RULE_TYPES.get(ProtoParser.RULE_ident); + public static final IElementType R_FIELD_MODIFIER = RULE_TYPES.get(ProtoParser.RULE_fieldModifier); + private static final IFileElementType FILE = new IFileElementType(ProtoLanguage.INSTANCE); + private static final TokenSet COMMENTS = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, COMMENT, LINE_COMMENT); + public static final TokenSet WHITESPACE = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, WS, NL); - LCURLY = tokenTypes.get(ProtoLexer.LCURLY); - RCURLY = tokenTypes.get(ProtoLexer.RCURLY); - LPAREN = tokenTypes.get(ProtoLexer.LPAREN); - RPAREN = tokenTypes.get(ProtoLexer.RPAREN); - LSQUARE = tokenTypes.get(ProtoLexer.LSQUARE); - RSQUARE = tokenTypes.get(ProtoLexer.RSQUARE); - ASSIGN = tokenTypes.get(ProtoLexer.ASSIGN); - LT = tokenTypes.get(ProtoLexer.LT); - GT = tokenTypes.get(ProtoLexer.GT); - } + private static final TokenSet STRING = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, STRING_VALUE); public static TokenIElementType token(int token) { - return tokenTypes.get(token); + return TOKEN_TYPES.get(token); } public static RuleIElementType rule(int rule) { - return ruleTypes.get(rule); + return RULE_TYPES.get(rule); } @NotNull diff --git a/src/main/java/io/protostuff/jetbrains/plugin/ProtoSyntaxHighlighter.java b/src/main/java/io/protostuff/jetbrains/plugin/ProtoSyntaxHighlighter.java index a447ae2..3a65c38 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/ProtoSyntaxHighlighter.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/ProtoSyntaxHighlighter.java @@ -37,17 +37,17 @@ */ public class ProtoSyntaxHighlighter extends SyntaxHighlighterBase { - public static final TextAttributesKey KEYWORD = + static final TextAttributesKey KEYWORD = createTextAttributesKey("PROTO_KEYWORD", DefaultLanguageHighlighterColors.KEYWORD); - public static final TextAttributesKey STRING = + static final TextAttributesKey STRING = createTextAttributesKey("PROTO_STRING", DefaultLanguageHighlighterColors.STRING); - public static final TextAttributesKey NUMBER = + static final TextAttributesKey NUMBER = createTextAttributesKey("PROTO_NUMBER", DefaultLanguageHighlighterColors.NUMBER); - public static final TextAttributesKey LINE_COMMENT = + static final TextAttributesKey LINE_COMMENT = createTextAttributesKey("PROTO_LINE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT); - public static final TextAttributesKey BLOCK_COMMENT = + static final TextAttributesKey BLOCK_COMMENT = createTextAttributesKey("PROTO_BLOCK_COMMENT", DefaultLanguageHighlighterColors.BLOCK_COMMENT); - public static final TextAttributesKey ENUM_CONSTANT = + static final TextAttributesKey ENUM_CONSTANT = createTextAttributesKey("PROTO_ENUM_CONSTANT", DefaultLanguageHighlighterColors.CONSTANT); private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0]; diff --git a/src/main/java/io/protostuff/jetbrains/plugin/ProtoSyntaxKeywordsAnnotator.java b/src/main/java/io/protostuff/jetbrains/plugin/ProtoSyntaxKeywordsAnnotator.java index 33ec272..30c1a1f 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/ProtoSyntaxKeywordsAnnotator.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/ProtoSyntaxKeywordsAnnotator.java @@ -7,6 +7,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.psi.PsiElement; +import io.protostuff.compiler.parser.ProtoParser; import io.protostuff.jetbrains.plugin.psi.EnumConstantNode; import io.protostuff.jetbrains.plugin.psi.KeywordsContainer; import org.jetbrains.annotations.NotNull; @@ -33,11 +34,9 @@ public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder hold } if (element instanceof EnumConstantNode) { ASTNode node = element.getNode(); - ASTNode name = node.findChildByType(ProtoParserDefinition.R_NAME); + ASTNode name = node.findChildByType(ProtoParserDefinition.rule(ProtoParser.RULE_enumFieldName)); if (name != null) { - // TODO: refactor, should be possible to highlight text with rule w/o finding token - PsiElement psiElement = (PsiElement) name.getFirstChildNode(); - setHighlighting(psiElement, holder, ProtoSyntaxHighlighter.ENUM_CONSTANT); + setHighlighting(name.getPsi(), holder, ProtoSyntaxHighlighter.ENUM_CONSTANT); } } } diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/EnumNode.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/EnumNode.java index d40f976..27502af 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/EnumNode.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/EnumNode.java @@ -1,14 +1,12 @@ package io.protostuff.jetbrains.plugin.psi; import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiNamedElement; +import com.intellij.navigation.ItemPresentation; import io.protostuff.compiler.parser.ProtoParser; +import io.protostuff.jetbrains.plugin.Icons; import io.protostuff.jetbrains.plugin.ProtoParserDefinition; -import org.antlr.jetbrains.adapter.psi.IdentifierDefSubtree; -import org.antlr.jetbrains.adapter.psi.ScopeNode; +import io.protostuff.jetbrains.plugin.view.structure.ProtoItemPresentation; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author Kostiantyn Shchepanovskyi @@ -20,4 +18,10 @@ public EnumNode(@NotNull ASTNode node) { super(node, ProtoParserDefinition.rule(ProtoParser.RULE_enumName)); } + @Override + public ItemPresentation getPresentation() { + String fullName = getFullName(); + return new ProtoItemPresentation(fullName, Icons.ENUM); + } + } \ No newline at end of file diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/FieldNode.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/FieldNode.java index aa0a780..8fb46bd 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/FieldNode.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/FieldNode.java @@ -4,7 +4,6 @@ import com.intellij.psi.PsiElement; import io.protostuff.compiler.parser.ProtoParser; import io.protostuff.jetbrains.plugin.ProtoParserDefinition; -import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode; import org.antlr.jetbrains.adapter.psi.IdentifierDefSubtree; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/ImportNode.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/ImportNode.java index 18407ef..5d555fb 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/ImportNode.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/ImportNode.java @@ -32,7 +32,7 @@ public ProtoRootNode getTargetProto() { return fileRoot.findChildByClass(ProtoRootNode.class); } return null; - } + } public boolean isPublic() { return findChildrenByType(ProtoParserDefinition.token(ProtoLexer.PUBLIC)) != null; diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNameNode.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNameNode.java index d694259..1b4e7a6 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNameNode.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNameNode.java @@ -1,8 +1,6 @@ package io.protostuff.jetbrains.plugin.psi; import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiReference; -import io.protostuff.jetbrains.plugin.reference.TypeReference; import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNode.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNode.java index 64b0261..7bb3bd8 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNode.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/MessageNode.java @@ -1,15 +1,12 @@ package io.protostuff.jetbrains.plugin.psi; import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiNamedElement; -import com.intellij.util.IncorrectOperationException; +import com.intellij.navigation.ItemPresentation; import io.protostuff.compiler.parser.ProtoParser; +import io.protostuff.jetbrains.plugin.Icons; import io.protostuff.jetbrains.plugin.ProtoParserDefinition; -import org.antlr.jetbrains.adapter.psi.IdentifierDefSubtree; -import org.antlr.jetbrains.adapter.psi.ScopeNode; +import io.protostuff.jetbrains.plugin.view.structure.ProtoItemPresentation; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collection; @@ -33,7 +30,6 @@ public String getName() { } - @Override public String getNamespace() { return getQualifiedName() + "."; @@ -43,4 +39,11 @@ public String getNamespace() { public Collection getChildrenTypes() { return Arrays.asList(findChildrenByClass(UserType.class)); } + + @Override + public ItemPresentation getPresentation() { + String fullName = getFullName(); + return new ProtoItemPresentation(fullName, Icons.MESSAGE); + } + } \ No newline at end of file diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/PackageStatement.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/PackageStatement.java index aeb9b84..3d3efa7 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/PackageStatement.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/PackageStatement.java @@ -3,12 +3,9 @@ import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import io.protostuff.compiler.parser.ProtoParser; -import io.protostuff.jetbrains.plugin.ProtoParserDefinition; import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode; import org.jetbrains.annotations.NotNull; -import java.util.List; - import static io.protostuff.jetbrains.plugin.ProtoParserDefinition.rule; /** diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/ProtoRootNode.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/ProtoRootNode.java index 2339067..21ed8b8 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/ProtoRootNode.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/ProtoRootNode.java @@ -1,8 +1,6 @@ package io.protostuff.jetbrains.plugin.psi; import com.intellij.lang.ASTNode; -import com.intellij.openapi.diagnostic.Logger; -import io.protostuff.compiler.model.*; import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/RpcMethodNode.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/RpcMethodNode.java index c661004..7dee0e0 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/RpcMethodNode.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/RpcMethodNode.java @@ -3,12 +3,9 @@ import com.intellij.lang.ASTNode; import io.protostuff.compiler.parser.ProtoParser; import io.protostuff.jetbrains.plugin.ProtoParserDefinition; -import org.antlr.jetbrains.adapter.psi.ANTLRPsiNode; import org.antlr.jetbrains.adapter.psi.IdentifierDefSubtree; import org.jetbrains.annotations.NotNull; -import static io.protostuff.jetbrains.plugin.ProtoParserDefinition.R_NAME; - /** * @author Kostiantyn Shchepanovskyi */ diff --git a/src/main/java/io/protostuff/jetbrains/plugin/psi/UserType.java b/src/main/java/io/protostuff/jetbrains/plugin/psi/UserType.java index 88687a0..590f0da 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/psi/UserType.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/psi/UserType.java @@ -5,7 +5,6 @@ import com.intellij.psi.PsiNamedElement; import com.intellij.psi.tree.IElementType; import com.intellij.util.IncorrectOperationException; -import io.protostuff.jetbrains.plugin.ProtoParserDefinition; import org.antlr.jetbrains.adapter.psi.IdentifierDefSubtree; import org.antlr.jetbrains.adapter.psi.ScopeNode; import org.jetbrains.annotations.NotNull; @@ -44,6 +43,13 @@ public String getQualifiedName() { + parent.getClass().getName()); } + /** + * Returns full name of this type without leading dot. + */ + public String getFullName() { + return getQualifiedName().substring(1); + } + @Nullable @Override public PsiElement resolve(PsiNamedElement element) { diff --git a/src/main/java/io/protostuff/jetbrains/plugin/view/structure/ProtoItemPresentation.java b/src/main/java/io/protostuff/jetbrains/plugin/view/structure/ProtoItemPresentation.java index 9a53695..1f7cdf6 100644 --- a/src/main/java/io/protostuff/jetbrains/plugin/view/structure/ProtoItemPresentation.java +++ b/src/main/java/io/protostuff/jetbrains/plugin/view/structure/ProtoItemPresentation.java @@ -8,12 +8,12 @@ /** * @author Kostiantyn Shchepanovskyi */ -final class ProtoItemPresentation implements ItemPresentation { +public final class ProtoItemPresentation implements ItemPresentation { private final String name; private final Icon icon; - ProtoItemPresentation(String name, Icon icon) { + public ProtoItemPresentation(String name, Icon icon) { this.name = name; this.icon = icon; } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index f6b6e1b..61c73d7 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -87,6 +87,8 @@ + diff --git a/src/test/java/io/protostuff/jetbrains/plugin/reference/FindUsagesTest.java b/src/test/java/io/protostuff/jetbrains/plugin/reference/FindUsagesTest.java new file mode 100644 index 0000000..70597d3 --- /dev/null +++ b/src/test/java/io/protostuff/jetbrains/plugin/reference/FindUsagesTest.java @@ -0,0 +1,24 @@ +package io.protostuff.jetbrains.plugin.reference; + +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.usageView.UsageInfo; + +import java.util.Collection; + +/** + * @author Kostiantyn Shchepanovskyi + */ +@SuppressWarnings("ConstantConditions") +public class FindUsagesTest extends LightCodeInsightFixtureTestCase { + + @Override + protected String getTestDataPath() { + return "src/test/resources/reference"; + } + + public void testFindUsages() { + Collection usageInfos = myFixture.testFindUsages("FindUsagesTestData.proto"); + assertEquals(2, usageInfos.size()); + } + +} diff --git a/src/test/resources/reference/FindUsagesTestData.proto b/src/test/resources/reference/FindUsagesTestData.proto new file mode 100644 index 0000000..0796c0e --- /dev/null +++ b/src/test/resources/reference/FindUsagesTestData.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package reference; + +message MessageA { + +} + +message TestMessage { + MessageA firstUsage = 1; + MessageA secondUsage = 2; +} \ No newline at end of file