diff options
-rw-r--r-- | build.xml | 374 | ||||
-rw-r--r-- | src/compiler/scala/tools/ant/Same.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/ant/antlib.xml | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 14 | ||||
-rwxr-xr-x | src/compiler/scala/tools/nsc/ast/DocComments.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 41 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 184 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala | 32 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 128 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala | 107 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/io/Pickler.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/javac/JavaScanners.scala | 53 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala | 30 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/Logic.scala | 229 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala | 44 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala | 52 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala | 41 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/Solving.scala | 242 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 18 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 50 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 129 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/ToolBoxFactory.scala | 2 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/CompilerControl.scala (renamed from src/compiler/scala/tools/nsc/interactive/CompilerControl.scala) | 33 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/ContextTrees.scala (renamed from src/compiler/scala/tools/nsc/interactive/ContextTrees.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/Global.scala (renamed from src/compiler/scala/tools/nsc/interactive/Global.scala) | 178 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/InteractiveReporter.scala (renamed from src/compiler/scala/tools/nsc/interactive/InteractiveReporter.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/Main.scala | 34 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/Picklers.scala (renamed from src/compiler/scala/tools/nsc/interactive/Picklers.scala) | 4 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/PresentationCompilerThread.scala (renamed from src/compiler/scala/tools/nsc/interactive/PresentationCompilerThread.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/REPL.scala (renamed from src/compiler/scala/tools/nsc/interactive/REPL.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/RangePositions.scala (renamed from src/compiler/scala/tools/nsc/interactive/RangePositions.scala) | 1 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/Response.scala (renamed from src/compiler/scala/tools/nsc/interactive/Response.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/RichCompilationUnits.scala (renamed from src/compiler/scala/tools/nsc/interactive/RichCompilationUnits.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/ScratchPadMaker.scala (renamed from src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/InteractiveTest.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/Tester.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/Tester.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala) | 11 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/Reporter.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/Reporter.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/TestMarker.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/TestMarker.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/TestResources.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/TestResources.scala) | 0 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/tests/core/TestSettings.scala (renamed from src/compiler/scala/tools/nsc/interactive/tests/core/TestSettings.scala) | 0 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/ArrayOps.scala | 23 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/nest/DirectRunner.scala | 26 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/nest/FileManager.scala | 14 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/nest/ReflectiveRunner.scala | 20 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Required.scala | 7 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 35 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeInfo.scala | 3 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 19 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaUniverse.scala | 2 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/ant/Scaladoc.scala (renamed from src/compiler/scala/tools/ant/Scaladoc.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/ScalaDoc.scala (renamed from src/compiler/scala/tools/nsc/ScalaDoc.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/DocFactory.scala (renamed from src/compiler/scala/tools/nsc/doc/DocFactory.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/DocParser.scala (renamed from src/compiler/scala/tools/nsc/doc/DocParser.scala) | 2 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/Index.scala (renamed from src/compiler/scala/tools/nsc/doc/Index.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala | 234 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala | 49 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/Settings.scala (renamed from src/compiler/scala/tools/nsc/doc/Settings.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala (renamed from src/compiler/scala/tools/nsc/doc/Uncompilable.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/Universe.scala (renamed from src/compiler/scala/tools/nsc/doc/Universe.scala) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala (renamed from src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala (renamed from src/compiler/scala/tools/nsc/doc/base/LinkTo.scala) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala (renamed from src/compiler/scala/tools/nsc/doc/base/MemberLookupBase.scala) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala (renamed from src/compiler/scala/tools/nsc/doc/base/comment/Body.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala (renamed from src/compiler/scala/tools/nsc/doc/base/comment/Comment.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala (renamed from src/compiler/scala/tools/nsc/doc/doclet/Generator.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala (renamed from src/compiler/scala/tools/nsc/doc/doclet/Indexer.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala (renamed from src/compiler/scala/tools/nsc/doc/doclet/Universer.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala (renamed from src/compiler/scala/tools/nsc/doc/html/Doclet.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala (renamed from src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala (renamed from src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/Page.scala (renamed from src/compiler/scala/tools/nsc/doc/html/Page.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala (renamed from src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/Index.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/ReferenceIndex.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/Source.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/Source.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/Template.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala (renamed from src/compiler/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-down.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/arrow-down.png) | bin | 6232 -> 6232 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-right.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/arrow-right.png) | bin | 6220 -> 6220 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/class.png) | bin | 3357 -> 3357 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/class_big.png) | bin | 7516 -> 7516 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_diagram.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/class_diagram.png) | bin | 3910 -> 3910 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_to_object_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/class_to_object_big.png) | bin | 9006 -> 9006 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/constructorsbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/constructorsbg.gif) | bin | 1206 -> 1206 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif) | bin | 167 -> 167 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/defbg-blue.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/defbg-blue.gif) | bin | 1544 -> 1544 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/defbg-green.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/defbg-green.gif) | bin | 1341 -> 1341 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.css (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/diagrams.css) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/diagrams.js) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left.png) | bin | 1692 -> 1692 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left.psd (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left.psd) | bin | 30823 -> 30823 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left2.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left2.gif) | bin | 1462 -> 1462 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_right.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_right.png) | bin | 1803 -> 1803 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_right.psd (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_right.psd) | bin | 31295 -> 31295 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filterbg.gif) | bin | 1324 -> 1324 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.gif) | bin | 1104 -> 1104 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.png) | bin | 965 -> 965 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbg.gif) | bin | 1366 -> 1366 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/fullcommenttopbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/fullcommenttopbg.gif) | bin | 1115 -> 1115 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/index.css) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.js) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png) | bin | 1198 -> 1198 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/navigation-li.png) | bin | 2441 -> 2441 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/object.png) | bin | 3356 -> 3356 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/object_big.png) | bin | 7653 -> 7653 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_diagram.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/object_diagram.png) | bin | 3903 -> 3903 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png) | bin | 9158 -> 9158 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png) | bin | 9200 -> 9200 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png) | bin | 9158 -> 9158 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif) | bin | 1145 -> 1145 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif) | bin | 1118 -> 1118 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif) | bin | 1145 -> 1145 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/package.png) | bin | 3335 -> 3335 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/package_big.png) | bin | 7312 -> 7312 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif) | bin | 1201 -> 1201 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/raphael-min.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/raphael-min.js) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/ref-index.css) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/remove.png) | bin | 3186 -> 3186 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.psd (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/remove.psd) | bin | 28904 -> 28904 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/scheduler.js) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png) | bin | 1150 -> 1150 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png) | bin | 646 -> 646 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right.png) | bin | 1380 -> 1380 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/selected.png) | bin | 1864 -> 1864 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2-right.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/selected2-right.png) | bin | 1434 -> 1434 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/selected2.png) | bin | 1965 -> 1965 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif) | bin | 1214 -> 1214 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif) | bin | 1209 -> 1209 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/trait.png) | bin | 3374 -> 3374 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_big.png) | bin | 7410 -> 7410 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png) | bin | 3882 -> 3882 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png) | bin | 8967 -> 8967 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/type.png) | bin | 1445 -> 1445 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/type_big.png) | bin | 4236 -> 4236 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_diagram.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/type_diagram.png) | bin | 1841 -> 1841 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_tags.ai (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/type_tags.ai) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png) | bin | 4969 -> 4969 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/typebg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/typebg.gif) | bin | 1206 -> 1206 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/unselected.png (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/unselected.png) | bin | 1879 -> 1879 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif) | bin | 1206 -> 1206 bytes | |||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/resource/lib/versions.txt (renamed from src/compiler/scala/tools/nsc/doc/html/resource/lib/versions.txt) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala (renamed from src/compiler/scala/tools/nsc/doc/model/CommentFactory.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/Entity.scala (renamed from src/compiler/scala/tools/nsc/doc/model/Entity.scala) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala (renamed from src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala (renamed from src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala (renamed from src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala (renamed from src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala (renamed from src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala (renamed from src/compiler/scala/tools/nsc/doc/model/TreeEntity.scala) | 0 | ||||
-rwxr-xr-x | src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala (renamed from src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala (renamed from src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala (renamed from src/compiler/scala/tools/nsc/doc/model/ValueArgument.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala (renamed from src/compiler/scala/tools/nsc/doc/model/Visibility.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala (renamed from src/compiler/scala/tools/nsc/doc/model/diagram/Diagram.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala (renamed from src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala (renamed from src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala) | 0 | ||||
-rw-r--r-- | src/scaladoc/scala/tools/partest/ScaladocModelTest.scala (renamed from src/partest/scala/tools/partest/ScaladocModelTest.scala) | 8 | ||||
-rw-r--r-- | test/files/jvm/nooptimise/Foo_1.flags | 1 | ||||
-rw-r--r-- | test/files/jvm/nooptimise/Foo_1.scala | 8 | ||||
-rw-r--r-- | test/files/jvm/nooptimise/Test.scala | 23 | ||||
-rw-r--r-- | test/files/jvm/t7006/Foo_1.flags | 2 | ||||
-rw-r--r-- | test/files/jvm/unreachable/Foo_1.flags | 1 | ||||
-rw-r--r-- | test/files/jvm/unreachable/Foo_1.scala | 110 | ||||
-rw-r--r-- | test/files/jvm/unreachable/Test.scala | 23 | ||||
-rw-r--r-- | test/files/neg/macro-basic-mamdmi.check | 3 | ||||
-rw-r--r-- | test/files/neg/t5753.check | 3 | ||||
-rw-r--r-- | test/files/neg/t7185.check | 7 | ||||
-rw-r--r-- | test/files/neg/t7185.scala | 3 | ||||
-rw-r--r-- | test/files/pos/t7126.scala | 11 | ||||
-rw-r--r-- | test/files/pos/t7183.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t7183.scala | 13 | ||||
-rw-r--r-- | test/files/pos/t7190.scala | 26 | ||||
-rw-r--r-- | test/files/presentation/doc.check | 50 | ||||
-rwxr-xr-x | test/files/presentation/doc/doc.scala | 128 | ||||
-rwxr-xr-x | test/files/presentation/doc/src/Class.scala | 1 | ||||
-rwxr-xr-x | test/files/presentation/doc/src/Test.scala | 1 | ||||
-rwxr-xr-x | test/files/presentation/doc/src/p/Base.scala | 11 | ||||
-rwxr-xr-x | test/files/presentation/doc/src/p/Derived.scala | 9 | ||||
-rw-r--r-- | test/files/run/inline-ex-handlers.check | 152 | ||||
-rw-r--r-- | test/files/run/t7185.check | 34 | ||||
-rw-r--r-- | test/files/run/t7185.scala | 12 | ||||
-rw-r--r-- | test/files/run/t7214.scala | 57 | ||||
-rw-r--r-- | test/files/run/t7215.scala | 6 | ||||
-rw-r--r-- | test/files/run/t7231.check | 2 | ||||
-rw-r--r-- | test/files/run/t7231.scala | 11 | ||||
-rw-r--r-- | test/files/run/unreachable.scala | 125 | ||||
-rw-r--r-- | test/scaladoc/run/t5527.check (renamed from test/files/run/t5527.check) | 9 | ||||
-rw-r--r-- | test/scaladoc/run/t5527.scala (renamed from test/files/run/t5527.scala) | 0 | ||||
-rw-r--r-- | test/scaladoc/scalacheck/IndexScriptTest.scala | 2 | ||||
-rw-r--r-- | test/scaladoc/scalacheck/IndexTest.scala | 6 | ||||
-rwxr-xr-x | tools/stability-test.sh | 29 |
218 files changed, 2110 insertions, 1311 deletions
@@ -433,6 +433,7 @@ INITIALISATION <property name="scalac.args.quickonly" value=""/> <property name="scalac.args.all" value="${scalac.args.always} ${scalac.args} ${scalac.args.optimise}"/> <property name="scalac.args.quick" value="${scalac.args.all} ${scalac.args.quickonly}"/> + <property name="scalac.args.strap" value="${scalac.args.quick}"/> <!-- Setting-up Ant contrib tasks --> <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant/ant-contrib.jar"/> <!-- This is the start time for the distribution --> @@ -926,7 +927,6 @@ QUICK BUILD (QUICK) <uptodate property="quick.lib.available" targetfile="${build-quick.dir}/library.complete"> <srcfiles dir="${src.dir}"> <include name="library/**"/> - <include name="continuations/**"/> <include name="swing/**"/> <include name="actors/**"/> </srcfiles> @@ -989,28 +989,14 @@ QUICK BUILD (QUICK) <include name="**/*.xml"/> <include name="**/*.js"/> <include name="**/*.css"/> + <include name="rootdoc.txt"/> </fileset> </copy> - </target> - - <target name="quick.swing" depends="quick.lib" if="has.java6" unless="quick.lib.available"> - <scalacfork - destdir="${build-quick.dir}/classes/library" - compilerpathref="locker.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/swing" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="quick.compilation.path"/> - </scalacfork> - </target> - - <target name="quick.lib.done" depends="quick.swing, quick.lib"> - <stopwatch name="quick.lib.timer" action="total"/> <touch file="${build-quick.dir}/library.complete" verbose="no"/> + <stopwatch name="quick.lib.timer" action="total"/> </target> - <target name="quick.pre-reflect" depends="quick.lib.done"> + <target name="quick.pre-reflect" depends="quick.lib"> <uptodate property="quick.reflect.available" targetfile="${build-quick.dir}/reflect.complete"> <srcfiles dir="${src.dir}"> <include name="reflect/**"/> @@ -1031,11 +1017,11 @@ QUICK BUILD (QUICK) <compilationpath> <pathelement location="${build-quick.dir}/classes/library"/> <pathelement location="${build-quick.dir}/classes/reflect"/> + <path refid="forkjoin.classpath"/> <path refid="aux.libs"/> <pathelement location="${jline.jar}"/> </compilationpath> </scalacfork> - <!-- TODO - needed? --> <propertyfile file="${build-quick.dir}/classes/reflect/reflect.properties"> <entry key="version.number" value="${version.number}"/> <entry key="maven.version.number" value="${maven.version.number}"/> @@ -1109,6 +1095,18 @@ QUICK BUILD (QUICK) <stopwatch name="quick.comp.timer" action="total"/> </target> + <target name="quick.swing" depends="quick.comp" if="has.java6" unless="quick.comp.available"> + <scalacfork + destdir="${build-quick.dir}/classes/library" + compilerpathref="locker.classpath" + params="${scalac.args.quick}" + srcdir="${src.dir}/swing" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath refid="quick.compilation.path"/> + </scalacfork> + </target> + <target name="quick.pre-plugins" depends="quick.comp"> <uptodate property="quick.plugins.available" targetfile="${build-quick.dir}/plugins.complete"> <srcfiles dir="${src.dir}/continuations"/> @@ -1118,6 +1116,7 @@ QUICK BUILD (QUICK) <target name="quick.plugins" depends="quick.pre-plugins" unless="quick.plugins.available"> <stopwatch name="quick.plugins.timer"/> <mkdir dir="${build-quick.dir}/classes/continuations-plugin"/> + <mkdir dir="${build-quick.dir}/classes/continuations-library"/> <scalacfork destdir="${build-quick.dir}/classes/continuations-plugin" compilerpathref="quick.classpath" @@ -1144,7 +1143,7 @@ QUICK BUILD (QUICK) </jar> <!-- might split off library part into its own ant target --> <scalacfork - destdir="${build-quick.dir}/classes/library" + destdir="${build-quick.dir}/classes/continuations-library" compilerpathref="quick.classpath" params="${scalac.args.quick} -Xplugin-require:continuations -P:continuations:enable" srcdir="${src.dir}/continuations/library" @@ -1269,7 +1268,86 @@ QUICK BUILD (QUICK) <stopwatch name="quick.partest.timer" action="total"/> </target> - <target name="quick.pre-bin" depends="quick.partest"> + <target name="quick.pre-scaladoc" depends="quick.partest"> + <uptodate property="quick.scaladoc.available" targetfile="${build-quick.dir}/scaladoc.complete"> + <srcfiles dir="${src.dir}/scaladoc" /> + </uptodate> + </target> + + <target name="quick.scaladoc" depends="quick.pre-scaladoc" unless="quick.scaladoc.available"> + <mkdir dir="${build-quick.dir}/classes/scaladoc"/> + <scalacfork + destdir="${build-quick.dir}/classes/scaladoc" + compilerpathref="quick.classpath" + params="${scalac.args.quick}" + srcdir="${src.dir}/scaladoc" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath> + <pathelement location="${build-quick.dir}/classes/library"/> + <pathelement location="${build-quick.dir}/classes/reflect"/> + <pathelement location="${build-quick.dir}/classes/compiler"/> + <pathelement location="${build-quick.dir}/classes/scalap"/> + <pathelement location="${build-quick.dir}/classes/partest"/> + <pathelement location="${build-quick.dir}/classes/scaladoc"/> + <pathelement location="${ant.jar}"/> + <path refid="forkjoin.classpath"/> + <pathelement location="${scalacheck.jar}"/> + </compilationpath> + </scalacfork> + <propertyfile file="${build-quick.dir}/classes/scaladoc/scaladoc.properties"> + <entry key="version.number" value="${scaladoc.version.number}"/> + <entry key="copyright.string" value="${copyright.string}"/> + </propertyfile> + <copy todir="${build-quick.dir}/classes/scaladoc"> + <fileset dir="${src.dir}/scaladoc"> + <include name="**/*.tmpl"/> + <include name="**/*.xml"/> + <include name="**/*.js"/> + <include name="**/*.css"/> + <include name="**/*.html"/> + <include name="**/*.properties"/> + <include name="**/*.swf"/> + <include name="**/*.png"/> + <include name="**/*.gif"/> + <include name="**/*.txt"/> + </fileset> + </copy> + <touch file="${build-quick.dir}/scaladoc.complete" verbose="no"/> + </target> + + <target name="quick.pre-interactive" depends="quick.scaladoc"> + <uptodate property="quick.interactive.available" targetfile="${build-quick.dir}/interactive.complete"> + <srcfiles dir="${src.dir}/interactive" /> + </uptodate> + </target> + + <target name="quick.interactive" depends="quick.pre-interactive" unless="quick.interactive.available"> + <mkdir dir="${build-quick.dir}/classes/interactive"/> + <scalacfork + destdir="${build-quick.dir}/classes/interactive" + compilerpathref="quick.classpath" + params="${scalac.args.quick}" + srcdir="${src.dir}/interactive" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath> + <pathelement location="${build-quick.dir}/classes/library"/> + <pathelement location="${build-quick.dir}/classes/reflect"/> + <pathelement location="${build-quick.dir}/classes/compiler"/> + <pathelement location="${build-quick.dir}/classes/scalap"/> + <pathelement location="${build-quick.dir}/classes/partest"/> + <pathelement location="${build-quick.dir}/classes/scaladoc"/> + <pathelement location="${build-quick.dir}/classes/interactive"/> + <pathelement location="${ant.jar}"/> + <path refid="forkjoin.classpath"/> + <pathelement location="${scalacheck.jar}"/> + </compilationpath> + </scalacfork> + <touch file="${build-quick.dir}/interactive.complete" verbose="no"/> + </target> + + <target name="quick.pre-bin" depends="quick.interactive"> <condition property="quick.bin.available"> <isset property="quick.comp.available"/> </condition> @@ -1360,6 +1438,7 @@ PACKED QUICK BUILD (PACK) <exclude name="scala/swing/**"/> <exclude name="scala/actors/**"/> </fileset> + <fileset dir="${build-quick.dir}/classes/continuations-library"/> <fileset dir="${build-libs.dir}/classes/forkjoin"/> </jar> <jar destfile="${build-pack.dir}/lib/scala-actors.jar"> @@ -1407,6 +1486,8 @@ PACKED QUICK BUILD (PACK) <mkdir dir="${build-pack.dir}/lib"/> <jar destfile="${build-pack.dir}/lib/scala-compiler.jar" manifest="${build-pack.dir}/META-INF/MANIFEST.MF"> <fileset dir="${build-quick.dir}/classes/compiler"/> + <fileset dir="${build-quick.dir}/classes/scaladoc"/> + <fileset dir="${build-quick.dir}/classes/interactive"/> <fileset dir="${build-asm.dir}/classes"/> </jar> <copy file="${jline.jar}" toDir="${build-pack.dir}/lib"/> @@ -1530,6 +1611,11 @@ PACKED QUICK BUILD (PACK) <pathelement location="${jline.jar}"/> <path refid="lib.extra"/> </path> + <path id="partest.classpath"> + <path refid="pack.classpath"/> + <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> + <pathelement location="${pack.dir}/lib/scala-swing.jar"/> <!-- TODO - segregate swing tests (there can't be many) --> + </path> <taskdef resource="scala/tools/ant/antlib.xml" classpathref="pack.classpath"/> <taskdef resource="scala/tools/partest/antlib.xml" classpathref="pack.classpath"/> </target> @@ -1714,7 +1800,7 @@ BOOTSTRAPPING BUILD (STRAP) destdir="${build-strap.dir}/classes/library" compilerpathref="pack.classpath" srcpath="${src.dir}/library" - params="${scalac.args.quick}" + params="${scalac.args.strap}" srcdir="${src.dir}/library" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -1723,7 +1809,7 @@ BOOTSTRAPPING BUILD (STRAP) <scalacfork destdir="${build-strap.dir}/classes/library" compilerpathref="pack.classpath" - params="${scalac.args.quick}" + params="${scalac.args.strap}" srcdir="${src.dir}/actors" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -1743,28 +1829,15 @@ BOOTSTRAPPING BUILD (STRAP) <include name="**/*.css"/> </fileset> </copy> - </target> - - <target name="strap.swing" if="has.java6" unless="strap.lib.available" depends="strap.lib"> - <scalacfork - destdir="${build-strap.dir}/classes/library" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/swing" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="strap.compilation.path"/> - </scalacfork> - </target> - - <target name="strap.lib.done" depends="strap.swing, strap.lib"> <touch file="${build-strap.dir}/library.complete" verbose="no"/> <stopwatch name="strap.lib.timer" action="total"/> </target> - <target name="strap.pre-reflect" depends="strap.lib.done"> + <target name="strap.pre-reflect" depends="strap.lib"> <uptodate property="strap.reflect.available" targetfile="${build-strap.dir}/reflect.complete"> - <srcfiles dir="${src.dir}/reflect"/> + <srcfiles dir="${src.dir}"> + <include name="reflect/**"/> + </srcfiles> </uptodate> </target> @@ -1807,7 +1880,7 @@ BOOTSTRAPPING BUILD (STRAP) </fileset> </copy> <touch file="${build-strap.dir}/reflect.complete" verbose="no"/> - <stopwatch name="strap.comp.timer" action="total"/> + <stopwatch name="strap.reflect.timer" action="total"/> </target> <target name="strap.pre-comp" depends="strap.reflect"> @@ -1822,7 +1895,7 @@ BOOTSTRAPPING BUILD (STRAP) <scalacfork destdir="${build-strap.dir}/classes/compiler" compilerpathref="pack.classpath" - params="${scalac.args.quick}" + params="${scalac.args.strap}" srcdir="${src.dir}/compiler" jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> @@ -1860,153 +1933,7 @@ BOOTSTRAPPING BUILD (STRAP) <stopwatch name="strap.comp.timer" action="total"/> </target> - <target name="strap.pre-plugins" depends="strap.comp"> - <uptodate property="strap.plugins.available" targetfile="${build-strap.dir}/plugins.complete"> - <srcfiles dir="${src.dir}/continuations"/> - </uptodate> - </target> - - <target name="strap.plugins" depends="strap.pre-plugins" unless="strap.plugins.available"> - <stopwatch name="strap.plugins.timer"/> - <mkdir dir="${build-strap.dir}/classes/continuations-plugin"/> - <scalacfork - destdir="${build-strap.dir}/classes/continuations-plugin" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/continuations/plugin" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <pathelement location="${build-strap.dir}/classes/continuations-plugin"/> - <path refid="forkjoin.classpath"/> - <path refid="aux.libs"/> - </compilationpath> - </scalacfork> - <copy - file="${src.dir}/continuations/plugin/scalac-plugin.xml" - todir="${build-strap.dir}/classes/continuations-plugin"/> - <!-- not very nice to create jar here but needed to load plugin --> - <mkdir dir="${build-strap.dir}/misc/scala-devel/plugins"/> - <jar destfile="${build-strap.dir}/misc/scala-devel/plugins/continuations.jar"> - <fileset dir="${build-strap.dir}/classes/continuations-plugin"/> - </jar> - <!-- might split off library part into its own ant target --> - <scalacfork - destdir="${build-strap.dir}/classes/library" - compilerpathref="pack.classpath" - params="${scalac.args.quick} -Xplugin-require:continuations -P:continuations:enable" - srcdir="${src.dir}/continuations/library" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath refid="strap.compilation.path"/> - <compilerarg value="-Xpluginsdir"/> - <compilerarg file="${build-strap.dir}/misc/scala-devel/plugins"/> - </scalacfork> - <touch file="${build-strap.dir}/plugins.complete" verbose="no"/> - <stopwatch name="strap.plugins.timer" action="total"/> - </target> - - <target name="strap.scalacheck" depends="strap.plugins"> - <mkdir dir="${build-strap.dir}/classes/scalacheck"/> - <scalacfork - destdir="${build-strap.dir}/classes/scalacheck" - compilerpathref="pack.classpath" - params="${scalac.args.quick} -nowarn" - srcdir="${src.dir}/scalacheck" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - </compilationpath> - </scalacfork> - </target> - - <target name="strap.pre-scalap" depends="strap.scalacheck"> - <uptodate property="strap.scalap.available" targetfile="${build-strap.dir}/scalap.complete"> - <srcfiles dir="${src.dir}/scalap"/> - </uptodate> - </target> - - <target name="strap.scalap" depends="strap.pre-scalap" unless="strap.scalap.available"> - <stopwatch name="strap.scalap.timer"/> - <mkdir dir="${build-strap.dir}/classes/scalap"/> - <scalacfork - destdir="${build-strap.dir}/classes/scalap" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/scalap" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <pathelement location="${build-strap.dir}/classes/scalap"/> - <pathelement location="${build-strap.dir}/classes/partest"/> - <pathelement location="${ant.jar}"/> - <path refid="forkjoin.classpath"/> - </compilationpath> - </scalacfork> - <touch file="${build-strap.dir}/scalap.complete" verbose="no"/> - <stopwatch name="strap.scalap.timer" action="total"/> - </target> - - <target name="strap.pre-partest" depends="strap.scalap, asm.done"> - <uptodate property="strap.partest.available" targetfile="${build-strap.dir}/partest.complete"> - <srcfiles dir="${src.dir}/partest"/> - </uptodate> - </target> - - <target name="strap.partest" depends="strap.pre-partest" unless="strap.partest.available"> - <stopwatch name="strap.partest.timer"/> - <mkdir dir="${build-strap.dir}/classes/partest"/> - <javac - srcdir="${src.dir}/partest" - destdir="${build-strap.dir}/classes/partest" - target="1.6" source="1.5"> - <classpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <pathelement location="${build-strap.dir}/classes/scalap"/> - <pathelement location="${build-strap.dir}/classes/partest"/> - <path refid="asm.classpath"/> - </classpath> - <include name="**/*.java"/> - <compilerarg line="${javac.args}"/> - </javac> - <scalacfork - destdir="${build-strap.dir}/classes/partest" - compilerpathref="pack.classpath" - params="${scalac.args.quick}" - srcdir="${src.dir}/partest" - jvmargs="${scalacfork.jvmargs}"> - <include name="**/*.scala"/> - <compilationpath> - <pathelement location="${build-strap.dir}/classes/library"/> - <pathelement location="${build-strap.dir}/classes/reflect"/> - <pathelement location="${build-strap.dir}/classes/compiler"/> - <pathelement location="${build-strap.dir}/classes/scalap"/> - <pathelement location="${build-strap.dir}/classes/partest"/> - <pathelement location="${ant.jar}"/> - <path refid="forkjoin.classpath"/> - <path refid="asm.classpath"/> - <pathelement location="${scalacheck.jar}"/> - </compilationpath> - </scalacfork> - <copy todir="${build-strap.dir}/classes/partest"> - <fileset dir="${src.dir}/partest"> - <include name="**/*.xml"/> - </fileset> - </copy> - <touch file="${build-strap.dir}/partest.complete" verbose="no"/> - <stopwatch name="strap.partest.timer" action="total"/> - </target> - - <target name="strap.done" depends="strap.partest"/> + <target name="strap.done" depends="strap.comp"/> <target name="strap.clean"> <delete dir="${build-strap.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/> @@ -2071,6 +1998,7 @@ SBT Compiler Interface jvmargs="${scalacfork.jvmargs}"> <include name="**/*.scala"/> <compilationpath> + <pathelement location="${build-quick.dir}/classes/scaladoc"/> <pathelement location="${build-quick.dir}/classes/library"/> <pathelement location="${build-quick.dir}/classes/reflect"/> <pathelement location="${build-quick.dir}/classes/compiler"/> @@ -2370,13 +2298,10 @@ DOCUMENTATION BOOTRAPING TEST AND TEST SUITE ============================================================================ --> - <target name="test.stability" depends="strap.done, init"> - <same dir="${build-quick.dir}" todir="${build-strap.dir}" failondifferent="yes"> - <exclude name="**/*.properties"/> - <exclude name="bin/**"/> - <exclude name="*.complete"/> - <exclude name="misc/scala-devel/plugins/*.jar"/> - </same> + <target name="test.stability" depends="pack.done, strap.done"> + <exec osfamily="unix" vmlauncher="false" executable="${basedir}/tools/stability-test.sh" failonerror="true" /> + <!-- I think doing it this way means it will auto-pass on windows... that's the idea. If not, something like this. --> + <!-- <exec osfamily="windows" executable="foo" failonerror="false" failifexecutionfails="false" /> --> </target> <target name="test.classload" depends="pack.done"> @@ -2395,47 +2320,39 @@ BOOTRAPING TEST AND TEST SUITE </antcall> </target> - <target name="test.run" depends="pack.done"> + <target name="test.pre-run" depends="pack.done"> <property name="partest.srcdir" value="files" /> + </target> + + <target name="test.run" depends="test.pre-run"> <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" timeout="1200000" srcdir="${partest.srcdir}" scalacopts="${scalac.args.optimise}"> - <compilationpath> - <path refid="pack.classpath"/> - <pathelement location="${pack.dir}/lib/scala-swing.jar"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + + <compilationpath refid="partest.classpath"/> <runtests dir="${partest.dir}/${partest.srcdir}/run" includes="*.scala"/> <jvmtests dir="${partest.dir}/${partest.srcdir}/jvm" includes="*.scala"/> </partest> </target> - <target name="test.ant" depends="pack.done"> + <target name="test.ant" depends="test.pre-run"> <property name="partest.srcdir" value="files" /> <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" srcdir="${partest.srcdir}" scalacopts="${scalac.args.optimise}"> - <compilationpath> - <path refid="pack.classpath"/> - <pathelement location="${pack.dir}/lib/scala-swing.jar"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + <compilationpath refid="partest.classpath"/> <anttests dir="${partest.dir}/${partest.srcdir}/ant" includes="*build.xml"/> </partest> </target> - <target name="test.suite" depends="pack.done"> + <target name="test.suite" depends="test.pre-run"> <property name="partest.srcdir" value="files" /> <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" timeout="2400000" srcdir="${partest.srcdir}" scalacopts="${scalac.args.optimise}"> - <compilationpath> - <path refid="pack.classpath"/> - <pathelement location="${pack.dir}/lib/scala-swing.jar"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + <compilationpath refid="partest.classpath"/> <postests dir="${partest.dir}/${partest.srcdir}/pos" includes="*.scala"/> <negtests dir="${partest.dir}/${partest.srcdir}/neg" includes="*.scala"/> <runtests dir="${partest.dir}/${partest.srcdir}/run" includes="*.scala"/> @@ -2451,14 +2368,10 @@ BOOTRAPING TEST AND TEST SUITE <instrumentedtests dir="${partest.dir}/${partest.srcdir}/instrumented"> <include name="*.scala"/> </instrumentedtests> - <presentationtests dir="${partest.dir}/${partest.srcdir}/presentation"> - <include name="*/*.scala"/> - </presentationtests> - <!-- <scripttests dir="${partest.dir}/${partest.srcdir}/script" includes="*.scala"/> --> </partest> </target> - <target name="test.continuations.suite" depends="pack.done"> + <target name="test.continuations.suite" depends="test.pre-run"> <property name="partest.srcdir" value="files" /> <partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java" timeout="2400000" @@ -2466,27 +2379,30 @@ BOOTRAPING TEST AND TEST SUITE scalacopts="${scalac.args.optimise} -Xplugin-require:continuations -P:continuations:enable"> <compilerarg value="-Xpluginsdir"/> <compilerarg file="${build-quick.dir}/misc/scala-devel/plugins"/> - <compilationpath> - <path refid="pack.classpath"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + <compilationpath refid="partest.classpath"/> <negtests dir="${partest.dir}/${partest.srcdir}/continuations-neg" includes="*.scala"/> <runtests dir="${partest.dir}/${partest.srcdir}/continuations-run" includes="*.scala"/> </partest> </target> - <target name="test.scaladoc" depends="pack.done"> + <target name="test.scaladoc" depends="test.pre-run"> <partest erroronfailed="yes" scalacopts="${scalac.args.optimise}" showlog="yes"> - <compilationpath> - <path refid="pack.classpath"/> - <fileset dir="${partest.dir}/files/lib" includes="*.jar" /> - </compilationpath> + <compilationpath refid="partest.classpath"/> <runtests dir="${partest.dir}/scaladoc/run" includes="*.scala" /> <scalachecktests dir="${partest.dir}/scaladoc/scalacheck" includes="*.scala" /> </partest> </target> - <target name="test.done" depends="test.suite, test.continuations.suite, test.scaladoc, test.stability, test.sbt"/> + <target name="test.interactive" depends="test.pre-run"> + <partest erroronfailed="yes" scalacopts="${scalac.args.optimise}" showlog="yes"> + <compilationpath refid="partest.classpath"/> + <presentationtests dir="${partest.dir}/${partest.srcdir}/presentation"> + <include name="*/*.scala"/> + </presentationtests> + </partest> + </target> + + <target name="test.done" depends="test.suite, test.continuations.suite, test.scaladoc, test.interactive, test.stability, test.sbt"/> <!-- =========================================================================== diff --git a/src/compiler/scala/tools/ant/Same.scala b/src/compiler/scala/tools/ant/Same.scala index a1f0cda662..6362d28580 100644 --- a/src/compiler/scala/tools/ant/Same.scala +++ b/src/compiler/scala/tools/ant/Same.scala @@ -32,7 +32,7 @@ import org.apache.tools.ant.types.Mapper * * @author Gilles Dubochet * @version 1.0 */ -class Same extends ScalaMatchingTask { +@deprecated("Use diff", "2.11.0") class Same extends ScalaMatchingTask { /*============================================================================*\ ** Ant user-properties ** \*============================================================================*/ diff --git a/src/compiler/scala/tools/ant/antlib.xml b/src/compiler/scala/tools/ant/antlib.xml index 78159e6d10..7885534689 100644 --- a/src/compiler/scala/tools/ant/antlib.xml +++ b/src/compiler/scala/tools/ant/antlib.xml @@ -11,8 +11,6 @@ classname="scala.tools.ant.Scaladoc"/> <taskdef name="scalatool" classname="scala.tools.ant.ScalaTool"/> - <taskdef name="same" - classname="scala.tools.ant.Same"/> <taskdef name="pack200" classname="scala.tools.ant.Pack200Task"/> </antlib> diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 51fa8f0ab9..c0f611daa7 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -425,12 +425,14 @@ class Global(var currentSettings: Settings, var reporter: Reporter) val printInfers = settings.Yinferdebug.value // phaseName = "parser" - object syntaxAnalyzer extends { + lazy val syntaxAnalyzer = new { val global: Global.this.type = Global.this val runsAfter = List[String]() val runsRightAfter = None } with SyntaxAnalyzer + import syntaxAnalyzer.{ UnitScanner, UnitParser } + // !!! I think we're overdue for all these phase objects being lazy vals. // There's no way for a Global subclass to provide a custom typer // despite the existence of a "def newTyper(context: Context): Typer" @@ -1120,9 +1122,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter) warning("there were %d %s warning(s); re-run with %s for details".format(warnings.size, what, option.name)) } - def newUnitParser(code: String) = new syntaxAnalyzer.UnitParser(newCompilationUnit(code)) - def newCompilationUnit(code: String) = new CompilationUnit(newSourceFile(code)) - def newSourceFile(code: String) = new BatchSourceFile("<console>", code) + def newCompilationUnit(code: String) = new CompilationUnit(newSourceFile(code)) + def newSourceFile(code: String) = new BatchSourceFile("<console>", code) + def newUnitScanner(unit: CompilationUnit): UnitScanner = new UnitScanner(unit) + def newUnitParser(unit: CompilationUnit): UnitParser = new UnitParser(unit) + def newUnitParser(code: String): UnitParser = newUnitParser(newCompilationUnit(code)) /** A Run is a single execution of the compiler on a sets of units */ @@ -1692,8 +1696,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) } }) } - def forInteractive = false - def forScaladoc = false def createJavadoc = false } diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index eac43c146a..3397797927 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -53,6 +53,11 @@ trait DocComments { self: Global => else sym.owner.ancestors map (sym overriddenSymbol _) filter (_ != NoSymbol) } + def fillDocComment(sym: Symbol, comment: DocComment) { + docComments(sym) = comment + comment.defineVariables(sym) + } + /** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by * missing sections of an inherited doc comment. * If a symbol does not have a doc comment but some overridden version of it does, diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 08a6adfded..9218ad3330 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -142,9 +142,9 @@ self => if (source.isSelfContained) () => compilationUnit() else () => scriptBody() - def newScanner = new SourceFileScanner(source) + def newScanner(): Scanner = new SourceFileScanner(source) - val in = newScanner + val in = newScanner() in.init() private val globalFresh = new FreshNameCreator.Default @@ -196,10 +196,9 @@ self => } class UnitParser(val unit: global.CompilationUnit, patches: List[BracePatch]) extends SourceFileParser(unit.source) { + def this(unit: global.CompilationUnit) = this(unit, Nil) - def this(unit: global.CompilationUnit) = this(unit, List()) - - override def newScanner = new UnitScanner(unit, patches) + override def newScanner() = new UnitScanner(unit, patches) override def freshTermName(prefix: String): TermName = unit.freshTermName(prefix) override def freshTypeName(prefix: String): TypeName = unit.freshTypeName(prefix) @@ -219,6 +218,7 @@ self => try body finally smartParsing = saved } + def withPatches(patches: List[BracePatch]): UnitParser = new UnitParser(unit, patches) val syntaxErrors = new ListBuffer[(Int, String)] def showSyntaxErrors() = @@ -244,7 +244,7 @@ self => if (syntaxErrors.isEmpty) firstTry else in.healBraces() match { case Nil => showSyntaxErrors() ; firstTry - case patches => new UnitParser(unit, patches).parse() + case patches => (this withPatches patches).parse() } } } @@ -650,31 +650,10 @@ self => /* --------- COMMENT AND ATTRIBUTE COLLECTION ----------------------------- */ - /** Join the comment associated with a definition. */ - def joinComment(trees: => List[Tree]): List[Tree] = { - val doc = in.flushDoc - if ((doc ne null) && doc.raw.length > 0) { - val joined = trees map { - t => - DocDef(doc, t) setPos { - if (t.pos.isDefined) { - val pos = doc.pos.withEnd(t.pos.endOrPoint) - // always make the position transparent - pos.makeTransparent - } else { - t.pos - } - } - } - joined.find(_.pos.isOpaqueRange) foreach { - main => - val mains = List(main) - joined foreach { t => if (t ne main) ensureNonOverlapping(t, mains) } - } - joined - } - else trees - } + /** A hook for joining the comment associated with a definition. + * Overridden by scaladoc. + */ + def joinComment(trees: => List[Tree]): List[Tree] = trees /* ---------- TREE CONSTRUCTION ------------------------------------------- */ diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 19cf1b5093..6ad1c50075 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -9,7 +9,7 @@ import scala.tools.nsc.util.CharArrayReader import scala.reflect.internal.util._ import scala.reflect.internal.Chars._ import Tokens._ -import scala.annotation.switch +import scala.annotation.{ switch, tailrec } import scala.collection.{ mutable, immutable } import mutable.{ ListBuffer, ArrayBuffer } import scala.xml.Utility.{ isNameStart } @@ -83,6 +83,69 @@ trait Scanners extends ScannersCommon { abstract class Scanner extends CharArrayReader with TokenData with ScannerCommon { private def isDigit(c: Char) = java.lang.Character isDigit c + private var openComments = 0 + protected def putCommentChar(): Unit = nextChar() + + @tailrec private def skipLineComment(): Unit = ch match { + case SU | CR | LF => + case _ => nextChar() ; skipLineComment() + } + private def maybeOpen() { + putCommentChar() + if (ch == '*') { + putCommentChar() + openComments += 1 + } + } + private def maybeClose(): Boolean = { + putCommentChar() + (ch == '/') && { + putCommentChar() + openComments -= 1 + openComments == 0 + } + } + @tailrec final def skipNestedComments(): Unit = ch match { + case '/' => maybeOpen() ; skipNestedComments() + case '*' => if (!maybeClose()) skipNestedComments() + case SU => incompleteInputError("unclosed comment") + case _ => putCommentChar() ; skipNestedComments() + } + def skipDocComment(): Unit = skipNestedComments() + def skipBlockComment(): Unit = skipNestedComments() + + private def skipToCommentEnd(isLineComment: Boolean) { + nextChar() + if (isLineComment) skipLineComment() + else { + openComments = 1 + val isDocComment = (ch == '*') && { nextChar(); true } + if (isDocComment) { + // Check for the amazing corner case of /**/ + if (ch == '/') + nextChar() + else + skipDocComment() + } + else skipBlockComment() + } + } + + /** @pre ch == '/' + * Returns true if a comment was skipped. + */ + def skipComment(): Boolean = ch match { + case '/' | '*' => skipToCommentEnd(isLineComment = ch == '/') ; true + case _ => false + } + def flushDoc(): DocComment = null + + /** To prevent doc comments attached to expressions from leaking out of scope + * onto the next documentable entity, they are discarded upon passing a right + * brace, bracket, or parenthesis. + */ + def discardDocBuffer(): Unit = () + def isAtEnd = charOffset >= buf.length def resume(lastCode: Int) = { @@ -130,22 +193,6 @@ trait Scanners extends ScannersCommon { cbuf.clear() } - /** Should doc comments be built? */ - def buildDocs: Boolean = forScaladoc - - /** holder for the documentation comment - */ - var docComment: DocComment = null - - def flushDoc: DocComment = { - val ret = docComment - docComment = null - ret - } - - protected def foundComment(value: String, start: Int, end: Int) = () - protected def foundDocComment(value: String, start: Int, end: Int) = () - private class TokenData0 extends TokenData /** we need one token lookahead and one token history @@ -218,12 +265,15 @@ trait Scanners extends ScannersCommon { case RBRACE => while (!sepRegions.isEmpty && sepRegions.head != RBRACE) sepRegions = sepRegions.tail - if (!sepRegions.isEmpty) sepRegions = sepRegions.tail - docComment = null + if (!sepRegions.isEmpty) + sepRegions = sepRegions.tail + + discardDocBuffer() case RBRACKET | RPAREN => if (!sepRegions.isEmpty && sepRegions.head == lastToken) sepRegions = sepRegions.tail - docComment = null + + discardDocBuffer() case ARROW => if (!sepRegions.isEmpty && sepRegions.head == lastToken) sepRegions = sepRegions.tail @@ -516,62 +566,6 @@ trait Scanners extends ScannersCommon { } } - private def skipComment(): Boolean = { - - if (ch == '/' || ch == '*') { - - val comment = new StringBuilder("/") - def appendToComment() = comment.append(ch) - - if (ch == '/') { - do { - appendToComment() - nextChar() - } while ((ch != CR) && (ch != LF) && (ch != SU)) - } else { - docComment = null - var openComments = 1 - appendToComment() - nextChar() - appendToComment() - var buildingDocComment = false - if (ch == '*' && buildDocs) { - buildingDocComment = true - } - while (openComments > 0) { - do { - do { - if (ch == '/') { - nextChar(); appendToComment() - if (ch == '*') { - nextChar(); appendToComment() - openComments += 1 - } - } - if (ch != '*' && ch != SU) { - nextChar(); appendToComment() - } - } while (ch != '*' && ch != SU) - while (ch == '*') { - nextChar(); appendToComment() - } - } while (ch != '/' && ch != SU) - if (ch == '/') nextChar() - else incompleteInputError("unclosed comment") - openComments -= 1 - } - - if (buildingDocComment) - foundDocComment(comment.toString, offset, charOffset - 2) - } - - foundComment(comment.toString, offset, charOffset - 2) - true - } else { - false - } - } - /** Can token start a statement? */ def inFirstOfStat(token: Int) = token match { case EOF | CATCH | ELSE | EXTENDS | FINALLY | FORSOME | MATCH | WITH | YIELD | @@ -1233,7 +1227,7 @@ trait Scanners extends ScannersCommon { /** A scanner over a given compilation unit */ - class UnitScanner(unit: CompilationUnit, patches: List[BracePatch]) extends SourceFileScanner(unit.source) { + class UnitScanner(val unit: CompilationUnit, patches: List[BracePatch]) extends SourceFileScanner(unit.source) { def this(unit: CompilationUnit) = this(unit, List()) override def deprecationWarning(off: Offset, msg: String) = unit.deprecationWarning(unit.position(off), msg) @@ -1281,17 +1275,6 @@ trait Scanners extends ScannersCommon { } } } - - override def foundComment(value: String, start: Int, end: Int) { - val pos = new RangePosition(unit.source, start, start, end) - unit.comment(pos, value) - } - - override def foundDocComment(value: String, start: Int, end: Int) { - val docPos = new RangePosition(unit.source, start, start, end) - docComment = new DocComment(value, docPos) - unit.comment(docPos, value) - } } class ParensAnalyzer(unit: CompilationUnit, patches: List[BracePatch]) extends UnitScanner(unit, patches) { @@ -1382,17 +1365,24 @@ trait Scanners extends ScannersCommon { bpbuf += current } } + def bracePairString(bp: BracePair, indent: Int): String = { + val rangeString = { + import bp._ + val lline = line(loff) + val rline = line(roff) + val tokens = List(lline, lindent, rline, rindent) map (n => if (n < 0) "??" else "" + n) + "%s:%s to %s:%s".format(tokens: _*) + } + val outer = (" " * indent) + rangeString + val inners = bp.nested map (bracePairString(_, indent + 2)) - def printBP(bp: BracePair, indent: Int) { - println(" "*indent+line(bp.loff)+":"+bp.lindent+" to "+line(bp.roff)+":"+bp.rindent) - if (bp.nested.nonEmpty) - for (bp1 <- bp.nested) { - printBP(bp1, indent + 2) - } + if (inners.isEmpty) outer + else inners.mkString(outer + "\n", "\n", "") } -// println("lineStart = "+lineStart)//DEBUG -// println("bracepairs = ") -// for (bp <- bpbuf.toList) printBP(bp, 0) + def bpString = bpbuf.toList map ("\n" + bracePairString(_, 0)) mkString "" + def startString = lineStart.mkString("line starts: [", ", ", "]") + + log(s"\n$startString\n$bpString") bpbuf.toList } diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala index f1bf590ebf..7cf5a07291 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala @@ -28,8 +28,8 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse if (unit.body == EmptyTree) { unit.body = if (unit.isJava) new JavaUnitParser(unit).parse() - else if (reporter.incompleteHandled) new UnitParser(unit).parse() - else new UnitParser(unit).smartParse() + else if (reporter.incompleteHandled) newUnitParser(unit).parse() + else newUnitParser(unit).smartParse() } if (settings.Yrangepos.value && !reporter.hasErrors) diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala index 917fe8b292..d772dcb6c4 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala @@ -17,7 +17,7 @@ trait BasicBlocks { self: ICodes => import opcodes._ - import global.{ settings, log, nme } + import global.{ settings, debuglog, log, nme } import nme.isExceptionResultName /** Override Array creation for efficiency (to not go through reflection). */ @@ -383,7 +383,6 @@ trait BasicBlocks { /** Close the block */ def close() { assert(!closed || ignore, this) - assert(instructionList.nonEmpty, "Empty block: " + this) if (ignore && closed) { // redundant `ignore &&` for clarity -- we should never be in state `!ignore && closed` // not doing anything to this block is important... // because the else branch reverses innocent blocks, which is wrong when they're in ignore mode (and closed) @@ -393,9 +392,38 @@ trait BasicBlocks { setFlag(DIRTYSUCCS) instructionList = instructionList.reverse instrs = instructionList.toArray + if (instructionList.isEmpty) { + debuglog(s"Removing empty block $this") + code removeBlock this + } } } + /** + * if cond is true, closes this block, entersIgnoreMode, and removes the block from + * its list of blocks. Used to allow a block to be started and then cancelled when it + * is discovered to be unreachable. + */ + def killIf(cond: Boolean) { + if (!settings.YdisableUnreachablePrevention.value && cond) { + debuglog(s"Killing block $this") + assert(instructionList.isEmpty, s"Killing a non empty block $this") + // only checked under debug because fetching predecessor list is moderately expensive + if (settings.debug.value) + assert(predecessors.isEmpty, s"Killing block $this which is referred to from ${predecessors.mkString}") + + close() + enterIgnoreMode() + } + } + + /** + * Same as killIf but with the logic of the condition reversed + */ + def killUnless(cond: Boolean) { + this killIf !cond + } + def open() { assert(closed, this) closed = false diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index ed458a4bbe..94116d6783 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -376,12 +376,14 @@ abstract class GenICode extends SubComponent { "I produce UNIT in a context where " + expectedType + " is expected!") // alternatives may be already closed by a tail-recursive jump + val contReachable = !(thenCtx.bb.ignore && elseCtx.bb.ignore) thenCtx.bb.closeWith(JUMP(contCtx.bb)) elseCtx.bb.closeWith( if (elsep == EmptyTree) JUMP(contCtx.bb) else JUMP(contCtx.bb) setPos tree.pos ) + contCtx.bb killUnless contReachable (contCtx, resKind) } private def genLoadTry(tree: Try, ctx: Context, setGeneratedType: TypeKind => Unit): Context = { @@ -477,7 +479,11 @@ abstract class GenICode extends SubComponent { val resCtx: Context = tree match { case LabelDef(name, params, rhs) => def genLoadLabelDef = { - val ctx1 = ctx.newBlock() + val ctx1 = ctx.newBlock() // note: we cannot kill ctx1 if ctx is in ignore mode because + // label defs can be the target of jumps from other locations. + // that means label defs can lead to unreachable code without + // proper reachability analysis + if (nme.isLoopHeaderLabel(name)) ctx1.bb.loopHeader = true @@ -560,6 +566,7 @@ abstract class GenICode extends SubComponent { // the list, otherwise infinite recursion happens for // finalizers that contain 'return' val fctx = finalizerCtx.newBlock() + fctx.bb killIf ctx1.bb.ignore ctx1.bb.closeWith(JUMP(fctx.bb)) ctx1 = genLoad(f1, fctx, UNIT) } @@ -949,6 +956,8 @@ abstract class GenICode extends SubComponent { debuglog("Generating SWITCH statement.") val ctx1 = genLoad(selector, ctx, INT) // TODO: Java 7 allows strings in switches (so, don't assume INT and don't convert the literals using intValue) val afterCtx = ctx1.newBlock() + afterCtx.bb killIf ctx1.bb.ignore + var afterCtxReachable = false var caseCtx: Context = null generatedType = toTypeKind(tree.tpe) @@ -959,6 +968,7 @@ abstract class GenICode extends SubComponent { for (caze @ CaseDef(pat, guard, body) <- cases) { assert(guard == EmptyTree, guard) val tmpCtx = ctx1.newBlock() + tmpCtx.bb killIf ctx1.bb.ignore pat match { case Literal(value) => tags = value.intValue :: tags @@ -980,12 +990,15 @@ abstract class GenICode extends SubComponent { } caseCtx = genLoad(body, tmpCtx, generatedType) + afterCtxReachable ||= !caseCtx.bb.ignore // close the block unless it's already been closed by the body, which closes the block if it ends in a jump (which is emitted to have alternatives share their body) caseCtx.bb.closeWith(JUMP(afterCtx.bb) setPos caze.pos) } + afterCtxReachable ||= (default == afterCtx) ctx1.bb.emitOnly( SWITCH(tags.reverse map (x => List(x)), (default :: targets).reverse) setPos tree.pos ) + afterCtx.bb killUnless afterCtxReachable afterCtx } genLoadMatch @@ -1025,7 +1038,7 @@ abstract class GenICode extends SubComponent { // this value into a local of type Null and we want the JVM to see that it's // a null value so we don't have to also adapt local loads. if (from == NullReference && to != UNIT && to != ObjectReference && to != AnyRefReference) { - assert(to.isReferenceType, "Attempt to adapt a null to a non reference type $to.") + assert(to.isRefOrArrayType, s"Attempt to adapt a null to a non reference type $to.") // adapt by dropping what we've got and pushing a null which // will convince the JVM we really do have null ctx.bb.emit(DROP(from), pos) @@ -1342,9 +1355,17 @@ abstract class GenICode extends SubComponent { private def genCond(tree: Tree, ctx: Context, thenCtx: Context, - elseCtx: Context): Unit = - { - def genComparisonOp(l: Tree, r: Tree, code: Int) { + elseCtx: Context): Boolean = + { + /** + * Generate the de-sugared comparison mechanism that will underly an '==' + * + * @param l left-hand side of the '==' + * @param r right-hand side of the '==' + * @param code the comparison operator to use + * @return true if either branch can continue normally to a follow on block, false otherwise + */ + def genComparisonOp(l: Tree, r: Tree, code: Int): Boolean = { val op: TestOp = code match { case scalaPrimitives.LT => LT case scalaPrimitives.LE => LE @@ -1360,27 +1381,33 @@ abstract class GenICode extends SubComponent { lazy val nonNullSide = ifOneIsNull(l, r) if (isReferenceEqualityOp(code) && nonNullSide != null) { val ctx1 = genLoad(nonNullSide, ctx, ObjectReference) + val branchesReachable = !ctx1.bb.ignore ctx1.bb.emitOnly( CZJUMP(thenCtx.bb, elseCtx.bb, op, ObjectReference) ) + branchesReachable } else { val kind = getMaxType(l.tpe :: r.tpe :: Nil) var ctx1 = genLoad(l, ctx, kind) ctx1 = genLoad(r, ctx1, kind) + val branchesReachable = !ctx1.bb.ignore ctx1.bb.emitOnly( CJUMP(thenCtx.bb, elseCtx.bb, op, kind) setPos r.pos ) + branchesReachable } } debuglog("Entering genCond with tree: " + tree) // the default emission - def default() = { + def default(): Boolean = { val ctx1 = genLoad(tree, ctx, BOOL) + val branchesReachable = !ctx1.bb.ignore ctx1.bb.closeWith(CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL) setPos tree.pos) + branchesReachable } tree match { @@ -1392,11 +1419,12 @@ abstract class GenICode extends SubComponent { lazy val Select(lhs, _) = fun lazy val rhs = args.head - def genZandOrZor(and: Boolean) = { + def genZandOrZor(and: Boolean): Boolean = { val ctxInterm = ctx.newBlock() - if (and) genCond(lhs, ctx, ctxInterm, elseCtx) + val branchesReachable = if (and) genCond(lhs, ctx, ctxInterm, elseCtx) else genCond(lhs, ctx, thenCtx, ctxInterm) + ctxInterm.bb killUnless branchesReachable genCond(rhs, ctxInterm, thenCtx, elseCtx) } @@ -1435,8 +1463,9 @@ abstract class GenICode extends SubComponent { * @param ctx current context * @param thenCtx target context if the comparison yields true * @param elseCtx target context if the comparison yields false + * @return true if either branch can continue normally to a follow on block, false otherwise */ - def genEqEqPrimitive(l: Tree, r: Tree, ctx: Context)(thenCtx: Context, elseCtx: Context): Unit = { + def genEqEqPrimitive(l: Tree, r: Tree, ctx: Context)(thenCtx: Context, elseCtx: Context): Boolean = { def getTempLocal = ctx.method.lookupLocal(nme.EQEQ_LOCAL_VAR) getOrElse { ctx.makeLocal(l.pos, AnyRefClass.tpe, nme.EQEQ_LOCAL_VAR.toString) } @@ -1476,26 +1505,40 @@ abstract class GenICode extends SubComponent { val ctx1 = genLoad(l, ctx, ObjectReference) val ctx2 = genLoad(r, ctx1, ObjectReference) + val branchesReachable = !ctx2.bb.ignore ctx2.bb.emitOnly( CALL_METHOD(equalsMethod, if (settings.optimise.value) Dynamic else Static(onInstance = false)), CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL) ) + branchesReachable } else { - if (isNull(l)) + if (isNull(l)) { // null == expr -> expr eq null - genLoad(r, ctx, ObjectReference).bb emitOnly CZJUMP(thenCtx.bb, elseCtx.bb, EQ, ObjectReference) - else if (isNull(r)) { + val ctx1 = genLoad(r, ctx, ObjectReference) + val branchesReachable = !ctx1.bb.ignore + ctx1.bb emitOnly CZJUMP(thenCtx.bb, elseCtx.bb, EQ, ObjectReference) + branchesReachable + } else if (isNull(r)) { // expr == null -> expr eq null - genLoad(l, ctx, ObjectReference).bb emitOnly CZJUMP(thenCtx.bb, elseCtx.bb, EQ, ObjectReference) + val ctx1 = genLoad(l, ctx, ObjectReference) + val branchesReachable = !ctx1.bb.ignore + ctx1.bb emitOnly CZJUMP(thenCtx.bb, elseCtx.bb, EQ, ObjectReference) + branchesReachable } else { val eqEqTempLocal = getTempLocal var ctx1 = genLoad(l, ctx, ObjectReference) - lazy val nonNullCtx = ctx1.newBlock() + val branchesReachable = !ctx1.bb.ignore + lazy val nonNullCtx = { + val block = ctx1.newBlock() + block.bb killUnless branchesReachable + block + } // l == r -> if (l eq null) r eq null else l.equals(r) ctx1 = genLoad(r, ctx1, ObjectReference) val nullCtx = ctx1.newBlock() + nullCtx.bb killUnless branchesReachable ctx1.bb.emitOnly( STORE_LOCAL(eqEqTempLocal) setPos l.pos, @@ -1512,6 +1555,7 @@ abstract class GenICode extends SubComponent { CALL_METHOD(Object_equals, Dynamic), CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL) ) + branchesReachable } } } @@ -1957,6 +2001,7 @@ abstract class GenICode extends SubComponent { val outerCtx = this.dup // context for generating exception handlers, covered by the catch-all finalizer val finalizerCtx = this.dup // context for generating finalizer handler val normalExitCtx = outerCtx.newBlock() // context where flow will go on a "normal" (non-return, non-throw) exit from a try or catch handler + var normalExitReachable = false var tmp: Local = null val kind = toTypeKind(tree.tpe) val guardResult = kind != UNIT && mayCleanStack(finalizer) @@ -1971,6 +2016,7 @@ abstract class GenICode extends SubComponent { def emitFinalizer(ctx: Context): Context = if (!finalizer.isEmpty) { val ctx1 = finalizerCtx.dup.newBlock() + ctx1.bb killIf ctx.bb.ignore ctx.bb.closeWith(JUMP(ctx1.bb)) if (guardResult) { @@ -1986,32 +2032,38 @@ abstract class GenICode extends SubComponent { // Generate the catch-all exception handler that deals with uncaught exceptions coming // from the try or exception handlers. It catches the exception, runs the finally code, then rethrows // the exception - if (finalizer != EmptyTree) { - val exh = outerCtx.newExceptionHandler(NoSymbol, finalizer.pos) // finalizer covers exception handlers - this.addActiveHandler(exh) // .. and body aswell - val exhStartCtx = finalizerCtx.enterExceptionHandler(exh) - val exception = exhStartCtx.makeLocal(finalizer.pos, ThrowableClass.tpe, "exc") - loadException(exhStartCtx, exh, finalizer.pos) - exhStartCtx.bb.emit(STORE_LOCAL(exception)) - val exhEndCtx = genLoad(finalizer, exhStartCtx, UNIT) - exhEndCtx.bb.emit(LOAD_LOCAL(exception)) - exhEndCtx.bb.closeWith(THROW(ThrowableClass)) - exhEndCtx.bb.enterIgnoreMode() - finalizerCtx.endHandler() - } - - // Generate each exception handler - for ((sym, kind, handler) <- handlers) { - val exh = this.newExceptionHandler(sym, tree.pos) - val exhStartCtx = outerCtx.enterExceptionHandler(exh) - exhStartCtx.addFinalizer(finalizer, finalizerCtx) - loadException(exhStartCtx, exh, tree.pos) - val exhEndCtx = handler(exhStartCtx) - exhEndCtx.bb.closeWith(JUMP(normalExitCtx.bb)) - outerCtx.endHandler() + if (settings.YdisableUnreachablePrevention.value || !outerCtx.bb.ignore) { + if (finalizer != EmptyTree) { + val exh = outerCtx.newExceptionHandler(NoSymbol, finalizer.pos) // finalizer covers exception handlers + this.addActiveHandler(exh) // .. and body aswell + val exhStartCtx = finalizerCtx.enterExceptionHandler(exh) + exhStartCtx.bb killIf outerCtx.bb.ignore + val exception = exhStartCtx.makeLocal(finalizer.pos, ThrowableClass.tpe, "exc") + loadException(exhStartCtx, exh, finalizer.pos) + exhStartCtx.bb.emit(STORE_LOCAL(exception)) + val exhEndCtx = genLoad(finalizer, exhStartCtx, UNIT) + exhEndCtx.bb.emit(LOAD_LOCAL(exception)) + exhEndCtx.bb.closeWith(THROW(ThrowableClass)) + exhEndCtx.bb.enterIgnoreMode() + finalizerCtx.endHandler() + } + + // Generate each exception handler + for ((sym, kind, handler) <- handlers) { + val exh = this.newExceptionHandler(sym, tree.pos) + val exhStartCtx = outerCtx.enterExceptionHandler(exh) + exhStartCtx.bb killIf outerCtx.bb.ignore + exhStartCtx.addFinalizer(finalizer, finalizerCtx) + loadException(exhStartCtx, exh, tree.pos) + val exhEndCtx = handler(exhStartCtx) + normalExitReachable ||= !exhEndCtx.bb.ignore + exhEndCtx.bb.closeWith(JUMP(normalExitCtx.bb)) + outerCtx.endHandler() + } } val bodyCtx = this.newBlock() + bodyCtx.bb killIf outerCtx.bb.ignore if (finalizer != EmptyTree) bodyCtx.addFinalizer(finalizer, finalizerCtx) @@ -2019,6 +2071,8 @@ abstract class GenICode extends SubComponent { outerCtx.bb.closeWith(JUMP(bodyCtx.bb)) + normalExitReachable ||= !bodyEndCtx.bb.ignore + normalExitCtx.bb killUnless normalExitReachable bodyEndCtx.bb.closeWith(JUMP(normalExitCtx.bb)) emitFinalizer(normalExitCtx) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 703922b20a..388efb4625 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -2144,8 +2144,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { val start = st.pop() seen ::= LocVarEntry(lv, start, end) case _ => - // TODO SI-6049 - getCurrentCUnit().warning(iPos, "Visited SCOPE_EXIT before visiting corresponding SCOPE_ENTER. SI-6049") + // TODO SI-6049 track down the cause for these. + debugwarn(s"$iPos: Visited SCOPE_EXIT before visiting corresponding SCOPE_ENTER. SI-6191") } } @@ -3298,7 +3298,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { def normalize(m: IMethod) { if(!m.hasCode) { return } collapseJumpOnlyBlocks(m) - elimUnreachableBlocks(m) + if (settings.optimise.value) + elimUnreachableBlocks(m) icodes checkValid m } diff --git a/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala b/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala deleted file mode 100644 index b8a0637b47..0000000000 --- a/src/compiler/scala/tools/nsc/doc/ScaladocGlobal.scala +++ /dev/null @@ -1,107 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package doc - -import scala.util.control.ControlThrowable -import reporters.Reporter -import typechecker.Analyzer -import scala.reflect.internal.util.BatchSourceFile - -trait ScaladocAnalyzer extends Analyzer { - val global : Global // generally, a ScaladocGlobal - import global._ - - override def newTyper(context: Context): ScaladocTyper = new ScaladocTyper(context) - - class ScaladocTyper(context0: Context) extends Typer(context0) { - private def unit = context.unit - - override def typedDocDef(docDef: DocDef, mode: Mode, pt: Type): Tree = { - val sym = docDef.symbol - - if ((sym ne null) && (sym ne NoSymbol)) { - val comment = docDef.comment - docComments(sym) = comment - comment.defineVariables(sym) - val typer1 = newTyper(context.makeNewScope(docDef, context.owner)) - for (useCase <- comment.useCases) { - typer1.silent(_ => typer1 defineUseCases useCase) match { - case SilentTypeError(err) => - unit.warning(useCase.pos, err.errMsg) - case _ => - } - for (useCaseSym <- useCase.defined) { - if (sym.name != useCaseSym.name) - unit.warning(useCase.pos, "@usecase " + useCaseSym.name.decode + " does not match commented symbol: " + sym.name.decode) - } - } - } - - super.typedDocDef(docDef, mode, pt) - } - - def defineUseCases(useCase: UseCase): List[Symbol] = { - def stringParser(str: String): syntaxAnalyzer.Parser = { - val file = new BatchSourceFile(context.unit.source.file, str) { - override def positionInUltimateSource(pos: Position) = { - pos.withSource(context.unit.source, useCase.pos.start) - } - } - val unit = new CompilationUnit(file) - new syntaxAnalyzer.UnitParser(unit) - } - - val trees = stringParser(useCase.body+";").nonLocalDefOrDcl - val enclClass = context.enclClass.owner - - def defineAlias(name: Name) = ( - if (context.scope.lookup(name) == NoSymbol) { - lookupVariable(name.toString.substring(1), enclClass) foreach { repl => - silent(_.typedTypeConstructor(stringParser(repl).typ())) map { tpt => - val alias = enclClass.newAliasType(name.toTypeName, useCase.pos) - val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias) - val newInfo = genPolyType(tparams, appliedType(tpt.tpe, tparams map (_.tpe))) - alias setInfo newInfo - context.scope.enter(alias) - } - } - } - ) - - for (tree <- trees; t <- tree) - t match { - case Ident(name) if name startsWith '$' => defineAlias(name) - case _ => - } - - useCase.aliases = context.scope.toList - namer.enterSyms(trees) - typedStats(trees, NoSymbol) - useCase.defined = context.scope.toList filterNot (useCase.aliases contains _) - - if (settings.debug.value) - useCase.defined foreach (sym => println("defined use cases: %s:%s".format(sym, sym.tpe))) - - useCase.defined - } - } -} - -class ScaladocGlobal(settings: doc.Settings, reporter: Reporter) extends { - override val useOffsetPositions = false -} with Global(settings, reporter) { - override protected def computeInternalPhases() { - phasesSet += syntaxAnalyzer - phasesSet += analyzer.namerFactory - phasesSet += analyzer.packageObjects - phasesSet += analyzer.typerFactory - } - override def forScaladoc = true - override lazy val analyzer = new { - val global: ScaladocGlobal.this.type = ScaladocGlobal.this - } with ScaladocAnalyzer -} diff --git a/src/compiler/scala/tools/nsc/io/Pickler.scala b/src/compiler/scala/tools/nsc/io/Pickler.scala index 43a6ef3c61..0e7da37c52 100644 --- a/src/compiler/scala/tools/nsc/io/Pickler.scala +++ b/src/compiler/scala/tools/nsc/io/Pickler.scala @@ -327,6 +327,12 @@ object Pickler { } } + /** A pickler for pairs, represented as `~`-pairs */ + implicit def tuple2Pickler[T1: Pickler, T2: Pickler]: Pickler[(T1, T2)] = + (pkl[T1] ~ pkl[T2]) + .wrapped { case x1 ~ x2 => (x1, x2) } { case (x1, x2) => x1 ~ x2 } + .labelled ("tuple2") + /** A pickler for 3-tuples, represented as `~`-tuples */ implicit def tuple3Pickler[T1, T2, T3](implicit p1: Pickler[T1], p2: Pickler[T2], p3: Pickler[T3]): Pickler[(T1, T2, T3)] = (p1 ~ p2 ~ p3) diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala index 1d1469f87d..f9b1e57e66 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala @@ -10,7 +10,7 @@ import scala.tools.nsc.util.JavaCharArrayReader import scala.reflect.internal.util._ import scala.reflect.internal.Chars._ import JavaTokens._ -import scala.annotation.switch +import scala.annotation.{ switch, tailrec } import scala.language.implicitConversions // Todo merge these better with Scanners @@ -235,16 +235,6 @@ trait JavaScanners extends ast.parser.ScannersCommon { cbuf.setLength(0) } - /** buffer for the documentation comment - */ - var docBuffer: StringBuilder = null - - /** add the given character to the documentation buffer - */ - protected def putDocChar(c: Char) { - if (docBuffer ne null) docBuffer.append(c) - } - private class JavaTokenData0 extends JavaTokenData /** we need one token lookahead @@ -587,33 +577,20 @@ trait JavaScanners extends ast.parser.ScannersCommon { } } - private def skipComment(): Boolean = { - if (in.ch == '/') { - do { - in.next() - } while ((in.ch != CR) && (in.ch != LF) && (in.ch != SU)) - true - } else if (in.ch == '*') { - docBuffer = null - in.next() - val scalaDoc = ("/**", "*/") - if (in.ch == '*' && forScaladoc) - docBuffer = new StringBuilder(scalaDoc._1) - do { - do { - if (in.ch != '*' && in.ch != SU) { - in.next(); putDocChar(in.ch) - } - } while (in.ch != '*' && in.ch != SU) - while (in.ch == '*') { - in.next(); putDocChar(in.ch) - } - } while (in.ch != '/' && in.ch != SU) - if (in.ch == '/') in.next() - else incompleteInputError("unclosed comment") - true - } else { - false + protected def skipComment(): Boolean = { + @tailrec def skipLineComment(): Unit = in.ch match { + case CR | LF | SU => + case _ => in.next; skipLineComment() + } + @tailrec def skipJavaComment(): Unit = in.ch match { + case SU => incompleteInputError("unclosed comment") + case '*' => in.next; if (in.ch == '/') in.next else skipJavaComment() + case _ => in.next; skipJavaComment() + } + in.ch match { + case '/' => in.next ; skipLineComment() ; true + case '*' => in.next ; skipJavaComment() ; true + case _ => false } } diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 2c9c20666d..2aee9bd4bc 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -43,6 +43,7 @@ trait ScalaSettings extends AbsScalaSettings /** Internal use - syntax enhancements. */ private class EnableSettings[T <: BooleanSetting](val s: T) { def enabling(toEnable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toEnable foreach (_.value = s.value)) + def disabling(toDisable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toDisable foreach (_.value = !s.value)) def andThen(f: s.T => Unit): s.type = s withPostSetHook (setting => f(setting.value)) } private implicit def installEnableSettings[T <: BooleanSetting](s: T) = new EnableSettings(s) @@ -172,6 +173,7 @@ trait ScalaSettings extends AbsScalaSettings val Yinvalidate = StringSetting ("-Yinvalidate", "classpath-entry", "Invalidate classpath entry before run", "") val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.") val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes") + val YdisableUnreachablePrevention = BooleanSetting("-Ydisable-unreachable-prevention", "Disable the prevention of unreachable blocks in code generation.") val exposeEmptyPackage = BooleanSetting("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly() @@ -194,6 +196,7 @@ trait ScalaSettings extends AbsScalaSettings */ val future = BooleanSetting("-Xfuture", "Turn on future language features.") enabling futureSettings val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize" enabling optimiseSettings + val nooptimise = BooleanSetting("-Ynooptimise", "Clears all the flags set by -optimise. Useful for testing optimizations in isolation.") withAbbreviation "-Ynooptimize" disabling optimise::optimiseSettings val Xexperimental = BooleanSetting("-Xexperimental", "Enable experimental extensions.") enabling experimentalSettings // Feature extensions diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 5b5118a94f..61ac07d18f 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -30,6 +30,14 @@ abstract class SymbolLoaders { member } + protected def signalError(root: Symbol, ex: Throwable) { + if (settings.debug.value) ex.printStackTrace() + globalError(ex.getMessage() match { + case null => "i/o error while loading " + root.name + case msg => "error while loading " + root.name + ", " + msg + }) + } + /** Enter class with given `name` into scope of `root` * and give them `completer` as type. */ @@ -168,18 +176,6 @@ abstract class SymbolLoaders { } override def complete(root: Symbol) { - def signalError(ex: Exception) { - ok = false - if (settings.debug.value) ex.printStackTrace() - val msg = ex.getMessage() - // SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented - // therefore, it will rummage through the classpath triggering errors whenever it encounters package objects - // that are not in their correct place (see bug for details) - if (!settings.isScaladoc) - globalError( - if (msg eq null) "i/o error while loading " + root.name - else "error while loading " + root.name + ", " + msg) - } try { val start = currentTime val currentphase = phase @@ -189,11 +185,11 @@ abstract class SymbolLoaders { ok = true setSource(root) setSource(root.companionSymbol) // module -> class, class -> module - } catch { - case ex: IOException => - signalError(ex) - case ex: MissingRequirementError => - signalError(ex) + } + catch { + case ex @ (_: IOException | _: MissingRequirementError) => + ok = false + signalError(root, ex) } initRoot(root) if (!root.isPackageClass) initRoot(root.companionSymbol) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index e676abb86a..55b9ce1be9 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -447,6 +447,7 @@ abstract class Erasure extends AddInterfaces def checkPair(member: Symbol, other: Symbol) { val otpe = specialErasure(root)(other.tpe) val bridgeNeeded = exitingErasure ( + !member.isMacro && !(other.tpe =:= member.tpe) && !(deconstMap(other.tpe) =:= deconstMap(member.tpe)) && { var e = bridgesScope.lookupEntry(member.name) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala index 4fc71a7410..69d9987b05 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala @@ -287,236 +287,9 @@ trait Logic extends Debugging { def findModelFor(f: Formula): Model def findAllModelsFor(f: Formula): List[Model] } - - trait CNF extends PropositionalLogic { - - /** Override Array creation for efficiency (to not go through reflection). */ - private implicit val clauseTag: scala.reflect.ClassTag[Clause] = new scala.reflect.ClassTag[Clause] { - def runtimeClass: java.lang.Class[Clause] = classOf[Clause] - final override def newArray(len: Int): Array[Clause] = new Array[Clause](len) - } - - import scala.collection.mutable.ArrayBuffer - type FormulaBuilder = ArrayBuffer[Clause] - def formulaBuilder = ArrayBuffer[Clause]() - def formulaBuilderSized(init: Int) = new ArrayBuffer[Clause](init) - def addFormula(buff: FormulaBuilder, f: Formula): Unit = buff ++= f - def toFormula(buff: FormulaBuilder): Formula = buff - - // CNF: a formula is a conjunction of clauses - type Formula = FormulaBuilder - def formula(c: Clause*): Formula = ArrayBuffer(c: _*) - - type Clause = Set[Lit] - // a clause is a disjunction of distinct literals - def clause(l: Lit*): Clause = l.toSet - - type Lit - def Lit(sym: Sym, pos: Boolean = true): Lit - - def andFormula(a: Formula, b: Formula): Formula = a ++ b - def simplifyFormula(a: Formula): Formula = a.distinct - - private def merge(a: Clause, b: Clause) = a ++ b - - // throws an AnalysisBudget.Exception when the prop results in a CNF that's too big - // TODO: be smarter/more efficient about this (http://lara.epfl.ch/w/sav09:tseitin_s_encoding) - def eqFreePropToSolvable(p: Prop): Formula = { - def negationNormalFormNot(p: Prop, budget: Int): Prop = - if (budget <= 0) throw AnalysisBudget.exceeded - else p match { - case And(a, b) => Or(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1)) - case Or(a, b) => And(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1)) - case Not(p) => negationNormalForm(p, budget - 1) - case True => False - case False => True - case s: Sym => Not(s) - } - - def negationNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Prop = - if (budget <= 0) throw AnalysisBudget.exceeded - else p match { - case And(a, b) => And(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1)) - case Or(a, b) => Or(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1)) - case Not(negated) => negationNormalFormNot(negated, budget - 1) - case True - | False - | (_ : Sym) => p - } - - val TrueF = formula() - val FalseF = formula(clause()) - def lit(s: Sym) = formula(clause(Lit(s))) - def negLit(s: Sym) = formula(clause(Lit(s, pos = false))) - - def conjunctiveNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Formula = { - def distribute(a: Formula, b: Formula, budget: Int): Formula = - if (budget <= 0) throw AnalysisBudget.exceeded - else - (a, b) match { - // true \/ _ = true - // _ \/ true = true - case (trueA, trueB) if trueA.size == 0 || trueB.size == 0 => TrueF - // lit \/ lit - case (a, b) if a.size == 1 && b.size == 1 => formula(merge(a(0), b(0))) - // (c1 /\ ... /\ cn) \/ d = ((c1 \/ d) /\ ... /\ (cn \/ d)) - // d \/ (c1 /\ ... /\ cn) = ((d \/ c1) /\ ... /\ (d \/ cn)) - case (cs, ds) => - val (big, small) = if (cs.size > ds.size) (cs, ds) else (ds, cs) - big flatMap (c => distribute(formula(c), small, budget - (big.size*small.size))) - } - - if (budget <= 0) throw AnalysisBudget.exceeded - - p match { - case True => TrueF - case False => FalseF - case s: Sym => lit(s) - case Not(s: Sym) => negLit(s) - case And(a, b) => - val cnfA = conjunctiveNormalForm(a, budget - 1) - val cnfB = conjunctiveNormalForm(b, budget - cnfA.size) - cnfA ++ cnfB - case Or(a, b) => - val cnfA = conjunctiveNormalForm(a) - val cnfB = conjunctiveNormalForm(b) - distribute(cnfA, cnfB, budget - (cnfA.size + cnfB.size)) - } - } - - val start = if (Statistics.canEnable) Statistics.startTimer(patmatCNF) else null - val res = conjunctiveNormalForm(negationNormalForm(p)) - - if (Statistics.canEnable) Statistics.stopTimer(patmatCNF, start) - - // - if (Statistics.canEnable) patmatCNFSizes(res.size).value += 1 - -// debug.patmat("cnf for\n"+ p +"\nis:\n"+cnfString(res)) - res - } - } - - trait DPLLSolver extends CNF { - // a literal is a (possibly negated) variable - def Lit(sym: Sym, pos: Boolean = true) = new Lit(sym, pos) - class Lit(val sym: Sym, val pos: Boolean) { - override def toString = if (!pos) "-"+ sym.toString else sym.toString - override def equals(o: Any) = o match { - case o: Lit => (o.sym eq sym) && (o.pos == pos) - case _ => false - } - override def hashCode = sym.hashCode + pos.hashCode - - def unary_- = Lit(sym, !pos) - } - - def cnfString(f: Formula) = alignAcrossRows(f map (_.toList) toList, "\\/", " /\\\n") - - // adapted from http://lara.epfl.ch/w/sav10:simple_sat_solver (original by Hossein Hojjat) - val EmptyModel = Map.empty[Sym, Boolean] - val NoModel: Model = null - - // returns all solutions, if any (TODO: better infinite recursion backstop -- detect fixpoint??) - def findAllModelsFor(f: Formula): List[Model] = { - val vars: Set[Sym] = f.flatMap(_ collect {case l: Lit => l.sym}).toSet - // debug.patmat("vars "+ vars) - // the negation of a model -(S1=True/False /\ ... /\ SN=True/False) = clause(S1=False/True, ...., SN=False/True) - def negateModel(m: Model) = clause(m.toSeq.map{ case (sym, pos) => Lit(sym, !pos) } : _*) - - def findAllModels(f: Formula, models: List[Model], recursionDepthAllowed: Int = 10): List[Model]= - if (recursionDepthAllowed == 0) models - else { - debug.patmat("find all models for\n"+ cnfString(f)) - val model = findModelFor(f) - // if we found a solution, conjunct the formula with the model's negation and recurse - if (model ne NoModel) { - val unassigned = (vars -- model.keySet).toList - debug.patmat("unassigned "+ unassigned +" in "+ model) - def force(lit: Lit) = { - val model = withLit(findModelFor(dropUnit(f, lit)), lit) - if (model ne NoModel) List(model) - else Nil - } - val forced = unassigned flatMap { s => - force(Lit(s, pos = true)) ++ force(Lit(s, pos = false)) - } - debug.patmat("forced "+ forced) - val negated = negateModel(model) - findAllModels(f :+ negated, model :: (forced ++ models), recursionDepthAllowed - 1) - } - else models - } - - findAllModels(f, Nil) - } - - private def withLit(res: Model, l: Lit): Model = if (res eq NoModel) NoModel else res + (l.sym -> l.pos) - private def dropUnit(f: Formula, unitLit: Lit): Formula = { - val negated = -unitLit - // drop entire clauses that are trivially true - // (i.e., disjunctions that contain the literal we're making true in the returned model), - // and simplify clauses by dropping the negation of the literal we're making true - // (since False \/ X == X) - val dropped = formulaBuilderSized(f.size) - for { - clause <- f - if !(clause contains unitLit) - } dropped += (clause - negated) - dropped - } - - def findModelFor(f: Formula): Model = { - @inline def orElse(a: Model, b: => Model) = if (a ne NoModel) a else b - - debug.patmat("DPLL\n"+ cnfString(f)) - - val start = if (Statistics.canEnable) Statistics.startTimer(patmatAnaDPLL) else null - - val satisfiableWithModel: Model = - if (f isEmpty) EmptyModel - else if(f exists (_.isEmpty)) NoModel - else f.find(_.size == 1) match { - case Some(unitClause) => - val unitLit = unitClause.head - // debug.patmat("unit: "+ unitLit) - withLit(findModelFor(dropUnit(f, unitLit)), unitLit) - case _ => - // partition symbols according to whether they appear in positive and/or negative literals - val pos = new mutable.HashSet[Sym]() - val neg = new mutable.HashSet[Sym]() - f.foreach{_.foreach{ lit => - if (lit.pos) pos += lit.sym else neg += lit.sym - }} - // appearing in both positive and negative - val impures = pos intersect neg - // appearing only in either positive/negative positions - val pures = (pos ++ neg) -- impures - - if (pures nonEmpty) { - val pureSym = pures.head - // turn it back into a literal - // (since equality on literals is in terms of equality - // of the underlying symbol and its positivity, simply construct a new Lit) - val pureLit = Lit(pureSym, pos(pureSym)) - // debug.patmat("pure: "+ pureLit +" pures: "+ pures +" impures: "+ impures) - val simplified = f.filterNot(_.contains(pureLit)) - withLit(findModelFor(simplified), pureLit) - } else { - val split = f.head.head - // debug.patmat("split: "+ split) - orElse(findModelFor(f :+ clause(split)), findModelFor(f :+ clause(-split))) - } - } - - if (Statistics.canEnable) Statistics.stopTimer(patmatAnaDPLL, start) - - satisfiableWithModel - } - } } -trait ScalaLogic extends Logic { self: PatternMatching => +trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis { trait TreesAndTypesDomain extends PropositionalLogic with CheckableTreeAndTypeAnalysis { type Type = global.Type type Tree = global.Tree diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala index 86eb3c9666..3ee75df6c4 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchAnalysis.scala @@ -125,23 +125,15 @@ trait TreeAndTypeAnalysis extends Debugging { } } -trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => - import PatternMatchingStats._ - import global.{Tree, Type, Symbol, CaseDef, atPos, - Select, Block, ThisType, SingleType, NoPrefix, NoType, definitions, needsOuterTest, - ConstantType, Literal, Constant, gen, This, analyzer, EmptyTree, map2, NoSymbol, Traverser, - Function, Typed, treeInfo, DefTree, ValDef, nme, appliedType, Name, WildcardType, Ident, TypeRef, - UniqueType, RefinedType, currentUnit, SingletonType, singleType, ModuleClassSymbol, - nestedMemberType, TypeMap, EmptyScope, Apply, If, Bind, lub, Alternative, deriveCaseDef, Match, MethodType, LabelDef, TypeTree, Throw, newTermName} - - import definitions._ - import analyzer.{Typer, ErrorUtils, formalTypes} +trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchTreeMaking { + import global.{Tree, Type, NoType, Symbol, NoSymbol, ConstantType, Literal, Constant, Ident, UniqueType, RefinedType, EmptyScope} + import global.definitions.{ListClass, NilModule} /** * Represent a match as a formula in propositional logic that encodes whether the match matches (abstractly: we only consider types) * */ - trait TreeMakerApproximation extends TreeMakers with PropositionalLogic with TreesAndTypesDomain with CheckableTreeAndTypeAnalysis { self: CodegenCore => + trait MatchApproximator extends TreeMakers with TreesAndTypesDomain { object Test { var currId = 0 } @@ -348,7 +340,14 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => } } - trait SymbolicMatchAnalysis extends TreeMakerApproximation { self: CodegenCore => +} + +trait MatchAnalysis extends MatchApproximation { + import PatternMatchingStats._ + import global.{Tree, Type, Symbol, NoSymbol, Ident, Select} + import global.definitions.{isPrimitiveValueClass, ConsClass, isTupleSymbol} + + trait MatchAnalyzer extends MatchApproximator { def uncheckedWarning(pos: Position, msg: String) = global.currentUnit.uncheckedWarning(pos, msg) def warn(pos: Position, ex: AnalysisBudget.Exception, kind: String) = uncheckedWarning(pos, s"Cannot check match for $kind.\n${ex.advice}") @@ -498,7 +497,7 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => // a way to construct a value that will make the match fail: a constructor invocation, a constant, an object of some type) class CounterExample { - protected[SymbolicMatchAnalysis] def flattenConsArgs: List[CounterExample] = Nil + protected[MatchAnalyzer] def flattenConsArgs: List[CounterExample] = Nil def coveredBy(other: CounterExample): Boolean = this == other || other == WildcardExample } case class ValueExample(c: ValueConst) extends CounterExample { override def toString = c.toString } @@ -513,11 +512,11 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => } } case class ListExample(ctorArgs: List[CounterExample]) extends CounterExample { - protected[SymbolicMatchAnalysis] override def flattenConsArgs: List[CounterExample] = ctorArgs match { + protected[MatchAnalyzer] override def flattenConsArgs: List[CounterExample] = ctorArgs match { case hd :: tl :: Nil => hd :: tl.flattenConsArgs case _ => Nil } - protected[SymbolicMatchAnalysis] lazy val elems = flattenConsArgs + protected[MatchAnalyzer] lazy val elems = flattenConsArgs override def coveredBy(other: CounterExample): Boolean = other match { @@ -691,5 +690,18 @@ trait MatchAnalysis extends TreeAndTypeAnalysis { self: PatternMatching => // this is the variable we want a counter example for VariableAssignment(scrutVar).toCounterExample() } + + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit = { + if (!suppression.unreachable) { + unreachableCase(prevBinder, cases, pt) foreach { caseIndex => + reportUnreachable(cases(caseIndex).last.pos) + } + } + if (!suppression.exhaustive) { + val counterExamples = exhaustive(prevBinder, cases, pt) + if (counterExamples.nonEmpty) + reportMissingCases(prevBinder.pos, counterExamples) + } + } } } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala index 273aebd71e..416bdf50f0 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala @@ -17,7 +17,7 @@ import scala.reflect.internal.util.NoPosition * We have two modes in which to emit trees: optimized (the default) * and pure (aka "virtualized": match is parametric in its monad). */ -trait MatchCodeGen { self: PatternMatching => +trait MatchCodeGen extends Interface { import PatternMatchingStats._ import global.{nme, treeInfo, definitions, gen, Tree, Type, Symbol, NoSymbol, appliedType, NoType, MethodType, newTermName, Name, diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala index c14b4ebc3b..dcf2413b15 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala @@ -19,7 +19,7 @@ import scala.reflect.internal.util.NoPosition * * TODO: split out match analysis */ -trait MatchOptimization { self: PatternMatching => +trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { import PatternMatchingStats._ import global.{Tree, Type, Symbol, NoSymbol, CaseDef, atPos, ConstantType, Literal, Constant, gen, EmptyTree, @@ -30,7 +30,7 @@ trait MatchOptimization { self: PatternMatching => //// - trait CommonSubconditionElimination extends TreeMakerApproximation { self: OptimizedCodegen => + trait CommonSubconditionElimination extends OptimizedCodegen with MatchApproximator { /** a flow-sensitive, generalised, common sub-expression elimination * reuse knowledge from performed tests * the only sub-expressions we consider are the conditions and results of the three tests (type, type&equality, equality) @@ -205,19 +205,19 @@ trait MatchOptimization { self: PatternMatching => //// DCE - trait DeadCodeElimination extends TreeMakers { self: CodegenCore => - // TODO: non-trivial dead-code elimination - // e.g., the following match should compile to a simple instanceof: - // case class Ident(name: String) - // for (Ident(name) <- ts) println(name) - def doDCE(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): List[List[TreeMaker]] = { - // do minimal DCE - cases - } - } +// trait DeadCodeElimination extends TreeMakers { +// // TODO: non-trivial dead-code elimination +// // e.g., the following match should compile to a simple instanceof: +// // case class Ident(name: String) +// // for (Ident(name) <- ts) println(name) +// def doDCE(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): List[List[TreeMaker]] = { +// // do minimal DCE +// cases +// } +// } //// SWITCHES -- TODO: operate on Tests rather than TreeMakers - trait SwitchEmission extends TreeMakers with OptimizedMatchMonadInterface { self: CodegenCore => + trait SwitchEmission extends TreeMakers with OptimizedMatchMonadInterface { import treeInfo.isGuardedCase abstract class SwitchMaker { @@ -589,26 +589,12 @@ trait MatchOptimization { self: PatternMatching => } } - - - - trait MatchOptimizations extends CommonSubconditionElimination - with DeadCodeElimination - with SwitchEmission - with OptimizedCodegen - with SymbolicMatchAnalysis - with DPLLSolver { self: TreeMakers => - override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) = { - unreachableCase(prevBinder, cases, pt) foreach { caseIndex => - reportUnreachable(cases(caseIndex).last.pos) - } - if (!unchecked) { - val counterExamples = exhaustive(prevBinder, cases, pt) - if (counterExamples.nonEmpty) - reportMissingCases(prevBinder.pos, counterExamples) - } - - val optCases = doCSE(prevBinder, doDCE(prevBinder, cases, pt), pt) + trait MatchOptimizer extends OptimizedCodegen + with SwitchEmission + with CommonSubconditionElimination { + override def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): (List[List[TreeMaker]], List[Tree]) = { + // TODO: do CSE on result of doDCE(prevBinder, cases, pt) + val optCases = doCSE(prevBinder, cases, pt) val toHoist = ( for (treeMakers <- optCases) yield treeMakers.collect{case tm: ReusedCondTreeMaker => tm.treesToHoist} diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala index 3ee9009116..23b33e9be6 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala @@ -24,7 +24,7 @@ trait MatchTranslation { self: PatternMatching => repeatedToSeq, isRepeatedParamType, getProductArgs} import global.analyzer.{ErrorUtils, formalTypes} - trait MatchTranslator extends MatchMonadInterface { self: TreeMakers with CodegenCore => + trait MatchTranslator extends TreeMakers { import typer.context // Why is it so difficult to say "here's a name and a context, give me any diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index c9285f9229..202f3444f8 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -18,21 +18,26 @@ import scala.reflect.internal.util.NoPosition * The IR is mostly concerned with sequencing, substitution, and rendering all necessary conditions, * mostly agnostic to whether we're in optimized/pure (virtualized) mode. */ -trait MatchTreeMaking { self: PatternMatching => +trait MatchTreeMaking extends MatchCodeGen with Debugging { import PatternMatchingStats._ import global.{Tree, Type, Symbol, CaseDef, atPos, settings, Select, Block, ThisType, SingleType, NoPrefix, NoType, needsOuterTest, ConstantType, Literal, Constant, gen, This, EmptyTree, map2, NoSymbol, Traverser, - Function, Typed, treeInfo, TypeRef, DefTree} + Function, Typed, treeInfo, TypeRef, DefTree, Ident, nme} import global.definitions.{SomeClass, AnyRefClass, UncheckedClass, BooleanClass} + final case class Suppression(exhaustive: Boolean, unreachable: Boolean) + object Suppression { + val NoSuppression = Suppression(false, false) + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // the making of the trees /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - trait TreeMakers extends TypedSubstitution { self: CodegenCore => - def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, unchecked: Boolean): (List[List[TreeMaker]], List[Tree]) = - (cases, Nil) + trait TreeMakers extends TypedSubstitution with CodegenCore { + def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type): (List[List[TreeMaker]], List[Tree]) + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type, matchFailGenOverride: Option[Tree => Tree], unchecked: Boolean): Option[Tree] = None @@ -522,18 +527,24 @@ trait MatchTreeMaking { self: PatternMatching => def matchFailGen = (matchFailGenOverride orElse Some(CODE.MATCHERROR(_: Tree))) debug.patmat("combining cases: "+ (casesNoSubstOnly.map(_.mkString(" >> ")).mkString("{", "\n", "}"))) - val (unchecked, requireSwitch) = - if (settings.XnoPatmatAnalysis.value) (true, false) + val (suppression, requireSwitch): (Suppression, Boolean) = + if (settings.XnoPatmatAnalysis.value) (Suppression.NoSuppression, false) else scrut match { - case Typed(_, tpt) => - (tpt.tpe hasAnnotation UncheckedClass, - // matches with two or fewer cases need not apply for switchiness (if-then-else will do) - treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0) + case Typed(tree, tpt) => + val suppressExhaustive = tpt.tpe hasAnnotation UncheckedClass + val supressUnreachable = tree match { + case Ident(name) if name startsWith nme.CHECK_IF_REFUTABLE_STRING => true // SI-7183 don't warn for withFilter's that turn out to be irrefutable. + case _ => false + } + val suppression = Suppression(suppressExhaustive, supressUnreachable) + // matches with two or fewer cases need not apply for switchiness (if-then-else will do) + val requireSwitch = treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0 + (suppression, requireSwitch) case _ => - (false, false) + (Suppression.NoSuppression, false) } - emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, unchecked).getOrElse{ + emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride, suppression.exhaustive).getOrElse{ if (requireSwitch) typer.context.unit.warning(scrut.pos, "could not emit switch for @switch annotated match") if (casesNoSubstOnly nonEmpty) { @@ -550,7 +561,9 @@ trait MatchTreeMaking { self: PatternMatching => }) None else matchFailGen - val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt, unchecked) + analyzeCases(scrutSym, casesNoSubstOnly, pt, suppression) + + val (cases, toHoist) = optimizeCases(scrutSym, casesNoSubstOnly, pt) val matchRes = codegen.matcher(scrut, scrutSym, pt)(cases map combineExtractors, synthCatchAll) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala index 38d148c915..8be8b72130 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/PatternMatching.scala @@ -34,13 +34,14 @@ import scala.reflect.internal.util.Position * - recover GADT typing by locally inserting implicit witnesses to type equalities derived from the current case, and considering these witnesses during subtyping (?) * - recover exhaustivity/unreachability of user-defined extractors by partitioning the types they match on using an HList or similar type-level structure */ -trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL +trait PatternMatching extends Transform with TypingTransformers with Debugging with Interface with MatchTranslation with MatchTreeMaking with MatchCodeGen with ScalaLogic + with Solving with MatchAnalysis with MatchOptimization { import global._ @@ -76,15 +77,20 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } } - class PureMatchTranslator(val typer: analyzer.Typer, val matchStrategy: Tree) extends MatchTranslator with TreeMakers with PureCodegen - class OptimizingMatchTranslator(val typer: analyzer.Typer) extends MatchTranslator with TreeMakers with MatchOptimizations + class PureMatchTranslator(val typer: analyzer.Typer, val matchStrategy: Tree) extends MatchTranslator with PureCodegen { + def optimizeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type) = (cases, Nil) + def analyzeCases(prevBinder: Symbol, cases: List[List[TreeMaker]], pt: Type, suppression: Suppression): Unit = {} + } + + class OptimizingMatchTranslator(val typer: analyzer.Typer) extends MatchTranslator + with MatchOptimizer + with MatchAnalyzer + with Solver } -trait HasGlobal { +trait Debugging { val global: Global -} -trait Debugging extends HasGlobal { // TODO: the inliner fails to inline the closures to debug.patmat unless the method is nested in an object object debug { val printPatmat = global.settings.Ypatmatdebug.value @@ -92,7 +98,7 @@ trait Debugging extends HasGlobal { } } -trait Interface { self: ast.TreeDSL with HasGlobal => +trait Interface extends ast.TreeDSL { import global.{newTermName, analyzer, Type, ErrorType, Symbol, Tree} import analyzer.Typer diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala new file mode 100644 index 0000000000..34cdbeba8e --- /dev/null +++ b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala @@ -0,0 +1,242 @@ +/* NSC -- new Scala compiler + * + * Copyright 2011-2013 LAMP/EPFL + * @author Adriaan Moors + */ + +package scala.tools.nsc.transform.patmat + +import scala.collection.mutable +import scala.reflect.internal.util.Statistics + +// naive CNF translation and simple DPLL solver +trait Solving extends Logic { + import PatternMatchingStats._ + trait CNF extends PropositionalLogic { + + /** Override Array creation for efficiency (to not go through reflection). */ + private implicit val clauseTag: scala.reflect.ClassTag[Clause] = new scala.reflect.ClassTag[Clause] { + def runtimeClass: java.lang.Class[Clause] = classOf[Clause] + final override def newArray(len: Int): Array[Clause] = new Array[Clause](len) + } + + import scala.collection.mutable.ArrayBuffer + type FormulaBuilder = ArrayBuffer[Clause] + def formulaBuilder = ArrayBuffer[Clause]() + def formulaBuilderSized(init: Int) = new ArrayBuffer[Clause](init) + def addFormula(buff: FormulaBuilder, f: Formula): Unit = buff ++= f + def toFormula(buff: FormulaBuilder): Formula = buff + + // CNF: a formula is a conjunction of clauses + type Formula = FormulaBuilder + def formula(c: Clause*): Formula = ArrayBuffer(c: _*) + + type Clause = Set[Lit] + // a clause is a disjunction of distinct literals + def clause(l: Lit*): Clause = l.toSet + + type Lit + def Lit(sym: Sym, pos: Boolean = true): Lit + + def andFormula(a: Formula, b: Formula): Formula = a ++ b + def simplifyFormula(a: Formula): Formula = a.distinct + + private def merge(a: Clause, b: Clause) = a ++ b + + // throws an AnalysisBudget.Exception when the prop results in a CNF that's too big + // TODO: be smarter/more efficient about this (http://lara.epfl.ch/w/sav09:tseitin_s_encoding) + def eqFreePropToSolvable(p: Prop): Formula = { + def negationNormalFormNot(p: Prop, budget: Int): Prop = + if (budget <= 0) throw AnalysisBudget.exceeded + else p match { + case And(a, b) => Or(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1)) + case Or(a, b) => And(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1)) + case Not(p) => negationNormalForm(p, budget - 1) + case True => False + case False => True + case s: Sym => Not(s) + } + + def negationNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Prop = + if (budget <= 0) throw AnalysisBudget.exceeded + else p match { + case And(a, b) => And(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1)) + case Or(a, b) => Or(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1)) + case Not(negated) => negationNormalFormNot(negated, budget - 1) + case True + | False + | (_ : Sym) => p + } + + val TrueF = formula() + val FalseF = formula(clause()) + def lit(s: Sym) = formula(clause(Lit(s))) + def negLit(s: Sym) = formula(clause(Lit(s, pos = false))) + + def conjunctiveNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Formula = { + def distribute(a: Formula, b: Formula, budget: Int): Formula = + if (budget <= 0) throw AnalysisBudget.exceeded + else + (a, b) match { + // true \/ _ = true + // _ \/ true = true + case (trueA, trueB) if trueA.size == 0 || trueB.size == 0 => TrueF + // lit \/ lit + case (a, b) if a.size == 1 && b.size == 1 => formula(merge(a(0), b(0))) + // (c1 /\ ... /\ cn) \/ d = ((c1 \/ d) /\ ... /\ (cn \/ d)) + // d \/ (c1 /\ ... /\ cn) = ((d \/ c1) /\ ... /\ (d \/ cn)) + case (cs, ds) => + val (big, small) = if (cs.size > ds.size) (cs, ds) else (ds, cs) + big flatMap (c => distribute(formula(c), small, budget - (big.size*small.size))) + } + + if (budget <= 0) throw AnalysisBudget.exceeded + + p match { + case True => TrueF + case False => FalseF + case s: Sym => lit(s) + case Not(s: Sym) => negLit(s) + case And(a, b) => + val cnfA = conjunctiveNormalForm(a, budget - 1) + val cnfB = conjunctiveNormalForm(b, budget - cnfA.size) + cnfA ++ cnfB + case Or(a, b) => + val cnfA = conjunctiveNormalForm(a) + val cnfB = conjunctiveNormalForm(b) + distribute(cnfA, cnfB, budget - (cnfA.size + cnfB.size)) + } + } + + val start = if (Statistics.canEnable) Statistics.startTimer(patmatCNF) else null + val res = conjunctiveNormalForm(negationNormalForm(p)) + + if (Statistics.canEnable) Statistics.stopTimer(patmatCNF, start) + + // + if (Statistics.canEnable) patmatCNFSizes(res.size).value += 1 + +// debug.patmat("cnf for\n"+ p +"\nis:\n"+cnfString(res)) + res + } + } + + // simple solver using DPLL + trait Solver extends CNF { + // a literal is a (possibly negated) variable + def Lit(sym: Sym, pos: Boolean = true) = new Lit(sym, pos) + class Lit(val sym: Sym, val pos: Boolean) { + override def toString = if (!pos) "-"+ sym.toString else sym.toString + override def equals(o: Any) = o match { + case o: Lit => (o.sym eq sym) && (o.pos == pos) + case _ => false + } + override def hashCode = sym.hashCode + pos.hashCode + + def unary_- = Lit(sym, !pos) + } + + def cnfString(f: Formula) = alignAcrossRows(f map (_.toList) toList, "\\/", " /\\\n") + + // adapted from http://lara.epfl.ch/w/sav10:simple_sat_solver (original by Hossein Hojjat) + val EmptyModel = Map.empty[Sym, Boolean] + val NoModel: Model = null + + // returns all solutions, if any (TODO: better infinite recursion backstop -- detect fixpoint??) + def findAllModelsFor(f: Formula): List[Model] = { + val vars: Set[Sym] = f.flatMap(_ collect {case l: Lit => l.sym}).toSet + // debug.patmat("vars "+ vars) + // the negation of a model -(S1=True/False /\ ... /\ SN=True/False) = clause(S1=False/True, ...., SN=False/True) + def negateModel(m: Model) = clause(m.toSeq.map{ case (sym, pos) => Lit(sym, !pos) } : _*) + + def findAllModels(f: Formula, models: List[Model], recursionDepthAllowed: Int = 10): List[Model]= + if (recursionDepthAllowed == 0) models + else { + debug.patmat("find all models for\n"+ cnfString(f)) + val model = findModelFor(f) + // if we found a solution, conjunct the formula with the model's negation and recurse + if (model ne NoModel) { + val unassigned = (vars -- model.keySet).toList + debug.patmat("unassigned "+ unassigned +" in "+ model) + def force(lit: Lit) = { + val model = withLit(findModelFor(dropUnit(f, lit)), lit) + if (model ne NoModel) List(model) + else Nil + } + val forced = unassigned flatMap { s => + force(Lit(s, pos = true)) ++ force(Lit(s, pos = false)) + } + debug.patmat("forced "+ forced) + val negated = negateModel(model) + findAllModels(f :+ negated, model :: (forced ++ models), recursionDepthAllowed - 1) + } + else models + } + + findAllModels(f, Nil) + } + + private def withLit(res: Model, l: Lit): Model = if (res eq NoModel) NoModel else res + (l.sym -> l.pos) + private def dropUnit(f: Formula, unitLit: Lit): Formula = { + val negated = -unitLit + // drop entire clauses that are trivially true + // (i.e., disjunctions that contain the literal we're making true in the returned model), + // and simplify clauses by dropping the negation of the literal we're making true + // (since False \/ X == X) + val dropped = formulaBuilderSized(f.size) + for { + clause <- f + if !(clause contains unitLit) + } dropped += (clause - negated) + dropped + } + + def findModelFor(f: Formula): Model = { + @inline def orElse(a: Model, b: => Model) = if (a ne NoModel) a else b + + debug.patmat("DPLL\n"+ cnfString(f)) + + val start = if (Statistics.canEnable) Statistics.startTimer(patmatAnaDPLL) else null + + val satisfiableWithModel: Model = + if (f isEmpty) EmptyModel + else if(f exists (_.isEmpty)) NoModel + else f.find(_.size == 1) match { + case Some(unitClause) => + val unitLit = unitClause.head + // debug.patmat("unit: "+ unitLit) + withLit(findModelFor(dropUnit(f, unitLit)), unitLit) + case _ => + // partition symbols according to whether they appear in positive and/or negative literals + val pos = new mutable.HashSet[Sym]() + val neg = new mutable.HashSet[Sym]() + f.foreach{_.foreach{ lit => + if (lit.pos) pos += lit.sym else neg += lit.sym + }} + // appearing in both positive and negative + val impures = pos intersect neg + // appearing only in either positive/negative positions + val pures = (pos ++ neg) -- impures + + if (pures nonEmpty) { + val pureSym = pures.head + // turn it back into a literal + // (since equality on literals is in terms of equality + // of the underlying symbol and its positivity, simply construct a new Lit) + val pureLit = Lit(pureSym, pos(pureSym)) + // debug.patmat("pure: "+ pureLit +" pures: "+ pures +" impures: "+ impures) + val simplified = f.filterNot(_.contains(pureLit)) + withLit(findModelFor(simplified), pureLit) + } else { + val split = f.head.head + // debug.patmat("split: "+ split) + orElse(findModelFor(f :+ clause(split)), findModelFor(f :+ clause(-split))) + } + } + + if (Statistics.canEnable) Statistics.stopTimer(patmatAnaDPLL, start) + + satisfiableWithModel + } + } +} diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 580f024b40..0af75a2aad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -683,7 +683,7 @@ trait ContextErrors { // same reason as for MacroBodyTypecheckException case object MacroExpansionException extends Exception with scala.util.control.ControlThrowable - private def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = { + protected def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = { def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg macroLogLite("macro expansion has failed: %s".format(msgForLog)) if (msg != null) context.error(pos, msg) // issueTypeError(PosAndMsgTypeError(..)) won't work => swallows positions @@ -772,15 +772,15 @@ trait ContextErrors { )) } - def MacroImplementationNotFoundError(expandee: Tree) = { - val message = - "macro implementation not found: " + expandee.symbol.name + " " + - "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)" + - (if (forScaladoc) ". When generating scaladocs for multiple projects at once, consider using -Ymacro-no-expand to disable macro expansions altogether." - else "") - macroExpansionError(expandee, message) - } + def MacroImplementationNotFoundError(expandee: Tree) = + macroExpansionError(expandee, macroImplementationNotFoundMessage(expandee.symbol.name)) } + + /** This file will be the death of me. */ + protected def macroImplementationNotFoundMessage(name: Name): String = ( + s"""|macro implementation not found: $name + |(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)""".stripMargin + ) } trait InferencerContextErrors { diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index d4f402b747..9f16f65a6a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1694,7 +1694,7 @@ trait Infer extends Checkable { } else if (sym.isOverloaded) { val xs = sym.alternatives - val tparams = new AsSeenFromMap(pre, xs.head.owner) mapOver xs.head.typeParams + val tparams = newAsSeenFromMap(pre, xs.head.owner) mapOver xs.head.typeParams val bounds = tparams map (_.tpeHK) // see e.g., #1236 val tpe = PolyType(tparams, OverloadedType(AntiPolyType(pre, bounds), xs)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index a1bf3a56c3..007c7c6a83 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -47,10 +47,11 @@ trait Namers extends MethodSynthesis { private class NormalNamer(context: Context) extends Namer(context) def newNamer(context: Context): Namer = new NormalNamer(context) - def newNamerFor(context: Context, tree: Tree): Namer = - newNamer(context.makeNewScope(tree, tree.symbol)) + def newNamerFor(context: Context, tree: Tree): Namer = newNamer(context.makeNewScope(tree, tree.symbol)) abstract class Namer(val context: Context) extends MethodSynth with NamerContextErrors { thisNamer => + // overridden by the presentation compiler + def saveDefaultGetter(meth: Symbol, default: Symbol) { } import NamerErrorGen._ val typer = newTyper(context) @@ -594,17 +595,6 @@ trait Namers extends MethodSynthesis { } } - def enterIfNotThere(sym: Symbol) { - val scope = context.scope - @tailrec def search(e: ScopeEntry) { - if ((e eq null) || (e.owner ne scope)) - scope enter sym - else if (e.sym ne sym) // otherwise, aborts since we found sym - search(e.tail) - } - search(scope lookupEntry sym.name) - } - def enterValDef(tree: ValDef) { if (noEnterGetterSetter(tree)) assignAndEnterFinishedSymbol(tree) @@ -697,22 +687,9 @@ trait Namers extends MethodSynthesis { validateCompanionDefs(tree) } - // this logic is needed in case typer was interrupted half - // way through and then comes back to do the tree again. In - // that case the definitions that were already attributed as - // well as any default parameters of such methods need to be - // re-entered in the current scope. - protected def enterExistingSym(sym: Symbol): Context = { - if (forInteractive && sym != null && sym.owner.isTerm) { - enterIfNotThere(sym) - if (sym.isLazy) - sym.lazyAccessor andAlso enterIfNotThere - - for (defAtt <- sym.attachments.get[DefaultsOfLocalMethodAttachment]) - defAtt.defaultGetters foreach enterIfNotThere - } - this.context - } + // Hooks which are overridden in the presentation compiler + def enterExistingSym(sym: Symbol): Context = this.context + def enterIfNotThere(sym: Symbol) { } def enterSyntheticSym(tree: Tree): Symbol = { enterSym(tree) @@ -1297,17 +1274,10 @@ trait Namers extends MethodSynthesis { if (!isConstr) methOwner.resetFlag(INTERFACE) // there's a concrete member now val default = parentNamer.enterSyntheticSym(defaultTree) - if (forInteractive && default.owner.isTerm) { - // save the default getters as attachments in the method symbol. if compiling the - // same local block several times (which can happen in interactive mode) we might - // otherwise not find the default symbol, because the second time it the method - // symbol will be re-entered in the scope but the default parameter will not. - meth.attachments.get[DefaultsOfLocalMethodAttachment] match { - case Some(att) => att.defaultGetters += default - case None => meth.updateAttachment(new DefaultsOfLocalMethodAttachment(default)) - } - } - } else if (baseHasDefault) { + if (default.owner.isTerm) + saveDefaultGetter(meth, default) + } + else if (baseHasDefault) { // the parameter does not have a default itself, but the // corresponding parameter in the base class does. sym.setFlag(DEFAULTPARAM) diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 1d28add6e0..e8925ce2d0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -186,18 +186,6 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT log("Expanded '%s' to '%s' in %s".format(savedName, s.name, sym)) } } - if (settings.verbose.value && forScaladoc && !sym.isAnonymousClass) { - println("========== scaladoc of "+sym+" =============================") - println(toJavaDoc(expandedDocComment(sym))) - for (member <- sym.info.members) { - println(member+":"+sym.thisType.memberInfo(member)+"\n"+ - toJavaDoc(expandedDocComment(member, sym))) - for ((useCase, comment, pos) <- useCases(member, sym)) { - println("usecase "+useCase+":"+useCase.info) - println(toJavaDoc(comment)) - } - } - } super.transform(tree) } transformClassDef diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1781dc1932..eaf57cd39c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -86,8 +86,6 @@ trait Typers extends Adaptations with Tags { // that are turned private by typedBlock private final val SYNTHETIC_PRIVATE = TRANS_FLAG - private def isPastTyper = phase.id > currentRun.typerPhase.id - // To enable decent error messages when the typer crashes. // TODO - this only catches trees which go through def typed, // but there are all kinds of back ways - typedClassDef, etc. etc. @@ -98,13 +96,18 @@ trait Typers extends Adaptations with Tags { // - we may virtualize matches (if -Xexperimental and there's a suitable __match in scope) // - we synthesize PartialFunction implementations for `x => x match {...}` and `match {...}` when the expected type is PartialFunction // this is disabled by: interactive compilation (we run it for scaladoc due to SI-5933) - private def newPatternMatching = !forInteractive //&& !forScaladoc && (phase.id < currentRun.uncurryPhase.id) + protected def newPatternMatching = true // presently overridden in the presentation compiler abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tag with TyperContextErrors { import context0.unit import typeDebug.{ ptTree, ptBlock, ptLine } import TyperErrorGen._ + /** Overridden to false in scaladoc and/or interactive. */ + def canAdaptConstantTypeToLiteral = true + def canTranslateEmptyListToNil = true + def missingSelectErrorTree(tree: Tree, qual: Tree, name: Name): Tree = tree + def typedDocDef(docDef: DocDef, mode: Mode, pt: Type): Tree = typed(docDef.definition, mode, pt) @@ -229,8 +232,13 @@ trait Typers extends Adaptations with Tags { new SubstWildcardMap(tparams).apply(tp) case TypeRef(_, sym, _) if sym.isAliasType => val tp0 = tp.dealias - val tp1 = dropExistential(tp0) - if (tp1 eq tp0) tp else tp1 + if (tp eq tp0) { + debugwarn(s"dropExistential did not progress dealiasing $tp, see SI-7126") + tp + } else { + val tp1 = dropExistential(tp0) + if (tp1 eq tp0) tp else tp1 + } case _ => tp } @@ -1017,7 +1025,7 @@ trait Typers extends Adaptations with Tags { val pre = if (owner.isPackageClass) owner.thisType else if (owner.isClass) context.enclosingSubClassContext(owner).prefix - else NoPrefix + else NoPrefix stabilize0(pre) case Select(qualqual, _) => stabilize0(qualqual.tpe) @@ -1033,7 +1041,7 @@ trait Typers extends Adaptations with Tags { tree.tpe match { case atp @ AnnotatedType(_, _, _) if canAdaptAnnotations(tree, this, mode, pt) => // (-1) adaptAnnotations(tree, this, mode, pt) - case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && !forScaladoc && !forInteractive => // (0) + case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && canAdaptConstantTypeToLiteral => // (0) val sym = tree.symbol if (sym != null && sym.isDeprecated) { val msg = sym.toString + sym.locationString + " is deprecated: " + sym.deprecationMessage.getOrElse("") @@ -1572,19 +1580,19 @@ trait Typers extends Adaptations with Tags { * from one of the parent types. Read more about why the argss are unknown in `tools.nsc.ast.Trees.Template`. */ private def typedPrimaryConstrBody(templ: Template)(actualSuperCall: => Tree): Tree = - treeInfo.firstConstructor(templ.body) match { + treeInfo.firstConstructor(templ.body) match { case ctor @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) => - val (preSuperStats, superCall) = { - val (stats, rest) = cstats span (x => !treeInfo.isSuperConstrCall(x)) - (stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate) - } + val (preSuperStats, superCall) = { + val (stats, rest) = cstats span (x => !treeInfo.isSuperConstrCall(x)) + (stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate) + } val superCall1 = (superCall match { case global.pendingSuperCall => actualSuperCall case EmptyTree => EmptyTree }) orElse cunit val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall1) val clazz = context.owner - assert(clazz != NoSymbol, templ) + assert(clazz != NoSymbol, templ) val cscope = context.outer.makeNewScope(ctor, context.outer.owner) val cbody2 = { // called both during completion AND typing. val typer1 = newTyper(cscope) @@ -1592,12 +1600,12 @@ trait Typers extends Adaptations with Tags { clazz.unsafeTypeParams foreach (sym => typer1.context.scope.enter(sym)) typer1.namer.enterValueParams(vparamss map (_.map(_.duplicate))) typer1.typed(cbody1) - } + } - val preSuperVals = treeInfo.preSuperFields(templ.body) - if (preSuperVals.isEmpty && preSuperStats.nonEmpty) + val preSuperVals = treeInfo.preSuperFields(templ.body) + if (preSuperVals.isEmpty && preSuperStats.nonEmpty) devWarning("Wanted to zip empty presuper val list with " + preSuperStats) - else + else map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt setType ldef.symbol.tpe) if (superCall1 == cunit) EmptyTree @@ -1605,13 +1613,13 @@ trait Typers extends Adaptations with Tags { case Block(_, expr) => expr case tree => tree } - case _ => + case _ => EmptyTree - } + } /** Makes sure that the first type tree in the list of parent types is always a class. * If the first parent is a trait, prepend its supertype to the list until it's a class. - */ +*/ private def normalizeFirstParent(parents: List[Tree]): List[Tree] = parents match { case first :: rest if treeInfo.isTraitRef(first) => def explode(supertpt: Tree, acc: List[Tree]): List[Tree] = { @@ -1638,14 +1646,14 @@ trait Typers extends Adaptations with Tags { * So we strip the duplicates before typer. */ private def fixDuplicateSyntheticParents(parents: List[Tree]): List[Tree] = parents match { - case Nil => Nil - case x :: xs => - val sym = x.symbol + case Nil => Nil + case x :: xs => + val sym = x.symbol x :: fixDuplicateSyntheticParents( - if (isPossibleSyntheticParent(sym)) xs filterNot (_.symbol == sym) - else xs - ) - } + if (isPossibleSyntheticParent(sym)) xs filterNot (_.symbol == sym) + else xs + ) + } def typedParentTypes(templ: Template): List[Tree] = templ.parents match { case Nil => List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe))) @@ -1666,16 +1674,16 @@ trait Typers extends Adaptations with Tags { supertpts mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt)) } catch { - case ex: TypeError => - // fallback in case of cyclic errors - // @H none of the tests enter here but I couldn't rule it out + case ex: TypeError => + // fallback in case of cyclic errors + // @H none of the tests enter here but I couldn't rule it out // upd. @E when a definition inherits itself, we end up here // because `typedParentType` triggers `initialize` for parent types symbols - log("Type error calculating parents in template " + templ) - log("Error: " + ex) - ParentTypesError(templ, ex) - List(TypeTree(AnyRefClass.tpe)) - } + log("Type error calculating parents in template " + templ) + log("Error: " + ex) + ParentTypesError(templ, ex) + List(TypeTree(AnyRefClass.tpe)) + } } /** <p>Check that</p> @@ -1921,7 +1929,7 @@ trait Typers extends Adaptations with Tags { assert(clazz.info.decls != EmptyScope, clazz) enterSyms(context.outer.make(templ, clazz, clazz.info.decls), templ.body) if (!templ.isErrorTyped) // if `parentTypes` has invalidated the template, don't validate it anymore - validateParentClasses(parents1, selfType) + validateParentClasses(parents1, selfType) if (clazz.isCase) validateNoCaseAncestor(clazz) if (clazz.isTrait && hasSuperArgs(parents1.head)) @@ -1934,9 +1942,9 @@ trait Typers extends Adaptations with Tags { checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType]) val body = { - val body = - if (isPastTyper || reporter.hasErrors) templ.body - else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _)) + val body = + if (isPastTyper || reporter.hasErrors) templ.body + else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _)) val primaryCtor = treeInfo.firstConstructor(body) val primaryCtor1 = primaryCtor match { case DefDef(_, _, _, _, _, Block(earlyVals :+ global.pendingSuperCall, unit)) => @@ -1999,7 +2007,7 @@ trait Typers extends Adaptations with Tags { checkNonCyclic(vdef, tpt1) if (sym.hasAnnotation(definitions.VolatileAttr) && !sym.isMutable) - VolatileValueError(vdef) + VolatileValueError(vdef) val rhs1 = if (vdef.rhs.isEmpty) { @@ -2161,7 +2169,7 @@ trait Typers extends Adaptations with Tags { foreachWithIndex(paramssTypes(meth.tpe)) { (paramList, listIdx) => foreachWithIndex(paramList) { (paramType, paramIdx) => - val sym = paramType.typeSymbol + val sym = paramType.typeSymbol def paramPos = nthParamPos(listIdx, paramIdx) /** Not enough to look for abstract types; have to recursively check the bounds @@ -2176,17 +2184,17 @@ trait Typers extends Adaptations with Tags { || (!sym.hasTransOwner(meth) && failStruct(paramPos, "a type member of that refinement", what)) || checkAbstract(sym.info.bounds.hi, "Type bound") ) - } + } tp0.dealiasWidenChain forall (t => check(t.typeSymbol)) } checkAbstract(paramType, "Parameter type") - if (sym.isDerivedValueClass) - failStruct(paramPos, "a user-defined value class") - if (paramType.isInstanceOf[ThisType] && sym == meth.owner) - failStruct(paramPos, "the type of that refinement (self type)") + if (sym.isDerivedValueClass) + failStruct(paramPos, "a user-defined value class") + if (paramType.isInstanceOf[ThisType] && sym == meth.owner) + failStruct(paramPos, "the type of that refinement (self type)") + } } - } if (resultType.typeSymbol.isDerivedValueClass) failStruct(ddef.tpt.pos, "a user-defined value class", where = "Result type") } @@ -2428,11 +2436,9 @@ trait Typers extends Adaptations with Tags { if (pat1.tpe.paramSectionCount > 0) pat1 setType pat1.tpe.finalResultType - if (forInteractive) { - for (bind @ Bind(name, _) <- cdef.pat) - if (name.toTermName != nme.WILDCARD && bind.symbol != null && bind.symbol != NoSymbol) - namer.enterIfNotThere(bind.symbol) - } + for (bind @ Bind(name, _) <- cdef.pat) + if (name.toTermName != nme.WILDCARD && bind.symbol != null && bind.symbol != NoSymbol) + namer.enterIfNotThere(bind.symbol) val guard1: Tree = if (cdef.guard == EmptyTree) EmptyTree else typed(cdef.guard, BooleanClass.tpe) @@ -3257,7 +3263,7 @@ trait Typers extends Adaptations with Tags { * forced during kind-arity checking, so it is guarded by additional * tests to ensure we're sufficiently far along. */ - if (args.isEmpty && !forInteractive && fun.symbol.isInitialized && ListModule.hasCompleteInfo && (fun.symbol == List_apply)) + if (args.isEmpty && canTranslateEmptyListToNil && fun.symbol.isInitialized && ListModule.hasCompleteInfo && (fun.symbol == List_apply)) atPos(tree.pos)(gen.mkNil setType restpe) else constfold(treeCopy.Apply(tree, fun, args1) setType ifPatternSkipFormals(restpe)) @@ -3442,7 +3448,7 @@ trait Typers extends Adaptations with Tags { else None case _ => None - } + } } /** @@ -3630,7 +3636,7 @@ trait Typers extends Adaptations with Tags { val Function(arg :: Nil, rhs) = typed(func, mode, funcType) rhs.substituteSymbols(arg.symbol :: Nil, selfsym :: Nil) - } + } def annInfo(t: Tree): AnnotationInfo = t match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => @@ -3658,7 +3664,7 @@ trait Typers extends Adaptations with Tags { if ((typedAnn.tpe == null) || typedAnn.tpe.isErroneous) ErroneousAnnotation else annInfo(typedAnn) }) - } + } def isRawParameter(sym: Symbol) = // is it a type parameter leaked by a raw type? sym.isTypeParameter && sym.owner.isJavaDefined @@ -4683,11 +4689,7 @@ trait Typers extends Adaptations with Tags { if (!reallyExists(sym)) { def handleMissing: Tree = { - def errorTree = tree match { - case _ if !forInteractive => tree - case Select(_, _) => treeCopy.Select(tree, qual, name) - case SelectFromTypeTree(_, _) => treeCopy.SelectFromTypeTree(tree, qual, name) - } + def errorTree = missingSelectErrorTree(tree, qual, name) def asTypeSelection = ( if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) { atPos(tree.pos)(gen.convertToSelectFromType(qual, name)) match { @@ -5008,8 +5010,8 @@ trait Typers extends Adaptations with Tags { def unbound(t: Tree) = t.symbol == null || t.symbol == NoSymbol cdef.pat match { case Bind(name, i @ Ident(_)) if unbound(i) => warn(name) - case i @ Ident(name) if unbound(i) => warn(name) - case _ => + case i @ Ident(name) if unbound(i) => warn(name) + case _ => } } @@ -5250,7 +5252,6 @@ trait Typers extends Adaptations with Tags { case tree: ApplyDynamic => typedApplyDynamic(tree) case tree: ReferenceToBoxed => typedReferenceToBoxed(tree) case tree: TypeTreeWithDeferredRefCheck => tree // TODO: retype the wrapped tree? TTWDRC would have to change to hold the wrapped tree (not a closure) - case tree: Import => assert(forInteractive, "!forInteractive") ; tree setType tree.symbol.tpe // should not happen in normal circumstances. case _ => abort(s"unexpected tree: ${tree.getClass}\n$tree") } } diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index df9d907377..3bde280681 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -283,7 +283,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => val file = new BatchSourceFile("<toolbox>", wrappedCode) val unit = new CompilationUnit(file) phase = run.parserPhase - val parser = new syntaxAnalyzer.UnitParser(unit) + val parser = newUnitParser(unit) val wrappedTree = parser.parse() throwIfErrors() val PackageDef(_, List(ModuleDef(_, _, Template(_, _, _ :: parsed)))) = wrappedTree diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala index a81604235b..f84fa161c0 100644 --- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala +++ b/src/interactive/scala/tools/nsc/interactive/CompilerControl.scala @@ -161,17 +161,22 @@ trait CompilerControl { self: Global => /** Sets sync var `response` to doc comment information for a given symbol. * - * @param sym The symbol whose doc comment should be retrieved (might come from a classfile) - * @param site The place where sym is observed. - * @param source The source file that's supposed to contain the definition - * @param response A response that will be set to the following: - * If `source` contains a definition of a given symbol that has a doc comment, - * the (expanded, raw, position) triplet for a comment, otherwise ("", "", NoPosition). - * Note: This operation does not automatically load `source`. If `source` - * is unloaded, it stays that way. + * @param sym The symbol whose doc comment should be retrieved (might come from a classfile) + * @param source The source file that's supposed to contain the definition + * @param site The symbol where 'sym' is observed + * @param fragments All symbols that can contribute to the generated documentation + * together with their source files. + * @param response A response that will be set to the following: + * If `source` contains a definition of a given symbol that has a doc comment, + * the (expanded, raw, position) triplet for a comment, otherwise ("", "", NoPosition). + * Note: This operation does not automatically load sources that are not yet loaded. */ - def askDocComment(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]) = - postWorkItem(new AskDocCommentItem(sym, site, source, response)) + def askDocComment(sym: Symbol, source: SourceFile, site: Symbol, fragments: List[(Symbol,SourceFile)], response: Response[(String, String, Position)]): Unit = + postWorkItem(new AskDocCommentItem(sym, source, site, fragments, response)) + + @deprecated("Use method that accepts fragments", "2.10.2") + def askDocComment(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]): Unit = + askDocComment(sym, source, site, (sym,source)::Nil, response) /** Sets sync var `response` to list of members that are visible * as members of the tree enclosing `pos`, possibly reachable by an implicit. @@ -258,7 +263,7 @@ trait CompilerControl { self: Global => * compiler thread. */ def parseTree(source: SourceFile): Tree = { - new UnitParser(new CompilationUnit(source)).parse() + newUnitParser(new CompilationUnit(source)).parse() } /** Asks for a computation to be done quickly on the presentation compiler thread */ @@ -384,9 +389,9 @@ trait CompilerControl { self: Global => response raise new MissingResponse } - case class AskDocCommentItem(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]) extends WorkItem { - def apply() = self.getDocComment(sym, site, source, response) - override def toString = "doc comment "+sym+" in "+source + case class AskDocCommentItem(sym: Symbol, source: SourceFile, site: Symbol, fragments: List[(Symbol,SourceFile)], response: Response[(String, String, Position)]) extends WorkItem { + def apply() = self.getDocComment(sym, source, site, fragments, response) + override def toString = "doc comment "+sym+" in "+source+" with fragments:"+fragments.mkString("(", ",", ")") def raiseMissing() = response raise new MissingResponse diff --git a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala b/src/interactive/scala/tools/nsc/interactive/ContextTrees.scala index 93ef4c4d6c..93ef4c4d6c 100644 --- a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala +++ b/src/interactive/scala/tools/nsc/interactive/ContextTrees.scala diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 921a07c805..099a882f10 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -14,11 +14,78 @@ import scala.tools.nsc.util.MultiHashMap import scala.reflect.internal.util.{ SourceFile, BatchSourceFile, Position, NoPosition } import scala.tools.nsc.reporters._ import scala.tools.nsc.symtab._ -import scala.tools.nsc.typechecker.DivergentImplicit +import scala.tools.nsc.doc.ScaladocAnalyzer +import scala.tools.nsc.typechecker.{ Analyzer, DivergentImplicit } import symtab.Flags.{ACCESSOR, PARAMACCESSOR} -import scala.annotation.elidable +import scala.annotation.{ elidable, tailrec } import scala.language.implicitConversions +trait InteractiveScaladocAnalyzer extends InteractiveAnalyzer with ScaladocAnalyzer { + val global : Global + import global._ + override def newTyper(context: Context) = new Typer(context) with InteractiveTyper with ScaladocTyper { + override def canAdaptConstantTypeToLiteral = false + } +} + +trait InteractiveAnalyzer extends Analyzer { + val global : Global + import global._ + + override def newTyper(context: Context): InteractiveTyper = new Typer(context) with InteractiveTyper + override def newNamer(context: Context): InteractiveNamer = new Namer(context) with InteractiveNamer + override protected def newPatternMatching = false + + trait InteractiveTyper extends Typer { + override def canAdaptConstantTypeToLiteral = false + override def canTranslateEmptyListToNil = false + override def missingSelectErrorTree(tree: Tree, qual: Tree, name: Name): Tree = tree match { + case Select(_, _) => treeCopy.Select(tree, qual, name) + case SelectFromTypeTree(_, _) => treeCopy.SelectFromTypeTree(tree, qual, name) + } + } + + trait InteractiveNamer extends Namer { + override def saveDefaultGetter(meth: Symbol, default: Symbol) { + // save the default getters as attachments in the method symbol. if compiling the + // same local block several times (which can happen in interactive mode) we might + // otherwise not find the default symbol, because the second time it the method + // symbol will be re-entered in the scope but the default parameter will not. + meth.attachments.get[DefaultsOfLocalMethodAttachment] match { + case Some(att) => att.defaultGetters += default + case None => meth.updateAttachment(new DefaultsOfLocalMethodAttachment(default)) + } + } + // this logic is needed in case typer was interrupted half + // way through and then comes back to do the tree again. In + // that case the definitions that were already attributed as + // well as any default parameters of such methods need to be + // re-entered in the current scope. + override def enterExistingSym(sym: Symbol): Context = { + if (sym != null && sym.owner.isTerm) { + enterIfNotThere(sym) + if (sym.isLazy) + sym.lazyAccessor andAlso enterIfNotThere + + for (defAtt <- sym.attachments.get[DefaultsOfLocalMethodAttachment]) + defAtt.defaultGetters foreach enterIfNotThere + } + super.enterExistingSym(sym) + } + override def enterIfNotThere(sym: Symbol) { + val scope = context.scope + @tailrec def search(e: ScopeEntry) { + if ((e eq null) || (e.owner ne scope)) + scope enter sym + else if (e.sym ne sym) // otherwise, aborts since we found sym + search(e.tail) + } + search(scope lookupEntry sym.name) + } + } +} + + /** The main class of the presentation compiler in an interactive environment such as an IDE */ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") extends { @@ -68,8 +135,26 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") @inline final def informIDE(msg: => String) = if (verboseIDE) println("[%s][%s]".format(projectName, msg)) + // don't keep the original owner in presentation compiler runs + // (the map will grow indefinitely, and the only use case is the backend) + override protected def saveOriginalOwner(sym: Symbol) { } + override protected def originalEnclosingMethod(sym: Symbol) = + abort("originalOwner is not kept in presentation compiler runs.") + override def forInteractive = true + override def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap = + new InteractiveAsSeenFromMap(pre, clazz) + + class InteractiveAsSeenFromMap(pre: Type, clazz: Symbol) extends AsSeenFromMap(pre, clazz) { + /** The method formerly known as 'instParamsRelaxed' goes here if it's still necessary, + * which it is currently supposed it is not. + * + * If it is, change AsSeenFromMap method correspondingTypeArgument to call an overridable + * method rather than aborting in the failure case. + */ + } + /** A map of all loaded files to the rich compilation units that correspond to them. */ val unitOfFile = new LinkedHashMap[AbstractFile, RichCompilationUnit] with @@ -127,6 +212,10 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") } } + override lazy val analyzer = new { + val global: Global.this.type = Global.this + } with InteractiveAnalyzer + private def cleanAllResponses() { cleanResponses(waitLoadedTypeResponses) cleanResponses(getParsedEnteredResponses) @@ -281,7 +370,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") * top-level idents. Therefore, we can detect top-level symbols that have a name * different from their source file */ - override lazy val loaders = new BrowsingLoaders { + override lazy val loaders: SymbolLoaders { val global: Global.this.type } = new BrowsingLoaders { val global: Global.this.type = Global.this } @@ -665,8 +754,8 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") * If we do just removeUnit, some problems with default parameters can ensue. * Calls to this method could probably be replaced by removeUnit once default parameters are handled more robustly. */ - private def afterRunRemoveUnitOf(source: SourceFile) { - toBeRemovedAfterRun += source.file + private def afterRunRemoveUnitsOf(sources: List[SourceFile]) { + toBeRemovedAfterRun ++= sources map (_.file) } /** A fully attributed tree located at position `pos` */ @@ -674,7 +763,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") case None => reloadSources(List(pos.source)) try typedTreeAt(pos) - finally afterRunRemoveUnitOf(pos.source) + finally afterRunRemoveUnitsOf(List(pos.source)) case Some(unit) => informIDE("typedTreeAt " + pos) parseAndEnter(unit) @@ -724,14 +813,23 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") respond(response)(typedTree(source, forceReload)) } + private def withTempUnits[T](sources: List[SourceFile])(f: (SourceFile => RichCompilationUnit) => T): T = { + val unitOfSrc: SourceFile => RichCompilationUnit = src => unitOfFile(src.file) + sources filterNot (getUnit(_).isDefined) match { + case Nil => + f(unitOfSrc) + case unknown => + reloadSources(unknown) + try { + f(unitOfSrc) + } finally + afterRunRemoveUnitsOf(unknown) + } + } + private def withTempUnit[T](source: SourceFile)(f: RichCompilationUnit => T): T = - getUnit(source) match { - case None => - reloadSources(List(source)) - try f(getUnit(source).get) - finally afterRunRemoveUnitOf(source) - case Some(unit) => - f(unit) + withTempUnits(List(source)){ srcToUnit => + f(srcToUnit(source)) } /** Find a 'mirror' of symbol `sym` in unit `unit`. Pre: `unit is loaded. */ @@ -795,50 +893,36 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") } } + private def forceDocComment(sym: Symbol, unit: RichCompilationUnit) { + unit.body foreachPartial { + case DocDef(comment, defn) if defn.symbol == sym => + fillDocComment(defn.symbol, comment) + EmptyTree + case _: ValOrDefDef => + EmptyTree + } + } + /** Implements CompilerControl.askDocComment */ - private[interactive] def getDocComment(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]) { - informIDE("getDocComment "+sym+" "+source) + private[interactive] def getDocComment(sym: Symbol, source: SourceFile, site: Symbol, fragments: List[(Symbol,SourceFile)], + response: Response[(String, String, Position)]) { + informIDE(s"getDocComment $sym at $source site $site") respond(response) { - withTempUnit(source){ u => - val mirror = findMirrorSymbol(sym, u) + withTempUnits(fragments.toList.unzip._2){ units => + for((sym, src) <- fragments) { + val mirror = findMirrorSymbol(sym, units(src)) + if (mirror ne NoSymbol) forceDocComment(mirror, units(src)) + } + val mirror = findMirrorSymbol(sym, units(source)) if (mirror eq NoSymbol) ("", "", NoPosition) else { - forceDocComment(mirror, u) - (expandedDocComment(mirror), rawDocComment(mirror), docCommentPos(mirror)) + (expandedDocComment(mirror, site), rawDocComment(mirror), docCommentPos(mirror)) } } } } - private def forceDocComment(sym: Symbol, unit: RichCompilationUnit) { - // Either typer has been run and we don't find DocDef, - // or we force the targeted typecheck here. - // In both cases doc comment maps should be filled for the subject symbol. - val docTree = - unit.body find { - case DocDef(_, defn) if defn.symbol eq sym => true - case _ => false - } - - for (t <- docTree) { - debugLog("Found DocDef tree for "+sym) - // Cannot get a typed tree at position since DocDef range is transparent. - val prevPos = unit.targetPos - val prevInterruptsEnabled = interruptsEnabled - try { - unit.targetPos = t.pos - interruptsEnabled = true - typeCheck(unit) - } catch { - case _: TyperResult => // ignore since we are after the side effect. - } finally { - unit.targetPos = prevPos - interruptsEnabled = prevInterruptsEnabled - } - } - } - def stabilizedType(tree: Tree): Type = tree match { case Ident(_) if tree.symbol.isStable => singleType(NoPrefix, tree.symbol) diff --git a/src/compiler/scala/tools/nsc/interactive/InteractiveReporter.scala b/src/interactive/scala/tools/nsc/interactive/InteractiveReporter.scala index 013b152e96..013b152e96 100644 --- a/src/compiler/scala/tools/nsc/interactive/InteractiveReporter.scala +++ b/src/interactive/scala/tools/nsc/interactive/InteractiveReporter.scala diff --git a/src/interactive/scala/tools/nsc/interactive/Main.scala b/src/interactive/scala/tools/nsc/interactive/Main.scala new file mode 100644 index 0000000000..3b4a36f62d --- /dev/null +++ b/src/interactive/scala/tools/nsc/interactive/Main.scala @@ -0,0 +1,34 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.tools +package nsc +package interactive + +/** The main class for NSC, a compiler for the programming + * language Scala. + */ +object Main extends nsc.MainClass { + override def processSettingsHook(): Boolean = { + if (this.settings.Yidedebug.value) { + this.settings.Xprintpos.value = true + this.settings.Yrangepos.value = true + val compiler = new interactive.Global(this.settings, this.reporter) + import compiler.{ reporter => _, _ } + + val sfs = command.files map getSourceFile + val reloaded = new interactive.Response[Unit] + askReload(sfs, reloaded) + + reloaded.get.right.toOption match { + case Some(ex) => reporter.cancelled = true // Causes exit code to be non-0 + case None => reporter.reset() // Causes other compiler errors to be ignored + } + askShutdown + false + } + else true + } +} diff --git a/src/compiler/scala/tools/nsc/interactive/Picklers.scala b/src/interactive/scala/tools/nsc/interactive/Picklers.scala index 09533fdeb5..b184afd0f5 100644 --- a/src/compiler/scala/tools/nsc/interactive/Picklers.scala +++ b/src/interactive/scala/tools/nsc/interactive/Picklers.scala @@ -164,8 +164,8 @@ trait Picklers { self: Global => .asClass (classOf[AskLinkPosItem]) implicit def askDocCommentItem: CondPickler[AskDocCommentItem] = - (pkl[Symbol] ~ pkl[Symbol] ~ pkl[SourceFile]) - .wrapped { case sym ~ site ~ source => new AskDocCommentItem(sym, site, source, new Response) } { item => item.sym ~ item.site ~ item.source } + (pkl[Symbol] ~ pkl[SourceFile] ~ pkl[Symbol] ~ pkl[List[(Symbol,SourceFile)]]) + .wrapped { case sym ~ source ~ site ~ fragments => new AskDocCommentItem(sym, source, site, fragments, new Response) } { item => item.sym ~ item.source ~ item.site ~ item.fragments } .asClass (classOf[AskDocCommentItem]) implicit def askLoadedTypedItem: CondPickler[AskLoadedTypedItem] = diff --git a/src/compiler/scala/tools/nsc/interactive/PresentationCompilerThread.scala b/src/interactive/scala/tools/nsc/interactive/PresentationCompilerThread.scala index a2d8e5d49a..a2d8e5d49a 100644 --- a/src/compiler/scala/tools/nsc/interactive/PresentationCompilerThread.scala +++ b/src/interactive/scala/tools/nsc/interactive/PresentationCompilerThread.scala diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/interactive/scala/tools/nsc/interactive/REPL.scala index 04c06b9357..04c06b9357 100644 --- a/src/compiler/scala/tools/nsc/interactive/REPL.scala +++ b/src/interactive/scala/tools/nsc/interactive/REPL.scala diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/interactive/scala/tools/nsc/interactive/RangePositions.scala index 6288400629..c57e1da184 100644 --- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala +++ b/src/interactive/scala/tools/nsc/interactive/RangePositions.scala @@ -10,4 +10,5 @@ package interactive trait RangePositions extends scala.reflect.internal.Positions with ast.Trees with ast.Positions { self: scala.tools.nsc.Global => + override def useOffsetPositions = false } diff --git a/src/compiler/scala/tools/nsc/interactive/Response.scala b/src/interactive/scala/tools/nsc/interactive/Response.scala index f36f769ec9..f36f769ec9 100644 --- a/src/compiler/scala/tools/nsc/interactive/Response.scala +++ b/src/interactive/scala/tools/nsc/interactive/Response.scala diff --git a/src/compiler/scala/tools/nsc/interactive/RichCompilationUnits.scala b/src/interactive/scala/tools/nsc/interactive/RichCompilationUnits.scala index b83c2cd095..b83c2cd095 100644 --- a/src/compiler/scala/tools/nsc/interactive/RichCompilationUnits.scala +++ b/src/interactive/scala/tools/nsc/interactive/RichCompilationUnits.scala diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/interactive/scala/tools/nsc/interactive/ScratchPadMaker.scala index 7af9174704..7af9174704 100644 --- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala +++ b/src/interactive/scala/tools/nsc/interactive/ScratchPadMaker.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala b/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTest.scala index a4a2de9b51..a4a2de9b51 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTest.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala b/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala index ad5c61b2b0..ad5c61b2b0 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/InteractiveTestSettings.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/Tester.scala b/src/interactive/scala/tools/nsc/interactive/tests/Tester.scala index 9382d5890f..9382d5890f 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/Tester.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/Tester.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala index 8d446cbbf8..8d446cbbf8 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala index 9085eb56e6..9085eb56e6 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala index 5cda0e53fb..9a2abd5139 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala @@ -13,11 +13,16 @@ private[tests] trait PresentationCompilerInstance extends TestSettings { override def compiler = PresentationCompilerInstance.this.compiler } + private class ScaladocEnabledGlobal extends Global(settings, compilerReporter) { + override lazy val analyzer = new { + val global: ScaladocEnabledGlobal.this.type = ScaladocEnabledGlobal.this + } with InteractiveScaladocAnalyzer + } + protected lazy val compiler: Global = { prepareSettings(settings) - new Global(settings, compilerReporter) { - override def forScaladoc = withDocComments - } + if (withDocComments) new ScaladocEnabledGlobal + else new Global(settings, compilerReporter) } /** diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala index b5ae5f2d75..b5ae5f2d75 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerRequestsWorkingMode.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala index 4d5b4e1129..4d5b4e1129 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/PresentationCompilerTestDef.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/Reporter.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/Reporter.scala index 631504cda5..631504cda5 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/Reporter.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/Reporter.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala index 676feeba8a..676feeba8a 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/SourcesCollector.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/TestMarker.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/TestMarker.scala index a5c228a549..a5c228a549 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/TestMarker.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/TestMarker.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/TestResources.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/TestResources.scala index 887c3cf29b..887c3cf29b 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/TestResources.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/TestResources.scala diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/TestSettings.scala b/src/interactive/scala/tools/nsc/interactive/tests/core/TestSettings.scala index 681204172b..681204172b 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/TestSettings.scala +++ b/src/interactive/scala/tools/nsc/interactive/tests/core/TestSettings.scala diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index fcbfd27738..4c996bfb88 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -90,18 +90,21 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza * @return An array obtained by replacing elements of this arrays with rows the represent. */ def transpose[U](implicit asArray: T => Array[U]): Array[Array[U]] = { - def mkRowBuilder() = Array.newBuilder(ClassTag[U](arrayElementClass(elementClass))) - val bs = asArray(head) map (_ => mkRowBuilder()) - for (xs <- this) { - var i = 0 - for (x <- asArray(xs)) { - bs(i) += x - i += 1 + val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass)) + if (isEmpty) bb.result() + else { + def mkRowBuilder() = Array.newBuilder(ClassTag[U](arrayElementClass(elementClass))) + val bs = asArray(head) map (_ => mkRowBuilder()) + for (xs <- this) { + var i = 0 + for (x <- asArray(xs)) { + bs(i) += x + i += 1 + } } + for (b <- bs) bb += b.result() + bb.result() } - val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass)) - for (b <- bs) bb += b.result - bb.result() } def seq = thisCollection diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala index 3aaf784cad..7e4c3b842c 100644 --- a/src/partest/scala/tools/partest/nest/DirectRunner.scala +++ b/src/partest/scala/tools/partest/nest/DirectRunner.scala @@ -38,27 +38,15 @@ trait DirectRunner { def runTestsForFiles(_kindFiles: List[File], kind: String): immutable.Map[String, TestState] = { System.setProperty("line.separator", "\n") - // @partest maintainer: we cannot create a fresh file manager here - // since the FM must respect --buildpath and --classpath from the command line - // for example, see how it's done in ReflectiveRunner - //val consFM = new ConsoleFileManager - //import consFM.{ latestCompFile, latestLibFile, latestPartestFile } - val latestCompFile = new File(fileManager.LATEST_COMP) - val latestReflectFile = new File(fileManager.LATEST_REFLECT) - val latestLibFile = new File(fileManager.LATEST_LIB) - val latestPartestFile = new File(fileManager.LATEST_PARTEST) - val latestActorsFile = new File(fileManager.LATEST_ACTORS) - val scalacheckURL = PathSettings.scalaCheck.toURL - val scalaCheckParentClassLoader = ScalaClassLoader.fromURLs( - scalacheckURL :: (List(latestCompFile, latestReflectFile, latestLibFile, latestActorsFile, latestPartestFile).map(_.toURI.toURL)) - ) - - val kindFiles = onlyValidTestPaths(_kindFiles) - val pool = Executors.newFixedThreadPool(numThreads) - val manager = new RunnerManager(kind, fileManager, TestRunParams(scalaCheckParentClassLoader)) - val futures = kindFiles map (f => (f, pool submit callable(manager runTest f))) toMap + val allUrls = PathSettings.scalaCheck.toURL :: fileManager.latestUrls + val scalaCheckParentClassLoader = ScalaClassLoader.fromURLs(allUrls) + val kindFiles = onlyValidTestPaths(_kindFiles) + val pool = Executors.newFixedThreadPool(numThreads) + val manager = new RunnerManager(kind, fileManager, TestRunParams(scalaCheckParentClassLoader)) + val futures = kindFiles map (f => (f, pool submit callable(manager runTest f))) toMap pool.shutdown() + try if (!pool.awaitTermination(4, TimeUnit.HOURS)) NestUI.warning("Thread pool timeout elapsed before all tests were complete!") catch { case t: InterruptedException => diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala index a4c4e7e6a6..a32c56e973 100644 --- a/src/partest/scala/tools/partest/nest/FileManager.scala +++ b/src/partest/scala/tools/partest/nest/FileManager.scala @@ -64,6 +64,20 @@ trait FileManager extends FileUtil { var LATEST_PARTEST: String var LATEST_ACTORS: String + protected def relativeToLibrary(what: String): String = { + if (LATEST_LIB endsWith ".jar") { + (SFile(LATEST_LIB).parent / s"scala-$what.jar").toAbsolute.path + } + else { + (SFile(LATEST_LIB).parent.parent / "classes" / what).toAbsolute.path + } + } + def latestScaladoc = relativeToLibrary("scaladoc") + def latestInteractive = relativeToLibrary("interactive") + def latestPaths = List(LATEST_LIB, LATEST_REFLECT, LATEST_COMP, LATEST_PARTEST, LATEST_ACTORS, latestScaladoc, latestInteractive) + def latestFiles = latestPaths map (p => new java.io.File(p)) + def latestUrls = latestFiles map (_.toURI.toURL) + var showDiff = false var updateCheck = false var showLog = false diff --git a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala index 3446dd0f72..05cae7b238 100644 --- a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala +++ b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala @@ -50,22 +50,15 @@ class ReflectiveRunner { else // auto detection new ConsoleFileManager - import fileManager. - { latestCompFile, latestReflectFile, latestLibFile, latestPartestFile, latestScalapFile, latestActorsFile } - val files = - Array(latestCompFile, latestReflectFile, latestLibFile, latestPartestFile, latestScalapFile, latestActorsFile) map (x => io.File(x)) - - val sepUrls = files map (_.toURL) - var sepLoader = new URLClassLoader(sepUrls, null) - // this is a workaround for https://issues.scala-lang.org/browse/SI-5433 - // when that bug is fixed, this paragraph of code can be safely removed + // when that bug is fixed, the addition of PathSettings.srcCodeLib can be removed // we hack into the classloader that will become parent classloader for scalac // this way we ensure that reflective macro lookup will pick correct Code.lift - sepLoader = new URLClassLoader((PathSettings.srcCodeLib +: files) map (_.toURL), null) + val sepUrls = PathSettings.srcCodeLib.toURI.toURL :: fileManager.latestUrls + val sepLoader = new URLClassLoader(sepUrls.toArray, null) if (isPartestDebug) - println("Loading classes from:\n" + sepUrls.mkString("\n")) + println("Loading classes from:\n " + fileManager.latestUrls.mkString("\n ")) // @partest maintainer: it seems to me that commented lines are incorrect // if classPath is not empty, then it has been provided by the --classpath option @@ -76,11 +69,8 @@ class ReflectiveRunner { // case Some(cp) => Nil // case _ => files.toList map (_.path) //} - val paths = files.toList map (_.path) - - val newClasspath = ClassPath.join(paths: _*) - setProp("java.class.path", newClasspath) + setProp("java.class.path", ClassPath.join(fileManager.latestPaths: _*)) // don't let partest find pluginsdir; in ant build, standard plugin has dedicated test suite //setProp("scala.home", latestLibFile.parent.parent.path) diff --git a/src/reflect/scala/reflect/internal/Required.scala b/src/reflect/scala/reflect/internal/Required.scala index 842491d56d..93383f5376 100644 --- a/src/reflect/scala/reflect/internal/Required.scala +++ b/src/reflect/scala/reflect/internal/Required.scala @@ -4,12 +4,9 @@ package internal import settings.MutableSettings trait Required { self: SymbolTable => - def picklerPhase: Phase - def settings: MutableSettings - def forInteractive: Boolean - - def forScaladoc: Boolean + @deprecated("Interactive is implemented with a custom Global; this flag is ignored", "2.11.0") def forInteractive = false + @deprecated("Scaladoc is implemented with a custom Global; this flag is ignored", "2.11.0") def forScaladoc = false } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 26ca62c44a..6837f37445 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -69,6 +69,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ val originalOwner = perRunCaches.newMap[Symbol, Symbol]() + // TODO - don't allow the owner to be changed without checking invariants, at least + // when under some flag. Define per-phase invariants for owner/owned relationships, + // e.g. after flatten all classes are owned by package classes, there are lots and + // lots of these to be declared (or more realistically, discovered.) + protected def saveOriginalOwner(sym: Symbol) { + if (originalOwner contains sym) () + else originalOwner(sym) = sym.rawowner + } + protected def originalEnclosingMethod(sym: Symbol): Symbol = { + if (sym.isMethod || sym == NoSymbol) sym + else { + val owner = originalOwner.getOrElse(sym, sym.rawowner) + if (sym.isLocalDummy) owner.enclClass.primaryConstructor + else originalEnclosingMethod(owner) + } + } + abstract class SymbolContextApiImpl extends SymbolContextApi { this: Symbol => @@ -948,13 +965,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => // e.g. after flatten all classes are owned by package classes, there are lots and // lots of these to be declared (or more realistically, discovered.) def owner_=(owner: Symbol) { - // don't keep the original owner in presentation compiler runs - // (the map will grow indefinitely, and the only use case is the - // backend). - if (!forInteractive) { - if (originalOwner contains this) () - else originalOwner(this) = rawowner - } + saveOriginalOwner(this) assert(isCompilerUniverse, "owner_= is not thread-safe; cannot be run in reflexive code") if (traceSymbolActivity) traceSymbols.recordNewSymbolOwner(this, owner) @@ -1912,15 +1923,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * originalOwner map is not populated for memory considerations (the symbol * may hang on to lazy types and in turn to whole (outdated) compilation units. */ - def originalEnclosingMethod: Symbol = { - assert(!forInteractive, "originalOwner is not kept in presentation compiler runs.") - if (isMethod) this - else { - val owner = originalOwner.getOrElse(this, rawowner) - if (isLocalDummy) owner.enclClass.primaryConstructor - else owner.originalEnclosingMethod - } - } + def originalEnclosingMethod: Symbol = Symbols.this.originalEnclosingMethod(this) /** The method or class which logically encloses the current symbol. * If the symbol is defined in the initialization part of a template diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index c7d2fa42d3..e96fcc90df 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -101,7 +101,8 @@ abstract class TreeInfo { // However, before typing, applications of nullary functional values are also // Apply(function, Nil) trees. To prevent them from being treated as pure, // we check that the callee is a method. - fn.symbol.isMethod && !fn.symbol.isLazy && isExprSafeToInline(fn) + // The callee might also be a Block, which has a null symbol, so we guard against that (SI-7185) + fn.symbol != null && fn.symbol.isMethod && !fn.symbol.isLazy && isExprSafeToInline(fn) case Typed(expr, _) => isExprSafeToInline(expr) case Block(stats, expr) => diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index a14938eeb5..a6c5367425 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3091,12 +3091,19 @@ trait Types * ?TC[?T] <: Any * }}} */ - def unifySimple = ( - (params.isEmpty || tp.typeSymbol == NothingClass || tp.typeSymbol == AnyClass) && { + def unifySimple = { + val sym = tp.typeSymbol + if (sym == NothingClass || sym == AnyClass) { // kind-polymorphic + // SI-7126 if we register some type alias `T=Any`, we can later end + // with malformed types like `T[T]` during type inference in + // `handlePolymorphicCall`. No such problem if we register `Any`. + addBound(sym.tpe) + true + } else if (params.isEmpty) { addBound(tp) true - } - ) + } else false + } /** Full case: involving a check of the form * {{{ @@ -3884,7 +3891,9 @@ trait Types case _ => NoType } - patType match { + // See the test for SI-7214 for motivation for dealias. Later `treeCondStrategy#outerTest` + // generates an outer test based on `patType.prefix` with automatically dealises. + patType.dealias match { case TypeRef(pre, sym, args) => val pre1 = maybeCreateDummyClone(pre, sym) (pre1 ne NoType) && isPopulated(copyTypeRef(patType, pre1, sym, args), selType) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index 5467d70cea..a130013398 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -11,8 +11,6 @@ class JavaUniverse extends internal.SymbolTable with ReflectSetup with runtime.S def inform(msg: String): Unit = log(msg) def picklerPhase = internal.SomePhase - def forInteractive = false - def forScaladoc = false lazy val settings = new Settings private val isLogging = sys.props contains "scala.debug.reflect" diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/scaladoc/scala/tools/ant/Scaladoc.scala index fd6d637212..fd6d637212 100644 --- a/src/compiler/scala/tools/ant/Scaladoc.scala +++ b/src/scaladoc/scala/tools/ant/Scaladoc.scala diff --git a/src/compiler/scala/tools/nsc/ScalaDoc.scala b/src/scaladoc/scala/tools/nsc/ScalaDoc.scala index 52a0c20a11..52a0c20a11 100644 --- a/src/compiler/scala/tools/nsc/ScalaDoc.scala +++ b/src/scaladoc/scala/tools/nsc/ScalaDoc.scala diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala index b4d2adaad4..b4d2adaad4 100644 --- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala diff --git a/src/compiler/scala/tools/nsc/doc/DocParser.scala b/src/scaladoc/scala/tools/nsc/doc/DocParser.scala index b753e84426..6dc3e5a62b 100644 --- a/src/compiler/scala/tools/nsc/doc/DocParser.scala +++ b/src/scaladoc/scala/tools/nsc/doc/DocParser.scala @@ -42,7 +42,7 @@ class DocParser(settings: nsc.Settings, reporter: Reporter) extends Global(setti */ def docUnit(code: String) = { val unit = new CompilationUnit(new BatchSourceFile("<console>", code)) - val scanner = new syntaxAnalyzer.UnitParser(unit) + val scanner = newUnitParser(unit) scanner.compilationUnit() } diff --git a/src/compiler/scala/tools/nsc/doc/Index.scala b/src/scaladoc/scala/tools/nsc/doc/Index.scala index f9b9eecdb3..f9b9eecdb3 100644 --- a/src/compiler/scala/tools/nsc/doc/Index.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Index.scala diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala new file mode 100644 index 0000000000..5ad50445a8 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala @@ -0,0 +1,234 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package doc + +import scala.tools.nsc.ast.parser.{ SyntaxAnalyzer, BracePatch } +import scala.reflect.internal.Chars._ +import symtab._ +import reporters.Reporter +import typechecker.Analyzer +import scala.reflect.internal.util.{ BatchSourceFile, RangePosition } + +trait ScaladocAnalyzer extends Analyzer { + val global : Global // generally, a ScaladocGlobal + import global._ + + override def newTyper(context: Context): ScaladocTyper = new Typer(context) with ScaladocTyper + + trait ScaladocTyper extends Typer { + private def unit = context.unit + + override def canAdaptConstantTypeToLiteral = false + + override protected def macroImplementationNotFoundMessage(name: Name): String = ( + super.macroImplementationNotFoundMessage(name) + + "\nWhen generating scaladocs for multiple projects at once, consider using -Ymacro-no-expand to disable macro expansions altogether." + ) + + override def typedDocDef(docDef: DocDef, mode: Mode, pt: Type): Tree = { + val sym = docDef.symbol + + if ((sym ne null) && (sym ne NoSymbol)) { + val comment = docDef.comment + docComments(sym) = comment + comment.defineVariables(sym) + val typer1 = newTyper(context.makeNewScope(docDef, context.owner)) + for (useCase <- comment.useCases) { + typer1.silent(_ => typer1 defineUseCases useCase) match { + case SilentTypeError(err) => + unit.warning(useCase.pos, err.errMsg) + case _ => + } + for (useCaseSym <- useCase.defined) { + if (sym.name != useCaseSym.name) + unit.warning(useCase.pos, "@usecase " + useCaseSym.name.decode + " does not match commented symbol: " + sym.name.decode) + } + } + } + + super.typedDocDef(docDef, mode, pt) + } + + def defineUseCases(useCase: UseCase): List[Symbol] = { + def stringParser(str: String): syntaxAnalyzer.Parser = { + val file = new BatchSourceFile(context.unit.source.file, str) { + override def positionInUltimateSource(pos: Position) = { + pos.withSource(context.unit.source, useCase.pos.start) + } + } + newUnitParser(new CompilationUnit(file)) + } + + val trees = stringParser(useCase.body+";").nonLocalDefOrDcl + val enclClass = context.enclClass.owner + + def defineAlias(name: Name) = ( + if (context.scope.lookup(name) == NoSymbol) { + lookupVariable(name.toString.substring(1), enclClass) foreach { repl => + silent(_.typedTypeConstructor(stringParser(repl).typ())) map { tpt => + val alias = enclClass.newAliasType(name.toTypeName, useCase.pos) + val tparams = cloneSymbolsAtOwner(tpt.tpe.typeSymbol.typeParams, alias) + val newInfo = genPolyType(tparams, appliedType(tpt.tpe, tparams map (_.tpe))) + alias setInfo newInfo + context.scope.enter(alias) + } + } + } + ) + + for (tree <- trees; t <- tree) + t match { + case Ident(name) if name startsWith '$' => defineAlias(name) + case _ => + } + + useCase.aliases = context.scope.toList + namer.enterSyms(trees) + typedStats(trees, NoSymbol) + useCase.defined = context.scope.toList filterNot (useCase.aliases contains _) + + if (settings.debug.value) + useCase.defined foreach (sym => println("defined use cases: %s:%s".format(sym, sym.tpe))) + + useCase.defined + } + } +} + +abstract class ScaladocSyntaxAnalyzer[G <: Global](val global: G) extends SyntaxAnalyzer { + import global._ + + class ScaladocJavaUnitParser(unit: CompilationUnit) extends { + override val in = new ScaladocJavaUnitScanner(unit) + } with JavaUnitParser(unit) { } + + class ScaladocJavaUnitScanner(unit: CompilationUnit) extends JavaUnitScanner(unit) { + /** buffer for the documentation comment + */ + var docBuffer: StringBuilder = null + + /** add the given character to the documentation buffer + */ + protected def putDocChar(c: Char) { + if (docBuffer ne null) docBuffer.append(c) + } + + override protected def skipComment(): Boolean = { + if (in.ch == '/') { + do { + in.next + } while ((in.ch != CR) && (in.ch != LF) && (in.ch != SU)) + true + } else if (in.ch == '*') { + docBuffer = null + in.next + val scalaDoc = ("/**", "*/") + if (in.ch == '*') + docBuffer = new StringBuilder(scalaDoc._1) + do { + do { + if (in.ch != '*' && in.ch != SU) { + in.next; putDocChar(in.ch) + } + } while (in.ch != '*' && in.ch != SU) + while (in.ch == '*') { + in.next; putDocChar(in.ch) + } + } while (in.ch != '/' && in.ch != SU) + if (in.ch == '/') in.next + else incompleteInputError("unclosed comment") + true + } else { + false + } + } + } + + class ScaladocUnitScanner(unit0: CompilationUnit, patches0: List[BracePatch]) extends UnitScanner(unit0, patches0) { + + private var docBuffer: StringBuilder = null // buffer for comments + private var docPos: Position = NoPosition // last doc comment position + private var inDocComment = false + + override def discardDocBuffer() = { + val doc = flushDoc + if (doc ne null) + unit.warning(docPos, "discarding unmoored doc comment") + } + + override def flushDoc(): DocComment = { + if (docBuffer eq null) null + else try DocComment(docBuffer.toString, docPos) finally docBuffer = null + } + + override protected def putCommentChar() { + if (inDocComment) + docBuffer append ch + + nextChar() + } + override def skipDocComment(): Unit = { + inDocComment = true + docBuffer = new StringBuilder("/**") + super.skipDocComment() + } + override def skipBlockComment(): Unit = { + inDocComment = false + docBuffer = new StringBuilder("/*") + super.skipBlockComment() + } + override def skipComment(): Boolean = { + super.skipComment() && { + if (docBuffer ne null) { + if (inDocComment) + foundDocComment(docBuffer.toString, offset, charOffset - 2) + else + try foundComment(docBuffer.toString, offset, charOffset - 2) finally docBuffer = null + } + true + } + } + def foundComment(value: String, start: Int, end: Int) { + val pos = new RangePosition(unit.source, start, start, end) + unit.comment(pos, value) + } + def foundDocComment(value: String, start: Int, end: Int) { + docPos = new RangePosition(unit.source, start, start, end) + unit.comment(docPos, value) + } + } + class ScaladocUnitParser(unit: CompilationUnit, patches: List[BracePatch]) extends UnitParser(unit, patches) { + override def newScanner() = new ScaladocUnitScanner(unit, patches) + override def withPatches(patches: List[BracePatch]) = new ScaladocUnitParser(unit, patches) + + override def joinComment(trees: => List[Tree]): List[Tree] = { + val doc = in.flushDoc + if ((doc ne null) && doc.raw.length > 0) { + log(s"joinComment(doc=$doc)") + val joined = trees map { + t => + DocDef(doc, t) setPos { + if (t.pos.isDefined) { + val pos = doc.pos.withEnd(t.pos.endOrPoint) + // always make the position transparent + pos.makeTransparent + } else { + t.pos + } + } + } + joined.find(_.pos.isOpaqueRange) foreach { + main => + val mains = List(main) + joined foreach { t => if (t ne main) ensureNonOverlapping(t, mains) } + } + joined + } + else trees + } + } +} diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala new file mode 100644 index 0000000000..20f24dc753 --- /dev/null +++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocGlobal.scala @@ -0,0 +1,49 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2013 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package doc + +import scala.tools.nsc.ast.parser.{ SyntaxAnalyzer, BracePatch } +import scala.reflect.internal.Chars._ +import symtab._ +import reporters.Reporter +import typechecker.Analyzer +import scala.reflect.internal.util.{ BatchSourceFile, RangePosition } + +trait ScaladocGlobalTrait extends Global { + outer => + + override val useOffsetPositions = false + override def newUnitParser(unit: CompilationUnit) = new syntaxAnalyzer.ScaladocUnitParser(unit, Nil) + + override lazy val syntaxAnalyzer = new ScaladocSyntaxAnalyzer[outer.type](outer) { + val runsAfter = List[String]() + val runsRightAfter = None + } + override lazy val loaders = new SymbolLoaders { + val global: outer.type = outer + + // SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented + // therefore, it will rummage through the classpath triggering errors whenever it encounters package objects + // that are not in their correct place (see bug for details) + override protected def signalError(root: Symbol, ex: Throwable) { + log(s"Suppressing error involving $root: $ex") + } + } +} + +class ScaladocGlobal(settings: doc.Settings, reporter: Reporter) extends Global(settings, reporter) with ScaladocGlobalTrait { + override protected def computeInternalPhases() { + phasesSet += syntaxAnalyzer + phasesSet += analyzer.namerFactory + phasesSet += analyzer.packageObjects + phasesSet += analyzer.typerFactory + } + override def forScaladoc = true + override lazy val analyzer = new { + val global: ScaladocGlobal.this.type = ScaladocGlobal.this + } with ScaladocAnalyzer +} diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala index 90b94e1336..90b94e1336 100644 --- a/src/compiler/scala/tools/nsc/doc/Settings.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala diff --git a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala b/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala index 9447e36610..9447e36610 100644 --- a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Uncompilable.scala diff --git a/src/compiler/scala/tools/nsc/doc/Universe.scala b/src/scaladoc/scala/tools/nsc/doc/Universe.scala index 11520c810e..11520c810e 100644 --- a/src/compiler/scala/tools/nsc/doc/Universe.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Universe.scala diff --git a/src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala index 2064d86860..2064d86860 100755 --- a/src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala diff --git a/src/compiler/scala/tools/nsc/doc/base/LinkTo.scala b/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala index c11179800c..c11179800c 100755 --- a/src/compiler/scala/tools/nsc/doc/base/LinkTo.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/LinkTo.scala diff --git a/src/compiler/scala/tools/nsc/doc/base/MemberLookupBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala index 8d80333195..8d80333195 100755 --- a/src/compiler/scala/tools/nsc/doc/base/MemberLookupBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala diff --git a/src/compiler/scala/tools/nsc/doc/base/comment/Body.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala index 2a07547de2..2a07547de2 100755 --- a/src/compiler/scala/tools/nsc/doc/base/comment/Body.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala diff --git a/src/compiler/scala/tools/nsc/doc/base/comment/Comment.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala index a3d05ae50b..a3d05ae50b 100644 --- a/src/compiler/scala/tools/nsc/doc/base/comment/Comment.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala diff --git a/src/compiler/scala/tools/nsc/doc/doclet/Generator.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala index 42b56aa927..42b56aa927 100644 --- a/src/compiler/scala/tools/nsc/doc/doclet/Generator.scala +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Generator.scala diff --git a/src/compiler/scala/tools/nsc/doc/doclet/Indexer.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala index 0cdd47182f..0cdd47182f 100644 --- a/src/compiler/scala/tools/nsc/doc/doclet/Indexer.scala +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Indexer.scala diff --git a/src/compiler/scala/tools/nsc/doc/doclet/Universer.scala b/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala index ee8b7809e5..ee8b7809e5 100644 --- a/src/compiler/scala/tools/nsc/doc/doclet/Universer.scala +++ b/src/scaladoc/scala/tools/nsc/doc/doclet/Universer.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/Doclet.scala b/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala index 21c5f6bb67..21c5f6bb67 100644 --- a/src/compiler/scala/tools/nsc/doc/html/Doclet.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/Doclet.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala index d721a96ad7..d721a96ad7 100644 --- a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala index 229e26d699..229e26d699 100644 --- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/Page.scala b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala index 91939cf3de..91939cf3de 100644 --- a/src/compiler/scala/tools/nsc/doc/html/Page.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/Page.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala index 5781e680dd..5781e680dd 100644 --- a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/SyntaxHigh.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala index c034647320..c034647320 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala index e3c94505ab..e3c94505ab 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/ReferenceIndex.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala index a74c2eedbd..a74c2eedbd 100755 --- a/src/compiler/scala/tools/nsc/doc/html/page/ReferenceIndex.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/ReferenceIndex.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Source.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Source.scala index 37145756d9..37145756d9 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Source.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Source.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala index 63509de4b5..63509de4b5 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala index 61c1819d11..61c1819d11 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramGenerator.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala index ec00cace75..ec00cace75 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala index 837d9e6f21..837d9e6f21 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala index 2fa1bf62f3..2fa1bf62f3 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/diagram/DotRunner.scala diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/arrow-down.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-down.png Binary files differindex 7229603ae5..7229603ae5 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/arrow-down.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-down.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/arrow-right.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-right.png Binary files differindex b2f2935dc9..b2f2935dc9 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/arrow-right.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-right.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/class.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class.png Binary files differindex 97edbd49db..97edbd49db 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/class.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/class_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_big.png Binary files differindex cb1f638a58..cb1f638a58 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/class_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/class_diagram.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_diagram.png Binary files differindex 9d7aec792b..9d7aec792b 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/class_diagram.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_diagram.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/class_to_object_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_to_object_big.png Binary files differindex 5dd6e38d2e..5dd6e38d2e 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/class_to_object_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/class_to_object_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/constructorsbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/constructorsbg.gif Binary files differindex 2e3f5ea530..2e3f5ea530 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/constructorsbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/constructorsbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif Binary files differindex 4be145d0af..4be145d0af 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/defbg-blue.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/defbg-blue.gif Binary files differindex 69038337a7..69038337a7 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/defbg-blue.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/defbg-blue.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/defbg-green.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/defbg-green.gif Binary files differindex 36c43be3a2..36c43be3a2 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/defbg-green.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/defbg-green.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/diagrams.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.css index 5fe33f72f5..5fe33f72f5 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/diagrams.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.css diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/diagrams.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js index 478f2e38ac..478f2e38ac 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/diagrams.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left.png Binary files differindex 0e8c893315..0e8c893315 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left.psd b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left.psd Binary files differindex 4d740f3b17..4d740f3b17 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left.psd +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left.psd diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left2.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left2.gif Binary files differindex b9b49076a6..b9b49076a6 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_left2.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_left2.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_right.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_right.png Binary files differindex f127e35b48..f127e35b48 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_right.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_right.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_right.psd b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_right.psd Binary files differindex 63a1ae8349..63a1ae8349 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filter_box_right.psd +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filter_box_right.psd diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filterbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterbg.gif Binary files differindex 542ba4aa5a..542ba4aa5a 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filterbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.gif Binary files differindex b5075c16cd..b5075c16cd 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.png Binary files differindex d613cf5633..d613cf5633 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbarbg.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbg.gif Binary files differindex ae2f85823b..ae2f85823b 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/filterboxbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/filterboxbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/fullcommenttopbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/fullcommenttopbg.gif Binary files differindex a0d93f4844..a0d93f4844 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/fullcommenttopbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/fullcommenttopbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css index 55fb370a41..55fb370a41 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.css diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js index 70073b272a..70073b272a 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js index faab0cf1a3..faab0cf1a3 100755 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery-ui.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.js index bc3fbc81b2..bc3fbc81b2 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js index 4dd48675b7..4dd48675b7 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.layout.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js index 4688d633fe..4688d633fe 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/modernizr.custom.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png Binary files differindex 9b32288e04..9b32288e04 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li-a.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/navigation-li.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li.png Binary files differindex fd0ad06e81..fd0ad06e81 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/navigation-li.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/navigation-li.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object.png Binary files differindex ad312793ea..ad312793ea 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_big.png Binary files differindex 67ffca79de..67ffca79de 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_diagram.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_diagram.png Binary files differindex 6e9f2f743f..6e9f2f743f 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_diagram.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_diagram.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png Binary files differindex 7502942eb6..7502942eb6 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_class_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png Binary files differindex c777bfce8d..c777bfce8d 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_trait_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png Binary files differindex 7502942eb6..7502942eb6 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/object_to_type_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif Binary files differindex 848dd5963a..848dd5963a 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownderbg2.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif Binary files differindex 34a04249ee..34a04249ee 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif Binary files differindex 2ed33b0aa4..2ed33b0aa4 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ownerbg2.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/package.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package.png Binary files differindex 6ea17ac320..6ea17ac320 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/package.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/package_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package_big.png Binary files differindex 529aa93188..529aa93188 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/package_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/package_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif Binary files differindex 00c3378a2a..00c3378a2a 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/packagesbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/raphael-min.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/raphael-min.js index d30dbad858..d30dbad858 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/raphael-min.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/raphael-min.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/ref-index.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css index 7d64b9c5c5..7d64b9c5c5 100755 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/ref-index.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/ref-index.css diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/remove.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.png Binary files differindex 4625f9df74..4625f9df74 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/remove.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/remove.psd b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.psd Binary files differindex 3764f82ccb..3764f82ccb 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/remove.psd +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/remove.psd diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/scheduler.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js index 4417f5b438..4417f5b438 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/scheduler.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png Binary files differindex bc29efb3e6..bc29efb3e6 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png Binary files differindex 8313f4975b..8313f4975b 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right.png Binary files differindex 04eda2f307..04eda2f307 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected-right.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected.png Binary files differindex c89765239e..c89765239e 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected2-right.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2-right.png Binary files differindex bf984ef0ba..bf984ef0ba 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected2-right.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2-right.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected2.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2.png Binary files differindex a790bb1169..a790bb1169 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected2.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/selected2.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif Binary files differindex b6ac4415e4..b6ac4415e4 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif Binary files differindex 9aae5ba0aa..9aae5ba0aa 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/signaturebg2.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css index b066027f04..b066027f04 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js index 6d1caf6d50..6d1caf6d50 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js index 0af34eca4c..0af34eca4c 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/tools.tooltip.js diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/trait.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait.png Binary files differindex fb961a2eda..fb961a2eda 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/trait.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_big.png Binary files differindex 625d9251cb..625d9251cb 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png Binary files differindex 88983254ce..88983254ce 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_diagram.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png Binary files differindex d0cd7fd512..d0cd7fd512 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/trait_to_object_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type.png Binary files differindex 6c6e1fe2f5..6c6e1fe2f5 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_big.png Binary files differindex 04c8794e92..04c8794e92 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type_diagram.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_diagram.png Binary files differindex d8152529fd..d8152529fd 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type_diagram.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_diagram.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type_tags.ai b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_tags.ai index 3b5c47c9e3..3b5c47c9e3 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type_tags.ai +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_tags.ai diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png Binary files differindex ef2615bacc..ef2615bacc 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/type_to_object_big.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/typebg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/typebg.gif Binary files differindex 2fcc77b2e8..2fcc77b2e8 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/typebg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/typebg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/unselected.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/unselected.png Binary files differindex d5ac639405..d5ac639405 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/unselected.png +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/unselected.png diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif Binary files differindex 2a949311d7..2a949311d7 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/valuemembersbg.gif diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/versions.txt b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/versions.txt index 17d1caeb66..17d1caeb66 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/versions.txt +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/versions.txt diff --git a/src/compiler/scala/tools/nsc/doc/model/CommentFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala index 574d6b04f8..574d6b04f8 100644 --- a/src/compiler/scala/tools/nsc/doc/model/CommentFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala index 924f203a59..924f203a59 100644 --- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala index 1272906df5..1272906df5 100755 --- a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/IndexModelFactory.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala index 23259a4ae8..23259a4ae8 100644 --- a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/MemberLookup.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala index 1df725636a..1df725636a 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 868c2fc3a4..868c2fc3a4 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala index 99e9059d79..99e9059d79 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/TreeEntity.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala index 5b4ec4a40b..5b4ec4a40b 100644 --- a/src/compiler/scala/tools/nsc/doc/model/TreeEntity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeEntity.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala index b972649194..b972649194 100755 --- a/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/TreeFactory.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala b/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala index cf5c1fb3fb..cf5c1fb3fb 100644 --- a/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/TypeEntity.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/ValueArgument.scala b/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala index f712869a4b..f712869a4b 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ValueArgument.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ValueArgument.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/Visibility.scala b/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala index 22580805aa..22580805aa 100644 --- a/src/compiler/scala/tools/nsc/doc/model/Visibility.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/Visibility.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/Diagram.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala index 150b293b81..150b293b81 100644 --- a/src/compiler/scala/tools/nsc/doc/model/diagram/Diagram.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/Diagram.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala index 6395446d3b..6395446d3b 100644 --- a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala index ebac25bbe4..ebac25bbe4 100644 --- a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/scaladoc/scala/tools/partest/ScaladocModelTest.scala index 3db9f18484..f0a9caac15 100644 --- a/src/partest/scala/tools/partest/ScaladocModelTest.scala +++ b/src/scaladoc/scala/tools/partest/ScaladocModelTest.scala @@ -5,9 +5,10 @@ package scala.tools.partest +import scala.tools.nsc import scala.tools.nsc._ import scala.tools.nsc.util.CommandLineParser -import scala.tools.nsc.doc.{Settings, DocFactory, Universe} +import scala.tools.nsc.doc.{ DocFactory, Universe } import scala.tools.nsc.doc.model._ import scala.tools.nsc.doc.model.diagram._ import scala.tools.nsc.doc.base.comment._ @@ -78,11 +79,11 @@ abstract class ScaladocModelTest extends DirectTest { System.setErr(prevErr) } - private[this] var settings: Settings = null + private[this] var settings: doc.Settings = null // create a new scaladoc compiler private[this] def newDocFactory: DocFactory = { - settings = new Settings(_ => ()) + settings = new doc.Settings(_ => ()) settings.scaladocQuietRun = true // yaay, no more "model contains X documentable templates"! val args = extraSettings + " " + scaladocSettings new ScalaDoc.Command((CommandLineParser tokenize (args)), settings) // side-effecting, I think @@ -96,7 +97,6 @@ abstract class ScaladocModelTest extends DirectTest { // so we don't get the newSettings warning override def isDebug = false - // finally, enable easy navigation inside the entities object access { diff --git a/test/files/jvm/nooptimise/Foo_1.flags b/test/files/jvm/nooptimise/Foo_1.flags new file mode 100644 index 0000000000..9686c20775 --- /dev/null +++ b/test/files/jvm/nooptimise/Foo_1.flags @@ -0,0 +1 @@ +-optimise -Ynooptimise
\ No newline at end of file diff --git a/test/files/jvm/nooptimise/Foo_1.scala b/test/files/jvm/nooptimise/Foo_1.scala new file mode 100644 index 0000000000..c6f1b06c8e --- /dev/null +++ b/test/files/jvm/nooptimise/Foo_1.scala @@ -0,0 +1,8 @@ +class Foo_1 { + def foo() { + // optimization will remove this magic 3 from appearing in the source + // so -Ynooptimize should prevent that + val x = 3 + + } +} diff --git a/test/files/jvm/nooptimise/Test.scala b/test/files/jvm/nooptimise/Test.scala new file mode 100644 index 0000000000..ec8daa6e16 --- /dev/null +++ b/test/files/jvm/nooptimise/Test.scala @@ -0,0 +1,23 @@ +import scala.tools.partest.BytecodeTest +import scala.tools.asm +import asm.tree.InsnList +import scala.collection.JavaConverters._ + +object Test extends BytecodeTest { + def show: Unit = { + val classNode = loadClassNode("Foo_1") + val methodNode = getMethod(classNode, "foo") + // if optimization didn't run then + // there should be some useless instructions + // with the magic constant 3 + val expected = 1 + val got = countMagicThrees(methodNode.instructions) + assert(got == expected, s"expected $expected but got $got magic threes") + } + + def countMagicThrees(insnList: InsnList): Int = { + def isMagicThree(node: asm.tree.AbstractInsnNode): Boolean = + (node.getOpcode == asm.Opcodes.ICONST_3) + insnList.iterator.asScala.count(isMagicThree) + } +} diff --git a/test/files/jvm/t7006/Foo_1.flags b/test/files/jvm/t7006/Foo_1.flags index 72fe7b1aa0..37b2116413 100644 --- a/test/files/jvm/t7006/Foo_1.flags +++ b/test/files/jvm/t7006/Foo_1.flags @@ -1 +1 @@ - -Ydead-code -Ydebug -Xfatal-warnings +-optimise -Ydebug -Xfatal-warnings diff --git a/test/files/jvm/unreachable/Foo_1.flags b/test/files/jvm/unreachable/Foo_1.flags new file mode 100644 index 0000000000..ce6e93b3da --- /dev/null +++ b/test/files/jvm/unreachable/Foo_1.flags @@ -0,0 +1 @@ +-Ynooptimise
\ No newline at end of file diff --git a/test/files/jvm/unreachable/Foo_1.scala b/test/files/jvm/unreachable/Foo_1.scala new file mode 100644 index 0000000000..d17421c516 --- /dev/null +++ b/test/files/jvm/unreachable/Foo_1.scala @@ -0,0 +1,110 @@ +class Foo_1 { + def unreachableNormalExit: Int = { + return 42 + 0 + } + + def unreachableIf: Int = { + return 42 + if (util.Random.nextInt % 2 == 0) + 0 + else + 1 + } + + def unreachableIfBranches: Int = { + if (util.Random.nextInt % 2 == 0) + return 42 + else + return 42 + + return 0 + } + + def unreachableOneLegIf: Int = { + if (util.Random.nextInt % 2 == 0) + return 42 + + return 42 + } + + def unreachableLeftBranch: Int = { + val result = if (util.Random.nextInt % 2 == 0) + return 42 + else + 42 + + return result + } + + def unreachableRightBranch: Int = { + val result = if (util.Random.nextInt % 2 == 0) + 42 + else + return 42 + + return result + } + + def unreachableTryCatchFinally: Int = { + return 42 + try { + return 0 + } catch { + case x: Throwable => return 1 + } finally { + return 2 + } + return 3 + } + + def unreachableAfterTry: Int = { + try { + return 42 + } catch { + case x: Throwable => return 2 + } + return 3 + } + + def unreachableAfterCatch: Int = { + try { + error("haha") + } catch { + case x: Throwable => return 42 + } + return 3 + } + + def unreachableAfterFinally: Int = { + try { + return 1 + } catch { + case x: Throwable => return 2 + } finally { + return 42 + } + return 3 + } + + def unreachableSwitch: Int = { + return 42 + val x = util.Random.nextInt % 2 + x match { + case 0 => return 0 + case 1 => return 1 + case _ => error("wtf") + } + 2 + } + + def unreachableAfterSwitch: Int = { + val x = util.Random.nextInt % 2 + x match { + case 0 => return 42 + case 1 => return 41 + x + case _ => error("wtf") + } + 2 + } +}
\ No newline at end of file diff --git a/test/files/jvm/unreachable/Test.scala b/test/files/jvm/unreachable/Test.scala new file mode 100644 index 0000000000..3f520eb106 --- /dev/null +++ b/test/files/jvm/unreachable/Test.scala @@ -0,0 +1,23 @@ +import scala.tools.partest.BytecodeTest +import scala.tools.asm +import asm.tree.InsnList +import scala.collection.JavaConverters._ + +object Test extends BytecodeTest { + def show: Unit = { + val classNode = loadClassNode("Foo_1") + // Foo_1 is full of unreachable code which if not elimintated + // will result in NOPs as can be confirmed by adding -Ydisable-unreachable-prevention + // to Foo_1.flags + for (methodNode <- classNode.methods.asScala) { + val got = count(methodNode.instructions, asm.Opcodes.NOP) + if (got != 0) println(s"Found $got NOP(s) in ${methodNode.name}") + } + } + + def count(insnList: InsnList, opcode: Int): Int = { + def isNop(node: asm.tree.AbstractInsnNode): Boolean = + (node.getOpcode == opcode) + insnList.iterator.asScala.count(isNop) + } +}
\ No newline at end of file diff --git a/test/files/neg/macro-basic-mamdmi.check b/test/files/neg/macro-basic-mamdmi.check index c7b58d70d2..621d318ceb 100644 --- a/test/files/neg/macro-basic-mamdmi.check +++ b/test/files/neg/macro-basic-mamdmi.check @@ -1,4 +1,5 @@ -Impls_Macros_Test_1.scala:36: error: macro implementation not found: foo (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them) +Impls_Macros_Test_1.scala:36: error: macro implementation not found: foo +(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them) println(foo(2) + Macros.bar(2) * new Macros().quux(4)) ^ one error found diff --git a/test/files/neg/t5753.check b/test/files/neg/t5753.check index 76602de17d..379416c179 100644 --- a/test/files/neg/t5753.check +++ b/test/files/neg/t5753.check @@ -1,4 +1,5 @@ -Test_2.scala:9: error: macro implementation not found: foo (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them) +Test_2.scala:9: error: macro implementation not found: foo +(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them) println(foo(42)) ^ one error found diff --git a/test/files/neg/t7185.check b/test/files/neg/t7185.check new file mode 100644 index 0000000000..46f2cc797e --- /dev/null +++ b/test/files/neg/t7185.check @@ -0,0 +1,7 @@ +t7185.scala:2: error: overloaded method value apply with alternatives: + (f: scala.xml.Node => Boolean)scala.xml.NodeSeq <and> + (i: Int)scala.xml.Node + cannot be applied to () + <e></e>() + ^ +one error found diff --git a/test/files/neg/t7185.scala b/test/files/neg/t7185.scala new file mode 100644 index 0000000000..2f9284bc5f --- /dev/null +++ b/test/files/neg/t7185.scala @@ -0,0 +1,3 @@ +object Test { + <e></e>() +} diff --git a/test/files/pos/t7126.scala b/test/files/pos/t7126.scala new file mode 100644 index 0000000000..6720511e08 --- /dev/null +++ b/test/files/pos/t7126.scala @@ -0,0 +1,11 @@ +import language._ + +object Test { + type T = Any + boom(???): Option[T] // SOE + def boom[CC[U]](t : CC[T]): Option[CC[T]] = None + + // okay + foo(???): Option[Any] + def foo[CC[U]](t : CC[Any]): Option[CC[Any]] = None +}
\ No newline at end of file diff --git a/test/files/pos/t7183.flags b/test/files/pos/t7183.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t7183.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t7183.scala b/test/files/pos/t7183.scala new file mode 100644 index 0000000000..7647c1634b --- /dev/null +++ b/test/files/pos/t7183.scala @@ -0,0 +1,13 @@ +class A +object A { + def unapply(a: A): Some[A] = Some(a) // Change return type to Option[A] and the warning is gone +} + +object Test { + for (A(a) <- List(new A)) yield a // spurious dead code warning. +} + +// List(new A()).withFilter(((check$ifrefutable$2) => check$ifrefutable$2: @scala.unchecked match { +// case A((a @ _)) => true +// case _ => false // this is dead code, but it's compiler generated. +// })) diff --git a/test/files/pos/t7190.scala b/test/files/pos/t7190.scala new file mode 100644 index 0000000000..f7ccded1b4 --- /dev/null +++ b/test/files/pos/t7190.scala @@ -0,0 +1,26 @@ +import scala.language.experimental.macros +import scala.reflect.macros._ + +trait A[T] { + def min[U >: T](implicit ord: Numeric[U]): T = macro A.min[T, U] +} + +object A { + def min[T: c.WeakTypeTag, U >: T: c.WeakTypeTag](c: Context)(ord: c.Expr[Numeric[U]]): c.Expr[T] = { + c.universe.reify { + ord.splice.zero.asInstanceOf[T] + } + } +} + +class B extends A[Int] { + override def min[U >: Int](implicit ord: Numeric[U]): Int = macro B.min[U] +} + +object B { + def min[U >: Int: c.WeakTypeTag](c: Context)(ord: c.Expr[Numeric[U]]): c.Expr[Int] = { + c.universe.reify { + ord.splice.zero.asInstanceOf[Int] + } + } +}
\ No newline at end of file diff --git a/test/files/presentation/doc.check b/test/files/presentation/doc.check index e33756773d..5a3ff13151 100644 --- a/test/files/presentation/doc.check +++ b/test/files/presentation/doc.check @@ -1,49 +1 @@ -reload: Test.scala -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version: -@since: -@todo: -@note: -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since: -@todo: -@note: -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10)))))) -@todo: -@note: -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10)))))) -@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe))))))) -@note: -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10)))))) -@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe))))))) -@note:Body(List(Paragraph(Chain(List(Summary(Text(Don't inherit!))))))) -@see: -body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( -)))))) -@example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) -@version:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(1), Text(.)))), Text(0, 09/07/2012)))))) -@since:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(2), Text(.)))), Text(10)))))) -@todo:Body(List(Paragraph(Chain(List(Summary(Text(this method is unsafe))))))) -@note:Body(List(Paragraph(Chain(List(Summary(Text(Don't inherit!))))))) -@see:Body(List(Paragraph(Chain(List(Summary(Text(some other method))))))) +reload: Base.scala, Class.scala, Derived.scala diff --git a/test/files/presentation/doc/doc.scala b/test/files/presentation/doc/doc.scala index f9ebd09876..7a2eb9a588 100755 --- a/test/files/presentation/doc/doc.scala +++ b/test/files/presentation/doc/doc.scala @@ -4,37 +4,56 @@ import scala.tools.nsc.doc.base.comment._ import scala.tools.nsc.interactive._ import scala.tools.nsc.interactive.tests._ import scala.tools.nsc.util._ -import scala.tools.nsc.io._ object Test extends InteractiveTest { val tags = Seq( "@example `\"abb\".permutations = Iterator(abb, bab, bba)`", "@version 1.0, 09/07/2012", "@since 2.10", - "@todo this method is unsafe", + "@todo this is unsafe!", "@note Don't inherit!", - "@see some other method" + "@see something else" ) - val comment = "This is a test comment." - val caret = "<caret>" + val names = Seq("Class", "Def", "Val", "Var", "AbstracType", "TypeAlias", "Trait", "InnerClass") + val bareText = + """abstract class %s { + | def %s = "" + | val %s = "" + | var %s: String = _ + | type %s + | type %s = String + | class %s + |} + |trait %s""".stripMargin.format(names: _*) - def text(nTags: Int) = - """|/** %s - | - | * %s */ - |trait Commented {} - |class User(c: %sCommented)""".stripMargin.format(comment, tags take nTags mkString "\n", caret) + def docComment(nTags: Int) = "/**\n%s*/".format(tags.take(nTags).mkString("\n")) + + def text(name: String, nTags: Int) = { + val nameIndex = bareText.indexOf(name) + val (pre, post) = bareText.splitAt(nameIndex) + val crIndex = pre.lastIndexOf("\n") + val (prepre, prepost) = pre.splitAt(crIndex) + prepre + docComment(nTags) + prepost + post + } override lazy val compiler = { prepareSettings(settings) - new Global(settings, compilerReporter) with MemberLookupBase with CommentFactoryBase { + new Global(settings, compilerReporter) with MemberLookupBase with CommentFactoryBase with doc.ScaladocGlobalTrait { outer => + val global: this.type = this override lazy val analyzer = new { val global: outer.type = outer - } with doc.ScaladocAnalyzer + } with doc.ScaladocAnalyzer with InteractiveAnalyzer { + override def newTyper(context: Context): InteractiveTyper with ScaladocTyper = + new Typer(context) with InteractiveTyper with ScaladocTyper + } + + override lazy val loaders = new scala.tools.nsc.symtab.SymbolLoaders { + val global: outer.type = outer + } def chooseLink(links: List[LinkTo]): LinkTo = links.head def internalLink(sym: Symbol, site: Symbol) = None @@ -44,9 +63,9 @@ object Test extends InteractiveTest { override def forScaladoc = true - def getComment(sym: Symbol, source: SourceFile) = { + def getComment(sym: Symbol, source: SourceFile, fragments: List[(Symbol,SourceFile)]): Option[Comment] = { val docResponse = new Response[(String, String, Position)] - askDocComment(sym, sym.owner, source, docResponse) + askDocComment(sym, source, sym.owner, fragments, docResponse) docResponse.get.left.toOption flatMap { case (expanded, raw, pos) => if (expanded.isEmpty) @@ -59,37 +78,74 @@ object Test extends InteractiveTest { } override def runDefaultTests() { - for (i <- 1 to tags.length) { - val markedText = text(i) - val idx = markedText.indexOf(caret) - val fileText = markedText.substring(0, idx) + markedText.substring(idx + caret.length) - val source = sourceFiles(0) - val batch = new BatchSourceFile(source.file, fileText.toCharArray) + import compiler._ + def findSource(name: String) = sourceFiles.find(_.file.name == name).get + + val className = names.head + for (name <- names; + i <- 1 to tags.length) { + val newText = text(name, i) + val source = findSource("Class.scala") + val batch = new BatchSourceFile(source.file, newText.toCharArray) val reloadResponse = new Response[Unit] compiler.askReload(List(batch), reloadResponse) reloadResponse.get.left.toOption match { case None => - reporter.println("Couldn't reload") + println("Couldn't reload") case Some(_) => - val treeResponse = new compiler.Response[compiler.Tree] - val pos = compiler.rangePos(batch, idx, idx, idx) - compiler.askTypeAt(pos, treeResponse) - treeResponse.get.left.toOption match { - case Some(tree) => - val sym = tree.tpe.typeSymbol - compiler.getComment(sym, batch) match { - case None => println("Got no doc comment") + val parseResponse = new Response[Tree] + askParsedEntered(batch, true, parseResponse) + parseResponse.get.left.toOption match { + case None => + println("Couldn't parse") + case Some(_) => + val sym = compiler.ask { () => + val toplevel = definitions.EmptyPackage.info.decl(newTypeName(name)) + if (toplevel eq NoSymbol) { + val clazz = definitions.EmptyPackage.info.decl(newTypeName(className)) + + val term = clazz.info.decl(newTermName(name)) + if (term eq NoSymbol) clazz.info.decl(newTypeName(name)) else + if (term.isAccessor) term.accessed else term + } else toplevel + } + + getComment(sym, batch, (sym,batch)::Nil) match { + case None => println(s"Got no doc comment for $name") case Some(comment) => import comment._ - val tags: List[(String, Iterable[Body])] = - List(("@example", example), ("@version", version), ("@since", since.toList), ("@todo", todo), ("@note", note), ("@see", see)) - val str = ("body:" + body + "\n") + - tags.map{ case (name, bodies) => name + ":" + bodies.mkString("\n") }.mkString("\n") - println(str) + def cnt(bodies: Iterable[Body]) = bodies.size + val actual = cnt(example) + cnt(version) + cnt(since) + cnt(todo) + cnt(note) + cnt(see) + if (actual != i) + println(s"Got docComment with $actual tags instead of $i, file text:\n$newText") } - case None => println("Couldn't find a typedTree") } } } + + // Check inter-classes documentation one-time retrieved ok. + val baseSource = findSource("Base.scala") + val derivedSource = findSource("Derived.scala") + def existsText(where: Any, text: String): Boolean = where match { + case `text` => true + case s: Seq[_] => s exists (existsText(_, text)) + case p: Product => p.productIterator exists (existsText(_, text)) + } + val (derived, base) = compiler.ask { () => + val derived = definitions.RootPackage.info.decl(newTermName("p")).info.decl(newTypeName("Derived")) + (derived, derived.ancestors(0)) + } + val cmt1 = getComment(derived, derivedSource, (base, baseSource)::(derived, derivedSource)::Nil) + if (!existsText(cmt1, "Derived comment.")) + println("Unexpected Derived class comment:"+cmt1) + + val (fooDerived, fooBase) = compiler.ask { () => + val decl = derived.tpe.decl(newTermName("foo")) + (decl, decl.allOverriddenSymbols(0)) + } + + val cmt2 = getComment(fooDerived, derivedSource, (fooBase, baseSource)::(fooDerived, derivedSource)::Nil) + if (!existsText(cmt2, "Base method has documentation.")) + println("Unexpected foo method comment:"+cmt2) } } diff --git a/test/files/presentation/doc/src/Class.scala b/test/files/presentation/doc/src/Class.scala new file mode 100755 index 0000000000..a974bd6f5c --- /dev/null +++ b/test/files/presentation/doc/src/Class.scala @@ -0,0 +1 @@ +object Class
\ No newline at end of file diff --git a/test/files/presentation/doc/src/Test.scala b/test/files/presentation/doc/src/Test.scala deleted file mode 100755 index fcc1554994..0000000000 --- a/test/files/presentation/doc/src/Test.scala +++ /dev/null @@ -1 +0,0 @@ -object Test
\ No newline at end of file diff --git a/test/files/presentation/doc/src/p/Base.scala b/test/files/presentation/doc/src/p/Base.scala new file mode 100755 index 0000000000..9031de3e3e --- /dev/null +++ b/test/files/presentation/doc/src/p/Base.scala @@ -0,0 +1,11 @@ +package p + +/** + * @define BaseComment $BaseVar comment. + */ +trait Base { + /** + * Base method has documentation. + */ + def foo: String +} diff --git a/test/files/presentation/doc/src/p/Derived.scala b/test/files/presentation/doc/src/p/Derived.scala new file mode 100755 index 0000000000..1a9c9a26d1 --- /dev/null +++ b/test/files/presentation/doc/src/p/Derived.scala @@ -0,0 +1,9 @@ +package p + +/** + * $BaseComment + * @define BaseVar Derived + */ +class Derived extends Base { + def foo = "" +} diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check index 0a234e2659..abcc8bf42d 100644 --- a/test/files/run/inline-ex-handlers.check +++ b/test/files/run/inline-ex-handlers.check @@ -14,9 +14,9 @@ < < 2: 247c246 -< blocks: [1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18] +< blocks: [1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,18] --- -> blocks: [1,2,3,4,5,6,8,10,11,12,13,14,15,16,17,18] +> blocks: [1,2,3,4,5,6,8,11,12,13,14,15,16,17,18] 258,260d256 < 92 JUMP 7 < @@ -57,19 +57,18 @@ > ? LOAD_LOCAL(value x5) > 106 CALL_METHOD MyException.message (dynamic) 519c518 -< blocks: [1,2,3,4,6,7,8,9,10] +< blocks: [1,2,3,4,6,7,9,10] --- -> blocks: [1,2,3,4,6,7,8,9,10,11,12,13] -548c547 +> blocks: [1,3,4,6,7,9,10,11,12,13] +548c547,552 < 306 THROW(MyException) --- > ? JUMP 11 -549a549,553 +> > 11: > ? LOAD_LOCAL(variable monitor4) > 305 MONITOR_EXIT > ? JUMP 12 -> 554c558 < ? THROW(Throwable) --- @@ -85,7 +84,13 @@ > 304 MONITOR_EXIT > ? STORE_LOCAL(value t) > ? JUMP 13 -575a587,598 +574c585 +< 310 JUMP 2 +--- +> 300 RETURN(UNIT) +576c587,596 +< 2: +--- > 13: > 310 LOAD_MODULE object Predef > 310 CALL_PRIMITIVE(StartConcat) @@ -96,37 +101,34 @@ > 310 CALL_PRIMITIVE(StringConcat(REF(class String))) > 310 CALL_PRIMITIVE(EndConcat) > 310 CALL_METHOD scala.Predef.println (dynamic) -> 310 JUMP 2 -> -584c607 -< catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6 +584c604 +< catch (Throwable) in ArrayBuffer(7, 9, 10) starting at: 6 --- -> catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6 -587c610 -< catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10) starting at: 3 +> catch (Throwable) in ArrayBuffer(7, 9, 10, 11) starting at: 6 +587c607 +< catch (Throwable) in ArrayBuffer(4, 6, 7, 9, 10) starting at: 3 --- -> catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10, 11, 12) starting at: 3 -619c642 +> catch (Throwable) in ArrayBuffer(4, 6, 7, 9, 10, 11, 12) starting at: 3 +619c639 < blocks: [1,3,4,5,6,8,9] --- > blocks: [1,3,4,5,6,8,9,10,11] -643c666,667 +643c663,669 < 78 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) > ? JUMP 10 -644a669,673 +> > 10: > 81 LOAD_LOCAL(value e) > ? STORE_LOCAL(variable exc1) > ? JUMP 11 -> -669c698,699 +669c695,696 < 81 THROW(Exception) --- > ? STORE_LOCAL(variable exc1) > ? JUMP 11 -685a716,728 +685a713,725 > 11: > 83 LOAD_MODULE object Predef > 83 CONSTANT("finally") @@ -140,19 +142,19 @@ > 84 LOAD_LOCAL(variable exc1) > 84 THROW(Throwable) > -691c734 +691c731 < catch (<none>) in ArrayBuffer(4, 5, 6, 8) starting at: 3 --- > catch (<none>) in ArrayBuffer(4, 5, 6, 8, 10) starting at: 3 -715c758 +715c755 < locals: value args, variable result, value ex6, variable exc2, value x4, value x5, value message, value x, value ex6, value x4, value x5, value message, value x --- > locals: value args, variable result, value ex6, variable exc2, value x4, value x5, value x, value ex6, value x4, value x5, value x -717c760 +717c757 < blocks: [1,3,4,5,6,9,13,14,15,18,20,21,23,24] --- > blocks: [1,3,4,5,6,9,13,14,15,18,20,21,23,24,25,26,27] -741c784,791 +741c781,788 < 172 THROW(MyException) --- > ? STORE_LOCAL(value ex6) @@ -163,64 +165,64 @@ > 170 STORE_LOCAL(value x4) > 170 SCOPE_ENTER value x4 > 170 JUMP 14 -781,784d830 +781,784d827 < 175 LOAD_LOCAL(value x5) < 175 CALL_METHOD MyException.message (dynamic) < 175 STORE_LOCAL(value message) < 175 SCOPE_ENTER value message -786c832,833 +786c829,830 < 176 LOAD_LOCAL(value message) --- > ? LOAD_LOCAL(value x5) > 176 CALL_METHOD MyException.message (dynamic) -790c837,838 +790c834,835 < 177 LOAD_LOCAL(value message) --- > ? LOAD_LOCAL(value x5) > 177 CALL_METHOD MyException.message (dynamic) -792c840,841 +792c837,838 < 177 THROW(MyException) --- > ? STORE_LOCAL(value ex6) > ? JUMP 26 -796c845,846 +796c842,843 < 170 THROW(Throwable) --- > ? STORE_LOCAL(value ex6) > ? JUMP 26 -805a856,861 +805a853,858 > 26: > 169 LOAD_LOCAL(value ex6) > 169 STORE_LOCAL(value x4) > 169 SCOPE_ENTER value x4 > 169 JUMP 5 > -816,819d871 +816,819d868 < 180 LOAD_LOCAL(value x5) < 180 CALL_METHOD MyException.message (dynamic) < 180 STORE_LOCAL(value message) < 180 SCOPE_ENTER value message -821c873,874 +821c870,871 < 181 LOAD_LOCAL(value message) --- > ? LOAD_LOCAL(value x5) > 181 CALL_METHOD MyException.message (dynamic) -825c878,879 +825c875,876 < 182 LOAD_LOCAL(value message) --- > ? LOAD_LOCAL(value x5) > 182 CALL_METHOD MyException.message (dynamic) -827c881,882 +827c878,879 < 182 THROW(MyException) --- > ? STORE_LOCAL(variable exc2) > ? JUMP 27 -831c886,887 +831c883,884 < 169 THROW(Throwable) --- > ? STORE_LOCAL(variable exc2) > ? JUMP 27 -847a904,916 +847a901,913 > 27: > 184 LOAD_MODULE object Predef > 184 CONSTANT("finally") @@ -234,23 +236,23 @@ > 185 LOAD_LOCAL(variable exc2) > 185 THROW(Throwable) > -853c922 +853c919 < catch (Throwable) in ArrayBuffer(13, 14, 15, 18, 20, 21, 23) starting at: 4 --- > catch (Throwable) in ArrayBuffer(13, 14, 15, 18, 20, 21, 23, 25) starting at: 4 -856c925 +856c922 < catch (<none>) in ArrayBuffer(4, 5, 6, 9, 13, 14, 15, 18, 20, 21, 23) starting at: 3 --- > catch (<none>) in ArrayBuffer(4, 5, 6, 9, 13, 14, 15, 18, 20, 21, 23, 25, 26) starting at: 3 -880c949 +880c946 < locals: value args, variable result, value e, value ex6, value x4, value x5, value message, value x --- > locals: value args, variable result, value e, value ex6, value x4, value x5, value x -882c951 +882c948 < blocks: [1,2,3,6,7,8,11,13,14,16] --- > blocks: [1,2,3,6,7,8,11,13,14,16,17] -906c975,982 +906c972,979 < 124 THROW(MyException) --- > ? STORE_LOCAL(value ex6) @@ -261,29 +263,29 @@ > 122 STORE_LOCAL(value x4) > 122 SCOPE_ENTER value x4 > 122 JUMP 7 -931,934d1006 +931,934d1003 < 127 LOAD_LOCAL(value x5) < 127 CALL_METHOD MyException.message (dynamic) < 127 STORE_LOCAL(value message) < 127 SCOPE_ENTER value message -936c1008,1009 +936c1005,1006 < 127 LOAD_LOCAL(value message) --- > ? LOAD_LOCAL(value x5) > 127 CALL_METHOD MyException.message (dynamic) -965c1038 +965c1035 < catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 13, 14, 16) starting at: 3 --- > catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 13, 14, 16, 17) starting at: 3 -989c1062 +989c1059 < locals: value args, variable result, value ex6, value x4, value x5, value message, value x, value e --- > locals: value args, variable result, value ex6, value x4, value x5, value x, value e -991c1064 +991c1061 < blocks: [1,2,3,4,5,8,12,13,14,16] --- > blocks: [1,2,3,5,8,12,13,14,16,17] -1015c1088,1097 +1015c1085,1094 < 148 THROW(MyException) --- > ? STORE_LOCAL(value ex6) @@ -296,25 +298,25 @@ > 154 LOAD_LOCAL(value x4) > 154 IS_INSTANCE REF(class MyException) > 154 CZJUMP (BOOL)NE ? 5 : 8 -1036,1038d1117 +1036,1038d1114 < 145 JUMP 4 < < 4: -1048,1051d1126 +1048,1051d1123 < 154 LOAD_LOCAL(value x5) < 154 CALL_METHOD MyException.message (dynamic) < 154 STORE_LOCAL(value message) < 154 SCOPE_ENTER value message -1053c1128,1129 +1053c1125,1126 < 154 LOAD_LOCAL(value message) --- > ? LOAD_LOCAL(value x5) > 154 CALL_METHOD MyException.message (dynamic) -1270c1346 +1270c1343 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1294c1370,1377 +1294c1367,1374 < 38 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -325,20 +327,20 @@ > 42 CONSTANT("IllegalArgumentException") > 42 CALL_METHOD scala.Predef.println (dynamic) > 42 JUMP 2 -1341c1424 +1341c1421 < locals: value args, variable result, value ex6, value x4, value x5, value message, value x --- > locals: value args, variable result, value ex6, value x4, value x5, value x -1343c1426 +1343c1423 < blocks: [1,2,3,4,5,8,10,11,13,14,16] --- > blocks: [1,2,3,5,8,10,11,13,14,16,17] -1367c1450,1451 +1367c1447,1448 < 203 THROW(MyException) --- > ? STORE_LOCAL(value ex6) > ? JUMP 17 -1387c1471,1480 +1387c1468,1477 < 209 THROW(MyException) --- > ? STORE_LOCAL(value ex6) @@ -351,41 +353,41 @@ > 212 LOAD_LOCAL(value x4) > 212 IS_INSTANCE REF(class MyException) > 212 CZJUMP (BOOL)NE ? 5 : 8 -1400,1402d1492 +1400,1402d1489 < 200 JUMP 4 < < 4: -1412,1415d1501 +1412,1415d1498 < 212 LOAD_LOCAL(value x5) < 212 CALL_METHOD MyException.message (dynamic) < 212 STORE_LOCAL(value message) < 212 SCOPE_ENTER value message -1417c1503,1504 +1417c1500,1501 < 213 LOAD_LOCAL(value message) --- > ? LOAD_LOCAL(value x5) > 213 CALL_METHOD MyException.message (dynamic) -1461c1548 +1461c1545 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1485c1572,1573 +1485c1569,1570 < 58 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) > ? JUMP 8 -1486a1575,1580 +1486a1572,1577 > 8: > 62 LOAD_MODULE object Predef > 62 CONSTANT("RuntimeException") > 62 CALL_METHOD scala.Predef.println (dynamic) > 62 JUMP 2 > -1534c1628 -< blocks: [1,2,3,4] +1534c1625 +< blocks: [1,3,4] --- -> blocks: [1,2,3,4,5] -1554c1648,1653 +> blocks: [1,3,4,5] +1554c1645,1650 < 229 THROW(MyException) --- > ? JUMP 5 @@ -394,19 +396,19 @@ > ? LOAD_LOCAL(variable monitor1) > 228 MONITOR_EXIT > 228 THROW(Throwable) -1560c1659 +1560c1656 < ? THROW(Throwable) --- > 228 THROW(Throwable) -1588c1687 +1588c1684 < locals: value args, variable result, variable monitor2, variable monitorResult1 --- > locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1 -1590c1689 -< blocks: [1,2,3,4] +1590c1686 +< blocks: [1,3,4] --- -> blocks: [1,2,3,4,5] -1613c1712,1720 +> blocks: [1,3,4,5] +1613c1709,1717 < 245 THROW(MyException) --- > ? STORE_LOCAL(value exception$1) @@ -418,7 +420,7 @@ > ? LOAD_LOCAL(variable monitor2) > 244 MONITOR_EXIT > 244 THROW(Throwable) -1619c1726 +1619c1723 < ? THROW(Throwable) --- > 244 THROW(Throwable) diff --git a/test/files/run/t7185.check b/test/files/run/t7185.check new file mode 100644 index 0000000000..f95910ba5f --- /dev/null +++ b/test/files/run/t7185.check @@ -0,0 +1,34 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.tools.reflect.ToolBox +import scala.tools.reflect.ToolBox + +scala> import scala.reflect.runtime.universe._ +import scala.reflect.runtime.universe._ + +scala> object O { def apply() = 0 } +defined object O + +scala> val ORef = reify { O }.tree +ORef: reflect.runtime.universe.Tree = $read.O + +scala> val tree = Apply(Block(Nil, Block(Nil, ORef)), Nil) +tree: reflect.runtime.universe.Apply = +{ + { + $read.O + } +}() + +scala> {val tb = reflect.runtime.currentMirror.mkToolBox(); tb.typeCheck(tree): Any} +res0: Any = +{ + { + $read.O.apply() + } +} + +scala> diff --git a/test/files/run/t7185.scala b/test/files/run/t7185.scala new file mode 100644 index 0000000000..d9d913e78a --- /dev/null +++ b/test/files/run/t7185.scala @@ -0,0 +1,12 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def code = """ +import scala.tools.reflect.ToolBox +import scala.reflect.runtime.universe._ +object O { def apply() = 0 } +val ORef = reify { O }.tree +val tree = Apply(Block(Nil, Block(Nil, ORef)), Nil) +{val tb = reflect.runtime.currentMirror.mkToolBox(); tb.typeCheck(tree): Any} +""" +} diff --git a/test/files/run/t7214.scala b/test/files/run/t7214.scala new file mode 100644 index 0000000000..ff1ea8082d --- /dev/null +++ b/test/files/run/t7214.scala @@ -0,0 +1,57 @@ +// pattern matcher crashes here trying to synthesize an uneeded outer test. +// no-symbol does not have an owner +// at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49) +// at scala.tools.nsc.Global.abort(Global.scala:253) +// at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3248) +// at scala.reflect.internal.Symbols$Symbol.effectiveOwner(Symbols.scala:678) +// at scala.reflect.internal.Symbols$Symbol.isDefinedInPackage(Symbols.scala:664) +// at scala.reflect.internal.TreeGen.mkAttributedSelect(TreeGen.scala:188) +// at scala.reflect.internal.TreeGen.mkAttributedRef(TreeGen.scala:124) +// at scala.tools.nsc.ast.TreeDSL$CODE$.REF(TreeDSL.scala:308) +// at scala.tools.nsc.typechecker.PatternMatching$TreeMakers$TypeTestTreeMaker$treeCondStrategy$.outerTest(PatternMatching.scala:1209) +class Crash { + type Alias = C#T + + val c = new C + val t = new c.T + + // Crash via a Typed Pattern... + (t: Any) match { + case e: Alias => + } + + // ... or via a Typed Extractor Pattern. + object Extractor { + def unapply(a: Alias): Option[Any] = None + } + (t: Any) match { + case Extractor() => + case _ => + } + + // checking that correct outer tests are applied when + // aliases for path dependent types are involved. + val c2 = new C + type CdotT = c.T + type C2dotT = c2.T + + val outerField = t.getClass.getDeclaredFields.find(_.getName contains ("outer")).get + outerField.setAccessible(true) + + (t: Any) match { + case _: C2dotT => + println(s"!!! wrong match. t.outer=${outerField.get(t)} / c2 = $c2") // this matches on 2.10.0 + case _: CdotT => + case _ => + println(s"!!! wrong match. t.outer=${outerField.get(t)} / c = $c") + } +} + +class C { + class T +} + +object Test extends App { + new Crash +} + diff --git a/test/files/run/t7215.scala b/test/files/run/t7215.scala new file mode 100644 index 0000000000..c93e97f9c8 --- /dev/null +++ b/test/files/run/t7215.scala @@ -0,0 +1,6 @@ +object Test extends App { + List[List[Any]]().transpose.isEmpty + Array[Array[Any]]().transpose.isEmpty + Vector[Vector[Any]]().transpose.isEmpty + Stream[Stream[Any]]().transpose.isEmpty +} diff --git a/test/files/run/t7231.check b/test/files/run/t7231.check new file mode 100644 index 0000000000..c1e4b6c175 --- /dev/null +++ b/test/files/run/t7231.check @@ -0,0 +1,2 @@ +null +null diff --git a/test/files/run/t7231.scala b/test/files/run/t7231.scala new file mode 100644 index 0000000000..7d6bc81f3f --- /dev/null +++ b/test/files/run/t7231.scala @@ -0,0 +1,11 @@ +object Test extends App { + val bar: Null = null + + def foo(x: Array[Int]) = x + def baz(x: String) = x + + // first line was failing + println(foo(bar)) + // this line worked but good to have a double check + println(baz(bar)) +}
\ No newline at end of file diff --git a/test/files/run/unreachable.scala b/test/files/run/unreachable.scala new file mode 100644 index 0000000000..50a8d88b7c --- /dev/null +++ b/test/files/run/unreachable.scala @@ -0,0 +1,125 @@ +object Test extends App { + def unreachableNormalExit: Int = { + return 42 + 0 + } + + def unreachableIf: Int = { + return 42 + if (util.Random.nextInt % 2 == 0) + 0 + else + 1 + } + + def unreachableIfBranches: Int = { + if (util.Random.nextInt % 2 == 0) + return 42 + else + return 42 + + return 0 + } + + def unreachableOneLegIf: Int = { + if (util.Random.nextInt % 2 == 0) + return 42 + + return 42 + } + + def unreachableLeftBranch: Int = { + val result = if (util.Random.nextInt % 2 == 0) + return 42 + else + 42 + + return result + } + + def unreachableRightBranch: Int = { + val result = if (util.Random.nextInt % 2 == 0) + 42 + else + return 42 + + return result + } + + def unreachableTryCatchFinally: Int = { + return 42 + try { + return 0 + } catch { + case x: Throwable => return 1 + } finally { + return 2 + } + return 3 + } + + def unreachableAfterTry: Int = { + try { + return 42 + } catch { + case x: Throwable => return 2 + } + return 3 + } + + def unreachableAfterCatch: Int = { + try { + error("haha") + } catch { + case x: Throwable => return 42 + } + return 3 + } + + def unreachableAfterFinally: Int = { + try { + return 1 + } catch { + case x: Throwable => return 2 + } finally { + return 42 + } + return 3 + } + + def unreachableSwitch: Int = { + return 42 + val x = util.Random.nextInt % 2 + x match { + case 0 => return 0 + case 1 => return 1 + case -1 => return 2 + } + 3 + } + + def unreachableAfterSwitch: Int = { + val x = util.Random.nextInt % 2 + x match { + case 0 => return 42 + case 1 => return 41 + x + case -1 => return 43 + x + } + 2 + } + + def check(f: Int) = assert(f == 42, s"Expected 42 but got $f") + + check(unreachableNormalExit) + check(unreachableIf) + check(unreachableIfBranches) + check(unreachableOneLegIf) + check(unreachableLeftBranch) + check(unreachableRightBranch) + check(unreachableTryCatchFinally) + check(unreachableAfterTry) + check(unreachableAfterCatch) + check(unreachableAfterFinally) + check(unreachableSwitch) + check(unreachableAfterSwitch) +}
\ No newline at end of file diff --git a/test/files/run/t5527.check b/test/scaladoc/run/t5527.check index 1518168c51..ab2aeb2d67 100644 --- a/test/files/run/t5527.check +++ b/test/scaladoc/run/t5527.check @@ -1,3 +1,12 @@ +newSource1:17: warning: discarding unmoored doc comment + /** Testing 123 */ + ^ +newSource1:27: warning: discarding unmoored doc comment + /** Calculate this result. */ + ^ +newSource1:34: warning: discarding unmoored doc comment + /** Another digit is a giveaway. */ + ^ [[syntax trees at end of parser]] // newSource1 package <empty> { object UselessComments extends scala.AnyRef { diff --git a/test/files/run/t5527.scala b/test/scaladoc/run/t5527.scala index 2449ff60c3..2449ff60c3 100644 --- a/test/files/run/t5527.scala +++ b/test/scaladoc/run/t5527.scala diff --git a/test/scaladoc/scalacheck/IndexScriptTest.scala b/test/scaladoc/scalacheck/IndexScriptTest.scala index 5aef38e00a..37f6947aaa 100644 --- a/test/scaladoc/scalacheck/IndexScriptTest.scala +++ b/test/scaladoc/scalacheck/IndexScriptTest.scala @@ -35,7 +35,7 @@ object Test extends Properties("IndexScript") { } property("allPackages") = { - createIndexScript("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match { + createIndexScript("src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala") match { case Some(index) => index.allPackages.map(_.toString) == List( "scala", diff --git a/test/scaladoc/scalacheck/IndexTest.scala b/test/scaladoc/scalacheck/IndexTest.scala index bf385898fc..dc4ab126d4 100644 --- a/test/scaladoc/scalacheck/IndexTest.scala +++ b/test/scaladoc/scalacheck/IndexTest.scala @@ -56,7 +56,7 @@ object Test extends Properties("Index") { } property("path") = { - createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match { + createIndex("src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala") match { case Some(index) => index.path == List("index.html") case None => false @@ -64,7 +64,7 @@ object Test extends Properties("Index") { } property("title") = { - createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match { + createIndex("src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala") match { case Some(index) => index.title == "" @@ -72,7 +72,7 @@ object Test extends Properties("Index") { } } property("browser contants a script element") = { - createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match { + createIndex("src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala") match { case Some(index) => (index.browser \ "script").size == 1 diff --git a/tools/stability-test.sh b/tools/stability-test.sh new file mode 100755 index 0000000000..f017ac0842 --- /dev/null +++ b/tools/stability-test.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# + +declare failed + +echo "Comparing build/quick/classes and build/strap/classes" +for dir in library reflect compiler; do + # feel free to replace by a more elegant approach -- don't know how + if diff -rw -x '*.css' \ + -x '*.custom' \ + -x '*.gif' \ + -x '*.js' \ + -x '*.layout' \ + -x '*.png' \ + -x '*.properties' \ + -x '*.tmpl' \ + -x '*.tooltip' \ + -x '*.txt' \ + -x '*.xml' \ + build/{quick,strap}/classes/$dir + then + classes=$(find build/quick/classes/$dir -name '*.class' | wc -l) + printf "%8s: %5d classfiles verified identical\n" $dir $classes + else + failed=true + fi +done + +[[ -z $failed ]] || exit 127 |