/* sxr -- Scala X-Ray
 * Copyright 2009 Mark Harrah
 */

package sxr

import scala.tools.nsc.{ast, plugins, symtab, util, Global}
import ast.parser.Tokens
import plugins.Plugin
import symtab.Flags
import util.SourceFile
import scala.collection.jcl.{TreeMap, TreeSet}

import java.io.{File, Reader, Writer}

/** The actual work extracting symbols and types is done here. */
abstract class class Browse extends scala.tools.nsc.plugins.Plugin with ScalaObjectBrowse extends scala.tools.nsc.plugins.PluginPlugin
{
	/** The directory to which the annotated sources will be written. */
	def => java.io.FileoutputDirectory: java.io.FileFile
	/** The directory against which the input source paths will be relativized.*/
	def => Option[java.io.File]baseDirectory: Option[java.io.File]Option[File]
	/** The compiler.*/
	val => scala.tools.nsc.Globalglobal: scala.tools.nsc.GlobalGlobal
	
	import global._
	import Browse._

	/** The entry method for producing a set of html files and auxiliary javascript and CSS files that
	* annotate the source code for display in a web browser. */
	def ()UnitgenerateOutput()
	{
		val java.io.FilecssFile = (java.io.File,java.lang.String)java.io.Filenew java.io.FileFile(=> java.io.FileoutputDirectory, => java.lang.StringCSSRelativePath)
		val java.io.FilejsFile = (java.io.File,java.lang.String)java.io.Filenew java.io.FileFile(=> java.io.FileoutputDirectory, => java.lang.StringJSRelativePath)
		(java.io.File)UnitwriteDefaultCSS(java.io.FilecssFile)
		(java.io.File)UnitwriteJS(java.io.FilejsFile)
		var List[java.io.File]outputFiles = object NilList[File]()
		for(((Browse.this.global.CompilationUnit) => Unit)Unitunit <- => Browse.this.global.RuncurrentRun.=> Iterator[Browse.this.global.CompilationUnit]units)
		{
			val java.io.FilesourceFile = Browse.this.global.CompilationUnitunit.=> scala.tools.nsc.util.SourceFilesource.=> scala.tools.nsc.io.AbstractFilefile.=> java.io.Filefile
			val StringrelativeSourcePath = (java.io.File)StringgetRelativeSourcePath(java.io.FilesourceFile)
			val java.io.FileoutputFile = (java.io.File,java.lang.String)java.io.Filenew java.io.FileFile(=> java.io.FileoutputDirectory, StringrelativeSourcePath (Any)java.lang.String+ java.lang.String(".html")".html")
			List[java.io.File]outputFiles (java.io.File)List[java.io.File]::= java.io.FileoutputFile
			val StringrelativizedCSSPath = object sxr.FileUtilFileUtil.(java.io.File,java.io.File)StringrelativePath(java.io.FileoutputFile, java.io.FilecssFile)
			val StringrelativizedJSPath = object sxr.FileUtilFileUtil.(java.io.File,java.io.File)StringrelativePath(java.io.FileoutputFile, java.io.FilejsFile)

			// generate the tokens
			val scala.collection.jcl.TreeSet[sxr.Token]tokens = (Browse.this.global.CompilationUnit)scala.collection.jcl.TreeSet[sxr.Token]scan(Browse.this.global.CompilationUnitunit)
			val Browse.this.Traversetraverser = Browse.this.Traversenew Browse.this.TraverseTraverse(scala.collection.jcl.TreeSet[sxr.Token]tokens, Browse.this.global.CompilationUnitunit.=> scala.tools.nsc.util.SourceFilesource)
			(Browse.this.global.Tree)Browse.this.global.Treetraverser(Browse.this.global.CompilationUnitunit.=> Browse.this.global.Treebody)

			val sxr.BasicStylerstyler = sxr.BasicStylernew sxr.BasicStylerBasicStyler(scala.collection.jcl.TreeSet[sxr.Token]tokens, StringrelativeSourcePath, StringrelativizedCSSPath, StringrelativizedJSPath)
			(java.io.File,java.io.File,scala.collection.jcl.TreeSet[sxr.Token],sxr.Styler)UnitAnnotate(java.io.FilesourceFile, java.io.FileoutputFile, scala.collection.jcl.TreeSet[sxr.Token]tokens, sxr.BasicStylerstyler)
		}
		val java.io.FileindexFile = (java.io.File,java.lang.String)java.io.Filenew java.io.FileFile(=> java.io.FileoutputDirectory, => java.lang.StringIndexRelativePath)
		(java.io.File,Iterable[java.io.File])UnitwriteIndex(java.io.FileindexFile, List[java.io.File]outputFiles)
	}
	/** Tokenizes the given source.  The tokens are put into an ordered set by the start position of the token.
	* Symbols will be mapped back to these tokens by the offset of the symbol.*/
	private def (Browse.this.global.CompilationUnit)scala.collection.jcl.TreeSet[sxr.Token]scan(Browse.this.global.CompilationUnitunit: Browse.this.global.CompilationUnitCompilationUnit) =
	{
		val scala.collection.jcl.TreeSet[sxr.Token]tokens = scala.collection.jcl.TreeSet[sxr.Token]new scala.collection.jcl.TreeSet[sxr.Token]TreeSet[Token]
		val Browse.this.global.syntaxAnalyzer.UnitScannerscanner = template $anon extends Browse.this.global.syntaxAnalyzer.UnitScannernew object Browse.this.global.syntaxAnalyzersyntaxAnalyzer.Browse.this.global.syntaxAnalyzer.UnitScannerUnitScanner(Browse.this.global.CompilationUnitunit) { override def => Unitinit Unit{} }
		for( (((Int, Int, Int)) => Unit)Unit(Intoffset, Intlength, Intcode) <- Browse.this.global.syntaxAnalyzer.UnitScannerscanner.=> <refinement> extends java.lang.Object with Iterator[(Int, Int, Int)]iterator)
		{
			Unitif((Int)BooleanincludeToken(Intcode))
				scala.collection.jcl.TreeSet[sxr.Token]tokens (sxr.Token)Unit+= sxr.Tokennew sxr.TokenToken(Intoffset, Intlength, Intcode)
		}
		scala.collection.jcl.TreeSet[sxr.Token]tokens
	}
	/** Filters out unwanted tokens such as whitespace and commas.  Braces are currently
	* included because () is annotated as Unit, and a partial function created by
	* { case ... } is associated with the opening brace.  */
	private def (Int)BooleanincludeToken(Intcode: IntInt) =
	{
		import Tokens.{COMMENT, USCORE, isBrace, isKeyword, isIdentifier, isLiteral}
		Intcode Booleanmatch
		{
			Boolean(true)case Int(97)COMMENT | Int(73)USCORE => Boolean(true)true
			Booleancase _ => (Int)BooleanisKeyword(Intcode) (Boolean)Boolean|| (Int)BooleanisIdentifier(Intcode) (Boolean)Boolean|| (Int)BooleanisLiteral(Intcode) (Boolean)Boolean|| (Int)BooleanisBrace(Intcode)
		}
	}
	/** Gets the token for the given offset.*/
	private def (scala.collection.jcl.TreeSet[sxr.Token],Int)Option[sxr.Token]tokenAt(scala.collection.jcl.TreeSet[sxr.Token]tokens: scala.collection.jcl.TreeSet[sxr.Token]TreeSet[Token], Intoffset: IntInt): Option[sxr.Token]Option[Token] =
	{
		// create artificial tokens to get a subset of the tokens starting at the given offset
		val tokens.SortedSelfinRange = scala.collection.jcl.TreeSet[sxr.Token]tokens.(sxr.Token,sxr.Token)tokens.SortedSelfrange(sxr.Tokennew sxr.TokenToken(Intoffset, Int(1)1, Int(0)0), sxr.Tokennew sxr.TokenToken(Intoffset(Int)Int+Int(1)1, Int(1)1, Int(0)0))
		// then, take the first token in the range
		Option[sxr.Token]if(tokens.SortedSelfinRange.=> BooleanisEmpty)
			object NoneNone
		else
			(sxr.Token)Some[sxr.Token]Some(tokens.SortedSelfinRange.=> sxr.TokenfirstKey)
	}

	/** Filters unwanted symbols, such as packages.*/
	private def (Browse.this.global.Symbol)Booleanignore(Browse.this.global.Symbols: Browse.this.global.SymbolSymbol): BooleanBoolean =
		(Browse.this.global.Symbol)BooleanignoreBase(Browse.this.global.Symbols) (Boolean)Boolean||
		Browse.this.global.Symbols.=> BooleanisModuleClass (Boolean)Boolean|| // ignore the generated class for modules
		Browse.this.global.Symbols.=> BooleanisPrimaryConstructor // the primary constructor overlaps with the class type, so just use the class type
	private def (Browse.this.global.Symbol)BooleanignoreBase(Browse.this.global.Symbols: Browse.this.global.SymbolSymbol): BooleanBoolean =
		=> Boolean!Browse.this.global.Symbols.=> Booleanexists (Boolean)Boolean||
		Browse.this.global.Symbols.=> BooleanisPackage (Boolean)Boolean|| // nothing done with packages
		Browse.this.global.Symbols.=> BooleanisImplClass
		
	private class class Traverse extends Browse.this.global.Traverser with ScalaObjectTraverse(scala.collection.jcl.TreeSet[sxr.Token]tokens: scala.collection.jcl.TreeSet[sxr.Token]TreeSet[Token], scala.tools.nsc.util.SourceFilesource: scala.tools.nsc.util.SourceFileSourceFile) extends Browse.this.global.TraverserTraverser
	{
		// magic method #1
		override def (Browse.this.global.Tree)Unittraverse(Browse.this.global.Treetree: Browse.this.global.TreeTree)
		{
			def ()UnithandleDefault()
			{
				(Browse.this.global.Tree)Unitprocess(Browse.this.global.Treetree)
				super.(Browse.this.global.Tree)Unittraverse(Browse.this.global.Treetree)
			}
			Browse.this.global.Treetree Unitmatch
			{
				Unitcase ValDef(_, _, _, Browse.this.global.Treerhs) =>
					// tests for synthetic val created for the x in x :: Nil, which would associate the wrong type with ::
					// because the synthetic val is associated with the :: token
					Unitif(Browse.this.global.Treetree.=> Browse.this.global.Symbolsymbol (AnyRef)Boolean!= Null(null)null (Boolean)Boolean&& Browse.this.global.Treetree.=> Browse.this.global.Symbolsymbol.(Long)BooleanhasFlag(Flags.Long(2097152L)SYNTHETIC))
						(Browse.this.global.Tree)Unittraverse(Browse.this.global.Treerhs)
					else
						()UnithandleDefault()
				Unitcase Template(List[Browse.this.global.Tree]parents, Browse.this.global.ValDefself, List[Browse.this.global.Tree]body) =>
					// If the first parent in the source is a trait, the first parent in parents will be AnyRef and it will
					// use the trait's token, bumping the trait.  So, this hack processes traits first
					val (List[Browse.this.global.Tree], List[Browse.this.global.Tree])(List[Browse.this.global.Tree]traits, List[Browse.this.global.Tree]notTraits) = List[Browse.this.global.Tree]parents.((Browse.this.global.Tree) => Boolean)(List[Browse.this.global.Tree], List[Browse.this.global.Tree])partition(Browse.this.global.Tree_.=> Browse.this.global.Symbolsymbol.=> BooleanisTrait)
					(List[Browse.this.global.Tree])UnittraverseTrees(List[Browse.this.global.Tree]traits)
					(List[Browse.this.global.Tree])UnittraverseTrees(List[Browse.this.global.Tree]notTraits)
					Unitif (=> Boolean!Browse.this.global.ValDefself.=> BooleanisEmpty) (Browse.this.global.Tree)Unittraverse(Browse.this.global.ValDefself)
					(List[Browse.this.global.Tree],Browse.this.global.Symbol)UnittraverseStats(List[Browse.this.global.Tree]body, Browse.this.global.Treetree.=> Browse.this.global.Symbolsymbol)
				/*case DefDef(_, _, tparams, vparamss, _, rhs) =>
					atOwner(tree.symbol) {
						traverseTrees(tparams); traverseTreess(vparamss); traverse(rhs)
					}*/
				Unitcase _ =>
					()UnithandleDefault()
			}
		}
		
		// magic method #2
		private def (Browse.this.global.Tree)Unitprocess(Browse.this.global.Treet: Browse.this.global.TreeTree)
		{
			for(((scala.tools.nsc.util.SourceFile) => Unit)UnittSource <- Browse.this.global.Treet.=> scala.tools.nsc.util.Positionpos.=> Option[scala.tools.nsc.util.SourceFile]source if scala.tools.nsc.util.SourceFiletSource (AnyRef)Boolean== scala.tools.nsc.util.SourceFilesource; ((Int) => Unit)Unitoffset <- Browse.this.global.Treet.=> scala.tools.nsc.util.Positionpos.=> Option[Int]offset; ((sxr.Token) => Unit)Unittoken <- (scala.collection.jcl.TreeSet[sxr.Token],Int)Option[sxr.Token]tokenAt(scala.collection.jcl.TreeSet[sxr.Token]tokens, Intoffset))
			{
				def ()UnitprocessDefaultSymbol() =
				{
					Unitif(Browse.this.global.Treet.=> BooleanhasSymbol (Boolean)Boolean&& => Boolean!(Browse.this.global.Symbol)Booleanignore(Browse.this.global.Treet.=> Browse.this.global.Symbolsymbol))
						(Browse.this.global.Tree,sxr.Token,java.io.File)UnitprocessSymbol(Browse.this.global.Treet, sxr.Tokentoken, scala.tools.nsc.util.SourceFilesource.=> scala.tools.nsc.io.AbstractFilefile.=> java.io.Filefile)
				}
				def ()UnitprocessSimple() { sxr.Tokentoken.(sxr.TypeAttribute)Unittpe = (String,Option[sxr.Link])sxr.TypeAttributeTypeAttribute((Browse.this.global.Type)StringtypeString(Browse.this.global.Treet.=> Browse.this.global.Typetpe), object NoneNone) }
				def (Browse.this.global.TypeTree)UnitprocessTypeTree(Browse.this.global.TypeTreett: Browse.this.global.TypeTreeTypeTree) { Unitif(=> Boolean!(Browse.this.global.Symbol)Booleanignore(Browse.this.global.TypeTreett.=> Browse.this.global.Symbolsymbol)) (Browse.this.global.Tree,sxr.Token,java.io.File)UnitprocessSymbol(Browse.this.global.TypeTreett, sxr.Tokentoken, scala.tools.nsc.util.SourceFilesource.=> scala.tools.nsc.io.AbstractFilefile.=> java.io.Filefile) }
				Browse.this.global.Treet Unitmatch
				{
					Unitcase _: Browse.this.global.ClassDefClassDef => ()UnitprocessDefaultSymbol()
					Unitcase _: Browse.this.global.ModuleDefModuleDef => ()UnitprocessDefaultSymbol()
					Unitcase _: Browse.this.global.ValOrDefDefValOrDefDef => ()UnitprocessDefaultSymbol()
					Unitcase _: Browse.this.global.TypeDefTypeDef => ()UnitprocessDefaultSymbol()
					//case _: Super => processDefaultSymbol()
					Unitcase _: Browse.this.global.ThisThis => ()UnitprocessDefaultSymbol()
					Unitcase Browse.this.global.Selects: Browse.this.global.SelectSelect => ()UnitprocessDefaultSymbol()
					Unitcase _: Browse.this.global.NewNew => ()UnitprocessSimple()
					Unitcase _: Browse.this.global.SequenceSequence => ()UnitprocessDefaultSymbol()
					Unitcase _: Browse.this.global.AlternativeAlternative => ()UnitprocessDefaultSymbol()
					Unitcase _: Browse.this.global.StarStar => ()UnitprocessDefaultSymbol()
					Unitcase _: Browse.this.global.BindBind => ()UnitprocessDefaultSymbol()
					Unitcase Apply(Browse.this.global.Treefun, List[Browse.this.global.Tree]args) => //processDefaultSymbol()
						/*fun match
						{
							case tt: TypeTree => if(!ignoreBase(tt.symbol)) processTypeTree(tt)
							case _ => traverse(fun)
						}
						traverseTrees(args)*/
					//case _: Import => processSimple()
					Unitcase _: Browse.this.global.ReturnReturn => ()UnitprocessSimple()
					Unitcase _: Browse.this.global.IfIf => ()UnitprocessSimple()
					Unitcase _: Browse.this.global.MatchMatch => ()UnitprocessSimple() // this will annotate the 'match' keyword with the type returned by the associated pattern match
					Unitcase _: Browse.this.global.CaseDefCaseDef => ()UnitprocessSimple() // this will annotate the 'case' keyword with the type returned by that particular case statement
					Unitcase _: Browse.this.global.ThrowThrow => ()UnitprocessSimple()
					Unitcase Browse.this.global.TypeApplyta: Browse.this.global.TypeApplyTypeApply => ()UnitprocessSimple() // this fills in type parameters for methods
					Unitcase Ident(_) => ()UnitprocessDefaultSymbol()
					Unitcase Literal(Browse.this.global.Constantvalue) => ()UnitprocessSimple() // annotate literals
					Unitcase Browse.this.global.TypeTreett: Browse.this.global.TypeTreeTypeTree =>
						Unitif(sxr.Tokentoken.=> BooleanisPlain)
							(Browse.this.global.Tree,sxr.Token,java.io.File)UnitprocessSymbol(Browse.this.global.TypeTreett, sxr.Tokentoken, scala.tools.nsc.util.SourceFilesource.=> scala.tools.nsc.io.AbstractFilefile.=> java.io.Filefile)
					Unitcase _ => Unit()
				}
			}
		}
	}
		// magic method #3
	private def (Browse.this.global.Tree,sxr.Token,java.io.File)UnitprocessSymbol(Browse.this.global.Treet: Browse.this.global.TreeTree, sxr.Tokentoken: sxr.TokenToken, java.io.FilesourceFile: java.io.FileFile)
	{
		val Browse.this.global.Symbolsym = Browse.this.global.Treet.=> Browse.this.global.Symbolsymbol
		Browse.this.global.Symbolsym Unitmatch
		{
			Unitcase Browse.this.global.TermSymbolts: Browse.this.global.TermSymbolTermSymbol =>
				val Browse.this.global.TypesType =
					Browse.this.global.Treet Browse.this.global.Typematch
					{
						Browse.this.global.Typecase Browse.this.global.ApplyDynamicad: Browse.this.global.ApplyDynamicApplyDynamic => Browse.this.global.ApplyDynamicad.=> Browse.this.global.Treequal.=> Browse.this.global.Typetpe.(Browse.this.global.Symbol)Browse.this.global.TypememberType(Browse.this.global.ApplyDynamicad.=> Browse.this.global.Symbolsymbol)
						Browse.this.global.Typecase Browse.this.global.Selects: Browse.this.global.SelectSelect => Browse.this.global.Selects.=> Browse.this.global.Treequalifier.=> Browse.this.global.Typetpe.(Browse.this.global.Symbol)Browse.this.global.TypememberType(Browse.this.global.Selects.=> Browse.this.global.Symbolsymbol)
						Browse.this.global.Typecase _ => Browse.this.global.TermSymbolts.=> Browse.this.global.Symbolowner.=> Browse.this.global.TypethisType.(Browse.this.global.Symbol)Browse.this.global.TypememberType(Browse.this.global.TermSymbolts)
					}
				Unitif(Browse.this.global.TypesType (AnyRef)Boolean!= Null(null)null)
				{
					val java.lang.StringasString =
						Browse.this.global.TypesType java.lang.Stringmatch
						{
							java.lang.Stringcase Browse.this.global.MethodTypemt: Browse.this.global.MethodTypeMethodType if Browse.this.global.TermSymbolts.(Long)BooleanhasFlag(Flags.Long(512L)IMPLICIT)=> java.lang.String("implicit ")"implicit " (Any)java.lang.String+ (Browse.this.global.Symbol)StringfullName(Browse.this.global.Symbolsym) (Any)java.lang.String+ java.lang.String(" : ")" : " (Any)java.lang.String+ (Browse.this.global.Type)StringtypeString(Browse.this.global.TypesType)
							Stringcase _ => (Browse.this.global.Type)StringtypeString(Browse.this.global.TypesType)
						}
					//println("Term symbol " + sym.id + ": " + asString)
					sxr.Tokentoken.(sxr.TypeAttribute)Unittpe = (String,Option[sxr.Link])sxr.TypeAttributeTypeAttribute(java.lang.StringasString, (java.io.File,Browse.this.global.Symbol)Option[sxr.Link]linkTo(java.io.FilesourceFile, Browse.this.global.TypesType.=> Browse.this.global.SymboltypeSymbol))
				}
			Unitcase Browse.this.global.TypeSymbolts: Browse.this.global.TypeSymbolTypeSymbol =>
				val Browse.this.global.TypetreeType = Browse.this.global.Treet.=> Browse.this.global.Typetpe
				val Browse.this.global.TypesType =
					Browse.this.global.Typeif(Browse.this.global.TypetreeType (AnyRef)Boolean== object Browse.this.global.NoTypeNoType) Browse.this.global.TypeSymbolts.=> Browse.this.global.Typeinfo
					else Browse.this.global.TypetreeType
				//println("Type symbol " + sym.id + ": " + typeString(sType))
				Unitif(Browse.this.global.TypesType (AnyRef)Boolean!= Null(null)null)
					sxr.Tokentoken.(sxr.TypeAttribute)Unittpe = (String,Option[sxr.Link])sxr.TypeAttributeTypeAttribute((Browse.this.global.Type)StringtypeString(Browse.this.global.TypesType), (java.io.File,Browse.this.global.Symbol)Option[sxr.Link]linkTo(java.io.FilesourceFile, Browse.this.global.TypesType.=> Browse.this.global.SymboltypeSymbol))
			Unitcase _ => Unit()
		}
		Unitif(Browse.this.global.Symbolsym (AnyRef)Boolean!= Null(null)null)
		{
			Unitif(Browse.this.global.Treet.=> BooleanisDef)
				sxr.Tokentoken (Int)Unit+= Browse.this.global.Symbolsym.=> Intid
			else
			{
				(java.io.File,Browse.this.global.Symbol)Option[sxr.Link]linkTo(java.io.FilesourceFile, Browse.this.global.Symbolsym) Unitmatch
				{
					Unitcase Some(sxr.Linkx) => sxr.Tokentoken.(sxr.Link)Unitreference = sxr.Linkx
					Unitcase object NoneNone => sxr.Tokentoken (Int)Unit+= Browse.this.global.Symbolsym.=> Intid
				}
			}
		}
	}
	/** Constructs a decoded fully qualified name for the given symbol. */
	private def (Browse.this.global.Symbol)StringfullName(Browse.this.global.Symbols: Browse.this.global.SymbolSymbol): StringString =
	{
		(Boolean)Unitrequire(Browse.this.global.Symbols (AnyRef)Boolean!= object Browse.this.global.NoSymbolNoSymbol)
		val Browse.this.global.Symbolowner = Browse.this.global.Symbols.=> Browse.this.global.Symbolowner
		(Boolean)Unitrequire(Browse.this.global.Symbolowner (AnyRef)Boolean!= object Browse.this.global.NoSymbolNoSymbol)
		Stringif(Browse.this.global.Symbolowner.=> BooleanisRoot (Boolean)Boolean|| Browse.this.global.Symbolowner.=> BooleanisEmptyPackageClass)
			Browse.this.global.Symbols.=> StringnameString
		else
			(Browse.this.global.Symbol)StringfullName(Browse.this.global.Symbolowner.=> Browse.this.global.SymbolenclClass) (Any)java.lang.String+ java.lang.String(".")"." (Any)java.lang.String+ Browse.this.global.Symbols.=> StringnameString
	}
	/** Produces a string for the given type that should be informative, but brief.*/
	private def (Browse.this.global.Type)StringtypeString(Browse.this.global.Typet: Browse.this.global.TypeType): StringString =
	{
		Browse.this.global.Typet Stringmatch
		{
			java.lang.Stringcase Browse.this.global.CompoundTypect: Browse.this.global.CompoundTypeCompoundType => (Browse.this.global.CompoundType,String)java.lang.StringcompoundTypeString(Browse.this.global.CompoundTypect, java.lang.String("")"")// tries to reduce size of some type strings
			Stringcase Browse.this.global.PolyTypept: Browse.this.global.PolyTypePolyType =>
				import pt._
				Stringif(=> List[Browse.this.global.Symbol]typeParams.=> BooleanisEmpty)
					java.lang.String("=> ")"=> " (Any)java.lang.String+ (Browse.this.global.Type)StringtypeString(=> Browse.this.global.TyperesultType)
				else
				{
					val StringtypeParameters = => List[Browse.this.global.Symbol]typeParams.((Browse.this.global.Symbol) => String)List[String]map(Browse.this.global.Symbol_.=> StringdefString).(String,String,String)StringmkString(java.lang.String("[")"[", java.lang.String(", ")", ", java.lang.String("]")"]")
					=> Browse.this.global.TyperesultType Stringmatch
					{
						java.lang.Stringcase Browse.this.global.CompoundTypect: Browse.this.global.CompoundTypeCompoundType => (Browse.this.global.CompoundType,String)java.lang.StringcompoundTypeString(Browse.this.global.CompoundTypect, StringtypeParameters)
						java.lang.Stringcase _ => StringtypeParameters (Any)java.lang.String+ (Browse.this.global.Type)StringtypeString(=> Browse.this.global.TyperesultType)
					}
				}
			Stringcase _ =>
				Stringif(Browse.this.global.Typet (AnyRef)Boolean== Null(null)null)
					java.lang.String("")""
				else
					Browse.this.global.Typet.()StringtoString
		}
	}
	/** Converts the given compound type to a string.  'mainPostfix' is copied after the main type symbol
	* but before any parents or refinements*/
	private def (Browse.this.global.CompoundType,String)java.lang.StringcompoundTypeString(Browse.this.global.CompoundTypect: Browse.this.global.CompoundTypeCompoundType, StringmainPostfix: StringString) =
	{
		import ct._
		=> Browse.this.global.SymboltypeSymbol.()StringtoString (Any)java.lang.String+ StringmainPostfix (Any)java.lang.String+
		{
			Anyif(Browse.this.global.CompoundTypect.=> Browse.this.global.SymboltypeSymbol.=> BooleanisPackageClass)
				java.lang.String("")""
			else Anyif(=> List[Browse.this.global.Type]parents.=> BooleanisEmpty)
			{
				Anyif(=> Browse.this.global.Scopedecls.=> BooleanisEmpty)
					java.lang.String("")""
				else
					=> Browse.this.global.Scopedecls.(String,String,String)StringmkString(java.lang.String("{")"{", java.lang.String("; ")"; ", java.lang.String("}")"}")
			}
			else
				=> List[Browse.this.global.Type]parents.(String,String,String)StringmkString(java.lang.String(" extends ")" extends ", java.lang.String(" with ")" with ", java.lang.String("")"")
		}
	}

	/** Generates a link usable in the file 'from' to the symbol 'to', which might be in some other file. */
	private def (java.io.File,Browse.this.global.Symbol)Option[sxr.Link]linkTo(java.io.Filefrom: java.io.FileFile, Browse.this.global.Symbolsym: Browse.this.global.SymbolSymbol): Option[sxr.Link]Option[Link] =
	{
		Option[sxr.Link]if(Browse.this.global.Symbolsym (AnyRef)Boolean== Null(null)null (Boolean)Boolean|| Browse.this.global.Symbolsym (AnyRef)Boolean== object Browse.this.global.NoSymbolNoSymbol)
			object NoneNone
		else
		{
			val scala.tools.nsc.io.AbstractFilesource = Browse.this.global.Symbolsym.=> scala.tools.nsc.io.AbstractFilesourceFile
			Option[sxr.Link]if(scala.tools.nsc.io.AbstractFilesource (AnyRef)Boolean== Null(null)null)
				object NoneNone
			else
			{
				val java.io.Filefile = scala.tools.nsc.io.AbstractFilesource.=> java.io.Filefile
				val java.lang.Stringbase = java.lang.Stringif(java.io.Filefile (AnyRef)Boolean== java.io.Filefrom) java.lang.String("")"" else object sxr.FileUtilFileUtil.(java.io.File,java.io.File)StringrelativePath(java.io.Filefrom, scala.tools.nsc.io.AbstractFilesource.=> java.io.Filefile) (Any)java.lang.String+ java.lang.String(".html")".html"
				(sxr.Link)Some[sxr.Link]Some(sxr.Linknew sxr.LinkLink(java.lang.Stringbase, Browse.this.global.Symbolsym.=> Intid.()java.lang.StringtoString))
			}
		}
	}
	/** Relativizes the path to the given Scala source file to the base directory. */
	private def (java.io.File)StringgetRelativeSourcePath(java.io.Filesource: java.io.FileFile): StringString =
	{
		=> Option[java.io.File]baseDirectory Stringmatch
		{
			Stringcase Some(java.io.Filebase) =>
				object sxr.FileUtilFileUtil.(java.io.File,java.io.File)Option[String]relativize(java.io.Filebase, java.io.Filesource) Stringmatch
				{
					Stringcase Some(Stringrelative) => Stringrelative
					java.lang.Stringcase object NoneNone => (String)Uniterror(java.lang.String("Source ")"Source " (Any)java.lang.String+ java.io.Filesource (Any)java.lang.String+ java.lang.String(" not in base directory ")" not in base directory " (Any)java.lang.String+ java.io.Filebase); java.lang.String("")""
				}
			java.lang.Stringcase object NoneNone => java.io.Filesource.()java.lang.StringgetName
		}
	}
}

object object sxr.BrowseBrowse
{
	/** The location to store the index relative to the output directory.*/
	val java.lang.StringIndexRelativePath = java.lang.String("index.html")"index.html"
	/** The location to store the style sheet relative to the output directory.*/
	val java.lang.StringCSSRelativePath = java.lang.String("style.css")"style.css"
	/** The location to store the script relative to the output directory.*/
	val java.lang.StringJSRelativePath = java.lang.String("linked.js")"linked.js"
	/** The path of the default style sheet resource.*/
	val java.lang.StringDefaultCSS = java.lang.String("/default-style.css")"/default-style.css"
	/** The path of the default script resource.*/
	val java.lang.StringLinkedJS = java.lang.String("/linked.js")"/linked.js"
	
	/** Copies the default style sheet available as a resource on the classpath to the file 'to'.*/
	def (java.io.File)UnitwriteDefaultCSS(java.io.Fileto: java.io.FileFile) { object sxr.FileUtilFileUtil.(String,java.io.File)UnitwriteResource(=> java.lang.StringDefaultCSS, java.io.Fileto) }
	/** Copies the default script available as a resource on the classpath to the file 'to'.*/
	def (java.io.File)UnitwriteJS(java.io.Fileto: java.io.FileFile) { object sxr.FileUtilFileUtil.(String,java.io.File)UnitwriteResource(=> java.lang.StringLinkedJS, java.io.Fileto) }
	
	def (java.io.File,Iterable[java.io.File])UnitwriteIndex(java.io.Fileto: java.io.FileFile, Iterable[java.io.File]files: Iterable[java.io.File]Iterable[File])
	{
		val java.io.FilerelativizeAgainst = java.io.Fileto.()java.io.FilegetParentFile
		val Iterable[String]rawRelativePaths = Iterable[java.io.File]files.((java.io.File) => Iterable[String])Iterable[String]flatMap(java.io.Filefile => object sxr.FileUtilFileUtil.(java.io.File,java.io.File)Option[String]relativize(java.io.FilerelativizeAgainst, java.io.Filefile).=> List[String]toList)
		val scala.collection.jcl.TreeSet[String]sortedRelativePaths = scala.collection.jcl.TreeSet[String]new scala.collection.jcl.TreeSet[String]TreeSet[String]
		scala.collection.jcl.TreeSet[String]sortedRelativePaths (Iterable[String])Unit++= Iterable[String]rawRelativePaths
		object sxr.FileUtilFileUtil.(java.io.File)((java.io.BufferedWriter) => Unit)UnitwithWriter(java.io.Fileto) { java.io.BufferedWriterout =>
			java.io.BufferedWriterout.(java.lang.String)Unitwrite(java.lang.String("<html><body>")"<html><body>")
			scala.collection.jcl.TreeSet[String]sortedRelativePaths.((String) => Unit)Unitforeach((java.io.File,java.io.Writer)(String)UnitwriteEntry(java.io.Fileto, java.io.BufferedWriterout))
			java.io.BufferedWriterout.(java.lang.String)Unitwrite(java.lang.String("</body></html>")"</body></html>")
		}
	}
	import java.io.Writer
	private def (java.io.File,java.io.Writer)(String)UnitwriteEntry(java.io.Fileindex: java.io.FileFile, java.io.Writerout: java.io.WriterWriter)(Stringpath: StringString)
	{
		java.io.Writerout.(java.lang.String)Unitwrite(java.lang.String("<li><a href="")"<li><a href=\"")
		java.io.Writerout.(java.lang.String)Unitwrite(Stringpath)
		java.io.Writerout.(java.lang.String)Unitwrite(java.lang.String("">")"\">")
		val java.lang.Stringlabel =
			java.lang.Stringif(Stringpath.(java.lang.String)BooleanendsWith(java.lang.String(".html")".html"))
				Stringpath.(Int,Int)java.lang.Stringsubstring(Int(0)0, Stringpath.()Intlength (Int)Int- java.lang.String(".html")".html".()Intlength)
			else
				Stringpath
		java.io.Writerout.(java.lang.String)Unitwrite(java.lang.Stringlabel)
		java.io.Writerout.(java.lang.String)Unitwrite(java.lang.String("</a></li>")"</a></li>")
	}
}