Skip to content

Code.Fragment.surround_context and reserved words #11889

@lukaszsamson

Description

@lukaszsamson

Environment

  • Elixir & Erlang/OTP versions (elixir --version): 1.13, dev

Current behavior

Code.Fragment.surround_context docs state that

The difference between cursor_context/2 and surround_context/3 is that the former assumes the expression in the code fragment is incomplete. For example, do in cursor_context/2 may be a keyword or a variable or a local call, while surround_context/3 assumes the expression in the code fragment is complete, therefore do would always be a keyword.

This is not the case as most of the reserved words are either not recognised or miscategorised.

used as atoms - miscategorised as local or var

Code.Fragment.surround_context("true", {1, 1})
%{begin: {1, 1}, context: {:local_or_var, 'true'}, end: {1, 5}}
Code.Fragment.surround_context("false", {1, 1}) 
%{begin: {1, 1}, context: {:local_or_var, 'false'}, end: {1, 6}}
Code.Fragment.surround_context("nil", {1, 1})   
%{begin: {1, 1}, context: {:local_or_var, 'nil'}, end: {1, 4}}

used in operators- recognised correctly

Code.Fragment.surround_context("when", {1, 1}) 
%{begin: {1, 1}, context: {:operator, 'when'}, end: {1, 5}}
Code.Fragment.surround_context("and", {1, 1})
%{begin: {1, 1}, context: {:operator, 'and'}, end: {1, 4}}
Code.Fragment.surround_context("or", {1, 1}) 
%{begin: {1, 1}, context: {:operator, 'or'}, end: {1, 3}}
Code.Fragment.surround_context("not", {1, 1})
%{begin: {1, 1}, context: {:operator, 'not'}, end: {1, 4}}
Code.Fragment.surround_context("in", {1, 1}) 
%{begin: {1, 1}, context: {:operator, 'in'}, end: {1, 3}}

used for anonymous function definitions - miscategorised but it's OK - it's an imported special form

Code.Fragment.surround_context("fn", {1, 1}) 
%{begin: {1, 1}, context: {:local_or_var, 'fn'}, end: {1, 3}}

used in do-end blocks- not recognised

Code.Fragment.surround_context("do", {1, 1})
:none
Code.Fragment.surround_context("end", {1, 1})
:none
Code.Fragment.surround_context("catch", {1, 1})
:none
Code.Fragment.surround_context("rescue", {1, 1})
:none
Code.Fragment.surround_context("after", {1, 1}) 
:none
Code.Fragment.surround_context("else", {1, 1}) 
:none

Expected behavior

Not sure. it would be convenient if they were recognised but it's not a critical issue as those keywords are not very interesting and some logic can be implemented on the API client side with matching on :local_or_var and checking the charlist against a list of known keywords.
If we decide not to address that then at least the documentation needs fixing to match the behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions