With both the contribution of ExUnit Mix Tasks in 4.7.0
and the conversion of the build to Gradle for 5.0.0
, I’ve added Jake Becker (@JakeBecker) as a Collaborator to the repo.
Thanks
- Reporting the
AssertionError
inorg.elixir_lang.code_insight.lookup.element_renderer.CallDefinitionClause.renderElement
- @bdarla
- Josué Henrique Ferreira da Silva (@josuehenrique)
- Arjan Molenaar (@amolenaar)
- Chris Desch (@ cdesch)
- Steve (@stevepm)
- Laura Stone (@tyrostone)
- @wee911
- Oleg Samorai (@Samorai)
- Jadenn (@dabaer)
- Jan Stevens (@JanStevens)
- Szymon Jeż (@szymon-jez)
- Reporting examples where
ElixirVariable
could not be determined if it was a variable.- Steve Wagner (@ciroque)
- Marcin Jakubowski (@mjakubowski84)
- Ryan Cammer (@ryancammer)
- Josué Henrique Ferreira da Silva (@josuehenrique) (multiple examples!)
- Matt Briggs (@mbriggs)
- Reporting examples where
ElixirMultipleAliases
could not resolve variable in match.- Дмитрий Дубина (@dmitrydprog
- Nitin Gupta (@nitingupta910) for
- Reporting examples of the annotator highlighting in the wrong file due to the call definition offset always being assumed to be in the same file.
- Wojciech Bednarski (@wbednarski)
- Artem Gordinsky (@ArtemGordinsky)
- Sam Brotherton (@sbrother)
- Alexander Merkulov (@merqlove)
- Reporting Parameter variable style being incorrectly applied
- Matt Briggs (@mbriggs)
- Working with me to figure out that the template tags in the color preview were messed up
- Dmitry Maltsev (@judgedim)
- Reporting mismatch between inspection resource and class due to a copy-and-paste error
- Markus Fischer (@mfn)
- Reporting incorrect highlighting of functions with guards
- Dmitry Maltsev (@judgedim)
- Requesting configurable code-folding for module attributes
- Artem Rizhov (@artemrizhov)
- Pointing out it makes no sense for context menus for ExUnit to appear in non-Elixir projects
- Alexander Merkulov (@merqlove)
- Reporting an example where
MatchedUnqualifiedParenthesesCall
could not be type highlighted- Ryan Scheel (@Havvy)
- Reporting that function complete didn’t take into account the already typed prefix
- Saeed Zarinfam (@zarinfam)
- Requesting completion of Aliases to
.beam
-only Module, which is what inspired me to attempt decompilation- Matt Briggs (@mbriggs)
Changelog
v5.0.0
Enhancements
- #574 - @KronicDeth
- Decompile
.beam
files- Structure view for decompiled
.beam
files - Index modules, functions, and macros exported by
.beam
files - Go To Symbol for Modules defined in
.beam
files (both SDK and deps)- Erlang using atoms (like
:idna
) - Elixir using Alias (like
Enum
)
- Erlang using atoms (like
- Completion for Modules defined in
.beam
files (both SDK and deps)- Elixir using Alias (like
Enum
)
- Elixir using Alias (like
- Completion for functions and macros exported by
.beam
files - Syntax highlighting
- Structure view for decompiled
- Decompile
- #579 - Regression test for #575 - @KronicDeth
- #583 - @KronicDeth
- Macros appear before functions in decompiled
.beam
files- Header for macro and function sections
- Macros appear before functions in decompiled
- #585 - @KronicDeth
- Update
ELIXIR_VERSION
for1.2.*
from1.2.3
to1.2.6
- Add
ELIXIR_VERSION
1.3.4
- Add
ELIXIR_VERSION
1.4.0
- Update
IDEA
for2016.*
to2016.3.1
- Show
OtpErlangBitStr
(and thereforeOtpErlangBinary
contents when tests fail - Quote binaries as
to_charlist
instead ofto_char_list
for Elixir>= 1.3
. Depends on Elixir version of project SDK. - Use
elixir
instead ofjava
VM, so now Erlang and Elixir don’t need to be built on travis-ci, butant
and thejdk
need to be installed, but unlike Erlang and Elixir, there are tarballs for that, so this way is faster than the old method without depending on travis-ci cache.
- Update
- #609 - @KronicDeth
- If
multiResolve
causes aStackOverflow
fororg.elixir_lang.annotator.Callable.visitCall
, thencatch
it and useerrorreport
logger to log the element. - Include file path in
errorreport
excerpt - Log element for
StackOverflow
related toimport
s - Regression test for #605.
- Log
LookupElement#getObject
whenLookupElement#getPsiElement
isnull
to track down how it wasnull
in #563.
- If
- #614 - Regression test for #559 - @KronicDeth
- #504 - @JakeBecker
- Switch to Gradle for builds.
./gradlew runIde
(or therunIde (VERSION)
Run Configurations) will run IDEA in a sandbox with the development version of the plugin../gradlew test
(or thetest (VERSION)
Run Configurations) will run the main plugin and jps-builder tests.- The plugin can now be published with
./gradlew publishPlugin
, BUT you’ll need to fill inpublish*
properties ingradle.properties
. This will eventually allow for automated “nightlies” from successful Travis-CI builds onmaster
.
- Switch to Gradle for builds.
- #638 - The
Callable
annotator is meant for variables, parameters, and macro and function calls and declarations. TheModuleAttribute
annotator handles module attribute declaration and usage, so we can save reference resolution time by skipping module attributes inCallable
. - @KronicDeth - #640 - Allow module attribute folding to be configured. - @KronicDeth
- #662 - @KronicDeth
- Allow call definition heads to resolves to themselves for consistency with Aliases of
defmodule
. - Generalize
Callable.callDefinitionClauseDefiner(Call)
: in addition to the currentCallDefinitionClause
, make it work forImplementation
,Module
, andProtocol
.
- Allow call definition heads to resolves to themselves for consistency with Aliases of
Bug Fixes
- #574 - Fix copy-paste errors in
MatchOperatorInsteadOfTypeOperator
- @KronicDeth - #579 - @KronicDeth
- Subtract 1 from arity in
.beam
file when decompiling todefmacro
calls because the Erlang function for Elixir macros has one addition argument: the first argument is theCaller
of the macro. - If the name of the decompiled macro/function is an infix operator, then decompile the head as a binary operation instead of a normal prefix name as infix operators aren’t valid prefix names and led to parsing errors, which was the root cause of #575.
- Fix IntelliJ warnings in
BeamFileImpl
- Remove unused
VirtualFile
argument toBeamFileImpl#buildFileStub
.
- Subtract 1 from arity in
- #583 - @KronicDeth
- Add
++
,=~
, andin
toINFIX_OPERATOR_SET
. - Only render infix operators if arity is
2
. - Prefix operator decompilation:
+
and-
are both binary and unary operators. When a unary operator they need to be wrapped in parentheses, so that the call definition clause is parsed correctly.
- Add
- #585 - @KronicDeth
- Ignore
JFLex
jar - Don’t check for
elixir-lang/elixr
files remove in1.3
- Allow
nil
as a keyword key.nil
was being lexed as a potential keyword key, but NIL was missing from the token list in the keywordKey grammar rule.
- Ignore
- #599 - Some SpecialForms don’t work as literals as they would be interpreted as metaprogramming, so their name needs to be wrapped as an atom to
unquote
. - @KronicDeth - #600 - @KronicDeth
- Check children of
MultipleAliases
for variable declarations. - Treat any variable declared in a
MultipleAliases
as invalid.
- Check children of
- #609 - @KronicDeth
- Skip
import Kernel
inkernel.ex
to prevent stack overflow due to recursiveimport
- Strip all outer parentheses for left type operand, so that
(+value)
can be see as+
operator type spec. - Use advice from
IndexNotReadyException
documentation and checkDumbService.isDumb(Project)
before callingStubIndex.getElements
inModule
andmodule.MultiResolve.indexNameElements
. - Don’t
assert
thatLookupElement#getPsiElement
is notnull
inCallDefinitionCluase.renderElement
- Update to
ant
1.10.1
because1.10.0
is no longer hosted.
- Skip
- #612 - Yeah, it sounds weird, but an
ElixirVariable
isn’t necessarily a variable if it doesn’t occur in a declaration context. It could just be a no-parentheses function call in the wrong spot, so check the parentPsiElement
to determine ifElixirVariable
is a variable. - @KronicDeth - #614 - Highlight parameterized type head (
maybe(t)
in@type maybe(t)
) the same as a full type definition (maybe(t)
in@type maybe(t) :: t | nil
) - @KronicDeth - #616 - Only show Mix ExUnit Run in context when the module, or when the module is not a available, the project SDK is Elixir. If there is no SDK configured, show “Mix ExUnit Run” in the menu. - @KronicDeth
- #617 - Mark
do:
as atom in demo text - @KronicDeth - #627 - Annotations can only be applied to the single, active file, which belongs to the
referrer
Callable
. Theresolved
may be outside the file if it is a cross-file function or macro usage, in which case it’sTextRange
should not be highlighted because it is referring to offsets in a different file. - @KronicDeth - #634 - @KronicDeth
Variable
scope forQualifiedMultipleAliases
, which occurs when qualified call occurs over a line with assignment to a tuple, such asQualifier.\n{:ok, value} = call()
- Remove call definition clauses (function or macro) completion for bare words as it had a detrimental impact on typing feedback (the editor still took input, but it wasn’t rendered until the completion returned OR
ESC
was hit to cancel the completion, which became excessive once the index of call definition clauses was expanded by the decompilation of the Elixir standard library.beam
s, so disable it. If bare-words completion is restored. It will either (1) need to not use theReference#getVariants()
API because it generates too many objects that need to be thrown away or (2) need to only complete call definition clauses that are provably in-scope from imports or other macros.
- #636 - @KronicDeth
- Both intellij-erlang and intellij-community are Apache 2.0 licensed and its the default license for Elixir projects, so seems like a good choice for
LICENSE.md
- Add
CODE_OF_CONDUCT.md
- Both intellij-erlang and intellij-community are Apache 2.0 licensed and its the default license for Elixir projects, so seems like a good choice for
- #638 - @KronicDeth
- The run configurations I put together in #504 didn’t allow for the debugger to work properly: neither pause nor breakpoints had any effect, so regenerate them from the Gradle pane.
- Check parent of
when
operation in case it’s a guarded function head inorg.elixir_lang.annonator.Parameter.putParameterized(Parameter, PsiElement)
- Instead of highlighting call definition clauses when they are referred to, which only works if it is in the same file, highlight all function and macro declarations when the
def*
call is encountered. - Only increment arity for right pipe operand instead of all operands, so that left operands resolve to correct arity or as variable/parameter.
- #662 - @KronicDeth
- Override
ModuleImpl#getProject()
to preventStackOverflowError
. Without overriding#getProject()
,IdentifierHighlighterPass
gets stuck in a loop betweengetManager
andgetProject
on the target (theModuleImpl
) when clicking on the space betweendef
s ordefmacro
s in the decompiled.beam
files. - Fix source formatting
- Skip looking for variables unless 0-arity AND no arguments
- Highlight unresolved macros as macro calls. Anything with a do keyword or a do block will be treated like a macro call even if it can’t be resolved. No resolved is either no resolve results or an empty list
- Implicit imports at top of file in addition to top of Module.
- Override
- #663 - @KronicDeth
CallDefinitionClause
completion provider is unexpectedly invoked both when.
is typed, but continues to be invoked after a letter is typed after the.
; however, once the letter is typed, the letter becomes the default prefix instead, so the prefix should only be reset to""
when it ends in.
.- Disable
Callable#getVariants
unlessUnqualified
to prevents local functions and macros being shown as completions for qualified names.
- #651 - @StabbyMcDuck
- Among many other tweaks, the String color is now green, so that Atom and String are no longer close to one another, which was the original issue in #569
Alias
now hasunderscored
effectBrackets
are now greenish instead of brownishCallbacks
are now a lighter blue and hasunderscored
effectCharList
is little lighterCharToken
is dark yellow now instead of dark purpleDot
is now purple instead of dark redExpression Substitution Mark
is a little lighterInterpolation
is now lime greenKernel Macros
are a burnt orangeMap
is now a dark blue instead of a dark yellowOperation Sign
is a little lighterParameters
are a little darkerParentheses
are redderPredefined
is orange instead of blueSpecification
is now red instead of purpleStruct
is now purple instead of yellowType
is now green instead of dark purpleVariable
is more tealish
- Among many other tweaks, the String color is now green, so that Atom and String are no longer close to one another, which was the original issue in #569
- #650 - @StabbyMcDuck
- Fix indentation to fix sub-lists in
CONTRIBUTING.md
- Fix pluralization in
CONTRIBUTING.md
- Fix indentation to fix sub-lists in
- #664 - @KronicDeth
- Check if resolve results are
null
forFor.resolveResultList
- Check if
Protocol.resolveResultList
isnull
- Check if resolve results are
- #665 - Check
match
Call
is anUnqualifiedNoArgumentCall
, in addition to being 0 resolved final arity, before checking if the name matches. - @KronicDeth
Incompatible Changes
- #585 - Move
^^^
to its own three-operator precedence level to match1.2
. This does mean the parsing will be wrong for Elixir1.1
, but is simpler than maintaining two grammars for those that are still using Elixir1.1
- @KronicDeth - #504 - The
ant
build files have been removed. To build the build plugin (for Install From Disk), use the./gradlew buildPlugin
. - @JakeBecker - #640 - Change to module attribute folding to off by default. - @KronicDeth
README Updates
Decompilation
.beam
files, such as those in the Elixir SDK and in your project’s build
directory will be decompiled to equivalent def
and defmacro
calls. The bodies will not be decompiled, only the call definition head and placeholder parameters. These decompiled call definition heads are enough to allow Go To Declaration, the Structure pane, and Completion to work with the decompiled .beam
files.
Installation
Inside IDE using JetBrains repository
- Preferences
- Plugins
- Browse Repositories
- Select Elixir
- Install plugin
- Apply
- Restart the IDE
Inside IDE using Github releases
In browser
- Go to releases.
- Download the lastest zip.
In IDE
- Preferences
- Plugins
- Install plugin from disk…
- Select the downloaded zip.
- Apply
- Restart the IDE.