Skip to content

Commit

Permalink
Implement {element} and {@State}
Browse files Browse the repository at this point in the history
Partly fixes google#172
  • Loading branch information
Alexander Pavlov committed Jan 8, 2020
1 parent 5398f3a commit e6f60d7
Show file tree
Hide file tree
Showing 29 changed files with 968 additions and 90 deletions.
8 changes: 3 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ buildscript {
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
classpath "com.github.hurricup:gradle-grammar-kit-plugin:2017.1.1"
}
}

plugins {
id 'org.jetbrains.intellij' version '0.2.17'
id 'org.jetbrains.grammarkit' version '2019.2'
id 'org.jetbrains.intellij' version '0.4.15'
id 'org.jetbrains.kotlin.jvm' version '1.2.10'
}

Expand All @@ -24,7 +22,7 @@ dependencies {
}

intellij {
version 'IC-2017.1.5'
version 'IC-2019.2'
updateSinceUntilBuild false
}

Expand Down
67 changes: 49 additions & 18 deletions src/main/grammars/Soy.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
elementTypeClass="com.google.bamboo.soy.parser.SoyElementType"
tokenTypeClass="com.google.bamboo.soy.lexer.SoyTokenType"

implements("Begin.*|.*Tag|.*Block")="com.google.bamboo.soy.elements.TagElement"
implements("Begin.*|.*Tag|(Namespace|Alias|DelegatePackage)Block")="com.google.bamboo.soy.elements.TagElement"
implements("(Css|LetSingle|SpecialCharacter|Xid|Print)Statement")
= ["com.google.bamboo.soy.elements.StatementElement" "com.google.bamboo.soy.elements.TagElement"]
implements("LiteralStatement") = ["com.google.bamboo.soy.elements.StatementElement"]
implements(".*Statement")
implements("(Call|Choice|For|Foreach|If|LetCompound|Literal|Msg)Statement")
= ["com.google.bamboo.soy.elements.StatementElement" "com.google.bamboo.soy.elements.TagBlockElement"]

extends(".*Expr|VariableReferenceIdentifier")=Expr
Expand All @@ -31,6 +31,7 @@
AS = "as"
AT_PARAM = "@param"
AT_PARAM_OPT = "@param?"
AT_STATE = "@state"
AT_INJECT = "@inject"
AT_INJECT_OPT = "@inject?"
BOOL_LITERAL = "regexp:false|true"
Expand All @@ -39,6 +40,7 @@
CARRIAGE_RETURN = "\\r"
CASE = "case"
COLON = ":"
COLON_EQUAL = ":="
COMMA = ","
CSS="css"
DEFAULT = "default"
Expand All @@ -48,6 +50,7 @@
DOLLAR = "$"
DOT = "."
DOT_NULL_CHECK = "?."
ELEMENT = "element"
ELSE = "else"
ELSEIF = "elseif"
EQUAL = "="
Expand Down Expand Up @@ -340,13 +343,14 @@ private AliasBody ::= ALIAS NamespaceIdentifier [AS AliasIdentifier] {

// Template block

TemplateBlock ::= LocalTemplateBlock | DelegateTemplateBlock {
TemplateBlock ::= LocalTemplateBlock | DelegateTemplateBlock | LocalElementBlock {
mixin="com.google.bamboo.soy.elements.impl.TemplateBlockMixin"
implements="com.google.bamboo.soy.elements.TemplateBlockElement"
stubClass = "com.google.bamboo.soy.stubs.TemplateBlockStub"
elementTypeFactory = "com.google.bamboo.soy.stubs.StubFactory.getType"
}

private LocalElementBlock ::= <<AbstractElementBlock ELEMENT>>
private LocalTemplateBlock ::= <<AbstractTemplateBlock TEMPLATE>>
private DelegateTemplateBlock ::= <<AbstractTemplateBlock DELTEMPLATE>>

Expand All @@ -358,6 +362,14 @@ private meta AbstractTemplateBlock ::=
pin = 1
}

private meta AbstractElementBlock ::=
<<BeginTemplate <<p>>>>
[AtParamOrStateList]
[<<StatementList !()>>]
<<EndTag <<p>>>> {
pin = 1
}

meta BeginTemplate ::= <<BracedTag <<BeginTemplateBody<<p>>>>>> {
hooks = [wsBinders = "LEADING_COMMENTS_BINDER, TRAILING_COMMENTS_BINDER"]
}
Expand All @@ -369,6 +381,8 @@ private meta BeginTemplateBody ::= <<p>> (TemplateDefinitionIdentifier [Attribut

private AtParamList ::= (AtParamSingle | AtInjectSingle)+

private AtParamOrStateList ::= (AtParamSingle | AtInjectSingle | AtStateSingle)+

AtParamSingle ::= <<BracedTag AtParamBody>> {
implements = "com.google.bamboo.soy.elements.AtParamElement"
mixin = "com.google.bamboo.soy.elements.impl.AtParamMixin"
Expand All @@ -382,6 +396,19 @@ private AtParamBody ::= (AT_PARAM | AT_PARAM_OPT) ParamDefinitionIdentifier COLO
recoverWhile = "recoverEndOfTag"
}

AtStateSingle ::= <<BracedTag AtStateBody>> {
implements = "com.google.bamboo.soy.elements.AtStateElement"
mixin = "com.google.bamboo.soy.elements.impl.AtStateMixin"
stubClass = "com.google.bamboo.soy.stubs.AtStateStub"
elementTypeFactory = "com.google.bamboo.soy.stubs.StubFactory.getType"
hooks = [wsBinders = "LEADING_COMMENTS_BINDER, TRAILING_COMMENTS_BINDER"]
}

private AtStateBody ::= (AT_STATE) ParamDefinitionIdentifier (COLON TypeExpression EQUAL Expr | COLON_EQUAL Expr) {
pin = 1
recoverWhile = "recoverEndOfTag"
}

AtInjectSingle ::= <<BracedTag AtInjectBody>> {
implements = "com.google.bamboo.soy.elements.AtInjectElement"
mixin = "com.google.bamboo.soy.elements.impl.AtInjectMixin"
Expand Down Expand Up @@ -430,6 +457,24 @@ private Content ::= OTHER
private Statement ::=
SingleTagStatement
|
BlockTagStatement
|
Content


private SingleTagStatement ::=
CssStatement
|
LetSingleStatement
|
SpecialCharacterStatement
|
XidStatement
|
PrintStatement


private BlockTagStatement ::=
CallStatement
|
ChoiceStatement
Expand All @@ -445,20 +490,6 @@ private Statement ::=
LiteralStatement
|
MsgStatement
|
Content


private SingleTagStatement ::=
CssStatement
|
LetSingleStatement
|
SpecialCharacterStatement
|
XidStatement
|
PrintStatement


// Same as StatementList but cannot empty.
Expand Down Expand Up @@ -616,7 +647,7 @@ private ParamList ::=
recoverWhile = "!(endOfStatementBlock)"
}

ParamListElement ::= !<<ClosedBracedTag BeginParamTagBody>> BlockParamListElement | BeginParamTag {
ParamListElement ::= !(<<ClosedBracedTag BeginParamTagBody>>) BlockParamListElement | BeginParamTag {
implements = "com.google.bamboo.soy.elements.ParamElement"
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/grammars/Soy.flex
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ NonSemantical=({WhiteSpace}|{DoubleSlashComment}|{DocComment}|{Comment})*
"deltemplate"/{NonSemantical}{QualifiedIdentifier} { yybegin(TAG_QUALIFIED_IDENTIFIER); return SoyTypes.DELTEMPLATE; }
"namespace"/{NonSemantical}{QualifiedIdentifier} { yybegin(TAG_QUALIFIED_IDENTIFIER); return SoyTypes.NAMESPACE; }
"template"/{NonSemantical}{QualifiedIdentifier} { yybegin(TAG_QUALIFIED_IDENTIFIER); return SoyTypes.TEMPLATE; }
"element"/{NonSemantical}{QualifiedIdentifier} { yybegin(TAG_QUALIFIED_IDENTIFIER); return SoyTypes.ELEMENT; }

"alias" { return SoyTypes.ALIAS; }
"call" { return SoyTypes.CALL; }
"delcall" { return SoyTypes.DELCALL; }
"delpackage" { return SoyTypes.DELPACKAGE; }
"deltemplate" { return SoyTypes.DELTEMPLATE; }
"element" { return SoyTypes.ELEMENT; }
"namespace" { return SoyTypes.NAMESPACE; }
"template" { return SoyTypes.TEMPLATE; }

Expand All @@ -136,6 +138,7 @@ NonSemantical=({WhiteSpace}|{DoubleSlashComment}|{DocComment}|{Comment})*
"@inject?" { return SoyTypes.AT_INJECT_OPT; }
"@param" { return SoyTypes.AT_PARAM; }
"@param?" { return SoyTypes.AT_PARAM_OPT; }
"@state" { return SoyTypes.AT_STATE; }
"case" { return SoyTypes.CASE; }
"default" { return SoyTypes.DEFAULT; }

Expand Down Expand Up @@ -210,6 +213,7 @@ NonSemantical=({WhiteSpace}|{DoubleSlashComment}|{DocComment}|{Comment})*

"=" { return SoyTypes.EQUAL; }
":" { return SoyTypes.COLON; }
":=" { return SoyTypes.COLON_EQUAL; }
"?" { return SoyTypes.QUESTIONMARK; }
"?:" { return SoyTypes.TERNARY_COALESCER; }

Expand Down
31 changes: 30 additions & 1 deletion src/main/java/com/google/bamboo/soy/SoyFindUsagesProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@
package com.google.bamboo.soy;

import com.google.bamboo.soy.lexer.SoyLexer;
import com.google.bamboo.soy.parser.SoyAtInjectSingle;
import com.google.bamboo.soy.parser.SoyAtParamSingle;
import com.google.bamboo.soy.parser.SoyAtStateSingle;
import com.google.bamboo.soy.parser.SoyBeginLet;
import com.google.bamboo.soy.parser.SoyBeginTemplate;
import com.google.bamboo.soy.parser.SoyLetSingleStatement;
import com.google.bamboo.soy.parser.SoyNamespaceDeclarationIdentifier;
import com.google.bamboo.soy.parser.SoyTypes;
import com.google.bamboo.soy.parser.SoyVariableDefinitionIdentifier;
import com.intellij.lang.cacheBuilder.DefaultWordsScanner;
import com.intellij.lang.cacheBuilder.WordsScanner;
import com.intellij.lang.findUsages.FindUsagesProvider;
Expand All @@ -26,6 +34,7 @@
import org.jetbrains.annotations.Nullable;

public class SoyFindUsagesProvider implements FindUsagesProvider {

@Nullable
@Override
public WordsScanner getWordsScanner() {
Expand All @@ -50,6 +59,26 @@ public String getHelpId(@NotNull PsiElement psiElement) {
@NotNull
@Override
public String getType(@NotNull PsiElement psiElement) {
if (psiElement instanceof SoyVariableDefinitionIdentifier) {
return "Variable"; // for/foreach/let
}
PsiElement parent = psiElement.getParent();
if (parent instanceof SoyAtParamSingle) {
return "Parameter";
}
if (parent instanceof SoyAtStateSingle) {
return "State param";
}
if (parent instanceof SoyAtInjectSingle) {
return "Injected param";
}
if (parent instanceof SoyNamespaceDeclarationIdentifier) {
return "Namespace";
}
if (parent instanceof SoyBeginTemplate) {
return ((SoyBeginTemplate) parent).getTagNameTokenType() == SoyTypes.ELEMENT
? "Element" : "Template";
}
return "";
}

Expand All @@ -62,6 +91,6 @@ public String getDescriptiveName(@NotNull PsiElement psiElement) {
@NotNull
@Override
public String getNodeText(@NotNull PsiElement psiElement, boolean useFullName) {
return "";
return psiElement.getText();
}
}
60 changes: 60 additions & 0 deletions src/main/java/com/google/bamboo/soy/elements/AtStateElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.bamboo.soy.elements;

import com.google.bamboo.soy.lang.Parameter;
import com.google.bamboo.soy.lang.StateVariable;
import com.google.bamboo.soy.parser.SoyParamDefinitionIdentifier;
import com.google.bamboo.soy.parser.SoyTypeExpression;
import com.google.bamboo.soy.parser.SoyTypes;
import com.google.bamboo.soy.stubs.AtParamStub;
import com.google.bamboo.soy.stubs.AtStateStub;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.StubBasedPsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public interface AtStateElement extends StubBasedPsiElement<AtStateStub>, PsiNamedElement,
TagElement {

@Nullable
SoyParamDefinitionIdentifier getParamDefinitionIdentifier();

@Nullable
SoyTypeExpression getTypeExpression();

default PsiElement setName(@NotNull String s) throws IncorrectOperationException {
return null;
}

@NotNull
default String getType() {
if (getStub() != null) {
return getStub().type;
}
if (getTypeExpression() != null) {
return getTypeExpression().getText();
}
return "";
}

default StateVariable toStateVariable() {
return this.getParamDefinitionIdentifier() == null
? null
: new StateVariable(getName(), getType(), this.getParamDefinitionIdentifier());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.bamboo.soy.lang.Variable;
import com.google.bamboo.soy.parser.SoyAtInjectSingle;
import com.google.bamboo.soy.parser.SoyAtParamSingle;
import com.google.bamboo.soy.parser.SoyAtStateSingle;
import com.google.bamboo.soy.parser.SoyTemplateDefinitionIdentifier;
import com.google.bamboo.soy.parser.SoyTypes;
import com.google.bamboo.soy.stubs.TemplateBlockStub;
Expand Down Expand Up @@ -46,6 +47,9 @@ public interface TemplateBlockElement
@NotNull
List<SoyAtParamSingle> getAtParamSingleList();

@NotNull
List<SoyAtStateSingle> getAtStateSingleList();

@Override
default PsiElement setName(@NotNull String s) throws IncorrectOperationException {
return null;
Expand Down Expand Up @@ -84,6 +88,7 @@ default List<Variable> getLocalVariables() {
List<Variable> variables = new ArrayList<>();
variables.addAll(getParameters());
variables.addAll(getInjectedVariables());
variables.addAll(getStateVariables());
return variables;
}

Expand All @@ -94,4 +99,12 @@ default List<Variable> getInjectedVariables() {
.filter(Objects::nonNull)
.collect(Collectors.toList());
}

default List<Variable> getStateVariables() {
return getAtStateSingleList()
.stream()
.map(SoyAtStateSingle::toStateVariable)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}
Loading

0 comments on commit e6f60d7

Please sign in to comment.