Skip to content

Commit

Permalink
Release 2.3 (#184)
Browse files Browse the repository at this point in the history
### Added

- Support for the latest Tact
  1.4.0 ([#177](#177), [#180](#180))
- Inspections for out of range integer values in FunC and Tact
- Inspections for integer division by zero in FunC and Tact
- Inspections for integer overflow in FunC
- Constant expression evaluation in FunC and Tact (with inline
  hints!) ([#22](#22))

### Fixed

- `message` and `bounced` highlight not working in Tact ([#174](#174))
- `com.intellij.diagnostic.PluginException: Template not found: Fift File` ([#182](#182))
- `Storage for FuncNamedElementIndex.storage is already registered` ([#181](#181))
  • Loading branch information
andreypfau authored Jul 15, 2024
1 parent ed130d0 commit c4fde77
Show file tree
Hide file tree
Showing 79 changed files with 2,227 additions and 380 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# TON Plugin for the IntelliJ IDEs Changelog

## [2.3.0]

### Added

- Support for the latest Tact
1.4.0 ([#177](https://github.com/ton-blockchain/intellij-ton/issues/177), [#180](https://github.com/ton-blockchain/intellij-ton/issues/180))
- Inspections for out of range integer values in FunC and Tact
- Inspections for integer division by zero in FunC and Tact
- Inspections for integer overflow in FunC
- Constant expression evaluation in FunC and Tact (with inline
hints!) ([#22](https://github.com/ton-blockchain/intellij-ton/issues/22))

### Fixed

- `message` and `bounced` highlight not working in Tact ([#174](https://github.com/ton-blockchain/intellij-ton/issues/174))
- `com.intellij.diagnostic.PluginException: Template not found: Fift File` ([#182](https://github.com/ton-blockchain/intellij-ton/issues/182))
- `Storage for FuncNamedElementIndex.storage is already registered` ([#181](https://github.com/ton-blockchain/intellij-ton/issues/181))

## [2.2.0]

### Added
Expand Down Expand Up @@ -54,6 +72,7 @@
## [1.0.3]

### Added

- Support try-catch statements

## [1.0.2]
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
org.gradle.jvmargs=-Xmx4096m
pluginGroup=org.ton
pluginVersion=2.2.1
publishChannel=release
pluginVersion=2.3
publishChannel=stable
publishToken=token
enableBuildSearchableOptions=false
# Existent IDE versions can be found in the following repos:
Expand Down
4 changes: 3 additions & 1 deletion src/main/grammar/FuncParser.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,9 @@ fake BinExpression ::= Expression BinaryOp Expression {
}

//noinspection BnfUnusedRule
fake BinaryOp ::= '=' | '+=' | '-=' | '*=' | '/=' | '~/=' | '^/=' | '%=' | '~%=' | '^%=' | '<<=' | '>>=' | '^>>=' | '~>>=' | '&=' | '|=' | '^='
fake BinaryOp ::= '=' | '+=' | '-=' | '*=' | '/=' | '~/=' | '^/=' | '%=' | '~%=' | '^%='
| '<<=' | '>>=' | '^>>=' | '~>>='
| '&=' | '|=' | '^='
| '==' | '!='
| '<' | '>' | '<=' | '>=' | '<=>'
| '<<' | '>>' | '~>>' | '^>>'
Expand Down
282 changes: 185 additions & 97 deletions src/main/grammar/TactLexer.flex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.ton.intellij.tact.parser;

import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.containers.Stack;

import static com.intellij.psi.TokenType.BAD_CHARACTER;
import static com.intellij.psi.TokenType.WHITE_SPACE;
Expand Down Expand Up @@ -31,12 +32,13 @@ import static org.ton.intellij.tact.psi.TactElementTypes.*;
private int zzParenDepth = 0;
private boolean zzStructScope = false;
private boolean zzContractScope = false;
private boolean zzStructIdentifierExpected = false;
%}

%{
IElementType imbueBlockComment() {
assert(zzNestedCommentLevel == 0);
yybegin(YYINITIAL);
popState();

zzStartRead = zzPostponedMarkedPos;
zzPostponedMarkedPos = -1;
Expand All @@ -59,8 +61,45 @@ import static org.ton.intellij.tact.psi.TactElementTypes.*;
%function advance
%type IElementType

%{
private static final class State {
final int lBraceCount;
final int state;

public State(int state, int lBraceCount) {
this.state = state;
this.lBraceCount = lBraceCount;
}

@Override
public String toString() {
return "yystate = " + state + (lBraceCount == 0 ? "" : "lBraceCount = " + lBraceCount);
}
}

private final Stack<State> states = new Stack<State>();
private int lBraceCount;

private int commentStart;
private int commentDepth;

private void pushState(int state) {
states.push(new State(yystate(), lBraceCount));
lBraceCount = 0;
yybegin(state);
}

private void popState() {
State state = states.pop();
lBraceCount = state.lBraceCount;
yybegin(state.state);
}
%}

%s IN_BLOCK_COMMENT
%s IN_NAME_ATTRIBUTE
%s STRING
%s STRUCT

%unicode

Expand All @@ -78,103 +117,24 @@ INTEGER_LITERAL_HEX = 0[xX] {HEX_DIGIT} (_?{HEX_DIGIT})*
INTEGER_LITERAL_BIN = 0[bB] {BIN_DIGIT} (_?{BIN_DIGIT})*
INTEGER_LITERAL_OCT = 0[oO] {OCT_DIGIT} (_?{OCT_DIGIT})*
INTEGER_LITERAL= {INTEGER_LITERAL_HEX} | {INTEGER_LITERAL_BIN} | {INTEGER_LITERAL_OCT} | {INTEGER_LITERAL_DEC}
STRING_LITERAL=(\"([^\"\r\n\\]|\\.)*\")
IDENTIFIER=[a-zA-Z_][a-zA-Z0-9_]*
FUNC_IDENTIFIER=[a-zA-Z_][a-zA-Z0-9_?!:&']*

%%
<YYINITIAL> {
{WHITE_SPACE} { return WHITE_SPACE; }

"/*" { yybegin(IN_BLOCK_COMMENT); yypushback(2); }
"//".* { return LINE_COMMENT; }
REGULAR_STRING_PART=[^\\\"]+
ESCAPE_SEQUENCE=\\\\ // backslash
| \\\" // double quote
| \\n // newline
| \\r // carriage return
| \\t // tab
| \\v // vertical tab
| \\b // backspace
| \\f // form feed
| \\u\{ {HEX_DIGIT} {HEX_DIGIT}? {HEX_DIGIT}? {HEX_DIGIT}? {HEX_DIGIT}? {HEX_DIGIT}? \} // unicode escape
| \\u {HEX_DIGIT} {HEX_DIGIT} {HEX_DIGIT} {HEX_DIGIT} // hex escape
| \\x {HEX_DIGIT} {HEX_DIGIT} // hex escape
| \\[^\n] // any other character

"{" { zzBlockDepth++; return LBRACE; }
"}" {
if (zzBlockDepth-- == 0) {
zzStructScope = false;
zzContractScope = false;
}
return RBRACE;
}
"[" { return LBRACK; }
"]" { return RBRACK; }
"(" { zzParenDepth++; return LPAREN; }
")" { zzParenDepth--; return RPAREN; }
":" { return COLON; }
";" { return SEMICOLON; }
"," { return COMMA; }
"." { return DOT; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MUL; }
"/" { return DIV; }
"%" { return REM; }
"&" { return AND; }
"|" { return OR; }
"^" { return XOR; }
"<" { return LT; }
">" { return GT; }
"=" { return EQ; }
"?" { return Q; }
"!" { return EXCL; }
"+=" { return PLUSLET; }
"-=" { return MINUSLET; }
"*=" { return TIMESLET; }
"/=" { return DIVLET; }
"%=" { return MODLET; }
"==" { return EQEQ; }
"!=" { return EXCLEQ; }
">=" { return GTEQ; }
"<=" { return LTEQ; }
">>" { return GTGT; }
"<<" { return LTLT; }
"||" { return OROR; }
"&&" { return ANDAND; }
"!!" { return EXCLEXCL; }
"if" { return IF_KEYWORD; }
"else" { return ELSE_KEYWORD; }
"while" { return WHILE_KEYWORD; }
"do" { return DO_KEYWORD; }
"until" { return UNTIL_KEYWORD; }
"repeat" { return REPEAT_KEYWORD; }
"return" { return RETURN_KEYWORD; }
"extends" { return EXTENDS_KEYWORD; }
"mutates" { return MUTATES_KEYWORD; }
"virtual" { return VIRTUAL_KEYWORD; }
"override" { return OVERRIDE_KEYWORD; }
"inline" { return INLINE_KEYWORD; }
"native" { return NATIVE_KEYWORD; }
"let" { return LET_KEYWORD; }
"const" { return CONST_KEYWORD; }
"fun" { return FUN_KEYWORD; }
"initOf" { return INIT_OF_KEYWORD; }
"as" { return AS_KEYWORD; }
"abstract" { return ABSTRACT_KEYWORD; }
"import" { return IMPORT_KEYWORD; }
"struct" { zzStructScope = true; return STRUCT_KEYWORD; }
"message" { return zzBlockDepth == 0 ? MESSAGE_KEYWORD : IDENTIFIER; }
"contract" { zzContractScope = true; return CONTRACT_KEYWORD; }
"trait" { return TRAIT_KEYWORD; }
"with" { return WITH_KEYWORD; }
"receive" { return RECEIVE_KEYWORD; }
"external" { return EXTERNAL_KEYWORD; }
"true" { return BOOLEAN_LITERAL; }
"false" { return BOOLEAN_LITERAL; }
"null" { return NULL_LITERAL; }
"primitive" { return PRIMITIVE_KEYWORD; }
"self" { return SELF_KEYWORD; }
"map" { return MAP_KEYWORD; }
"bounced" { return zzBlockDepth == 1 && zzContractScope ? BOUNCED_KEYWORD : IDENTIFIER; }
"init" { return zzBlockDepth == 1 && zzParenDepth == 0 ? INIT_KEYWORD : IDENTIFIER; }
"get" { return zzBlockDepth <= 1 ? GET_KEYWORD : IDENTIFIER; }
"@interface" { return INTERFACE_MACRO; }
"@name" { yybegin(IN_NAME_ATTRIBUTE); yypushback(5); }

{INTEGER_LITERAL} { return INTEGER_LITERAL; }
{STRING_LITERAL} { return STRING_LITERAL; }
{IDENTIFIER} { return IDENTIFIER; }
}
%%

<IN_BLOCK_COMMENT> {
"/*" { if (zzNestedCommentLevel++ == 0)
Expand All @@ -190,12 +150,140 @@ FUNC_IDENTIFIER=[a-zA-Z_][a-zA-Z0-9_?!:&']*
[^] { }
}

<STRING> {
{REGULAR_STRING_PART} { return REGULAR_STRING_PART; }
{ESCAPE_SEQUENCE} { return ESCAPE_SEQUENCE; }
\" { popState(); return CLOSE_QUOTE; }
[^] { popState(); yypushback(1); }
}

<IN_NAME_ATTRIBUTE> {
"@name" { return NAME_MACRO; }
"(" { zzParenDepth++; return LPAREN; }
")" { zzParenDepth--; yybegin(YYINITIAL); return RPAREN; }
{FUNC_IDENTIFIER} { yybegin(YYINITIAL); return FUNC_IDENTIFIER; }
[^] { yybegin(YYINITIAL); yypushback(1); }
")" { zzParenDepth--; popState(); return RPAREN; }
{FUNC_IDENTIFIER} { popState(); return FUNC_IDENTIFIER; }
[^] { popState(); yypushback(1); }
}

{WHITE_SPACE} { return WHITE_SPACE; }
\" { pushState(STRING); return OPEN_QUOTE; }

"/*" { pushState(IN_BLOCK_COMMENT); yypushback(2); }
"//".* { return LINE_COMMENT; }

"{" {
zzBlockDepth++;
if (zzStructScope) {
zzStructIdentifierExpected = true;
}
return LBRACE;
}
"}" {
if (zzBlockDepth-- == 0) {
zzStructScope = false;
zzContractScope = false;
}
return RBRACE;
}
"[" { return LBRACK; }
"]" { return RBRACK; }
"(" { zzParenDepth++; return LPAREN; }
")" { zzParenDepth--; return RPAREN; }
":" {
if (zzStructScope) {
zzStructIdentifierExpected = false;
}
return COLON;
}
";" {
if (zzStructScope) {
zzStructIdentifierExpected = true;
}
return SEMICOLON;
}
"," { return COMMA; }
"." { return DOT; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MUL; }
"/" { return DIV; }
"%" { return REM; }
"&" { return AND; }
"|" { return OR; }
"^" { return XOR; }
"<" { return LT; }
">" { return GT; }
"=" { return EQ; }
"?" { return Q; }
"!" { return EXCL; }
"~" { return TILDE; }
"+=" { return PLUSLET; }
"-=" { return MINUSLET; }
"*=" { return TIMESLET; }
"/=" { return DIVLET; }
"%=" { return MODLET; }
"&=" { return ANDLET; }
"|=" { return ORLET; }
"^=" { return XORLET; }
"==" { return EQEQ; }
"!=" { return EXCLEQ; }
">=" { return GTEQ; }
"<=" { return LTEQ; }
">>" { return GTGT; }
"<<" { return LTLT; }
"||" { return OROR; }
"&&" { return ANDAND; }
"!!" { return EXCLEXCL; }
"if" { return IF_KEYWORD; }
"else" { return ELSE_KEYWORD; }
"while" { return WHILE_KEYWORD; }
"do" { return DO_KEYWORD; }
"until" { return UNTIL_KEYWORD; }
"repeat" { return REPEAT_KEYWORD; }
"return" { return RETURN_KEYWORD; }
"extends" { return EXTENDS_KEYWORD; }
"mutates" { return MUTATES_KEYWORD; }
"virtual" { return VIRTUAL_KEYWORD; }
"override" { return OVERRIDE_KEYWORD; }
"inline" { return INLINE_KEYWORD; }
"native" { return NATIVE_KEYWORD; }
"let" { return LET_KEYWORD; }
"const" { return CONST_KEYWORD; }
"fun" { return FUN_KEYWORD; }
"initOf" { return INIT_OF_KEYWORD; }
"as" { return AS_KEYWORD; }
"abstract" { return ABSTRACT_KEYWORD; }
"import" { return IMPORT_KEYWORD; }
"struct" { zzStructScope = true; return STRUCT_KEYWORD; }
"message" { return zzBlockDepth == 0 ? MESSAGE_KEYWORD : IDENTIFIER; }
"contract" { zzContractScope = true; return CONTRACT_KEYWORD; }
"trait" { return TRAIT_KEYWORD; }
"with" { return WITH_KEYWORD; }
"receive" { return RECEIVE_KEYWORD; }
"external" { return EXTERNAL_KEYWORD; }
"true" { return BOOLEAN_LITERAL; }
"false" { return BOOLEAN_LITERAL; }
"null" { return NULL_LITERAL; }
"primitive" { return PRIMITIVE_KEYWORD; }
"self" { return SELF_KEYWORD; }
"map" { return MAP_KEYWORD; }
"try" { return TRY_KEYWORD; }
"catch" { return CATCH_KEYWORD; }
"foreach" { return FOREACH_KEYWORD; }
"in" { return IN_KEYWORD; }
"bounced" {
if (zzStructScope && zzStructIdentifierExpected) {
zzStructIdentifierExpected = false;
return IDENTIFIER;
}
return BOUNCED_KEYWORD;
}
"init" { return zzBlockDepth == 1 && zzParenDepth == 0 ? INIT_KEYWORD : IDENTIFIER; }
"get" { return zzBlockDepth <= 1 ? GET_KEYWORD : IDENTIFIER; }
"@interface" { return INTERFACE_MACRO; }
"@name" { pushState(IN_NAME_ATTRIBUTE); yypushback(5); }

{INTEGER_LITERAL} { return INTEGER_LITERAL; }
{IDENTIFIER} { return IDENTIFIER; }

[^] { return BAD_CHARACTER; }
Loading

0 comments on commit c4fde77

Please sign in to comment.