Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Google Protocol Buffers support for JetBrains IDEs
## Protobuf Support for JetBrains IDEs

[Protobuf Support Plugin](https://plugins.jetbrains.com/plugin/8277) for IntelliJ IDEA & other JetBrains products.

Expand Down
20 changes: 9 additions & 11 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ buildscript {

plugins {
id "org.jetbrains.intellij" version "0.0.43"
id "com.jfrog.bintray" version "1.6"
}

group = 'org.antlr'
description = 'Support for using ANTLR-generated parsers/lexers in jetbrains IDE plug-ins.'
group = 'io.protostuff'
description = 'Protobuf Plugin for JetBrains IDEs'

repositories {
jcenter()
Expand All @@ -21,13 +20,11 @@ repositories {
}
}

apply plugin: 'antlr'

dependencies {
compile 'org.antlr:antlr4-runtime:4.5.1'
compile 'org.antlr:antlr4-jetbrains-adapter:1.0.0'
antlr 'org.antlr:antlr4:4.5'
compile 'io.protostuff:protostuff-parser:2.0.0-alpha12'
compile 'com.google.guava:guava:19.0'
compile 'io.protostuff:protostuff-parser:2.0.0-alpha17-SNAPSHOT'
}

apply plugin: 'idea'
Expand All @@ -36,16 +33,17 @@ idea {
jdkName = javaVersion
languageLevel = javaVersion
}
module {
generatedSourceDirs += file('gen')
}
}

apply plugin: 'org.jetbrains.intellij'
intellij {
version = ideaVersion
updateSinceUntilBuild = false

// TODO: we do not need dependency on this plugin in runtime
// TODO: should be removed, but then tests are failing with
// TODO: ERROR: java.lang.ClassNotFoundException: com.intellij.lang.properties.PropertiesFileTypeFactory
plugins 'properties'
// downloadSources = false
publish {
username = project.hasProperty('jetbrainsUser') \
? project.property('jetbrainsUser') \
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Available idea versions:
# https://www.jetbrains.com/intellij-repository/releases
# https://www.jetbrains.com/intellij-repository/snapshots
version=0.2.0
version=0.3.0-SNAPSHOT
ideaVersion=145.258.11
# https://intellij-support.jetbrains.com/hc/en-us/articles/206544879-Selecting-the-JDK-version-the-IDE-will-run-under
# Java 8 is required to run IntelliJ IDEA starting from version 16
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,29 @@ public class ProtoParserDefinition implements ParserDefinition {
public static final TokenIElementType RSQUARE;
public static final TokenIElementType LT;
public static final TokenIElementType GT;
public static final TokenIElementType ASSIGN;

// 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;
private static final TokenSet WHITESPACE;
private static final TokenSet STRING;
public static final TokenSet WHITESPACE;

private static final TokenSet STRING;

private static List<TokenIElementType> tokenTypes;
private static List<RuleIElementType> ruleTypes;

static {
PSIElementTypeFactory.defineLanguageIElementTypes(ProtoLanguage.INSTANCE,
ProtoParser.tokenNames, ProtoParser.ruleNames);
List<TokenIElementType> tokenTypes =
PSIElementTypeFactory.getTokenIElementTypes(ProtoLanguage.INSTANCE);
tokenTypes = PSIElementTypeFactory.getTokenIElementTypes(ProtoLanguage.INSTANCE);
ID = tokenTypes.get(ProtoLexer.NAME);
FILE = new IFileElementType(ProtoLanguage.INSTANCE);
COMMENTS = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, COMMENT, LINE_COMMENT);
WHITESPACE = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, WS);
WHITESPACE = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, WS, NL);
STRING = PSIElementTypeFactory.createTokenSet(ProtoLanguage.INSTANCE, STRING_VALUE);


Expand Down Expand Up @@ -111,7 +113,7 @@ public class ProtoParserDefinition implements ParserDefinition {
ProtoLexer.BYTES
);

List<RuleIElementType> ruleTypes = PSIElementTypeFactory.getRuleIElementTypes(ProtoLanguage.INSTANCE);
ruleTypes = PSIElementTypeFactory.getRuleIElementTypes(ProtoLanguage.INSTANCE);

R_TYPE_REFERENCE = ruleTypes.get(ProtoParser.RULE_typeReference);
R_NAME = ruleTypes.get(ProtoParser.RULE_name);
Expand All @@ -123,10 +125,19 @@ public class ProtoParserDefinition implements ParserDefinition {
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);
}

public static TokenIElementType token(int token) {
return tokenTypes.get(token);
}

public static RuleIElementType rule(int rule) {
return ruleTypes.get(rule);
}

@NotNull
@Override
public Lexer createLexer(Project project) {
Expand Down Expand Up @@ -229,14 +240,6 @@ public PsiElement createElement(ASTNode node) {
return new RpcMethodTypeNode(node);
case ProtoParser.RULE_proto:
return new ProtoRootNode(node);
case ProtoParser.RULE_statement:
return new ProtoRootStatementNode(node);
case ProtoParser.RULE_messageBlockEntry:
return new MessageBlockEntryNode(node);
case ProtoParser.RULE_enumBlockEntry:
return new EnumBlockEntryNode(node);
case ProtoParser.RULE_serviceBlockEntry:
return new ServiceBlockEntryNode(node);
default:
return new ANTLRPsiNode(node);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package io.protostuff.jetbrains.plugin.formatter;

import com.intellij.formatting.Alignment;
import com.intellij.formatting.Block;
import com.intellij.formatting.Indent;
import com.intellij.lang.ASTNode;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;

import java.util.HashMap;
import java.util.Map;

import static io.protostuff.compiler.parser.ProtoParser.*;
import static io.protostuff.jetbrains.plugin.ProtoParserDefinition.rule;

/**
* @author Kostiantyn Shchepanovskyi
*/
class BlockFactory {

static final Map<IElementType, Factory> registry = new HashMap<>();

static {
Factory FAIL_ROOT_NODE = (node, alignment, indent, settings) -> {
throw new IllegalStateException("Root node cannot be handled here");
};
register(rule(RULE_proto), FAIL_ROOT_NODE);
register(rule(RULE_packageName), LeafBlock::new);
register(rule(RULE_rpcType), LeafBlock::new);
register(rule(RULE_name), LeafBlock::new);
register(rule(RULE_mapKey), LeafBlock::new);
register(rule(RULE_mapValue), LeafBlock::new);
register(rule(RULE_tag), LeafBlock::new);
register(rule(RULE_fieldName), LeafBlock::new);
register(rule(RULE_textFormatOptionName), LeafBlock::new);
register(rule(RULE_textFormatOptionValue), LeafBlock::new);
register(rule(RULE_optionName), LeafBlock::new);
register(rule(RULE_optionValue), LeafBlock::new);
register(rule(RULE_fieldModifier), LeafBlock::new);
register(rule(RULE_typeReference), LeafBlock::new);
register(rule(RULE_ranges), StatementBlock::new);
register(rule(RULE_range), StatementBlock::new);
register(rule(RULE_reserved), StatementBlock::new);
register(rule(RULE_fieldNames), StatementBlock::new);
register(rule(RULE_fieldOptions), StatementBlock::new);
register(rule(RULE_map), StatementBlock::new);
register(rule(RULE_syntax), StatementBlock::new);
register(rule(RULE_packageStatement), StatementBlock::new);
register(rule(RULE_importStatement), StatementBlock::new);
register(rule(RULE_optionEntry), StatementBlock::new);
register(rule(RULE_option), StatementBlock::new);
register(rule(RULE_messageBlock), ParentBlock::new);
register(rule(RULE_textFormat), ParentBlock::new);
register(rule(RULE_textFormatEntry), ParentBlock::new);
register(rule(RULE_field), StatementBlock::new);
register(rule(RULE_enumBlock), ParentBlock::new);
register(rule(RULE_enumConstant), StatementBlock::new);
register(rule(RULE_serviceBlock), ParentBlock::new);
register(rule(RULE_rpcMethod), ParentBlock::new);
register(rule(RULE_extendBlock), ParentBlock::new);
register(rule(RULE_extendBlockEntry), StatementBlock::new);
register(rule(RULE_oneof), ParentBlock::new);
register(rule(RULE_oneofField), StatementBlock::new);
register(rule(RULE_oneofGroup), ParentBlock::new);
register(rule(RULE_groupBlock), ParentBlock::new);
register(rule(RULE_extensions), StatementBlock::new);
}

private static void register(IElementType elementType, Factory factory) {
if (registry.containsKey(elementType)) {
throw new IllegalStateException("Already registered: " + elementType);
}
registry.put(elementType, factory);
}

static Block createBlock(ASTNode node, Alignment alignment, Indent indent, CodeStyleSettings settings) {
Factory factory = registry.get(node.getElementType());
if (factory == null) {
// If element type is unknown it is best to keep existing formatting
return createLeaf(node, alignment, indent, settings);
}
return factory.create(node, alignment, indent, settings);
}

@NotNull
private static LeafBlock createLeaf(ASTNode node, Alignment alignment, Indent indent, CodeStyleSettings settings) {
return new LeafBlock(node, alignment, indent, settings);
}

interface Factory {
Block create(ASTNode node, Alignment alignment, Indent indent, CodeStyleSettings settings);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package io.protostuff.jetbrains.plugin.formatter;

import com.intellij.formatting.*;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import io.protostuff.jetbrains.plugin.ProtoLanguage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static io.protostuff.jetbrains.plugin.formatter.StatementBlock.*;
/**
* @author Kostiantyn Shchepanovskyi
*/
public class FormattingModelBuilder implements com.intellij.formatting.FormattingModelBuilder {

@NotNull
@Override
public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
PsiFile containingFile = element.getContainingFile().getViewProvider().getPsi(ProtoLanguage.INSTANCE);
ASTNode fileNode = containingFile.getNode();
Wrap wrap = Wrap.createWrap(WrapType.NONE, false);
Alignment alignment = Alignment.createAlignment();
ProtoFileBlock block = new ProtoFileBlock(fileNode, wrap, alignment, settings);
return FormattingModelProvider.createFormattingModelForPsiFile(containingFile, block, settings);
}

@Nullable
@Override
public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) {
return null;
}

public static SpacingBuilder createSpacingBuilder(CodeStyleSettings settings) {
CommonCodeStyleSettings protoSettings = settings.getCommonSettings(ProtoLanguage.INSTANCE);
return new SpacingBuilder(settings, ProtoLanguage.INSTANCE)
.around(ASSIGN).spaceIf(protoSettings.SPACE_AROUND_ASSIGNMENT_OPERATORS)
.before(SEMICOLON).spaceIf(protoSettings.SPACE_BEFORE_SEMICOLON)
.after(LINE_COMMENT).spacing(0, 0, 1, true, 2)
.after(LCURLY).spacing(0, 0, 1, true, 2)
.before(RCURLY).spacing(0, 0, 1, true, 2)
.after(LPAREN).spacing(0, 0, 0, false, 0)
.before(RPAREN).spacing(0, 0, 0, false, 0)
.after(LSQUARE).spacing(0, 0, 0, false, 0)
.before(RSQUARE).spacing(0, 0, 0, false, 0)
.before(LT).spacing(0, 0, 0, false, 0)
.after(LT).spacing(0, 0, 0, false, 0)
.before(GT).spacing(0, 0, 0, false, 0)
.before(COMMA).spacing(0, 0, 0, false, 0)
.before(SEMICOLON).spacing(0, 0, 0, false, 0)
.after(COMMA).spacing(1, 1, 0, false, 0);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.protostuff.jetbrains.plugin.formatter;

import com.intellij.formatting.*;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.List;

class LeafBlock implements ASTBlock {
private final ASTNode node;
private final Alignment alignment;
private final Indent myIndent;

LeafBlock(ASTNode node, Alignment alignment, Indent indent, CodeStyleSettings settings) {
this.node = node;
this.alignment = alignment;
myIndent = indent;
}

@Override
public ASTNode getNode() {
return node;
}

@Override
@NotNull
public TextRange getTextRange() {
return node.getTextRange();
}

@Override
@NotNull
public List<Block> getSubBlocks() {
return Collections.emptyList();
}

@Override
public Wrap getWrap() {
return null;
}

@Override
public Indent getIndent() {
return myIndent;
}

@Override
public Alignment getAlignment() {
return alignment;
}

@Override
public Spacing getSpacing(Block child1, @NotNull Block child2) {
return null;
}

@Override
@NotNull
public ChildAttributes getChildAttributes(final int newChildIndex) {
return new ChildAttributes(getIndent(), null);
}

@Override
public boolean isIncomplete() {
return false;
}

@Override
public boolean isLeaf() {
return true;
}

}
Loading