<commit_before>/*
 * Copyright (c) 2014 Contributor. All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Scala License which accompanies this distribution, and
 * is available at http://www.scala-lang.org/license.html
 */
package org.scalaide.ui.internal.editor.decorators.implicits

import scala.reflect.internal.util.SourceFile
import org.scalaide.ui.internal.editor.decorators.BaseSemanticAction
import org.eclipse.jface.preference.IPreferenceStore
import org.eclipse.jface.text.Position
import org.eclipse.jface.text.Region
import org.eclipse.jface.text.source.Annotation
import org.eclipse.jface.text.source.ISourceViewer
import org.scalaide.core.IScalaPlugin
import org.scalaide.core.internal.compiler.ScalaPresentationCompiler
import org.scalaide.core.hyperlink.Hyperlink
import org.scalaide.core.hyperlink.HyperlinkFactory
import org.scalaide.core.internal.jdt.model.ScalaCompilationUnit
import org.scalaide.ui.internal.preferences.ImplicitsPreferencePage
import org.scalaide.core.compiler.IScalaPresentationCompiler

/**
 * Semantic action for highlighting implicit conversions and parameters.
 */
class ImplicitHighlightingPresenter(sourceViewer: ISourceViewer)
  extends BaseSemanticAction(
    sourceViewer,
    ImplicitAnnotation.ID,
    Some("implicit")) {

  protected override def findAll(compiler: ScalaPresentationCompiler, scu: ScalaCompilationUnit, sourceFile: SourceFile): Map[Annotation, Position] =
    ImplicitHighlightingPresenter.findAllImplicitConversions(compiler, scu, sourceFile)
}

object ImplicitHighlightingPresenter {
  final val DisplayStringSeparator = " => "

  private def pluginStore: IPreferenceStore = IScalaPlugin().getPreferenceStore

  def findAllImplicitConversions(compiler: IScalaPresentationCompiler, scu: ScalaCompilationUnit, sourceFile: SourceFile) = {
    import compiler.Tree
    import compiler.Traverser
    import compiler.Apply
    import compiler.Select
    import compiler.ApplyImplicitView
    import compiler.ApplyToImplicitArgs

    object ImplicitHyperlinkFactory extends HyperlinkFactory {
      protected val global: compiler.type = compiler
    }

    def mkPosition(pos: compiler.Position, txt: String): Position = {
      val start = pos.start
      val end = if (pluginStore.getBoolean(ImplicitsPreferencePage.P_FIRST_LINE_ONLY)) {
        val eol = txt.indexOf('\n')
        if (eol > -1) eol else txt.length
      } else txt.length

      new Position(start, end)
    }

    def mkImplicitConversionAnnotation(t: ApplyImplicitView) = {
      val txt = new String(sourceFile.content, t.pos.start, math.max(0, t.pos.end - t.pos.start)).trim()
      val pos = mkPosition(t.pos, txt)
      val region = new Region(pos.offset, pos.getLength)
      val annotation = new ImplicitConversionAnnotation(
          () => ImplicitHyperlinkFactory.create(Hyperlink.withText("Open Implicit"), scu, t.symbol, region),
          s"Implicit conversion found: `$txt`$DisplayStringSeparator`${t.fun.symbol.name}($txt): ${t.tpe}`")<commit_msg>Prevent Race Condition in mkImplicitConversionAnnotation<commit_after>/*
 * Copyright (c) 2014 Contributor. All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Scala License which accompanies this distribution, and
 * is available at http://www.scala-lang.org/license.html
 */
package org.scalaide.ui.internal.editor.decorators.implicits

import scala.reflect.internal.util.SourceFile
import org.scalaide.ui.internal.editor.decorators.BaseSemanticAction
import org.eclipse.jface.preference.IPreferenceStore
import org.eclipse.jface.text.Position
import org.eclipse.jface.text.Region
import org.eclipse.jface.text.source.Annotation
import org.eclipse.jface.text.source.ISourceViewer
import org.scalaide.core.IScalaPlugin
import org.scalaide.core.internal.compiler.ScalaPresentationCompiler
import org.scalaide.core.hyperlink.Hyperlink
import org.scalaide.core.hyperlink.HyperlinkFactory
import org.scalaide.core.internal.jdt.model.ScalaCompilationUnit
import org.scalaide.ui.internal.preferences.ImplicitsPreferencePage
import org.scalaide.core.compiler.IScalaPresentationCompiler

/**
 * Semantic action for highlighting implicit conversions and parameters.
 */
class ImplicitHighlightingPresenter(sourceViewer: ISourceViewer)
  extends BaseSemanticAction(
    sourceViewer,
    ImplicitAnnotation.ID,
    Some("implicit")) {

  protected override def findAll(compiler: ScalaPresentationCompiler, scu: ScalaCompilationUnit, sourceFile: SourceFile): Map[Annotation, Position] =
    ImplicitHighlightingPresenter.findAllImplicitConversions(compiler, scu, sourceFile)
}

object ImplicitHighlightingPresenter {
  final val DisplayStringSeparator = " => "

  private def pluginStore: IPreferenceStore = IScalaPlugin().getPreferenceStore

  def findAllImplicitConversions(compiler: IScalaPresentationCompiler, scu: ScalaCompilationUnit, sourceFile: SourceFile) = {
    import compiler.Tree
    import compiler.Traverser
    import compiler.Apply
    import compiler.Select
    import compiler.ApplyImplicitView
    import compiler.ApplyToImplicitArgs

    object ImplicitHyperlinkFactory extends HyperlinkFactory {
      protected val global: compiler.type = compiler
    }

    def mkPosition(pos: compiler.Position, txt: String): Position = {
      val start = pos.start
      val end = if (pluginStore.getBoolean(ImplicitsPreferencePage.P_FIRST_LINE_ONLY)) {
        val eol = txt.indexOf('\n')
        if (eol > -1) eol else txt.length
      } else txt.length

      new Position(start, end)
    }

    def mkImplicitConversionAnnotation(t: ApplyImplicitView) = {
      import org.scalaide.core.compiler.IScalaPresentationCompiler.Implicits.RichResponse
      val txt = new String(sourceFile.content, t.pos.start, math.max(0, t.pos.end - t.pos.start)).trim()
      val pos = mkPosition(t.pos, txt)
      val region = new Region(pos.offset, pos.getLength)
      val sname = scu.withSourceFile((_, compiler) => compiler.asyncExec{t.fun.symbol.name}.getOption()).flatten
      val annotation = new ImplicitConversionAnnotation(
          () => ImplicitHyperlinkFactory.create(Hyperlink.withText("Open Implicit"), scu, t.symbol, region),
          s"Implicit conversion found: `$txt`$DisplayStringSeparator`${sname.getOrElse("")}($txt): ${t.tpe}`")
{'fraction_non_alphanumeric': 0.09146725440806046, 'fraction_numerical': 0.001889168765743073, 'mean_word_length': 4.812442817932296, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6993491', 'n_tokens_mistral': 1864, 'n_tokens_neox': 1801, 'n_words': 394}