<commit_before>package org.jetbrains.plugins.scala.editor.documentationProvider

import _root_.org.jetbrains.plugins.scala.lang.psi.types.ScType
import _root_.scala.collection.immutable.HashSet
import _root_.scala.collection.mutable.ArrayBuffer
import com.intellij.codeInsight.javadoc.JavaDocUtil
import com.intellij.lang.documentation.DocumentationProvider
import com.intellij.lang.java.JavaDocumentationProvider
import com.intellij.openapi.module.ModuleUtil
import com.intellij.psi._
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil
import lang.psi.api.base.patterns.ScReferencePattern
import lang.psi.api.base.ScPrimaryConstructor
import lang.psi.api.ScalaFile
import lang.psi.api.statements._
import lang.psi.api.statements.params.{ScClassParameter, ScParameter, ScParameterClause, ScTypeParam}
import lang.psi.api.toplevel.templates.{ScExtendsBlock, ScTemplateBody}
import lang.psi.api.toplevel.typedef._

import lang.psi.api.toplevel.{ScModifierListOwner, ScNamedElement, ScTyped, ScTypeParametersOwner}
import lang.psi.ScalaPsiUtil
import org.jetbrains.plugins.scala.lang.structureView.StructureViewUtil

/**
 * User: <NAME>
 * Date: 11.11.2008
 */

class ScalaDocumentationProvider extends DocumentationProvider {
  import ScalaDocumentationProvider._
  def getDocumentationElementForLookupItem(psiManager: PsiManager, `object` : Object, element: PsiElement): PsiElement = {
    null
  }

  def getUrlFor(element: PsiElement, originalElement: PsiElement): String = {
    null
  }

  def getQuickNavigateInfo(element: PsiElement): String = {
    element match {
      case clazz: ScTypeDefinition => generateClassInfo(clazz)
      case function: ScFunction => generateFunctionInfo(function)
      case value: ScNamedElement if ScalaPsiUtil.nameContext(value).isInstanceOf[ScValue]
              || ScalaPsiUtil.nameContext(value).isInstanceOf[ScVariable] => generateValueInfo(value)
      case alias: ScTypeAlias => generateTypeAliasInfo(alias)
      case parameter: ScParameter => generateParameterInfo(parameter)
      case _ => null
    }
  }

  def getDocumentationElementForLink(psiManager: PsiManager, link: String, context: PsiElement): PsiElement = {
    JavaDocUtil.findReferenceTarget(psiManager, link, context)
  }

  def generateDoc(element: PsiElement, originalElement: PsiElement): String = {
    var e = getDocedElement(element).getNavigationElement
    e match {
      case clazz: ScTypeDefinition => {
        val buffer: StringBuilder = new StringBuilder("")
        val qualName = clazz.getQualifiedName
        val pack = {
          val lastIndexOf = qualName.lastIndexOf(".", 0)
          if (lastIndexOf >= 0) qualName.substring(0, lastIndexOf) else ""
        }

        if (pack != "") buffer.append("<font size=\"-1\"><b>" + pack + "</b></font>")


        buffer.append("<PRE>")
        buffer.append(parseAnnotations(clazz))
        buffer.append(parseModifiers(clazz))
        buffer.append(clazz match {
          case _: ScClass => "class "
          case _: ScObject => "object "
          case _: ScTrait => "trait "
        })
        buffer.append("<b>" + clazz.name + "</b>")
        buffer.append(parseTypeParameters(clazz))
        clazz match {
          case par: ScParameterOwner => buffer.append(parseParameters(par))
          case _ =>
        }
        buffer.append("\n")
        buffer.append(parseExtendsBlock(clazz.extendsBlock))
        buffer.append("</PRE>")
        buffer.append(parseDocComment(clazz))

        return "<html><body>" + buffer.toString + "</body></html>"
      }
      case fun: ScFunction => {
        val buffer: StringBuilder = new StringBuilder("")
        buffer.append(parseClassUrl(fun))
        buffer.append("<PRE>")
        buffer.append(parseAnnotations(fun))
        buffer.append(parseModifiers(fun))
        buffer.append("def ")
        buffer.append("<b>" + fun.name + "</b>")
        buffer.append(parseTypeParameters(fun))
        buffer.append(parseParameters(fun))
        buffer.append(parseType(fun))
        buffer.append("</PRE>")
        buffer.append(parseDocComment(fun))
        return "<html><body>" + buffer.toString + "</body></html>"
      }
      case decl: ScDeclaredElementsHolder if decl.isInstanceOf[ScValue] || decl.isInstanceOf[ScVariable] => {
        val buffer: StringBuilder = new StringBuilder("")
        decl match {case decl: ScMember => buffer.append(parseClassUrl(decl)) case _ =>}
        buffer.append("<PRE>")
        decl match {case an: ScAnnotationsHolder => buffer.append(parseAnnotations(an)) case _ =>}
        decl match {case m: ScModifierListOwner => buffer.append(parseModifiers(m)) case _ =>}
        buffer.append(decl match {case _: ScValue => "val " case _: ScVariable => "var " case _ => ""})
        buffer.append("<b>" + (element match {case named: ScNamedElement => named.name case _ => "unknown"}) + "</b>")
        buffer.append(element match {case typed: ScTyped => parseType(typed) case _ => ": Nothing"} )
        buffer.append("</PRE>")
        decl match {case doc: ScDocCommentOwner => buffer.append(parseDocComment(doc)) case _ =>}
        return "<html><body>" + buffer.toString + "</body></html>"
      }
      case param: ScParameter => {
        val buffer: StringBuilder = new StringBuilder("")
        buffer.append("<PRE>")
        buffer.append(parseAnnotations(param))
        param match {case cl: ScClassParameter => buffer.append(parseModifiers(cl)) case _ => }
        buffer.append(param match {
          case c: ScClassParameter if c.isVal => "val "
          case c: ScClassParameter if c.isVar => "var "
          case _ => ""
        })
        buffer.append("<b>" + param.name + "</b>")
        buffer.append(parseType(param))
        return "<html><body>" + buffer.toString + "</body></html>"
      }
      case _: ScTypeAlias => {
        //tested code
        val codeText = """
         package test
         import com.sun.istack.internal.NotNull;

         @NotNull
         public class Test extends Object {
           public int x() {
             return 0;
           }
         }
         """
        val dummyFile: PsiJavaFile = PsiFileFactory.getInstance(element.getProject).
                createFileFromText("dummy" + ".java", codeText).asInstanceOf[PsiJavaFile]
        val javadoc = JavaDocumentationProvider.generateExternalJavadoc(dummyFile.getClasses.apply(0)/*.getAllMethods.apply(0)*/)
        println("\n" + javadoc)
      }
      case _ =>
    }
    null
  }
}

private object ScalaDocumentationProvider {
  private def parseType(elem: ScTyped): String = "" 
  private def parseClassUrl(elem: ScMember): String = {
    val clazz = elem.getContainingClass
    if (clazz == null) return ""
    return "<a href=\"psi_element://" + clazz.getQualifiedName + "\"><code>" + clazz.getQualifiedName + "</code></a>"
  }

  private def parseParameters(elem: ScParameterOwner): String = {
    elem.allClauses.map(parseParameterClause(_)).mkString("")
  }

  private def parseParameterClause(elem: ScParameterClause): String = {
    elem.parameters.map(parseParameter(_)).mkString(if (elem.isImplicit) "(implicit " else "(", ", ", ")")
  }

  private def parseParameter(param: ScParameter): String = {
    val buffer: StringBuilder = new StringBuilder("")
    buffer.append(parseAnnotations(param))
    param match {case cl: ScClassParameter => buffer.append(parseModifiers(cl)) case _ =>}
    buffer.append(param match {
      case c: ScClassParameter if c.isVal => "val "
      case c: ScClassParameter if c.isVar => "var "
      case _ => ""
    })
    buffer.append(param.name)
    buffer.append(parseType(param))
    buffer.toString
  }

  private def parseTypeParameters(elems: ScTypeParametersOwner): String = ""

  private def parseExtendsBlock(elem: ScExtendsBlock): String = ""

  private def parseModifiers(elem: ScModifierListOwner): String = ""

  private def parseAnnotations(elem: ScAnnotationsHolder): String = ""

  
  private def parseDocComment(elem: ScDocCommentOwner): String = {
    def getParams(fun: ScFunction): String = {
      fun.parameters.map((param: ScParameter) => "int     " + param.name).mkString("(", ",\n", ")")
    }<commit_msg>Ctrl + Q added typeParams<commit_after>package org.jetbrains.plugins.scala.editor.documentationProvider

import _root_.org.jetbrains.plugins.scala.lang.psi.types.ScType
import _root_.scala.collection.immutable.HashSet
import _root_.scala.collection.mutable.ArrayBuffer
import com.intellij.codeInsight.javadoc.JavaDocUtil
import com.intellij.lang.documentation.DocumentationProvider
import com.intellij.lang.java.JavaDocumentationProvider
import com.intellij.openapi.module.ModuleUtil
import com.intellij.psi._
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil
import lang.psi.api.base.patterns.ScReferencePattern
import lang.psi.api.base.ScPrimaryConstructor
import lang.psi.api.ScalaFile
import lang.psi.api.statements._
import lang.psi.api.statements.params.{ScClassParameter, ScParameter, ScParameterClause, ScTypeParam}
import lang.psi.api.toplevel.templates.{ScExtendsBlock, ScTemplateBody}
import lang.psi.api.toplevel.typedef._

import lang.psi.api.toplevel.{ScModifierListOwner, ScNamedElement, ScTyped, ScTypeParametersOwner}
import lang.psi.ScalaPsiUtil
import org.jetbrains.plugins.scala.lang.structureView.StructureViewUtil

/**
 * User: <NAME>
 * Date: 11.11.2008
 */

class ScalaDocumentationProvider extends DocumentationProvider {
  import ScalaDocumentationProvider._
  def getDocumentationElementForLookupItem(psiManager: PsiManager, `object` : Object, element: PsiElement): PsiElement = {
    null
  }

  def getUrlFor(element: PsiElement, originalElement: PsiElement): String = {
    null
  }

  def getQuickNavigateInfo(element: PsiElement): String = {
    element match {
      case clazz: ScTypeDefinition => generateClassInfo(clazz)
      case function: ScFunction => generateFunctionInfo(function)
      case value: ScNamedElement if ScalaPsiUtil.nameContext(value).isInstanceOf[ScValue]
              || ScalaPsiUtil.nameContext(value).isInstanceOf[ScVariable] => generateValueInfo(value)
      case alias: ScTypeAlias => generateTypeAliasInfo(alias)
      case parameter: ScParameter => generateParameterInfo(parameter)
      case _ => null
    }
  }

  def getDocumentationElementForLink(psiManager: PsiManager, link: String, context: PsiElement): PsiElement = {
    JavaDocUtil.findReferenceTarget(psiManager, link, context)
  }

  def generateDoc(element: PsiElement, originalElement: PsiElement): String = {
    var e = getDocedElement(element).getNavigationElement
    e match {
      case clazz: ScTypeDefinition => {
        val buffer: StringBuilder = new StringBuilder("")
        val qualName = clazz.getQualifiedName
        val pack = {
          val lastIndexOf = qualName.lastIndexOf(".", 0)
          if (lastIndexOf >= 0) qualName.substring(0, lastIndexOf) else ""
        }

        if (pack != "") buffer.append("<font size=\"-1\"><b>" + pack + "</b></font>")


        buffer.append("<PRE>")
        buffer.append(parseAnnotations(clazz))
        buffer.append(parseModifiers(clazz))
        buffer.append(clazz match {
          case _: ScClass => "class "
          case _: ScObject => "object "
          case _: ScTrait => "trait "
        })
        buffer.append("<b>" + clazz.name + "</b>")
        buffer.append(parseTypeParameters(clazz))
        clazz match {
          case par: ScParameterOwner => buffer.append(parseParameters(par))
          case _ =>
        }
        buffer.append("\n")
        buffer.append(parseExtendsBlock(clazz.extendsBlock))
        buffer.append("</PRE>")
        buffer.append(parseDocComment(clazz))

        return "<html><body>" + buffer.toString + "</body></html>"
      }
      case fun: ScFunction => {
        val buffer: StringBuilder = new StringBuilder("")
        buffer.append(parseClassUrl(fun))
        buffer.append("<PRE>")
        buffer.append(parseAnnotations(fun))
        buffer.append(parseModifiers(fun))
        buffer.append("def ")
        buffer.append("<b>" + fun.name + "</b>")
        buffer.append(parseTypeParameters(fun))
        buffer.append(parseParameters(fun))
        buffer.append(parseType(fun))
        buffer.append("</PRE>")
        buffer.append(parseDocComment(fun))
        return "<html><body>" + buffer.toString + "</body></html>"
      }
      case decl: ScDeclaredElementsHolder if decl.isInstanceOf[ScValue] || decl.isInstanceOf[ScVariable] => {
        val buffer: StringBuilder = new StringBuilder("")
        decl match {case decl: ScMember => buffer.append(parseClassUrl(decl)) case _ =>}
        buffer.append("<PRE>")
        decl match {case an: ScAnnotationsHolder => buffer.append(parseAnnotations(an)) case _ =>}
        decl match {case m: ScModifierListOwner => buffer.append(parseModifiers(m)) case _ =>}
        buffer.append(decl match {case _: ScValue => "val " case _: ScVariable => "var " case _ => ""})
        buffer.append("<b>" + (element match {case named: ScNamedElement => named.name case _ => "unknown"}) + "</b>")
        buffer.append(element match {case typed: ScTyped => parseType(typed) case _ => ": Nothing"} )
        buffer.append("</PRE>")
        decl match {case doc: ScDocCommentOwner => buffer.append(parseDocComment(doc)) case _ =>}
        return "<html><body>" + buffer.toString + "</body></html>"
      }
      case param: ScParameter => {
        val buffer: StringBuilder = new StringBuilder("")
        buffer.append("<PRE>")
        buffer.append(parseAnnotations(param))
        param match {case cl: ScClassParameter => buffer.append(parseModifiers(cl)) case _ => }
        buffer.append(param match {
          case c: ScClassParameter if c.isVal => "val "
          case c: ScClassParameter if c.isVar => "var "
          case _ => ""
        })
        buffer.append("<b>" + param.name + "</b>")
        buffer.append(parseType(param))
        return "<html><body>" + buffer.toString + "</body></html>"
      }
      case _: ScTypeAlias => {
        //tested code
        val codeText = """
         package test
         import com.sun.istack.internal.NotNull;

         @NotNull
         public class Test extends Object {
           public int x() {
             return 0;
           }
         }
         """
        val dummyFile: PsiJavaFile = PsiFileFactory.getInstance(element.getProject).
                createFileFromText("dummy" + ".java", codeText).asInstanceOf[PsiJavaFile]
        val javadoc = JavaDocumentationProvider.generateExternalJavadoc(dummyFile.getClasses.apply(0)/*.getAllMethods.apply(0)*/)
        println("\n" + javadoc)
      }
      case _ =>
    }
    null
  }
}

private object ScalaDocumentationProvider {
  private def parseType(elem: ScTyped): String = "" 
  private def parseClassUrl(elem: ScMember): String = {
    val clazz = elem.getContainingClass
    if (clazz == null) return ""
    return "<a href=\"psi_element://" + clazz.getQualifiedName + "\"><code>" + clazz.getQualifiedName + "</code></a>"
  }

  private def parseParameters(elem: ScParameterOwner): String = {
    elem.allClauses.map(parseParameterClause(_)).mkString("")
  }

  private def parseParameterClause(elem: ScParameterClause): String = {
    elem.parameters.map(parseParameter(_)).mkString(if (elem.isImplicit) "(implicit " else "(", ", ", ")")
  }

  private def parseParameter(param: ScParameter): String = {
    val buffer: StringBuilder = new StringBuilder("")
    buffer.append(parseAnnotations(param))
    param match {case cl: ScClassParameter => buffer.append(parseModifiers(cl)) case _ =>}
    buffer.append(param match {
      case c: ScClassParameter if c.isVal => "val "
      case c: ScClassParameter if c.isVar => "var "
      case _ => ""
    })
    buffer.append(param.name)
    buffer.append(parseType(param))
    buffer.toString
  }

  private def parseTypeParameters(elems: ScTypeParametersOwner): String = {
    elems.typeParameters.map(_.name).mkString("[", ", ", "]")
  }

  private def parseExtendsBlock(elem: ScExtendsBlock): String = ""

  private def parseModifiers(elem: ScModifierListOwner): String = ""

  private def parseAnnotations(elem: ScAnnotationsHolder): String = ""

  
  private def parseDocComment(elem: ScDocCommentOwner): String = {
    def getParams(fun: ScFunction): String = {
      fun.parameters.map((param: ScParameter) => "int     " + param.name).mkString("(", ",\n", ")")
    }
{'fraction_non_alphanumeric': 0.12948679016094747, 'fraction_numerical': 0.0018220467658669906, 'mean_word_length': 3.3286014721345953, 'pattern_counts': {'":': 2, '<': 83, '<?xml version=': 0, '>': 171, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '5941608', 'n_tokens_mistral': 4767, 'n_tokens_neox': 4712, 'n_words': 952}