Intellij-elixir: StackOverflowError when annotating Call

Created on 9 May 2019  路  9Comments  路  Source: KronicDeth/intellij-elixir

Exception

Message

* exception class was changed or removed

Stacktrace

StackOverflowError when annotating Call

### Excerpt

use HalfDomeWeb, :controller

 Line(s) 1-1 in /Users/Sparta/Development/half_dome/lib/half_dome_web/controllers/superuser/trial_controller.ex


### Element Class Name

org.elixir_lang.psi.impl.ElixirUnmatchedUnqualifiedNoParenthesesCallImpl

org.elixir_lang.errorreport.Logger.error(Logger.java:51)
org.elixir_lang.errorreport.Logger.error(Logger.java:34)
org.elixir_lang.annotator.Callable$annotate$1.visitPlainCall(Callable.kt:100)
org.elixir_lang.annotator.Callable$annotate$1.visitNonModuleAttributeCall(Callable.kt:87)
org.elixir_lang.annotator.Callable$annotate$1.visitCall(Callable.kt:47)
org.elixir_lang.annotator.Callable$annotate$1.visitElement(Callable.kt:78)
com.intellij.psi.impl.PsiElementBase.accept(PsiElementBase.java:274)
org.elixir_lang.psi.impl.ElixirUnmatchedUnqualifiedNoParenthesesCallImpl.accept(ElixirUnmatchedUnqualifiedNoParenthesesCallImpl.java:38)
org.elixir_lang.annotator.Callable.annotate(Callable.kt:39)
com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.runAnnotators(DefaultHighlightVisitor.java:120)
com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.visit(DefaultHighlightVisitor.java:87)
com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.runVisitors(GeneralHighlightingPass.java:351)
com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.lambda$collectHighlights$5(GeneralHighlightingPass.java:284)
com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.analyzeByVisitors(GeneralHighlightingPass.java:311)
com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.lambda$analyzeByVisitors$6(GeneralHighlightingPass.java:314)
com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.analyze(DefaultHighlightVisitor.java:71)
com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.analyzeByVisitors(GeneralHighlightingPass.java:314)
com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.collectHighlights(GeneralHighlightingPass.java:281)
com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.collectInformationWithProgress(GeneralHighlightingPass.java:225)
com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:84)
com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:69)
com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$null$1(PassExecutorService.java:430)
com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1166)
com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$2(PassExecutorService.java:423)
com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:586)
com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:532)
com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:86)
com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.doRun(PassExecutorService.java:422)
com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$run$0(PassExecutorService.java:398)
com.intellij.openapi.application.impl.ReadMostlyRWLock.executeByImpatientReader(ReadMostlyRWLock.java:164)
com.intellij.openapi.application.impl.ApplicationImpl.executeByImpatientReader(ApplicationImpl.java:218)
com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:396)
com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:174)
java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Bug Duplicate Waiting on Feedback

Most helpful comment

The problematic line seems to be the line 71 of our web.ex (the line use App.Web, :view, when we "recursively" use the Web module)

defmodule App.Web do
  @moduledoc """
  A module that keeps using definitions for controllers,
  views and so on.

  This can be used in your application as:

      use App.Web, :controller
      use App.Web, :view

  The definitions below will be executed for every view,
  controller, etc, so keep them short and clean, focused
  on imports, uses and aliases.

  Do NOT define functions inside the quoted expressions
  below.
  """

  def model do
    quote do
      use Ecto.Schema

      import Ecto
      import Ecto.Changeset
      import Ecto.Query

      @primary_key {:id, :binary_id, autogenerate: true}
      @foreign_key_type :binary_id
      @timestamps_opts [type: :utc_datetime_usec, usec: true]
    end
  end

  def controller do
    quote do
      use Phoenix.Controller, namespace: App.Web

      alias App.Domain
      alias App.Repo

      import Ecto
      import Ecto.Query
      import App.Web.Router.Helpers
      import App.Web.Gettext
    end
  end

  def view do
    quote do
      use Phoenix.View, root: "lib/app/web/templates", namespace: App.Web

      # Import convenience functions from controllers
      import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]

      # Use all HTML functionality (forms, tags, etc)
      use Phoenix.HTML
      import Scrivener.HTML
      require HtmlEntities

      import App.Web.Router.Helpers
      import App.Web.ErrorHelpers
      import App.Web.Gettext
      import App.Web.ViewHelpers

      def render_one(%Ecto.Association.NotLoaded{}), do: nil
      def render_many(%Ecto.Association.NotLoaded{}), do: nil
    end
  end

  def admin_view do
    quote do
      use App.Web, :view   # When commenting this, the plugin doesn't crash anymore
      use App.Web.Admin.ViewHelpers
    end
  end

  @doc """
  When used, dispatch to the appropriate controller/view/etc.
  """
  defmacro __using__(which) when is_atom(which) do
    apply(__MODULE__, which, [])
  end
end

All 9 comments

We're getting this error when we open any of our Phoenix controllers. When we open any other type of Elixir file, the plugin is fine.

We have the same issue with our Phoenix controllers, but also our models and views.

Everytime there is one of the

use App.Web, :controller
use App.Web, :model
use App.Web, :view

The syntax highlighting is stuck at the use App.Web, :controller expression, and the CPU is heavily used, as if there was an infinite loop.

We're getting this error when we open any of our Phoenix controllers. When we open any other type of Elixir file, the plugin is fine.

This will turn out important. The use App.Web is weird in that it uses apply to dispatch on the argument, so there is special handling to follow that statically.

@sparta-developers I can't reproduce, so it something more complicated with the setup than a Phoenix project in a controller. Do you have a repo you can add me on that reproduces? We can also do a Zoom screenshare this week if you can't share code otherwise.

@a12e I can't reproduce with models or views either. Can you share a repository that reproduces the problem for you? If not, could you screenshare on Zoom this week?

The problematic line seems to be the line 71 of our web.ex (the line use App.Web, :view, when we "recursively" use the Web module)

defmodule App.Web do
  @moduledoc """
  A module that keeps using definitions for controllers,
  views and so on.

  This can be used in your application as:

      use App.Web, :controller
      use App.Web, :view

  The definitions below will be executed for every view,
  controller, etc, so keep them short and clean, focused
  on imports, uses and aliases.

  Do NOT define functions inside the quoted expressions
  below.
  """

  def model do
    quote do
      use Ecto.Schema

      import Ecto
      import Ecto.Changeset
      import Ecto.Query

      @primary_key {:id, :binary_id, autogenerate: true}
      @foreign_key_type :binary_id
      @timestamps_opts [type: :utc_datetime_usec, usec: true]
    end
  end

  def controller do
    quote do
      use Phoenix.Controller, namespace: App.Web

      alias App.Domain
      alias App.Repo

      import Ecto
      import Ecto.Query
      import App.Web.Router.Helpers
      import App.Web.Gettext
    end
  end

  def view do
    quote do
      use Phoenix.View, root: "lib/app/web/templates", namespace: App.Web

      # Import convenience functions from controllers
      import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]

      # Use all HTML functionality (forms, tags, etc)
      use Phoenix.HTML
      import Scrivener.HTML
      require HtmlEntities

      import App.Web.Router.Helpers
      import App.Web.ErrorHelpers
      import App.Web.Gettext
      import App.Web.ViewHelpers

      def render_one(%Ecto.Association.NotLoaded{}), do: nil
      def render_many(%Ecto.Association.NotLoaded{}), do: nil
    end
  end

  def admin_view do
    quote do
      use App.Web, :view   # When commenting this, the plugin doesn't crash anymore
      use App.Web.Admin.ViewHelpers
    end
  end

  @doc """
  When used, dispatch to the appropriate controller/view/etc.
  """
  defmacro __using__(which) when is_atom(which) do
    apply(__MODULE__, which, [])
  end
end

We successfully got _around_ the issue by rewriting the recursion of the use App.Web, :view in another way. Without this recursion of use inside App.Web, the plugin doesn't crash.

  defp base_view do
    quote do
      use Phoenix.View, root: "lib/app/web/templates", namespace: App.Web

      # Import convenience functions from controllers
      import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]

      # Use all HTML functionality (forms, tags, etc)
      use Phoenix.HTML
      import Scrivener.HTML
      require HtmlEntities

      import App.Web.Router.Helpers
      import App.Web.ErrorHelpers
      import App.Web.Gettext
      import App.Web.ViewHelpers

      def render_one(%Ecto.Association.NotLoaded{}), do: nil
      def render_many(%Ecto.Association.NotLoaded{}), do: nil
    end
  end

  def view do
    [
      base_view,
      quote do

      end,
    ]
  end

  def admin_view do
    [
      base_view,
      quote do
        use App.Web.Admin.ViewHelpers
      end,
    ]
  end

@a12e I can reproduce using https://github.com/KronicDeth/intellij-elixir/issues/1475#issuecomment-491616192, thanks.

Duplicate of #1467

Was this page helpful?
0 / 5 - 0 ratings

Related issues

merqlove picture merqlove  路  3Comments

SyedWasiHaider picture SyedWasiHaider  路  4Comments

KronicDeth picture KronicDeth  路  7Comments

bengro picture bengro  路  3Comments

Nicholi picture Nicholi  路  6Comments