Giter Club home page Giter Club logo

intellij-elixir's Issues

Access Expression

access_expr is partially implemented in #50, but various portions could not be implemented because the lexical tokens were not available.

Prereqs

Features

When all prereqs are complete, then accessExpression should completely match access_expr.

Sigil modifiers only work on heredoc

When I added sigils, I added support for modifiers at the end of the work and forgot to add the support to both the group format and heredoc format for sigils: currently only heredoc supports modifiers.

Group format such as ~r()i should be accepted, but it is not while

~r"""
"""i

is accepted.

Syntax highlighter is incomplete and needs clearer error messages

Even a simple file like this is completely red and no sensible Syntax highlighting.

defmodule Chat do
  use Application

  # See http://elixir-lang.org/docs/stable/Application.Behaviour.html
  # for more information on OTP Applications
  def start(_type, _args) do
    Chat.Supervisor.start_link
  end
end

The error is something like "ElixirTokenType... or ...[..] expected, but got 'd' "

No Parentheses Operator Expression

Implement no_parens_op_expr to complete match_expr where it uses no_parens_expr.

Prereqs

  • matchedExpression (#50)
  • noParenthesesExpression (#58)

Features

matched_expr direct-dependencies

no_parens_op_expr

This is matched_expr no_parens_op_expr should be rewritten as binary operations with matchedExpression as the left operand and noParenthesesExpression as the right operand. This can be accomplished with either new binary operations or by changing the matchedExpression*Operations from #50 to accept either a matchedExpression or a noParenthesesExpression as the right operand.

  • Allow noParenthesesExpression as right operand to matchedExpressionMatchOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionAdditionOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionMultiplicationOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionHatOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionTwoOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionAndOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionOrOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionInOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionInMatchOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionTypeOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionPipeOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionComparisonOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionRelationalOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionArrowOperation
  • Allow noParenthesesExpression as right operand to matchedExpressionWhenOperation

when handling for no_parens_op_expr has an additional right operand choice in addition to no_parens_expr: call_args_no_parens_kw

  • Allow call_args_no_parens_kw as right operand to matcheExpressionWhenOperation

Dot

Handle dot, which needs the rest to be operators (so complete #29 first), ( for anonymous function calls and interpolated function names. (For example, Keyword."get"([a: 1], :a) is valid and the same as Keyword.get([a: 1], :a), so you can use a string or char list the after dot the same way you pass Symbols to send in Ruby.) Finally, there is normal . call syntax. All these forms need to accept multiple newlines and whitespace on either side of the ..

Right Operand

Call Identifier

No Parentheses One Expression

no_parens_one_expr is part of matched_expr. The dot_identifier portion of it is currently implemented by matchedExpressionDotOperation and identifierExpression, but the call_args_no_parens_one still needs to be implemented.

I was able to trigger do_identifier in the tokenizer like so:

iex(37)> :elixir_tokenizer.tokenize('one do end', 1, [])
{:ok, 1, [{:do_identifier, 1, :one}, {:do, 1}, {:end, 1}]}

This held into the parser too:

iex(38)> Code.string_to_quoted("one do end")            
{:ok, {:one, [line: 1], [[do: nil]]}}

Prereqs

Features

matched_expr direct-dependencies

no_parens_one_expr direct-dependencies

call_args_no_parens_one direct-dependencies

No Parentheses Expression

Implement as much of no_parens_expr as is possible given the pre-existing translation of elixir_parser.yrl

Prereqs

  • matchedExpression (#50)

Features

no_parens_expr direct-dependencies

call_args_no_parens_many_strict direct-dependencies

Without error handling

With error handling

call_args_no_parens_many

call_args_no_parens_kw direct-dependencies

call_args_no_parens_kw_expr direct-dependencies

call_args_no_parens_expr direct-dependencies

Without error handling

With error hanlding

call_args_no_parens_comma_expr direct-dependencies

Complete matchExpression

  • Add as operand to matchedExpressionUnaryOperation
  • Add as operand to matchedExpressionAtOperation
  • Add as operand to matchedExpressionCaptureOperation
  • #59

Comments starting in strings when using `#{...}`

There is a bug about highlighting comments:

# This comment will to displayed correctly
IO.puts "All your #{inspect tuple} are belong to us"

The last part of the second line #{inspect tuple} are belong to us" will be displayed as a comment.

I dont know the name for the #{...} syntax in strings, but it needs to be handled.

(I know its a early version, but i would like to document my findings.)

Max Expression

max_expression is used in access_expr and used in map_expr.

Prereqs

Features

access_expr direct-dependencies

  • Add max_expr to access_expr

max_expr direct-dependencies

parens_call direct-dependencies

dot_paren_identifer direct dependencies

dot_call_op

  • Lex {DOT_OPERATOR} / {OPENING_PARENTHESES} as DOT_CALL_OPERATOR.

call_args_parens

call_args_parens_base

  • Use containerExpression from #68

New > Elixir File should underscore file name

The current version of New > Elixir File, as so nicely provided by @abaire, doesn't differentiate between the File name and the Module name, so if you enter a Module name of Foo, the file is named Foo.ex, but Elixir convention is for the file name to be lowercase and underscored, so ExUnit Module name becomes ex_unit.ex. I tried debugging the Action and I'm not sure if using the CreateFileFromTemplateAction allows us to have a different File name and Module name since there is only one NAME attribute passed into the template. I may be possible to look at how the Package and Class creation actions work for Java and see if its possible to set the Module name as the PACKAGE_NAME or CLASS_NAME attribute and have the file name derived from that for the NAME attribute.

Containers and commas

Implementing commas as operators in #29 does not makes sense as unlike other operators, commas should parse a list of expressions (that don't themselves contain commas) instead of nested binary operations. elixir_parser.yrl is able to get away with parsing commas as binary expressions because the yrl format allows the elements of a given rule to be concatenated into a flattened list. To do this in the bnf format for Grammar Kit I need to actually write a list like expression, which means separating operations into a different rule than comma so that comma only contains comma-less direct children to prevent left-recursion.

Map

map is used in access_expr

Prereqs

Features

access_expr direct-dependencies

  • Add map to accessExpression

map direct-dependencies

  • Lex % instead of %{} as MAP_OPERATOR. It will be used for both map_op and struct_op.
  • map_args
  • map_expr

map_args direct-dependencies

map_close direct-dependencies

  • Extract kw ((keywordPair (COMMA EOL* keywordPair)* COMMA?)?) from list in Elixir.bnf
  • assoc
  • assoc_base

assoc direct-dependencies

assoc_base

assoc_expr

  • Use pre-existing rules

assoc_update direct-dependencies

assoc_update_kw

  • Use existing rules.

map_expr

  • Use existing rules

Recovery for invalid numbers

Be able to recovery from invalid digits in numbers so that parsing in pygment example doesn't stop at first invalid number example.

  • Detect obsolete 0B and parse without PsiErrorElement
  • Detect obsolete 0X and parse without PsiErrorElement
  • Detect invalid binary digits for 0b and 0B
  • Detect invalid digits for decimal numbers
  • Detect invalid octal digits for 0o.
  • Detect invalid hexadecimal digits for 0x and 0X

Identifiers

Any token that starts with a lowercase letter or underscore (_) and does not match any other token type is an identifier

Regular keywords

Lex regular keywords as distinct tokens from IDENTIFIER.

Elixir.flex

  • Lex fn as FN
  • Lex end as END
  • Lex true as TRUE
  • Lex false as FALSE
  • Lex nil as NIL

Elixir.bnf

  • Add TRUE to accessExpression
  • Add FALSE to accessExpression
  • Add NIL to accessExpression

Dot Operator

dot_op is used for the call syntax. In Elixir's implementation, the parser matches . directly, but in IntelliJ, I'll need to parse it in the lexer, Elixir.flex, as DOT_OPERATOR and then use it in Elixir.bnf for the parser.

Comments consuming EOL causes expression separation to fail

Comments currently consume the EOL to make combining multiline comments together easier, but this leads to trailing comments to eat the EOL, which means the required EOL between expressions is not there leading to invalid parses.

0x1 # does not consume EOL to separate 0x1 and 0x2
0x2 # does not have EOL at EOF

Expected:

Elixir File(0,81)
  PsiElement(ElixirTokenType.NUMBER)('0x1')(0,3)
  PsiWhiteSpace(' ')(3,4)
  PsiComment(ElixirTokenType.COMMENT)('# does not consume EOL to separate 0x1 and 0x2')(4,50)
  PsiElement(ElixirTokenType.EOL)('\n')(50,51)
  PsiElement(ElixirTokenType.NUMBER)('0x2')(51,54)
  PsiWhiteSpace(' ')(54,55)
  PsiComment(ElixirTokenType.COMMENT)('# does not have EOL at EOF')(55,81)

Actual:

Elixir File(0,81)
  PsiElement(ElixirTokenType.NUMBER)('0x1')(0,3)
  PsiWhiteSpace(' ')(3,4)
  PsiComment(ElixirTokenType.COMMENT)('# does not consume EOL to separate 0x1 and 0x2\n')(4,51)
  PsiErrorElement:ElixirTokenType.EOL expected, got '0x2'(51,54)
    PsiElement(ElixirTokenType.NUMBER)('0x2')(51,54)
  PsiWhiteSpace(' ')(54,55)
  PsiComment(ElixirTokenType.COMMENT)('# does not have EOL at EOF')(55,81)

Aliases/Module names

Recognize aliases as module names. Note: Not all tokens with leading capital letters are aliases/Module names if they're followed by : (<colon><space>) then they should just be parsed as the atom keyword identifier for a Keyword list or map.

New > Elixir File should convert . in Module name to directories

This builds on top of #19.

If a Module name has multiple levels, such as ExUnit.AssertionError, then the file should have a nested path of ex_unit/assertion_error.ex. It may be possible to determine how to do this by treating the ExUnit has a PACKAGE_NAME and AssertionError as a CLASS_NAME and seeing how the Java Class action work in the IDEA Community Edition source.

Blank lines parsed as bad character

Blank lines, such between comments are erroneously marked as bad characters because only single EOL are expected to separate expressions. Blank lines should be treated as whitespace, so they aren't consumed by the parser.
screen shot 2014-10-12 at 7 24 04 pm

Sigil terminator escapes are not recognized

The current set of VALID_ESCAPE_SEQUENCE

VALID_ESCAPE_SEQUENCE = {ESCAPED_DOUBLE_QUOTES} |
                        {ESCAPED_SINGLE_QUOTE} |
                        {ESCAPED_INTERPOLATION_START}

is too limited and misses escapes of sigil terminators.
screen shot 2014-10-13 at 7 56 49 pm

Not only should the sigil terminators be escapable, but VALID_ESCAPE_SEQUENCE needs to be updated to cover all escapes that Elixir's lexer handles.

Support for :atoms

As a next smaller step, visual support for atoms might be cool.

I think i might not be abled to help developing, but testing for sure :)

In operator

in is keyword for a binary operator used as an "include" operator as in

x = 1
x in [1, 2, 3] # true

Keyword List

kw is a prereq for list_args which is a prereq for list, but list_args and kw don't make sense as independent expressions, so to implement kw, implement list_args -> kw and list -> open_bracket list_args close_bracket to form a minimal list. list should be parsed as a value in Elixir.bnf.

  • Empty Lists
  • Keyword Pairs
  • Disallow Space Between Alias and :
  • Disallow Space Between Identifier and :
  • Disallow Space Between quote and :

Stab

stab is used in access_expr (and used in do_block)

Prereqs

Features

access_expr direct-dependencies

  • Add fn_eoe stab end_eoe
  • Add open_paren stab close_paren
  • Add open_paren stab ';' close_paren
  • Add open_paren ';' stab ';' close_paren

stab

stab_expr direct-dependencies

stab_maybe_expr direct-dependencies

  • expression?

call_args_no_parens_all direct-dependencies

  • Use pre-existing rules

stab_parens_many

  • Use pre-existing rules.

Recover from missing end-of-expression

The pygment example has escape sequences with too many digits. These extra digits are currently lexed as a separate decimal number immediately adjacent to the valid escape sequences. This problem can be generalized to expressions being adjacent to each other with missing end-of-expressions. When end-of-expressions are missing, then the parser should recover. There should also be quick fixes to insert end-of-expressions.

... identifier

The elixir tokenizer contains a 'Stand-alone token' for "...", which needs to be parsed as an identifier.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.