summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2012-04-26 15:35:57 -0700
committerSom Snytt <som.snytt@gmail.com>2012-04-26 15:35:57 -0700
commit2a9cce8a6859a34c259d0b399687df3a242de16b (patch)
treeca15e0b069265ff7ec43d147e613bb044f38c91a
parent47bfd744177121de08fed489a5b0b1b59a1ae06a (diff)
parentf7e1a4940386491b0691147b12b1b321c4cce2c5 (diff)
downloadscala-2a9cce8a6859a34c259d0b399687df3a242de16b.tar.gz
scala-2a9cce8a6859a34c259d0b399687df3a242de16b.tar.bz2
scala-2a9cce8a6859a34c259d0b399687df3a242de16b.zip
SI-5543: Merge with trunk
Reverts name unenmanglement that was objectionable in the previous patch commit 47bfd744177121de08fed489a5b0b1b59a1ae06a.
-rw-r--r--build.xml307
-rw-r--r--classpath.SAMPLE5
-rw-r--r--docs/README14
-rw-r--r--docs/development/scala.dbc/SQLTypes.dot48
-rw-r--r--gitignore.SAMPLE5
-rw-r--r--lib/forkjoin.jar.desired.sha12
-rw-r--r--lib/scala-compiler.jar.desired.sha12
-rw-r--r--lib/scala-library-src.jar.desired.sha12
-rw-r--r--lib/scala-library.jar.desired.sha12
-rw-r--r--project/Build.scala16
-rw-r--r--src/actors/scala/actors/Actor.scala8
-rw-r--r--src/actors/scala/actors/Future.scala4
-rw-r--r--src/actors/scala/actors/Reactor.scala4
-rw-r--r--src/build/genprod.scala134
-rw-r--r--src/build/maven/continuations-plugin-pom.xml9
-rw-r--r--src/build/maven/jline-pom.xml9
-rw-r--r--src/build/maven/maven-deploy.xml3
-rw-r--r--src/build/maven/scala-actors-pom.xml9
-rw-r--r--src/build/maven/scala-compiler-pom.xml9
-rw-r--r--src/build/maven/scala-dbc-pom.xml62
-rw-r--r--src/build/maven/scala-dotnet-library-pom.xml9
-rw-r--r--src/build/maven/scala-library-pom.xml38
-rw-r--r--src/build/maven/scala-partest-pom.xml9
-rw-r--r--src/build/maven/scala-swing-pom.xml9
-rw-r--r--src/build/maven/scalap-pom.xml9
-rw-r--r--src/build/pack.xml122
-rw-r--r--src/compiler/scala/reflect/internal/AnnotationInfos.scala18
-rw-r--r--src/compiler/scala/reflect/internal/CapturedVariables.scala36
-rw-r--r--src/compiler/scala/reflect/internal/Constants.scala10
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala652
-rw-r--r--src/compiler/scala/reflect/internal/Flags.scala215
-rw-r--r--src/compiler/scala/reflect/internal/FreeVars.scala60
-rw-r--r--src/compiler/scala/reflect/internal/FrontEnds.scala75
-rw-r--r--src/compiler/scala/reflect/internal/HasFlags.scala181
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala53
-rw-r--r--src/compiler/scala/reflect/internal/JvmClassInfo.scala440
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala215
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala11
-rw-r--r--src/compiler/scala/reflect/internal/Positions.scala38
-rw-r--r--src/compiler/scala/reflect/internal/Required.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Scopes.scala2
-rw-r--r--src/compiler/scala/reflect/internal/StdAttachments.scala10
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala594
-rw-r--r--src/compiler/scala/reflect/internal/SymbolCreations.scala112
-rw-r--r--src/compiler/scala/reflect/internal/SymbolFlags.scala175
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala54
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala1449
-rw-r--r--src/compiler/scala/reflect/internal/TreeBuildUtil.scala66
-rw-r--r--src/compiler/scala/reflect/internal/TreeGen.scala5
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala210
-rw-r--r--src/compiler/scala/reflect/internal/TreePrinters.scala22
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala96
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala404
-rw-r--r--src/compiler/scala/reflect/internal/pickling/UnPickler.scala45
-rw-r--r--src/compiler/scala/reflect/internal/settings/MutableSettings.scala1
-rw-r--r--src/compiler/scala/reflect/internal/transform/Erasure.scala7
-rw-r--r--src/compiler/scala/reflect/internal/transform/UnCurry.scala16
-rw-r--r--src/compiler/scala/reflect/internal/util/Collections.scala45
-rw-r--r--src/compiler/scala/reflect/internal/util/Origins.scala2
-rw-r--r--src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala168
-rw-r--r--src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala6
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Aliases.scala21
-rw-r--r--src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala14
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Context.scala27
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Enclosures.scala23
-rw-r--r--src/compiler/scala/reflect/makro/runtime/FrontEnds.scala44
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Infrastructure.scala34
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Names.scala20
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Reifiers.scala34
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Settings.scala36
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Symbols.scala10
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Traces.scala8
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Typers.scala75
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Util.scala34
-rw-r--r--src/compiler/scala/reflect/makro/util/Traces.scala18
-rw-r--r--src/compiler/scala/reflect/reify/Errors.scala60
-rw-r--r--src/compiler/scala/reflect/reify/NodePrinters.scala111
-rw-r--r--src/compiler/scala/reflect/reify/Phases.scala42
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala164
-rw-r--r--src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala56
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Names.scala15
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Positions.scala18
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Symbols.scala184
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Trees.scala259
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Types.scala168
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Util.scala112
-rw-r--r--src/compiler/scala/reflect/reify/package.scala58
-rw-r--r--src/compiler/scala/reflect/reify/phases/Calculate.scala60
-rw-r--r--src/compiler/scala/reflect/reify/phases/Metalevels.scala150
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reify.scala65
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reshape.scala290
-rw-r--r--src/compiler/scala/reflect/runtime/ClassLoaders.scala25
-rw-r--r--src/compiler/scala/reflect/runtime/ConversionUtil.scala1
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala209
-rw-r--r--src/compiler/scala/reflect/runtime/Memoizer.scala15
-rw-r--r--src/compiler/scala/reflect/runtime/Mirror.scala38
-rw-r--r--src/compiler/scala/reflect/runtime/RuntimeTypes.scala27
-rw-r--r--src/compiler/scala/reflect/runtime/Settings.scala3
-rw-r--r--src/compiler/scala/reflect/runtime/SymbolLoaders.scala (renamed from src/compiler/scala/reflect/runtime/Loaders.scala)7
-rw-r--r--src/compiler/scala/reflect/runtime/SymbolTable.scala23
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedOps.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala69
-rw-r--r--src/compiler/scala/reflect/runtime/ToolBoxes.scala363
-rw-r--r--src/compiler/scala/reflect/runtime/TreeBuildUtil.scala49
-rw-r--r--src/compiler/scala/reflect/runtime/Universe.scala15
-rw-r--r--src/compiler/scala/reflect/runtime/package.scala5
-rw-r--r--src/compiler/scala/tools/ant/ScalaBazaar.scala316
-rw-r--r--src/compiler/scala/tools/ant/ScalaTool.scala3
-rw-r--r--src/compiler/scala/tools/ant/Scaladoc.scala70
-rw-r--r--src/compiler/scala/tools/ant/antlib.xml6
-rw-r--r--src/compiler/scala/tools/cmd/FromString.scala16
-rw-r--r--src/compiler/scala/tools/cmd/gen/AnyVals.scala64
-rw-r--r--src/compiler/scala/tools/cmd/program/DumpClass.scala40
-rw-r--r--src/compiler/scala/tools/nsc/ClassLoaders.scala64
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala22
-rw-r--r--src/compiler/scala/tools/nsc/CompileSocket.scala4
-rw-r--r--src/compiler/scala/tools/nsc/CompilerCommand.scala2
-rw-r--r--src/compiler/scala/tools/nsc/GenericRunnerSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala104
-rw-r--r--src/compiler/scala/tools/nsc/MacroContext.scala10
-rw-r--r--src/compiler/scala/tools/nsc/PhaseAssembly.scala1
-rw-r--r--src/compiler/scala/tools/nsc/Phases.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ReflectGlobal.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ReflectMain.scala11
-rw-r--r--src/compiler/scala/tools/nsc/ToolBoxes.scala83
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala73
-rw-r--r--src/compiler/scala/tools/nsc/ast/FreeVars.scala26
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala81
-rw-r--r--src/compiler/scala/tools/nsc/ast/Positions.scala44
-rw-r--r--src/compiler/scala/tools/nsc/ast/Reifiers.scala761
-rw-r--r--src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala75
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala8
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala60
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala147
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala137
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala53
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala14
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Tokens.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala53
-rw-r--r--src/compiler/scala/tools/nsc/backend/JavaPlatform.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala15
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala65
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala75
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala18
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocFactory.scala22
-rw-r--r--src/compiler/scala/tools/nsc/doc/Settings.scala133
-rw-r--r--src/compiler/scala/tools/nsc/doc/Uncompilable.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala3
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala12
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala8
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Template.scala170
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gifbin0 -> 167 bytes
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.pngbin0 -> 1150 bytes
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.pngbin0 -> 646 bytes
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css125
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js104
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/Entity.scala107
-rwxr-xr-xsrc/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala3
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala120
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala520
-rwxr-xr-xsrc/compiler/scala/tools/nsc/doc/model/TreeFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interactive/BuildManager.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala5
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala5
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala12
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala12
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala117
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala183
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala216
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala14
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/NamedParam.scala15
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Naming.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Phased.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala52
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala57
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplVals.scala35
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/RichClass.scala13
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala161
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/package.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/session/package.scala1
-rw-r--r--src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala6
-rw-r--r--src/compiler/scala/tools/nsc/io/File.scala1
-rw-r--r--src/compiler/scala/tools/nsc/io/Jar.scala1
-rw-r--r--src/compiler/scala/tools/nsc/io/Path.scala1
-rw-r--r--src/compiler/scala/tools/nsc/io/Pickler.scala8
-rw-r--r--src/compiler/scala/tools/nsc/io/package.scala5
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaScanners.scala1
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatchSupport.scala6
-rw-r--r--src/compiler/scala/tools/nsc/matching/Matrix.scala3
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala5
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternBindings.scala3
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala9
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugins.scala4
-rw-r--r--src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala11
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/Executor.scala2
-rw-r--r--src/compiler/scala/tools/nsc/settings/AbsSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/settings/AestheticSettings.scala3
-rw-r--r--src/compiler/scala/tools/nsc/settings/MutableSettings.scala8
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala191
-rw-r--r--src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Positions.scala21
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala18
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTable.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala14
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala6
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala21
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala133
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala15
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala204
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala26
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala26
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala237
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala11
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala356
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Analyzer.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala86
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala54
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala206
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala192
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala91
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala1456
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala201
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala89
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala124
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala124
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Taggings.scala71
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala49
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala71
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala907
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala17
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala14
-rw-r--r--src/compiler/scala/tools/nsc/util/CommandLineParser.scala3
-rw-r--r--src/compiler/scala/tools/nsc/util/Exceptional.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala127
-rw-r--r--src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala12
-rw-r--r--src/compiler/scala/tools/nsc/util/Statistics.scala55
-rw-r--r--src/compiler/scala/tools/nsc/util/package.scala2
-rw-r--r--src/compiler/scala/tools/reflect/Invoked.scala2
-rw-r--r--src/compiler/scala/tools/reflect/UniversalFn.scala4
-rw-r--r--src/compiler/scala/tools/reflect/package.scala22
-rw-r--r--src/compiler/scala/tools/util/StringOps.scala10
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala3
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala4
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala196
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala19
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala47
-rw-r--r--src/dbc/scala/dbc/DataType.scala69
-rw-r--r--src/dbc/scala/dbc/Database.scala187
-rw-r--r--src/dbc/scala/dbc/Syntax.scala47
-rw-r--r--src/dbc/scala/dbc/Utilities.scala28
-rw-r--r--src/dbc/scala/dbc/Value.scala27
-rw-r--r--src/dbc/scala/dbc/Vendor.scala41
-rw-r--r--src/dbc/scala/dbc/datatype/ApproximateNumeric.scala57
-rw-r--r--src/dbc/scala/dbc/datatype/Boolean.scala31
-rw-r--r--src/dbc/scala/dbc/datatype/Character.scala40
-rw-r--r--src/dbc/scala/dbc/datatype/CharacterLargeObject.scala31
-rw-r--r--src/dbc/scala/dbc/datatype/CharacterString.scala24
-rw-r--r--src/dbc/scala/dbc/datatype/CharacterVarying.scala41
-rw-r--r--src/dbc/scala/dbc/datatype/ExactNumeric.scala65
-rw-r--r--src/dbc/scala/dbc/datatype/Factory.scala250
-rw-r--r--src/dbc/scala/dbc/datatype/Numeric.scala32
-rw-r--r--src/dbc/scala/dbc/datatype/String.scala24
-rw-r--r--src/dbc/scala/dbc/datatype/Unknown.scala34
-rw-r--r--src/dbc/scala/dbc/exception/IncompatibleSchema.scala19
-rw-r--r--src/dbc/scala/dbc/package.scala6
-rw-r--r--src/dbc/scala/dbc/result/Field.scala63
-rw-r--r--src/dbc/scala/dbc/result/FieldMetadata.scala40
-rw-r--r--src/dbc/scala/dbc/result/Relation.scala84
-rw-r--r--src/dbc/scala/dbc/result/Status.scala28
-rw-r--r--src/dbc/scala/dbc/result/Tuple.scala42
-rw-r--r--src/dbc/scala/dbc/statement/DerivedColumn.scala38
-rw-r--r--src/dbc/scala/dbc/statement/Expression.scala28
-rw-r--r--src/dbc/scala/dbc/statement/Insert.scala31
-rw-r--r--src/dbc/scala/dbc/statement/InsertionData.scala40
-rw-r--r--src/dbc/scala/dbc/statement/IsolationLevel.scala32
-rw-r--r--src/dbc/scala/dbc/statement/JoinType.scala56
-rw-r--r--src/dbc/scala/dbc/statement/Jointure.scala45
-rw-r--r--src/dbc/scala/dbc/statement/Relation.scala55
-rw-r--r--src/dbc/scala/dbc/statement/Select.scala99
-rw-r--r--src/dbc/scala/dbc/statement/SetQuantifier.scala38
-rw-r--r--src/dbc/scala/dbc/statement/Status.scala32
-rw-r--r--src/dbc/scala/dbc/statement/Table.scala38
-rw-r--r--src/dbc/scala/dbc/statement/Transaction.scala55
-rw-r--r--src/dbc/scala/dbc/statement/Update.scala47
-rw-r--r--src/dbc/scala/dbc/statement/expression/Aggregate.scala35
-rw-r--r--src/dbc/scala/dbc/statement/expression/BinaryOperator.scala33
-rw-r--r--src/dbc/scala/dbc/statement/expression/Constant.scala23
-rw-r--r--src/dbc/scala/dbc/statement/expression/Default.scala22
-rw-r--r--src/dbc/scala/dbc/statement/expression/Field.scala40
-rw-r--r--src/dbc/scala/dbc/statement/expression/FunctionCall.scala33
-rw-r--r--src/dbc/scala/dbc/statement/expression/Select.scala28
-rw-r--r--src/dbc/scala/dbc/statement/expression/SetFunction.scala40
-rw-r--r--src/dbc/scala/dbc/statement/expression/TypeCast.scala32
-rw-r--r--src/dbc/scala/dbc/statement/expression/UnaryOperator.scala33
-rw-r--r--src/dbc/scala/dbc/syntax/DataTypeUtil.scala98
-rw-r--r--src/dbc/scala/dbc/syntax/Database.scala33
-rw-r--r--src/dbc/scala/dbc/syntax/Statement.scala274
-rw-r--r--src/dbc/scala/dbc/syntax/StatementExpression.scala221
-rw-r--r--src/dbc/scala/dbc/value/ApproximateNumeric.scala28
-rw-r--r--src/dbc/scala/dbc/value/Boolean.scala27
-rw-r--r--src/dbc/scala/dbc/value/Character.scala35
-rw-r--r--src/dbc/scala/dbc/value/CharacterLargeObject.scala35
-rw-r--r--src/dbc/scala/dbc/value/CharacterVarying.scala35
-rw-r--r--src/dbc/scala/dbc/value/Conversion.scala156
-rw-r--r--src/dbc/scala/dbc/value/ExactNumeric.scala35
-rw-r--r--src/dbc/scala/dbc/value/Factory.scala95
-rw-r--r--src/dbc/scala/dbc/value/Unknown.scala27
-rw-r--r--src/dbc/scala/dbc/vendor/PostgreSQL.scala29
-rw-r--r--src/detach/library/scala/remoting/Channel.scala32
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java414
-rw-r--r--src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java195
-rw-r--r--src/intellij/dbc.iml.SAMPLE3
-rw-r--r--src/intellij/scala-lang.ipr.SAMPLE1
-rw-r--r--src/library/scala/Array.scala65
-rw-r--r--src/library/scala/Boolean.scala4
-rw-r--r--src/library/scala/Byte.scala211
-rw-r--r--src/library/scala/Char.scala210
-rw-r--r--src/library/scala/Double.scala162
-rw-r--r--src/library/scala/Dynamic.scala2
-rw-r--r--src/library/scala/Either.scala19
-rw-r--r--src/library/scala/Enumeration.scala9
-rw-r--r--src/library/scala/Float.scala163
-rw-r--r--src/library/scala/Function.scala7
-rw-r--r--src/library/scala/Function0.scala2
-rw-r--r--src/library/scala/Function1.scala16
-rw-r--r--src/library/scala/Function2.scala14
-rw-r--r--src/library/scala/Int.scala209
-rw-r--r--src/library/scala/Long.scala208
-rw-r--r--src/library/scala/LowPriorityImplicits.scala1
-rw-r--r--src/library/scala/Option.scala26
-rw-r--r--src/library/scala/PartialFunction.scala134
-rw-r--r--src/library/scala/Predef.scala69
-rw-r--r--src/library/scala/Product1.scala2
-rw-r--r--src/library/scala/Product10.scala2
-rw-r--r--src/library/scala/Product11.scala2
-rw-r--r--src/library/scala/Product12.scala2
-rw-r--r--src/library/scala/Product13.scala2
-rw-r--r--src/library/scala/Product14.scala2
-rw-r--r--src/library/scala/Product15.scala2
-rw-r--r--src/library/scala/Product16.scala2
-rw-r--r--src/library/scala/Product17.scala2
-rw-r--r--src/library/scala/Product18.scala2
-rw-r--r--src/library/scala/Product19.scala2
-rw-r--r--src/library/scala/Product2.scala2
-rw-r--r--src/library/scala/Product20.scala2
-rw-r--r--src/library/scala/Product21.scala2
-rw-r--r--src/library/scala/Product22.scala2
-rw-r--r--src/library/scala/Product3.scala2
-rw-r--r--src/library/scala/Product4.scala2
-rw-r--r--src/library/scala/Product5.scala2
-rw-r--r--src/library/scala/Product6.scala2
-rw-r--r--src/library/scala/Product7.scala2
-rw-r--r--src/library/scala/Product8.scala2
-rw-r--r--src/library/scala/Product9.scala2
-rw-r--r--src/library/scala/ScalaObject.scala (renamed from src/dbc/scala/dbc/statement/Statement.scala)14
-rw-r--r--src/library/scala/Short.scala210
-rw-r--r--src/library/scala/StringContext.scala28
-rw-r--r--src/library/scala/Tuple2.scala106
-rw-r--r--src/library/scala/Tuple3.scala2
-rw-r--r--src/library/scala/Unit.scala4
-rw-r--r--src/library/scala/annotation/ClassfileAnnotation.scala2
-rw-r--r--src/library/scala/annotation/meta/companionClass.scala (renamed from src/dbc/scala/dbc/statement/SetClause.scala)24
-rw-r--r--src/library/scala/annotation/meta/companionMethod.scala17
-rw-r--r--src/library/scala/annotation/meta/companionObject.scala (renamed from src/dbc/scala/dbc/statement/AccessMode.scala)26
-rw-r--r--src/library/scala/annotation/meta/languageFeature.scala (renamed from src/dbc/scala/dbc/exception/UnsupportedFeature.scala)17
-rw-r--r--src/library/scala/annotation/switch.scala4
-rw-r--r--src/library/scala/collection/DefaultMap.scala2
-rw-r--r--src/library/scala/collection/GenSeqLike.scala6
-rw-r--r--src/library/scala/collection/GenTraversableLike.scala6
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala16
-rw-r--r--src/library/scala/collection/IterableLike.scala2
-rw-r--r--src/library/scala/collection/IterableViewLike.scala1
-rw-r--r--src/library/scala/collection/Iterator.scala4
-rw-r--r--src/library/scala/collection/JavaConversions.scala883
-rwxr-xr-xsrc/library/scala/collection/JavaConverters.scala484
-rw-r--r--src/library/scala/collection/SeqExtractors.scala6
-rw-r--r--src/library/scala/collection/SeqLike.scala4
-rw-r--r--src/library/scala/collection/SeqProxyLike.scala2
-rw-r--r--src/library/scala/collection/Traversable.scala2
-rw-r--r--src/library/scala/collection/TraversableLike.scala4
-rw-r--r--src/library/scala/collection/TraversableOnce.scala16
-rw-r--r--src/library/scala/collection/TraversableProxyLike.scala2
-rw-r--r--src/library/scala/collection/TraversableViewLike.scala3
-rw-r--r--src/library/scala/collection/concurrent/BasicNode.java (renamed from src/library/scala/collection/mutable/BasicNode.java)2
-rw-r--r--src/library/scala/collection/concurrent/CNodeBase.java (renamed from src/library/scala/collection/mutable/CNodeBase.java)2
-rw-r--r--src/library/scala/collection/concurrent/Gen.java (renamed from src/library/scala/collection/mutable/Gen.java)2
-rw-r--r--src/library/scala/collection/concurrent/INodeBase.java (renamed from src/library/scala/collection/mutable/INodeBase.java)2
-rw-r--r--src/library/scala/collection/concurrent/MainNode.java (renamed from src/library/scala/collection/mutable/MainNode.java)2
-rw-r--r--src/library/scala/collection/concurrent/Map.scala88
-rw-r--r--src/library/scala/collection/concurrent/TrieMap.scala (renamed from src/library/scala/collection/mutable/ConcurrentTrieMap.scala)120
-rw-r--r--src/library/scala/collection/convert/DecorateAsJava.scala318
-rw-r--r--src/library/scala/collection/convert/DecorateAsScala.scala209
-rw-r--r--src/library/scala/collection/convert/Decorators.scala46
-rw-r--r--src/library/scala/collection/convert/WrapAsJava.scala286
-rw-r--r--src/library/scala/collection/convert/WrapAsScala.scala213
-rw-r--r--src/library/scala/collection/convert/Wrappers.scala469
-rw-r--r--src/library/scala/collection/convert/package.scala18
-rw-r--r--src/library/scala/collection/generic/ArrayTagTraversableFactory.scala (renamed from src/library/scala/collection/generic/ClassManifestTraversableFactory.scala)12
-rw-r--r--src/library/scala/collection/generic/GenMapFactory.scala1
-rw-r--r--src/library/scala/collection/generic/GenSeqFactory.scala1
-rw-r--r--src/library/scala/collection/generic/GenSetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/GenTraversableFactory.scala4
-rw-r--r--src/library/scala/collection/generic/GenericArrayTagCompanion.scala (renamed from src/library/scala/collection/generic/GenericClassManifestCompanion.scala)11
-rw-r--r--src/library/scala/collection/generic/GenericArrayTagTraversableTemplate.scala30
-rw-r--r--src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala25
-rw-r--r--src/library/scala/collection/generic/GenericCompanion.scala1
-rw-r--r--src/library/scala/collection/generic/GenericOrderedCompanion.scala1
-rw-r--r--src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala3
-rw-r--r--src/library/scala/collection/generic/GenericParCompanion.scala1
-rw-r--r--src/library/scala/collection/generic/GenericParTemplate.scala1
-rw-r--r--src/library/scala/collection/generic/GenericSeqCompanion.scala1
-rw-r--r--src/library/scala/collection/generic/GenericSetTemplate.scala2
-rw-r--r--src/library/scala/collection/generic/GenericTraversableTemplate.scala1
-rw-r--r--src/library/scala/collection/generic/ImmutableMapFactory.scala2
-rw-r--r--src/library/scala/collection/generic/ImmutableSetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/ImmutableSortedMapFactory.scala2
-rw-r--r--src/library/scala/collection/generic/ImmutableSortedSetFactory.scala4
-rw-r--r--src/library/scala/collection/generic/MapFactory.scala1
-rw-r--r--src/library/scala/collection/generic/MutableMapFactory.scala1
-rw-r--r--src/library/scala/collection/generic/MutableSetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/MutableSortedSetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/OrderedTraversableFactory.scala4
-rw-r--r--src/library/scala/collection/generic/ParFactory.scala1
-rw-r--r--src/library/scala/collection/generic/ParMapFactory.scala1
-rw-r--r--src/library/scala/collection/generic/ParSetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/SeqFactory.scala1
-rw-r--r--src/library/scala/collection/generic/SetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/SortedMapFactory.scala1
-rw-r--r--src/library/scala/collection/generic/SortedSetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/TraversableFactory.scala1
-rw-r--r--src/library/scala/collection/generic/TraversableForwarder.scala2
-rw-r--r--src/library/scala/collection/generic/package.scala9
-rw-r--r--src/library/scala/collection/immutable/List.scala2
-rw-r--r--src/library/scala/collection/immutable/ListSet.scala4
-rw-r--r--src/library/scala/collection/immutable/NumericRange.scala7
-rw-r--r--src/library/scala/collection/immutable/PagedSeq.scala10
-rw-r--r--src/library/scala/collection/immutable/Stream.scala3
-rw-r--r--src/library/scala/collection/immutable/StringLike.scala19
-rw-r--r--src/library/scala/collection/immutable/TrieIterator.scala2
-rw-r--r--src/library/scala/collection/interfaces/IterableMethods.scala1
-rw-r--r--src/library/scala/collection/interfaces/SeqMethods.scala1
-rw-r--r--src/library/scala/collection/interfaces/SetMethods.scala1
-rw-r--r--src/library/scala/collection/interfaces/TraversableOnceMethods.scala2
-rw-r--r--src/library/scala/collection/mutable/ArrayBuilder.scala27
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala29
-rw-r--r--src/library/scala/collection/mutable/ArrayStack.scala2
-rw-r--r--src/library/scala/collection/mutable/ConcurrentMap.scala1
-rw-r--r--src/library/scala/collection/mutable/FlatArray.scala150
-rw-r--r--src/library/scala/collection/mutable/HashTable.scala2
-rw-r--r--src/library/scala/collection/mutable/IndexedSeqView.scala1
-rw-r--r--src/library/scala/collection/mutable/LinkedHashSet.scala2
-rw-r--r--src/library/scala/collection/mutable/Stack.scala2
-rw-r--r--src/library/scala/collection/mutable/StringBuilder.scala2
-rw-r--r--src/library/scala/collection/mutable/UnrolledBuffer.scala14
-rw-r--r--src/library/scala/collection/mutable/WeakHashMap.scala5
-rw-r--r--src/library/scala/collection/mutable/WrappedArray.scala43
-rw-r--r--src/library/scala/collection/mutable/WrappedArrayBuilder.scala26
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala21
-rw-r--r--src/library/scala/collection/parallel/ParIterableViewLike.scala1
-rw-r--r--src/library/scala/collection/parallel/TaskSupport.scala2
-rw-r--r--src/library/scala/collection/parallel/immutable/ParHashMap.scala4
-rw-r--r--src/library/scala/collection/parallel/immutable/ParHashSet.scala2
-rw-r--r--src/library/scala/collection/parallel/immutable/ParRange.scala2
-rw-r--r--src/library/scala/collection/parallel/immutable/ParVector.scala2
-rw-r--r--src/library/scala/collection/parallel/mutable/ParArray.scala10
-rw-r--r--src/library/scala/collection/parallel/mutable/ParHashMap.scala2
-rw-r--r--src/library/scala/collection/parallel/mutable/ParHashSet.scala2
-rw-r--r--src/library/scala/collection/parallel/mutable/ParTrieMap.scala (renamed from src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala)68
-rw-r--r--src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala2
-rw-r--r--src/library/scala/collection/parallel/package.scala1
-rw-r--r--src/library/scala/concurrent/Awaitable.scala16
-rw-r--r--src/library/scala/concurrent/ConcurrentPackageObject.scala94
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala130
-rw-r--r--src/library/scala/concurrent/Future.scala275
-rw-r--r--src/library/scala/concurrent/FutureTaskRunner.scala2
-rw-r--r--src/library/scala/concurrent/JavaConversions.scala1
-rw-r--r--src/library/scala/concurrent/ManagedBlocker.scala1
-rw-r--r--src/library/scala/concurrent/Promise.scala41
-rw-r--r--src/library/scala/concurrent/TaskRunner.scala2
-rw-r--r--src/library/scala/concurrent/ThreadPoolRunner.scala1
-rw-r--r--src/library/scala/concurrent/ThreadRunner.scala1
-rw-r--r--src/library/scala/concurrent/impl/AbstractPromise.java6
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala169
-rw-r--r--src/library/scala/concurrent/impl/Future.scala131
-rw-r--r--src/library/scala/concurrent/impl/NonFatal.scala37
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala166
-rw-r--r--src/library/scala/concurrent/impl/Unsafe.java32
-rw-r--r--src/library/scala/concurrent/package.scala38
-rw-r--r--src/library/scala/concurrent/util/Duration.scala183
-rw-r--r--src/library/scala/concurrent/util/duration/Classifier.scala9
-rw-r--r--src/library/scala/concurrent/util/duration/IntMult.scala18
-rw-r--r--src/library/scala/concurrent/util/duration/package.scala31
-rw-r--r--src/library/scala/io/BytePickle.scala2
-rw-r--r--src/library/scala/io/Codec.scala1
-rw-r--r--src/library/scala/io/Source.scala2
-rw-r--r--src/library/scala/language.scala124
-rw-r--r--src/library/scala/languageFeature.scala30
-rw-r--r--src/library/scala/math/BigDecimal.scala18
-rw-r--r--src/library/scala/math/BigInt.scala39
-rw-r--r--src/library/scala/math/Fractional.scala2
-rw-r--r--src/library/scala/math/Integral.scala2
-rw-r--r--src/library/scala/math/Numeric.scala6
-rw-r--r--src/library/scala/math/Ordered.scala2
-rw-r--r--src/library/scala/math/Ordering.scala1
-rw-r--r--src/library/scala/parallel/Future.scala3
-rw-r--r--src/library/scala/reflect/ArrayTag.scala25
-rw-r--r--src/library/scala/reflect/ClassManifest.scala43
-rw-r--r--src/library/scala/reflect/ClassTag.scala96
-rw-r--r--src/library/scala/reflect/DummyMirror.scala784
-rw-r--r--src/library/scala/reflect/DynamicProxy.scala74
-rw-r--r--src/library/scala/reflect/ErasureTag.scala23
-rw-r--r--src/library/scala/reflect/Manifest.scala53
-rw-r--r--src/library/scala/reflect/NoManifest.scala3
-rw-r--r--src/library/scala/reflect/OptManifest.scala3
-rw-r--r--src/library/scala/reflect/ReflectionUtils.scala49
-rw-r--r--src/library/scala/reflect/TagInterop.scala34
-rwxr-xr-xsrc/library/scala/reflect/api/AnnotationInfos.scala2
-rw-r--r--src/library/scala/reflect/api/Attachment.scala29
-rw-r--r--src/library/scala/reflect/api/ClassLoaders.scala16
-rw-r--r--src/library/scala/reflect/api/Exprs.scala19
-rw-r--r--src/library/scala/reflect/api/FreeVars.scala42
-rw-r--r--src/library/scala/reflect/api/FrontEnds.scala68
-rw-r--r--src/library/scala/reflect/api/Importers.scala19
-rw-r--r--src/library/scala/reflect/api/Mirror.scala17
-rwxr-xr-xsrc/library/scala/reflect/api/Names.scala8
-rw-r--r--src/library/scala/reflect/api/Positions.scala197
-rw-r--r--src/library/scala/reflect/api/RuntimeTypes.scala20
-rwxr-xr-xsrc/library/scala/reflect/api/Scopes.scala9
-rwxr-xr-xsrc/library/scala/reflect/api/StandardDefinitions.scala140
-rw-r--r--src/library/scala/reflect/api/StandardNames.scala157
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala200
-rw-r--r--src/library/scala/reflect/api/ToolBoxes.scala90
-rw-r--r--src/library/scala/reflect/api/TreeBuildUtil.scala143
-rw-r--r--src/library/scala/reflect/api/TreePrinters.scala6
-rw-r--r--src/library/scala/reflect/api/Trees.scala206
-rw-r--r--src/library/scala/reflect/api/TypeTags.scala254
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala108
-rwxr-xr-xsrc/library/scala/reflect/api/Universe.scala62
-rw-r--r--src/library/scala/reflect/macro/Context.scala36
-rw-r--r--src/library/scala/reflect/makro/Aliases.scala26
-rw-r--r--src/library/scala/reflect/makro/CapturedVariables.scala20
-rw-r--r--src/library/scala/reflect/makro/Context.scala44
-rw-r--r--src/library/scala/reflect/makro/Enclosures.scala53
-rw-r--r--src/library/scala/reflect/makro/FrontEnds.scala39
-rw-r--r--src/library/scala/reflect/makro/Infrastructure.scala73
-rw-r--r--src/library/scala/reflect/makro/Names.scala14
-rw-r--r--src/library/scala/reflect/makro/Reifiers.scala77
-rw-r--r--src/library/scala/reflect/makro/Settings.scala38
-rw-r--r--src/library/scala/reflect/makro/Symbols.scala24
-rw-r--r--src/library/scala/reflect/makro/Typers.scala85
-rw-r--r--src/library/scala/reflect/makro/Util.scala31
-rw-r--r--src/library/scala/reflect/makro/internal/Utils.scala146
-rw-r--r--src/library/scala/reflect/makro/internal/macroImpl.scala5
-rw-r--r--src/library/scala/reflect/package.scala52
-rw-r--r--src/library/scala/runtime/AbstractPartialFunction.scala84
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java363
-rw-r--r--src/library/scala/runtime/RichDouble.scala12
-rw-r--r--src/library/scala/runtime/RichFloat.scala12
-rw-r--r--src/library/scala/runtime/RichFunction1.scala27
-rw-r--r--src/library/scala/runtime/RichFunction2.scala26
-rw-r--r--src/library/scala/runtime/RichLong.scala8
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala36
-rw-r--r--src/library/scala/runtime/Tuple2Zipped.scala109
-rw-r--r--src/library/scala/sys/BooleanProp.scala2
-rw-r--r--src/library/scala/sys/SystemProperties.scala2
-rw-r--r--src/library/scala/sys/process/Process.scala1
-rw-r--r--src/library/scala/testing/Show.scala10
-rw-r--r--src/library/scala/util/Marshal.scala33
-rw-r--r--src/library/scala/util/Random.scala23
-rw-r--r--src/library/scala/util/Sorting.scala16
-rw-r--r--src/library/scala/util/Try.scala53
-rw-r--r--src/library/scala/util/automata/BaseBerrySethi.scala2
-rw-r--r--src/library/scala/util/automata/NondetWordAutom.scala4
-rw-r--r--src/library/scala/util/automata/SubsetConstruction.scala2
-rw-r--r--src/library/scala/util/automata/WordBerrySethi.scala6
-rw-r--r--src/library/scala/util/control/Exception.scala13
-rw-r--r--src/library/scala/util/control/NoStackTrace.scala6
-rw-r--r--src/library/scala/util/matching/Regex.scala58
-rw-r--r--src/library/scala/util/parsing/ast/Binders.scala1
-rw-r--r--src/library/scala/util/parsing/combinator/ImplicitConversions.scala2
-rw-r--r--src/library/scala/util/parsing/combinator/PackratParsers.scala1
-rw-r--r--src/library/scala/util/parsing/combinator/Parsers.scala1
-rw-r--r--src/library/scala/util/parsing/combinator/RegexParsers.scala1
-rw-r--r--src/library/scala/util/parsing/combinator/lexical/Lexical.scala2
-rw-r--r--src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala1
-rw-r--r--src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala1
-rw-r--r--src/library/scala/util/parsing/combinator/testing/RegexTest.scala1
-rwxr-xr-xsrc/library/scala/xml/Elem.scala2
-rw-r--r--src/library/scala/xml/MetaData.scala2
-rw-r--r--src/library/scala/xml/NodeSeq.scala3
-rwxr-xr-xsrc/library/scala/xml/Utility.scala5
-rw-r--r--src/library/scala/xml/dtd/ContentModel.scala4
-rw-r--r--src/library/scala/xml/factory/LoggedNodeFactory.scala4
-rw-r--r--src/library/scala/xml/parsing/ConstructingParser.scala4
-rw-r--r--src/manual/scala/man1/fsc.scala5
-rw-r--r--src/manual/scala/man1/sbaz.scala209
-rw-r--r--src/manual/scala/man1/scala.scala1
-rw-r--r--src/manual/scala/man1/scalac.scala5
-rw-r--r--src/manual/scala/man1/scaladoc.scala1
-rw-r--r--src/manual/scala/man1/scalap.scala1
-rw-r--r--src/manual/scala/tools/docutil/resources/index.html17
-rw-r--r--src/partest/scala/tools/partest/CompilerTest.scala11
-rw-r--r--src/partest/scala/tools/partest/ScaladocModelTest.scala146
-rw-r--r--src/partest/scala/tools/partest/SigTest.scala24
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleFileManager.scala1
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleRunner.scala7
-rw-r--r--src/partest/scala/tools/partest/nest/TestFile.scala4
-rw-r--r--src/partest/scala/tools/partest/nest/Worker.scala16
-rw-r--r--src/scalacheck/org/scalacheck/Arbitrary.scala2
-rw-r--r--src/scalacheck/org/scalacheck/util/Buildable.scala2
-rw-r--r--src/swing/scala/swing/Font.scala.disabled32
-rw-r--r--test/benchmarking/ParHashMap.scala33
-rw-r--r--test/benchmarking/ParVector-reduce.scala33
-rw-r--r--test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala8
-rw-r--r--test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala26
-rw-r--r--test/disabled/continuations-neg/infer0.check (renamed from test/files/continuations-neg/infer0.check)0
-rw-r--r--test/disabled/continuations-neg/infer0.scala (renamed from test/files/continuations-neg/infer0.scala)8
-rw-r--r--test/disabled/jvm/concurrent-future.check (renamed from test/files/jvm/concurrent-future.check)2
-rw-r--r--test/disabled/jvm/concurrent-future.scala (renamed from test/files/jvm/concurrent-future.scala)40
-rw-r--r--test/disabled/presentation/akka.check24
-rw-r--r--test/disabled/presentation/akka/src/akka/actor/Actor.scala4
-rw-r--r--test/disabled/presentation/akka/src/akka/actor/ActorRef.scala16
-rw-r--r--test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala30
-rw-r--r--test/disabled/presentation/akka/src/akka/event/EventHandler.scala4
-rw-r--r--test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala4
-rw-r--r--test/disabled/presentation/akka/src/akka/util/Helpers.scala2
-rw-r--r--test/disabled/presentation/shutdown-deadlock.check (renamed from test/files/presentation/shutdown-deadlock.check)0
-rw-r--r--test/disabled/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala (renamed from test/files/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala)2
-rw-r--r--test/disabled/presentation/shutdown-deadlock/src/arrays.scala (renamed from test/files/presentation/shutdown-deadlock/src/arrays.scala)0
-rw-r--r--test/disabled/presentation/simple-tests.check2
-rw-r--r--test/files/buildmanager/t2559/D.scala6
-rw-r--r--test/files/buildmanager/t2559/t2559.check5
-rw-r--r--test/files/buildmanager/t2650_1/t2650_1.check1
-rw-r--r--test/files/buildmanager/t2657/t2657.check1
-rw-r--r--test/files/codelib/code.jar.desired.sha12
-rw-r--r--test/files/continuations-run/match2.scala2
-rw-r--r--test/files/continuations-run/shift-pct.check25
-rw-r--r--test/files/continuations-run/shift-pct.scala30
-rw-r--r--test/files/continuations-run/z1673.check (renamed from test/pending/run/reify_classfileann_b.check)0
-rw-r--r--test/files/continuations-run/z1673.scala31
-rw-r--r--[-rwxr-xr-x]test/files/jvm/interpreter.check740
-rw-r--r--test/files/jvm/interpreter.scala9
-rw-r--r--test/files/jvm/manifests-new.check58
-rw-r--r--test/files/jvm/manifests-new.scala109
-rw-r--r--test/files/jvm/manifests-old.check (renamed from test/files/jvm/manifests.check)0
-rw-r--r--test/files/jvm/manifests-old.scala (renamed from test/files/jvm/manifests.scala)10
-rw-r--r--test/files/jvm/scala-concurrent-tck.scala382
-rw-r--r--test/files/jvm/serialization-new.check313
-rw-r--r--test/files/jvm/serialization-new.scala651
-rw-r--r--test/files/jvm/serialization.check8
-rw-r--r--test/files/jvm/serialization.scala15
-rw-r--r--test/files/jvm/si5471.check2
-rw-r--r--test/files/jvm/si5471.scala17
-rw-r--r--test/files/macros/Printf.scala39
-rw-r--r--test/files/macros/Test.scala8
-rw-r--r--test/files/macros/macros_v0001.bat40
-rw-r--r--test/files/macros/macros_v0001.sh30
-rw-r--r--test/files/neg/applydynamic_sip.check10
-rw-r--r--test/files/neg/applydynamic_sip.scala10
-rw-r--r--test/files/neg/array-not-seq.check12
-rw-r--r--test/files/neg/checksensible.check200
-rw-r--r--test/files/neg/classtags_contextbound_a.check4
-rw-r--r--test/files/neg/classtags_contextbound_a.scala4
-rw-r--r--test/files/neg/classtags_contextbound_b.check4
-rw-r--r--test/files/neg/classtags_contextbound_b.scala5
-rw-r--r--test/files/neg/classtags_contextbound_c.check4
-rw-r--r--test/files/neg/classtags_contextbound_c.scala5
-rw-r--r--test/files/neg/classtags_dont_use_typetags.check4
-rw-r--r--test/files/neg/classtags_dont_use_typetags.scala3
-rw-r--r--test/files/neg/exhausting.flags2
-rw-r--r--test/files/neg/gadts1.check5
-rw-r--r--test/files/neg/interop_classmanifests_arenot_concretetypetags.check4
-rw-r--r--test/files/neg/interop_classmanifests_arenot_concretetypetags.scala9
-rw-r--r--test/files/neg/interop_classtags_arenot_manifests.check7
-rw-r--r--test/files/neg/interop_classtags_arenot_manifests.scala17
-rw-r--r--test/files/neg/interop_erasuretags_arenot_classmanifests.check4
-rw-r--r--test/files/neg/interop_erasuretags_arenot_classmanifests.scala9
-rw-r--r--test/files/neg/interop_erasuretags_arenot_manifests.check4
-rw-r--r--test/files/neg/interop_erasuretags_arenot_manifests.scala9
-rw-r--r--test/files/neg/interop_typetags_arenot_classmanifests.check4
-rw-r--r--test/files/neg/interop_typetags_arenot_classmanifests.scala9
-rw-r--r--test/files/neg/interop_typetags_arenot_manifests.check4
-rw-r--r--test/files/neg/interop_typetags_arenot_manifests.scala9
-rw-r--r--test/files/neg/macro-argtype-mismatch.flags2
-rw-r--r--test/files/neg/macro-argtype-mismatch/Macros_1.scala3
-rw-r--r--test/files/neg/macro-basic-mamdmi.check5
-rw-r--r--test/files/neg/macro-basic-mamdmi.flags1
-rw-r--r--test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala37
-rw-r--r--test/files/neg/macro-cyclic.check4
-rw-r--r--test/files/neg/macro-cyclic.flags1
-rw-r--r--test/files/neg/macro-cyclic/Impls_Macros_1.scala25
-rw-r--r--test/files/neg/macro-deprecate-idents.check52
-rw-r--r--test/files/neg/macro-deprecate-idents.flags1
-rw-r--r--test/files/neg/macro-deprecate-idents.scala56
-rw-r--r--test/files/neg/macro-invalidimpl-a.check4
-rw-r--r--test/files/neg/macro-invalidimpl-a.flags1
-rw-r--r--test/files/neg/macro-invalidimpl-a/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala9
-rw-r--r--test/files/neg/macro-invalidimpl-b.check4
-rw-r--r--test/files/neg/macro-invalidimpl-b.flags1
-rw-r--r--test/files/neg/macro-invalidimpl-b/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala9
-rw-r--r--test/files/neg/macro-invalidimpl-c.check4
-rw-r--r--test/files/neg/macro-invalidimpl-c.flags1
-rw-r--r--test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala9
-rw-r--r--test/files/neg/macro-invalidimpl-c/Test_2.scala3
-rw-r--r--test/files/neg/macro-invalidimpl-d.check4
-rw-r--r--test/files/neg/macro-invalidimpl-d.flags1
-rw-r--r--test/files/neg/macro-invalidimpl-d/Impls_1.scala7
-rw-r--r--test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala7
-rw-r--r--test/files/neg/macro-invalidimpl-e.check13
-rw-r--r--test/files/neg/macro-invalidimpl-e.flags1
-rw-r--r--test/files/neg/macro-invalidimpl-e/Impls_1.scala6
-rw-r--r--test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala9
-rw-r--r--test/files/neg/macro-invalidimpl-f.check7
-rw-r--r--test/files/neg/macro-invalidimpl-f.flags1
-rw-r--r--test/files/neg/macro-invalidimpl-f/Impls_1.scala11
-rw-r--r--test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala9
-rw-r--r--test/files/neg/macro-invalidimpl-g.check7
-rw-r--r--test/files/neg/macro-invalidimpl-g.flags1
-rw-r--r--test/files/neg/macro-invalidimpl-g/Impls_1.scala11
-rw-r--r--test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidimpl-h.check4
-rw-r--r--test/files/neg/macro-invalidimpl-h.flags1
-rw-r--r--test/files/neg/macro-invalidimpl-h/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidret-nontree.check7
-rw-r--r--test/files/neg/macro-invalidret-nontree.flags1
-rw-r--r--test/files/neg/macro-invalidret-nontree/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidret-nonuniversetree.check7
-rw-r--r--test/files/neg/macro-invalidret-nonuniversetree.flags1
-rw-r--r--test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidshape-a.check6
-rw-r--r--test/files/neg/macro-invalidshape-a.flags1
-rw-r--r--test/files/neg/macro-invalidshape-a/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidshape-a/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidshape-b.check6
-rw-r--r--test/files/neg/macro-invalidshape-b.flags1
-rw-r--r--test/files/neg/macro-invalidshape-b/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidshape-b/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidshape-c.check6
-rw-r--r--test/files/neg/macro-invalidshape-c.flags1
-rw-r--r--test/files/neg/macro-invalidshape-c/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidshape-c/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidshape-d.check8
-rw-r--r--test/files/neg/macro-invalidshape-d.flags1
-rw-r--r--test/files/neg/macro-invalidshape-d/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidshape-d/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-context-bounds.check4
-rw-r--r--test/files/neg/macro-invalidsig-context-bounds.flags1
-rw-r--r--test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala8
-rw-r--r--test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badargc.check7
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badargc.flags1
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badtype.check7
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badtype.flags1
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badvarargs.check7
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badvarargs.flags1
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-ctx-noctx.check7
-rw-r--r--test/files/neg/macro-invalidsig-ctx-noctx.flags1
-rw-r--r--test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-implicit-params.check4
-rw-r--r--test/files/neg/macro-invalidsig-implicit-params.flags1
-rw-r--r--test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala18
-rw-r--r--test/files/neg/macro-invalidsig-implicit-params/Test_2.scala4
-rw-r--r--test/files/neg/macro-invalidsig-params-badargc.check7
-rw-r--r--test/files/neg/macro-invalidsig-params-badargc.flags1
-rw-r--r--test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala9
-rw-r--r--test/files/neg/macro-invalidsig-params-badargc/Test_2.scala (renamed from test/files/neg/macro-noexpand/Test_2.scala)2
-rw-r--r--test/files/neg/macro-invalidsig-params-badtype.check7
-rw-r--r--test/files/neg/macro-invalidsig-params-badtype.flags1
-rw-r--r--test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala9
-rw-r--r--test/files/neg/macro-invalidsig-params-badtype/Test_2.scala (renamed from test/files/neg/macro-argtype-mismatch/Test_2.scala)2
-rw-r--r--test/files/neg/macro-invalidsig-params-badvarargs.check7
-rw-r--r--test/files/neg/macro-invalidsig-params-badvarargs.flags1
-rw-r--r--test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala9
-rw-r--r--test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala4
-rw-r--r--test/files/neg/macro-invalidsig-params-namemismatch.check7
-rw-r--r--test/files/neg/macro-invalidsig-params-namemismatch.flags1
-rw-r--r--test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala9
-rw-r--r--test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala4
-rw-r--r--test/files/neg/macro-invalidsig-tparams-badtype.check7
-rw-r--r--test/files/neg/macro-invalidsig-tparams-badtype.flags1
-rw-r--r--test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-tparams-bounds-a.check4
-rw-r--r--test/files/neg/macro-invalidsig-tparams-bounds-a.flags1
-rw-r--r--test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-tparams-bounds-b.check4
-rw-r--r--test/files/neg/macro-invalidsig-tparams-bounds-b.flags1
-rw-r--r--test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-a.check4
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-a.flags1
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-b.check4
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-b.flags1
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala10
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala11
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-c.check4
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-c.flags1
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala11
-rw-r--r--test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala11
-rw-r--r--test/files/neg/macro-invalidusage-badargs.check6
-rw-r--r--test/files/neg/macro-invalidusage-badargs.flags1
-rw-r--r--test/files/neg/macro-invalidusage-badargs/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidusage-badbounds.check4
-rw-r--r--test/files/neg/macro-invalidusage-badbounds.flags1
-rw-r--r--test/files/neg/macro-invalidusage-badbounds/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidusage-badtargs.check4
-rw-r--r--test/files/neg/macro-invalidusage-badtargs.flags1
-rw-r--r--test/files/neg/macro-invalidusage-badtargs/Impls_1.scala5
-rw-r--r--test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-invalidusage-methodvaluesyntax.check4
-rw-r--r--test/files/neg/macro-invalidusage-methodvaluesyntax.flags1
-rw-r--r--test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala9
-rw-r--r--test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-noexpand.check2
-rw-r--r--test/files/neg/macro-noexpand.flags2
-rw-r--r--test/files/neg/macro-noexpand/Impls_1.scala5
-rw-r--r--test/files/neg/macro-noexpand/Macros_1.scala3
-rw-r--r--test/files/neg/macro-noexpand/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-noncompilertree.flags2
-rw-r--r--test/files/neg/macro-noncompilertree/Macros_1.scala3
-rw-r--r--test/files/neg/macro-nontree.flags2
-rw-r--r--test/files/neg/macro-nontree/Macros_1.scala3
-rw-r--r--test/files/neg/macro-nontypeablebody.check4
-rw-r--r--test/files/neg/macro-nontypeablebody.flags1
-rw-r--r--test/files/neg/macro-nontypeablebody/Impls_1.scala5
-rw-r--r--test/files/neg/macro-nontypeablebody/Macros_Test_2.scala8
-rw-r--r--test/files/neg/macro-override-macro-overrides-abstract-method-a.check5
-rw-r--r--test/files/neg/macro-override-macro-overrides-abstract-method-a.flags1
-rw-r--r--test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala13
-rw-r--r--test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala4
-rw-r--r--test/files/neg/macro-override-macro-overrides-abstract-method-b.check5
-rw-r--r--test/files/neg/macro-override-macro-overrides-abstract-method-b.flags1
-rw-r--r--test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala13
-rw-r--r--test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala4
-rw-r--r--test/files/neg/macro-override-method-overrides-macro.check5
-rw-r--r--test/files/neg/macro-override-method-overrides-macro.flags1
-rw-r--r--test/files/neg/macro-override-method-overrides-macro/Impls_1.scala15
-rw-r--r--test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala15
-rw-r--r--test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check7
-rw-r--r--test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala9
-rw-r--r--test/files/neg/macro-reify-groundtypetag-typeparams-notags.check7
-rw-r--r--test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala9
-rw-r--r--test/files/neg/macro-reify-groundtypetag-usetypetag.check7
-rw-r--r--test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala9
-rw-r--r--test/files/neg/macro-without-xmacros-a.check17
-rw-r--r--test/files/neg/macro-without-xmacros-a/Impls_1.scala18
-rw-r--r--test/files/neg/macro-without-xmacros-a/Macros_2.scala12
-rw-r--r--test/files/neg/macro-without-xmacros-a/Test_3.scala (renamed from test/files/run/macro-basic/Test_2.scala)0
-rw-r--r--test/files/neg/macro-without-xmacros-b.check17
-rw-r--r--test/files/neg/macro-without-xmacros-b/Impls_1.scala18
-rw-r--r--test/files/neg/macro-without-xmacros-b/Macros_2.scala10
-rw-r--r--test/files/neg/macro-without-xmacros-b/Test_3.scala4
-rw-r--r--test/files/neg/override-object-flag.check2
-rw-r--r--test/files/neg/override-object-no.check2
-rw-r--r--test/files/neg/pat_unreachable.flags1
-rw-r--r--test/files/neg/patmat-type-check.check14
-rw-r--r--test/files/neg/patmatexhaust.flags2
-rw-r--r--test/files/neg/reify_ann2a.check4
-rw-r--r--test/files/neg/reify_ann2b.check11
-rw-r--r--test/files/neg/reify_ann2b.scala11
-rw-r--r--test/files/neg/saferJavaConversions.check6
-rw-r--r--test/files/neg/saferJavaConversions.scala20
-rw-r--r--test/files/neg/sealed-java-enums.flags2
-rw-r--r--test/files/neg/switch.flags1
-rw-r--r--test/files/neg/t0418.check5
-rw-r--r--test/files/neg/t112706A.check5
-rw-r--r--test/files/neg/t1878.check5
-rw-r--r--test/files/neg/t2386.check4
-rw-r--r--test/files/neg/t2386.scala3
-rw-r--r--test/files/neg/t2775.check8
-rw-r--r--test/files/neg/t3098.flags2
-rw-r--r--test/files/neg/t3392.check5
-rw-r--r--test/files/neg/t3507-old.check (renamed from test/files/neg/t3507.check)8
-rw-r--r--test/files/neg/t3507-old.scala (renamed from test/files/neg/t3507.scala)0
-rw-r--r--test/files/neg/t3683a.flags2
-rw-r--r--test/files/neg/t3692-new.check (renamed from test/files/neg/t3692.check)8
-rw-r--r--test/files/neg/t3692-new.flags1
-rw-r--r--test/files/neg/t3692-new.scala19
-rw-r--r--test/files/neg/t3692-old.check8
-rw-r--r--test/files/neg/t3692-old.flags1
-rw-r--r--test/files/neg/t3692-old.scala (renamed from test/files/neg/t3692.scala)0
-rw-r--r--test/files/neg/t3816.check2
-rw-r--r--test/files/neg/t4134.check4
-rw-r--r--test/files/neg/t4134.scala30
-rw-r--r--test/files/neg/t418.check5
-rw-r--r--test/files/neg/t4425.check2
-rw-r--r--test/files/neg/t4515.check4
-rw-r--r--test/files/neg/t4987.check4
-rw-r--r--test/files/neg/t4987.scala2
-rw-r--r--test/files/neg/t5063.check4
-rw-r--r--test/files/neg/t5063.scala3
-rw-r--r--test/files/neg/t5067.check8
-rw-r--r--test/files/neg/t5067.scala6
-rw-r--r--test/files/neg/t5334_1.check4
-rw-r--r--test/files/neg/t5334_1.scala8
-rw-r--r--test/files/neg/t5334_2.check4
-rw-r--r--test/files/neg/t5334_2.scala8
-rw-r--r--test/files/neg/t5452-new.check8
-rw-r--r--test/files/neg/t5452-new.scala29
-rw-r--r--test/files/neg/t5452-old.check (renamed from test/files/neg/t5452.check)16
-rw-r--r--test/files/neg/t5452-old.scala (renamed from test/files/neg/t5452.scala)0
-rw-r--r--test/files/neg/t5510.check19
-rw-r--r--test/files/neg/t5510.scala7
-rw-r--r--test/files/neg/t5580a.check6
-rw-r--r--test/files/neg/t5580a.scala11
-rw-r--r--test/files/neg/t5589neg.check5
-rw-r--r--test/files/neg/t5663-badwarneq.check22
-rw-r--r--test/files/neg/t5663-badwarneq.flags1
-rw-r--r--test/files/neg/t5663-badwarneq.scala76
-rw-r--r--test/files/neg/t5666.check10
-rw-r--r--test/files/neg/t5666.scala14
-rw-r--r--test/files/neg/t5689.check7
-rw-r--r--test/files/neg/t5689.flags1
-rw-r--r--test/files/neg/t5689.scala6
-rw-r--r--test/files/neg/t961.check2
-rw-r--r--test/files/neg/tailrec.check6
-rw-r--r--test/files/neg/unreachablechar.flags1
-rw-r--r--test/files/neg/valueclasses.check5
-rw-r--r--test/files/neg/valueclasses.scala23
-rw-r--r--test/files/neg/variances.check19
-rw-r--r--test/files/neg/variances.scala29
-rw-r--r--test/files/pos/contextbounds-implicits-new.scala8
-rw-r--r--test/files/pos/contextbounds-implicits-old.scala (renamed from test/files/pos/contextbounds-implicits.scala)0
-rw-r--r--test/files/pos/generic-sigs.scala4
-rw-r--r--test/files/pos/hkarray.flags2
-rw-r--r--test/files/pos/implicits-new.scala89
-rw-r--r--test/files/pos/implicits-old.scala (renamed from test/files/pos/implicits.scala)0
-rw-r--r--test/files/pos/liftcode_polymorphic.scala4
-rw-r--r--test/files/pos/macro-deprecate-dont-touch-backquotedidents.flags1
-rw-r--r--test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala56
-rw-r--r--test/files/pos/macros.scala8
-rw-r--r--test/files/pos/manifest1-new.scala21
-rw-r--r--test/files/pos/manifest1-old.scala (renamed from test/files/pos/manifest1.scala)0
-rw-r--r--test/files/pos/nothing_manifest_disambig-new.scala10
-rw-r--r--test/files/pos/nothing_manifest_disambig-old.scala (renamed from test/files/pos/nothing_manifest_disambig.scala)0
-rw-r--r--test/files/pos/spec-constr-new.scala7
-rw-r--r--test/files/pos/spec-constr-old.scala (renamed from test/files/pos/spec-constr.scala)0
-rw-r--r--test/files/pos/spec-doubledef-new.scala28
-rw-r--r--test/files/pos/spec-doubledef-old.scala (renamed from test/files/pos/spec-doubledef.scala)0
-rw-r--r--test/files/pos/spec-fields-new.scala10
-rw-r--r--test/files/pos/spec-fields-old.scala (renamed from test/files/pos/spec-fields.scala)0
-rw-r--r--test/files/pos/spec-params-new.scala32
-rw-r--r--test/files/pos/spec-params-old.scala (renamed from test/files/pos/spec-params.scala)0
-rw-r--r--test/files/pos/spec-sparsearray-new.scala24
-rw-r--r--test/files/pos/spec-sparsearray-old.scala (renamed from test/files/pos/spec-sparsearray.scala)0
-rw-r--r--test/files/pos/t1381-new.scala31
-rw-r--r--test/files/pos/t1381-old.scala (renamed from test/files/pos/t1381.scala)0
-rw-r--r--test/files/pos/t1439.flags2
-rw-r--r--test/files/pos/t2795-new.scala17
-rw-r--r--test/files/pos/t2795-old.scala (renamed from test/files/pos/t2795.scala)0
-rw-r--r--test/files/pos/t3272.scala8
-rw-r--r--test/files/pos/t3363-new.scala18
-rw-r--r--[-rwxr-xr-x]test/files/pos/t3363-old.scala (renamed from test/files/pos/t3363.scala)0
-rw-r--r--test/files/pos/t3498-new.scala15
-rw-r--r--test/files/pos/t3498-old.scala (renamed from test/files/pos/t3498.scala)0
-rw-r--r--test/files/pos/t4545.scala14
-rw-r--r--test/files/pos/t4910.scala6
-rw-r--r--test/files/pos/t5223.scala6
-rw-r--r--test/files/pos/t531.scala5
-rw-r--r--test/files/pos/t532.scala5
-rw-r--r--test/files/pos/t5580b.scala19
-rw-r--r--test/files/pos/t5604/ReplConfig.scala53
-rw-r--r--test/files/pos/t5604/ReplReporter.scala30
-rw-r--r--test/files/pos/t5644/BoxesRunTime.java836
-rw-r--r--test/files/pos/t5644/other.scala3
-rw-r--r--test/files/pos/t5706.flags1
-rw-r--r--test/files/pos/t5706.scala10
-rw-r--r--test/files/pos/virtpatmat_alts_subst.flags2
-rw-r--r--test/files/pos/virtpatmat_anonfun_for.flags1
-rw-r--r--test/files/pos/virtpatmat_binding_opt.flags2
-rw-r--r--test/files/pos/virtpatmat_castbinder.flags2
-rw-r--r--test/files/pos/virtpatmat_exist1.flags2
-rw-r--r--test/files/pos/virtpatmat_exist2.flags2
-rw-r--r--test/files/pos/virtpatmat_exist3.flags2
-rw-r--r--test/files/pos/virtpatmat_exist_uncurry.scala6
-rw-r--r--test/files/pos/virtpatmat_gadt_array.flags2
-rw-r--r--test/files/pos/virtpatmat_infer_single_1.flags2
-rw-r--r--test/files/pos/virtpatmat_instof_valuetype.flags2
-rw-r--r--test/files/pos/virtpatmat_obj_in_case.flags2
-rw-r--r--test/files/presentation/callcc-interpreter.check2
-rw-r--r--test/files/presentation/ide-bug-1000531.check2
-rw-r--r--test/files/presentation/memory-leaks.check54
-rw-r--r--test/files/presentation/memory-leaks/MemoryLeaksTest.scala126
-rw-r--r--test/files/presentation/patmat.check36
-rw-r--r--test/files/presentation/patmat.flags3
-rw-r--r--test/files/presentation/patmat/Runner.scala11
-rw-r--r--test/files/presentation/patmat/src/PatMatTests.scala28
-rw-r--r--test/files/run/Meter.check8
-rw-r--r--test/files/run/Meter.scala36
-rw-r--r--test/files/run/MeterCaseClass.check8
-rw-r--r--test/files/run/MeterCaseClass.scala36
-rw-r--r--test/files/run/applydynamic_sip.check22
-rw-r--r--test/files/run/applydynamic_sip.scala58
-rw-r--r--test/files/run/arrayclone-new.scala106
-rw-r--r--test/files/run/arrayclone-old.scala (renamed from test/files/run/arrayclone.scala)0
-rw-r--r--test/files/run/arraytags_basic.check36
-rw-r--r--test/files/run/arraytags_basic.scala22
-rw-r--r--test/files/run/arraytags_core.check48
-rw-r--r--test/files/run/arraytags_core.scala50
-rw-r--r--test/files/run/arraytags_usage.check3
-rw-r--r--test/files/run/arraytags_usage.scala15
-rw-r--r--test/files/run/classtags_contextbound.check1
-rw-r--r--test/files/run/classtags_contextbound.scala5
-rw-r--r--test/files/run/classtags_core.check32
-rw-r--r--test/files/run/classtags_core.scala34
-rw-r--r--test/files/run/classtags_multi.check5
-rw-r--r--test/files/run/classtags_multi.scala7
-rw-r--r--test/files/run/classtags_use_concretetypetags.scala3
-rw-r--r--test/files/run/compiler-asSeenFrom.check36
-rw-r--r--test/files/run/concretetypetags_core.check32
-rw-r--r--test/files/run/concretetypetags_core.scala34
-rw-r--r--test/files/run/concretetypetags_multi.check5
-rw-r--r--test/files/run/concretetypetags_multi.scala7
-rw-r--r--test/files/run/concurrent-map-conversions.scala36
-rw-r--r--test/files/run/constrained-types.check7
-rw-r--r--test/files/run/ctries-new/DumbHash.scala (renamed from test/files/run/ctries/DumbHash.scala)0
-rw-r--r--test/files/run/ctries-new/Wrap.scala (renamed from test/files/run/ctries/Wrap.scala)0
-rw-r--r--test/files/run/ctries-new/concmap.scala (renamed from test/files/run/ctries/concmap.scala)24
-rw-r--r--test/files/run/ctries-new/iterator.scala (renamed from test/files/run/ctries/iterator.scala)20
-rw-r--r--test/files/run/ctries-new/lnode.scala (renamed from test/files/run/ctries/lnode.scala)14
-rw-r--r--test/files/run/ctries-new/main.scala45
-rw-r--r--test/files/run/ctries-new/snapshot.scala (renamed from test/files/run/ctries/snapshot.scala)26
-rw-r--r--test/files/run/ctries-old/DumbHash.scala14
-rw-r--r--test/files/run/ctries-old/Wrap.scala9
-rw-r--r--test/files/run/ctries-old/concmap.scala188
-rw-r--r--test/files/run/ctries-old/iterator.scala289
-rw-r--r--test/files/run/ctries-old/lnode.scala61
-rw-r--r--test/files/run/ctries-old/main.scala (renamed from test/files/run/ctries/main.scala)0
-rw-r--r--test/files/run/ctries-old/snapshot.scala267
-rw-r--r--test/files/run/delay-bad.check47
-rw-r--r--test/files/run/delay-bad.scala77
-rw-r--r--test/files/run/delay-good.check41
-rw-r--r--test/files/run/delay-good.scala77
-rw-r--r--test/files/run/dynamic-proxy.check20
-rw-r--r--test/files/run/dynamic-proxy.flags1
-rw-r--r--test/files/run/dynamic-proxy.scala72
-rw-r--r--test/files/run/erasuretags_abstract.check4
-rw-r--r--test/files/run/erasuretags_abstract.scala9
-rw-r--r--test/files/run/erasuretags_basic.check24
-rw-r--r--test/files/run/erasuretags_basic.scala21
-rw-r--r--test/files/run/erasuretags_core.check32
-rw-r--r--test/files/run/erasuretags_core.scala34
-rw-r--r--test/files/run/erasuretags_usage.scala12
-rw-r--r--test/files/run/existentials-in-compiler.check16
-rw-r--r--test/files/run/existentials3-new.check24
-rw-r--r--test/files/run/existentials3-new.scala78
-rw-r--r--test/files/run/existentials3-old.check (renamed from test/files/run/existentials3.check)44
-rw-r--r--test/files/run/existentials3-old.scala (renamed from test/files/run/existentials3.scala)8
-rw-r--r--test/files/run/finalvar.check6
-rw-r--r--test/files/run/finalvar.flags1
-rw-r--r--test/files/run/finalvar.scala37
-rw-r--r--test/files/run/getClassTest-new.check (renamed from test/files/run/getClassTest.check)0
-rw-r--r--test/files/run/getClassTest-new.scala66
-rw-r--r--test/files/run/getClassTest-old.check18
-rw-r--r--test/files/run/getClassTest-old.scala (renamed from test/files/run/getClassTest.scala)10
-rw-r--r--test/files/run/implicitclasses.scala10
-rw-r--r--test/files/run/inline-ex-handlers.check268
-rw-r--r--test/files/run/inner-parse.check86
-rw-r--r--test/files/run/inner-parse/J_1.java9
-rw-r--r--test/files/run/inner-parse/S_2.scala9
-rw-r--r--test/files/run/inner-parse/S_3.scala12
-rw-r--r--test/files/run/interop_classmanifests_arepartially_typetags.check6
-rw-r--r--test/files/run/interop_classmanifests_arepartially_typetags.scala10
-rw-r--r--test/files/run/interop_classtags_are_classmanifests.check6
-rw-r--r--test/files/run/interop_classtags_are_classmanifests.scala17
-rw-r--r--test/files/run/interop_concretetypetags_are_classmanifests.check3
-rw-r--r--test/files/run/interop_concretetypetags_are_classmanifests.scala9
-rw-r--r--test/files/run/interop_concretetypetags_are_manifests.check3
-rw-r--r--test/files/run/interop_concretetypetags_are_manifests.scala9
-rw-r--r--test/files/run/interop_manifests_are_classtags.check24
-rw-r--r--test/files/run/interop_manifests_are_classtags.scala23
-rw-r--r--test/files/run/interop_manifests_are_concretetypetags.check6
-rw-r--r--test/files/run/interop_manifests_are_concretetypetags.scala10
-rw-r--r--test/files/run/interop_manifests_are_typetags.check6
-rw-r--r--test/files/run/interop_manifests_are_typetags.scala10
-rw-r--r--test/files/run/is-valid-num.scala294
-rw-r--r--test/files/run/lift-and-unlift.scala6
-rw-r--r--test/files/run/macro-abort-fresh.check6
-rw-r--r--test/files/run/macro-abort-fresh.flags1
-rw-r--r--test/files/run/macro-abort-fresh/Macros_1.scala15
-rw-r--r--test/files/run/macro-abort-fresh/Test_2.scala6
-rw-r--r--test/files/run/macro-basic-ma-md-mi.check1
-rw-r--r--test/files/run/macro-basic-ma-md-mi.flags1
-rw-r--r--test/files/run/macro-basic-ma-md-mi/Impls_1.scala21
-rw-r--r--test/files/run/macro-basic-ma-md-mi/Macros_2.scala10
-rw-r--r--test/files/run/macro-basic-ma-md-mi/Test_3.scala4
-rw-r--r--test/files/run/macro-basic-ma-mdmi.check1
-rw-r--r--test/files/run/macro-basic-ma-mdmi.flags1
-rw-r--r--test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala32
-rw-r--r--test/files/run/macro-basic-ma-mdmi/Test_2.scala4
-rw-r--r--test/files/run/macro-basic-mamd-mi.check1
-rw-r--r--test/files/run/macro-basic-mamd-mi.flags1
-rw-r--r--test/files/run/macro-basic-mamd-mi/Impls_1.scala19
-rw-r--r--test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala15
-rw-r--r--test/files/run/macro-basic.check1
-rw-r--r--test/files/run/macro-basic.flags1
-rw-r--r--test/files/run/macro-basic/Macros_1.scala10
-rw-r--r--test/files/run/macro-bodyexpandstoimpl.check1
-rw-r--r--test/files/run/macro-bodyexpandstoimpl.flags1
-rw-r--r--test/files/run/macro-bodyexpandstoimpl/Impls_1.scala12
-rw-r--r--test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-declared-in-annotation.check1
-rw-r--r--test/files/run/macro-declared-in-annotation.flags1
-rw-r--r--test/files/run/macro-declared-in-annotation/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-annotation/Macros_2.scala8
-rw-r--r--test/files/run/macro-declared-in-annotation/Test_3.scala3
-rw-r--r--test/files/run/macro-declared-in-anonymous.check2
-rw-r--r--test/files/run/macro-declared-in-anonymous.flags1
-rw-r--r--test/files/run/macro-declared-in-anonymous/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala4
-rw-r--r--test/files/run/macro-declared-in-block.check2
-rw-r--r--test/files/run/macro-declared-in-block.flags1
-rw-r--r--test/files/run/macro-declared-in-block/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-block/Macros_Test_2.scala6
-rw-r--r--test/files/run/macro-declared-in-class-class.check2
-rw-r--r--test/files/run/macro-declared-in-class-class.flags1
-rw-r--r--test/files/run/macro-declared-in-class-class/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-class-class/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-declared-in-class-object.check2
-rw-r--r--test/files/run/macro-declared-in-class-object.flags1
-rw-r--r--test/files/run/macro-declared-in-class-object/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-class-object/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-declared-in-class.check2
-rw-r--r--test/files/run/macro-declared-in-class.flags1
-rw-r--r--test/files/run/macro-declared-in-class/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-class/Macros_Test_2.scala7
-rw-r--r--test/files/run/macro-declared-in-default-param.check5
-rw-r--r--test/files/run/macro-declared-in-default-param.flags1
-rw-r--r--test/files/run/macro-declared-in-default-param/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-default-param/Macros_Test_2.scala7
-rw-r--r--test/files/run/macro-declared-in-implicit-class.check2
-rw-r--r--test/files/run/macro-declared-in-implicit-class.flags1
-rw-r--r--test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala19
-rw-r--r--test/files/run/macro-declared-in-implicit-class/Test_2.scala4
-rw-r--r--test/files/run/macro-declared-in-method.check2
-rw-r--r--test/files/run/macro-declared-in-method.flags1
-rw-r--r--test/files/run/macro-declared-in-method/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-method/Macros_Test_2.scala8
-rw-r--r--test/files/run/macro-declared-in-object-class.check2
-rw-r--r--test/files/run/macro-declared-in-object-class.flags1
-rw-r--r--test/files/run/macro-declared-in-object-class/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-object-class/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-declared-in-object-object.check2
-rw-r--r--test/files/run/macro-declared-in-object-object.flags1
-rw-r--r--test/files/run/macro-declared-in-object-object/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-object-object/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-declared-in-object.check2
-rw-r--r--test/files/run/macro-declared-in-object.flags1
-rw-r--r--test/files/run/macro-declared-in-object/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-object/Macros_Test_2.scala7
-rw-r--r--test/files/run/macro-declared-in-package-object.check2
-rw-r--r--test/files/run/macro-declared-in-package-object.flags1
-rw-r--r--test/files/run/macro-declared-in-package-object/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-package-object/Macros_Test_2.scala8
-rw-r--r--test/files/run/macro-declared-in-refinement.check2
-rw-r--r--test/files/run/macro-declared-in-refinement.flags1
-rw-r--r--test/files/run/macro-declared-in-refinement/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-refinement/Macros_Test_2.scala6
-rw-r--r--test/files/run/macro-declared-in-trait.check15
-rw-r--r--test/files/run/macro-declared-in-trait.flags1
-rw-r--r--test/files/run/macro-declared-in-trait/Impls_1.scala11
-rw-r--r--test/files/run/macro-declared-in-trait/Macros_Test_2.scala13
-rw-r--r--test/files/run/macro-def-infer-return-type-a.check1
-rw-r--r--test/files/run/macro-def-infer-return-type-a.flags1
-rw-r--r--test/files/run/macro-def-infer-return-type-a/Impls_1.scala5
-rw-r--r--test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala4
-rw-r--r--test/files/run/macro-def-infer-return-type-b.check6
-rw-r--r--test/files/run/macro-def-infer-return-type-b.flags1
-rw-r--r--test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala10
-rw-r--r--test/files/run/macro-def-infer-return-type-b/Test_2.scala6
-rw-r--r--test/files/run/macro-def-infer-return-type-c.check1
-rw-r--r--test/files/run/macro-def-infer-return-type-c.flags1
-rw-r--r--test/files/run/macro-def-infer-return-type-c/Impls_1.scala5
-rw-r--r--test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala4
-rw-r--r--test/files/run/macro-def-path-dependent-a.check1
-rw-r--r--test/files/run/macro-def-path-dependent-a.flags1
-rw-r--r--test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala21
-rw-r--r--test/files/run/macro-def-path-dependent-a/Test_2.scala3
-rw-r--r--test/files/run/macro-def-path-dependent-b.check1
-rw-r--r--test/files/run/macro-def-path-dependent-b.flags1
-rw-r--r--test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala20
-rw-r--r--test/files/run/macro-def-path-dependent-b/Test_2.scala3
-rw-r--r--test/files/run/macro-def-path-dependent-c.check1
-rw-r--r--test/files/run/macro-def-path-dependent-c.flags1
-rw-r--r--test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala20
-rw-r--r--test/files/run/macro-def-path-dependent-c/Test_2.scala3
-rw-r--r--test/files/run/macro-def-path-dependent-d.check1
-rw-r--r--test/files/run/macro-def-path-dependent-d.flags1
-rw-r--r--test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala8
-rw-r--r--test/files/run/macro-def-path-dependent-d/Test_2.scala3
-rw-r--r--test/files/run/macro-expand-implicit-macro-has-implicit.check1
-rw-r--r--test/files/run/macro-expand-implicit-macro-has-implicit.flags1
-rw-r--r--test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala9
-rw-r--r--test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala5
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-implicit.check2
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-implicit.flags1
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala9
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-val.check1
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-val.flags1
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala9
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala5
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-view.check1
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-view.flags1
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala9
-rw-r--r--test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala9
-rw-r--r--test/files/run/macro-expand-multiple-arglists.check1
-rw-r--r--test/files/run/macro-expand-multiple-arglists.flags1
-rw-r--r--test/files/run/macro-expand-multiple-arglists/Impls_1.scala10
-rw-r--r--test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala4
-rw-r--r--test/files/run/macro-expand-nullary-generic.check6
-rw-r--r--test/files/run/macro-expand-nullary-generic.flags1
-rw-r--r--test/files/run/macro-expand-nullary-generic/Impls_1.scala14
-rw-r--r--test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala15
-rw-r--r--test/files/run/macro-expand-nullary-nongeneric.check6
-rw-r--r--test/files/run/macro-expand-nullary-nongeneric.flags1
-rw-r--r--test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala14
-rw-r--r--test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala15
-rw-r--r--test/files/run/macro-expand-overload.check6
-rw-r--r--test/files/run/macro-expand-overload.flags1
-rw-r--r--test/files/run/macro-expand-overload/Impls_1.scala15
-rw-r--r--test/files/run/macro-expand-overload/Macros_Test_2.scala20
-rw-r--r--test/files/run/macro-expand-override.check15
-rw-r--r--test/files/run/macro-expand-override.flags1
-rw-r--r--test/files/run/macro-expand-override/Impls_1.scala15
-rw-r--r--test/files/run/macro-expand-override/Macros_Test_2.scala43
-rw-r--r--test/files/run/macro-expand-recursive.check1
-rw-r--r--test/files/run/macro-expand-recursive.flags1
-rw-r--r--test/files/run/macro-expand-recursive/Impls_1.scala15
-rw-r--r--test/files/run/macro-expand-recursive/Macros_Test_2.scala8
-rw-r--r--test/files/run/macro-expand-tparams-bounds-a.check (renamed from test/pending/run/t5271_1.check)0
-rw-r--r--test/files/run/macro-expand-tparams-bounds-a.flags1
-rw-r--r--test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala5
-rw-r--r--test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala8
-rw-r--r--test/files/run/macro-expand-tparams-bounds-b.check0
-rw-r--r--test/files/run/macro-expand-tparams-bounds-b.flags1
-rw-r--r--test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala7
-rw-r--r--test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-expand-tparams-explicit.check1
-rw-r--r--test/files/run/macro-expand-tparams-explicit.flags1
-rw-r--r--test/files/run/macro-expand-tparams-explicit/Impls_1.scala10
-rw-r--r--test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala4
-rw-r--r--test/files/run/macro-expand-tparams-implicit.check2
-rw-r--r--test/files/run/macro-expand-tparams-implicit.flags1
-rw-r--r--test/files/run/macro-expand-tparams-implicit/Impls_1.scala10
-rw-r--r--test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala5
-rw-r--r--test/files/run/macro-expand-tparams-only-in-impl.flags1
-rw-r--r--test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala5
-rw-r--r--test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala8
-rw-r--r--test/files/run/macro-expand-tparams-optional.check1
-rw-r--r--test/files/run/macro-expand-tparams-optional.flags1
-rw-r--r--test/files/run/macro-expand-tparams-optional/Impls_1.scala9
-rw-r--r--test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala4
-rw-r--r--test/files/run/macro-expand-tparams-prefix-a.check4
-rw-r--r--test/files/run/macro-expand-tparams-prefix-a.flags1
-rw-r--r--test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala10
-rw-r--r--test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-expand-tparams-prefix-b.check2
-rw-r--r--test/files/run/macro-expand-tparams-prefix-b.flags1
-rw-r--r--test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala11
-rw-r--r--test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c1.check3
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c1.flags1
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala12
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala11
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c2.check3
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c2.flags1
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala18
-rw-r--r--test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala5
-rw-r--r--test/files/run/macro-expand-tparams-prefix-d1.check3
-rw-r--r--test/files/run/macro-expand-tparams-prefix-d1.flags1
-rw-r--r--test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala12
-rw-r--r--test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala11
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check4
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags1
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala9
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala10
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check1
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags1
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala13
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala8
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-varargs.check1
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-varargs.flags1
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala13
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala8
-rw-r--r--test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check1
-rw-r--r--test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags1
-rw-r--r--test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala9
-rw-r--r--test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala7
-rw-r--r--test/files/run/macro-expand-varargs-implicit-over-varargs.check1
-rw-r--r--test/files/run/macro-expand-varargs-implicit-over-varargs.flags1
-rw-r--r--test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala13
-rw-r--r--test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala7
-rw-r--r--test/files/run/macro-impl-default-params.check5
-rw-r--r--test/files/run/macro-impl-default-params.flags1
-rw-r--r--test/files/run/macro-impl-default-params/Impls_Macros_1.scala20
-rw-r--r--test/files/run/macro-impl-default-params/Test_2.scala4
-rw-r--r--test/files/run/macro-impl-rename-context.check2
-rw-r--r--test/files/run/macro-impl-rename-context.flags1
-rw-r--r--test/files/run/macro-impl-rename-context/Impls_Macros_1.scala15
-rw-r--r--test/files/run/macro-impl-rename-context/Test_2.scala4
-rw-r--r--test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check5
-rw-r--r--test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags1
-rw-r--r--test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala12
-rw-r--r--test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala6
-rw-r--r--test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check0
-rw-r--r--test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags1
-rw-r--r--test/files/run/macro-invalidret-nontypeable.check3
-rw-r--r--test/files/run/macro-invalidret-nontypeable.flags1
-rw-r--r--test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala13
-rw-r--r--test/files/run/macro-invalidret-nontypeable/Test_2.scala6
-rw-r--r--test/files/run/macro-invalidusage-badret.check5
-rw-r--r--test/files/run/macro-invalidusage-badret.flags1
-rw-r--r--test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala9
-rw-r--r--test/files/run/macro-invalidusage-badret/Test_2.scala6
-rw-r--r--test/files/run/macro-invalidusage-partialapplication.check3
-rw-r--r--test/files/run/macro-invalidusage-partialapplication.flags1
-rw-r--r--test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala14
-rw-r--r--test/files/run/macro-invalidusage-partialapplication/Test_2.scala6
-rw-r--r--test/files/run/macro-openmacros.check3
-rw-r--r--test/files/run/macro-openmacros.flags1
-rw-r--r--test/files/run/macro-openmacros/Impls_Macros_1.scala26
-rw-r--r--test/files/run/macro-openmacros/Test_2.scala3
-rw-r--r--test/files/run/macro-quasiinvalidbody-c.check1
-rw-r--r--test/files/run/macro-quasiinvalidbody-c.flags1
-rw-r--r--test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala9
-rw-r--r--test/files/run/macro-quasiinvalidbody-c/Test_2.scala4
-rw-r--r--test/files/run/macro-range.flags2
-rw-r--r--test/files/run/macro-range/Common_1.scala48
-rw-r--r--test/files/run/macro-range/Expansion_Impossible_2.scala53
-rw-r--r--test/files/run/macro-range/Expansion_Possible_3.scala7
-rw-r--r--test/files/run/macro-range/macro_range_1.scala99
-rw-r--r--test/files/run/macro-range/macro_range_2.scala99
-rw-r--r--test/files/run/macro-reflective-ma-normal-mdmi.check1
-rw-r--r--test/files/run/macro-reflective-ma-normal-mdmi.flags1
-rw-r--r--test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala13
-rw-r--r--test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala5
-rw-r--r--test/files/run/macro-reflective-mamd-normal-mi.check1
-rw-r--r--test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala9
-rw-r--r--test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala17
-rw-r--r--test/files/run/macro-reify-basic.check1
-rw-r--r--test/files/run/macro-reify-basic.flags1
-rw-r--r--test/files/run/macro-reify-basic/Macros_1.scala11
-rw-r--r--test/files/run/macro-reify-basic/Test_2.scala3
-rw-r--r--test/files/run/macro-reify-eval-eval.check1
-rw-r--r--test/files/run/macro-reify-eval-eval.flags1
-rw-r--r--test/files/run/macro-reify-eval-eval/Macros_1.scala12
-rw-r--r--test/files/run/macro-reify-eval-eval/Test_2.scala3
-rw-r--r--test/files/run/macro-reify-eval-outside-reify.check1
-rw-r--r--test/files/run/macro-reify-eval-outside-reify.flags1
-rw-r--r--test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala9
-rw-r--r--test/files/run/macro-reify-eval-outside-reify/Test_2.scala5
-rw-r--r--test/files/run/macro-reify-freevars.check3
-rw-r--r--test/files/run/macro-reify-freevars.flags1
-rw-r--r--test/files/run/macro-reify-freevars/Macros_1.scala19
-rw-r--r--test/files/run/macro-reify-freevars/Test_2.scala9
-rw-r--r--test/files/run/macro-reify-groundtypetag-notypeparams.check2
-rw-r--r--test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala6
-rw-r--r--test/files/run/macro-reify-groundtypetag-typeparams-tags.check2
-rw-r--r--test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala9
-rw-r--r--test/files/run/macro-reify-nested-a.check0
-rw-r--r--test/files/run/macro-reify-nested-a.flags1
-rw-r--r--test/files/run/macro-reify-nested-a/Impls_Macros_1.scala43
-rw-r--r--test/files/run/macro-reify-nested-a/Test_2.scala4
-rw-r--r--test/files/run/macro-reify-nested-b.check0
-rw-r--r--test/files/run/macro-reify-nested-b.flags1
-rw-r--r--test/files/run/macro-reify-nested-b/Impls_Macros_1.scala43
-rw-r--r--test/files/run/macro-reify-nested-b/Test_2.scala4
-rw-r--r--test/files/run/macro-reify-ref-to-packageless.check1
-rw-r--r--test/files/run/macro-reify-ref-to-packageless.flags1
-rw-r--r--test/files/run/macro-reify-ref-to-packageless/Impls_1.scala6
-rw-r--r--test/files/run/macro-reify-ref-to-packageless/Test_2.scala4
-rw-r--r--test/files/run/macro-reify-tagful-a.check1
-rw-r--r--test/files/run/macro-reify-tagful-a.flags1
-rw-r--r--test/files/run/macro-reify-tagful-a/Macros_1.scala11
-rw-r--r--test/files/run/macro-reify-tagful-a/Test_2.scala4
-rw-r--r--test/files/run/macro-reify-tagless-a.check3
-rw-r--r--test/files/run/macro-reify-tagless-a.flags1
-rw-r--r--test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala11
-rw-r--r--test/files/run/macro-reify-tagless-a/Test_2.scala12
-rw-r--r--test/files/run/macro-reify-typetag-notypeparams.check2
-rw-r--r--test/files/run/macro-reify-typetag-notypeparams/Test.scala6
-rw-r--r--test/files/run/macro-reify-typetag-typeparams-notags.check2
-rw-r--r--test/files/run/macro-reify-typetag-typeparams-notags/Test.scala9
-rw-r--r--test/files/run/macro-reify-typetag-typeparams-tags.check2
-rw-r--r--test/files/run/macro-reify-typetag-typeparams-tags/Test.scala9
-rw-r--r--test/files/run/macro-reify-typetag-usegroundtypetag.check2
-rw-r--r--test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala9
-rw-r--r--test/files/run/macro-reify-unreify.check1
-rw-r--r--test/files/run/macro-reify-unreify.flags1
-rw-r--r--test/files/run/macro-reify-unreify/Macros_1.scala19
-rw-r--r--test/files/run/macro-reify-unreify/Test_2.scala3
-rw-r--r--test/files/run/macro-reify-value-outside-reify.check1
-rw-r--r--test/files/run/macro-reify-value-outside-reify.flags1
-rw-r--r--test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala9
-rw-r--r--test/files/run/macro-reify-value-outside-reify/Test_2.scala6
-rw-r--r--test/files/run/macro-repl-basic.check79
-rw-r--r--test/files/run/macro-repl-basic.scala31
-rw-r--r--test/files/run/macro-repl-dontexpand.check5
-rw-r--r--test/files/run/macro-repl-dontexpand.scala7
-rw-r--r--test/files/run/macro-rettype-mismatch.flags2
-rw-r--r--test/files/run/macro-rettype-mismatch/Macros_1.scala3
-rw-r--r--test/files/run/macro-rettype-mismatch/Test_2.scala16
-rw-r--r--test/files/run/macro-settings.check1
-rw-r--r--test/files/run/macro-settings.flags1
-rw-r--r--test/files/run/macro-settings/Impls_Macros_1.scala11
-rw-r--r--test/files/run/macro-settings/Test_2.scala3
-rw-r--r--test/files/run/macro-sip19-revised.check5
-rw-r--r--test/files/run/macro-sip19-revised.flags1
-rw-r--r--test/files/run/macro-sip19-revised/Impls_Macros_1.scala34
-rw-r--r--test/files/run/macro-sip19-revised/Test_2.scala12
-rw-r--r--test/files/run/macro-sip19.check5
-rw-r--r--test/files/run/macro-sip19.flags1
-rw-r--r--test/files/run/macro-sip19/Impls_Macros_1.scala25
-rw-r--r--test/files/run/macro-sip19/Test_2.scala16
-rw-r--r--test/files/run/macro-typecheck-implicitsdisabled.check2
-rw-r--r--test/files/run/macro-typecheck-implicitsdisabled.flags1
-rw-r--r--test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala28
-rw-r--r--test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala4
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled.check5
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled.flags1
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala29
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled/Test_2.scala4
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled2.check5
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled2.flags1
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala29
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled2/Test_2.scala4
-rw-r--r--test/files/run/macro-undetparams-consfromsls.check5
-rw-r--r--test/files/run/macro-undetparams-consfromsls.flags1
-rw-r--r--test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala17
-rw-r--r--test/files/run/macro-undetparams-consfromsls/Test_2.scala7
-rw-r--r--test/files/run/macro-undetparams-implicitval.check1
-rw-r--r--test/files/run/macro-undetparams-implicitval.flags1
-rw-r--r--test/files/run/macro-undetparams-implicitval/Test.scala4
-rw-r--r--test/files/run/macro-undetparams-macroitself.check2
-rw-r--r--test/files/run/macro-undetparams-macroitself.flags1
-rw-r--r--test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala7
-rw-r--r--test/files/run/macro-undetparams-macroitself/Test_2.scala4
-rw-r--r--test/files/run/manifests-new.scala147
-rw-r--r--test/files/run/manifests-old.scala (renamed from test/files/run/manifests.scala)67
-rw-r--r--test/files/run/numbereq.scala35
-rw-r--r--test/files/run/option-fold.check5
-rw-r--r--test/files/run/option-fold.scala19
-rw-r--r--test/files/run/patmat_unapp_abstype-new.check (renamed from test/files/run/patmat_unapp_abstype.check)2
-rw-r--r--test/files/run/patmat_unapp_abstype-new.flags1
-rw-r--r--test/files/run/patmat_unapp_abstype-new.scala83
-rw-r--r--test/files/run/patmat_unapp_abstype-old.check4
-rw-r--r--test/files/run/patmat_unapp_abstype-old.flags1
-rw-r--r--test/files/run/patmat_unapp_abstype-old.scala83
-rw-r--r--test/files/run/patmat_unapp_abstype.scala39
-rw-r--r--test/files/run/phantomValueClass.check1
-rw-r--r--test/files/run/phantomValueClass.scala10
-rw-r--r--test/files/run/primitive-sigs-2-new.check7
-rw-r--r--test/files/run/primitive-sigs-2-new.scala31
-rw-r--r--test/files/run/primitive-sigs-2-old.check (renamed from test/files/run/primitive-sigs-2.check)14
-rw-r--r--test/files/run/primitive-sigs-2-old.scala (renamed from test/files/run/primitive-sigs-2.scala)0
-rw-r--r--test/files/run/reflect-overload.scala16
-rw-r--r--test/files/run/reflection-implClass-new.scala38
-rw-r--r--test/files/run/reflection-implClass-old.scala (renamed from test/files/run/reflection-implClass.scala)4
-rw-r--r--test/files/run/reify-repl-fail-gracefully.check21
-rw-r--r--test/files/run/reify-repl-fail-gracefully.scala10
-rw-r--r--test/files/run/reify_ann1a.check60
-rw-r--r--test/files/run/reify_ann1a.scala11
-rw-r--r--test/files/run/reify_ann1b.check60
-rw-r--r--test/files/run/reify_ann1b.scala11
-rw-r--r--test/files/run/reify_ann2a.check44
-rw-r--r--test/files/run/reify_ann2a.scala (renamed from test/files/neg/reify_ann2a.scala)11
-rw-r--r--test/files/run/reify_ann3.check21
-rw-r--r--test/files/run/reify_ann3.scala19
-rw-r--r--test/files/run/reify_ann4.check32
-rw-r--r--test/files/run/reify_ann4.scala23
-rw-r--r--test/files/run/reify_ann5.check22
-rw-r--r--test/files/run/reify_ann5.scala20
-rw-r--r--test/files/run/reify_anonymous.scala12
-rw-r--r--test/files/run/reify_classfileann_a.check36
-rw-r--r--test/files/run/reify_classfileann_a.scala11
-rw-r--r--test/files/run/reify_classfileann_b.check20
-rw-r--r--test/files/run/reify_classfileann_b.scala (renamed from test/pending/run/reify_classfileann_b.scala)17
-rw-r--r--test/files/run/reify_closure1.scala9
-rw-r--r--test/files/run/reify_closure2a.scala9
-rw-r--r--test/files/run/reify_closure3a.scala9
-rw-r--r--test/files/run/reify_closure4a.scala9
-rw-r--r--test/files/run/reify_closure5a.scala17
-rw-r--r--test/files/run/reify_closure6.scala17
-rw-r--r--test/files/run/reify_closure7.scala17
-rw-r--r--test/files/run/reify_closure8a.scala10
-rw-r--r--test/files/run/reify_closure8b.check3
-rw-r--r--test/files/run/reify_closure8b.scala18
-rw-r--r--test/files/run/reify_closures10.scala10
-rw-r--r--test/files/run/reify_complex.scala12
-rw-r--r--test/files/run/reify_extendbuiltins.scala12
-rw-r--r--test/files/run/reify_for1.scala12
-rw-r--r--test/files/run/reify_fors.flags1
-rw-r--r--test/files/run/reify_fors.scala12
-rw-r--r--test/files/run/reify_generic.scala12
-rw-r--r--test/files/run/reify_generic2.scala12
-rw-r--r--test/files/run/reify_getter.scala11
-rw-r--r--test/files/run/reify_implicits-new.check (renamed from test/files/run/reify_implicits.check)0
-rw-r--r--test/files/run/reify_implicits-new.scala14
-rw-r--r--test/files/run/reify_implicits-old.check1
-rw-r--r--test/files/run/reify_implicits-old.scala (renamed from test/files/run/reify_implicits.scala)12
-rw-r--r--test/files/run/reify_inheritance.scala12
-rw-r--r--test/files/run/reify_inner1.scala12
-rw-r--r--test/files/run/reify_inner2.scala12
-rw-r--r--test/files/run/reify_inner3.scala12
-rw-r--r--test/files/run/reify_inner4.scala12
-rw-r--r--test/files/run/reify_maps.flags1
-rw-r--r--test/files/run/reify_maps.scala12
-rw-r--r--test/files/run/reify_metalevel_breach_+0_refers_to_1.check1
-rw-r--r--test/files/run/reify_metalevel_breach_+0_refers_to_1.scala13
-rw-r--r--test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check1
-rw-r--r--test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala11
-rw-r--r--test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check1
-rw-r--r--test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala15
-rw-r--r--test/files/run/reify_metalevel_breach_-1_refers_to_1.check1
-rw-r--r--test/files/run/reify_metalevel_breach_-1_refers_to_1.scala13
-rw-r--r--test/files/run/reify_nested_inner_refers_to_global.check1
-rw-r--r--test/files/run/reify_nested_inner_refers_to_global.scala14
-rw-r--r--test/files/run/reify_nested_inner_refers_to_local.check1
-rw-r--r--test/files/run/reify_nested_inner_refers_to_local.scala12
-rw-r--r--test/files/run/reify_nested_outer_refers_to_global.check1
-rw-r--r--test/files/run/reify_nested_outer_refers_to_global.scala16
-rw-r--r--test/files/run/reify_nested_outer_refers_to_local.check1
-rw-r--r--test/files/run/reify_nested_outer_refers_to_local.scala16
-rw-r--r--test/files/run/reify_newimpl_01.check1
-rw-r--r--test/files/run/reify_newimpl_01.scala11
-rw-r--r--test/files/run/reify_newimpl_02.check1
-rw-r--r--test/files/run/reify_newimpl_02.scala11
-rw-r--r--test/files/run/reify_newimpl_03.check1
-rw-r--r--test/files/run/reify_newimpl_03.scala11
-rw-r--r--test/files/run/reify_newimpl_04.check1
-rw-r--r--test/files/run/reify_newimpl_04.scala11
-rw-r--r--test/files/run/reify_newimpl_05.check1
-rw-r--r--test/files/run/reify_newimpl_05.scala12
-rw-r--r--test/files/run/reify_newimpl_06.check1
-rw-r--r--test/files/run/reify_newimpl_06.scala11
-rw-r--r--test/files/run/reify_newimpl_09.check1
-rw-r--r--test/files/run/reify_newimpl_09.scala11
-rw-r--r--test/files/run/reify_newimpl_10.check1
-rw-r--r--test/files/run/reify_newimpl_10.scala12
-rw-r--r--test/files/run/reify_newimpl_11.check2
-rw-r--r--test/files/run/reify_newimpl_11.scala17
-rw-r--r--test/files/run/reify_newimpl_12.check1
-rw-r--r--test/files/run/reify_newimpl_12.scala12
-rw-r--r--test/files/run/reify_newimpl_13.check2
-rw-r--r--test/files/run/reify_newimpl_13.scala19
-rw-r--r--test/files/run/reify_newimpl_14.check1
-rw-r--r--test/files/run/reify_newimpl_14.scala14
-rw-r--r--test/files/run/reify_newimpl_15.check1
-rw-r--r--test/files/run/reify_newimpl_15.scala13
-rw-r--r--test/files/run/reify_newimpl_16.check1
-rw-r--r--test/files/run/reify_newimpl_16.scala15
-rw-r--r--test/files/run/reify_newimpl_17.check2
-rw-r--r--test/files/run/reify_newimpl_17.scala18
-rw-r--r--test/files/run/reify_newimpl_18.check1
-rw-r--r--test/files/run/reify_newimpl_18.scala13
-rw-r--r--test/files/run/reify_newimpl_19.check2
-rw-r--r--test/files/run/reify_newimpl_19.scala18
-rw-r--r--test/files/run/reify_newimpl_20.check1
-rw-r--r--test/files/run/reify_newimpl_20.scala14
-rw-r--r--test/files/run/reify_newimpl_21.check1
-rw-r--r--test/files/run/reify_newimpl_21.scala18
-rw-r--r--test/files/run/reify_newimpl_22.check23
-rw-r--r--test/files/run/reify_newimpl_22.scala15
-rw-r--r--test/files/run/reify_newimpl_23.check22
-rw-r--r--test/files/run/reify_newimpl_23.scala14
-rw-r--r--test/files/run/reify_newimpl_24.check24
-rw-r--r--test/files/run/reify_newimpl_24.scala16
-rw-r--r--test/files/run/reify_newimpl_25.check21
-rw-r--r--test/files/run/reify_newimpl_25.scala13
-rw-r--r--test/files/run/reify_newimpl_26.check23
-rw-r--r--test/files/run/reify_newimpl_26.scala13
-rw-r--r--test/files/run/reify_newimpl_27.check1
-rw-r--r--test/files/run/reify_newimpl_27.scala13
-rw-r--r--test/files/run/reify_newimpl_28.check1
-rw-r--r--test/files/run/reify_newimpl_28.scala15
-rw-r--r--test/files/run/reify_newimpl_29.check1
-rw-r--r--test/files/run/reify_newimpl_29.scala13
-rw-r--r--test/files/run/reify_newimpl_30.check1
-rw-r--r--test/files/run/reify_newimpl_30.scala15
-rw-r--r--test/files/run/reify_newimpl_31.check1
-rw-r--r--test/files/run/reify_newimpl_31.scala13
-rw-r--r--test/files/run/reify_newimpl_32.check1
-rw-r--r--test/files/run/reify_newimpl_32.scala15
-rw-r--r--test/files/run/reify_newimpl_33.check1
-rw-r--r--test/files/run/reify_newimpl_33.scala14
-rw-r--r--test/files/run/reify_newimpl_34.check1
-rw-r--r--test/files/run/reify_newimpl_34.scala16
-rw-r--r--test/files/run/reify_newimpl_36.check1
-rw-r--r--test/files/run/reify_newimpl_36.scala14
-rw-r--r--test/files/run/reify_newimpl_37.check1
-rw-r--r--test/files/run/reify_newimpl_37.scala15
-rw-r--r--test/files/run/reify_newimpl_38.check1
-rw-r--r--test/files/run/reify_newimpl_38.scala14
-rw-r--r--test/files/run/reify_newimpl_39.check1
-rw-r--r--test/files/run/reify_newimpl_39.scala15
-rw-r--r--test/files/run/reify_newimpl_40.check1
-rw-r--r--test/files/run/reify_newimpl_40.scala15
-rw-r--r--test/files/run/reify_newimpl_41.check3
-rw-r--r--test/files/run/reify_newimpl_41.scala17
-rw-r--r--test/files/run/reify_newimpl_42.check3
-rw-r--r--test/files/run/reify_newimpl_42.scala16
-rw-r--r--test/files/run/reify_newimpl_43.check2
-rw-r--r--test/files/run/reify_newimpl_43.scala15
-rw-r--r--test/files/run/reify_newimpl_44.check2
-rw-r--r--test/files/run/reify_newimpl_44.scala15
-rw-r--r--test/files/run/reify_newimpl_45.check2
-rw-r--r--test/files/run/reify_newimpl_45.scala12
-rw-r--r--test/files/run/reify_newimpl_47.check1
-rw-r--r--test/files/run/reify_newimpl_47.scala15
-rw-r--r--test/files/run/reify_newimpl_48.check1
-rw-r--r--test/files/run/reify_newimpl_48.scala20
-rw-r--r--test/files/run/reify_newimpl_49.check3
-rw-r--r--test/files/run/reify_newimpl_49.scala15
-rw-r--r--test/files/run/reify_newimpl_50.check3
-rw-r--r--test/files/run/reify_newimpl_50.scala14
-rw-r--r--test/files/run/reify_newimpl_51.check3
-rw-r--r--test/files/run/reify_newimpl_51.scala17
-rw-r--r--test/files/run/reify_newimpl_52.check3
-rw-r--r--test/files/run/reify_newimpl_52.scala17
-rw-r--r--test/files/run/reify_printf.scala11
-rw-r--r--test/files/run/reify_sort.scala12
-rw-r--r--test/files/run/reify_sort1.scala12
-rw-r--r--test/files/run/reify_this.scala25
-rw-r--r--test/files/run/reify_timeofday.scala12
-rw-r--r--test/files/run/reify_typerefs_1a.check1
-rw-r--r--test/files/run/reify_typerefs_1a.scala15
-rw-r--r--test/files/run/reify_typerefs_1b.check1
-rw-r--r--test/files/run/reify_typerefs_1b.scala15
-rw-r--r--test/files/run/reify_typerefs_2a.check1
-rw-r--r--test/files/run/reify_typerefs_2a.scala17
-rw-r--r--test/files/run/reify_typerefs_2b.check1
-rw-r--r--test/files/run/reify_typerefs_2b.scala17
-rw-r--r--test/files/run/reify_typerefs_3a.check1
-rw-r--r--test/files/run/reify_typerefs_3a.scala17
-rw-r--r--test/files/run/reify_typerefs_3b.check1
-rw-r--r--test/files/run/reify_typerefs_3b.scala17
-rw-r--r--test/files/run/reify_varargs.scala12
-rw-r--r--test/files/run/repl-colon-type.check173
-rw-r--r--test/files/run/repl-colon-type.scala8
-rw-r--r--test/files/run/repl-parens.check2
-rw-r--r--test/files/run/repl-parens.scala4
-rw-r--r--test/files/run/repl-power.check64
-rw-r--r--test/files/run/repl-power.scala3
-rw-r--r--test/files/run/repl-reset.check2
-rw-r--r--test/files/run/repl-suppressed-warnings.scala1
-rw-r--r--test/files/run/repl-type-verbose.check186
-rw-r--r--test/files/run/repl-type-verbose.scala20
-rw-r--r--test/files/run/si4750.check1
-rw-r--r--test/files/run/si4750.scala7
-rw-r--r--test/files/run/t0421-new.check (renamed from test/files/run/t0421.check)0
-rw-r--r--test/files/run/t0421-new.scala30
-rw-r--r--test/files/run/t0421-old.check3
-rw-r--r--test/files/run/t0421-old.scala (renamed from test/files/run/t0421.scala)0
-rw-r--r--test/files/run/t0677-new.scala8
-rw-r--r--test/files/run/t0677-old.scala (renamed from test/files/run/t0677.scala)0
-rw-r--r--test/files/run/t1195-new.check6
-rw-r--r--test/files/run/t1195-new.scala26
-rw-r--r--test/files/run/t1195-old.check (renamed from test/files/run/t1195.check)12
-rw-r--r--test/files/run/t1195-old.scala (renamed from test/files/run/t1195.scala)2
-rw-r--r--test/files/run/t2236-new.scala17
-rw-r--r--[-rwxr-xr-x]test/files/run/t2236-old.scala (renamed from test/files/run/t2236.scala)0
-rw-r--r--test/files/run/t2386-new.check2
-rw-r--r--test/files/run/t2386-new.scala5
-rw-r--r--test/files/run/t2886.check10
-rw-r--r--test/files/run/t2886.scala9
-rw-r--r--test/files/run/t3507-new.check1
-rw-r--r--test/files/run/t3507-new.scala15
-rw-r--r--test/files/run/t3569.check10
-rw-r--r--test/files/run/t3758-old.scala (renamed from test/files/run/t3758.scala)2
-rw-r--r--test/files/run/t3835.scala9
-rw-r--r--test/files/run/t4110-new.check2
-rw-r--r--test/files/run/t4110-new.scala11
-rw-r--r--test/files/run/t4110-old.check (renamed from test/files/run/t4110.check)0
-rw-r--r--test/files/run/t4110-old.scala (renamed from test/files/run/t4110.scala)2
-rw-r--r--test/files/run/t4172.check2
-rw-r--r--test/files/run/t4317/S_1.scala2
-rw-r--r--test/files/run/t4658.check12
-rw-r--r--test/files/run/t4658.scala14
-rw-r--r--test/files/run/t4710.check1
-rw-r--r--test/files/run/t5224.check18
-rw-r--r--test/files/run/t5224.scala5
-rw-r--r--test/files/run/t5225_1.check8
-rw-r--r--test/files/run/t5225_1.scala5
-rw-r--r--test/files/run/t5225_2.check8
-rw-r--r--test/files/run/t5225_2.scala5
-rw-r--r--test/files/run/t5229_1.scala12
-rw-r--r--test/files/run/t5229_2.scala9
-rw-r--r--test/files/run/t5230.scala9
-rw-r--r--test/files/run/t5258a.scala13
-rw-r--r--test/files/run/t5266_1.scala9
-rw-r--r--test/files/run/t5266_2.scala9
-rw-r--r--test/files/run/t5269.scala12
-rw-r--r--test/files/run/t5270.scala12
-rw-r--r--test/files/run/t5271_1.check23
-rw-r--r--test/files/run/t5271_1.scala10
-rw-r--r--test/files/run/t5271_2.check26
-rw-r--r--test/files/run/t5271_2.scala10
-rw-r--r--test/files/run/t5271_3.check40
-rw-r--r--test/files/run/t5271_3.scala10
-rw-r--r--test/files/run/t5271_4.scala12
-rw-r--r--test/files/run/t5272_1.flags1
-rw-r--r--test/files/run/t5272_1.scala12
-rw-r--r--test/files/run/t5272_2.flags1
-rw-r--r--test/files/run/t5272_2.scala12
-rw-r--r--test/files/run/t5273_1.flags1
-rw-r--r--test/files/run/t5273_1.scala12
-rw-r--r--test/files/run/t5273_2a.flags1
-rw-r--r--test/files/run/t5273_2a.scala12
-rw-r--r--test/files/run/t5273_2b.flags1
-rw-r--r--test/files/run/t5273_2b.scala12
-rw-r--r--test/files/run/t5274_1.scala12
-rw-r--r--test/files/run/t5274_2.scala12
-rw-r--r--test/files/run/t5275.scala12
-rw-r--r--test/files/run/t5276_1a.scala12
-rw-r--r--test/files/run/t5276_1b.scala12
-rw-r--r--test/files/run/t5276_2a.scala12
-rw-r--r--test/files/run/t5276_2b.scala12
-rw-r--r--test/files/run/t5277_1.scala12
-rw-r--r--test/files/run/t5277_2.scala12
-rw-r--r--test/files/run/t5279.scala12
-rw-r--r--test/files/run/t5334_1.scala12
-rw-r--r--test/files/run/t5334_2.scala12
-rw-r--r--test/files/run/t5335.scala12
-rw-r--r--test/files/run/t5415.scala10
-rw-r--r--test/files/run/t5419.check2
-rw-r--r--test/files/run/t5419.scala5
-rw-r--r--test/files/run/t5423.scala3
-rw-r--r--test/files/run/t5535.check20
-rw-r--r--test/files/run/t5535.scala10
-rw-r--r--test/files/run/t5583.check20
-rw-r--r--test/files/run/t5583.scala11
-rw-r--r--test/files/run/t5614.check3
-rw-r--r--test/files/run/t5614.flags1
-rw-r--r--test/files/run/t5614.scala5
-rw-r--r--test/files/run/t5648.check4
-rw-r--r--test/files/run/t5648.flags1
-rw-r--r--test/files/run/t5648.scala10
-rw-r--r--test/files/run/t5680.check3
-rw-r--r--test/files/run/t5680.scala7
-rw-r--r--test/files/run/t5704.check1
-rw-r--r--test/files/run/t5704.flags1
-rw-r--r--test/files/run/t5704.scala16
-rw-r--r--test/files/run/toolbox_console_reporter.check0
-rw-r--r--test/files/run/toolbox_console_reporter.scala16
-rw-r--r--test/files/run/toolbox_default_reporter_is_silent.check1
-rw-r--r--test/files/run/toolbox_default_reporter_is_silent.scala13
-rw-r--r--test/files/run/toolbox_silent_reporter.check4
-rw-r--r--test/files/run/toolbox_silent_reporter.scala16
-rw-r--r--test/files/run/toolbox_typecheck_implicitsdisabled.check5
-rw-r--r--test/files/run/toolbox_typecheck_implicitsdisabled.scala24
-rw-r--r--test/files/run/toolbox_typecheck_macrosdisabled.check5
-rw-r--r--test/files/run/toolbox_typecheck_macrosdisabled.scala17
-rw-r--r--test/files/run/toolbox_typecheck_macrosdisabled2.check5
-rw-r--r--test/files/run/toolbox_typecheck_macrosdisabled2.scala17
-rw-r--r--test/files/run/treePrint.scala11
-rw-r--r--test/files/run/tuple-zipped.scala2
-rw-r--r--test/files/run/typetags_core.check32
-rw-r--r--test/files/run/typetags_core.scala34
-rw-r--r--test/files/run/typetags_multi.check5
-rw-r--r--test/files/run/typetags_multi.scala7
-rw-r--r--test/files/run/valueclasses-constr.check10
-rw-r--r--test/files/run/valueclasses-constr.scala84
-rw-r--r--test/files/run/virtpatmat_alts.flags2
-rw-r--r--test/files/run/virtpatmat_apply.flags2
-rw-r--r--test/files/run/virtpatmat_casting.flags2
-rw-r--r--test/files/run/virtpatmat_extends_product.flags2
-rw-r--r--test/files/run/virtpatmat_literal.flags2
-rw-r--r--test/files/run/virtpatmat_nested_lists.flags2
-rw-r--r--test/files/run/virtpatmat_npe.flags2
-rw-r--r--test/files/run/virtpatmat_opt_sharing.flags2
-rw-r--r--test/files/run/virtpatmat_partial.flags2
-rw-r--r--test/files/run/virtpatmat_partial_backquoted.check1
-rw-r--r--test/files/run/virtpatmat_partial_backquoted.scala12
-rw-r--r--test/files/run/virtpatmat_staging.flags2
-rw-r--r--test/files/run/virtpatmat_stringinterp.check1
-rw-r--r--test/files/run/virtpatmat_stringinterp.flags (renamed from test/files/pos/annotDepMethType.flags)0
-rw-r--r--test/files/run/virtpatmat_stringinterp.scala13
-rw-r--r--test/files/run/virtpatmat_switch.flags2
-rw-r--r--test/files/run/virtpatmat_tailcalls_verifyerror.check1
-rw-r--r--test/files/run/virtpatmat_tailcalls_verifyerror.flags1
-rw-r--r--test/files/run/virtpatmat_tailcalls_verifyerror.scala14
-rw-r--r--test/files/run/virtpatmat_try.flags2
-rw-r--r--test/files/run/virtpatmat_typed.flags2
-rw-r--r--test/files/run/virtpatmat_unapply.flags2
-rw-r--r--test/files/run/virtpatmat_unapplyprod.flags2
-rw-r--r--test/files/run/virtpatmat_unapplyseq.flags2
-rw-r--r--test/files/run/virtpatmat_valdef.check1
-rw-r--r--test/files/run/virtpatmat_valdef.scala6
-rw-r--r--test/files/scalacheck/Ctrie.scala14
-rw-r--r--test/files/scalacheck/array-new.scala36
-rw-r--r--test/files/scalacheck/array-old.scala (renamed from test/files/scalacheck/array.scala)0
-rw-r--r--test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala8
-rw-r--r--test/files/scalacheck/t2460.scala32
-rw-r--r--test/files/scalap/caseClass/result.test6
-rw-r--r--test/files/specialized/spec-matrix-new.check (renamed from test/files/specialized/spec-matrix.check)0
-rw-r--r--test/files/specialized/spec-matrix-new.scala80
-rw-r--r--test/files/specialized/spec-matrix-old.check2
-rw-r--r--test/files/specialized/spec-matrix-old.scala (renamed from test/files/specialized/spec-matrix.scala)0
-rw-r--r--test/files/specialized/spec-patmatch.check2
-rw-r--r--test/files/speclib/instrumented.jar.desired.sha12
-rw-r--r--test/instrumented/boxes.patch40
-rw-r--r--test/instrumented/library/scala/runtime/BoxesRunTime.java384
-rw-r--r--test/instrumented/library/scala/runtime/ScalaRunTime.scala93
-rw-r--r--test/instrumented/srt.patch17
-rw-r--r--test/pending/neg/reify_packed.check4
-rw-r--r--test/pending/neg/reify_packed.scala10
-rw-r--r--test/pending/pos/inference.scala20
-rw-r--r--test/pending/pos/t1476.scala23
-rw-r--r--test/pending/pos/t5626.scala12
-rw-r--r--test/pending/run/implicit-classes.scala17
-rw-r--r--test/pending/run/macro-expand-default.flags (renamed from test/files/pos/macros.flags)0
-rw-r--r--test/pending/run/macro-expand-default/Impls_1.scala10
-rw-r--r--test/pending/run/macro-expand-default/Macros_Test_2.scala8
-rw-r--r--test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check6
-rw-r--r--test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags1
-rw-r--r--test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala10
-rw-r--r--test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala6
-rw-r--r--test/pending/run/macro-expand-implicit-macro-has-context-bound.check1
-rw-r--r--test/pending/run/macro-expand-implicit-macro-has-context-bound.flags (renamed from test/pending/run/macro-overload.flags)0
-rw-r--r--test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala10
-rw-r--r--test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala4
-rw-r--r--test/pending/run/macro-expand-named.flags1
-rw-r--r--test/pending/run/macro-expand-named/Impls_1.scala10
-rw-r--r--test/pending/run/macro-expand-named/Macros_Test_2.scala5
-rw-r--r--test/pending/run/macro-expand-tparams-prefix-e1.check3
-rw-r--r--test/pending/run/macro-expand-tparams-prefix-e1.flags1
-rw-r--r--test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala12
-rw-r--r--test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala13
-rw-r--r--test/pending/run/macro-expand-tparams-prefix-f1.check3
-rw-r--r--test/pending/run/macro-expand-tparams-prefix-f1.flags1
-rw-r--r--test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala12
-rw-r--r--test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala13
-rw-r--r--test/pending/run/macro-overload.check4
-rw-r--r--test/pending/run/macro-overload/Macros_1.scala9
-rw-r--r--test/pending/run/macro-overload/Test_2.scala6
-rw-r--r--test/pending/run/macro-quasiinvalidbody-a.check1
-rw-r--r--test/pending/run/macro-quasiinvalidbody-a.flags1
-rw-r--r--test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala5
-rw-r--r--test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala10
-rw-r--r--test/pending/run/macro-quasiinvalidbody-b.check1
-rw-r--r--test/pending/run/macro-quasiinvalidbody-b.flags1
-rw-r--r--test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala7
-rw-r--r--test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala10
-rw-r--r--test/pending/run/macro-reify-array.flags1
-rw-r--r--test/pending/run/macro-reify-array/Macros_1.scala11
-rw-r--r--test/pending/run/macro-reify-array/Test_2.scala4
-rw-r--r--test/pending/run/macro-reify-eval-vs-value.flags1
-rw-r--r--test/pending/run/macro-reify-eval-vs-value/Macros_1.scala25
-rw-r--r--test/pending/run/macro-reify-eval-vs-value/Test_2.scala5
-rw-r--r--test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check2
-rw-r--r--test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala9
-rw-r--r--test/pending/run/macro-reify-tagful-b.check1
-rw-r--r--test/pending/run/macro-reify-tagful-b.flags1
-rw-r--r--test/pending/run/macro-reify-tagful-b/Macros_1.scala11
-rw-r--r--test/pending/run/macro-reify-tagful-b/Test_2.scala4
-rw-r--r--test/pending/run/macro-reify-tagless-b.check3
-rw-r--r--test/pending/run/macro-reify-tagless-b.flags1
-rw-r--r--test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala11
-rw-r--r--test/pending/run/macro-reify-tagless-b/Test_2.scala11
-rw-r--r--test/pending/run/macro-reify-typetag-hktypeparams-notags.check2
-rw-r--r--test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala9
-rw-r--r--test/pending/run/macro-reify-typetag-hktypeparams-tags.check2
-rw-r--r--test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala9
-rw-r--r--test/pending/run/reify_addressbook.scala12
-rw-r--r--test/pending/run/reify_brainf_ck.scala12
-rw-r--r--test/pending/run/reify_callccinterpreter.scala12
-rw-r--r--test/pending/run/reify_closure2b.scala9
-rw-r--r--test/pending/run/reify_closure3b.scala9
-rw-r--r--test/pending/run/reify_closure4b.scala9
-rw-r--r--test/pending/run/reify_closure5b.scala9
-rw-r--r--test/pending/run/reify_closure8b.check1
-rw-r--r--test/pending/run/reify_closure8b.scala16
-rw-r--r--test/pending/run/reify_closure9a.scala11
-rw-r--r--test/pending/run/reify_closure9b.scala11
-rw-r--r--test/pending/run/reify_closures11.scala11
-rw-r--r--test/pending/run/reify_csv.scala12
-rw-r--r--test/pending/run/reify_gadts.scala12
-rw-r--r--test/pending/run/reify_lazyevaluation.scala12
-rw-r--r--test/pending/run/reify_newimpl_07.scala13
-rw-r--r--test/pending/run/reify_newimpl_08.scala15
-rw-r--r--test/pending/run/reify_newimpl_35.scala10
-rw-r--r--test/pending/run/reify_newimpl_46.scala12
-rw-r--r--test/pending/run/reify_newimpl_53.scala15
-rw-r--r--test/pending/run/reify_properties.scala12
-rw-r--r--test/pending/run/reify_simpleinterpreter.scala12
-rw-r--r--test/pending/run/t5258a.check (renamed from test/files/run/t5258a.check)0
-rw-r--r--test/pending/run/t5258a.scala7
-rw-r--r--test/pending/run/t5258b.scala12
-rw-r--r--test/pending/run/t5258c.scala12
-rw-r--r--test/pending/run/t5271_1.scala13
-rw-r--r--test/pending/run/t5271_2.check1
-rw-r--r--test/pending/run/t5271_2.scala15
-rw-r--r--test/pending/run/t5271_3.check1
-rw-r--r--test/pending/run/t5271_3.scala16
-rw-r--r--test/pending/run/t5418.scala12
-rw-r--r--test/pending/run/t5629.check2
-rw-r--r--test/pending/run/t5629.scala25
-rw-r--r--test/pending/run/t5692.flags1
-rw-r--r--test/pending/run/t5692/Impls_Macros_1.scala9
-rw-r--r--test/pending/run/t5692/Test_2.scala4
-rw-r--r--test/pending/shootout/meteor.scala64
-rw-r--r--test/scaladoc/resources/implicits-base-res.scala148
-rw-r--r--test/scaladoc/resources/implicits-chaining-res.scala50
-rw-r--r--test/scaladoc/resources/implicits-elimination-res.scala14
-rw-r--r--test/scaladoc/resources/implicits-scopes-res.scala52
-rw-r--r--test/scaladoc/resources/implicits-shadowing-res.scala64
-rw-r--r--test/scaladoc/run/SI-5373.check1
-rw-r--r--test/scaladoc/run/SI-5373.scala34
-rw-r--r--test/scaladoc/run/implicits-base.check1
-rw-r--r--test/scaladoc/run/implicits-base.scala180
-rw-r--r--test/scaladoc/run/implicits-chaining.check1
-rw-r--r--test/scaladoc/run/implicits-chaining.scala65
-rw-r--r--test/scaladoc/run/implicits-elimination.check1
-rw-r--r--test/scaladoc/run/implicits-elimination.scala23
-rw-r--r--test/scaladoc/run/implicits-scopes.check1
-rw-r--r--test/scaladoc/run/implicits-scopes.scala77
-rw-r--r--test/scaladoc/run/implicits-shadowing.check1
-rw-r--r--test/scaladoc/run/implicits-shadowing.scala70
-rw-r--r--test/scaladoc/scala/html.flags1
-rw-r--r--test/scaladoc/scalacheck/CommentFactoryTest.scala (renamed from test/scaladoc/scala/model/CommentFactoryTest.scala)5
-rw-r--r--test/scaladoc/scalacheck/HtmlFactoryTest.flags (renamed from test/scaladoc/scala/html/HtmlFactoryTest.flags)0
-rw-r--r--test/scaladoc/scalacheck/HtmlFactoryTest.scala (renamed from test/scaladoc/scala/html/HtmlFactoryTest.scala)19
-rw-r--r--test/scaladoc/scalacheck/IndexScriptTest.scala (renamed from test/scaladoc/scala/IndexScriptTest.scala)2
-rw-r--r--test/scaladoc/scalacheck/IndexTest.scala (renamed from test/scaladoc/scala/IndexTest.scala)2
-rwxr-xr-xtools/binary-repo-lib.sh59
-rwxr-xr-xtools/cleanup-commit130
-rwxr-xr-xtools/dump-class6
-rw-r--r--tools/get-scala-commit-date.bat33
-rw-r--r--tools/get-scala-commit-sha.bat30
1984 files changed, 38680 insertions, 17278 deletions
diff --git a/build.xml b/build.xml
index 504f454e19..d0828ff6f2 100644
--- a/build.xml
+++ b/build.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project name="sabbus" default="build">
+<project name="sabbus" default="build" xmlns:artifact="urn:maven-artifact-ant">
<description>
SuperSabbus for Scala core, builds the scala library and compiler. It can also package it as a simple distribution, tests it for stable bootstrapping and against the Scala test suite.
</description>
@@ -8,10 +8,10 @@ SuperSabbus for Scala core, builds the scala library and compiler. It can also p
<!-- ===========================================================================
END-USER TARGETS
============================================================================ -->
-
+
<target name="build" depends="pack.done"
description="Builds the Scala compiler and library. Executables are in 'build/pack/bin'."/>
-
+
<target name="build-opt"
description="Builds the optimised Scala compiler and library. Executables are in 'build/pack/bin'.">
<antcall target="build">
@@ -34,20 +34,20 @@ END-USER TARGETS
<target name="docs" depends="docs.done"
description="Builds documentation for the Scala library. Scaladoc is in 'build/scaladoc/library'."/>
-
+
<target name="docscomp" depends="docs.comp"
description="Builds documentation for the Scala compiler and library. Scaladoc is in 'build/scaladoc'."/>
-
+
<target name="docsclean" depends="docs.clean"
description="Removes generated documentation. Distributions are untouched."/>
-
+
<target name="dist"
description="Makes a new distribution and tests it. Will remove existing binaries and documentation.">
<antcall target="locker.clean"/>
<antcall target="docs.clean"/>
<antcall target="all.done"/>
</target>
-
+
<target name="dist-opt"
description="Makes a new optimised distribution and tests it. Will remove existing binaries and documentation.">
<antcall target="dist">
@@ -67,7 +67,7 @@ END-USER TARGETS
<target name="distclean" depends="dist.clean"
description="Removes all distributions. Binaries and documentation are untouched."/>
-
+
<target name="replacestarr"
description="Replaces the Starr compiler and library by fresh ones built from current sources and tests them.">
<fail message="This target is not available on Windows. Use 'ant replacestarrwin' instead.">
@@ -81,7 +81,7 @@ END-USER TARGETS
<antcall target="locker.clean"/>
<antcall target="test.done"/>
</target>
-
+
<target name="replacestarr-opt"
description="Replaces the Starr compiler and library by fresh, optimised ones built from current sources and tests them.">
<antcall target="replacestarr">
@@ -103,7 +103,7 @@ END-USER TARGETS
<antcall target="locker.clean"/>
<antcall target="test.done"/>
</target>
-
+
<target name="replacelocker"
description="Replaces the Locker compiler and library by fresh ones built from current sources.">
<antcall target="palo.clean"/>
@@ -144,7 +144,7 @@ END-USER TARGETS
description="Requires forkjoin library to be rebuilt. Add this target before any other if class file format is incompatible.">
<property name="forkjoin.outdated" value="yes"/>
</target>
-
+
<!-- ===========================================================================
PROPERTIES
============================================================================ -->
@@ -159,7 +159,7 @@ PROPERTIES
<property name="lib-ant.dir" value="${lib.dir}/ant"/>
<property name="src.dir" value="${basedir}/src"/>
<property name="partest.dir" value="${basedir}/test"/>
-
+
<!-- For developers: any jars placed in this dir will be added to the classpath
of all targets and copied into quick/pack/etc builds. -->
<property name="lib-extra.dir" value="${lib.dir}/extra"/>
@@ -238,6 +238,21 @@ INITIALISATION
</touch>
</target>
+ <!-- Add our maven ant tasks -->
+ <target name="init.maven.tasks" depends="init.jars.check" unless="init.maven.tasks.finished">
+ <path id="maven-ant-tasks.classpath" path="${lib.dir}/ant/maven-ant-tasks-2.1.1.jar" />
+ <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
+
+ <property name="init.maven.tasks.finished" value="true" />
+ </target>
+
+ <!-- Resolve maven dependencies -->
+ <target name="init.maven.jars" depends="init.maven.tasks">
+ <artifact:dependencies pathId="dependency.classpath" filesetId="dependency.fileset">
+ <dependency groupId="com.typesafe" artifactId="config" version="0.4.0"/>
+ </artifact:dependencies>
+ </target>
+
<!-- Determines OSGi string + maven extension. -->
<target name="init.hasbuildnum">
<condition property="version.hasbuildnum">
@@ -259,28 +274,33 @@ INITIALISATION
<property name="version.suffix" value="-${version.bnum}"/>
</target>
- <target name="init.build.suffix.done" depends="init.build.release, init.build.patch.release"/>
+ <target name="init.hasmavensuffix" if="build.release" depends="init.build.patch.release, init.build.release">
+ <condition property="version.hasmavensuffix">
+ <not><equals arg1="${maven.version.suffix}" arg2=""/></not>
+ </condition>
+ </target>
- <target name="init" depends="init.jars, init.build.suffix.done">
- <!-- scalac.args.optimise is selectively overridden in certain antcall tasks. -->
- <property name="scalac.args.optimise" value=""/>
- <!-- scalac.args.quickonly are added to quick.* targets but not others (particularly, locker.)
- This is to facilitate testing new command line options which do not yet exist in starr. -->
- <property name="scalac.args.quickonly" value=""/>
- <property name="scalac.args.all" value="${scalac.args} ${scalac.args.optimise}"/>
- <property name="scalac.args.quick" value="${scalac.args.all} ${scalac.args.quickonly}"/>
- <!-- 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 -->
- <tstamp prefix="time">
- <format property="human" pattern="d MMMM yyyy, HH:mm:ss" locale="en,US"/>
- <format property="short" pattern="yyyyMMddHHmmss"/>
- </tstamp>
+ <target name="init.osgi.suffix" if="version.hasmavensuffix" depends="init.hasmavensuffix">
+ <property name="osgi.version.suffix" value="${maven.version.suffix}"/>
+ </target>
+
+ <target name="init.osgi.suffix.final" if="build.release" unless="version.hasmavensuffix" depends="init.hasmavensuffix">
+ <property name="osgi.version.suffix" value="-VFINAL"/>
+ </target>
+
+
+ <target name="init.osgi.suffix.snapshot" unless="build.release" depends="init.hasmavensuffix">
+ <property name="osgi.version.suffix" value=""/>
+ </target>
+
+ <target name="init.build.suffix.done" depends="init.build.release, init.build.patch.release, init.osgi.suffix, init.osgi.suffix.final, init.osgi.suffix.snapshot"/>
+
+ <target name="init.version.git" depends="init.build.suffix.done">
<!-- Find out whether we are running on Windows -->
<condition property="os.win">
<os family="windows"/>
</condition>
-
+
<exec osfamily="unix" executable="tools/get-scala-commit-sha" outputproperty="git.commit.sha" failifexecutionfails="false" />
<exec osfamily="windows" executable="tools/get-scala-commit-sha.bat" outputproperty="git.commit.sha" failifexecutionfails="false" />
<exec osfamily="unix" executable="tools/get-scala-commit-date" outputproperty="git.commit.date" failifexecutionfails="false" />
@@ -294,18 +314,49 @@ INITIALISATION
name="maven.version.number"
value="${version.major}.${version.minor}.${version.patch}${version.suffix}${maven.version.suffix}"/>
<property
+ name="osgi.version.number"
+ value="${version.major}.${version.minor}.${version.patch}.v${git.commit.date}${version.suffix}${osgi.version.suffix}-${git.commit.sha}"/>
+ </target>
+
+ <target name="init.version.snapshot" unless="build.release" depends="init.version.git">
+ <property
name="version.number"
value="${version.major}.${version.minor}.${version.patch}${version.suffix}-${git.commit.date}-${git.commit.sha}"/>
- <property
- name="osgi.version.number"
- value="${version.major}.${version.minor}.${version.patch}.v${git.commit.date}${version.suffix}-${git.commit.sha}"/>
+ </target>
+
+ <target name="init.version.release" if="build.release" depends="init.version.git">
+ <property
+ name="version.number"
+ value="${maven.version.number}"/>
+ </target>
+
+ <target name="init.version.done" depends="init.version.release, init.version.snapshot"/>
+
+ <target name="init" depends="init.jars, init.maven.jars, init.version.done">
+ <property name="scalac.args.always" value="-Xmacros" />
+ <!-- scalac.args.optimise is selectively overridden in certain antcall tasks. -->
+ <property name="scalac.args.optimise" value=""/>
+ <!-- scalac.args.quickonly are added to quick.* targets but not others (particularly, locker.)
+ This is to facilitate testing new command line options which do not yet exist in starr. -->
+ <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}"/>
+ <!-- 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 -->
+ <tstamp prefix="time">
+ <format property="human" pattern="d MMMM yyyy, HH:mm:ss" locale="en,US"/>
+ <format property="short" pattern="yyyyMMddHHmmss"/>
+ </tstamp>
+
<!-- some default in case something went wrong getting the revision -->
<property name="version.number" value="-unknown-"/>
<property name="init.avail" value="yes"/>
+
<!-- Local libs (developer use.) -->
<mkdir dir="${lib-extra.dir}"/>
-
+
<path id="lib.extra">
<!-- needs ant 1.7.1 -->
<!-- <fileset dir="${lib-extra.dir}" erroronmissingdir="false"> -->
@@ -323,6 +374,7 @@ INITIALISATION
</fileset>
<pathelement location="${ant.jar}"/>
<path refid="lib.extra"/>
+ <path refid="dependency.classpath"/>
</path>
<!-- And print-out what we are building -->
@@ -354,7 +406,7 @@ INITIALISATION
<pathelement location="${lib.dir}/forkjoin.jar"/>
<path refid="lib.extra"/>
</path>
- <taskdef resource="scala/tools/ant/sabbus/antlib.xml" classpathref="starr.classpath"/>
+ <taskdef resource="scala/tools/ant/sabbus/antlib.xml" classpathref="starr.classpath"/>
</target>
<!-- ===========================================================================
@@ -382,7 +434,7 @@ LOCAL REFERENCE BUILD (LOCKER)
classpath="${build-locker.dir}/classes/library"
includes="**/*.java"
target="1.5" source="1.5">
- <compilerarg line="${javac.args}"/>
+ <compilerarg line="${javac.args} -XDignore.symbol.file"/>
</javac>
<!-- NOTE: Potential problem with maximal command line length on Windows
(32768 characters for XP, since executed with Java's "exec"). See
@@ -417,7 +469,7 @@ LOCAL REFERENCE BUILD (LOCKER)
<touch file="${build-locker.dir}/library.complete" verbose="no"/>
<stopwatch name="locker.lib.timer" action="total"/>
</target>
-
+
<target name="locker.pre-comp" depends="locker.lib" unless="locker.available">
<condition property="locker.comp.needed">
<not><available file="${build-locker.dir}/compiler.complete"/></not>
@@ -477,11 +529,11 @@ LOCAL REFERENCE BUILD (LOCKER)
<path refid="aux.libs"/>
</path>
</target>
-
+
<target name="locker.clean" depends="palo.clean">
<delete dir="${build-locker.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/>
</target>
-
+
<target name="locker.unlock.pre-lib">
<uptodate property="locker.lib.available" targetfile="${build-locker.dir}/library.complete">
<srcfiles dir="${src.dir}">
@@ -603,14 +655,13 @@ PACKED LOCKER BUILD (PALO)
<!-- ===========================================================================
QUICK BUILD (QUICK)
============================================================================ -->
-
+
<target name="quick.start" depends="locker.done"/>
<target name="quick.pre-lib" depends="quick.start">
<uptodate property="quick.lib.available" targetfile="${build-quick.dir}/library.complete">
<srcfiles dir="${src.dir}">
<include name="library/**"/>
- <include name="dbc/**"/>
<include name="continuations/**"/>
<include name="swing/**"/>
<include name="actors/**"/>
@@ -627,7 +678,7 @@ QUICK BUILD (QUICK)
classpath="${build-quick.dir}/classes/library"
includes="**/*.java"
target="1.5" source="1.5">
- <compilerarg line="${javac.args}"/>
+ <compilerarg line="${javac.args} -XDignore.symbol.file"/>
</javac>
<javac
srcdir="${src.dir}/actors"
@@ -660,15 +711,6 @@ QUICK BUILD (QUICK)
destdir="${build-quick.dir}/classes/library"
compilerpathref="locker.classpath"
params="${scalac.args.quick}"
- srcdir="${src.dir}/dbc"
- jvmargs="${scalacfork.jvmargs}">
- <include name="**/*.scala"/>
- <compilationpath refid="quick.compilation.path"/>
- </scalacfork>
- <scalacfork
- destdir="${build-quick.dir}/classes/library"
- compilerpathref="locker.classpath"
- params="${scalac.args.quick}"
srcdir="${src.dir}/swing"
jvmargs="${scalacfork.jvmargs}">
<include name="**/*.scala"/>
@@ -691,13 +733,13 @@ QUICK BUILD (QUICK)
<touch file="${build-quick.dir}/library.complete" verbose="no"/>
<stopwatch name="quick.lib.timer" action="total"/>
</target>
-
+
<target name="quick.newlibs" depends="quick.lib" if="libs.outdated">
<antcall target="libs.done" inheritRefs="true"/>
<property name="fjbg.jar" value="${build-libs.dir}/fjbg.jar"/>
<property name="msil.jar" value="${build-libs.dir}/msil.jar"/>
</target>
-
+
<target name="quick.libs" depends="quick.newlibs" unless="libs.outdated">
<property name="fjbg.jar" value="${lib.dir}/fjbg.jar"/>
<property name="msil.jar" value="${lib.dir}/msil.jar"/>
@@ -794,7 +836,7 @@ QUICK BUILD (QUICK)
<scalacfork
destdir="${build-quick.dir}/classes/library"
compilerpathref="quick.classpath"
- params="${scalac.args.quick} -Xplugin-require:continuations"
+ params="${scalac.args.quick} -Xplugin-require:continuations -P:continuations:enable"
srcdir="${src.dir}/continuations/library"
jvmargs="${scalacfork.jvmargs}">
<include name="**/*.scala"/>
@@ -805,7 +847,7 @@ QUICK BUILD (QUICK)
<touch file="${build-quick.dir}/plugins.complete" verbose="no"/>
<stopwatch name="quick.plugins.timer" action="total"/>
</target>
-
+
<target name="quick.pre-scalacheck" depends="quick.plugins">
<uptodate property="quick.scalacheck.available" targetfile="${build-quick.dir}/scalacheck.complete">
<srcfiles dir="${src.dir}/scalacheck"/>
@@ -830,7 +872,7 @@ QUICK BUILD (QUICK)
<touch file="${build-quick.dir}/scalacheck.complete" verbose="no"/>
<stopwatch name="quick.scalacheck.timer" action="total"/>
</target>
-
+
<target name="quick.pre-scalap" depends="quick.scalacheck">
<uptodate property="quick.scalap.available" targetfile="${build-quick.dir}/scalap.complete">
<srcfiles dir="${src.dir}/scalap"/>
@@ -865,7 +907,7 @@ QUICK BUILD (QUICK)
<srcfiles dir="${src.dir}/partest"/>
</uptodate>
</target>
-
+
<target name="quick.partest" depends="quick.pre-partest" unless="quick.partest.available">
<stopwatch name="quick.partest.timer"/>
<mkdir dir="${build-quick.dir}/classes/partest"/>
@@ -960,7 +1002,7 @@ QUICK BUILD (QUICK)
<chmod perm="ugo+rx" file="${build-quick.dir}/bin/scalap"/>
<touch file="${build-quick.dir}/bin.complete" verbose="no"/>
</target>
-
+
<target name="quick.done" depends="quick.bin">
<path id="quick.classpath">
<pathelement location="${build-quick.dir}/classes/library"/>
@@ -976,9 +1018,9 @@ QUICK BUILD (QUICK)
<!-- ===========================================================================
PACKED QUICK BUILD (PACK)
============================================================================ -->
-
+
<target name="pack.start" depends="quick.done"/>
-
+
<target name="pack.pre-lib" depends="pack.start">
<uptodate
property="pack.lib.available"
@@ -988,19 +1030,18 @@ PACKED QUICK BUILD (PACK)
<target name="pack.lib" depends="pack.pre-lib" unless="pack.lib.available">
<mkdir dir="${build-pack.dir}/lib"/>
+ <!-- First copy maven dependencies -->
+ <copy todir="${build-pack.dir}/lib">
+ <fileset refid="dependency.fileset" />
+ <mapper type="flatten" />
+ </copy>
<jar destfile="${build-pack.dir}/lib/scala-library.jar">
<fileset dir="${build-quick.dir}/classes/library">
- <exclude name="scala/dbc/**"/>
<exclude name="scala/swing/**"/>
<exclude name="scala/actors/**"/>
</fileset>
<zipfileset dirmode="755" filemode="644" src="${forkjoin.jar}"/>
</jar>
- <jar destfile="${build-pack.dir}/lib/scala-dbc.jar">
- <fileset dir="${build-quick.dir}/classes/library">
- <include name="scala/dbc/**"/>
- </fileset>
- </jar>
<jar destfile="${build-pack.dir}/lib/scala-swing.jar">
<fileset dir="${build-quick.dir}/classes/library">
<include name="scala/swing/**"/>
@@ -1012,7 +1053,7 @@ PACKED QUICK BUILD (PACK)
</fileset>
</jar>
</target>
-
+
<target name="pack.pre-comp" depends="pack.lib">
<uptodate
property="pack.comp.available"
@@ -1040,7 +1081,7 @@ PACKED QUICK BUILD (PACK)
</fileset>
</copy>
</target>
-
+
<target name="pack.pre-plugins" depends="pack.comp">
<uptodate
property="pack.plugins.available"
@@ -1054,13 +1095,13 @@ PACKED QUICK BUILD (PACK)
<fileset dir="${build-quick.dir}/classes/continuations-plugin"/>
</jar>
</target>
-
+
<target name="pack.scalacheck" depends="pack.plugins">
<jar destfile="${build-pack.dir}/lib/scalacheck.jar">
<fileset dir="${build-quick.dir}/classes/scalacheck"/>
</jar>
</target>
-
+
<target name="pack.pre-partest" depends="pack.scalacheck">
<uptodate
property="pack.partest.available"
@@ -1074,7 +1115,7 @@ PACKED QUICK BUILD (PACK)
<fileset dir="${build-quick.dir}/classes/partest"/>
</jar>
</target>
-
+
<target name="pack.pre-scalap" depends="pack.partest">
<uptodate
property="pack.scalap.available"
@@ -1086,10 +1127,10 @@ PACKED QUICK BUILD (PACK)
<mkdir dir="${build-pack.dir}/lib"/>
<jar destfile="${build-pack.dir}/lib/scalap.jar">
<fileset dir="${build-quick.dir}/classes/scalap"/>
- <fileset file="${src.dir}/scalap/decoder.properties"/>
+ <fileset file="${src.dir}/scalap/decoder.properties"/>
</jar>
</target>
-
+
<target name="pack.pre-bin" depends="pack.scalap">
<uptodate
property="pack.bin.available"
@@ -1133,7 +1174,7 @@ PACKED QUICK BUILD (PACK)
<chmod perm="ugo+rx" file="${build-pack.dir}/bin/scalap"/>
<touch file="${build-pack.dir}/bin.complete" verbose="no"/>
</target>
-
+
<target name="pack.done" depends="pack.bin">
<path id="pack.classpath">
<pathelement location="${build-pack.dir}/lib/scala-library.jar"/>
@@ -1156,14 +1197,13 @@ PACKED QUICK BUILD (PACK)
<!-- ===========================================================================
BOOTSTRAPPING BUILD (STRAP)
============================================================================ -->
-
+
<target name="strap.start" depends="pack.done"/>
-
+
<target name="strap.pre-lib" depends="strap.start">
<uptodate property="strap.lib.available" targetfile="${build-strap.dir}/library.complete">
<srcfiles dir="${src.dir}">
<include name="library/**"/>
- <include name="dbc/**"/>
<include name="swing/**"/>
<include name="actors/**"/>
</srcfiles>
@@ -1179,7 +1219,7 @@ BOOTSTRAPPING BUILD (STRAP)
classpath="${build-strap.dir}/classes/library"
includes="**/*.java"
target="1.5" source="1.5">
- <compilerarg line="${javac.args}"/>
+ <compilerarg line="${javac.args} -XDignore.symbol.file"/>
</javac>
<javac
srcdir="${src.dir}/actors"
@@ -1212,15 +1252,6 @@ BOOTSTRAPPING BUILD (STRAP)
destdir="${build-strap.dir}/classes/library"
compilerpathref="pack.classpath"
params="${scalac.args.all}"
- srcdir="${src.dir}/dbc"
- jvmargs="${scalacfork.jvmargs}">
- <include name="**/*.scala"/>
- <compilationpath refid="strap.compilation.path"/>
- </scalacfork>
- <scalacfork
- destdir="${build-strap.dir}/classes/library"
- compilerpathref="pack.classpath"
- params="${scalac.args.all}"
srcdir="${src.dir}/swing"
jvmargs="${scalacfork.jvmargs}">
<include name="**/*.scala"/>
@@ -1243,7 +1274,7 @@ BOOTSTRAPPING BUILD (STRAP)
<touch file="${build-strap.dir}/library.complete" verbose="no"/>
<stopwatch name="strap.lib.timer" action="total"/>
</target>
-
+
<target name="strap.pre-comp" depends="strap.lib">
<uptodate property="strap.comp.available" targetfile="${build-strap.dir}/compiler.complete">
<srcfiles dir="${src.dir}/compiler"/>
@@ -1326,7 +1357,7 @@ BOOTSTRAPPING BUILD (STRAP)
<scalacfork
destdir="${build-strap.dir}/classes/library"
compilerpathref="pack.classpath"
- params="${scalac.args.all} -Xplugin-require:continuations"
+ params="${scalac.args.all} -Xplugin-require:continuations -P:continuations:enable"
srcdir="${src.dir}/continuations/library"
jvmargs="${scalacfork.jvmargs}">
<include name="**/*.scala"/>
@@ -1337,7 +1368,7 @@ BOOTSTRAPPING BUILD (STRAP)
<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
@@ -1381,13 +1412,13 @@ BOOTSTRAPPING BUILD (STRAP)
<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">
<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"/>
@@ -1439,9 +1470,9 @@ BOOTSTRAPPING BUILD (STRAP)
<!-- ===========================================================================
LIBRARIES (MSIL, FJBG maybe later)
============================================================================ -->
-
+
<target name="libs.start"/>
-
+
<target name="libs.pre-forkjoin" depends="libs.start">
<property name="java6.home" value="/home/linuxsoft/apps/java-1.6"/>
<fail message="Compiling forkjoin.jar requires java 1.6. Please set the property `java6.home` in build.properties or using `-Djava6.home=/path/to/java6`">
@@ -1457,7 +1488,7 @@ LIBRARIES (MSIL, FJBG maybe later)
</srcfiles>
</uptodate>
</target>
-
+
<target name="libs.forkjoin" depends="libs.pre-forkjoin" unless="libs.forkjoin.available">
<mkdir dir="${build-libs.dir}/classes/forkjoin"/>
<javac
@@ -1474,16 +1505,16 @@ LIBRARIES (MSIL, FJBG maybe later)
</javac>
<touch file="${build-libs.dir}/forkjoin.complete" verbose="no"/>
</target>
-
+
<target name="libs.pre-forkjoinpack" depends="libs.forkjoin">
</target>
-
+
<target name="libs.forkjoinpack" depends="libs.pre-forkjoinpack" unless="libs.forkjoinpack.available">
<jar destfile="${build-libs.dir}/forkjoin.jar">
<fileset dir="${build-libs.dir}/classes/forkjoin"/>
</jar>
</target>
-
+
<target name="libs.pre-msil" depends="libs.start">
<uptodate property="libs.msil.available" targetfile="${build-libs.dir}/msil.complete">
<srcfiles dir="${src.dir}/msil">
@@ -1492,7 +1523,7 @@ LIBRARIES (MSIL, FJBG maybe later)
</srcfiles>
</uptodate>
</target>
-
+
<target name="libs.msil" depends="libs.pre-msil" unless="libs.msil.available">
<mkdir dir="${build-libs.dir}/classes/msil"/>
<javac
@@ -1519,16 +1550,16 @@ LIBRARIES (MSIL, FJBG maybe later)
</scalacfork>
<touch file="${build-libs.dir}/msil.complete" verbose="no"/>
</target>
-
+
<target name="libs.pre-msilpack" depends="libs.msil">
</target>
-
+
<target name="libs.msilpack" depends="libs.pre-msilpack" unless="libs.msilpack.available">
<jar destfile="${build-libs.dir}/msil.jar">
<fileset dir="${build-libs.dir}/classes/msil"/>
</jar>
</target>
-
+
<target name="libs.pre-fjbg" depends="libs.start">
<uptodate property="libs.fjbg.available" targetfile="${build-libs.dir}/fjbg.complete">
<srcfiles dir="${src.dir}/fjbg">
@@ -1537,7 +1568,7 @@ LIBRARIES (MSIL, FJBG maybe later)
</srcfiles>
</uptodate>
</target>
-
+
<target name="libs.fjbg" depends="libs.pre-fjbg" unless="libs.fjbg.available">
<mkdir dir="${build-libs.dir}/classes/fjbg"/>
<javac
@@ -1551,10 +1582,10 @@ LIBRARIES (MSIL, FJBG maybe later)
</javac>
<touch file="${build-libs.dir}/fjbg.complete" verbose="no"/>
</target>
-
+
<target name="libs.pre-fjbgpack" depends="libs.fjbg">
</target>
-
+
<target name="libs.fjbgpack" depends="libs.pre-fjbgpack" unless="libs.fjbgpack.available">
<jar destfile="${build-libs.dir}/fjbg.jar">
<fileset dir="${build-libs.dir}/classes/fjbg"/>
@@ -1564,7 +1595,7 @@ LIBRARIES (MSIL, FJBG maybe later)
<target name="libs.done" depends="libs.msilpack, libs.fjbgpack"/>
<target name="forkjoin.done" depends="libs.forkjoinpack"/>
-
+
<target name="libs.clean" depends="pack.clean">
<delete dir="${build-libs.dir}" includeemptydirs="yes" quiet="yes" failonerror="no"/>
</target>
@@ -1572,7 +1603,7 @@ LIBRARIES (MSIL, FJBG maybe later)
<!-- ===========================================================================
DOCUMENTATION
============================================================================ -->
-
+
<target name="docs.start" depends="pack.done">
<macrodef name="doc-uptodate-check">
<attribute name="name" />
@@ -1586,13 +1617,27 @@ DOCUMENTATION
</uptodate>
</sequential>
</macrodef>
+
+ <!-- Set the github commit scaladoc sources point to -->
+ <!-- For releases, look for the tag with the same name as the maven version -->
+ <condition property="scaladoc.git.commit" value="v${maven.version.number}">
+ <isset property="build.release"/>
+ </condition>
+ <!-- For snapshots, if we know the commit, point scaladoc to that particular commit instead of master -->
+ <condition property="scaladoc.git.commit" value="${git.commit.sha}">
+ <not><equals arg1="${git.commit.sha}" arg2="unknown"/></not>
+ </condition>
+ <!-- Fallback: point scaladoc to master -->
+ <property name="scaladoc.git.commit" value="master"/>
+ <!-- Compute the URL and show it -->
+ <property name="scaladoc.url" value="https://github.com/scala/scala/tree/${scaladoc.git.commit}/src"/>
+ <echo message="Scaladoc will point to ${scaladoc.url} for source files."/>
</target>
-
+
<target name="docs.pre-lib" depends="docs.start">
<doc-uptodate-check name="library" srcdir="${src.dir}">
<source-includes>
<include name="library/**"/>
- <include name="dbc/**"/>
<include name="swing/**"/>
<include name="actors/**"/>
</source-includes>
@@ -1606,13 +1651,14 @@ DOCUMENTATION
destdir="${build-docs.dir}/library"
doctitle="Scala Standard Library API (Scaladoc)"
docversion="${version.number}"
- docfooter="epfl"
- docsourceurl="https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/€{FILE_PATH}.scala#L1"
+ docfooter="epfl"
+ docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1"
docUncompilable="${src.dir}/library-aux"
sourcepath="${src.dir}"
classpathref="pack.classpath"
addparams="${scalac.args.all}"
- docRootContent="${src.dir}/library/rootdoc.txt">
+ docRootContent="${src.dir}/library/rootdoc.txt"
+ implicits="on" diagrams="on">
<src>
<files includes="${src.dir}/actors"/>
<files includes="${src.dir}/library/scala"/>
@@ -1658,7 +1704,7 @@ DOCUMENTATION
<taskdef name="genman"
classname="scala.tools.docutil.ManMaker"
classpathref="manual.classpath"/>
- <genman command="fsc, sbaz, scala, scalac, scaladoc, scalap"
+ <genman command="fsc, scala, scalac, scaladoc, scalap"
htmlout="${build-docs.dir}/manual/html"
manout="${build-docs.dir}/manual/genman"/>
<!-- On Windows source and target files can't be the same ! -->
@@ -1688,12 +1734,13 @@ DOCUMENTATION
destdir="${build-docs.dir}/compiler"
doctitle="Scala Compiler"
docversion="${version.number}"
- docsourceurl="https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/€{FILE_PATH}.scala#L1"
+ docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1"
sourcepath="${src.dir}"
classpathref="pack.classpath"
srcdir="${src.dir}/compiler"
docRootContent="${src.dir}/compiler/rootdoc.txt"
- addparams="${scalac.args.all}">
+ addparams="${scalac.args.all}"
+ implicits="on" diagrams="on">
<include name="**/*.scala"/>
</scaladoc>
<touch file="${build-docs.dir}/compiler.complete" verbose="no"/>
@@ -1714,7 +1761,8 @@ DOCUMENTATION
sourcepath="${src.dir}"
classpathref="pack.classpath"
srcdir="${src.dir}/jline/src/main/java"
- addparams="${scalac.args.all}">
+ addparams="${scalac.args.all}"
+ implicits="on" diagrams="on">
<include name="**/*.scala"/>
<include name="**/*.java"/>
</scaladoc>
@@ -1733,11 +1781,12 @@ DOCUMENTATION
destdir="${build-docs.dir}/scalap"
doctitle="Scalap"
docversion="${version.number}"
- docsourceurl="https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/€{FILE_PATH}.scala#L1"
+ docsourceurl="${scaladoc.url}€{FILE_PATH}.scala#L1"
sourcepath="${src.dir}"
classpathref="pack.classpath"
srcdir="${src.dir}/scalap"
- addparams="${scalac.args.all}">
+ addparams="${scalac.args.all}"
+ implicits="on" diagrams="on">
<include name="**/*.scala"/>
</scaladoc>
<touch file="${build-docs.dir}/scalap.complete" verbose="no"/>
@@ -1758,7 +1807,8 @@ DOCUMENTATION
sourcepath="${src.dir}"
classpathref="pack.classpath"
srcdir="${src.dir}/partest"
- addparams="${scalac.args.all}">
+ addparams="${scalac.args.all}"
+ implicits="on" diagrams="on">
<include name="**/*.scala"/>
</scaladoc>
<touch file="${build-docs.dir}/partest.complete" verbose="no"/>
@@ -1779,7 +1829,8 @@ DOCUMENTATION
sourcepath="${src.dir}"
classpathref="pack.classpath"
srcdir="${src.dir}/continuations/plugin"
- addparams="${scalac.args.all}">
+ addparams="${scalac.args.all}"
+ implicits="on" diagrams="on">
<include name="**/*.scala"/>
</scaladoc>
<touch file="${build-docs.dir}/continuations-plugin.complete" verbose="no"/>
@@ -1811,7 +1862,7 @@ BOOTRAPING TEST AND TEST SUITE
<target name="test.classload" depends="pack.done">
<classloadVerify classpath="${build-pack.dir}/lib/scala-library.jar" />
</target>
-
+
<!-- this target will run only those tests found in test/debug -->
<target name="test.debug">
<antcall target="test.suite">
@@ -1885,7 +1936,7 @@ BOOTRAPING TEST AND TEST SUITE
<partest showlog="yes" erroronfailed="yes" javacmd="${java.home}/bin/java"
timeout="2400000"
srcdir="${partest.srcdir}"
- scalacopts="${scalac.args.optimise} -Xplugin-require:continuations">
+ scalacopts="${scalac.args.optimise} -Xplugin-require:continuations -P:continuations:enable">
<compilerarg value="-Xpluginsdir"/>
<compilerarg file="${build-quick.dir}/misc/scala-devel/plugins"/>
<compilationpath>
@@ -1903,7 +1954,8 @@ BOOTRAPING TEST AND TEST SUITE
<path refid="pack.classpath"/>
<fileset dir="${partest.dir}/files/lib" includes="*.jar" />
</compilationpath>
- <scalachecktests dir="${partest.dir}/scaladoc/scala" includes="**/*.scala" />
+ <runtests dir="${partest.dir}/scaladoc/run" includes="*.scala" />
+ <scalachecktests dir="${partest.dir}/scaladoc/scalacheck" includes="*.scala" />
</partest>
</target>
@@ -1973,9 +2025,6 @@ DISTRIBUTION
<fileset dir="${src.dir}/library"/>
<fileset dir="${src.dir}/continuations/library"/>
</jar>
- <jar destfile="${dist.dir}/src/scala-dbc-src.jar">
- <fileset dir="${src.dir}/dbc"/>
- </jar>
<jar destfile="${dist.dir}/src/scala-swing-src.jar">
<fileset dir="${src.dir}/swing"/>
</jar>
@@ -2063,7 +2112,6 @@ STABLE REFERENCE (STARR)
<fileset dir="${basedir}/src/library"/>
<fileset dir="${basedir}/src/swing"/>
<fileset dir="${basedir}/src/actors"/>
- <fileset dir="${basedir}/src/dbc"/>
</jar>
</target>
@@ -2101,7 +2149,7 @@ STABLE REFERENCE (STARR)
<!-- ===========================================================================
FORWARDED TARGETS FOR PACKAGING
============================================================================ -->
-
+
<target name="distpack" depends="dist.done, docs.all">
<ant antfile="${src.dir}/build/pack.xml" target="pack-all.done" inheritall="yes" inheritrefs="yes"/>
</target>
@@ -2116,7 +2164,7 @@ FORWARDED TARGETS FOR PACKAGING
<param name="scalac.args.optimise" value="-optimise"/>
</antcall>
</target>
-
+
<target name="distpack-maven-opt"
description="Builds an optimised maven distribution.">
<antcall target="distpack-maven">
@@ -2166,9 +2214,6 @@ POSITIONS
<param name="test.srcs" value="${src.dir}/actors"/>
</antcall>
<antcall target="test.positions.sub" inheritRefs="true">
- <param name="test.srcs" value="${src.dir}/dbc"/>
- </antcall>
- <antcall target="test.positions.sub" inheritRefs="true">
<param name="test.srcs" value="${src.dir}/swing"/>
</antcall>
<antcall target="test.positions.sub" inheritRefs="true">
diff --git a/classpath.SAMPLE b/classpath.SAMPLE
index 69c2baeba7..9e607a41d9 100644
--- a/classpath.SAMPLE
+++ b/classpath.SAMPLE
@@ -3,10 +3,9 @@
<classpathentry kind="src" path="src/compiler"/>
<classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry exported="true" kind="lib" path="lib/msil.jar"/>
+ <classpathentry kind="lib" path="lib/msil.jar"/>
<classpathentry kind="lib" path="lib/jline.jar"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry exported="true" kind="lib" path="lib/fjbg.jar"/>
+ <classpathentry kind="lib" path="lib/fjbg.jar"/>
<classpathentry kind="lib" path="lib/forkjoin.jar"/>
<classpathentry kind="lib" path="lib/ant/ant.jar"/>
<classpathentry kind="output" path="build/quick/classes/compiler"/>
diff --git a/docs/README b/docs/README
index bcc7108399..6af633444d 100644
--- a/docs/README
+++ b/docs/README
@@ -2,8 +2,7 @@
Scala Software Distributions
----------------------------
-- scala-<major>.<minor>.<patch>.tar.bz2 Unix distribution
-- scala-<major>.<minor>.<patch>.tar.gz Unix distribution
+- scala-<major>.<minor>.<patch>.tgz Unix distribution
- scala-<major>.<minor>.<patch>.zip Windows distribution
The standard distributions require Java 1.5 or above. If you don't
@@ -32,15 +31,10 @@ directly accessible.
You may test the distribution by running the following commands:
-$ ./bin/sbaz install scala-devel-docs
-$ ./bin/scalac doc/scala-devel-docs/examples/sort.scala
-$ ./bin/scala examples.sort
-[6,2,8,5,1]
-[1,2,5,6,8]
$ ./bin/scala
-scala> examples.sort.main(null)
-[6,2,8,5,1]
-[1,2,5,6,8]
+scala> Array(4,3,2,1).sorted
+res0: Array[Int] = Array(1, 2, 3, 4)
+
scala>:quit
$
diff --git a/docs/development/scala.dbc/SQLTypes.dot b/docs/development/scala.dbc/SQLTypes.dot
deleted file mode 100644
index 77c27cf729..0000000000
--- a/docs/development/scala.dbc/SQLTypes.dot
+++ /dev/null
@@ -1,48 +0,0 @@
-digraph SQLTypes {
- node [shape = record]
- DataType [label = "{DataType|nullable: Boolean}"]
- StringType [label = "{StringType|maxLength: Int}"]
- CharacterStringType [label = "{CharacterStringType|encoding: String}"]
- CharacterType [label = "{CharacterType|length: Int}"]
- CharacterVaryingType [label = "{CharacterVaryingType|length: Int}"]
- CharacterLargeObjectType [label = "CharacterLargeObjectType"]
- BinaryStringType [label = "BinaryStringType"]
- BinaryType [label = "{BinaryType|length: Int}"]
- BinaryVaryingType [label = "{BinaryVaryingType|length: Int}"]
- BinaryLargeObjectType [label = "BinaryLargeObjectType"]
- BooleanType [label = "BooleanType"]
- NumericType [label = "{NumericType|precisionRadix: Int\nprecision: Int}"]
- ExactNumericType [label = "{ExactNumericType|scale: Int}"]
- ApproximateNumericType [label = "ApproximateNumericType"]
- DateTimeType [label = "DateTimeType"]
- TimeType [label = "{TimeType|precisionRadix: Int\nsecondScale: Int}"]
- TimeWithoutTimezoneType [label = "TimeWithoutTimezoneType"]
- TimeWithTimezoneType [label = "TimeWithTimezoneType"]
- TimestampType [label = "{TimestampType|precisionRadix: Int\nsecondScale: Int}"]
- TimestampWithoutTimezoneType [label = "TimestampWithoutTimezoneType"]
- TimestampWithTimezoneType [label = "TimestampWithTimezoneType"]
- DateType [label = "DateType"]
- IntervalType [label = "{IntervalType|precisionRadix: Int\nsecondScale: Int}"]
- StringType -> DataType
- BooleanType -> DataType
- NumericType -> DataType
- DateTimeType -> DataType
- IntervalType -> DataType
- CharacterStringType -> StringType
- BinaryStringType -> StringType
- ExactNumericType -> NumericType
- ApproximateNumericType -> NumericType
- TimeType -> DateTimeType
- TimestampType -> DateTimeType
- DateType -> DateTimeType
- CharacterType -> CharacterStringType
- CharacterVaryingType -> CharacterStringType
- CharacterLargeObjectType -> CharacterStringType
- BinaryType -> BinaryStringType
- BinaryVaryingType -> BinaryStringType
- BinaryLargeObjectType -> BinaryStringType
- TimeWithoutTimezoneType -> TimeType
- TimeWithTimezoneType -> TimeType
- TimestampWithoutTimezoneType -> TimestampType
- TimestampWithTimezoneType -> TimestampType
-}
diff --git a/gitignore.SAMPLE b/gitignore.SAMPLE
index 3c15a5de9e..483ad4caca 100644
--- a/gitignore.SAMPLE
+++ b/gitignore.SAMPLE
@@ -27,4 +27,9 @@
/src/intellij/*.iml
/src/intellij/*.ipr
/src/intellij/*.iws
+/.cache
+/.idea
+/.settings
+# bak files produced by ./cleanup-commit
+*.bak
diff --git a/lib/forkjoin.jar.desired.sha1 b/lib/forkjoin.jar.desired.sha1
index d37b84d8c7..d31539daf4 100644
--- a/lib/forkjoin.jar.desired.sha1
+++ b/lib/forkjoin.jar.desired.sha1
@@ -1 +1 @@
-996fc132b05046112b9d4dc62e2d2c9057d836bc ?forkjoin.jar
+b5baf94dff8d3ca991d44a59add7bcbf6640379b ?forkjoin.jar
diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1
index 0bbbea1e7b..5a541f8cf3 100644
--- a/lib/scala-compiler.jar.desired.sha1
+++ b/lib/scala-compiler.jar.desired.sha1
@@ -1 +1 @@
-f9fcb59f3dbe1b060f8c57d4463dde5e0796951f ?scala-compiler.jar
+c020eccb8cf37963725985f36b44d070915cf4d2 ?scala-compiler.jar
diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1
index 51704e29c9..0ea32125f5 100644
--- a/lib/scala-library-src.jar.desired.sha1
+++ b/lib/scala-library-src.jar.desired.sha1
@@ -1 +1 @@
-d407ee67fa7e0d79e8e5786fb32ea7c9bdf5b088 ?scala-library-src.jar
+b85bc62675c2262a75ddcdd4df2dfc0ea0ddc2dd ?scala-library-src.jar
diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1
index 703eb006da..d059e861f0 100644
--- a/lib/scala-library.jar.desired.sha1
+++ b/lib/scala-library.jar.desired.sha1
@@ -1 +1 @@
-1d53671b52f2052c0690fcef9c9989150d8a4704 ?scala-library.jar
+31c7188cef85c28b84b9ce35bc6780996e5dd139 ?scala-library.jar
diff --git a/project/Build.scala b/project/Build.scala
index 5b09e053f0..25fb31cf5b 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -44,7 +44,7 @@ object ScalaBuild extends Build with Layers {
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
</scm>
<issueManagement>
<system>jira</system>
@@ -77,9 +77,9 @@ object ScalaBuild extends Build with Layers {
)
// Collections of projects to run 'compile' on.
- lazy val compiledProjects = Seq(quickLib, quickComp, continuationsLibrary, actors, swing, dbc, forkjoin, fjbg)
+ lazy val compiledProjects = Seq(quickLib, quickComp, continuationsLibrary, actors, swing, forkjoin, fjbg)
// Collection of projects to 'package' and 'publish' together.
- lazy val packagedBinaryProjects = Seq(scalaLibrary, scalaCompiler, swing, dbc, continuationsPlugin, jline, scalap)
+ lazy val packagedBinaryProjects = Seq(scalaLibrary, scalaCompiler, swing, continuationsPlugin, jline, scalap)
lazy val partestRunProjects = Seq(testsuite, continuationsTestsuite)
private def epflPomExtra = (
@@ -92,7 +92,7 @@ object ScalaBuild extends Build with Layers {
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
</scm>
<issueManagement>
<system>jira</system>
@@ -249,7 +249,6 @@ object ScalaBuild extends Build with Layers {
// TODO - Actors + swing separate jars...
lazy val dependentProjectSettings = settingOverrides ++ Seq(quickScalaInstance, quickScalaLibraryDependency, addCheaterDependency("scala-library"))
lazy val actors = Project("actors", file(".")) settings(dependentProjectSettings:_*) dependsOn(forkjoin % "provided")
- lazy val dbc = Project("dbc", file(".")) settings(dependentProjectSettings:_*)
// TODO - Remove actors dependency from pom...
lazy val swing = Project("swing", file(".")) settings(dependentProjectSettings:_*) dependsOn(actors % "provided")
// This project will generate man pages (in man1 and html) for scala.
@@ -489,7 +488,7 @@ object ScalaBuild extends Build with Layers {
genBin <<= genBinTask(genBinRunner, binDir, fullClasspath in Runtime, false),
binDir in genBinQuick <<= baseDirectory apply (_ / "target" / "bin"),
// Configure the classpath this way to avoid having .jar files and previous layers on the classpath.
- fullClasspath in Runtime in genBinQuick <<= Seq(quickComp,quickLib,scalap,actors,swing,dbc,fjbg,jline,forkjoin).map(classDirectory in Compile in _).join.map(Attributed.blankSeq),
+ fullClasspath in Runtime in genBinQuick <<= Seq(quickComp,quickLib,scalap,actors,swing,fjbg,jline,forkjoin).map(classDirectory in Compile in _).join.map(Attributed.blankSeq),
fullClasspath in Runtime in genBinQuick <++= (fullClasspath in Compile in jline),
genBinQuick <<= genBinTask(genBinRunner, binDir in genBinQuick, fullClasspath in Runtime in genBinQuick, true),
runManmakerMan <<= runManmakerTask(fullClasspath in Runtime in manmaker, runner in manmaker, "scala.tools.docutil.EmitManPage", "man1", ".1"),
@@ -518,10 +517,9 @@ object ScalaBuild extends Build with Layers {
},
// Add in some more dependencies
makeDistMappings <<= (makeDistMappings,
- packageBin in swing in Compile,
- packageBin in dbc in Compile) map {
+ packageBin in swing in Compile) map {
(dist, s, d) =>
- dist ++ Seq(s -> "lib/scala-swing.jar", d -> "lib/scala-dbc.jar")
+ dist ++ Seq(s -> "lib/scala-swing.jar")
},
makeDist <<= (makeDistMappings, baseDirectory, streams) map { (maps, dir, s) =>
s.log.debug("Map = " + maps.mkString("\n"))
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala
index aab533ae8d..bc9bbc6ef0 100644
--- a/src/actors/scala/actors/Actor.scala
+++ b/src/actors/scala/actors/Actor.scala
@@ -1,3 +1,5 @@
+
+
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2005-2011, LAMP/EPFL **
@@ -246,8 +248,8 @@ object Actor extends Combinators {
rawSelf.react(new RecursiveProxyHandler(rawSelf, f))
private class RecursiveProxyHandler(a: InternalReplyReactor, f: PartialFunction[Any, Unit])
- extends scala.runtime.AbstractPartialFunction[Any, Unit] {
- def _isDefinedAt(m: Any): Boolean =
+ extends PartialFunction[Any, Unit] {
+ def isDefinedAt(m: Any): Boolean =
true // events are immediately removed from the mailbox
def apply(m: Any) {
if (f.isDefinedAt(m)) f(m)
@@ -404,5 +406,5 @@ trait Actor extends InternalActor with ReplyReactor {
this
}
-}
+ }
diff --git a/src/actors/scala/actors/Future.scala b/src/actors/scala/actors/Future.scala
index eec43013d3..735c13190b 100644
--- a/src/actors/scala/actors/Future.scala
+++ b/src/actors/scala/actors/Future.scala
@@ -200,8 +200,8 @@ object Futures {
Actor.timer.schedule(timerTask, timeout)
def awaitWith(partFuns: Seq[PartialFunction[Any, Pair[Int, Any]]]) {
- val reaction: PartialFunction[Any, Unit] = new scala.runtime.AbstractPartialFunction[Any, Unit] {
- def _isDefinedAt(msg: Any) = msg match {
+ val reaction: PartialFunction[Any, Unit] = new PartialFunction[Any, Unit] {
+ def isDefinedAt(msg: Any) = msg match {
case TIMEOUT => true
case _ => partFuns exists (_ isDefinedAt msg)
}
diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala
index 8fc7578344..206a97d97c 100644
--- a/src/actors/scala/actors/Reactor.scala
+++ b/src/actors/scala/actors/Reactor.scala
@@ -38,8 +38,8 @@ private[actors] object Reactor {
}
}
- val waitingForNone: PartialFunction[Any, Unit] = new scala.runtime.AbstractPartialFunction[Any, Unit] {
- def _isDefinedAt(x: Any) = false
+ val waitingForNone: PartialFunction[Any, Unit] = new PartialFunction[Any, Unit] {
+ def isDefinedAt(x: Any) = false
def apply(x: Any) {}
}
}
diff --git a/src/build/genprod.scala b/src/build/genprod.scala
index 6016f6fb92..8a5c44f1c1 100644
--- a/src/build/genprod.scala
+++ b/src/build/genprod.scala
@@ -123,23 +123,7 @@ object FunctionOne extends Function(1) {
* assert(succ(0) == anonfun1(0))
* """)
- override def moreMethods = """
- /** Composes two instances of Function1 in a new Function1, with this function applied last.
- *
- * @tparam A the type to which function `g` can be applied
- * @param g a function A => T1
- * @return a new function `f` such that `f(x) == apply(g(x))`
- */
- def compose[A](g: A => T1): A => R = { x => apply(g(x)) }
-
- /** Composes two instances of Function1 in a new Function1, with this function applied first.
- *
- * @tparam A the result type of function `g`
- * @param g a function R => A
- * @return a new function `f` such that `f(x) == g(apply(x))`
- */
- def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) }
-"""
+ override def moreMethods = ""
}
object FunctionTwo extends Function(2) {
@@ -155,6 +139,8 @@ object FunctionTwo extends Function(2) {
* }
* assert(max(0, 1) == anonfun2(0, 1))
* """)
+
+ override def moreMethods = ""
}
object Function {
@@ -255,11 +241,6 @@ class Function(val i: Int) extends Group("Function") with Arity {
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */
object Tuple {
- val zipImports = """
-import scala.collection.{ TraversableLike => TLike, IterableLike => ILike }
-import scala.collection.generic.{ CanBuildFrom => CBF }
-"""
-
def make(i: Int) = apply(i)()
def apply(i: Int) = i match {
case 1 => TupleOne
@@ -276,7 +257,6 @@ object TupleOne extends Tuple(1)
object TupleTwo extends Tuple(2)
{
- override def imports = Tuple.zipImports
override def covariantSpecs = "@specialized(Int, Long, Double, Char, Boolean, AnyRef) "
override def moreMethods = """
/** Swaps the elements of this `Tuple`.
@@ -284,112 +264,14 @@ object TupleTwo extends Tuple(2)
* second element is the first element of this Tuple.
*/
def swap: Tuple2[T2,T1] = Tuple2(_2, _1)
-
- @deprecated("Use `zipped` instead.", "2.9.0")
- def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1],
- w2: T2 => Iterable[El2],
- cbf1: CBF[Repr1, (El1, El2), To]): To = {
- zipped map ((x, y) => ((x, y)))
- }
-
- /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc.
- * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]]
- * or [[scala.collection.IterableLike]].
- * {{{
- * scala> val tuple = (List(1,2,3),List('a','b','c'))
- * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c))
- *
- * scala> tuple.zipped map { (x,y) => x + ":" + y }
- * res6: List[java.lang.String] = List(1:a, 2:b, 3:c)
- * }}}
- *
- * @see Zipped
- * Note: will not terminate for infinite-sized collections.
- */
- def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2]
- = new Zipped[Repr1, El1, Repr2, El2](_1, _2)
-
- class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { // coll2: ILike for filter
- def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = {
- val b = cbf(coll1.repr)
- b.sizeHint(coll1)
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext)
- b += f(el1, elems2.next)
- else
- return b.result
- }
-
- b.result
- }
-
- def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = {
- val b = cbf(coll1.repr)
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext)
- b ++= f(el1, elems2.next)
- else
- return b.result
- }
-
- b.result
- }
-
- def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = {
- val b1 = cbf1(coll1.repr)
- val b2 = cbf2(coll2.repr)
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext) {
- val el2 = elems2.next
- if (f(el1, el2)) {
- b1 += el1
- b2 += el2
- }
- }
- else return (b1.result, b2.result)
- }
-
- (b1.result, b2.result)
- }
-
- def exists(f: (El1, El2) => Boolean): Boolean = {
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext) {
- if (f(el1, elems2.next))
- return true
- }
- else return false
- }
- false
- }
-
- def forall(f: (El1, El2) => Boolean): Boolean =
- !exists((x, y) => !f(x, y))
-
- def foreach[U](f: (El1, El2) => U): Unit = {
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext)
- f(el1, elems2.next)
- else
- return
- }
- }
- }
"""
}
object TupleThree extends Tuple(3) {
- override def imports = Tuple.zipImports
+ override def imports = """
+import scala.collection.{ TraversableLike => TLike, IterableLike => ILike }
+import scala.collection.generic.{ CanBuildFrom => CBF }
+ """
override def moreMethods = """
@deprecated("Use `zipped` instead.", "2.9.0")
@@ -578,7 +460,7 @@ class Product(val i: Int) extends Group("Product") with Arity {
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
"""
diff --git a/src/build/maven/continuations-plugin-pom.xml b/src/build/maven/continuations-plugin-pom.xml
index aca519b87e..9abb0a36f0 100644
--- a/src/build/maven/continuations-plugin-pom.xml
+++ b/src/build/maven/continuations-plugin-pom.xml
@@ -23,13 +23,12 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
<dependencies>
diff --git a/src/build/maven/jline-pom.xml b/src/build/maven/jline-pom.xml
index 4752deb5e0..0d6e801551 100644
--- a/src/build/maven/jline-pom.xml
+++ b/src/build/maven/jline-pom.xml
@@ -28,13 +28,12 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
<dependencies>
diff --git a/src/build/maven/maven-deploy.xml b/src/build/maven/maven-deploy.xml
index 7f8343a84e..ac0f8f745b 100644
--- a/src/build/maven/maven-deploy.xml
+++ b/src/build/maven/maven-deploy.xml
@@ -112,7 +112,6 @@
<deploy-local name="scala-compiler" version="@{version}" repository="@{repository}" />
<deploy-local-plugin name="continuations" version="@{version}" repository="@{repository}"/>
<deploy-local name="scala-actors" version="@{version}" repository="@{repository}" />
- <deploy-local name="scala-dbc" version="@{version}" repository="@{repository}" />
<deploy-local name="scala-swing" version="@{version}" repository="@{repository}"/>
<deploy-local name="scalap" version="@{version}" repository="@{repository}"/>
<deploy-local name="scala-partest" version="@{version}" repository="@{repository}"/>
@@ -171,7 +170,6 @@
</deploy-remote>
<deploy-remote name="jline" version="@{version}" repository="@{repository}"/>
<deploy-remote name="scala-compiler" version="@{version}" repository="@{repository}" />
- <deploy-remote name="scala-dbc" version="@{version}" repository="@{repository}" />
<deploy-remote name="scala-swing" version="@{version}" repository="@{repository}"/>
<deploy-remote name="scala-actors" version="@{version}" repository="@{repository}"/>
<deploy-remote name="scalap" version="@{version}" repository="@{repository}"/>
@@ -239,7 +237,6 @@
<deploy-remote-signed name="scala-library" version="@{version}" repository="@{repository}"/>
<deploy-remote-signed name="jline" version="@{version}" repository="@{repository}"/>
<deploy-remote-signed name="scala-compiler" version="@{version}" repository="@{repository}" />
- <deploy-remote-signed name="scala-dbc" version="@{version}" repository="@{repository}" />
<deploy-remote-signed name="scala-swing" version="@{version}" repository="@{repository}"/>
<deploy-remote-signed name="scala-actors" version="@{version}" repository="@{repository}"/>
<deploy-remote-signed name="scalap" version="@{version}" repository="@{repository}"/>
diff --git a/src/build/maven/scala-actors-pom.xml b/src/build/maven/scala-actors-pom.xml
index 12bae2a23d..e8c6649721 100644
--- a/src/build/maven/scala-actors-pom.xml
+++ b/src/build/maven/scala-actors-pom.xml
@@ -23,13 +23,12 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
<dependencies>
<dependency>
diff --git a/src/build/maven/scala-compiler-pom.xml b/src/build/maven/scala-compiler-pom.xml
index f9bcb6719d..82d0ed7c91 100644
--- a/src/build/maven/scala-compiler-pom.xml
+++ b/src/build/maven/scala-compiler-pom.xml
@@ -23,13 +23,12 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
<dependencies>
diff --git a/src/build/maven/scala-dbc-pom.xml b/src/build/maven/scala-dbc-pom.xml
deleted file mode 100644
index 23092d10ad..0000000000
--- a/src/build/maven/scala-dbc-pom.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<project
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.scala-lang</groupId>
- <artifactId>scala-dbc</artifactId>
- <packaging>jar</packaging>
- <version>@VERSION@</version>
- <name>Scala Database Connectivity</name>
- <description>Connectivity for your DBs</description>
- <url>http://www.scala-lang.org/</url>
- <inceptionYear>2002</inceptionYear>
- <organization>
- <name>LAMP/EPFL</name>
- <url>http://lamp.epfl.ch/</url>
- </organization>
- <licenses>
- <license>
- <name>BSD-like</name>
- <url>http://www.scala-lang.org/downloads/license.html
- </url>
- <distribution>repo</distribution>
- </license>
- </licenses>
- <scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
- </scm>
- <issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
- </issueManagement>
- <dependencies>
- <dependency>
- <groupId>org.scala-lang</groupId>
- <artifactId>scala-library</artifactId>
- <version>@VERSION@</version>
- </dependency>
- </dependencies>
- <distributionManagement>
- <repository>
- <id>scala-tools.org</id>
- <url>@RELEASE_REPOSITORY@</url>
- </repository>
- <snapshotRepository>
- <id>scala-tools.org</id>
- <url>@SNAPSHOT_REPOSITORY@</url>
- <uniqueVersion>false</uniqueVersion>
- </snapshotRepository>
- </distributionManagement>
- <developers>
- <developer>
- <id>lamp</id>
- <name>EPFL LAMP</name>
- </developer>
- <developer>
- <id>Typesafe</id>
- <name>Typesafe, Inc.</name>
- </developer>
- </developers>
-</project>
diff --git a/src/build/maven/scala-dotnet-library-pom.xml b/src/build/maven/scala-dotnet-library-pom.xml
index 339460924a..007e8be173 100644
--- a/src/build/maven/scala-dotnet-library-pom.xml
+++ b/src/build/maven/scala-dotnet-library-pom.xml
@@ -24,13 +24,12 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
<distributionManagement>
<repository>
diff --git a/src/build/maven/scala-library-pom.xml b/src/build/maven/scala-library-pom.xml
index 8e0abd4937..e8db512125 100644
--- a/src/build/maven/scala-library-pom.xml
+++ b/src/build/maven/scala-library-pom.xml
@@ -23,25 +23,31 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
- <distributionManagement>
- <repository>
- <id>scala-tools.org</id>
- <url>@RELEASE_REPOSITORY@</url>
- </repository>
- <snapshotRepository>
- <id>scala-tools.org</id>
- <url>@SNAPSHOT_REPOSITORY@</url>
- <uniqueVersion>false</uniqueVersion>
- </snapshotRepository>
- </distributionManagement>
+ <dependencies>
+ <dependency>
+ <groupId>com.typesafe</groupId>
+ <artifactId>config</artifactId>
+ <version>0.4.0</version>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <repository>
+ <id>scala-tools.org</id>
+ <url>@RELEASE_REPOSITORY@</url>
+ </repository>
+ <snapshotRepository>
+ <id>scala-tools.org</id>
+ <url>@SNAPSHOT_REPOSITORY@</url>
+ <uniqueVersion>false</uniqueVersion>
+ </snapshotRepository>
+ </distributionManagement>
<developers>
<developer>
<id>lamp</id>
diff --git a/src/build/maven/scala-partest-pom.xml b/src/build/maven/scala-partest-pom.xml
index f18ca46c50..ac05f242d5 100644
--- a/src/build/maven/scala-partest-pom.xml
+++ b/src/build/maven/scala-partest-pom.xml
@@ -23,13 +23,12 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
<dependencies>
diff --git a/src/build/maven/scala-swing-pom.xml b/src/build/maven/scala-swing-pom.xml
index a03bc07ab0..3df5db5b21 100644
--- a/src/build/maven/scala-swing-pom.xml
+++ b/src/build/maven/scala-swing-pom.xml
@@ -23,13 +23,12 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
<dependencies>
<dependency>
diff --git a/src/build/maven/scalap-pom.xml b/src/build/maven/scalap-pom.xml
index d7f867d4a1..50c08e899c 100644
--- a/src/build/maven/scalap-pom.xml
+++ b/src/build/maven/scalap-pom.xml
@@ -23,13 +23,12 @@
</license>
</licenses>
<scm>
- <connection>scm:svn:http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk</connection>
- <url>https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk</url>
+ <connection>scm:git:git://github.com/scala/scala.git</connection>
+ <url>https://github.com/scala/scala.git</url>
</scm>
<issueManagement>
- <system>trac</system>
- <url>http://lampsvn.epfl.ch/trac/scala
- </url>
+ <system>JIRA</system>
+ <url>https://issues.scala-lang.org/</url>
</issueManagement>
<dependencies>
diff --git a/src/build/pack.xml b/src/build/pack.xml
index c12cfa44bf..f96c6b9799 100644
--- a/src/build/pack.xml
+++ b/src/build/pack.xml
@@ -3,14 +3,13 @@
<project name="sabbus-pack">
<description>
- SuperSabbus extension for packaging a distribution to Sbaz or other distribution methods. THIS FILE IS NOT STAND-ALONE AND SHOULD ONLY BE USED THROUGH ENTRY POINTS IN SUPERSABBUS.
+ SuperSabbus extension for packaging a distribution. THIS FILE IS NOT STAND-ALONE AND SHOULD ONLY BE USED THROUGH ENTRY POINTS IN SUPERSABBUS.
</description>
<!-- ===========================================================================
PROPERTIES
============================================================================ -->
- <property name="sbaz.universe" value="http://www.scala-lang.org/downloads/packages"/>
<property file="${basedir}/build.number.maven"/>
<!-- the maven stuff requires version.major, version.minor and version.patch properties.
the "get-scala-revision" script only returns "version.number" -->
@@ -78,6 +77,7 @@ MAIN DISTRIBUTION PACKAGING
<exclude name="logs/**"/>
<exclude name="sandbox/**"/>
<exclude name="test/partest"/>
+ <exclude name=".git"/>
</tarfileset>
<tarfileset dir="${basedir}" prefix="${dist.name}-sources" filemode="755">
<include name="test/partest"/>
@@ -95,111 +95,22 @@ MAIN DISTRIBUTION PACKAGING
</fileset>
</checksum>
</target>
-
- <target name="pack-archives.done" depends="pack-archives.src"/>
-
-<!-- ===========================================================================
-MAIN DISTRIBUTION SBAZ
-============================================================================ -->
-
- <target name="pack-sbaz.start">
- <mkdir dir="${dists.dir}/sbaz"/>
- </target>
-
- <target name="pack-sbaz.lib" depends="pack-sbaz.start">
- <sbaz
- file="${dists.dir}/sbaz/scala-library-${version.number}.sbp"
- adfile="${dists.dir}/sbaz/scala-library-${version.number}.advert"
- name="scala-library"
- version="${version.number}"
- desc="The Scala library. This is the minimal requirement to run any Scala program."
- link="${sbaz.universe}/scala-library-${version.number}.sbp">
- <libset dir="${dist.dir}/lib" includes="scala-library.jar,scala-dbc.jar,scala-swing.jar,scala-actors.jar"/>
- <srcset dir="${dist.dir}/src" includes="scala-library-src.jar,scala-dbc-src.jar,scala-swing-src.jar,scala-actors-src.jar"/>
- <looseset destination="doc">
- <fileset dir="${dist.dir}/doc" includes="LICENSE,README"/>
- </looseset>
- </sbaz>
- </target>
-
- <target name="pack-sbaz.comp" depends="pack-sbaz.lib">
- <sbaz
- file="${dists.dir}/sbaz/scala-devel-${version.number}.sbp"
- adfile="${dists.dir}/sbaz/scala-devel-${version.number}.advert"
- name="scala-devel"
- version="${version.number}"
- desc="The Scala developer tools. This contains everything that is required to write, test and document new Scala programs."
- depends="scala-library"
- link="${sbaz.universe}/scala-devel-${version.number}.sbp">
- <binset
- dir="${dist.dir}/bin"
- includes="scala,scala.bat,scalac,scalac.bat,scaladoc,scaladoc.bat,fsc,fsc.bat"/>
- <libset dir="${dist.dir}/lib" includes="scala-compiler.jar,jline.jar"/>
- <miscset dir="${dist.dir}/misc/scala-devel"
- includes="plugins/continuations.jar"/>
- <manset dir="${dist.dir}/man" includes="**"/>
- <srcset dir="${dist.dir}/src" includes="scala-compiler-src.jar"/>
- </sbaz>
- </target>
- <target name="pack-sbaz.test" depends="pack-sbaz.comp">
- <sbaz
- file="${dists.dir}/sbaz/scala-test-${version.number}.sbp"
- adfile="${dists.dir}/sbaz/scala-test-${version.number}.advert"
- name="scala-test"
- version="${version.number}"
- desc="The Scala test package contains everything needed to test Scala."
- link="${sbaz.universe}/scala-test-${version.number}.sbp">
- <binset dir="${basedir}/test"
- includes="clitest,diff/diff.*,diff/lib*.dll,partest,partest.bat"/>
- <miscset dir="${basedir}/test"
- includes="files/**/*.args,files/**/*.check,files/**/*.dll,files/**/*.jar,files/**/*.java,files/**/*.scala,files/**/*.flags,files/cli/**/*.check.*,files/jvm/*.so,files/shootout/*.javaopts,files/shootout/*.runner,files/shootout/*.txt,files/specialized/*.txt,files/**/*.test"
- excludes="files/presentation"/>
- <!-- <srcset dir="${dist.dir}/src" includes="scala-partest-src.jar"/> -->
- <libset dir="${dist.dir}/lib" includes="scala-partest.jar"/>
- <libset dir="${lib.dir}" includes="scalacheck.jar"/>
- </sbaz>
- </target>
-
- <target name="pack-sbaz.scalap" depends="pack-sbaz.test">
- <sbaz
- file="${dists.dir}/sbaz/scalap-${version.number}.sbp"
- adfile="${dists.dir}/sbaz/scalap-${version.number}.advert"
- name="scalap"
- version="${version.number}"
- desc="The scalap package contains the Scala classfile decoder."
- link="${sbaz.universe}/scalap-${version.number}.sbp">
- <binset dir="${dist.dir}/bin"
- includes="scalap,scalap.bat"/>
- <libset dir="${dist.dir}/lib" includes="scalap.jar"/>
- </sbaz>
- </target>
-
- <target name="pack-sbaz.doc" depends="pack-sbaz.scalap">
- <sbaz
- file="${dists.dir}/sbaz/scala-devel-docs-${version.number}.sbp"
- adfile="${dists.dir}/sbaz/scala-devel-docs-${version.number}.advert"
- name="scala-devel-docs"
- version="${version.number}"
- desc="The Scala developer documentation. This contains all developer documentation."
- link="${sbaz.universe}/scala-devel-docs-${version.number}.sbp">
- <docset dir="${dist.dir}/doc/scala-devel-docs"/>
- </sbaz>
+ <target name="pack-archives.latest.unix" depends="pack-archives.src" unless="os.win">
+ <symlink link="${dists.dir}/archives/scala-latest-sources.tgz"
+ resource="${dists.dir}/archives/scala-${version.number}-sources.tgz"
+ overwrite="yes"/>
</target>
- <target name="pack-sbaz.all" depends="pack-sbaz.doc">
- <sbaz
- file="${dists.dir}/sbaz/${dist.name}.sbp"
- adfile="${dists.dir}/sbaz/${dist.name}.advert"
- name="scala"
- version="${version.number}"
- desc="The base Scala package that contains everything needed to start using Scala."
- depends="scala-library,scala-devel"
- link="${sbaz.universe}/${dist.name}.sbp"/>
+ <target name="pack-archives.latest.win" depends="pack-archives.src" if="os.win">
+ <copy tofile="${dists.dir}/archives/scala-latest-sources.tgz">
+ <fileset dir="${dists.dir}/archives">
+ <include name="scala-${version.number}-sources.tgz"/>
+ </fileset>
+ </copy>
</target>
-
- <target name="pack-sbaz.done" depends="pack-sbaz.all"/>
+ <target name="pack-archives.done" depends="pack-archives.src, pack-archives.latest.win, pack-archives.latest.unix"/>
<target name="pack-maven.start">
<mkdir dir="${dists.dir}/maven/${version.number}"/>
@@ -226,7 +137,6 @@ MAIN DISTRIBUTION SBAZ
<mvn-copy-lib mvn.artifact.name="jline"/>
<mvn-copy-lib mvn.artifact.name="scala-library"/>
<mvn-copy-lib mvn.artifact.name="scala-compiler"/>
- <mvn-copy-lib mvn.artifact.name="scala-dbc"/>
<mvn-copy-lib mvn.artifact.name="scala-swing"/>
<mvn-copy-lib mvn.artifact.name="scala-actors"/>
<mvn-copy-lib mvn.artifact.name="scala-partest"/>
@@ -291,11 +201,9 @@ MAIN DISTRIBUTION SBAZ
basedir="${build-docs.dir}/continuations-plugin">
<include name="**/*"/>
</jar>
- <!-- TODO - Scala swing, dbc and actors should maybe have thier own jar, but creating it is SLOW. -->
+ <!-- TODO - Scala swing and actors should maybe have thier own jar, but creating it is SLOW. -->
<copy tofile="${dists.dir}/maven/${version.number}/scala-swing/scala-swing-docs.jar"
file="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar"/>
- <copy tofile="${dists.dir}/maven/${version.number}/scala-dbc/scala-dbc-docs.jar"
- file="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar"/>
<copy tofile="${dists.dir}/maven/${version.number}/scala-actors/scala-actors-docs.jar"
file="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar"/>
</target>
@@ -327,7 +235,7 @@ MAIN DISTRIBUTION SBAZ
MISCELLANEOUS
============================================================================ -->
- <target name="pack-all.done" depends="pack-archives.done, pack-sbaz.done, pack-maven.done"/>
+ <target name="pack-all.done" depends="pack-archives.done, pack-maven.done"/>
<!-- ===========================================================================
MISCELLANEOUS
diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
index 9a7c79d856..fe0175fe72 100644
--- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
@@ -116,7 +116,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
// Classfile annot: args empty. Scala annot: assocs empty.
assert(args.isEmpty || assocs.isEmpty, atp)
- // @xeno.by: necessary for reification, see Reifiers.scala for more info
+ // necessary for reification, see Reifiers.scala for more info
private var orig: Tree = EmptyTree
def original = orig
def setOriginal(t: Tree): this.type = { orig = t; this }
@@ -168,24 +168,15 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
*
* `assocs` stores arguments to classfile annotations as name-value pairs.
*/
- sealed abstract class AnnotationInfo extends Product3[Type, List[Tree], List[(Name, ClassfileAnnotArg)]] {
+ sealed abstract class AnnotationInfo {
def atp: Type
def args: List[Tree]
def assocs: List[(Name, ClassfileAnnotArg)]
- // @xeno.by: necessary for reification, see Reifiers.scala for more info
+ // necessary for reification, see Reifiers.scala for more info
def original: Tree
def setOriginal(t: Tree): this.type
- /** Hand rolling Product. */
- def _1 = atp
- def _2 = args
- def _3 = assocs
- // @xeno.by: original hasn't become a product member for backward compatibility purposes
- // def _4 = original
- def canEqual(other: Any) = other.isInstanceOf[AnnotationInfo]
- override def productPrefix = "AnnotationInfo"
-
// see annotationArgRewriter
lazy val isTrivial = atp.isTrivial && !hasArgWhich(_.isInstanceOf[This])
@@ -269,8 +260,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
}
}
- lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] =
- reflect.ClassManifest.classType(classOf[ClassfileAnnotArg])
+ lazy val classfileAnnotArgTag: ArrayTag[ClassfileAnnotArg] = arrayTag[ClassfileAnnotArg]
object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil)
}
diff --git a/src/compiler/scala/reflect/internal/CapturedVariables.scala b/src/compiler/scala/reflect/internal/CapturedVariables.scala
new file mode 100644
index 0000000000..77909d9157
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/CapturedVariables.scala
@@ -0,0 +1,36 @@
+package scala.reflect
+package internal
+
+import Flags._
+
+trait CapturedVariables { self: SymbolTable =>
+
+ import definitions._
+
+ /** Mark a variable as captured; i.e. force boxing in a *Ref type.
+ */
+ def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED
+
+ /** Mark given identifier as a reference to a captured variable itself
+ * suppressing dereferencing with the `elem` field.
+ */
+ def referenceCapturedVariable(vble: Symbol): Tree = ReferenceToBoxed(Ident(vble))
+
+ /** Convert type of a captured variable to *Ref type.
+ */
+ def capturedVariableType(vble: Symbol): Type =
+ capturedVariableType(vble, NoType, false)
+
+ /** Convert type of a captured variable to *Ref type.
+ */
+ def capturedVariableType(vble: Symbol, tpe: Type = NoType, erasedTypes: Boolean = false): Type = {
+ val tpe1 = if (tpe == NoType) vble.tpe else tpe
+ val symClass = tpe1.typeSymbol
+ def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) =
+ if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe
+ else if (erasedTypes) objectRefClass.tpe
+ else appliedType(objectRefClass, tpe)
+ if (vble.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass)
+ else refType(refClass, ObjectRefClass)
+ }
+}
diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala
index c328cc49cb..135d18d5ad 100644
--- a/src/compiler/scala/reflect/internal/Constants.scala
+++ b/src/compiler/scala/reflect/internal/Constants.scala
@@ -26,7 +26,7 @@ trait Constants extends api.Constants {
final val DoubleTag = 9
final val StringTag = 10
final val NullTag = 11
- final val ClassTag = 12
+ final val ClazzTag = 12
// For supporting java enumerations inside java annotations (see ClassfileParser)
final val EnumTag = 13
@@ -43,7 +43,7 @@ trait Constants extends api.Constants {
case x: Double => DoubleTag
case x: String => StringTag
case x: Char => CharTag
- case x: Type => ClassTag
+ case x: Type => ClazzTag
case x: Symbol => EnumTag
case _ => throw new Error("bad constant value: " + value + " of class " + value.getClass)
}
@@ -70,7 +70,7 @@ trait Constants extends api.Constants {
case DoubleTag => DoubleClass.tpe
case StringTag => StringClass.tpe
case NullTag => NullClass.tpe
- case ClassTag => ClassType(value.asInstanceOf[Type])
+ case ClazzTag => ClassType(value.asInstanceOf[Type])
case EnumTag =>
// given (in java): "class A { enum E { VAL1 } }"
// - symbolValue: the symbol of the actual enumeration value (VAL1)
@@ -201,7 +201,7 @@ trait Constants extends api.Constants {
def stringValue: String =
if (value == null) "null"
- else if (tag == ClassTag) signature(typeValue)
+ else if (tag == ClazzTag) signature(typeValue)
else value.toString()
@switch def escapedChar(ch: Char): String = ch match {
@@ -221,7 +221,7 @@ trait Constants extends api.Constants {
tag match {
case NullTag => "null"
case StringTag => "\"" + escape(stringValue) + "\""
- case ClassTag => "classOf[" + signature(typeValue) + "]"
+ case ClazzTag => "classOf[" + signature(typeValue) + "]"
case CharTag => "'" + escapedChar(charValue) + "'"
case LongTag => longValue.toString() + "L"
case _ => String.valueOf(value)
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index a2dd6fc4c3..d89e852124 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -10,10 +10,31 @@ import annotation.{ switch }
import scala.collection.{ mutable, immutable }
import Flags._
import PartialFunction._
+import scala.reflect.{ mirror => rm }
trait Definitions extends reflect.api.StandardDefinitions {
self: SymbolTable =>
+ object definitions extends DefinitionsClass
+
+ // [Eugene] find a way to make these non-lazy
+ lazy val ByteTpe = definitions.ByteClass.asType
+ lazy val ShortTpe = definitions.ShortClass.asType
+ lazy val CharTpe = definitions.CharClass.asType
+ lazy val IntTpe = definitions.IntClass.asType
+ lazy val LongTpe = definitions.LongClass.asType
+ lazy val FloatTpe = definitions.FloatClass.asType
+ lazy val DoubleTpe = definitions.DoubleClass.asType
+ lazy val BooleanTpe = definitions.BooleanClass.asType
+ lazy val UnitTpe = definitions.UnitClass.asType
+ lazy val AnyTpe = definitions.AnyClass.asType
+ lazy val ObjectTpe = definitions.ObjectClass.asType
+ lazy val AnyValTpe = definitions.AnyValClass.asType
+ lazy val AnyRefTpe = definitions.AnyRefClass.asType
+ lazy val NothingTpe = definitions.NothingClass.asType
+ lazy val NullTpe = definitions.NullClass.asType
+ lazy val StringTpe = definitions.StringClass.asType
+
/** Since both the value parameter types and the result type may
* require access to the type parameter symbols, we model polymorphic
* creation as a function from those symbols to (formal types, result type).
@@ -22,34 +43,21 @@ trait Definitions extends reflect.api.StandardDefinitions {
*/
private type PolyMethodCreator = List[Symbol] => (Option[List[Type]], Type)
- private def enterNewClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): Symbol = {
+ private def enterNewClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): ClassSymbol = {
val clazz = owner.newClassSymbol(name, NoPosition, flags)
clazz setInfoAndEnter ClassInfoType(parents, newScope, clazz)
}
- private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol = {
+ private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol = {
val msym = owner.newMethod(name.encode, NoPosition, flags)
val params = msym.newSyntheticValueParams(formals)
msym setInfo MethodType(params, restpe)
}
- private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol =
+ private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): MethodSymbol =
owner.info.decls enter newMethod(owner, name, formals, restpe, flags)
// the scala value classes
trait ValueClassDefinitions {
- self: definitions.type =>
-
- private[Definitions] def valueCache(name: Name) = {
- val res = (
- if (name.isTypeName) ScalaPackageClass.info member name
- else ScalaPackageClass.info member name suchThat (_ hasFlag MODULE)
- )
- if (res eq NoSymbol)
- abort("Could not find value classes! This is a catastrophic failure. scala " + scala.util.Properties.versionString)
- else res
- }
- private[Definitions] def valueModuleMethod(className: Name, methodName: Name): Symbol = {
- valueCache(className.toTermName).moduleClass.tpe member methodName
- }
+ self: DefinitionsClass =>
import ClassfileConstants._
@@ -75,8 +83,27 @@ trait Definitions extends reflect.api.StandardDefinitions {
tpnme.Unit -> VOID_TAG
)
+ private def catastrophicFailure() =
+ abort("Could not find value classes! This is a catastrophic failure. scala " +
+ scala.util.Properties.versionString)
+
+ private def valueClassSymbol(name: TypeName): ClassSymbol = {
+ getMember(ScalaPackageClass, name) match {
+ case x: ClassSymbol => x
+ case _ => catastrophicFailure()
+ }
+ }
+ private def valueClassCompanion(name: TermName): ModuleSymbol = {
+ getMember(ScalaPackageClass, name) match {
+ case x: ModuleSymbol => x
+ case _ => catastrophicFailure()
+ }
+ }
+ private def valueCompanionMember(className: Name, methodName: TermName): MethodSymbol =
+ getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName)
+
private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f)
- private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = syms zip (syms map (x => f(x.name))) toMap
+ private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = mapFrom(syms)(x => f(x.name))
private def symbolsMapFilt[T](syms: List[Symbol], p: Name => Boolean, f: Name => T) = symbolsMap(syms filter (x => p(x.name)), f)
private def boxedName(name: Name) = sn.Boxed(name.toTypeName)
@@ -87,8 +114,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val boxedClass = classesMap(x => getClass(boxedName(x)))
lazy val refClass = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref"))
lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref"))
- lazy val boxMethod = classesMap(x => valueModuleMethod(x, nme.box))
- lazy val unboxMethod = classesMap(x => valueModuleMethod(x, nme.unbox))
+ lazy val boxMethod = classesMap(x => valueCompanionMember(x, nme.box))
+ lazy val unboxMethod = classesMap(x => valueCompanionMember(x, nme.unbox))
def isNumericSubClass(sub: Symbol, sup: Symbol) = (
(numericWeight contains sub)
@@ -97,27 +124,28 @@ trait Definitions extends reflect.api.StandardDefinitions {
)
/** Is symbol a numeric value class? */
- def isNumericValueClass(sym: Symbol): Boolean =
- numericWeight contains sym
+ def isNumericValueClass(sym: Symbol) = ScalaNumericValueClasses contains sym
def isGetClass(sym: Symbol) =
- (sym.name == nme.getClass_) && (sym.paramss.isEmpty || sym.paramss.head.isEmpty)
-
- lazy val UnitClass = valueCache(tpnme.Unit)
- lazy val ByteClass = valueCache(tpnme.Byte)
- lazy val ShortClass = valueCache(tpnme.Short)
- lazy val CharClass = valueCache(tpnme.Char)
- lazy val IntClass = valueCache(tpnme.Int)
- lazy val LongClass = valueCache(tpnme.Long)
- lazy val FloatClass = valueCache(tpnme.Float)
- lazy val DoubleClass = valueCache(tpnme.Double)
- lazy val BooleanClass = valueCache(tpnme.Boolean)
+ (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss)
+
+ lazy val UnitClass = valueClassSymbol(tpnme.Unit)
+ lazy val ByteClass = valueClassSymbol(tpnme.Byte)
+ lazy val ShortClass = valueClassSymbol(tpnme.Short)
+ lazy val CharClass = valueClassSymbol(tpnme.Char)
+ lazy val IntClass = valueClassSymbol(tpnme.Int)
+ lazy val LongClass = valueClassSymbol(tpnme.Long)
+ lazy val FloatClass = valueClassSymbol(tpnme.Float)
+ lazy val DoubleClass = valueClassSymbol(tpnme.Double)
+ lazy val BooleanClass = valueClassSymbol(tpnme.Boolean)
lazy val Boolean_and = getMember(BooleanClass, nme.ZAND)
lazy val Boolean_or = getMember(BooleanClass, nme.ZOR)
lazy val Boolean_not = getMember(BooleanClass, nme.UNARY_!)
+ lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass)
+
def ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass)
- def ScalaValueClasses: List[Symbol] = List(
+ def ScalaValueClasses: List[ClassSymbol] = List(
UnitClass,
BooleanClass,
ByteClass,
@@ -129,54 +157,83 @@ trait Definitions extends reflect.api.StandardDefinitions {
DoubleClass
)
def ScalaValueClassCompanions: List[Symbol] = ScalaValueClasses map (_.companionSymbol)
+ def ScalaPrimitiveValueClasses: List[ClassSymbol] = ScalaValueClasses
}
- object definitions extends AbsDefinitions with ValueClassDefinitions {
+ abstract class DefinitionsClass extends AbsDefinitions with ValueClassDefinitions {
private var isInitialized = false
def isDefinitionsInitialized = isInitialized
// symbols related to packages
var emptypackagescope: Scope = null //debug
- // This is the package _root_. The actual root cannot be referenced at
- // the source level, but _root_ is essentially a function () => <root>.
- lazy val RootPackage: Symbol = {
- val rp = (
- NoSymbol.newValue(nme.ROOTPKG, NoPosition, FINAL | MODULE | PACKAGE | JAVA)
- setInfo NullaryMethodType(RootClass.tpe)
- )
- RootClass.sourceModule = rp
- rp
+ // TODO - having these as objects means they elude the attempt to
+ // add synchronization in SynchronizedSymbols. But we should either
+ // flip on object overrides or find some other accomodation, because
+ // lazy vals are unnecessarily expensive relative to objects and it
+ // is very beneficial for a handful of bootstrap symbols to have
+ // first class identities
+ sealed trait WellKnownSymbol extends Symbol {
+ this initFlags TopLevelCreationFlags
+ }
+ // Features common to RootClass and RootPackage, the roots of all
+ // type and term symbols respectively.
+ sealed trait RootSymbol extends WellKnownSymbol {
+ final override def isRootSymbol = true
+ override def owner = NoSymbol
+ override def typeOfThis = thisSym.tpe
}
+ // This is the package _root_. The actual root cannot be referenced at
+ // the source level, but _root_ is essentially a function => <root>.
+ final object RootPackage extends PackageSymbol(NoSymbol, NoPosition, nme.ROOTPKG) with RootSymbol {
+ this setInfo NullaryMethodType(RootClass.tpe)
+ RootClass.sourceModule = this
- // This is the actual root of everything, including the package _root_.
- lazy val RootClass: ModuleClassSymbol = (
- NoSymbol.newModuleClassSymbol(tpnme.ROOT, NoPosition, FINAL | MODULE | PACKAGE | JAVA)
- setInfo rootLoader
- )
+ override def isRootPackage = true
+ }
+ // This is <root>, the actual root of everything except the package _root_.
+ // <root> and _root_ (RootPackage and RootClass) should be the only "well known"
+ // symbols owned by NoSymbol. All owner chains should go through RootClass,
+ // although it is probable that some symbols are created as direct children
+ // of NoSymbol to ensure they will not be stumbled upon. (We should designate
+ // a better encapsulated place for that.)
+ final object RootClass extends PackageClassSymbol(NoSymbol, NoPosition, tpnme.ROOT) with RootSymbol {
+ this setInfo rootLoader
+
+ override def isRoot = true
+ override def isEffectiveRoot = true
+ override def isStatic = true
+ override def isNestedClass = false
+ override def ownerOfNewSymbols = EmptyPackageClass
+ }
// The empty package, which holds all top level types without given packages.
- lazy val EmptyPackage = RootClass.newPackage(nme.EMPTY_PACKAGE_NAME, NoPosition, FINAL)
- lazy val EmptyPackageClass = EmptyPackage.moduleClass
-
- lazy val JavaLangPackage = getModule(sn.JavaLang)
+ final object EmptyPackage extends PackageSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
+ override def isEmptyPackage = true
+ }
+ final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
+ override def isEffectiveRoot = true
+ override def isEmptyPackageClass = true
+ }
+ // It becomes tricky to create dedicated objects for other symbols because
+ // of initialization order issues.
+ lazy val JavaLangPackage = getRequiredPackage(sn.JavaLang)
lazy val JavaLangPackageClass = JavaLangPackage.moduleClass
- lazy val ScalaPackage = getModule(nme.scala_)
+ lazy val ScalaPackage = getRequiredPackage(nme.scala_)
lazy val ScalaPackageClass = ScalaPackage.moduleClass
-
- lazy val RuntimePackage = getRequiredModule("scala.runtime")
+ lazy val RuntimePackage = getRequiredPackage("scala.runtime")
lazy val RuntimePackageClass = RuntimePackage.moduleClass
- lazy val JavaLangEnumClass = getRequiredClass("java.lang.Enum")
+ lazy val JavaLangEnumClass = requiredClass[java.lang.Enum[_]]
// convenient one-argument parameter lists
- lazy val anyparam = List(AnyClass.typeConstructor)
+ lazy val anyparam = List(AnyClass.tpe)
lazy val anyvalparam = List(AnyValClass.typeConstructor)
lazy val anyrefparam = List(AnyRefClass.typeConstructor)
// private parameter conveniences
- private def booltype = BooleanClass.typeConstructor
- private def inttype = IntClass.typeConstructor
- private def stringtype = StringClass.typeConstructor
+ private def booltype = BooleanClass.tpe
+ private def inttype = IntClass.tpe
+ private def stringtype = StringClass.tpe
// Java types
def javaTypeName(jclazz: Class[_]): TypeName = newTypeName(jclazz.getName)
@@ -219,9 +276,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
// top types
- lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT)
- lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.typeConstructor)
- lazy val ObjectClass = getClass(sn.Object)
+ lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT)
+ lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.tpe)
+ lazy val ObjectClass = getRequiredClass(sn.Object.toString)
// Note: this is not the type alias AnyRef, it's a companion-like
// object used by the @specialize annotation.
@@ -229,12 +286,13 @@ trait Definitions extends reflect.api.StandardDefinitions {
@deprecated("Use AnyRefModule", "2.10.0")
def Predef_AnyRef = AnyRefModule
- lazy val AnyValClass = ScalaPackageClass.info member tpnme.AnyVal orElse {
+ lazy val AnyValClass: ClassSymbol = (ScalaPackageClass.info member tpnme.AnyVal orElse {
val anyval = enterNewClass(ScalaPackageClass, tpnme.AnyVal, List(AnyClass.tpe, NotNullClass.tpe), ABSTRACT)
val av_constr = anyval.newClassConstructor(NoPosition)
anyval.info.decls enter av_constr
anyval
- }
+ }).asInstanceOf[ClassSymbol]
+
lazy val AnyVal_getClass = enterNewMethod(AnyValClass, nme.getClass_, Nil, getClassReturnType(AnyValClass.tpe))
// bottom types
@@ -243,7 +301,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) {
locally {
- this initFlags ABSTRACT | TRAIT | FINAL
+ this initFlags ABSTRACT | FINAL
this setInfoAndEnter ClassInfoType(List(parent.tpe), newScope, this)
}
final override def isBottomClass = true
@@ -259,24 +317,24 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
// exceptions and other throwables
- lazy val ClassCastExceptionClass = getRequiredClass("java.lang.ClassCastException")
+ lazy val ClassCastExceptionClass = requiredClass[ClassCastException]
lazy val IndexOutOfBoundsExceptionClass = getClass(sn.IOOBException)
lazy val InvocationTargetExceptionClass = getClass(sn.InvTargetException)
- lazy val MatchErrorClass = getRequiredClass("scala.MatchError")
- lazy val NonLocalReturnControlClass = getRequiredClass("scala.runtime.NonLocalReturnControl")
+ lazy val MatchErrorClass = requiredClass[MatchError]
+ lazy val NonLocalReturnControlClass = requiredClass[scala.runtime.NonLocalReturnControl[_]]
lazy val NullPointerExceptionClass = getClass(sn.NPException)
lazy val ThrowableClass = getClass(sn.Throwable)
- lazy val UninitializedErrorClass = getRequiredClass("scala.UninitializedFieldError")
+ lazy val UninitializedErrorClass = requiredClass[UninitializedFieldError]
// fundamental reference classes
- lazy val PartialFunctionClass = getRequiredClass("scala.PartialFunction")
+ lazy val PartialFunctionClass = requiredClass[PartialFunction[_,_]]
lazy val AbstractPartialFunctionClass = getRequiredClass("scala.runtime.AbstractPartialFunction")
lazy val SymbolClass = getRequiredClass("scala.Symbol")
- lazy val StringClass = getClass(sn.String)
+ lazy val StringClass = requiredClass[java.lang.String]
lazy val StringModule = StringClass.linkedClassOfClass
- lazy val ClassClass = getClass(sn.Class)
+ lazy val ClassClass = getRequiredClass("java.lang.Class")
def Class_getMethod = getMember(ClassClass, nme.getMethod_)
- lazy val DynamicClass = getRequiredClass("scala.Dynamic")
+ lazy val DynamicClass = requiredClass[Dynamic]
// fundamental modules
lazy val SysPackage = getPackageObject("scala.sys")
@@ -287,14 +345,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
// Those modules and their module classes
lazy val UnqualifiedOwners = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass)
- lazy val PredefModule: Symbol = getRequiredModule("scala.Predef")
+ lazy val PredefModule = requiredModule[scala.Predef.type]
lazy val PredefModuleClass = PredefModule.moduleClass
- def Predef_classOf = getMember(PredefModule, nme.classOf)
- def Predef_identity = getMember(PredefModule, nme.identity)
- def Predef_conforms = getMember(PredefModule, nme.conforms)
+ def Predef_classOf = getMember(PredefModule, nme.classOf)
+ def Predef_identity = getMember(PredefModule, nme.identity)
+ def Predef_conforms = getMember(PredefModule, nme.conforms)
def Predef_wrapRefArray = getMember(PredefModule, nme.wrapRefArray)
- def Predef_??? = getMember(PredefModule, nme.???)
+ def Predef_??? = getMember(PredefModule, nme.???)
/** Is `sym` a member of Predef with the given name?
* Note: DON't replace this by sym == Predef_conforms/etc, as Predef_conforms is a `def`
@@ -307,8 +365,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
/** Specialization.
*/
- lazy val SpecializableModule = getRequiredModule("scala.Specializable")
- lazy val GroupOfSpecializable = SpecializableModule.info.member(newTypeName("Group"))
+ lazy val SpecializableModule = requiredModule[Specializable]
+ lazy val GroupOfSpecializable = getMember(SpecializableModule, tpnme.Group)
lazy val ConsoleModule: Symbol = getRequiredModule("scala.Console")
lazy val ScalaRunTimeModule: Symbol = getRequiredModule("scala.runtime.ScalaRunTime")
@@ -322,6 +380,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
def arrayCloneMethod = getMember(ScalaRunTimeModule, nme.array_clone)
def ensureAccessibleMethod = getMember(ScalaRunTimeModule, nme.ensureAccessible)
def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements)
+ def arrayClassMethod = getMember(ScalaRunTimeModule, nme.arrayClass)
+ def arrayElementClassMethod = getMember(ScalaRunTimeModule, nme.arrayElementClass)
// classes with special meanings
lazy val StringAddClass = getRequiredClass("scala.runtime.StringAdd")
@@ -330,7 +390,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val NotNullClass = getRequiredClass("scala.NotNull")
lazy val ScalaNumberClass = getRequiredClass("scala.math.ScalaNumber")
lazy val TraitSetterAnnotationClass = getRequiredClass("scala.runtime.TraitSetter")
- lazy val DelayedInitClass = getRequiredClass("scala.DelayedInit")
+ lazy val DelayedInitClass = requiredClass[scala.DelayedInit]
def delayedInitMethod = getMember(DelayedInitClass, nme.delayedInit)
// a dummy value that communicates that a delayedInit call is compiler-generated
// from phase UnCurry to phase Constructors
@@ -347,10 +407,12 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val RemoteInterfaceClass = getRequiredClass("java.rmi.Remote")
lazy val RemoteExceptionClass = getRequiredClass("java.rmi.RemoteException")
- lazy val ByNameParamClass = specialPolyClass(tpnme.BYNAME_PARAM_CLASS_NAME, COVARIANT)(_ => AnyClass.typeConstructor)
- lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN_NAME, 0L)(_ => AnyClass.typeConstructor)
- lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.typeConstructor))
- lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.typeConstructor))
+ lazy val ByNameParamClass = specialPolyClass(tpnme.BYNAME_PARAM_CLASS_NAME, COVARIANT)(_ => AnyClass.tpe)
+ lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN_NAME, 0L)(_ => AnyClass.tpe)
+ lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe))
+ lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe))
+
+ lazy val MarkerCPSTypes = getClassIfDefined("scala.util.continuations.cpsParam")
def isByNameParamType(tp: Type) = tp.typeSymbol == ByNameParamClass
def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass
@@ -359,10 +421,10 @@ trait Definitions extends reflect.api.StandardDefinitions {
def isCastSymbol(sym: Symbol) = sym == Any_asInstanceOf || sym == Object_asInstanceOf
def isJavaVarArgsMethod(m: Symbol) = m.isMethod && isJavaVarArgs(m.info.params)
- def isJavaVarArgs(params: List[Symbol]) = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe)
- def isScalaVarArgs(params: List[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe)
- def isVarArgsList(params: List[Symbol]) = params.nonEmpty && isRepeatedParamType(params.last.tpe)
- def isVarArgTypes(formals: List[Type]) = formals.nonEmpty && isRepeatedParamType(formals.last)
+ def isJavaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe)
+ def isScalaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe)
+ def isVarArgsList(params: Seq[Symbol]) = params.nonEmpty && isRepeatedParamType(params.last.tpe)
+ def isVarArgTypes(formals: Seq[Type]) = formals.nonEmpty && isRepeatedParamType(formals.last)
def hasRepeatedParam(tp: Type): Boolean = tp match {
case MethodType(formals, restpe) => isScalaVarArgs(formals) || hasRepeatedParam(restpe)
@@ -407,8 +469,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val Array_clone = getMember(ArrayClass, nme.clone_)
// reflection / structural types
- lazy val SoftReferenceClass = getRequiredClass("java.lang.ref.SoftReference")
- lazy val WeakReferenceClass = getRequiredClass("java.lang.ref.WeakReference")
+ lazy val SoftReferenceClass = requiredClass[java.lang.ref.SoftReference[_]]
+ lazy val WeakReferenceClass = requiredClass[java.lang.ref.WeakReference[_]]
lazy val MethodClass = getClass(sn.MethodAsObject)
def methodClass_setAccessible = getMember(MethodClass, nme.setAccessible)
lazy val EmptyMethodCacheClass = getRequiredClass("scala.runtime.EmptyMethodCache")
@@ -417,12 +479,11 @@ trait Definitions extends reflect.api.StandardDefinitions {
def methodCache_add = getMember(MethodCacheClass, nme.add_)
// scala.reflect
- lazy val ReflectApiUniverse = getRequiredClass("scala.reflect.api.Universe")
- lazy val ReflectMacroContext = getRequiredClass("scala.reflect.macro.Context")
- lazy val ReflectRuntimeMirror = getRequiredModule("scala.reflect.runtime.Mirror")
- def freeValueMethod = getMember(ReflectRuntimeMirror, nme.freeValue)
+ lazy val ReflectPackageClass = getMember(ScalaPackageClass, nme.reflect)
lazy val ReflectPackage = getPackageObject("scala.reflect")
- def Reflect_mirror = getMember(ReflectPackage, nme.mirror)
+ def ReflectMirror = getMember(ReflectPackage, nme.mirror)
+ // [Eugene] is this a good place for ReflectMirrorPrefix?
+ def ReflectMirrorPrefix = gen.mkAttributedRef(ReflectMirror) setType singleType(ReflectMirror.owner.thisPrefix, ReflectMirror)
lazy val PartialManifestClass = getRequiredClass("scala.reflect.ClassManifest")
lazy val PartialManifestModule = getRequiredModule("scala.reflect.ClassManifest")
@@ -431,41 +492,58 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val OptManifestClass = getRequiredClass("scala.reflect.OptManifest")
lazy val NoManifest = getRequiredModule("scala.reflect.NoManifest")
+ lazy val ExprClass = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr)
+ def ExprTree = getMember(ExprClass, nme.tree)
+ def ExprTpe = getMember(ExprClass, nme.tpe)
+ def ExprEval = getMember(ExprClass, nme.eval)
+ def ExprValue = getMember(ExprClass, nme.value)
+ lazy val ExprModule = getMember(getRequiredClass("scala.reflect.api.Exprs"), nme.Expr)
+
+ lazy val ArrayTagClass = requiredClass[scala.reflect.ArrayTag[_]]
+ lazy val ErasureTagClass = requiredClass[scala.reflect.ErasureTag[_]]
+ lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]]
+ lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]]
+ lazy val TypeTagsClass = requiredClass[scala.reflect.api.TypeTags]
+ lazy val TypeTagClass = getMemberClass(TypeTagsClass, tpnme.TypeTag)
+ lazy val TypeTagModule = getMemberModule(TypeTagsClass, nme.TypeTag)
+ lazy val ConcreteTypeTagClass = getMemberClass(TypeTagsClass, tpnme.ConcreteTypeTag)
+ lazy val ConcreteTypeTagModule = getMemberModule(TypeTagsClass, nme.ConcreteTypeTag)
+
+ def ArrayTagWrap = getMemberMethod(ArrayTagClass, nme.wrap)
+ def ArrayTagNewArray = getMemberMethod(ArrayTagClass, nme.newArray)
+ def ErasureTagErasure = getMemberMethod(ErasureTagClass, nme.erasure)
+ def ClassTagTpe = getMemberMethod(ClassTagClass, nme.tpe)
+ def TypeTagTpe = getMemberMethod(TypeTagClass, nme.tpe)
+
+ lazy val MacroContextClass = getRequiredClass("scala.reflect.makro.Context")
+ def MacroContextPrefix = getMember(MacroContextClass, nme.prefix)
+ def MacroContextPrefixType = getMember(MacroContextClass, tpnme.PrefixType)
+ def MacroContextMirror = getMember(MacroContextClass, nme.mirror)
+ def MacroContextReify = getMember(MacroContextClass, nme.reify)
+ lazy val MacroImplAnnotation = getRequiredClass("scala.reflect.makro.internal.macroImpl")
+ lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal")
+ def MacroInternal_materializeArrayTag = getMemberMethod(MacroInternalPackage, nme.materializeArrayTag)
+ def MacroInternal_materializeErasureTag = getMemberMethod(MacroInternalPackage, nme.materializeErasureTag)
+ def MacroInternal_materializeClassTag = getMemberMethod(MacroInternalPackage, nme.materializeClassTag)
+ def MacroInternal_materializeTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag)
+ def MacroInternal_materializeConcreteTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeConcreteTypeTag)
+
lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature")
lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature")
// Option classes
- lazy val OptionClass: Symbol = getRequiredClass("scala.Option")
- lazy val SomeClass: Symbol = getRequiredClass("scala.Some")
+ lazy val OptionClass: Symbol = requiredClass[Option[_]]
+ lazy val SomeClass: Symbol = requiredClass[Some[_]]
lazy val NoneModule: Symbol = getRequiredModule("scala.None")
lazy val SomeModule: Symbol = getRequiredModule("scala.Some")
- /** Note: don't use this manifest/type function for anything important,
- * as it is incomplete. Would love to have things like existential types
- * working, but very unfortunately the manifests just stuff the relevant
- * information into the toString method.
- */
- def manifestToType(m: OptManifest[_]): Type = m match {
- case m: ClassManifest[_] =>
- val sym = manifestToSymbol(m)
- val args = m.typeArguments
+ // [Eugene] how do I make this work without casts?
+ // private lazy val importerFromRm = self.mkImporter(rm)
+ private lazy val importerFromRm = self.mkImporter(rm).asInstanceOf[self.Importer { val from: rm.type }]
- if ((sym eq NoSymbol) || args.isEmpty) sym.tpe
- else appliedType(sym.typeConstructor, args map manifestToType)
- case _ =>
- NoType
- }
+ def compilerTypeFromTag(t: rm.TypeTag[_]): Type = importerFromRm.importType(t.tpe)
- def manifestToSymbol(m: ClassManifest[_]): Symbol = m match {
- case x: scala.reflect.AnyValManifest[_] =>
- getMember(ScalaPackageClass, newTypeName("" + x))
- case _ =>
- val name = m.erasure.getName
- if (name endsWith nme.MODULE_SUFFIX_STRING)
- getModuleIfDefined(name stripSuffix nme.MODULE_SUFFIX_STRING)
- else
- getClassIfDefined(name)
- }
+ def compilerSymbolFromTag(t: rm.TypeTag[_]): Symbol = importerFromRm.importSymbol(t.sym)
// The given symbol represents either String.+ or StringAdd.+
def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+
@@ -482,33 +560,34 @@ trait Definitions extends reflect.api.StandardDefinitions {
def hasJavaMainMethod(path: String): Boolean =
hasJavaMainMethod(getModuleIfDefined(path))
- def isOptionType(tp: Type) = cond(tp.normalize) { case TypeRef(_, OptionClass, List(_)) => true }
- def isSomeType(tp: Type) = cond(tp.normalize) { case TypeRef(_, SomeClass, List(_)) => true }
- def isNoneType(tp: Type) = cond(tp.normalize) { case TypeRef(_, NoneModule, List(_)) => true }
-
- def optionType(tp: Type) = typeRef(NoPrefix, OptionClass, List(tp))
- def someType(tp: Type) = typeRef(NoPrefix, SomeClass, List(tp))
- def symbolType = typeRef(SymbolClass.typeConstructor.prefix, SymbolClass, List())
- def longType = typeRef(LongClass.typeConstructor.prefix, LongClass, List())
+ def isOptionType(tp: Type) = tp.typeSymbol isSubClass OptionClass
+ def isSomeType(tp: Type) = tp.typeSymbol eq SomeClass
+ def isNoneType(tp: Type) = tp.typeSymbol eq NoneModule
- // Product, Tuple, Function
+ // Product, Tuple, Function, AbstractFunction
private def mkArityArray(name: String, arity: Int, countFrom: Int = 1): Array[Symbol] = {
val list = countFrom to arity map (i => getRequiredClass("scala." + name + i))
if (countFrom == 0) list.toArray
else (NoSymbol +: list).toArray
}
+ private def aritySpecificType(symbolArray: Array[Symbol], args: List[Type], others: Type*): Type = {
+ val arity = args.length
+ if (arity >= symbolArray.length) NoType
+ else appliedType(symbolArray(arity), args ++ others: _*)
+ }
val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22
- /** The maximal dimensions of a generic array creation.
- * I.e. new Array[Array[Array[Array[Array[T]]]]] creates a 5 times
- * nested array. More is not allowed.
- */
- val MaxArrayDims = 5
- lazy val TupleClass = mkArityArray("Tuple", MaxTupleArity)
- lazy val ProductClass = mkArityArray("Product", MaxProductArity)
- lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0)
+ lazy val ProductClass = { val arr = mkArityArray("Product", MaxProductArity) ; arr(0) = UnitClass ; arr }
+ lazy val TupleClass = mkArityArray("Tuple", MaxTupleArity)
+ lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0)
lazy val AbstractFunctionClass = mkArityArray("runtime.AbstractFunction", MaxFunctionArity, 0)
- lazy val isProductNClass = ProductClass.toSet
+
+ /** Creators for TupleN, ProductN, FunctionN. */
+ def tupleType(elems: List[Type]) = aritySpecificType(TupleClass, elems)
+ def productType(elems: List[Type]) = aritySpecificType(ProductClass, elems)
+ def functionType(formals: List[Type], restpe: Type) = aritySpecificType(FunctionClass, formals, restpe)
+ def abstractFunctionType(formals: List[Type], restpe: Type) = aritySpecificType(AbstractFunctionClass, formals, restpe)
+
def wrapArrayMethodName(elemtp: Type): TermName = elemtp.typeSymbol match {
case ByteClass => nme.wrapByteArray
case ShortClass => nme.wrapShortArray
@@ -524,34 +603,55 @@ trait Definitions extends reflect.api.StandardDefinitions {
else nme.genericWrapArray
}
+ @deprecated("Use isTupleType", "2.10.0")
+ def isTupleTypeOrSubtype(tp: Type) = isTupleType(tp)
+
def tupleField(n: Int, j: Int) = getMember(TupleClass(n), nme.productAccessorName(j))
- def isTupleType(tp: Type): Boolean = isTupleType(tp, false)
- def isTupleTypeOrSubtype(tp: Type): Boolean = isTupleType(tp, true)
- private def isTupleType(tp: Type, subtypeOK: Boolean) = tp.normalize match {
- case TypeRef(_, sym, args) if args.nonEmpty =>
- val len = args.length
- len <= MaxTupleArity && {
- val tsym = TupleClass(len)
- (sym == tsym) || (subtypeOK && !tp.isHigherKinded && sym.isSubClass(tsym))
- }
- case _ => false
+ def isTupleSymbol(sym: Symbol) = TupleClass contains unspecializedSymbol(sym)
+ def isProductNClass(sym: Symbol) = ProductClass contains sym
+
+ def unspecializedSymbol(sym: Symbol): Symbol = {
+ if (sym hasFlag SPECIALIZED) {
+ // add initialization from its generic class constructor
+ val genericName = nme.unspecializedName(sym.name)
+ val member = sym.owner.info.decl(genericName.toTypeName)
+ member
}
+ else sym
+ }
- def tupleType(elems: List[Type]) = {
- val len = elems.length
- if (len <= MaxTupleArity) {
- val sym = TupleClass(len)
- typeRef(sym.typeConstructor.prefix, sym, elems)
- } else NoType
- }
+ // Checks whether the given type is true for the given condition,
+ // or if it is a specialized subtype of a type for which it is true.
+ //
+ // Origins notes:
+ // An issue was introduced with specialization in that the implementation
+ // of "isTupleType" in Definitions relied upon sym == TupleClass(elems.length).
+ // This test is untrue for specialized tuples, causing mysterious behavior
+ // because only some tuples are specialized.
+ def isPossiblySpecializedType(tp: Type)(cond: Type => Boolean) = {
+ cond(tp) || (tp match {
+ case TypeRef(pre, sym, args) if sym hasFlag SPECIALIZED =>
+ cond(tp baseType unspecializedSymbol(sym))
+ case _ =>
+ false
+ })
+ }
+ // No normalization.
+ def isTupleTypeDirect(tp: Type) = isPossiblySpecializedType(tp) {
+ case TypeRef(_, sym, args) if args.nonEmpty =>
+ val len = args.length
+ len <= MaxTupleArity && sym == TupleClass(len)
+ case _ => false
+ }
+ def isTupleType(tp: Type) = isTupleTypeDirect(tp.normalize)
- lazy val ProductRootClass: Symbol = getRequiredClass("scala.Product")
- def Product_productArity = getMember(ProductRootClass, nme.productArity)
- def Product_productElement = getMember(ProductRootClass, nme.productElement)
- // def Product_productElementName = getMember(ProductRootClass, nme.productElementName)
- def Product_iterator = getMember(ProductRootClass, nme.productIterator)
- def Product_productPrefix = getMember(ProductRootClass, nme.productPrefix)
- def Product_canEqual = getMember(ProductRootClass, nme.canEqual_)
+ lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product]
+ def Product_productArity = getMemberMethod(ProductRootClass, nme.productArity)
+ def Product_productElement = getMemberMethod(ProductRootClass, nme.productElement)
+ def Product_iterator = getMemberMethod(ProductRootClass, nme.productIterator)
+ def Product_productPrefix = getMemberMethod(ProductRootClass, nme.productPrefix)
+ def Product_canEqual = getMemberMethod(ProductRootClass, nme.canEqual_)
+ // def Product_productElementName = getMemberMethod(ProductRootClass, nme.productElementName)
def productProj(z:Symbol, j: Int): Symbol = getMember(z, nme.productAccessorName(j))
def productProj(n: Int, j: Int): Symbol = productProj(ProductClass(n), j)
@@ -559,18 +659,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
/** returns true if this type is exactly ProductN[T1,...,Tn], not some subclass */
def isExactProductType(tp: Type): Boolean = isProductNClass(tp.typeSymbol)
- def productType(elems: List[Type]) = {
- if (elems.isEmpty) UnitClass.tpe
- else {
- val len = elems.length
- if (len <= MaxProductArity) {
- val sym = ProductClass(len)
- typeRef(sym.typeConstructor.prefix, sym, elems)
- }
- else NoType
- }
- }
-
/** if tpe <: ProductN[T1,...,TN], returns List(T1,...,TN) else Nil */
def getProductArgs(tpe: Type): List[Type] = tpe.baseClasses find isProductNClass match {
case Some(x) => tpe.baseType(x).typeArgs
@@ -583,30 +671,24 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
def functionApply(n: Int) = getMember(FunctionClass(n), nme.apply)
- def functionType(formals: List[Type], restpe: Type) = {
- val len = formals.length
- if (len <= MaxFunctionArity) {
- val sym = FunctionClass(len)
- typeRef(sym.typeConstructor.prefix, sym, formals :+ restpe)
- } else NoType
- }
- def abstractFunctionForFunctionType(tp: Type) = tp.normalize match {
- case tr @ TypeRef(_, _, args) if isFunctionType(tr) =>
- val sym = AbstractFunctionClass(args.length - 1)
- typeRef(sym.typeConstructor.prefix, sym, args)
- case _ =>
- NoType
- }
+ def abstractFunctionForFunctionType(tp: Type) =
+ if (isFunctionType(tp)) abstractFunctionType(tp.typeArgs.init, tp.typeArgs.last)
+ else NoType
def isFunctionType(tp: Type): Boolean = tp.normalize match {
case TypeRef(_, sym, args) if args.nonEmpty =>
- val len = args.length
- len < MaxFunctionArity && sym == FunctionClass(len - 1)
+ val arity = args.length - 1 // -1 is the return type
+ arity <= MaxFunctionArity && sym == FunctionClass(arity)
case _ =>
false
}
+ def isPartialFunctionType(tp: Type): Boolean = {
+ val sym = tp.typeSymbol
+ (sym eq PartialFunctionClass) || (sym eq AbstractPartialFunctionClass)
+ }
+
def isSeqType(tp: Type) = elementType(SeqClass, tp.normalize) != NoType
def elementType(container: Symbol, tp: Type): Type = tp match {
@@ -614,17 +696,21 @@ trait Definitions extends reflect.api.StandardDefinitions {
case _ => NoType
}
- def seqType(arg: Type) = appliedType(SeqClass.typeConstructor, List(arg))
- def arrayType(arg: Type) = appliedType(ArrayClass.typeConstructor, List(arg))
- def byNameType(arg: Type) = appliedType(ByNameParamClass.typeConstructor, List(arg))
- def iteratorOfType(tp: Type) = appliedType(IteratorClass.typeConstructor, List(tp))
+ def arrayType(arg: Type) = appliedType(ArrayClass, arg)
+ def byNameType(arg: Type) = appliedType(ByNameParamClass, arg)
+ def iteratorOfType(tp: Type) = appliedType(IteratorClass, tp)
+ def javaRepeatedType(arg: Type) = appliedType(JavaRepeatedParamClass, arg)
+ def optionType(tp: Type) = appliedType(OptionClass, tp)
+ def scalaRepeatedType(arg: Type) = appliedType(RepeatedParamClass, arg)
+ def seqType(arg: Type) = appliedType(SeqClass, arg)
+ def someType(tp: Type) = appliedType(SomeClass, tp)
- lazy val StringArray = arrayType(StringClass.tpe)
+ def StringArray = arrayType(StringClass.tpe)
lazy val ObjectArray = arrayType(ObjectClass.tpe)
def ClassType(arg: Type) =
if (phase.erasedTypes || forMSIL) ClassClass.tpe
- else appliedType(ClassClass.typeConstructor, List(arg))
+ else appliedType(ClassClass, arg)
def vmClassType(arg: Type): Type = ClassType(arg)
def vmSignature(sym: Symbol, info: Type): String = signature(info) // !!!
@@ -808,7 +894,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
// boxed classes
lazy val ObjectRefClass = getRequiredClass("scala.runtime.ObjectRef")
lazy val VolatileObjectRefClass = getRequiredClass("scala.runtime.VolatileObjectRef")
- lazy val BoxesRunTimeClass = getRequiredModule("scala.runtime.BoxesRunTime")
+ lazy val BoxesRunTimeModule = getRequiredModule("scala.runtime.BoxesRunTime")
+ lazy val BoxesRunTimeClass = BoxesRunTimeModule.moduleClass
lazy val BoxedNumberClass = getClass(sn.BoxedNumber)
lazy val BoxedCharacterClass = getClass(sn.BoxedCharacter)
lazy val BoxedBooleanClass = getClass(sn.BoxedBoolean)
@@ -819,6 +906,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val BoxedFloatClass = getRequiredClass("java.lang.Float")
lazy val BoxedDoubleClass = getRequiredClass("java.lang.Double")
+ lazy val Boxes_isNumberOrBool = getDecl(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean)
+ lazy val Boxes_isNumber = getDecl(BoxesRunTimeClass, nme.isBoxedNumber)
+
lazy val BoxedUnitClass = getRequiredClass("scala.runtime.BoxedUnit")
lazy val BoxedUnitModule = getRequiredModule("scala.runtime.BoxedUnit")
def BoxedUnit_UNIT = getMember(BoxedUnitModule, nme.UNIT)
@@ -865,21 +955,35 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val GetterTargetClass = getMetaAnnotation("getter")
lazy val ParamTargetClass = getMetaAnnotation("param")
lazy val SetterTargetClass = getMetaAnnotation("setter")
- // TODO: module, moduleClass? package, packageObject?
+ lazy val ClassTargetClass = getMetaAnnotation("companionClass")
+ lazy val ObjectTargetClass = getMetaAnnotation("companionObject")
+ lazy val MethodTargetClass = getMetaAnnotation("companionMethod") // TODO: module, moduleClass? package, packageObject?
+ lazy val LanguageFeatureAnnot = getMetaAnnotation("languageFeature")
+
+ // Language features
+ lazy val languageFeatureModule = getRequiredModule("scala.languageFeature")
+ lazy val experimentalModule = getMember(languageFeatureModule, newTermName("experimental"))
+ lazy val MacrosFeature = getLanguageFeature("macros", experimentalModule)
+ lazy val DynamicsFeature = getLanguageFeature("dynamics")
+ lazy val PostfixOpsFeature = getLanguageFeature("postfixOps")
+ lazy val ReflectiveCallsFeature = getLanguageFeature("reflectiveCalls")
+ lazy val ImplicitConversionsFeature = getLanguageFeature("implicitConversions")
+ lazy val HigherKindsFeature = getLanguageFeature("higherKinds")
+ lazy val ExistentialsFeature = getLanguageFeature("existentials")
private def getMetaAnnotation(name: String) = getRequiredClass("scala.annotation.meta." + name)
def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || (
// Trying to allow for deprecated locations
sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol)
)
- lazy val metaAnnotations = Set(
+ lazy val metaAnnotations = Set[Symbol](
FieldTargetClass, ParamTargetClass,
GetterTargetClass, SetterTargetClass,
BeanGetterTargetClass, BeanSetterTargetClass
)
lazy val AnnotationDefaultAttr: Symbol = {
- val attr = enterNewClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.typeConstructor))
+ val attr = enterNewClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.tpe))
// This attribute needs a constructor so that modifiers in parsed Java code make sense
attr.info.decls enter attr.newClassConstructor(NoPosition)
attr
@@ -891,31 +995,67 @@ trait Definitions extends reflect.api.StandardDefinitions {
def getPackageObject(fullname: String): Symbol =
getModule(newTermName(fullname)).info member nme.PACKAGE
- def getModule(fullname: Name): Symbol =
- getModuleOrClass(fullname.toTermName)
+ def getModule(fullname: Name): ModuleSymbol =
+ getModuleOrClass(fullname.toTermName) match {
+ case x: ModuleSymbol => x
+ case _ => MissingRequirementError.notFound("object " + fullname)
+ }
- def getClass(fullname: Name): Symbol = {
- var result = getModuleOrClass(fullname.toTypeName)
- while (result.isAliasType) result = result.info.typeSymbol
- result
+ def getPackage(fullname: Name): PackageSymbol =
+ getModuleOrClass(fullname.toTermName) match {
+ case x: PackageSymbol => x
+ case _ => MissingRequirementError.notFound("package " + fullname)
+ }
+ @inline private def wrapMissing(body: => Symbol): Symbol =
+ try body
+ catch { case _: MissingRequirementError => NoSymbol }
+
+ private def fatalMissingSymbol(owner: Symbol, name: Name, what: String = "member") = {
+ throw new FatalError(owner + " does not have a " + what + " " + name)
}
- def getRequiredModule(fullname: String): Symbol =
+ @deprecated("Use getClassByName", "2.10.0")
+ def getClass(fullname: Name): Symbol = getClassByName(fullname)
+
+ def getRequiredPackage(fullname: String): PackageSymbol =
+ getPackage(newTermNameCached(fullname))
+
+ def getRequiredModule(fullname: String): ModuleSymbol =
getModule(newTermNameCached(fullname))
- def getRequiredClass(fullname: String): Symbol =
- getClass(newTypeNameCached(fullname))
+
+ def requiredClass[T: ClassTag] : ClassSymbol =
+ getRequiredClass(classTag[T].erasure.getName)
+
+ // TODO: What syntax do we think should work here? Say you have an object
+ // like scala.Predef. You can't say requiredModule[scala.Predef] since there's
+ // no accompanying Predef class, and if you say requiredModule[scala.Predef.type]
+ // the name found via the erasure is scala.Predef$. For now I am
+ // removing the trailing $, but I think that classTag should have
+ // a method which returns a usable name, one which doesn't expose this
+ // detail of the backend.
+ def requiredModule[T: ClassTag] : ModuleSymbol =
+ getRequiredModule(classTag[T].erasure.getName stripSuffix "$")
+
+ def getRequiredClass(fullname: String): ClassSymbol =
+ getClassByName(newTypeNameCached(fullname)) match {
+ case x: ClassSymbol => x
+ case _ => MissingRequirementError.notFound("class " + fullname)
+ }
def getClassIfDefined(fullname: String): Symbol =
getClassIfDefined(newTypeName(fullname))
+
def getClassIfDefined(fullname: Name): Symbol =
- try getClass(fullname.toTypeName)
- catch { case _: MissingRequirementError => NoSymbol }
+ wrapMissing(getClass(fullname.toTypeName))
def getModuleIfDefined(fullname: String): Symbol =
getModuleIfDefined(newTermName(fullname))
+
def getModuleIfDefined(fullname: Name): Symbol =
- try getModule(fullname.toTermName)
- catch { case _: MissingRequirementError => NoSymbol }
+ wrapMissing(getModule(fullname.toTermName))
+
+ def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule) =
+ getMember(owner, newTypeName(name))
def termMember(owner: Symbol, name: String): Symbol = owner.info.member(newTermName(name))
def typeMember(owner: Symbol, name: String): Symbol = owner.info.member(newTypeName(name))
@@ -935,13 +1075,47 @@ trait Definitions extends reflect.api.StandardDefinitions {
else findNamedMember(segs.tail, root.info member segs.head)
def getMember(owner: Symbol, name: Name): Symbol = {
- if (owner == NoSymbol) NoSymbol
- else owner.info.nonPrivateMember(name) match {
- case NoSymbol => throw new FatalError(owner + " does not have a member " + name)
- case result => result
+ getMemberIfDefined(owner, name) orElse {
+ if (phase.flatClasses && name.isTypeName && !owner.isPackageObjectOrClass) {
+ val pkg = owner.owner
+ val flatname = nme.flattenedName(owner.name, name)
+ getMember(pkg, flatname)
+ }
+ else fatalMissingSymbol(owner, name)
+ }
+ }
+ def getMemberModule(owner: Symbol, name: Name): ModuleSymbol = {
+ getMember(owner, name.toTermName) match {
+ case x: ModuleSymbol => x
+ case _ => fatalMissingSymbol(owner, name, "member object")
+ }
+ }
+ def getMemberClass(owner: Symbol, name: Name): ClassSymbol = {
+ getMember(owner, name.toTypeName) match {
+ case x: ClassSymbol => x
+ case _ => fatalMissingSymbol(owner, name, "member class")
+ }
+ }
+ def getMemberMethod(owner: Symbol, name: Name): MethodSymbol = {
+ getMember(owner, name.toTermName) match {
+ case x: MethodSymbol => x
+ case _ => fatalMissingSymbol(owner, name, "method")
}
}
-
+
+ def getMemberIfDefined(owner: Symbol, name: Name): Symbol =
+ owner.info.nonPrivateMember(name)
+
+ /** Using getDecl rather than getMember may avoid issues with
+ * OverloadedTypes turning up when you don't want them, if you
+ * know the method in question is uniquely declared in the given owner.
+ */
+ def getDecl(owner: Symbol, name: Name): Symbol = {
+ getDeclIfDefined(owner, name) orElse fatalMissingSymbol(owner, name, "decl")
+ }
+ def getDeclIfDefined(owner: Symbol, name: Name): Symbol =
+ owner.info.nonPrivateDecl(name)
+
def packageExists(packageName: String): Boolean =
getModuleIfDefined(packageName).isPackage
@@ -967,10 +1141,16 @@ trait Definitions extends reflect.api.StandardDefinitions {
*/
private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length)
- private def newAlias(owner: Symbol, name: TypeName, alias: Type): Symbol =
+ private def getClassByName(fullname: Name): Symbol = {
+ var result = getModuleOrClass(fullname.toTypeName)
+ while (result.isAliasType) result = result.info.typeSymbol
+ result
+ }
+
+ private def newAlias(owner: Symbol, name: TypeName, alias: Type): AliasTypeSymbol =
owner.newAliasType(name) setInfoAndEnter alias
- private def specialPolyClass(name: TypeName, flags: Long)(parentFn: Symbol => Type): Symbol = {
+ private def specialPolyClass(name: TypeName, flags: Long)(parentFn: Symbol => Type): ClassSymbol = {
val clazz = enterNewClass(ScalaPackageClass, name, Nil)
val tparam = clazz.newSyntheticTypeParam("T0", flags)
val parents = List(AnyRefClass.tpe, parentFn(tparam))
@@ -978,7 +1158,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
clazz setInfo GenPolyType(List(tparam), ClassInfoType(parents, newScope, clazz))
}
- def newPolyMethod(typeParamCount: Int, owner: Symbol, name: TermName, flags: Long)(createFn: PolyMethodCreator): Symbol = {
+ def newPolyMethod(typeParamCount: Int, owner: Symbol, name: TermName, flags: Long)(createFn: PolyMethodCreator): MethodSymbol = {
val msym = owner.newMethod(name.encode, NoPosition, flags)
val tparams = msym.newSyntheticTypeParams(typeParamCount)
val mtpe = createFn(tparams) match {
@@ -991,16 +1171,16 @@ trait Definitions extends reflect.api.StandardDefinitions {
/** T1 means one type parameter.
*/
- def newT1NullaryMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): Symbol = {
+ def newT1NullaryMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): MethodSymbol = {
newPolyMethod(1, owner, name, flags)(tparams => (None, createFn(tparams.head)))
}
- def newT1NoParamsMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): Symbol = {
+ def newT1NoParamsMethod(owner: Symbol, name: TermName, flags: Long)(createFn: Symbol => Type): MethodSymbol = {
newPolyMethod(1, owner, name, flags)(tparams => (Some(Nil), createFn(tparams.head)))
}
- lazy val boxedClassValues = boxedClass.values.toSet
- lazy val isUnbox = unboxMethod.values.toSet
- lazy val isBox = boxMethod.values.toSet
+ lazy val boxedClassValues = boxedClass.values.toSet[Symbol]
+ lazy val isUnbox = unboxMethod.values.toSet[Symbol]
+ lazy val isBox = boxMethod.values.toSet[Symbol]
/** Is symbol a phantom class for which no runtime representation exists? */
lazy val isPhantomClass = Set[Symbol](AnyClass, AnyValClass, NullClass, NothingClass)
@@ -1008,14 +1188,13 @@ trait Definitions extends reflect.api.StandardDefinitions {
/** Is the symbol that of a parent which is added during parsing? */
lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass
- lazy val scalaValueClassesSet = ScalaValueClasses.toSet
- private lazy val boxedValueClassesSet = boxedClass.values.toSet + BoxedUnitClass
+ private lazy val boxedValueClassesSet = boxedClass.values.toSet[Symbol] + BoxedUnitClass
/** Is symbol a value class? */
- def isPrimitiveValueClass(sym: Symbol) = scalaValueClassesSet(sym)
+ def isPrimitiveValueClass(sym: Symbol) = ScalaValueClasses contains sym
def isNonUnitValueClass(sym: Symbol) = isPrimitiveValueClass(sym) && (sym != UnitClass)
def isSpecializableClass(sym: Symbol) = isPrimitiveValueClass(sym) || (sym == AnyRefClass)
- def isScalaValueType(tp: Type) = scalaValueClassesSet(tp.typeSymbol)
+ def isScalaValueType(tp: Type) = ScalaValueClasses contains tp.typeSymbol
/** Is symbol a boxed value class, e.g. java.lang.Integer? */
def isBoxedValueClass(sym: Symbol) = boxedValueClassesSet(sym)
@@ -1090,9 +1269,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
def init() {
if (isInitialized) return
+ // Still fiddling with whether it's cleaner to do some of this setup here
+ // or from constructors. The latter approach tends to invite init order issues.
EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass)
EmptyPackage setInfo EmptyPackageClass.tpe
+ connectModuleToClass(EmptyPackage, EmptyPackageClass)
+ connectModuleToClass(RootPackage, RootClass)
+
RootClass.info.decls enter EmptyPackage
RootClass.info.decls enter RootPackage
diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala
index 3110d73461..c6901d1cf6 100644
--- a/src/compiler/scala/reflect/internal/Flags.scala
+++ b/src/compiler/scala/reflect/internal/Flags.scala
@@ -83,89 +83,89 @@ import scala.collection.{ mutable, immutable }
/** Flags set on Modifiers instances in the parsing stage.
*/
class ModifierFlags {
- final val IMPLICIT = 0x00000200
- final val FINAL = 0x00000020
- final val PRIVATE = 0x00000004
- final val PROTECTED = 0x00000001
-
- final val SEALED = 0x00000400
- final val OVERRIDE = 0x00000002
- final val CASE = 0x00000800
- final val ABSTRACT = 0x00000008 // abstract class, or used in conjunction with abstract override.
+ final val IMPLICIT = 1 << 9
+ final val FINAL = 1 << 5 // May not be overridden. Note that java final implies much more than scala final.
+ final val PRIVATE = 1 << 2
+ final val PROTECTED = 1 << 0
+
+ final val SEALED = 1 << 10
+ final val OVERRIDE = 1 << 1
+ final val CASE = 1 << 11
+ final val ABSTRACT = 1 << 3 // abstract class, or used in conjunction with abstract override.
// Note difference to DEFERRED!
- final val DEFERRED = 0x00000010 // was `abstract' for members | trait is virtual
- final val INTERFACE = 0x00000080 // symbol is an interface (i.e. a trait which defines only abstract methods)
- final val MUTABLE = 0x00001000 // symbol is a mutable variable.
- final val PARAM = 0x00002000 // symbol is a (value or type) parameter to a method
- final val MACRO = 0x00008000 // symbol is a macro definition
-
- final val COVARIANT = 0x00010000 // symbol is a covariant type variable
- final val BYNAMEPARAM = 0x00010000 // parameter is by name
- final val CONTRAVARIANT = 0x00020000 // symbol is a contravariant type variable
- final val ABSOVERRIDE = 0x00040000 // combination of abstract & override
- final val LOCAL = 0x00080000 // symbol is local to current class (i.e. private[this] or protected[this]
+ final val DEFERRED = 1 << 4 // was `abstract' for members | trait is virtual
+ final val INTERFACE = 1 << 7 // symbol is an interface (i.e. a trait which defines only abstract methods)
+ final val MUTABLE = 1 << 12 // symbol is a mutable variable.
+ final val PARAM = 1 << 13 // symbol is a (value or type) parameter to a method
+ final val MACRO = 1 << 15 // symbol is a macro definition
+
+ final val COVARIANT = 1 << 16 // symbol is a covariant type variable
+ final val BYNAMEPARAM = 1 << 16 // parameter is by name
+ final val CONTRAVARIANT = 1 << 17 // symbol is a contravariant type variable
+ final val ABSOVERRIDE = 1 << 18 // combination of abstract & override
+ final val LOCAL = 1 << 19 // symbol is local to current class (i.e. private[this] or protected[this]
// pre: PRIVATE or PROTECTED are also set
- final val JAVA = 0x00100000 // symbol was defined by a Java class
- final val STATIC = 0x00800000 // static field, method or class
- final val CASEACCESSOR = 0x01000000 // symbol is a case parameter (or its accessor, or a GADT skolem)
- final val TRAIT = 0x02000000 // symbol is a trait
- final val DEFAULTPARAM = 0x02000000 // the parameter has a default value
- final val PARAMACCESSOR = 0x20000000 // for field definitions generated for primary constructor
+ final val JAVA = 1 << 20 // symbol was defined by a Java class
+ final val STATIC = 1 << 23 // static field, method or class
+ final val CASEACCESSOR = 1 << 24 // symbol is a case parameter (or its accessor, or a GADT skolem)
+ final val TRAIT = 1 << 25 // symbol is a trait
+ final val DEFAULTPARAM = 1 << 25 // the parameter has a default value
+ final val PARAMACCESSOR = 1 << 29 // for field definitions generated for primary constructor
// parameters (no matter if it's a 'val' parameter or not)
// for parameters of a primary constructor ('val' or not)
// for the accessor methods generated for 'val' or 'var' parameters
- final val LAZY = 0x80000000L // symbol is a lazy val. can't have MUTABLE unless transformed by typer
- final val PRESUPER = 0x2000000000L // value is evaluated before super call
- final val DEFAULTINIT = 0x20000000000L// symbol is initialized to the default value: used by -Xcheckinit
+ final val LAZY = 1L << 31 // symbol is a lazy val. can't have MUTABLE unless transformed by typer
+ final val PRESUPER = 1L << 37 // value is evaluated before super call
+ final val DEFAULTINIT = 1L << 41 // symbol is initialized to the default value: used by -Xcheckinit
// Overridden.
def flagToString(flag: Long): String = ""
- final val PrivateLocal: Long = PRIVATE | LOCAL
- final val ProtectedLocal: Long = PROTECTED | LOCAL
- final val AccessFlags: Long = PRIVATE | PROTECTED | LOCAL
+ final val PrivateLocal = PRIVATE | LOCAL
+ final val ProtectedLocal = PROTECTED | LOCAL
+ final val AccessFlags = PRIVATE | PROTECTED | LOCAL
}
object ModifierFlags extends ModifierFlags
/** All flags and associated operatins */
class Flags extends ModifierFlags {
- final val METHOD = 0x00000040 // a method
- final val MODULE = 0x00000100 // symbol is module or class implementing a module
- final val PACKAGE = 0x00004000 // symbol is a java package
-
- final val CAPTURED = 0x00010000 // variable is accessed from nested function. Set by LambdaLift.
- final val LABEL = 0x00020000 // method symbol is a label. Set by TailCall
- final val INCONSTRUCTOR = 0x00020000 // class symbol is defined in this/superclass constructor.
- final val SYNTHETIC = 0x00200000 // symbol is compiler-generated
- final val STABLE = 0x00400000 // functions that are assumed to be stable
+ final val METHOD = 1 << 6 // a method
+ final val MODULE = 1 << 8 // symbol is module or class implementing a module
+ final val PACKAGE = 1 << 14 // symbol is a java package
+
+ final val CAPTURED = 1 << 16 // variable is accessed from nested function. Set by LambdaLift.
+ final val LABEL = 1 << 17 // method symbol is a label. Set by TailCall
+ final val INCONSTRUCTOR = 1 << 17 // class symbol is defined in this/superclass constructor.
+ final val SYNTHETIC = 1 << 21 // symbol is compiler-generated
+ final val STABLE = 1 << 22 // functions that are assumed to be stable
// (typically, access methods for valdefs)
// or classes that do not contain abstract types.
- final val BRIDGE = 0x04000000 // function is a bridge method. Set by Erasure
- final val ACCESSOR = 0x08000000 // a value or variable accessor (getter or setter)
+ final val BRIDGE = 1 << 26 // function is a bridge method. Set by Erasure
+ final val ACCESSOR = 1 << 27 // a value or variable accessor (getter or setter)
- final val SUPERACCESSOR = 0x10000000 // a super accessor
- final val MODULEVAR = 0x40000000 // for variables: is the variable caching a module value
+ final val SUPERACCESSOR = 1 << 28 // a super accessor
+ final val MODULEVAR = 1 << 30 // for variables: is the variable caching a module value
- final val IS_ERROR = 0x100000000L // symbol is an error symbol
- final val OVERLOADED = 0x200000000L // symbol is overloaded
- final val LIFTED = 0x400000000L // class has been lifted out to package level
+ final val IS_ERROR = 1L << 32 // symbol is an error symbol
+ final val OVERLOADED = 1L << 33 // symbol is overloaded
+ final val LIFTED = 1L << 34 // class has been lifted out to package level
// local value has been lifted out to class level
// todo: make LIFTED = latePRIVATE?
- final val MIXEDIN = 0x800000000L // term member has been mixed in
- final val EXISTENTIAL = 0x800000000L // type is an existential parameter or skolem
- final val EXPANDEDNAME = 0x1000000000L // name has been expanded with class suffix
- final val IMPLCLASS = 0x2000000000L // symbol is an implementation class
- final val TRANS_FLAG = 0x4000000000L // transient flag guaranteed to be reset after each phase.
+ final val MIXEDIN = 1L << 35 // term member has been mixed in
+ final val EXISTENTIAL = 1L << 35 // type is an existential parameter or skolem
+ final val EXPANDEDNAME = 1L << 36 // name has been expanded with class suffix
+ final val IMPLCLASS = 1L << 37 // symbol is an implementation class
+ final val TRANS_FLAG = 1L << 38 // transient flag guaranteed to be reset after each phase.
- final val LOCKED = 0x8000000000L // temporary flag to catch cyclic dependencies
- final val SPECIALIZED = 0x10000000000L// symbol is a generated specialized member
- final val VBRIDGE = 0x40000000000L// symbol is a varargs bridge
+ final val LOCKED = 1L << 39 // temporary flag to catch cyclic dependencies
+ final val SPECIALIZED = 1L << 40 // symbol is a generated specialized member
+ final val VBRIDGE = 1L << 42 // symbol is a varargs bridge
- final val VARARGS = 0x80000000000L// symbol is a Java-style varargs method
- final val TRIEDCOOKING = 0x100000000000L // ``Cooking'' has been tried on this symbol
- // A Java method's type is ``cooked'' by transforming raw types to existentials
+ final val VARARGS = 1L << 43 // symbol is a Java-style varargs method
+ final val TRIEDCOOKING = 1L << 44 // ``Cooking'' has been tried on this symbol
+ // A Java method's type is ``cooked'' by transforming raw types to existentials
- final val SYNCHRONIZED = 0x200000000000L // symbol is a method which should be marked ACC_SYNCHRONIZED
+ final val SYNCHRONIZED = 1L << 45 // symbol is a method which should be marked ACC_SYNCHRONIZED
// ------- shift definitions -------------------------------------------------------
final val InitialFlags = 0x0001FFFFFFFFFFFFL // flags that are enabled from phase 1.
@@ -174,6 +174,9 @@ class Flags extends ModifierFlags {
final val LateShift = 47L
final val AntiShift = 56L
+ // Flags which sketchily share the same slot
+ val OverloadedFlagsMask = 0L | BYNAMEPARAM | CONTRAVARIANT | DEFAULTPARAM | EXISTENTIAL | IMPLCLASS
+
// ------- late flags (set by a transformer phase) ---------------------------------
//
// Summary of when these are claimed to be first used.
@@ -206,34 +209,46 @@ class Flags extends ModifierFlags {
// ------- masks -----------------------------------------------------------------------
+ /** To be a little clearer to people who aren't habitual bit twiddlers.
+ */
+ final val AllFlags = -1L
+
/** These flags can be set when class or module symbol is first created.
* They are the only flags to survive a call to resetFlags().
*/
- final val TopLevelCreationFlags: Long =
+ final val TopLevelCreationFlags =
MODULE | PACKAGE | FINAL | JAVA
+ // TODO - there's no call to slap four flags onto every package.
+ final val PackageFlags = TopLevelCreationFlags
+
+ // FINAL not included here due to possibility of object overriding.
+ // In fact, FINAL should not be attached regardless. We should be able
+ // to reconstruct whether an object was marked final in source.
+ final val ModuleFlags = MODULE
+
/** These modifiers can be set explicitly in source programs. This is
* used only as the basis for the default flag mask (which ones to display
* when printing a normal message.)
*/
- final val ExplicitFlags: Long =
+ final val ExplicitFlags =
PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED |
OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE | LAZY
- /** These modifiers appear in TreePrinter output. */
- final val PrintableFlags: Long =
- ExplicitFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | MACRO |
- ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | BRIDGE | STATIC | VBRIDGE | SPECIALIZED | SYNCHRONIZED
-
/** The two bridge flags */
final val BridgeFlags = BRIDGE | VBRIDGE
final val BridgeAndPrivateFlags = BridgeFlags | PRIVATE
+ /** These modifiers appear in TreePrinter output. */
+ final val PrintableFlags =
+ ExplicitFlags | BridgeFlags | LOCAL | SYNTHETIC | STABLE | CASEACCESSOR | MACRO |
+ ACCESSOR | SUPERACCESSOR | PARAMACCESSOR | STATIC | SPECIALIZED | SYNCHRONIZED
+
/** When a symbol for a field is created, only these flags survive
* from Modifiers. Others which may be applied at creation time are:
* PRIVATE, LOCAL.
*/
- final val FieldFlags: Long =
+ final val FieldFlags =
MUTABLE | CASEACCESSOR | PARAMACCESSOR | STATIC | FINAL | PRESUPER | LAZY
/** Masks for getters and setters, where the flags are derived from those
@@ -247,24 +262,23 @@ class Flags extends ModifierFlags {
* flags from the method with the default. Other flags applied at creation
* time are SYNTHETIC, DEFAULTPARAM, and possibly OVERRIDE.
*/
- final val DefaultGetterFlags: Long =
- PRIVATE | PROTECTED | FINAL
+ final val DefaultGetterFlags = PRIVATE | PROTECTED | FINAL
/** When a symbol for a method parameter is created, only these flags survive
* from Modifiers. Others which may be applied at creation time are:
* SYNTHETIC.
*/
- final val ValueParameterFlags: Long = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM
- final val BeanPropertyFlags = DEFERRED | OVERRIDE | STATIC
- final val VarianceFlags = COVARIANT | CONTRAVARIANT
+ final val ValueParameterFlags = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM
+ final val BeanPropertyFlags = DEFERRED | OVERRIDE | STATIC
+ final val VarianceFlags = COVARIANT | CONTRAVARIANT
/** These appear to be flags which should be transferred from owner symbol
* to a newly created constructor symbol.
*/
- final val ConstrFlags: Long = JAVA
+ final val ConstrFlags = JAVA
/** Module flags inherited by their module-class */
- final val ModuleToClassFlags: Long = AccessFlags | MODULE | PACKAGE | CASE | SYNTHETIC | JAVA | FINAL
+ final val ModuleToClassFlags = AccessFlags | TopLevelCreationFlags | CASE | SYNTHETIC
def getterFlags(fieldFlags: Long): Long = ACCESSOR + (
if ((fieldFlags & MUTABLE) != 0) fieldFlags & ~MUTABLE & ~PRESUPER
@@ -294,7 +308,7 @@ class Flags extends ModifierFlags {
private final val PKL_MASK = 0x00000FFF
- final val PickledFlags: Long = 0xFFFFFFFFL
+ final val PickledFlags = 0xFFFFFFFFL
private def rawPickledCorrespondence = Array(
(IMPLICIT, IMPLICIT_PKL),
@@ -406,32 +420,28 @@ class Flags extends ModifierFlags {
case 0x8000000000000000L => "" // (1L << 63)
case _ => ""
}
-
+
+ private def accessString(flags: Long, privateWithin: String)= (
+ if (privateWithin == "") {
+ if ((flags & PrivateLocal) == PrivateLocal) "private[this]"
+ else if ((flags & ProtectedLocal) == ProtectedLocal) "protected[this]"
+ else if ((flags & PRIVATE) != 0) "private"
+ else if ((flags & PROTECTED) != 0) "protected"
+ else ""
+ }
+ else if ((flags & PROTECTED) != 0) "protected[" + privateWithin + "]"
+ else "private[" + privateWithin + "]"
+ )
+
+ @deprecated("Use flagString on the flag-carrying member", "2.10.0")
def flagsToString(flags: Long, privateWithin: String): String = {
- var f = flags
- val pw =
- if (privateWithin == "") {
- if ((flags & PrivateLocal) == PrivateLocal) {
- f &= ~PrivateLocal
- "private[this]"
- } else if ((flags & ProtectedLocal) == ProtectedLocal) {
- f &= ~ProtectedLocal
- "protected[this]"
- } else {
- ""
- }
- } else if ((f & PROTECTED) != 0L) {
- f &= ~PROTECTED
- "protected[" + privateWithin + "]"
- } else {
- "private[" + privateWithin + "]"
- }
- List(flagsToString(f), pw) filterNot (_ == "") mkString " "
- }
+ val access = accessString(flags, privateWithin)
+ val nonAccess = flagsToString(flags & ~AccessFlags)
- // List of the raw flags, in pickled order
- protected final val MaxBitPosition = 62
+ List(nonAccess, access) filterNot (_ == "") mkString " "
+ }
+ @deprecated("Use flagString on the flag-carrying member", "2.10.0")
def flagsToString(flags: Long): String = {
// Fast path for common case
if (flags == 0L) "" else {
@@ -459,13 +469,16 @@ class Flags extends ModifierFlags {
def pickledToRawFlags(pflags: Long): Long =
(pflags & ~PKL_MASK) | p2r(pflags.toInt & PKL_MASK)
- protected final val pickledListOrder: List[Long] = {
+ // List of the raw flags, in pickled order
+ final val MaxBitPosition = 62
+
+ final val pickledListOrder: List[Long] = {
val all = 0 to MaxBitPosition map (1L << _)
val front = rawFlags map (_.toLong)
front.toList ++ (all filterNot (front contains _))
}
- protected final val rawFlagPickledOrder: Array[Long] = pickledListOrder.toArray
+ final val rawFlagPickledOrder: Array[Long] = pickledListOrder.toArray
def flagOfModifier(mod: Modifier): Long = mod match {
case Modifier.`protected` => PROTECTED
diff --git a/src/compiler/scala/reflect/internal/FreeVars.scala b/src/compiler/scala/reflect/internal/FreeVars.scala
new file mode 100644
index 0000000000..8b6e8b61f3
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/FreeVars.scala
@@ -0,0 +1,60 @@
+package scala.reflect
+package internal
+
+trait FreeVars extends api.FreeVars {
+ self: SymbolTable =>
+
+ object FreeTerm extends FreeTermExtractor {
+ def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] =
+ Some(freeTerm.name, freeTerm.info, freeTerm.value, freeTerm.origin)
+ }
+
+ object FreeType extends FreeTypeExtractor {
+ def unapply(freeType: FreeType): Option[(TypeName, Type, String)] =
+ Some(freeType.name, freeType.info, freeType.origin)
+ }
+
+ // [Eugene] am I doing this right?
+ def freeTerms(tree: Tree): List[FreeTerm] = {
+ def isFreeTermSym(sym: Symbol) = sym != null && sym.isFreeTerm
+ def isFreeTermTpe(t: Type) = t != null && isFreeTermSym(t.termSymbol)
+
+ val buf = collection.mutable.Set[Symbol]()
+ tree foreach (sub => {
+ if (sub.tpe != null) buf ++= (sub.tpe collect { case tpe if isFreeTermTpe(tpe) => tpe.typeSymbol })
+ if (sub.symbol != null && isFreeTermSym(sub.symbol)) buf += sub.symbol
+ })
+
+ buf.toList.collect{ case fty: FreeTerm => fty }
+ }
+
+ // [Eugene] am I doing this right?
+ def freeTypes(tree: Tree): List[FreeType] = {
+ def isFreeTypeSym(sym: Symbol) = sym != null && sym.isFreeType
+ def isFreeTypeTpe(t: Type) = t != null && isFreeTypeSym(t.typeSymbol)
+
+ val buf = collection.mutable.Set[Symbol]()
+ tree foreach (sub => {
+ if (sub.tpe != null) buf ++= (sub.tpe collect { case tpe if isFreeTypeTpe(tpe) => tpe.typeSymbol })
+ if (sub.symbol != null && isFreeTypeSym(sub.symbol)) buf += sub.symbol
+ })
+
+ buf.toList.collect{ case fty: FreeType => fty }
+ }
+
+ // todo. also update tpe's of dependent free vars
+ // e.g. if we substitute free$C, then free$C$this should have its info updated
+ // todo. should also transform typetags of types dependent on that free type?
+ // [Eugene] how do I check that the substitution is legal w.r.t fty.info?
+ def substituteFreeTypes(tree0: Tree, subs: Map[FreeType, Type]): Tree = {
+ val tree = tree0.duplicate
+ new TreeTypeSubstituter(subs.keys.toList, subs.values.toList).traverse(tree)
+ tree
+ }
+
+ // [Eugene] how do I check that the substitution is legal w.r.t fty.info?
+ def substituteFreeTypes(tpe0: Type, subs: Map[FreeType, Type]): Type = {
+ val tpe = tpe0 // [Eugene] tpe0.duplicate?
+ tpe.subst(subs.keys.toList, subs.values.toList)
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/FrontEnds.scala b/src/compiler/scala/reflect/internal/FrontEnds.scala
new file mode 100644
index 0000000000..74501c7686
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/FrontEnds.scala
@@ -0,0 +1,75 @@
+package scala.reflect
+package internal
+
+trait FrontEnds { self: SymbolTable =>
+
+ import scala.tools.nsc.reporters._
+ import scala.tools.nsc.Settings
+
+ def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
+ val settings = new Settings()
+ if (minSeverity <= 0) settings.verbose.value = true
+ if (minSeverity > 1) settings.nowarn.value = true
+ wrapReporter(new ConsoleReporter(settings))
+ }
+
+ abstract class FrontEndToReporterProxy(val frontEnd: FrontEnd) extends AbstractReporter {
+ import frontEnd.{Severity => ApiSeverity}
+ val API_INFO = frontEnd.INFO
+ val API_WARNING = frontEnd.WARNING
+ val API_ERROR = frontEnd.ERROR
+
+ type NscSeverity = Severity
+ val NSC_INFO = INFO
+ val NSC_WARNING = WARNING
+ val NSC_ERROR = ERROR
+
+ def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
+ frontEnd.log(pos, msg, nscSeverity match {
+ case NSC_INFO => API_INFO
+ case NSC_WARNING => API_WARNING
+ case NSC_ERROR => API_ERROR
+ })
+
+ def displayPrompt(): Unit =
+ frontEnd.interactive()
+ }
+
+ def wrapFrontEnd(frontEnd: FrontEnd): Reporter = new FrontEndToReporterProxy(frontEnd) {
+ val settings = new Settings()
+ settings.verbose.value = true
+ settings.nowarn.value = false
+ }
+
+ class ReporterToFrontEndProxy(val reporter: Reporter) extends FrontEnd {
+ val API_INFO = INFO
+ val API_WARNING = WARNING
+ val API_ERROR = ERROR
+
+ override def hasErrors = reporter.hasErrors
+ override def hasWarnings = reporter.hasWarnings
+
+ def display(info: Info): Unit = info.severity match {
+ case API_INFO => reporter.info(info.pos, info.msg, false)
+ case API_WARNING => reporter.warning(info.pos, info.msg)
+ case API_ERROR => reporter.error(info.pos, info.msg)
+ }
+
+ def interactive(): Unit = reporter match {
+ case reporter: AbstractReporter => reporter.displayPrompt()
+ case _ => // do nothing
+ }
+
+ override def flush(): Unit = {
+ super.flush()
+ reporter.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ reporter.reset()
+ }
+ }
+
+ def wrapReporter(reporter: Reporter): FrontEnd = new ReporterToFrontEndProxy(reporter)
+}
diff --git a/src/compiler/scala/reflect/internal/HasFlags.scala b/src/compiler/scala/reflect/internal/HasFlags.scala
index 8affd66cd5..348f81c51d 100644
--- a/src/compiler/scala/reflect/internal/HasFlags.scala
+++ b/src/compiler/scala/reflect/internal/HasFlags.scala
@@ -1,83 +1,12 @@
package scala.reflect
package internal
-/** ISSUE #1: Flag names vs. Test method names
- *
- * The following methods from Symbol have a name of
- * the form isFoo where FOO is the name of a flag, but where the method
- * body tests for more than whether the flag is set.
- *
- * There are two possibilities with such methods. Either the extra
- * tests are strictly to partition among overloaded flags (which is
- * the case we can live with in the short term, if each such flag's
- * partitioning assumptions are documented) or they aren't.
- *
- * The second case implies that "x hasFlag FOO" and "x.isFoo" have
- * different semantics, and this we can't live with, because even if
- * we're smart enough to avoid being tripped up by that, the next guy isn't.
- *
- * No extreme measures necessary, only renaming isFoo to something
- * which hews more closely to its implementation. (Or renaming the flag.)
- *
- // Defined in the compiler Symbol
- //
- final def isLabel = isMethod && !hasAccessorFlag && hasFlag(LABEL)
- final def isLocal: Boolean = owner.isTerm
- final def isModuleVar: Boolean = isVariable && hasFlag(MODULEVAR)
- final def isStable =
- isTerm &&
- !hasTraitFlag &&
- (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) &&
- !(tpe.isVolatile && !hasAnnotation(uncheckedStableClass))
- final def isStatic: Boolean =
- hasFlag(STATIC) || isRoot || owner.isStaticOwner
- override final def isTrait: Boolean =
- isClass && hasFlag(TRAIT | notDEFERRED) // A virtual class becomes a trait (part of DEVIRTUALIZE)
-
- // Defined in the library Symbol
- //
- def isTrait: Boolean = isClass && hasFlag(TRAIT) // refined later for virtual classes.
- final def isContravariant = isType && hasFlag(CONTRAVARIANT)
- final def isCovariant = isType && hasFlag(COVARIANT)
- final def isMethod = isTerm && hasFlag(METHOD)
- final def isModule = isTerm && hasFlag(MODULE)
- final def isPackage = isModule && hasFlag(PACKAGE)
- *
- */
-
-/** ISSUE #2: Implicit flag relationships must be made explicit.
- *
- * For instance, every time the MODULE flag is set, the FINAL flag is
- * set along with it:
- *
- .setFlag(FINAL | MODULE | PACKAGE | JAVA)
- .setFlag(FINAL | MODULE | PACKAGE | JAVA).setInfo(rootLoader)
- new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL)
- new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL)
- val m = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL)
- setFlag(module.getFlag(ModuleToClassFlags) | MODULE | FINAL)
- sourceModule.flags = MODULE | FINAL
-
- * However the same is not true of when the MODULE flag is cleared:
-
- sym.resetFlag(MODULE)
- .setFlag(sym.flags | STABLE).resetFlag(MODULE)
- sym.resetFlag(MODULE | FINAL | CASE)
-
- * It's not relevant whether this example poses any issues: we must
- * not tolerate these uncertainties. If the flags are to move together
- * then both setting and clearing have to be encapsulated. If there
- * is a useful and used distinction between the various permutations
- * of on and off, then it must be documented. It's the only way!
- */
-
import Flags._
/** Common code utilized by Modifiers (which carry the flags associated
* with Trees) and Symbol.
*/
trait HasFlags {
- type FlagsType
type AccessBoundaryType
type AnnotationType
@@ -86,12 +15,7 @@ trait HasFlags {
* flag methods through accessors and disallow raw flag manipulation.
* And after that, perhaps, on some magical day: a typesafe enumeration.
*/
- protected def flags: FlagsType
-
- /** The printable representation of this entity's flags and access boundary,
- * restricted to flags in the given mask.
- */
- def hasFlagsToString(mask: FlagsType): String
+ protected def flags: Long
/** Access level encoding: there are three scala flags (PRIVATE, PROTECTED,
* and LOCAL) which combine with value privateWithin (the "foo" in private[foo])
@@ -137,6 +61,23 @@ trait HasFlags {
*/
def hasNoFlags(mask: Long): Boolean = !hasFlag(mask)
+ /** The printable representation of this entity's flags and access boundary,
+ * restricted to flags in the given mask.
+ */
+ def flagString: String = flagString(flagMask)
+ def flagString(mask: Long): String = calculateFlagString(flags & mask)
+
+ /** The default mask determining which flags to display.
+ */
+ def flagMask: Long = AllFlags
+
+ /** The string representation of a single bit, seen from this
+ * flag carrying entity.
+ */
+ def resolveOverloadedFlag(flag: Long): String = Flags.flagToString(flag)
+
+ def privateWithinString = if (hasAccessBoundary) privateWithin.toString else ""
+
protected def isSetting(f: Long, mask: Long) = !hasFlag(f) && ((mask & f) != 0L)
protected def isClearing(f: Long, mask: Long) = hasFlag(f) && ((mask & f) != 0L)
@@ -165,26 +106,20 @@ trait HasFlags {
// which must have been a bug.
def isPublic = hasNoFlags(PRIVATE | PROTECTED) && !hasAccessBoundary
- // Renamed the Modifiers impl from isArgument.
- def isParameter = hasFlag(PARAM)
-
// Removed isClass qualification since the flag isn't overloaded and
// sym.isClass is enforced in Namers#validate.
def isSealed = hasFlag(SEALED)
// Removed !isClass qualification since the flag isn't overloaded.
- def isDeferred = hasFlag(DEFERRED )
+ def isDeferred = hasFlag(DEFERRED)
// Dropped isTerm condition because flag isn't overloaded.
def isAbstractOverride = hasFlag(ABSOVERRIDE)
def isAnyOverride = hasFlag(OVERRIDE | ABSOVERRIDE)
- def isDefaultInit = hasFlag(DEFAULTINIT)
// Disambiguating: DEFAULTPARAM, TRAIT
def hasDefault = hasAllFlags(DEFAULTPARAM | PARAM)
def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM)
- def hasTraitFlag = hasFlag(TRAIT)
- def hasDefaultFlag = hasFlag(DEFAULTPARAM)
// Straightforwardly named accessors already being used differently.
// These names are most likely temporary.
@@ -193,16 +128,9 @@ trait HasFlags {
def hasLocalFlag = hasFlag(LOCAL)
def hasModuleFlag = hasFlag(MODULE)
def hasPackageFlag = hasFlag(PACKAGE)
- def hasPreSuperFlag = hasFlag(PRESUPER)
def hasStableFlag = hasFlag(STABLE)
def hasStaticFlag = hasFlag(STATIC)
- // Disambiguating: BYNAMEPARAM, CAPTURED, COVARIANT.
- def isByNameParam = hasAllFlags(BYNAMEPARAM | PARAM)
- // Nope, these aren't going to fly:
- // def isCapturedVariable = hasAllFlags(CAPTURED | MUTABLE)
- // def isCovariant = hasFlag(COVARIANT) && hasNoFlags(PARAM | MUTABLE)
-
// Disambiguating: LABEL, CONTRAVARIANT, INCONSTRUCTOR
def isLabel = hasAllFlags(LABEL | METHOD) && !hasAccessorFlag
// Cannot effectively disambiguate the others at this level.
@@ -212,23 +140,60 @@ trait HasFlags {
// Name
def isJavaDefined = hasFlag(JAVA)
- // Keeping some potentially ambiguous names around so as not to break
- // the rest of the world
+ def flagBitsToString(bits: Long): String = {
+ // Fast path for common case
+ if (bits == 0L) "" else {
+ var sb: StringBuilder = null
+ var i = 0
+ while (i <= MaxBitPosition) {
+ val flag = Flags.rawFlagPickledOrder(i)
+ if ((bits & flag) != 0L) {
+ val s = resolveOverloadedFlag(flag)
+ if (s.length > 0) {
+ if (sb eq null) sb = new StringBuilder append s
+ else if (sb.length == 0) sb append s
+ else sb append " " append s
+ }
+ }
+ i += 1
+ }
+ if (sb eq null) "" else sb.toString
+ }
+ }
+
+ def accessString: String = {
+ val pw = privateWithinString
+
+ if (pw == "") {
+ if (hasAllFlags(PrivateLocal)) "private[this]"
+ else if (hasAllFlags(ProtectedLocal)) "protected[this]"
+ else if (hasFlag(PRIVATE)) "private"
+ else if (hasFlag(PROTECTED)) "protected"
+ else ""
+ }
+ else if (hasFlag(PROTECTED)) "protected[" + pw + "]"
+ else "private[" + pw + "]"
+ }
+ protected def calculateFlagString(basis: Long): String = {
+ val access = accessString
+ val nonAccess = flagBitsToString(basis & ~AccessFlags)
+
+ if (access == "") nonAccess
+ else if (nonAccess == "") access
+ else nonAccess + " " + access
+ }
+
+ // Backward compat section
+ @deprecated( "Use isTrait", "2.10.0")
+ def hasTraitFlag = hasFlag(TRAIT)
+ @deprecated("Use hasDefault", "2.10.0")
+ def hasDefaultFlag = hasFlag(DEFAULTPARAM)
@deprecated("", "2.9.0")
def isAbstract = hasFlag(ABSTRACT)
- // Problematic:
- // ABSTRACT and DEFERRED too easy to confuse, and
- // ABSTRACT + OVERRIDE ==> ABSOVERRIDE adds to it.
- //
- // final def isAbstractClass = isClass && hasFlag(ABSTRACT)
- // def isAbstractType = false // to be overridden
-
- // Question:
- // Which name? All other flags are isFlag so it's probably a mistake to
- // vary from that, but isAccessor does sound like it includes the other
- // *ACCESSOR flags. Perhaps something like isSimpleAccessor.
- //
- // def isAccessor = hasFlag(ACCESSOR )
- // final def isGetterOrSetter = hasAccessorFlag
+ @deprecated("Use isValueParameter or isTypeParameter", "2.10.0")
+ def isParameter = hasFlag(PARAM)
+ @deprecated("Use flagString", "2.10.0")
+ def defaultFlagString = flagString
+ @deprecated("Use flagString(mask)", "2.10.0")
+ def hasFlagsToString(mask: Long): String = flagString(mask)
}
-
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 04381937d1..8404386e10 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -4,7 +4,24 @@ import scala.collection.mutable.WeakHashMap
trait Importers { self: SymbolTable =>
- abstract class Importer {
+ // [Eugene] possible to make this less cast-heavy?
+ def mkImporter(from0: api.Universe): Importer { val from: from0.type } = (
+ if (self eq from0) {
+ new Importer {
+ val from = from0
+ val reverse = this.asInstanceOf[from.Importer{ val from: self.type }]
+ def importSymbol(sym: from.Symbol) = sym.asInstanceOf[self.Symbol]
+ def importType(tpe: from.Type) = tpe.asInstanceOf[self.Type]
+ def importTree(tree: from.Tree) = tree.asInstanceOf[self.Tree]
+ }
+ } else {
+ // todo. fix this loophole
+ assert(from0.isInstanceOf[SymbolTable], "`from` should be an instance of scala.reflect.internal.SymbolTable")
+ new StandardImporter { val from = from0.asInstanceOf[SymbolTable] }
+ }
+ ).asInstanceOf[Importer { val from: from0.type }]
+
+ abstract class StandardImporter extends Importer {
val from: SymbolTable
@@ -24,13 +41,15 @@ trait Importers { self: SymbolTable =>
}
}
- object reverse extends from.Importer {
+ object reverse extends from.StandardImporter {
val from: self.type = self
- for ((fromsym, mysym) <- Importer.this.symMap) symMap += ((mysym, fromsym))
- for ((fromtpe, mytpe) <- Importer.this.tpeMap) tpeMap += ((mytpe, fromtpe))
+ for ((fromsym, mysym) <- StandardImporter.this.symMap) symMap += ((mysym, fromsym))
+ for ((fromtpe, mytpe) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, fromtpe))
}
- def importPosition(pos: from.Position): Position = NoPosition
+ // todo. careful import of positions
+ def importPosition(pos: from.Position): Position =
+ pos.asInstanceOf[Position]
def importSymbol(sym0: from.Symbol): Symbol = {
def doImport(sym: from.Symbol): Symbol = {
@@ -51,8 +70,10 @@ trait Importers { self: SymbolTable =>
linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol)
case x: from.ModuleSymbol =>
linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol)
- case x: from.FreeVar =>
- newFreeVar(importName(x.name).toTermName, importType(x.tpe), x.value, myflags)
+ case x: from.FreeTerm =>
+ newFreeTermSymbol(importName(x.name).toTermName, importType(x.info), x.value, x.flags, x.origin)
+ case x: from.FreeType =>
+ newFreeTypeSymbol(importName(x.name).toTypeName, importType(x.info), x.value, x.flags, x.origin)
case x: from.TermSymbol =>
linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol)
case x: from.TypeSkolem =>
@@ -63,7 +84,7 @@ trait Importers { self: SymbolTable =>
}
myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags)
case x: from.ModuleClassSymbol =>
- val mysym = myowner.newModuleClassSymbol(myname.toTypeName, mypos, myflags)
+ val mysym = myowner.newModuleClass(myname.toTypeName, mypos, myflags)
symMap(x) = mysym
mysym.sourceModule = importSymbol(x.sourceModule)
mysym
@@ -72,7 +93,7 @@ trait Importers { self: SymbolTable =>
symMap(x) = mysym
if (sym.thisSym != sym) {
mysym.typeOfThis = importType(sym.typeOfThis)
- mysym.thisSym.name = importName(sym.thisSym.name)
+ mysym.thisSym setName importName(sym.thisSym.name)
}
mysym
case x: from.TypeSymbol =>
@@ -109,14 +130,18 @@ trait Importers { self: SymbolTable =>
val owner = sym.owner
var scope = if (owner.isClass && !owner.isRefinementClass) owner.info else from.NoType
var existing = scope.decl(name)
- if (sym.isPackageClass || sym.isModuleClass) existing = existing.moduleClass
+ if (sym.isModuleClass)
+ existing = existing.moduleClass
+
if (!existing.exists) scope = from.NoType
val myname = importName(name)
val myowner = importSymbol(owner)
val myscope = if (scope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType
var myexisting = if (myscope != NoType) myowner.info.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods
- if (sym.isPackageClass || sym.isModuleClass) myexisting = importSymbol(sym.sourceModule).moduleClass
+ if (sym.isModuleClass)
+ myexisting = importSymbol(sym.sourceModule).moduleClass
+
if (!sym.isOverloaded && myexisting.isOverloaded) {
myexisting =
if (sym.isMethod) {
@@ -301,7 +326,7 @@ trait Importers { self: SymbolTable =>
case from.ValDef(mods, name, tpt, rhs) =>
new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs))
case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, vparamss map (_ map importValDef), importTree(tpt), importTree(rhs))
+ new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs))
case from.TypeDef(mods, name, tparams, rhs) =>
new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs))
case from.LabelDef(name, params, rhs) =>
@@ -370,6 +395,8 @@ trait Importers { self: SymbolTable =>
case _ =>
new Ident(importName(name))
}
+ case from.ReferenceToBoxed(ident) =>
+ new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident })
case from.Literal(constant @ from.Constant(_)) =>
new Literal(importConstant(constant))
case from.TypeTree() =>
@@ -421,7 +448,7 @@ trait Importers { self: SymbolTable =>
def importIdent(tree: from.Ident): Ident = importTree(tree).asInstanceOf[Ident]
def importCaseDef(tree: from.CaseDef): CaseDef = importTree(tree).asInstanceOf[CaseDef]
def importConstant(constant: from.Constant): Constant = new Constant(constant.tag match {
- case ClassTag => importType(constant.value.asInstanceOf[from.Type])
+ case ClazzTag => importType(constant.value.asInstanceOf[from.Type])
case EnumTag => importSymbol(constant.value.asInstanceOf[from.Symbol])
case _ => constant.value
})
diff --git a/src/compiler/scala/reflect/internal/JvmClassInfo.scala b/src/compiler/scala/reflect/internal/JvmClassInfo.scala
new file mode 100644
index 0000000000..d47f51e512
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/JvmClassInfo.scala
@@ -0,0 +1,440 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.reflect.internal
+
+import java.io.{ DataInput, InputStream, DataInputStream, ByteArrayInputStream, BufferedInputStream, FileInputStream }
+import scala.tools.nsc.io.{ Directory }
+import scala.reflect.NameTransformer.decode
+import scala.tools.util.StringOps.trimTrailingSpace
+import ConstantPool._
+
+final case class JvmVersion(minorVersion: Int, majorVersion: Int)
+
+trait ClassfileModel {
+ type Result
+ type Entry
+ type InterfaceInfo
+ type MemberInfo
+ type AttributeInfo
+ type InnerClassInfo
+
+ protected implicit def EntryArrayTag: ArrayTag[Entry]
+ protected implicit def InterfaceInfoArrayTag: ArrayTag[InterfaceInfo]
+ protected implicit def MemberInfoArrayTag: ArrayTag[MemberInfo]
+ protected implicit def AttributeInfoArrayTag: ArrayTag[AttributeInfo]
+ protected implicit def InnerClassInfoArrayTag: ArrayTag[InnerClassInfo]
+
+ // These could be implemented to jump forward in the stream if the
+ // result is not wanted.
+ def readConstantPoolEntry(): Entry
+ def readInterface(): InterfaceInfo
+ def readMember(): MemberInfo
+ def readAttribute(): AttributeInfo
+ def readInnerClass(): InnerClassInfo
+
+ def createInfo(
+ version: JvmVersion,
+ entries: Array[Entry],
+ flags: Int,
+ name: String,
+ superName: String,
+ interfaces: Array[InterfaceInfo],
+ fields: Array[MemberInfo],
+ methods: Array[MemberInfo],
+ attributes: Array[AttributeInfo]
+ ): Result
+}
+
+abstract class StreamingClassfileModel extends ClassfileModel {
+ protected[this] val in: DataInput
+ private[this] var name: String = _
+ private[this] var entries: Array[PoolEntry] = _
+
+ type Entry = PoolEntry
+
+ // These translate null into "", it's less troublesome.
+ protected def nameAt(idx: Int) = entries(idx) match {
+ case x: Name_Info => stringAt(x.name_index).replace('/', '.')
+ case _ => ""
+ }
+ protected def stringAt(idx: Int) = entries(idx) match {
+ case x: Utf8_info => x.stringValue
+ case _ => ""
+ }
+
+ protected def u4 = in.readInt
+ protected def u2 = in.readUnsignedShort.toChar
+ protected def u1 = in.readUnsignedByte
+
+ // The constant_pool table is indexed from 1 to constant_pool_count−1.
+ protected def readConstantPool(): Array[Entry] = {
+ val count = u2
+ val entries = new Array[Entry](count)
+ var i = 1
+ while (i < count) {
+ val entry = readConstantPoolEntry()
+ entries(i) = entry
+ i += entry.width
+ }
+ entries
+ }
+ protected def readInterfaces() = {
+ val count = u2
+ val interfaces = new Array[InterfaceInfo](count)
+ var i = 0
+ while (i < count) {
+ interfaces(i) = readInterface()
+ i += 1
+ }
+ interfaces
+ }
+ protected def readMembers() = {
+ val count = u2
+ val arr = new Array[MemberInfo](count)
+ var i = 0
+ while (i < count) {
+ arr(i) = readMember()
+ i += 1
+ }
+ arr
+ }
+ protected def readAttributes(): Array[AttributeInfo] = {
+ val count = u2
+ val arr = new Array[AttributeInfo](count)
+ var i = 0
+ while (i < count) {
+ arr(i) = readAttribute()
+ i += 1
+ }
+ arr
+ }
+ protected def readInnerClasses() = {
+ val count = u2
+ val arr = new Array[InnerClassInfo](count)
+ var i = 0
+ while (i < count) {
+ arr(i) = readInnerClass()
+ i += 1
+ }
+ arr
+ }
+ protected def thisClass = name
+
+ def parse() = {
+ assert(u4 == 0xCAFEBABE, "Bad magic number")
+ val version = JvmVersion(u2, u2)
+ this.entries = readConstantPool()
+ val flags = u2.toShort
+ this.name = nameAt(u2)
+ val superName = nameAt(u2)
+ val interfaces = readInterfaces()
+ val fields = readMembers()
+ val methods = readMembers()
+ val attributes = readAttributes()
+
+ try createInfo(version, entries, flags, name, superName, interfaces, fields, methods, attributes)
+ finally entries = null
+ }
+}
+
+abstract class ScalacClassfileModel extends StreamingClassfileModel {
+ type Result = JvmClassInfo
+ type InterfaceInfo = String
+ type MemberInfo = JvmMemberInfo
+ type AttributeInfo = JvmAttributeInfo
+ type InnerClassInfo = JvmInnerClassInfo
+
+ protected implicit def EntryArrayTag = arrayTag[PoolEntry]
+ protected implicit def InterfaceInfoArrayTag = arrayTag[InterfaceInfo]
+ protected implicit def MemberInfoArrayTag = arrayTag[MemberInfo]
+ protected implicit def AttributeInfoArrayTag = arrayTag[AttributeInfo]
+ protected implicit def InnerClassInfoArrayTag = arrayTag[InnerClassInfo]
+
+ def readConstantPoolEntry(): PoolEntry
+ def readInterface(): String
+ def readMember(): JvmMemberInfo
+ def readAttribute(): JvmAttributeInfo
+ def readInnerClass(): JvmInnerClassInfo
+
+ def createInfo(
+ version: JvmVersion,
+ entries: Array[PoolEntry],
+ flags: Int,
+ name: String,
+ superName: String,
+ interfaces: Array[String],
+ fields: Array[JvmMemberInfo],
+ methods: Array[JvmMemberInfo],
+ attributes: Array[JvmAttributeInfo]
+ ): JvmClassInfo = new JvmClassInfo(name, superName, interfaces, fields, methods, attributes)
+}
+
+class JvmClassInfoBuilder(protected[this] val in: DataInput) extends ScalacClassfileModel {
+ def readInterface(): InterfaceInfo = nameAt(u2)
+ def readMember(): JvmMemberInfo = new JvmMemberInfo(u2.toShort, stringAt(u2), stringAt(u2), readAttributes())
+ def readInnerClass(): JvmInnerClassInfo = new JvmInnerClassInfo(thisClass, nameAt(u2), nameAt(u2), stringAt(u2), u2.toShort)
+
+ def readConstantPoolEntry(): Entry = (u1: @annotation.switch) match {
+ case CONSTANT_Utf8 => new Utf8_info(in.readUTF)
+ case CONSTANT_Integer => new Integer_info(in.readInt)
+ case CONSTANT_Float => new Float_info(in.readFloat)
+ case CONSTANT_Long => new Long_info(in.readLong)
+ case CONSTANT_Double => new Double_info(in.readDouble)
+ case CONSTANT_Class => new Class_info(u2)
+ case CONSTANT_String => new String_info(u2)
+ case CONSTANT_Fieldref => new Fieldref_info(u2, u2)
+ case CONSTANT_Methodref => new Methodref_info(u2, u2)
+ case CONSTANT_InterfaceMethodref => new InterfaceMethodref_info(u2, u2)
+ case CONSTANT_NameAndType => new NameAndType_info(u2, u2)
+ }
+
+ // field_info attributes:
+ // ConstantValue (§4.7.2), Synthetic (§4.7.8), Signature (§4.7.9), Deprecated (§4.7.15),
+ // RuntimeVisibleAnnotations (§4.7.16) and RuntimeInvisibleAnnotations (§4.7.17).
+ //
+ // method_info attributes:
+ // Code (§4.7.3), Exceptions (§4.7.5), Synthetic (§4.7.8), Signature (§4.7.9), Deprecated (§4.7.15),
+ // RuntimeVisibleAnnotations (§4.7.16), RuntimeInvisibleAnnotations (§4.7.17), RuntimeVisibleParameterAnnotations (§4.7.18),
+ // RuntimeInvisibleParameterAnnotations (§4.7.19) and AnnotationDefault (§4.7.20).
+
+ def readAttribute(): AttributeInfo = stringAt(u2) match {
+ case "Signature" => u4 ; new SignatureAttr(stringAt(u2))
+ case "InnerClasses" => u4 ; new InnerClassesAttr(readInnerClasses())
+ case name => val bytes = new Array[Byte](u4) ; in.readFully(bytes) ; new GenericAttr(name, bytes)
+ }
+}
+
+object Classify {
+
+ /*
+
+
+ 4.2.2 Unqualified Names
+
+Names of methods, fields and local variables are stored as unqualified
+names. Unqualified names must not contain the characters '.', ';', '['
+or '/'. Method names are further constrained so that, with the exception
+of the special method names <init> and <clinit> (§3.9), they must not
+contain the characters '<' or '>'.
+
+ 4.3 Descriptors and Signatures
+
+A descriptor is a string representing the type of a field or method.
+Descriptors are represented in the class file format using modified
+UTF-8 strings (§4.4.7) and thus may be drawn, where not further
+constrained, from the entire Unicode character set. A signature is a
+string representing the generic type of a field or method, or generic
+type information for a class declaration.
+*/
+
+}
+
+object ConstantPool {
+ type UShort = Char
+
+ final val CONSTANT_Utf8 = 1
+ final val CONSTANT_Integer = 3
+ final val CONSTANT_Float = 4
+ final val CONSTANT_Long = 5
+ final val CONSTANT_Double = 6
+ final val CONSTANT_Class = 7
+ final val CONSTANT_String = 8
+ final val CONSTANT_Fieldref = 9
+ final val CONSTANT_Methodref = 10
+ final val CONSTANT_InterfaceMethodref = 11
+ final val CONSTANT_NameAndType = 12
+
+ abstract class Name_Info(tag: Byte) extends PoolEntry(tag) {
+ def name_index: UShort
+ }
+ abstract class Ref_Info(tag: Byte) extends PoolEntry(tag) {
+ def class_index: UShort
+ def name_and_type_index: UShort
+ }
+ class Class_info(val name_index: UShort) extends Name_Info(CONSTANT_Class) { }
+ class Double_info(val value: Double) extends PoolEntry(CONSTANT_Double) {
+ override def width = 2
+ }
+ class Fieldref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_Fieldref)
+ class Float_info(val value: Float) extends PoolEntry(CONSTANT_Float)
+ class Integer_info(val value: Int) extends PoolEntry(CONSTANT_Integer)
+ class InterfaceMethodref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_InterfaceMethodref)
+ class Long_info(val value: Long) extends PoolEntry(CONSTANT_Long) {
+ override def width = 2
+ }
+ class Methodref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_Methodref)
+ class NameAndType_info(val name_index: UShort, val descriptor_index: UShort) extends Name_Info(CONSTANT_NameAndType) {
+ override def toString = "NameAndType #%s:#%s;".format(name_index, descriptor_index)
+ }
+ class String_info(val string_index: UShort) extends PoolEntry(CONSTANT_String) { }
+ class Utf8_info(override val stringValue: String) extends PoolEntry(CONSTANT_Utf8) {
+ override def toString = ("Asciz " + stringValue).trim
+ }
+
+ abstract class PoolEntry(tag: Byte) {
+ def width = 1
+ def stringValue: String = sys.error("Not a String-valued constant pool entry: " + this)
+ override def toString = (
+ getClass.getName.split("[.$]").last + "/" + tag
+ )
+ }
+ object NoEntry extends PoolEntry(-1) { }
+}
+
+abstract class JvmInfo(attributes: Array[JvmAttributeInfo]) {
+ // def flags: Short
+ def name: String
+
+ val signature = attributes collectFirst { case x: SignatureAttr => x.value } getOrElse ""
+ val innerClasses = attributes collectFirst { case x: InnerClassesAttr => x.value } getOrElse Array()
+}
+
+
+class JvmClassInfo(
+ val name: String,
+ val superName: String,
+ val interfaces: Array[String],
+ val fields: Array[JvmMemberInfo],
+ val methods: Array[JvmMemberInfo],
+ attributes: Array[JvmAttributeInfo]
+) extends JvmInfo(attributes) {
+
+ def members = fields ++ methods sortBy (_.decodedName)
+ def memberDescriptors = members map (_.toErasedString)
+ def memberSignatures = members filter (_.hasSignature) map (_.toGenericString)
+ def descriptorsString = if (memberDescriptors.nonEmpty) memberDescriptors.mkString("\n-- Member Descriptors --\n", "\n", "\n") else ""
+ def signaturesString = if (memberSignatures.nonEmpty) memberSignatures.mkString("\n-- Member Signatures --\n", "\n", "\n") else ""
+ def innersString = if (innerClasses.isEmpty) "" else innerClasses.mkString("\n-- Inner Classes --\n", "\n", "\n")
+ def membersString = descriptorsString + signaturesString
+ def extendsString = if (superName == "") "" else " extends " + superName
+ def implementsString = if (interfaces.isEmpty) "" else interfaces.mkString("Implements: ", ", ", "")
+
+ private def group(label: String, xs: Traversable[(String, String)]) =
+ xs map { case (name, value) => line(label, name, value) } mkString "\n"
+
+ private def line(label: String, name: String, data: String) =
+ trimTrailingSpace(" %-15s %30s %s".format(label, name, data))
+
+ override def toString = (
+ List(
+ "class " + name + extendsString,
+ if (signature == "") "" else line("class sig", "", signature),
+ group("interface", interfaces map (x => (("", x)))),
+ (innerClasses map (ic => line(ic.kind, ic.innerName, ic.nestString))).sorted.mkString("\n"),
+ group("descriptor", members map (x => (x.name, x.descriptor))),
+ group("signature", members filter (_.hasSignature) map (x => (x.name, x.signature)))
+ ) map trimTrailingSpace filterNot (_ == "") mkString ("", "\n", "\n")
+ )
+}
+
+// method_info or field_info {
+// u2 access_flags;
+// u2 name_index;
+// u2 descriptor_index;
+// u2 attributes_count;
+// attribute_info attributes[attributes_count];
+// }
+class JvmMemberInfo(
+ val flags: Short,
+ val name: String,
+ val descriptor: String,
+ attributes: Array[JvmAttributeInfo]
+) extends JvmInfo(attributes) {
+ def decodedName = decode(name)
+ def hasSignature = signature != ""
+ def toErasedString = "%-30s %s".format(decodedName, descriptor)
+ def toGenericString = "%-30s %s".format(decodedName, signature)
+
+ override def toString = (
+ if (hasSignature) toGenericString else toErasedString
+ )
+}
+
+abstract class JvmAttributeInfo {
+ def name: String
+ def value: Any
+}
+class GenericAttr(val name: String, val value: Array[Byte]) extends JvmAttributeInfo {
+ // attribute_info {
+ // u2 attribute_name_index;
+ // u4 attribute_length;
+ // u1 info[attribute_length];
+ // }
+}
+class SignatureAttr(val value: String) extends JvmAttributeInfo {
+ def name = "Signature"
+}
+class InnerClassesAttr(val value: Array[JvmInnerClassInfo]) extends JvmAttributeInfo {
+ def name = "InnerClasses"
+}
+
+// package foo { class Foo { class Bar } }
+//
+// javap would say
+// Bar = class foo.Foo$Bar of class foo.Foo
+// which is translated as
+// innerClass = foo.Foo$Bar
+// outerClass = foo.Foo
+// innerName = Bar
+
+class JvmInnerClassInfo(
+ thisClass: String, // classfile which is being parsed
+ val innerClass: String, // the full name of the inner/nested class
+ val outerClass: String, // the full name of the outer class - must be a prefix of innerClass
+ val innerName: String, // the simple name of the inner class - should (?) be a suffix of innerClass
+ val flags: Short // flags
+) {
+ val isEntryOfEnclosingClass = !isAnonymousClass && (innerClass == thisClass)
+ val isEntryOfNestedClass = !isAnonymousClass && (outerClass == thisClass)
+
+ def isTopLevelClass = outerClass == ""
+ def isAnonymousClass = innerName == ""
+ def isMemberClass = !isTopLevelClass
+
+ def kind = (
+ if (isEntryOfEnclosingClass) "inner/enclosing"
+ else if (isEntryOfNestedClass) "inner/nested"
+ else if (isAnonymousClass) "inner/anon"
+ else "inner"
+ )
+ def nestString = (
+ if (isEntryOfEnclosingClass) "enclosing class: " + outerClass
+ else if (isEntryOfNestedClass) "member class: " + innerClass
+ else if (isAnonymousClass) "anonymous class: " + innerClass
+ else innerClass + " in " + outerClass
+ )
+ override def toString = innerName + "=" + nestString
+}
+
+object JvmClassInfo {
+ private def classFiles(path: String) =
+ Directory(path).deepFiles filter (_ hasExtension "class")
+
+ def classInfoMap(path: String): Map[String, JvmClassInfo] = {
+ classFiles(path) map (f => (f.path, JvmClassInfo fromFile f.jfile)) toMap
+ }
+ def classInfoList(path: String): List[(String, JvmClassInfo)] = {
+ classInfoMap(path).toList sortBy (_._1)
+ }
+
+ def fromFile(file: java.io.File) =
+ fromStream(new BufferedInputStream(new FileInputStream(file)))
+
+ def fromBytes(bytes: Array[Byte]) =
+ fromStream(new ByteArrayInputStream(bytes))
+
+ def fromPath(path: String) =
+ fromStream(new BufferedInputStream(new FileInputStream(path)))
+
+ def fromStream(in0: InputStream) = {
+ val in = new DataInputStream(in0)
+ try fromDataInput(in) finally in.close()
+ }
+
+ def fromDataInput(in: DataInput): JvmClassInfo = {
+ new JvmClassInfoBuilder(in) parse
+ }
+}
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
deleted file mode 100644
index 5ec8d08ffb..0000000000
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ /dev/null
@@ -1,215 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Martin Odersky
- */
-
-package scala.reflect
-package internal
-
-import java.security.MessageDigest
-import scala.io.Codec
-import Chars.isOperatorPart
-
-/** A trait to encapsulate name mangling. It's intended for the
- * values and methods involved in assembling names out of other names,
- * and not for simple synthetically named locals.
- */
-trait NameManglers {
- self: SymbolTable =>
-
- trait NameManglingCommon {
- self: CommonNames =>
-
- val MODULE_SUFFIX_STRING = NameTransformer.MODULE_SUFFIX_STRING
- val NAME_JOIN_STRING = NameTransformer.NAME_JOIN_STRING
-
- val MODULE_SUFFIX_NAME: TermName = newTermName(MODULE_SUFFIX_STRING)
- val NAME_JOIN_NAME: TermName = newTermName(NAME_JOIN_STRING)
-
- def flattenedName(segments: Name*): NameType = compactedString(segments mkString NAME_JOIN_STRING)
-
- /**
- * COMPACTIFY
- *
- * The hashed name has the form (prefix + marker + md5 + marker + suffix), where
- * - prefix/suffix.length = MaxNameLength / 4
- * - md5.length = 32
- *
- * We obtain the formula:
- *
- * FileNameLength = 2*(MaxNameLength / 4) + 2.marker.length + 32 + 6
- *
- * (+6 for ".class"). MaxNameLength can therefore be computed as follows:
- */
- private final val marker = "$$$$"
- private final val MaxNameLength = math.min(
- settings.maxClassfileName.value - 6,
- 2 * (settings.maxClassfileName.value - 6 - 2*marker.length - 32)
- )
- private lazy val md5 = MessageDigest.getInstance("MD5")
- private def toMD5(s: String, edge: Int) = {
- val prefix = s take edge
- val suffix = s takeRight edge
-
- val cs = s.toArray
- val bytes = Codec toUTF8 cs
- md5 update bytes
- val md5chars = md5.digest() map (b => (b & 0xFF).toHexString) mkString
-
- prefix + marker + md5chars + marker + suffix
- }
- private def compactedString(s: String) =
- if (s.length <= MaxNameLength) s
- else toMD5(s, MaxNameLength / 4)
- }
-
- trait TypeNameMangling extends NameManglingCommon {
- self: tpnme.type =>
-
- }
-
- trait TermNameMangling extends NameManglingCommon {
- self: nme.type =>
-
- val IMPL_CLASS_SUFFIX = "$class"
- val LOCALDUMMY_PREFIX = "<local " // owner of local blocks
- val PROTECTED_PREFIX = "protected$"
- val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set"
- val SINGLETON_SUFFIX = ".type"
- val SUPER_PREFIX_STRING = "super$"
- val INIT_DEFAULT_PREFIX = "init$"
- val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
- val SETTER_SUFFIX: TermName = encode("_=")
-
- @deprecated("Use SPECIALIZED_SUFFIX", "2.10.0")
- def SPECIALIZED_SUFFIX_STRING = SPECIALIZED_SUFFIX.toString
- @deprecated("Use SPECIALIZED_SUFFIX", "2.10.0")
- def SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX.toTermName
-
- def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR
- def isExceptionResultName(name: Name) = name startsWith EXCEPTION_RESULT_PREFIX
- def isImplClassName(name: Name) = name endsWith IMPL_CLASS_SUFFIX
- def isLocalDummyName(name: Name) = name startsWith LOCALDUMMY_PREFIX
- def isLocalName(name: Name) = name endsWith LOCAL_SUFFIX_STRING
- def isLoopHeaderLabel(name: Name) = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
- def isProtectedAccessorName(name: Name) = name startsWith PROTECTED_PREFIX
- def isSuperAccessorName(name: Name) = name startsWith SUPER_PREFIX_STRING
- def isReplWrapperName(name: Name) = name containsName INTERPRETER_IMPORT_WRAPPER
- def isSetterName(name: Name) = name endsWith SETTER_SUFFIX
- def isTraitSetterName(name: Name) = isSetterName(name) && (name containsName TRAIT_SETTER_SEPARATOR_STRING)
- def isSingletonName(name: Name) = name endsWith SINGLETON_SUFFIX
- def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_NAME
-
- def isOpAssignmentName(name: Name) = name match {
- case raw.NE | raw.LE | raw.GE | EMPTY => false
- case _ =>
- name.endChar == '=' && name.startChar != '=' && isOperatorPart(name.startChar)
- }
-
- /** The expanded setter name of `name` relative to this class `base`
- */
- def expandedSetterName(name: TermName, base: Symbol): TermName =
- expandedName(name, base, separator = TRAIT_SETTER_SEPARATOR_STRING)
-
- /** If `name` is an expandedName name, the original name.
- * Otherwise `name` itself.
- */
- def originalName(name: Name): Name = {
- var i = name.length
- while (i >= 2 && !(name(i - 1) == '$' && name(i - 2) == '$')) i -= 1
- if (i >= 2) {
- while (i >= 3 && name(i - 3) == '$') i -= 1
- name.subName(i, name.length)
- } else name
- }
-
- def unspecializedName(name: Name): Name = (
- if (name endsWith SPECIALIZED_SUFFIX)
- name.subName(0, name.lastIndexOf('m') - 1)
- else name
- )
-
- def macroMethodName(name: Name) = {
- val base = if (name.isTypeName) nme.TYPEkw else nme.DEFkw
- base append nme.MACRO append name
- }
-
- /** Return the original name and the types on which this name
- * is specialized. For example,
- * {{{
- * splitSpecializedName("foo$mIcD$sp") == ('foo', "I", "D")
- * }}}
- * `foo$mIcD$sp` is the name of a method specialized on two type
- * parameters, the first one belonging to the method itself, on Int,
- * and another one belonging to the enclosing class, on Double.
- */
- def splitSpecializedName(name: Name): (Name, String, String) =
- if (name endsWith SPECIALIZED_SUFFIX) {
- val name1 = name dropRight SPECIALIZED_SUFFIX.length
- val idxC = name1 lastIndexOf 'c'
- val idxM = name1 lastIndexOf 'm'
-
- (name1.subName(0, idxM - 1),
- name1.subName(idxC + 1, name1.length).toString,
- name1.subName(idxM + 1, idxC).toString)
- } else
- (name, "", "")
-
- def getterName(name: TermName): TermName = if (isLocalName(name)) localToGetter(name) else name
- def getterToLocal(name: TermName): TermName = name append LOCAL_SUFFIX_STRING
- def getterToSetter(name: TermName): TermName = name append SETTER_SUFFIX
- def localToGetter(name: TermName): TermName = name dropRight LOCAL_SUFFIX_STRING.length
-
- def dropLocalSuffix(name: Name): Name = if (name endsWith ' ') name dropRight 1 else name
-
- def setterToGetter(name: TermName): TermName = {
- val p = name.pos(TRAIT_SETTER_SEPARATOR_STRING)
- if (p < name.length)
- setterToGetter(name drop (p + TRAIT_SETTER_SEPARATOR_STRING.length))
- else
- name.subName(0, name.length - SETTER_SUFFIX.length)
- }
-
- def defaultGetterName(name: Name, pos: Int): TermName = {
- val prefix = if (isConstructorName(name)) INIT_DEFAULT_PREFIX else name
- newTermName(prefix + DEFAULT_GETTER_STRING + pos)
- }
- def defaultGetterToMethod(name: Name): TermName = {
- val p = name.pos(DEFAULT_GETTER_STRING)
- if (p < name.length) {
- val q = name.toTermName.subName(0, p)
- if (q.decoded == INIT_DEFAULT_PREFIX) CONSTRUCTOR else q
- } else name.toTermName
- }
-
- // This isn't needed at the moment since I fixed $class$1 but
- // I expect it will be at some point.
- //
- // def anonNumberSuffix(name: Name): Name = {
- // ("" + name) lastIndexOf '$' match {
- // case -1 => nme.EMPTY
- // case idx =>
- // val s = name drop idx
- // if (s.toString forall (_.isDigit)) s
- // else nme.EMPTY
- // }
- // }
-
- def stripModuleSuffix(name: Name): Name = (
- if (isModuleName(name)) name dropRight MODULE_SUFFIX_STRING.length else name
- )
-
- def dropSingletonName(name: Name): TypeName = name dropRight SINGLETON_SUFFIX.length toTypeName
- def singletonName(name: Name): TypeName = name append SINGLETON_SUFFIX toTypeName
- def implClassName(name: Name): TypeName = name append IMPL_CLASS_SUFFIX toTypeName
- def interfaceName(implname: Name): TypeName = implname dropRight IMPL_CLASS_SUFFIX.length toTypeName
- def localDummyName(clazz: Symbol): TermName = newTermName(LOCALDUMMY_PREFIX + clazz.name + ">")
- def superName(name: Name): TermName = newTermName(SUPER_PREFIX_STRING + name)
-
- /** The name of an accessor for protected symbols. */
- def protName(name: Name): TermName = newTermName(PROTECTED_PREFIX + name)
-
- /** The name of a setter for protected symbols. Used for inherited Java fields. */
- def protSetterName(name: Name): TermName = newTermName(PROTECTED_SET_PREFIX + name)
- }
-}
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index 5f38374f20..23eaa1088c 100644
--- a/src/compiler/scala/reflect/internal/Names.scala
+++ b/src/compiler/scala/reflect/internal/Names.scala
@@ -8,6 +8,7 @@ package internal
import scala.io.Codec
import java.security.MessageDigest
+import language.implicitConversions
/** The class Names ...
*
@@ -355,8 +356,10 @@ trait Names extends api.Names {
final def endsWith(char: Char): Boolean = len > 0 && endChar == char
final def endsWith(name: String): Boolean = endsWith(newTermName(name))
- def dropRight(n: Int) = subName(0, len - n)
- def drop(n: Int) = subName(n, len)
+ def dropRight(n: Int): ThisNameType = subName(0, len - n)
+ def drop(n: Int): ThisNameType = subName(n, len)
+ def stripSuffix(suffix: Name): ThisNameType =
+ if (this endsWith suffix) dropRight(suffix.length) else thisName
def indexOf(ch: Char) = {
val idx = pos(ch)
@@ -394,14 +397,14 @@ trait Names extends api.Names {
// def decodedName: ThisNameType = newName(decoded)
def encodedName: ThisNameType = encode
- /** Replace operator symbols by corresponding $op_name. */
+ /** Replace operator symbols by corresponding \$op_name. */
def encode: ThisNameType = {
val str = toString
val res = NameTransformer.encode(str)
if (res == str) thisName else newName(res)
}
- /** Replace $op_name by corresponding operator symbol. */
+ /** Replace \$op_name by corresponding operator symbol. */
def decode: String = {
if (this containsChar '$') {
val str = toString
diff --git a/src/compiler/scala/reflect/internal/Positions.scala b/src/compiler/scala/reflect/internal/Positions.scala
index 78de8d0ff2..5ec2659098 100644
--- a/src/compiler/scala/reflect/internal/Positions.scala
+++ b/src/compiler/scala/reflect/internal/Positions.scala
@@ -3,9 +3,8 @@ package internal
trait Positions extends api.Positions { self: SymbolTable =>
- def focusPos(pos: Position): Position
- def isRangePos(pos: Position): Boolean
- def showPos(pos: Position): String
+ type Position = scala.tools.nsc.util.Position
+ val NoPosition = scala.tools.nsc.util.NoPosition
/** A position that wraps a set of trees.
* The point of the wrapping position is the point of the default position.
@@ -27,4 +26,37 @@ trait Positions extends api.Positions { self: SymbolTable =>
* to some of the nodes in `tree`.
*/
def ensureNonOverlapping(tree: Tree, others: List[Tree]) {}
+
+ trait PosAssigner extends Traverser {
+ var pos: Position
+ }
+ protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner
+
+ protected class DefaultPosAssigner extends PosAssigner {
+ var pos: Position = _
+ override def traverse(t: Tree) {
+ if (t eq EmptyTree) ()
+ else if (t.pos == NoPosition) {
+ t.setPos(pos)
+ super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
+ // @PP: it's pruning whenever it encounters a node with a
+ // position, which I interpret to mean that (in the author's
+ // mind at least) either the children of a positioned node will
+ // already be positioned, or the children of a positioned node
+ // do not merit positioning.
+ //
+ // Whatever the author's rationale, it does seem like a bad idea
+ // to press on through a positioned node to find unpositioned
+ // children beneath it and then to assign whatever happens to
+ // be in `pos` to such nodes. There are supposed to be some
+ // position invariants which I can't imagine surviving that.
+ }
+ }
+ }
+
+ def atPos[T <: Tree](pos: Position)(tree: T): T = {
+ posAssigner.pos = pos
+ posAssigner.traverse(tree)
+ tree
+ }
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/Required.scala b/src/compiler/scala/reflect/internal/Required.scala
index 1bf1a2e97e..ba6d65a306 100644
--- a/src/compiler/scala/reflect/internal/Required.scala
+++ b/src/compiler/scala/reflect/internal/Required.scala
@@ -12,8 +12,6 @@ trait Required { self: SymbolTable =>
def picklerPhase: Phase
- val gen: TreeGen { val global: Required.this.type }
-
def settings: MutableSettings
def forInteractive: Boolean
diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala
index ef48d6102f..36e8ebb212 100644
--- a/src/compiler/scala/reflect/internal/Scopes.scala
+++ b/src/compiler/scala/reflect/internal/Scopes.scala
@@ -113,7 +113,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
*
* @param sym ...
*/
- def enter(sym: Symbol): Symbol = { enter(newScopeEntry(sym, this)); sym }
+ def enter[T <: Symbol](sym: T): T = { enter(newScopeEntry(sym, this)); sym }
/** enter a symbol, asserting that no symbol with same name exists in scope
*
diff --git a/src/compiler/scala/reflect/internal/StdAttachments.scala b/src/compiler/scala/reflect/internal/StdAttachments.scala
new file mode 100644
index 0000000000..ae2ad87deb
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/StdAttachments.scala
@@ -0,0 +1,10 @@
+package scala.reflect
+package internal
+
+import scala.reflect.makro.runtime.{Context => MacroContext}
+
+trait StdAttachments {
+ self: SymbolTable =>
+
+ case class ReifyAttachment(original: Symbol)
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index 84007425ed..a55efea2e6 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -6,26 +6,141 @@
package scala.reflect
package internal
-import scala.collection.immutable
-import NameTransformer.MODULE_SUFFIX_STRING
+import java.security.MessageDigest
+import Chars.isOperatorPart
import annotation.switch
+import language.implicitConversions
+import scala.collection.immutable
+import scala.io.Codec
-trait StdNames extends NameManglers { self: SymbolTable =>
+trait StdNames {
+ self: SymbolTable =>
def encode(str: String): TermName = newTermNameCached(NameTransformer.encode(str))
- implicit def lowerTermNames(n: TermName): String = "" + n
-
- // implicit def stringToTermName(s: String): TermName = newTermName(s)
-
- /** This should be the first trait in the linearization. */
- trait Keywords {
+ implicit def lowerTermNames(n: TermName): String = n.toString
+
+ /** Tensions: would like the keywords to be the very first names entered into the names
+ * storage so their ids count from 0, which simplifies the parser. Switched to abstract
+ * classes to avoid all the indirection which is generated with implementation-containing
+ * traits. Since all these classes use eager vals, that means the constructor with the
+ * keywords must run first. If it's the top in the superclass chain, then CommonNames
+ * must inherit from it, which means TypeNames would inherit keywords as well.
+ *
+ * Solution: Keywords extends CommonNames and uses early defs to beat the
+ * CommonNames constructor out of the starting gate. This is its builder.
+ */
+ private class KeywordSetBuilder {
private var kws: Set[TermName] = Set()
- private def kw(s: String): TermName = {
+ def apply(s: String): TermName = {
val result = newTermNameCached(s)
kws = kws + result
result
}
+ def result: Set[TermName] = {
+ val result = kws
+ kws = null
+ result
+ }
+ }
+
+ private final object compactify extends (String => String) {
+ val md5 = MessageDigest.getInstance("MD5")
+
+ /**
+ * COMPACTIFY
+ *
+ * The hashed name has the form (prefix + marker + md5 + marker + suffix), where
+ * - prefix/suffix.length = MaxNameLength / 4
+ * - md5.length = 32
+ *
+ * We obtain the formula:
+ *
+ * FileNameLength = 2*(MaxNameLength / 4) + 2.marker.length + 32 + 6
+ *
+ * (+6 for ".class"). MaxNameLength can therefore be computed as follows:
+ */
+ val marker = "$$$$"
+ val MaxNameLength = math.min(
+ settings.maxClassfileName.value - 6,
+ 2 * (settings.maxClassfileName.value - 6 - 2*marker.length - 32)
+ )
+ def toMD5(s: String, edge: Int): String = {
+ val prefix = s take edge
+ val suffix = s takeRight edge
+
+ val cs = s.toArray
+ val bytes = Codec toUTF8 cs
+ md5 update bytes
+ val md5chars = md5.digest() map (b => (b & 0xFF).toHexString) mkString
+
+ prefix + marker + md5chars + marker + suffix
+ }
+ def apply(s: String): String = (
+ if (s.length <= MaxNameLength) s
+ else toMD5(s, MaxNameLength / 4)
+ )
+ }
+
+ abstract class CommonNames {
+ type NameType <: Name
+ protected implicit def createNameType(name: String): NameType
+
+ def flattenedName(segments: Name*): NameType =
+ compactify(segments mkString NAME_JOIN_STRING)
+
+ val MODULE_SUFFIX_STRING: String = NameTransformer.MODULE_SUFFIX_STRING
+ val NAME_JOIN_STRING: String = NameTransformer.NAME_JOIN_STRING
+ val SINGLETON_SUFFIX: String = ".type"
+
+ val ANON_CLASS_NAME: NameType = "$anon"
+ val ANON_FUN_NAME: NameType = "$anonfun"
+ val EMPTY: NameType = ""
+ val EMPTY_PACKAGE_NAME: NameType = "<empty>"
+ val IMPL_CLASS_SUFFIX = "$class"
+ val IMPORT: NameType = "<import>"
+ val MODULE_SUFFIX_NAME: NameType = MODULE_SUFFIX_STRING
+ val MODULE_VAR_SUFFIX: NameType = "$module"
+ val NAME_JOIN_NAME: NameType = NAME_JOIN_STRING
+ val PACKAGE: NameType = "package"
+ val ROOT: NameType = "<root>"
+ val SPECIALIZED_SUFFIX: NameType = "$sp"
+
+ // value types (and AnyRef) are all used as terms as well
+ // as (at least) arguments to the @specialize annotation.
+ final val Boolean: NameType = "Boolean"
+ final val Byte: NameType = "Byte"
+ final val Char: NameType = "Char"
+ final val Double: NameType = "Double"
+ final val Float: NameType = "Float"
+ final val Int: NameType = "Int"
+ final val Long: NameType = "Long"
+ final val Short: NameType = "Short"
+ final val Unit: NameType = "Unit"
+
+ final val ScalaValueNames: scala.List[NameType] =
+ scala.List(Byte, Char, Short, Int, Long, Float, Double, Boolean, Unit)
+
+ // some types whose companions we utilize
+ final val AnyRef: NameType = "AnyRef"
+ final val Array: NameType = "Array"
+ final val List: NameType = "List"
+ final val Seq: NameType = "Seq"
+ final val Symbol: NameType = "Symbol"
+ final val ClassTag: NameType = "ClassTag"
+ final val TypeTag : NameType = "TypeTag"
+ final val ConcreteTypeTag: NameType = "ConcreteTypeTag"
+
+ // fictions we use as both types and terms
+ final val ERROR: NameType = "<error>"
+ final val NO_NAME: NameType = "<none>" // formerly NOSYMBOL
+ final val WILDCARD: NameType = "_"
+ }
+
+ /** This should be the first trait in the linearization. */
+ // abstract class Keywords extends CommonNames {
+ abstract class Keywords extends {
+ private val kw = new KeywordSetBuilder
final val ABSTRACTkw: TermName = kw("abstract")
final val CASEkw: TermName = kw("case")
@@ -44,6 +159,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val IMPLICITkw: TermName = kw("implicit")
final val IMPORTkw: TermName = kw("import")
final val LAZYkw: TermName = kw("lazy")
+ final val MACROkw: TermName = kw("macro")
final val MATCHkw: TermName = kw("match")
final val NEWkw: TermName = kw("new")
final val NULLkw: TermName = kw("null")
@@ -55,6 +171,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val RETURNkw: TermName = kw("return")
final val SEALEDkw: TermName = kw("sealed")
final val SUPERkw: TermName = kw("super")
+ final val THENkw: TermName = kw("then")
final val THISkw: TermName = kw("this")
final val THROWkw: TermName = kw("throw")
final val TRAITkw: TermName = kw("trait")
@@ -78,72 +195,31 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val HASHkw: TermName = kw("#")
final val ATkw: TermName = kw("@")
- final val keywords = {
- val result = kws.toSet
- kws = null
- result
- }
-
+ final val keywords = kw.result
+ } with CommonNames {
final val javaKeywords = new JavaKeywords()
}
- trait CommonNames /*extends LibraryCommonNames*/ {
-
- type NameType <: Name
- protected implicit def createNameType(name: String): NameType
-
- val EMPTY: NameType = ""
- val ANON_FUN_NAME: NameType = "$anonfun"
- val ANON_CLASS_NAME: NameType = "$anon"
- val EMPTY_PACKAGE_NAME: NameType = "<empty>"
- val IMPORT: NameType = "<import>"
- val MODULE_VAR_SUFFIX: NameType = "$module"
- val ROOT: NameType = "<root>"
- val PACKAGE: NameType = "package"
- val SPECIALIZED_SUFFIX: NameType = "$sp"
-
- // value types (and AnyRef) are all used as terms as well
- // as (at least) arguments to the @specialize annotation.
- final val Boolean: NameType = "Boolean"
- final val Byte: NameType = "Byte"
- final val Char: NameType = "Char"
- final val Double: NameType = "Double"
- final val Float: NameType = "Float"
- final val Int: NameType = "Int"
- final val Long: NameType = "Long"
- final val Short: NameType = "Short"
- final val Unit: NameType = "Unit"
-
- final val ScalaValueNames: scala.List[NameType] =
- scala.List(Byte, Char, Short, Int, Long, Float, Double, Boolean, Unit)
-
- // some types whose companions we utilize
- final val AnyRef: NameType = "AnyRef"
- final val Array: NameType = "Array"
- final val List: NameType = "List"
- final val Seq: NameType = "Seq"
- final val Symbol: NameType = "Symbol"
-
- // fictions we use as both types and terms
- final val ERROR: NameType = "<error>"
- final val NO_NAME: NameType = "<none>" // formerly NOSYMBOL
- final val WILDCARD: NameType = "_"
- }
+ abstract class TypeNames extends Keywords {
+ type NameType = TypeName
+ protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
- trait TypeNames extends CommonNames {
final val BYNAME_PARAM_CLASS_NAME: NameType = "<byname>"
final val EQUALS_PATTERN_NAME: NameType = "<equals>"
final val JAVA_REPEATED_PARAM_CLASS_NAME: NameType = "<repeated...>"
final val LOCAL_CHILD: NameType = "<local child>"
+ final val REFINE_CLASS_NAME: NameType = "<refinement>"
final val REPEATED_PARAM_CLASS_NAME: NameType = "<repeated>"
final val WILDCARD_STAR: NameType = "_*"
final val Any: NameType = "Any"
final val AnyVal: NameType = "AnyVal"
+ final val Expr: NameType = "Expr"
final val Nothing: NameType = "Nothing"
final val Null: NameType = "Null"
final val Object: NameType = "Object"
final val PartialFunction: NameType = "PartialFunction"
+ final val PrefixType: NameType = "PrefixType"
final val Product: NameType = "Product"
final val Serializable: NameType = "Serializable"
final val Singleton: NameType = "Singleton"
@@ -153,7 +229,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val Annotation: NameType = "Annotation"
final val ClassfileAnnotation: NameType = "ClassfileAnnotation"
final val Enum: NameType = "Enum"
-
+ final val Group: NameType = "Group"
final val Tree: NameType = "Tree"
final val TypeTree: NameType = "TypeTree"
@@ -181,36 +257,200 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val SignatureATTR: NameType = "Signature"
final val SourceFileATTR: NameType = "SourceFile"
final val SyntheticATTR: NameType = "Synthetic"
+
+ def dropSingletonName(name: Name): TypeName = name dropRight SINGLETON_SUFFIX.length toTypeName
+ def singletonName(name: Name): TypeName = name append SINGLETON_SUFFIX toTypeName
+ def implClassName(name: Name): TypeName = name append IMPL_CLASS_SUFFIX toTypeName
+ def interfaceName(implname: Name): TypeName = implname dropRight IMPL_CLASS_SUFFIX.length toTypeName
}
- trait TermNames extends Keywords with CommonNames {
+ abstract class TermNames extends Keywords {
+ type NameType = TermName
+ protected implicit def createNameType(name: String): TermName = newTermNameCached(name)
+
+ /** Base strings from which synthetic names are derived. */
+ val BITMAP_PREFIX = "bitmap$"
+ val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$"
+ val DEFAULT_GETTER_STRING = "$default$"
+ val DO_WHILE_PREFIX = "doWhile$"
+ val EVIDENCE_PARAM_PREFIX = "evidence$"
+ val EXCEPTION_RESULT_PREFIX = "exceptionResult"
+ val EXPAND_SEPARATOR_STRING = "$$"
+ val INTERPRETER_IMPORT_WRAPPER = "$iw"
+ val INTERPRETER_LINE_PREFIX = "line"
+ val INTERPRETER_VAR_PREFIX = "res"
+ val INTERPRETER_WRAPPER_SUFFIX = "$object"
+ val LOCALDUMMY_PREFIX = "<local " // owner of local blocks
+ val PROTECTED_PREFIX = "protected$"
+ val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set"
+ val SUPER_PREFIX_STRING = "super$"
+ val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
+ val WHILE_PREFIX = "while$"
+
// Compiler internal names
- val EXPAND_SEPARATOR_STRING = "$$"
-
- val ANYNAME: NameType = "<anyname>"
- val CONSTRUCTOR: NameType = "<init>"
- val FAKE_LOCAL_THIS: NameType = "this$"
- val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something?
- val LAZY_LOCAL: NameType = "$lzy"
- val LOCAL_SUFFIX_STRING = " "
- val MACRO: NameType = "macro$"
- val MIRROR_PREFIX: NameType = "$mr."
- val MIRROR_SHORT: NameType = "$mr"
- val MIXIN_CONSTRUCTOR: NameType = "$init$"
- val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
- val OUTER: NameType = "$outer"
- val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space
- val OUTER_SYNTH: NameType = "<outer>" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter
- val SELECTOR_DUMMY: NameType = "<unapply-selector>"
- val SELF: NameType = "$this"
- val SPECIALIZED_INSTANCE: NameType = "specInstance$"
- val STAR: NameType = "*"
- val THIS: NameType = "_$this"
-
- final val Nil: NameType = "Nil"
- final val Predef: NameType = "Predef"
- final val ScalaRunTime: NameType = "ScalaRunTime"
- final val Some: NameType = "Some"
+ val ANYNAME: NameType = "<anyname>"
+ val CONSTRUCTOR: NameType = "<init>"
+ val FAKE_LOCAL_THIS: NameType = "this$"
+ val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something?
+ val LAZY_LOCAL: NameType = "$lzy"
+ val LOCAL_SUFFIX_STRING = " "
+ val MIRROR_FREE_PREFIX: NameType = "free$"
+ val MIRROR_FREE_THIS_SUFFIX: NameType = "$this"
+ val MIRROR_FREE_VALUE_SUFFIX: NameType = "$value"
+ val MIRROR_PREFIX: NameType = "$mr."
+ val MIRROR_SHORT: NameType = "$mr"
+ val MIRROR_SYMDEF_PREFIX: NameType = "symdef$"
+ val MIXIN_CONSTRUCTOR: NameType = "$init$"
+ val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
+ val OUTER: NameType = "$outer"
+ val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space
+ val OUTER_SYNTH: NameType = "<outer>" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter
+ val SELECTOR_DUMMY: NameType = "<unapply-selector>"
+ val SELF: NameType = "$this"
+ val SETTER_SUFFIX: NameType = encode("_=")
+ val SPECIALIZED_INSTANCE: NameType = "specInstance$"
+ val STAR: NameType = "*"
+ val THIS: NameType = "_$this"
+
+ @deprecated("Use SPECIALIZED_SUFFIX", "2.10.0")
+ def SPECIALIZED_SUFFIX_STRING = SPECIALIZED_SUFFIX.toString
+ @deprecated("Use SPECIALIZED_SUFFIX", "2.10.0")
+ def SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX.toTermName
+
+ def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR
+ def isExceptionResultName(name: Name) = name startsWith EXCEPTION_RESULT_PREFIX
+ def isImplClassName(name: Name) = name endsWith IMPL_CLASS_SUFFIX
+ def isLocalDummyName(name: Name) = name startsWith LOCALDUMMY_PREFIX
+ def isLocalName(name: Name) = name endsWith LOCAL_SUFFIX_STRING
+ def isLoopHeaderLabel(name: Name) = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
+ def isProtectedAccessorName(name: Name) = name startsWith PROTECTED_PREFIX
+ def isSuperAccessorName(name: Name) = name startsWith SUPER_PREFIX_STRING
+ def isReplWrapperName(name: Name) = name containsName INTERPRETER_IMPORT_WRAPPER
+ def isSetterName(name: Name) = name endsWith SETTER_SUFFIX
+ def isTraitSetterName(name: Name) = isSetterName(name) && (name containsName TRAIT_SETTER_SEPARATOR_STRING)
+ def isSingletonName(name: Name) = name endsWith SINGLETON_SUFFIX
+ def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_NAME
+
+ def isOpAssignmentName(name: Name) = name match {
+ case raw.NE | raw.LE | raw.GE | EMPTY => false
+ case _ =>
+ name.endChar == '=' && name.startChar != '=' && isOperatorPart(name.startChar)
+ }
+
+ /** The expanded name of `name` relative to this class `base` with given `separator`
+ */
+ def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName =
+ newTermNameCached(base.fullName('$') + separator + name)
+
+ /** The expanded setter name of `name` relative to this class `base`
+ */
+ def expandedSetterName(name: TermName, base: Symbol): TermName =
+ expandedName(name, base, separator = TRAIT_SETTER_SEPARATOR_STRING)
+
+ /** If `name` is an expandedName name, the original name.
+ * Otherwise `name` itself.
+ */
+ def originalName(name: Name): Name = {
+ var i = name.length
+ while (i >= 2 && !(name(i - 1) == '$' && name(i - 2) == '$')) i -= 1
+ if (i >= 2) {
+ while (i >= 3 && name(i - 3) == '$') i -= 1
+ name.subName(i, name.length)
+ } else name
+ }
+
+ def unspecializedName(name: Name): Name = (
+ if (name endsWith SPECIALIZED_SUFFIX)
+ name.subName(0, name.lastIndexOf('m') - 1)
+ else name
+ )
+
+ /*
+ def anonNumberSuffix(name: Name): Name = {
+ ("" + name) lastIndexOf '$' match {
+ case -1 => nme.EMPTY
+ case idx =>
+ val s = name drop idx
+ if (s.toString forall (_.isDigit)) s
+ else nme.EMPTY
+ }
+ }
+ */
+
+ /** Return the original name and the types on which this name
+ * is specialized. For example,
+ * {{{
+ * splitSpecializedName("foo$mIcD$sp") == ('foo', "I", "D")
+ * }}}
+ * `foo$mIcD$sp` is the name of a method specialized on two type
+ * parameters, the first one belonging to the method itself, on Int,
+ * and another one belonging to the enclosing class, on Double.
+ */
+ def splitSpecializedName(name: Name): (Name, String, String) =
+ if (name endsWith SPECIALIZED_SUFFIX) {
+ val name1 = name dropRight SPECIALIZED_SUFFIX.length
+ val idxC = name1 lastIndexOf 'c'
+ val idxM = name1 lastIndexOf 'm'
+
+ (name1.subName(0, idxM - 1),
+ name1.subName(idxC + 1, name1.length).toString,
+ name1.subName(idxM + 1, idxC).toString)
+ } else
+ (name, "", "")
+
+ def getterName(name: TermName): TermName = if (isLocalName(name)) localToGetter(name) else name
+ def getterToLocal(name: TermName): TermName = name append LOCAL_SUFFIX_STRING
+ def getterToSetter(name: TermName): TermName = name append SETTER_SUFFIX
+ def localToGetter(name: TermName): TermName = name dropRight LOCAL_SUFFIX_STRING.length
+
+ def dropLocalSuffix(name: Name): Name = if (name endsWith ' ') name dropRight 1 else name
+
+ def setterToGetter(name: TermName): TermName = {
+ val p = name.pos(TRAIT_SETTER_SEPARATOR_STRING)
+ if (p < name.length)
+ setterToGetter(name drop (p + TRAIT_SETTER_SEPARATOR_STRING.length))
+ else
+ name.subName(0, name.length - SETTER_SUFFIX.length)
+ }
+
+ def defaultGetterName(name: Name, pos: Int): TermName = {
+ val prefix = if (isConstructorName(name)) "init" else name
+ newTermName(prefix + DEFAULT_GETTER_STRING + pos)
+ }
+ def defaultGetterToMethod(name: Name): TermName = {
+ val p = name.pos(DEFAULT_GETTER_STRING)
+ if (p < name.length) name.toTermName.subName(0, p)
+ else name.toTermName
+ }
+
+ // If the name ends with $nn where nn are
+ // all digits, strip the $ and the digits.
+ // Otherwise return the argument.
+ def stripAnonNumberSuffix(name: Name): Name = {
+ var pos = name.length
+ while (pos > 0 && name(pos - 1).isDigit)
+ pos -= 1
+
+ if (pos <= 0 || pos == name.length || name(pos - 1) != '$') name
+ else name.subName(0, pos - 1)
+ }
+
+ def stripModuleSuffix(name: Name): Name = (
+ if (isModuleName(name)) name dropRight MODULE_SUFFIX_STRING.length else name
+ )
+ def localDummyName(clazz: Symbol): TermName = newTermName(LOCALDUMMY_PREFIX + clazz.name + ">")
+ def superName(name: Name): TermName = newTermName(SUPER_PREFIX_STRING + name)
+
+ /** The name of an accessor for protected symbols. */
+ def protName(name: Name): TermName = newTermName(PROTECTED_PREFIX + name)
+
+ /** The name of a setter for protected symbols. Used for inherited Java fields. */
+ def protSetterName(name: Name): TermName = newTermName(PROTECTED_SET_PREFIX + name)
+
+ final val Nil: NameType = "Nil"
+ final val Predef: NameType = "Predef"
+ final val ScalaRunTime: NameType = "ScalaRunTime"
+ final val Some: NameType = "Some"
val _1 : NameType = "_1"
val _2 : NameType = "_2"
@@ -275,23 +515,56 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val genericWrapArray: NameType = "genericWrapArray"
// Compiler utilized names
- // val productElementName: NameType = "productElementName"
+
+ val AnnotatedType: NameType = "AnnotatedType"
+ val AnnotationInfo: NameType = "AnnotationInfo"
+ val Any: NameType = "Any"
+ val AnyVal: NameType = "AnyVal"
+ val AppliedTypeTree: NameType = "AppliedTypeTree"
+ val Apply: NameType = "Apply"
+ val ArrayAnnotArg: NameType = "ArrayAnnotArg"
+ val Constant: NameType = "Constant"
+ val ConstantType: NameType = "ConstantType"
+ val EmptyPackage: NameType = "EmptyPackage"
+ val EmptyPackageClass: NameType = "EmptyPackageClass"
+ val ExistentialTypeTree: NameType = "ExistentialTypeTree"
+ val Expr: NameType = "Expr"
val Ident: NameType = "Ident"
+ val Import: NameType = "Import"
+ val Literal: NameType = "Literal"
+ val LiteralAnnotArg: NameType = "LiteralAnnotArg"
+ val NestedAnnotArg: NameType = "NestedAnnotArg"
+ val NoPrefix: NameType = "NoPrefix"
+ val NoSymbol: NameType = "NoSymbol"
+ val Nothing: NameType = "Nothing"
+ val NoType: NameType = "NoType"
+ val Null: NameType = "Null"
+ val Object: NameType = "Object"
+ val RootPackage: NameType = "RootPackage"
+ val RootClass: NameType = "RootClass"
+ val Select: NameType = "Select"
val StringContext: NameType = "StringContext"
val This: NameType = "This"
val Tree : NameType = "Tree"
+ val Tuple2: NameType = "Tuple2"
val TYPE_ : NameType = "TYPE"
+ val TypeApply: NameType = "TypeApply"
+ val TypeRef: NameType = "TypeRef"
val TypeTree: NameType = "TypeTree"
val UNIT : NameType = "UNIT"
- val _isDefinedAt: NameType = "_isDefinedAt"
val add_ : NameType = "add"
val annotation: NameType = "annotation"
val anyValClass: NameType = "anyValClass"
val append: NameType = "append"
val apply: NameType = "apply"
val applyDynamic: NameType = "applyDynamic"
+ val applyDynamicNamed: NameType = "applyDynamicNamed"
+ val applyOrElse: NameType = "applyOrElse"
val args : NameType = "args"
val argv : NameType = "argv"
+ val arrayClass: NameType = "arrayClass"
+ val arrayElementClass: NameType = "arrayElementClass"
+ val arrayTagToClassManifest: NameType = "arrayTagToClassManifest"
val arrayValue: NameType = "arrayValue"
val array_apply : NameType = "array_apply"
val array_clone : NameType = "array_clone"
@@ -309,8 +582,10 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val checkInitialized: NameType = "checkInitialized"
val classOf: NameType = "classOf"
val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure
+ val concreteTypeTagToManifest: NameType = "concreteTypeTagToManifest"
val conforms: NameType = "conforms"
val copy: NameType = "copy"
+ val definitions: NameType = "definitions"
val delayedInit: NameType = "delayedInit"
val delayedInitArg: NameType = "delayedInit$body"
val drop: NameType = "drop"
@@ -322,7 +597,9 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val equalsNumNum : NameType = "equalsNumNum"
val equalsNumObject : NameType = "equalsNumObject"
val equals_ : NameType = if (forMSIL) "Equals" else "equals"
+ val erasure: NameType = "erasure"
val error: NameType = "error"
+ val eval: NameType = "eval"
val ex: NameType = "ex"
val false_ : NameType = "false"
val filter: NameType = "filter"
@@ -330,7 +607,6 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val find_ : NameType = "find"
val flatMap: NameType = "flatMap"
val foreach: NameType = "foreach"
- val freeValue : NameType = "freeValue"
val genericArrayOps: NameType = "genericArrayOps"
val get: NameType = "get"
val getOrElse: NameType = "getOrElse"
@@ -339,6 +615,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val hash_ : NameType = "hash"
val head: NameType = "head"
val identity: NameType = "identity"
+ val info: NameType = "info"
val inlinedEquals: NameType = "inlinedEquals"
val isArray: NameType = "isArray"
val isDefinedAt: NameType = "isDefinedAt"
@@ -350,37 +627,60 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val lang: NameType = "lang"
val length: NameType = "length"
val lengthCompare: NameType = "lengthCompare"
- val lift_ : NameType = "lift"
- val macro_ : NameType = "macro"
val macroThis : NameType = "_this"
- val macroContext : NameType = "_context"
+ val macroContext : NameType = "c"
val main: NameType = "main"
+ val manifest: NameType = "manifest"
+ val manifestToConcreteTypeTag: NameType = "manifestToConcreteTypeTag"
val map: NameType = "map"
+ val materializeArrayTag: NameType = "materializeArrayTag"
+ val materializeClassTag: NameType = "materializeClassTag"
+ val materializeConcreteTypeTag: NameType = "materializeConcreteTypeTag"
+ val materializeErasureTag: NameType= "materializeErasureTag"
+ val materializeTypeTag: NameType = "materializeTypeTag"
val mirror : NameType = "mirror"
- val missingCase: NameType = "missingCase"
+ val moduleClass : NameType = "moduleClass"
+ val name: NameType = "name"
val ne: NameType = "ne"
val newArray: NameType = "newArray"
+ val newFreeExistential: NameType = "newFreeExistential"
+ val newFreeTerm: NameType = "newFreeTerm"
+ val newFreeType: NameType = "newFreeType"
+ val newNestedSymbol: NameType = "newNestedSymbol"
val newScopeWith: NameType = "newScopeWith"
val next: NameType = "next"
+ val nmeNewTermName: NameType = "newTermName"
+ val nmeNewTypeName: NameType = "newTypeName"
+ val normalize: NameType = "normalize"
val notifyAll_ : NameType = "notifyAll"
val notify_ : NameType = "notify"
val null_ : NameType = "null"
val ofDim: NameType = "ofDim"
+ val origin: NameType = "origin"
+ val prefix : NameType = "prefix"
val productArity: NameType = "productArity"
val productElement: NameType = "productElement"
val productIterator: NameType = "productIterator"
val productPrefix: NameType = "productPrefix"
val readResolve: NameType = "readResolve"
+ val reflect : NameType = "reflect"
+ val reify : NameType = "reify"
val runOrElse: NameType = "runOrElse"
val runtime: NameType = "runtime"
val sameElements: NameType = "sameElements"
val scala_ : NameType = "scala"
+ val selectDynamic: NameType = "selectDynamic"
+ val selectOverloadedMethod: NameType = "selectOverloadedMethod"
+ val selectTerm: NameType = "selectTerm"
+ val selectType: NameType = "selectType"
val self: NameType = "self"
val setAccessible: NameType = "setAccessible"
val setAnnotations: NameType = "setAnnotations"
val setSymbol: NameType = "setSymbol"
val setType: NameType = "setType"
val setTypeSignature: NameType = "setTypeSignature"
+ val staticClass : NameType = "staticClass"
+ val staticModule : NameType = "staticModule"
val synchronized_ : NameType = "synchronized"
val tail: NameType = "tail"
val thisModuleType: NameType = "thisModuleType"
@@ -391,20 +691,26 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val toObjectArray : NameType = "toObjectArray"
val toSeq: NameType = "toSeq"
val toString_ : NameType = if (forMSIL) "ToString" else "toString"
+ val tpe : NameType = "tpe"
+ val tree : NameType = "tree"
val true_ : NameType = "true"
val typedProductIterator: NameType = "typedProductIterator"
val unapply: NameType = "unapply"
val unapplySeq: NameType = "unapplySeq"
val unbox: NameType = "unbox"
val update: NameType = "update"
+ val updateDynamic: NameType = "updateDynamic"
val value: NameType = "value"
val valueOf : NameType = "valueOf"
val values : NameType = "values"
val view_ : NameType = "view"
val wait_ : NameType = "wait"
val withFilter: NameType = "withFilter"
+ val wrap: NameType = "wrap"
val zip: NameType = "zip"
+ val synthSwitch: NameType = "$synthSwitch"
+
// unencoded operators
object raw {
final val AMP : NameType = "&"
@@ -438,19 +744,11 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val toInteger: NameType = "toInteger"
}
- object tpnme extends AbsTypeNames with TypeNames /*with LibraryTypeNames*/ with TypeNameMangling {
- type NameType = TypeName
- protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
-
- val REFINE_CLASS_NAME: NameType = "<refinement>"
- }
+ object tpnme extends TypeNames with AbsTypeNames { }
/** For fully qualified type names.
*/
object fulltpnme extends TypeNames {
- type NameType = TypeName
- protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
-
val RuntimeNothing: NameType = "scala.runtime.Nothing$"
val RuntimeNull: NameType = "scala.runtime.Null$"
val JavaLangEnum: NameType = "java.lang.Enum"
@@ -465,18 +763,9 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val RuntimeNull = toBinary(fulltpnme.RuntimeNull).toTypeName
}
- object fullnme extends TermNames {
- type NameType = TermName
- protected implicit def createNameType(name: String): TermName = newTermNameCached(name)
-
- val MirrorPackage: NameType = "scala.reflect.mirror"
- }
-
val javanme = nme.javaKeywords
- object nme extends AbsTermNames with TermNames /*with LibraryTermNames*/ with TermNameMangling {
- type NameType = TermName
- protected implicit def createNameType(name: String): TermName = newTermNameCached(name)
+ object nme extends TermNames with AbsTermNames {
/** Translate a String into a list of simple TypeNames and TermNames.
* In all segments before the last, type/term is determined by whether
@@ -516,42 +805,26 @@ trait StdNames extends NameManglers { self: SymbolTable =>
def newBitmapName(bitmapPrefix: Name, n: Int) = bitmapPrefix append ("" + n)
- val BITMAP_PREFIX: String = "bitmap$"
val BITMAP_NORMAL: NameType = BITMAP_PREFIX + "" // initialization bitmap for public/protected lazy vals
val BITMAP_TRANSIENT: NameType = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals
val BITMAP_PRIVATE: NameType = BITMAP_PREFIX + "priv$" // initialization bitmap for private lazy vals
val BITMAP_CHECKINIT: NameType = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values
val BITMAP_CHECKINIT_TRANSIENT: NameType = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values
- /** The expanded name of `name` relative to this class `base` with given `separator`
- */
- def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName =
- newTermNameCached(base.fullName('$') + separator + name)
+ def isModuleVarName(name: Name): Boolean =
+ stripAnonNumberSuffix(name) endsWith MODULE_VAR_SUFFIX
def moduleVarName(name: TermName): TermName =
newTermNameCached("" + name + MODULE_VAR_SUFFIX)
- val ROOTPKG: TermName = "_root_"
+ val ROOTPKG: TermName = "_root_"
+ val EQEQ_LOCAL_VAR: TermName = "eqEqTemp$"
- /** Base strings from which synthetic names are derived. */
- val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$"
- val DEFAULT_GETTER_STRING = "$default$"
- val DO_WHILE_PREFIX = "doWhile$"
- val EQEQ_LOCAL_VAR_STRING = "eqEqTemp$"
- val EVIDENCE_PARAM_PREFIX = "evidence$"
- val EXCEPTION_RESULT_PREFIX = "exceptionResult"
- val INTERPRETER_IMPORT_WRAPPER = "$iw"
- val INTERPRETER_LINE_PREFIX = "line"
- val INTERPRETER_VAR_PREFIX = "res"
- val INTERPRETER_WRAPPER_SUFFIX = "$object"
- val WHILE_PREFIX = "while$"
-
- val EQEQ_LOCAL_VAR: TermName = newTermName(EQEQ_LOCAL_VAR_STRING)
-
- def getCause = sn.GetCause
- def getClass_ = sn.GetClass
- def getMethod_ = sn.GetMethod
- def invoke_ = sn.Invoke
+ def getCause = sn.GetCause
+ def getClass_ = sn.GetClass
+ def getComponentType = sn.GetComponentType
+ def getMethod_ = sn.GetMethod
+ def invoke_ = sn.Invoke
val ADD = encode("+")
val AND = encode("&")
@@ -710,6 +983,11 @@ trait StdNames extends NameManglers { self: SymbolTable =>
case 22 => nme._22
case _ => newTermName("_" + j)
}
+
+ @deprecated("Use a method in tpnme", "2.10.0") def dropSingletonName(name: Name): TypeName = tpnme.dropSingletonName(name)
+ @deprecated("Use a method in tpnme", "2.10.0") def singletonName(name: Name): TypeName = tpnme.singletonName(name)
+ @deprecated("Use a method in tpnme", "2.10.0") def implClassName(name: Name): TypeName = tpnme.implClassName(name)
+ @deprecated("Use a method in tpnme", "2.10.0") def interfaceName(implname: Name): TypeName = tpnme.interfaceName(implname)
}
abstract class SymbolNames {
@@ -735,6 +1013,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val ForName : TermName
val GetCause : TermName
val GetClass : TermName
+ val GetComponentType : TermName
val GetMethod : TermName
val Invoke : TermName
val JavaLang : TermName
@@ -743,12 +1022,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
}
class JavaKeywords {
- private var kws: Set[TermName] = Set()
- private def kw(s: String): TermName = {
- val result = newTermNameCached(s)
- kws = kws + result
- result
- }
+ private val kw = new KeywordSetBuilder
final val ABSTRACTkw: TermName = kw("abstract")
final val ASSERTkw: TermName = kw("assert")
@@ -801,11 +1075,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val VOLATILEkw: TermName = kw("volatile")
final val WHILEkw: TermName = kw("while")
- final val keywords = {
- val result = kws.toSet
- kws = null
- result
- }
+ final val keywords = kw.result
}
private abstract class JavaNames extends SymbolNames {
@@ -829,12 +1099,13 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val Throwable: TypeName = "java.lang.Throwable"
final val ValueType: TypeName = tpnme.NO_NAME
- final val ForName: TermName = newTermName("forName")
- final val GetCause: TermName = newTermName("getCause")
- final val GetClass: TermName = newTermName("getClass")
- final val GetMethod: TermName = newTermName("getMethod")
- final val Invoke: TermName = newTermName("invoke")
- final val JavaLang: TermName = newTermName("java.lang")
+ final val ForName: TermName = newTermName("forName")
+ final val GetCause: TermName = newTermName("getCause")
+ final val GetClass: TermName = newTermName("getClass")
+ final val GetComponentType: TermName = newTermName("getComponentType")
+ final val GetMethod: TermName = newTermName("getMethod")
+ final val Invoke: TermName = newTermName("invoke")
+ final val JavaLang: TermName = newTermName("java.lang")
val Boxed = immutable.Map[TypeName, TypeName](
tpnme.Boolean -> BoxedBoolean,
@@ -866,12 +1137,13 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val Throwable: TypeName = "System.Exception"
final val ValueType: TypeName = "System.ValueType"
- final val ForName: TermName = newTermName("GetType")
- final val GetCause: TermName = newTermName("InnerException") /* System.Reflection.TargetInvocationException.InnerException */
- final val GetClass: TermName = newTermName("GetType")
- final val GetMethod: TermName = newTermName("GetMethod")
- final val Invoke: TermName = newTermName("Invoke")
- final val JavaLang: TermName = newTermName("System")
+ final val ForName: TermName = newTermName("GetType")
+ final val GetCause: TermName = newTermName("InnerException") /* System.Reflection.TargetInvocationException.InnerException */
+ final val GetClass: TermName = newTermName("GetType")
+ final val GetComponentType: TermName = newTermName("GetElementType")
+ final val GetMethod: TermName = newTermName("GetMethod")
+ final val Invoke: TermName = newTermName("Invoke")
+ final val JavaLang: TermName = newTermName("System")
val Boxed = immutable.Map[TypeName, TypeName](
tpnme.Boolean -> "System.Boolean",
diff --git a/src/compiler/scala/reflect/internal/SymbolCreations.scala b/src/compiler/scala/reflect/internal/SymbolCreations.scala
new file mode 100644
index 0000000000..ac82ffe62a
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/SymbolCreations.scala
@@ -0,0 +1,112 @@
+ /* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.reflect
+package internal
+
+import scala.collection.{ mutable, immutable }
+import scala.collection.mutable.ListBuffer
+import util.Statistics._
+import Flags._
+import api.Modifier
+
+trait SymbolCreations {
+ self: SymbolTable =>
+
+ import definitions._
+
+ /** Symbol creation interface, possibly better moved somewhere else.
+ * It'd be nice if we had virtual classes, but since we
+ * don't: these methods insulate the direct instantiation of the symbols
+ * (which may be overridden, e.g. in SynchronizedSymbols) from the
+ * enforcement of preconditions and choice of symbol constructor based
+ * on flags, which are (or should be) final so they can be reasoned about
+ * without lots of surprises.
+ */
+ trait SymbolCreatorInterface {
+ // Fallbacks; more precise creators should normally be called.
+ protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol
+ // This in fact does not exist anymore in the interests of better typed TypeSymbols.
+ // protected def createTypeSymbol(name: TypeName, pos: Position, newFlags: Long): TypeSymbol
+
+ // I believe all but rogue TypeSymbols are one of: ClassSymbol, AbstractTypeSymbol, AliasTypeSymbol, or TypeSkolem.
+ protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol
+ protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol
+ protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem
+ protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol
+
+ // More specific ClassSymbols.
+ // TODO - AnonymousClassSymbol.
+ // TODO maybe - PackageObjects, but that one cost me a lot of time when I tried it before
+ // because it broke reification some way I couldn't see.
+ protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol
+ protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol
+ protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol
+ protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol
+ protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol
+
+ // Distinguished term categories include methods, modules, packages, package objects,
+ // value parameters, and values (including vals, vars, and lazy vals.)
+ protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol
+ protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol
+ protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol
+
+ // TODO
+ // protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol
+ // protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol
+ }
+
+ trait SymbolCreator extends SymbolCreatorInterface {
+ self: Symbol =>
+
+ /*** Predictable symbol creation.
+ *
+ * newTermSymbol, newClassSymbol, and newNonClassSymbol all create symbols based
+ * only on the flags (for reconstruction after reification.) It would be nice to
+ * combine the last two into newTypeSymbol, but this requires some flag which allows us
+ * to distinguish classes and type aliases, which as yet does not exist.
+ *
+ * The fundamental flags used to determine which Symbol subclass to instantiate are:
+ * METHOD, PACKAGE, MODULE, PARAM, DEFERRED.
+ */
+ final def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = {
+ if ((newFlags & METHOD) != 0)
+ createMethodSymbol(name, pos, newFlags)
+ else if ((newFlags & PACKAGE) != 0)
+ createPackageSymbol(name, pos, newFlags | PackageFlags)
+ else if ((newFlags & MODULE) != 0)
+ createModuleSymbol(name, pos, newFlags)
+ else if ((newFlags & PARAM) != 0)
+ createValueParameterSymbol(name, pos, newFlags)
+ else
+ createValueMemberSymbol(name, pos, newFlags)
+ }
+
+ final def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = {
+ if (name == tpnme.REFINE_CLASS_NAME)
+ createRefinementClassSymbol(pos, newFlags)
+ else if ((newFlags & PACKAGE) != 0)
+ createPackageClassSymbol(name, pos, newFlags | PackageFlags)
+ else if (name == tpnme.PACKAGE)
+ createPackageObjectClassSymbol(pos, newFlags)
+ else if ((newFlags & MODULE) != 0)
+ createModuleClassSymbol(name, pos, newFlags)
+ else if ((newFlags & IMPLCLASS) != 0)
+ createImplClassSymbol(name, pos, newFlags)
+ else
+ createClassSymbol(name, pos, newFlags)
+ }
+
+ final def newNonClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = {
+ if ((newFlags & DEFERRED) != 0)
+ createAbstractTypeSymbol(name, pos, newFlags)
+ else
+ createAliasTypeSymbol(name, pos, newFlags)
+ }
+
+ def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
+ newNonClassSymbol(name, pos, newFlags)
+ }
+}
diff --git a/src/compiler/scala/reflect/internal/SymbolFlags.scala b/src/compiler/scala/reflect/internal/SymbolFlags.scala
new file mode 100644
index 0000000000..7741d700b9
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/SymbolFlags.scala
@@ -0,0 +1,175 @@
+ /* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.reflect
+package internal
+
+import scala.collection.{ mutable, immutable }
+import scala.collection.mutable.ListBuffer
+import util.Statistics._
+import Flags._
+import api.Modifier
+
+trait SymbolFlags {
+ self: SymbolTable =>
+
+ import definitions._
+
+ /** Not mixed in under normal conditions; a powerful debugging aid.
+ */
+ trait FlagVerifier extends Symbol {
+ private def assert0(cond: Boolean, message: => Any) {
+ if (!cond) {
+ Console.err.println("[flag verification failure]\n%s\n%s\n".format(atPhaseStackMessage, message))
+ (new Throwable).getStackTrace.take(13).drop(3).foreach(println)
+ println("")
+ }
+ }
+
+ protected def verifyChange(isAdd: Boolean, mask: Long, before: Long) {
+ val after = if (isAdd) before | mask else before & ~mask
+ val added = after & ~before
+ val removed = before & ~after
+ val ignored = mask & ~added & ~removed
+ val error = (
+ (added & OverloadedFlagsMask) != 0 || (removed & OverloadedFlagsMask) != 0
+ // || (ignored != 0)
+ )
+ val addString = if (added == 0) "" else "+(" + flagsToString(added) + ")"
+ val removeString = if (removed == 0) "" else "-(" + flagsToString(removed) + ")"
+ val changeString = if (added == 0 && removed == 0) "no change" else addString + " " + removeString
+
+ if (error) {
+ val templ = (
+ """| symbol: %s %s in %s
+ | call: %s(%s)
+ | flags: %s
+ | result: %s""".stripMargin
+ )
+
+ assert0(false, templ.format(
+ shortSymbolClass,
+ name.decode,
+ owner,
+ if (isAdd) "+" else "-",
+ flagsToString(mask),
+ flagsToString(before),
+ changeString
+ ))
+ }
+ }
+
+ protected def verifyFlags(what: String) {
+ assert0(this hasAllFlags alwaysHasFlags, symbolCreationString + "\n always=%s, what=%s\n".format(flagsToString(alwaysHasFlags), what))
+ if (this hasFlag neverHasFlags) {
+ val hasRaw = (rawflags & neverHasFlags) != 0
+ assert0(!hasRaw, symbolCreationString + "\n never=%s, what=%s".format(flagsToString(neverHasFlags), what))
+ }
+ }
+ abstract override def initFlags(mask: Long): this.type = {
+ super.initFlags(mask)
+ verifyFlags("initFlags(" + flagsToString(mask) + ")")
+ this
+ }
+ abstract override def setFlag(mask: Long): this.type = {
+ verifyChange(true, mask, rawflags)
+ super.setFlag(mask)
+ verifyFlags("setFlag(" + flagsToString(mask) + ")")
+ this
+ }
+ abstract override def resetFlag(mask: Long): this.type = {
+ verifyChange(false, mask, rawflags)
+ super.resetFlag(mask)
+ verifyFlags("resetFlag(" + flagsToString(mask) + ")")
+ this
+ }
+ abstract override def flags_=(fs: Long) {
+ if ((fs & ~rawflags) != 0)
+ verifyChange(true, fs & ~rawflags, rawflags)
+ if ((rawflags & ~fs) != 0)
+ verifyChange(false, rawflags & ~fs, rawflags)
+
+ super.flags_=(fs)
+ verifyFlags("flags_=(" + flagsToString(fs) + ")")
+ }
+ }
+
+ /** Flags which should always be present on a particular class of
+ * Symbol, and never be present on any others.
+ */
+ def AllDistinguishingFlags: Long = METHOD | MODULE | IMPLCLASS
+
+ /** A distinguishing flag is one which the mixing class must always
+ * have, and which no other symbol class is allowed to have.
+ */
+ trait DistinguishingFlag extends SymbolFlagLogic {
+ this: Symbol =>
+
+ def distinguishingFlag: Long
+ override protected def alwaysHasFlags = super.alwaysHasFlags | distinguishingFlag
+ override protected def neverHasFlags = super.neverHasFlags & ~distinguishingFlag
+ }
+
+ trait SymbolFlagLogic {
+ this: Symbol =>
+
+ // Forced for performance reasons to define all the flag manipulation
+ // methods alongside the field being manipulated.
+ def getFlag(mask: Long): Long
+ def hasFlag(mask: Long): Boolean
+ def hasAllFlags(mask: Long): Boolean
+ def setFlag(mask: Long): this.type
+ def resetFlag(mask: Long): this.type
+ def initFlags(mask: Long): this.type
+ def resetFlags(): Unit
+
+ protected def resolveOverloadedFlag(flag: Long): String
+ protected def calculateFlagString(basis: Long): String
+
+ protected def alwaysHasFlags: Long = 0L
+ protected def neverHasFlags: Long = AllDistinguishingFlags
+
+ def rawFlagString(mask: Long): String = calculateFlagString(rawflags & mask)
+ def rawFlagString: String = rawFlagString(flagMask)
+ def debugFlagString: String = flagString(AllFlags)
+
+ /** String representation of symbol's variance */
+ def varianceString: String =
+ if (variance == 1) "+"
+ else if (variance == -1) "-"
+ else ""
+
+ override def flagMask =
+ if (settings.debug.value && !isAbstractType) AllFlags
+ else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE
+ else ExplicitFlags
+
+ // make the error message more googlable
+ def flagsExplanationString =
+ if (isGADTSkolem) " (this is a GADT skolem)"
+ else ""
+
+ /** If the given flag is set on this symbol, also set the corresponding
+ * notFLAG. For instance if flag is PRIVATE, the notPRIVATE flag will
+ * be set if PRIVATE is currently set.
+ */
+ final def setNotFlag(flag: Int) = if (hasFlag(flag)) setFlag((flag: @annotation.switch) match {
+ case PRIVATE => notPRIVATE
+ case PROTECTED => notPROTECTED
+ case OVERRIDE => notOVERRIDE
+ case _ => abort("setNotFlag on invalid flag: " + flag)
+ })
+
+ protected def shortSymbolClass = getClass.getName.split('.').last.stripPrefix("Symbols$")
+ def symbolCreationString: String = (
+ "%s%25s | %-40s | %s".format(
+ if (settings.uniqid.value) "%06d | ".format(id) else "",
+ shortSymbolClass,
+ name.decode + " in " + owner,
+ rawFlagString
+ )
+ )
+ }
+}
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index b58a0ef7d5..9158c2a4d4 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -13,7 +13,10 @@ import scala.tools.nsc.util.WeakHashSet
abstract class SymbolTable extends api.Universe
with Collections
with Names
+ with SymbolCreations
with Symbols
+ with SymbolFlags
+ with FreeVars
with Types
with Kinds
with ExistentialsAndSkolems
@@ -32,6 +35,10 @@ abstract class SymbolTable extends api.Universe
with TypeDebugging
with Importers
with Required
+ with TreeBuildUtil
+ with FrontEnds
+ with CapturedVariables
+ with StdAttachments
{
def rootLoader: LazyType
def log(msg: => AnyRef): Unit
@@ -47,6 +54,13 @@ abstract class SymbolTable extends api.Universe
/** Overridden when we know more about what was happening during a failure. */
def supplementErrorMessage(msg: String): String = msg
+ private[scala] def printCaller[T](msg: String)(result: T) = {
+ Console.err.println(msg + ": " + result)
+ Console.err.println("Called from:")
+ (new Throwable).getStackTrace.drop(2).take(15).foreach(Console.err.println)
+ result
+ }
+
private[scala] def printResult[T](msg: String)(result: T) = {
Console.err.println(msg + ": " + result)
result
@@ -55,6 +69,32 @@ abstract class SymbolTable extends api.Universe
log(msg + ": " + result)
result
}
+ private[scala] def logResultIf[T](msg: String, cond: T => Boolean)(result: T): T = {
+ if (cond(result))
+ log(msg + ": " + result)
+
+ result
+ }
+
+ // For too long have we suffered in order to sort NAMES.
+ // I'm pretty sure there's a reasonable default for that.
+ // Notice challenge created by Ordering's invariance.
+ implicit def lowPriorityNameOrdering[T <: Names#Name]: Ordering[T] =
+ SimpleNameOrdering.asInstanceOf[Ordering[T]]
+
+ private object SimpleNameOrdering extends Ordering[Names#Name] {
+ def compare(n1: Names#Name, n2: Names#Name) = (
+ if (n1 eq n2) 0
+ else n1.toString compareTo n2.toString
+ )
+ }
+
+ /** Dump each symbol to stdout after shutdown.
+ */
+ final val traceSymbolActivity = sys.props contains "scalac.debug.syms"
+ object traceSymbols extends {
+ val global: SymbolTable.this.type = SymbolTable.this
+ } with util.TraceSymbolActivity
/** Are we compiling for Java SE? */
// def forJVM: Boolean
@@ -87,6 +127,11 @@ abstract class SymbolTable extends api.Universe
final def atPhaseStack: List[Phase] = phStack
final def phase: Phase = ph
+ def atPhaseStackMessage = atPhaseStack match {
+ case Nil => ""
+ case ps => ps.reverseMap("->" + _).mkString("(", " ", ")")
+ }
+
final def phase_=(p: Phase) {
//System.out.println("setting phase to " + p)
assert((p ne null) && p != NoPhase, p)
@@ -138,7 +183,7 @@ abstract class SymbolTable extends api.Universe
try op
finally popPhase(saved)
}
-
+
/** Since when it is to be "at" a phase is inherently ambiguous,
* a couple unambiguously named methods.
@@ -200,7 +245,7 @@ abstract class SymbolTable extends api.Universe
def arrayToRepeated(tp: Type): Type = tp match {
case MethodType(params, rtpe) =>
val formals = tp.paramTypes
- assert(formals.last.typeSymbol == definitions.ArrayClass)
+ assert(formals.last.typeSymbol == definitions.ArrayClass, formals)
val method = params.last.owner
val elemtp = formals.last.typeArgs.head match {
case RefinedType(List(t1, t2), _) if (t1.typeSymbol.isAbstractType && t2.typeSymbol == definitions.ObjectClass) =>
@@ -208,8 +253,7 @@ abstract class SymbolTable extends api.Universe
case t =>
t
}
- val newParams = method.newSyntheticValueParams(
- formals.init :+ appliedType(definitions.JavaRepeatedParamClass.typeConstructor, List(elemtp)))
+ val newParams = method.newSyntheticValueParams(formals.init :+ definitions.javaRepeatedType(elemtp))
MethodType(newParams, rtpe)
case PolyType(tparams, rtpe) =>
PolyType(tparams, arrayToRepeated(rtpe))
@@ -237,6 +281,8 @@ abstract class SymbolTable extends api.Universe
import java.lang.ref.WeakReference
import scala.runtime.ScalaRunTime.stringOf
+ import language.reflectiveCalls
+
// We can allow ourselves a structural type, these methods
// amount to a few calls per run at most. This does suggest
// a "Clearable" trait may be useful.
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 2ba45c5972..31f068494c 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-
package scala.reflect
package internal
@@ -46,21 +45,32 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
m
}
- /** Create a new free variable. Its owner is NoSymbol.
+ /** Create a new free term. Its owner is NoSymbol.
+ */
+ def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeTerm =
+ new FreeTerm(name, value, origin) initFlags flags setInfo info
+
+ /** Create a new free type. Its owner is NoSymbol.
*/
- def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar =
- new FreeVar(name, value) initFlags newFlags setInfo tpe
+ def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String): FreeType =
+ new FreeType(name, value, origin) initFlags flags setInfo info
/** The original owner of a class. Used by the backend to generate
* EnclosingMethod attributes.
*/
val originalOwner = perRunCaches.newMap[Symbol, Symbol]()
- abstract class AbsSymbolImpl extends AbsSymbol { this: Symbol =>
- def newNestedSymbol(name: Name, pos: Position, newFlags: Long) = name match {
+ abstract class AbsSymbolImpl extends AbsSymbol {
+ this: Symbol =>
+
+ def kind: String = kindString
+ def isExistential: Boolean = this.isExistentiallyBound
+
+ def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match {
case n: TermName => newTermSymbol(n, pos, newFlags)
- case n: TypeName => newTypeSymbol(n, pos, newFlags)
+ case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags)
}
+
def enclosingClass: Symbol = enclClass
def enclosingMethod: Symbol = enclMethod
def thisPrefix: Type = thisType
@@ -74,39 +84,130 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def setInternalFlags(flag: Long): this.type = { setFlag(flag); this }
def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this }
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
+
+ private def lastElemType(ts: Seq[Type]): Type = ts.last.normalize.typeArgs.head
+
+ private def formalTypes(formals: List[Type], nargs: Int): List[Type] = {
+ val formals1 = formals mapConserve {
+ case TypeRef(_, ByNameParamClass, List(arg)) => arg
+ case formal => formal
+ }
+ if (isVarArgTypes(formals1)) {
+ val ft = lastElemType(formals)
+ formals1.init ::: List.fill(nargs - (formals1.length - 1))(ft)
+ } else formals1
+ }
+
+ def resolveOverloaded(pre: Type, targs: Seq[Type], actuals: Seq[Type]): Symbol = {
+ def firstParams(tpe: Type): (List[Symbol], List[Type]) = tpe match {
+ case PolyType(tparams, restpe) =>
+ val (Nil, formals) = firstParams(restpe)
+ (tparams, formals)
+ case MethodType(params, _) =>
+ (Nil, params map (_.tpe))
+ case _ =>
+ (Nil, Nil)
+ }
+ def isApplicable(alt: Symbol, targs: List[Type], actuals: Seq[Type]) = {
+ def isApplicableType(tparams: List[Symbol], tpe: Type): Boolean = {
+ val (tparams, formals) = firstParams(pre memberType alt)
+ val formals1 = formalTypes(formals, actuals.length)
+ val actuals1 =
+ if (isVarArgTypes(actuals)) {
+ if (!isVarArgTypes(formals)) return false
+ actuals.init :+ lastElemType(actuals)
+ } else actuals
+ if (formals1.length != actuals1.length) return false
+
+ if (tparams.isEmpty) return (actuals1 corresponds formals1)(_ <:< _)
+
+ if (targs.length == tparams.length)
+ isApplicableType(List(), tpe.instantiateTypeParams(tparams, targs))
+ else if (targs.nonEmpty)
+ false
+ else {
+ val tvars = tparams map (TypeVar(_))
+ (actuals1 corresponds formals1) { (actual, formal) =>
+ val tp1 = actual.deconst.instantiateTypeParams(tparams, tvars)
+ val pt1 = actual.instantiateTypeParams(tparams, tvars)
+ tp1 <:< pt1
+ } &&
+ solve(tvars, tparams, List.fill(tparams.length)(COVARIANT), upper = false)
+ }
+ }
+ isApplicableType(List(), pre.memberType(alt))
+ }
+ def isAsGood(alt1: Symbol, alt2: Symbol): Boolean = {
+ alt1 == alt2 ||
+ alt2 == NoSymbol || {
+ val (tparams, formals) = firstParams(pre memberType alt1)
+ isApplicable(alt2, tparams map (_.tpe), formals)
+ }
+ }
+ assert(isOverloaded)
+ val applicables = alternatives filter (isApplicable(_, targs.toList, actuals))
+ def winner(alts: List[Symbol]) =
+ ((NoSymbol: Symbol) /: alts)((best, alt) => if (isAsGood(alt, best)) alt else best)
+ val best = winner(applicables)
+ if (best == winner(applicables.reverse)) best else NoSymbol
+ }
}
/** The class for all symbols */
abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name)
extends AbsSymbolImpl
with HasFlags
+ with SymbolFlagLogic
+ with SymbolCreator
+ // with FlagVerifier // DEBUG
with Annotatable[Symbol] {
- type FlagsType = Long
type AccessBoundaryType = Symbol
type AnnotationType = AnnotationInfo
+ // TODO - don't allow names to be renamed in this unstructured a fashion.
+ // Rename as little as possible. Enforce invariants on all renames.
+ type NameType >: Null <: Name
+ type TypeOfClonedSymbol >: Null <: Symbol { type NameType = Symbol.this.NameType }
+
+ // Abstract here so TypeSymbol and TermSymbol can have a private[this] field
+ // with the proper specific type.
+ def rawname: NameType
+ def name: NameType
+ def name_=(n: Name): Unit
+ def asNameType(n: Name): NameType
+
private[this] var _rawowner = initOwner // Syncnote: need not be protected, as only assignment happens in owner_=, which is not exposed to api
- private[this] var _rawname = initName
- private[this] var _rawflags = 0L
+ private[this] var _rawflags: Long = _
def rawowner = _rawowner
- def rawname = _rawname
def rawflags = _rawflags
- protected def rawflags_=(x: FlagsType) { _rawflags = x }
-
private var rawpos = initPos
val id = nextId() // identity displayed when -uniqid
-
private[this] var _validTo: Period = NoPeriod
+ if (traceSymbolActivity)
+ traceSymbols.recordNewSymbol(this)
+
def validTo = _validTo
def validTo_=(x: Period) { _validTo = x}
def pos = rawpos
def setPos(pos: Position): this.type = { this.rawpos = pos; this }
+ def setName(name: Name): this.type = { this.name = asNameType(name) ; this }
+
+ // Update the surrounding scopes
+ protected[this] def changeNameInOwners(name: Name) {
+ if (owner.isClass) {
+ var ifs = owner.infos
+ while (ifs != null) {
+ ifs.info.decls.rehash(this, name)
+ ifs = ifs.prev
+ }
+ }
+ }
/** !!! The logic after "hasFlag" is far too opaque to be unexplained.
* I'm guessing it's attempting to compensate for flag overloading,
@@ -131,87 +232,54 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
newTermSymbol(name, pos, PARAM | newFlags)
/** Create local dummy for template (owner of local blocks) */
- final def newLocalDummy(pos: Position) =
+ final def newLocalDummy(pos: Position): TermSymbol =
newTermSymbol(nme.localDummyName(this), pos) setInfo NoType
final def newMethod(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol =
- newMethodSymbol(name, pos, METHOD | newFlags)
+ createMethodSymbol(name, pos, METHOD | newFlags)
final def newLabel(name: TermName, pos: Position = NoPosition): MethodSymbol =
newMethod(name, pos, LABEL)
/** Propagates ConstrFlags (JAVA, specifically) from owner to constructor. */
- final def newConstructor(pos: Position, newFlags: Long = 0L) =
+ final def newConstructor(pos: Position, newFlags: Long = 0L): MethodSymbol =
newMethod(nme.CONSTRUCTOR, pos, getFlag(ConstrFlags) | newFlags)
/** Static constructor with info set. */
- def newStaticConstructor(pos: Position) =
+ def newStaticConstructor(pos: Position): MethodSymbol =
newConstructor(pos, STATIC) setInfo UnitClass.tpe
+
/** Instance constructor with info set. */
- def newClassConstructor(pos: Position) =
+ def newClassConstructor(pos: Position): MethodSymbol =
newConstructor(pos) setInfo MethodType(Nil, this.tpe)
- // Top-level objects can be automatically marked final, but others
- // must be explicitly marked final if overridable objects are enabled.
- private def ModuleFlags = (
- if (isPackage || !settings.overrideObjects.value) MODULE | FINAL
- else MODULE
- )
def newLinkedModule(clazz: Symbol, newFlags: Long = 0L): ModuleSymbol = {
- val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, ModuleFlags | newFlags)
+ val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, MODULE | newFlags)
connectModuleToClass(m, clazz.asInstanceOf[ClassSymbol])
}
final def newModule(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = {
- val m = newModuleSymbol(name, pos, newFlags | ModuleFlags)
- val clazz = newModuleClassSymbol(name.toTypeName, pos, (m getFlag ModuleToClassFlags) | MODULE)
+ val m = newModuleSymbol(name, pos, newFlags | MODULE)
+ val clazz = newModuleClass(name.toTypeName, pos, m getFlag ModuleToClassFlags)
connectModuleToClass(m, clazz)
}
final def newPackage(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = {
assert(name == nme.ROOT || isPackageClass, this)
- newModule(name, pos, JAVA | PACKAGE | newFlags)
+ newModule(name, pos, PackageFlags | newFlags)
}
- final def newThisSym(pos: Position) =
- newTermSymbol(nme.this_, pos, SYNTHETIC)
- final def newImport(pos: Position) =
- newTermSymbol(nme.IMPORT, pos)
-
- /** Direct symbol factories.
- * For internal use; these are unlikely to be what you want.
- */
- def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol =
- new TermSymbol(this, pos, name) initFlags newFlags
-
- def newAbstractTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol =
- new AbstractTypeSymbol(this, pos, name) initFlags newFlags
- def newAliasTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol =
- new AliasTypeSymbol(this, pos, name) initFlags newFlags
-
- def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
- new ModuleSymbol(this, pos, name) initFlags newFlags
+ final def newThisSym(name: TermName = nme.this_, pos: Position = NoPosition): TermSymbol =
+ newTermSymbol(name, pos, SYNTHETIC)
- def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol =
- new MethodSymbol(this, pos, name) initFlags newFlags
-
- def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol =
- new ClassSymbol(this, pos, name) initFlags newFlags
+ final def newImport(pos: Position): TermSymbol =
+ newTermSymbol(nme.IMPORT, pos)
- def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol =
- new ModuleClassSymbol(this, pos, name) initFlags newFlags
+ final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
+ newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol]
- /** Derive whether it is an abstract type from the flags; after creation
- * the DEFERRED flag will be ignored.
- */
- def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
- if ((newFlags & DEFERRED) == 0L)
- newAliasTypeSymbol(name, pos, newFlags)
- else
- newAbstractTypeSymbol(name, pos, newFlags)
+ final def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol =
+ newClassSymbol(name, pos, newFlags).asInstanceOf[ModuleClassSymbol]
- def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem =
- if ((newFlags & DEFERRED) == 0L)
- new TypeSkolem(this, pos, name, origin) initFlags newFlags
- else
- new TypeSkolem(this, pos, name, origin) with AbstractTypeMixin initFlags newFlags
+ final def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem =
+ createTypeSkolemSymbol(name, origin, pos, newFlags)
/** @param pre type relative to which alternatives are seen.
* for instance:
@@ -231,40 +299,45 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*
* pre.memberType(m)
*/
- final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol = (
+ final def newOverloaded(pre: Type, alternatives: List[Symbol]): TermSymbol = (
newTermSymbol(alternatives.head.name.toTermName, alternatives.head.pos, OVERLOADED)
setInfo OverloadedType(pre, alternatives)
)
- final def newErrorValue(name: TermName) =
+ final def newErrorValue(name: TermName): TermSymbol =
newTermSymbol(name, pos, SYNTHETIC | IS_ERROR) setInfo ErrorType
/** Symbol of a type definition type T = ...
*/
- final def newAliasType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol =
- newAliasTypeSymbol(name, pos, newFlags)
+ final def newAliasType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol =
+ createAliasTypeSymbol(name, pos, newFlags)
/** Symbol of an abstract type type T >: ... <: ...
*/
- final def newAbstractType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol =
- newAbstractTypeSymbol(name, pos, DEFERRED | newFlags)
+ final def newAbstractType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol =
+ createAbstractTypeSymbol(name, pos, DEFERRED | newFlags)
/** Symbol of a type parameter
*/
- final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) =
+ final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
newAbstractType(name, pos, PARAM | newFlags)
+ /** Symbol of an existential type T forSome { ... }
+ */
+ final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
+ newAbstractType(name, pos, EXISTENTIAL | newFlags)
+
/** Synthetic value parameters when parameter symbols are not available
*/
- final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[Symbol]] = {
+ final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[TermSymbol]] = {
var cnt = 0
def freshName() = { cnt += 1; nme.syntheticParamName(cnt) }
- mmap(argtypess)(tp => newValueParameter(freshName(), focusPos(owner.pos), SYNTHETIC) setInfo tp)
+ mmap(argtypess)(tp => newValueParameter(freshName(), owner.pos.focus, SYNTHETIC) setInfo tp)
}
- def newSyntheticTypeParam(): Symbol = newSyntheticTypeParam("T0", 0L)
- def newSyntheticTypeParam(name: String, newFlags: Long): Symbol = newTypeParameter(newTypeName(name), NoPosition, newFlags) setInfo TypeBounds.empty
- def newSyntheticTypeParams(num: Int): List[Symbol] = (0 until num).toList map (n => newSyntheticTypeParam("T" + n, 0L))
+ def newSyntheticTypeParam(): TypeSymbol = newSyntheticTypeParam("T0", 0L)
+ def newSyntheticTypeParam(name: String, newFlags: Long): TypeSymbol = newTypeParameter(newTypeName(name), NoPosition, newFlags) setInfo TypeBounds.empty
+ def newSyntheticTypeParams(num: Int): List[TypeSymbol] = (0 until num).toList map (n => newSyntheticTypeParam("T" + n, 0L))
/** Create a new existential type skolem with this symbol its owner,
* based on the given symbol and origin.
@@ -279,17 +352,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def newGADTSkolem(name: TypeName, origin: Symbol, info: Type): TypeSkolem =
newTypeSkolemSymbol(name, origin, origin.pos, origin.flags & ~(EXISTENTIAL | PARAM) | CASEACCESSOR | SYNTHETIC) setInfo info
-
- final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol =
- newAbstractType(name, pos, EXISTENTIAL | newFlags)
-
- final def freshExistential(suffix: String): Symbol =
+ final def freshExistential(suffix: String): TypeSymbol =
newExistential(freshExistentialName(suffix), pos)
/** Synthetic value parameters when parameter symbols are not available.
* Calling this method multiple times will re-use the same parameter names.
*/
- final def newSyntheticValueParams(argtypes: List[Type]): List[Symbol] =
+ final def newSyntheticValueParams(argtypes: List[Type]): List[TermSymbol] =
newSyntheticValueParamss(List(argtypes)).head
/** Synthetic value parameter when parameter symbol is not available.
@@ -303,41 +372,42 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* with name `T` in its typeParams list. While type checking the parameters, result type and
* body of the method, there's a local copy of `T` which is a TypeSkolem.
*/
- final def newTypeSkolem: Symbol =
+ final def newTypeSkolem: TypeSkolem =
owner.newTypeSkolemSymbol(name.toTypeName, this, pos, flags)
- final def newClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) =
+ final def newClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol =
newClassSymbol(name, pos, newFlags)
/** A new class with its info set to a ClassInfoType with given scope and parents. */
- def newClassWithInfo(name: TypeName, parents: List[Type], scope: Scope, pos: Position = NoPosition, newFlags: Long = 0L) = {
+ def newClassWithInfo(name: TypeName, parents: List[Type], scope: Scope, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = {
val clazz = newClass(name, pos, newFlags)
clazz setInfo ClassInfoType(parents, scope, clazz)
}
- final def newErrorClass(name: TypeName) =
+ final def newErrorClass(name: TypeName): ClassSymbol =
newClassWithInfo(name, Nil, new ErrorScope(this), pos, SYNTHETIC | IS_ERROR)
- final def newModuleClass(name: TypeName, pos: Position = NoPosition) =
- newModuleClassSymbol(name, pos)
+ final def newModuleClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol =
+ newModuleClassSymbol(name, pos, newFlags | MODULE)
- final def newAnonymousClass(pos: Position) =
- newClassSymbol(tpnme.ANON_CLASS_NAME, pos)
-
- final def newAnonymousFunctionClass(pos: Position, newFlags: Long = 0L) =
+ final def newAnonymousFunctionClass(pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol =
newClassSymbol(tpnme.ANON_FUN_NAME, pos, FINAL | SYNTHETIC | newFlags)
- final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L) =
+ final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L): TermSymbol =
newTermSymbol(nme.ANON_FUN_NAME, pos, SYNTHETIC | newFlags) setInfo NoType
+ def newImplClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = {
+ newClassSymbol(name, pos, newFlags | IMPLCLASS)
+ }
+
/** Refinement types P { val x: String; type T <: Number }
* also have symbols, they are refinementClasses
*/
- final def newRefinementClass(pos: Position) =
- newClass(tpnme.REFINE_CLASS_NAME, pos)
+ final def newRefinementClass(pos: Position): RefinementClassSymbol =
+ createRefinementClassSymbol(pos, 0L)
/** Create a new getter for current symbol (which must be a field)
*/
- final def newGetter: Symbol = (
+ final def newGetter: MethodSymbol = (
owner.newMethod(nme.getterName(name.toTermName), NoPosition, getterFlags(flags))
setPrivateWithin privateWithin
setInfo MethodType(Nil, tpe)
@@ -348,6 +418,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case x: TermName => newErrorValue(x)
}
+ /** To overcome the crazy challenge of more specific types appearing
+ * in incoming positions. Don't need this much.
+ */
+ def asTypeSymbol: TypeSymbol = this match {
+ case x: TypeSymbol => x
+ case x => throw new FatalError(this + " is not a TypeSymbol")
+ }
+ def asTermSymbol: TermSymbol = this match {
+ case x: TermSymbol => x
+ case x => throw new FatalError(this + " is not a TermSymbol")
+ }
+
@deprecated("Use the other signature", "2.10.0")
def newClass(pos: Position, name: TypeName): Symbol = newClass(name, pos)
@deprecated("Use the other signature", "2.10.0")
@@ -371,7 +453,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// True if the symbol is locked but still below the allowed recursion depth.
// False otherwise
private[scala] def lockOK: Boolean = {
- ((rawflags & LOCKED) == 0L) ||
+ ((_rawflags & LOCKED) == 0L) ||
((settings.Yrecursion.value != 0) &&
(recursionTable get this match {
case Some(n) => (n <= settings.Yrecursion.value)
@@ -380,7 +462,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// Lock a symbol, using the handler if the recursion depth becomes too great.
private[scala] def lock(handler: => Unit): Boolean = {
- if ((rawflags & LOCKED) != 0L) {
+ if ((_rawflags & LOCKED) != 0L) {
if (settings.Yrecursion.value != 0) {
recursionTable get this match {
case Some(n) =>
@@ -397,7 +479,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
} else { handler; false }
} else {
- rawflags |= LOCKED
+ _rawflags |= LOCKED
true
// activeLocks += 1
// lockedSyms += this
@@ -406,10 +488,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// Unlock a symbol
private[scala] def unlock() = {
- if ((rawflags & LOCKED) != 0L) {
+ if ((_rawflags & LOCKED) != 0L) {
// activeLocks -= 1
// lockedSyms -= this
- _rawflags = rawflags & ~LOCKED
+ _rawflags &= ~LOCKED
if (settings.Yrecursion.value != 0)
recursionTable -= this
}
@@ -417,94 +499,171 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ----- tests ----------------------------------------------------------------------
- def isTerm = false // to be overridden
- def isType = false // to be overridden
- def isClass = false // to be overridden
- def isBottomClass = false // to be overridden
- def isAliasType = false // to be overridden
- def isAbstractType = false // to be overridden
- private[scala] def isSkolem = false // to be overridden
-
- /** Is this symbol a type but not a class? */
- def isNonClassType = false // to be overridden
-
- override final def isTrait = isClass && hasFlag(TRAIT)
- final def isAbstractClass = isClass && hasFlag(ABSTRACT)
- final def isBridge = hasFlag(BRIDGE)
- final def isContravariant = isType && hasFlag(CONTRAVARIANT)
- final def isConcreteClass = isClass && !hasFlag(ABSTRACT | TRAIT)
- final def isCovariant = isType && hasFlag(COVARIANT)
- final def isEarlyInitialized = isTerm && hasFlag(PRESUPER)
- final def isExistentiallyBound = isType && hasFlag(EXISTENTIAL)
- final def isImplClass = isClass && hasFlag(IMPLCLASS)
+ /** All symbols are one of three categories: TermSymbol, TypeSymbol, or NoSymbol.
+ * There is only one NoSymbol.
+ */
+ def isTerm = false
+ def isType = false
+
+ /** TypeSymbols fall into four named direct subclasses:
+ * - ClassSymbol
+ * - AliasTypeSymbol
+ * - AbstractTypeSymbol
+ * - TypeSkolem
+ */
+ def isClass = false
+ def isAliasType = false
+ def isAbstractType = false
+ def isSkolem = false
+
+ /** A Type, but not a Class. */
+ def isNonClassType = false
+
+ /** The bottom classes are Nothing and Null, found in Definitions. */
+ def isBottomClass = false
+ def isSpecialized = this hasFlag SPECIALIZED
+
+ /** These are all tests for varieties of ClassSymbol, which has these subclasses:
+ * - ModuleClassSymbol
+ * - RefinementClassSymbol
+ * - PackageClassSymbol (extends ModuleClassSymbol)
+ */
+ def isAbstractClass = false
+ def isAnonOrRefinementClass = false
+ def isAnonymousClass = false
+ def isCaseClass = false
+ def isConcreteClass = false
+ def isImplClass = false // the implementation class of a trait
+ def isJavaInterface = false
+ def isModuleClass = false
+ def isNumericValueClass = false
+ def isPrimitiveValueClass = false
+ def isRefinementClass = false
+ override def isTrait = false
+
+ /** Qualities of Types, always false for TermSymbols.
+ */
+ def isContravariant = false
+ def isCovariant = false
+ def isExistentialQuantified = false
+ def isExistentialSkolem = false
+ def isExistentiallyBound = false
+ def isGADTSkolem = false
+ def isTypeParameter = false
+ def isTypeParameterOrSkolem = false
+ def isTypeSkolem = false
+ def isTypeMacro = false
+ def isFreeType = false
+
+ /** Qualities of Terms, always false for TypeSymbols.
+ */
+ def isAccessor = false
+ def isBridge = false
+ def isCapturedVariable = false
+ def isClassConstructor = false
+ def isConstructor = false
+ def isEarlyInitialized = false
+ def isGetter = false
+ def isLocalDummy = false
+ def isMixinConstructor = false
+ def isModule = false
+ def isOverloaded = false
+ def isSetter = false
+ def isSetterParameter = false
+ def isValue = false
+ def isValueParameter = false
+ def isVariable = false
+ override def hasDefault = false
+ def isTermMacro = false
+ def isFreeTerm = false
+
+ /** Qualities of MethodSymbols, always false for TypeSymbols
+ * and other TermSymbols.
+ */
+ def isCaseAccessorMethod = false
+ def isLiftedMethod = false
+ def isMethod = false
+ def isSourceMethod = false
+ def isVarargsMethod = false
+ override def isLabel = false
+
+ /** Package/package object tests */
+ def isPackage = false
+ def isPackageClass = false
+ def isPackageObject = false
+ def isPackageObjectClass = false
+ def isPackageObjectOrClass = isPackageObject || isPackageObjectClass
+ def isModuleOrModuleClass = isModule || isModuleClass
+
+ /** Overridden in custom objects in Definitions */
+ def isRoot = false
+ def isRootPackage = false
+ def isRootSymbol = false // RootPackage and RootClass. TODO: also NoSymbol.
+ def isEmptyPackage = false
+ def isEmptyPackageClass = false
+
+ /** Is this symbol an effective root for fullname string?
+ */
+ def isEffectiveRoot = false
+
+ /** For RootClass, this is EmptyPackageClass. For all other symbols,
+ * the symbol itself.
+ */
+ def ownerOfNewSymbols = this
+
final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol
- final def isMethod = isTerm && hasFlag(METHOD)
- final def isModule = isTerm && hasFlag(MODULE)
- final def isModuleClass = isClass && hasFlag(MODULE)
- final def isNumericValueClass = definitions.isNumericValueClass(this)
- final def isOverloaded = hasFlag(OVERLOADED)
- final def isOverridableMember = !(isClass || isEffectivelyFinal) && owner.isClass
- final def isRefinementClass = isClass && name == tpnme.REFINE_CLASS_NAME
- final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!!
- final def isTypeParameter = isType && isParameter && !isSkolem
- final def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this)
- final def isVarargsMethod = isMethod && hasFlag(VARARGS)
-
- /** Package tests */
- final def isEmptyPackage = isPackage && name == nme.EMPTY_PACKAGE_NAME
- final def isEmptyPackageClass = isPackageClass && name == tpnme.EMPTY_PACKAGE_NAME
- final def isPackage = isModule && hasFlag(PACKAGE)
- final def isPackageClass = isClass && hasFlag(PACKAGE)
- final def isRoot = isPackageClass && owner == NoSymbol
- final def isRootPackage = isPackage && owner == NoSymbol
+ final def isOverridableMember = !(isClass || isEffectivelyFinal) && (this ne NoSymbol) && owner.isClass
/** Does this symbol denote a wrapper created by the repl? */
final def isInterpreterWrapper = (
- (isModule || isModuleClass)
+ (this hasFlag MODULE)
&& owner.isPackageClass
&& nme.isReplWrapperName(name)
)
- /** Is this symbol an effective root for fullname string?
- */
- def isEffectiveRoot = isRoot || isEmptyPackageClass
+ @inline final override def getFlag(mask: Long): Long = flags & mask
+ /** Does symbol have ANY flag in `mask` set? */
+ @inline final override def hasFlag(mask: Long): Boolean = (flags & mask) != 0
+ /** Does symbol have ALL the flags in `mask` set? */
+ @inline final override def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask
- /** Term symbols with the exception of static parts of Java classes and packages.
- */
- final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA))
+ override def setFlag(mask: Long): this.type = { _rawflags |= mask ; this }
+ override def resetFlag(mask: Long): this.type = { _rawflags &= ~mask ; this }
+ override def resetFlags() { rawflags &= (TopLevelCreationFlags | alwaysHasFlags) }
- final def isVariable = isTerm && isMutable && !isMethod
+ /** Default implementation calls the generic string function, which
+ * will print overloaded flags as <flag1/flag2/flag3>. Subclasses
+ * of Symbol refine.
+ */
+ override def resolveOverloadedFlag(flag: Long): String = Flags.flagToString(flag)
- // interesting only for lambda lift. Captured variables are accessed from inner lambdas.
- final def isCapturedVariable = isVariable && hasFlag(CAPTURED)
+ /** Set the symbol's flags to the given value, asserting
+ * that the previous value was 0.
+ */
+ override def initFlags(mask: Long): this.type = {
+ assert(rawflags == 0L, symbolCreationString)
+ _rawflags = mask
+ this
+ }
- final def isGetter = isTerm && hasAccessorFlag && !nme.isSetterName(name)
- // todo: make independent of name, as this can be forged.
- final def isSetter = isTerm && hasAccessorFlag && nme.isSetterName(name)
- def isSetterParameter = isValueParameter && owner.isSetter
+ final def flags: Long = {
+ val fs = _rawflags & phase.flagMask
+ (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift)
+ }
+ def flags_=(fs: Long) = _rawflags = fs
+ def rawflags_=(x: Long) { _rawflags = x }
final def hasGetter = isTerm && nme.isLocalName(name)
- final def isValueParameter = isTerm && hasFlag(PARAM)
- final def isLocalDummy = isTerm && nme.isLocalDummyName(name)
final def isInitializedToDefault = !isType && hasAllFlags(DEFAULTINIT | ACCESSOR)
- final def isClassConstructor = isTerm && (name == nme.CONSTRUCTOR)
- final def isMixinConstructor = isTerm && (name == nme.MIXIN_CONSTRUCTOR)
- final def isConstructor = isTerm && nme.isConstructorName(name)
final def isStaticModule = isModule && isStatic && !isMethod
final def isThisSym = isTerm && owner.thisSym == this
final def isError = hasFlag(IS_ERROR)
final def isErroneous = isError || isInitialized && tpe.isErroneous
- final def isTypeParameterOrSkolem = isType && hasFlag(PARAM)
- final def isHigherOrderTypeParameter = (this ne NoSymbol) && owner.isTypeParameterOrSkolem
- final def isTypeSkolem = isSkolem && hasFlag(PARAM)
- // a type symbol bound by an existential type, for instance the T in
- // List[T] forSome { type T }
- final def isExistentialSkolem = isExistentiallyBound && isSkolem
- final def isExistentialQuantified = isExistentiallyBound && !isSkolem
- final def isGADTSkolem = isSkolem && hasFlag(CASEACCESSOR | SYNTHETIC)
+
+ def isHigherOrderTypeParameter = owner.isTypeParameterOrSkolem
// class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor
- final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR)
+ def isClassLocalToConstructor = false
final def isDerivedValueClass =
isClass && info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass
@@ -512,29 +671,26 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isMethodWithExtension =
isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR)
- final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME)
- final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
- final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
-
- // A package object or its module class
- final def isPackageObjectOrClass = (this ne NoSymbol) && owner.isPackageClass && (name == nme.PACKAGE || name == tpnme.PACKAGE)
- final def isPackageObject = (this ne NoSymbol) && owner.isPackageClass && name == nme.PACKAGE
- final def isPackageObjectClass = (this ne NoSymbol) && owner.isPackageClass && name == tpnme.PACKAGE
-
+ final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
final def isDefinedInPackage = effectiveOwner.isPackageClass
- final def isJavaInterface = isJavaDefined && isTrait
- final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass
+ final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass
+
+ /** change name by appending $$<fully-qualified-name-of-class `base`>
+ * Do the same for any accessed symbols or setters/getters.
+ * Implementation in TermSymbol.
+ */
+ def expandName(base: Symbol) { }
// In java.lang, Predef, or scala package/package object
def isInDefaultNamespace = UnqualifiedOwners(effectiveOwner)
/** The owner, skipping package objects.
*/
- def effectiveOwner = if (owner.isPackageObjectClass) owner.skipPackageObject else owner
+ def effectiveOwner = owner.skipPackageObject
/** If this is a package object or its implementing class, its owner: otherwise this.
*/
- final def skipPackageObject: Symbol = if (isPackageObjectOrClass) owner else this
+ def skipPackageObject: Symbol = this
/** If this is a constructor, its owner: otherwise this.
*/
@@ -543,7 +699,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Conditions where we omit the prefix when printing a symbol, to avoid
* unpleasantries like Predef.String, $iw.$iw.Foo and <empty>.Bippy.
*/
- final def isOmittablePrefix = !settings.debug.value && (
+ final def isOmittablePrefix = /*!settings.debug.value &&*/ (
UnqualifiedOwners(skipPackageObject)
|| isEmptyPrefix
)
@@ -552,7 +708,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
|| isAnonOrRefinementClass // has uninteresting <anon> or <refinement> prefix
|| nme.isReplWrapperName(name) // has ugly $iw. prefix (doesn't call isInterpreterWrapper due to nesting)
)
- def isFBounded = info.baseTypeSeq exists (_ contains this)
+ def isFBounded = info match {
+ case TypeBounds(_, _) => info.baseTypeSeq exists (_ contains this)
+ case _ => false
+ }
/** Is symbol a monomorphic type?
* assumption: if a type starts out as monomorphic, it will not acquire
@@ -560,13 +719,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
final def isMonomorphicType =
isType && {
- var is = infos
- (is eq null) || {
- while (is.prev ne null) { is = is.prev }
- is.info.isComplete && !is.info.isHigherKinded // was: is.info.typeParams.isEmpty.
- // YourKit listed the call to PolyType.typeParams as a hot spot but it is likely an artefact.
- // The change to isHigherKinded did not reduce the total running time.
- }
+ val info = originalInfo
+ info.isComplete && !info.isHigherKinded
}
def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr)
@@ -605,22 +759,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** Does this symbol denote a stable value? */
- final def isStable =
- isTerm &&
- !isMutable &&
- (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) &&
- !(tpe.isVolatile && !hasAnnotation(uncheckedStableClass))
-
- // def isVirtualClass = hasFlag(DEFERRED) && isClass
- // def isVirtualTrait = hasFlag(DEFERRED) && isTrait
- def isLiftedMethod = isMethod && hasFlag(LIFTED)
- def isCaseClass = isClass && isCase
-
- // unfortunately having the CASEACCESSOR flag does not actually mean you
- // are a case accessor (you can also be a field.)
- def isCaseAccessorMethod = isMethod && isCaseAccessor
-
- def isMacro = isMethod && hasFlag(MACRO)
+ def isStable = false
/** Does this symbol denote the primary constructor of its enclosing class? */
final def isPrimaryConstructor =
@@ -635,25 +774,28 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
isMethod && isCase && isSynthetic
/** Is this symbol a trait which needs an implementation class? */
- final def needsImplClass: Boolean =
- isTrait && (!isInterface || hasFlag(lateINTERFACE)) && !isImplClass
+ final def needsImplClass = (
+ isTrait
+ && (!isInterface || hasFlag(lateINTERFACE))
+ && !isImplClass
+ )
/** Is this a symbol which exists only in the implementation class, not in its trait? */
- final def isImplOnly: Boolean =
- hasFlag(PRIVATE) ||
- (owner.isImplClass || owner.isTrait) &&
- ((hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR | MODULE) || isConstructor) ||
- (hasFlag(LIFTED) && isModule && isMethod))
-
- /** Is this symbol a module variable?
- * This used to have to test for MUTABLE to distinguish the overloaded
- * MODULEVAR/SYNTHETICMETH flag, but now SYNTHETICMETH is gone.
- */
+ final def isImplOnly = isPrivate || (
+ (owner.isTrait || owner.isImplClass) && (
+ hasAllFlags(LIFTED | MODULE | METHOD)
+ || isConstructor
+ || hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR | MODULE)
+ )
+ )
final def isModuleVar = hasFlag(MODULEVAR)
- /** Is this symbol static (i.e. with no outer instance)? */
- final def isStatic: Boolean =
- hasFlag(STATIC) || isRoot || owner.isStaticOwner
+ /** Is this symbol static (i.e. with no outer instance)?
+ * Q: When exactly is a sym marked as STATIC?
+ * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep.
+ * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6
+ */
+ def isStatic = (this hasFlag STATIC) || owner.isStaticOwner
/** Is this symbol a static constructor? */
final def isStaticConstructor: Boolean =
@@ -667,10 +809,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isStaticOwner: Boolean =
isPackageClass || isModuleClass && isStatic
+ def isTopLevelModule = hasFlag(MODULE) && owner.isPackageClass
+
/** Is this symbol effectively final? I.e, it cannot be overridden */
final def isEffectivelyFinal: Boolean = (
- isFinal
- || hasModuleFlag && !settings.overrideObjects.value
+ (this hasFlag FINAL | PACKAGE)
+ || isModuleOrModuleClass && (owner.isPackageClass || !settings.overrideObjects.value)
|| isTerm && (
isPrivate
|| isLocal
@@ -685,8 +829,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isConstant: Boolean = isStable && isConstantType(tpe.resultType)
/** Is this class nested in another class or module (not a package)? */
- final def isNestedClass: Boolean =
- isClass && !isRoot && !owner.isPackageClass
+ def isNestedClass = false
/** Is this class locally defined?
* A class is local, if
@@ -694,9 +837,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* - its owner is a value
* - it is defined within a local class
*/
- final def isLocalClass: Boolean =
- isClass && (isAnonOrRefinementClass || isLocal ||
- !owner.isPackageClass && owner.isLocalClass)
+ def isLocalClass = false
+
+ def isStableClass = false
/* code for fixing nested objects
override final def isModuleClass: Boolean =
@@ -707,6 +850,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isStructuralRefinement: Boolean =
(isClass || isType || isModule) && info.normalize/*.underlying*/.isStructuralRefinement
+ /** Is this a term symbol only defined in a refinement (so that it needs
+ * to be accessed by reflection)?
+ */
+ def isOnlyRefinementMember: Boolean =
+ isTerm && // type members are not affected
+ owner.isRefinementClass && // owner must be a refinement class
+ (owner.info decl name) == this && // symbol must be explicitly declared in the refinement (not synthesized from glb)
+ allOverriddenSymbols.isEmpty && // symbol must not override a symbol in a base class
+ !isConstant // symbol must not be a constant. Question: Can we exclude @inline methods as well?
+
final def isStructuralRefinementMember = owner.isStructuralRefinement && isPossibleInRefinement && isPublic
final def isPossibleInRefinement = !isConstructor && !isOverridingSymbol
@@ -731,25 +884,29 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// Does not always work if the rawInfo is a SourcefileLoader, see comment
// in "def coreClassesFirst" in Global.
- final def exists: Boolean =
- this != NoSymbol && (!owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType })
+ def exists = !owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType }
final def isInitialized: Boolean =
validTo != NoPeriod
- final def isStableClass: Boolean = {
- def hasNoAbstractTypeMember(clazz: Symbol): Boolean =
- (clazz hasFlag STABLE) || {
- var e = clazz.info.decls.elems
- while ((e ne null) && !(e.sym.isAbstractType && info.member(e.sym.name) == e.sym))
- e = e.next
- e == null
- }
- def checkStable() =
- (info.baseClasses forall hasNoAbstractTypeMember) && { setFlag(STABLE); true }
- isClass && (hasFlag(STABLE) || checkStable())
+ // [Eugene] is this correct?
+ /** Determines whether this symbol can be loaded by subsequent reflective compilation */
+ final def isLocatable: Boolean = {
+ if (this == NoSymbol) return false
+ if (isRoot || isRootPackage) return true
+
+ if (!owner.isLocatable) return false
+ if (owner.isTerm) return false
+ if (isLocalDummy) return false
+
+ if (isType && isNonClassType) return false
+ if (isRefinementClass) return false
+ return true
}
+ // [Eugene] is it a good idea to add ``dealias'' to Symbol?
+ /** Expands type aliases */
+ def dealias: Symbol = this
/** The variance of this symbol as an integer */
final def variance: Int =
@@ -757,7 +914,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isContravariant) -1
else 0
-
/** The sequence number of this parameter symbol among all type
* and value parameters of symbol's owner. -1 if symbol does not
* appear among the parameters of its owner.
@@ -781,6 +937,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ------ owner attribute --------------------------------------------------------------
def owner: Symbol = rawowner
+ // 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.)
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
@@ -790,17 +950,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else originalOwner(this) = rawowner
}
assert(!inReflexiveMirror, "owner_= is not thread-safe; cannot be run in reflexive code")
+ if (traceSymbolActivity)
+ traceSymbols.recordNewSymbolOwner(this, owner)
_rawowner = owner
}
def ownerChain: List[Symbol] = this :: owner.ownerChain
def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain
- def enclClassChain: List[Symbol] = {
- if ((this eq NoSymbol) || isPackageClass) Nil
- else if (isClass) this :: owner.enclClassChain
- else owner.enclClassChain
- }
+ // Non-classes skip self and return rest of owner chain; overridden in ClassSymbol.
+ def enclClassChain: List[Symbol] = owner.enclClassChain
def ownersIterator: Iterator[Symbol] = new Iterator[Symbol] {
private var current = Symbol.this
@@ -808,34 +967,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def next = { val r = current; current = current.owner; r }
}
- /** same as ownerChain contains sym, but more efficient, and
- * with a twist for refinement classes. A refinement class
- * has a transowner X if an of its parents has transowner X.
+ /** Same as `ownerChain contains sym` but more efficient, and
+ * with a twist for refinement classes (see RefinementClassSymbol.)
*/
def hasTransOwner(sym: Symbol): Boolean = {
var o = this
while ((o ne sym) && (o ne NoSymbol)) o = o.owner
- (o eq sym) ||
- isRefinementClass && (info.parents exists (_.typeSymbol.hasTransOwner(sym)))
+ (o eq sym)
}
// ------ name attribute --------------------------------------------------------------
- def name: Name = rawname
-
- def name_=(name: Name) {
- if (name != rawname) {
- if (owner.isClass) {
- var ifs = owner.infos
- while (ifs != null) {
- ifs.info.decls.rehash(this, name)
- ifs = ifs.prev
- }
- }
- _rawname = name
- }
- }
-
/** If this symbol has an expanded name, its original name, otherwise its name itself.
* @see expandName
*/
@@ -894,43 +1036,54 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
final def fullName: String = fullName('.')
-// ------ flags attribute --------------------------------------------------------------
+ /**
+ * Symbol creation implementations.
+ */
- final def flags: Long = {
- val fs = rawflags & phase.flagMask
- (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift)
- }
- def flags_=(fs: Long) = _rawflags = fs
+ protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol =
+ new AbstractTypeSymbol(this, pos, name) initFlags newFlags
- /** Set the symbol's flags to the given value, asserting
- * that the previous value was 0.
- */
- def initFlags(mask: Long): this.type = {
- assert(rawflags == 0L, this)
- _rawflags = mask
- this
- }
- def setFlag(mask: Long): this.type = { _rawflags = rawflags | mask ; this }
- def resetFlag(mask: Long): this.type = { _rawflags = rawflags & ~mask ; this }
- final def getFlag(mask: Long): Long = flags & mask
- final def resetFlags() { _rawflags = rawflags & TopLevelCreationFlags }
+ protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol =
+ new AliasTypeSymbol(this, pos, name) initFlags newFlags
- /** Does symbol have ANY flag in `mask` set? */
- final def hasFlag(mask: Long): Boolean = (flags & mask) != 0L
+ protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem =
+ new TypeSkolem(this, pos, name, origin) initFlags newFlags
- /** Does symbol have ALL the flags in `mask` set? */
- final def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask
+ protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol =
+ new ClassSymbol(this, pos, name) initFlags newFlags
- /** If the given flag is set on this symbol, also set the corresponding
- * notFLAG. For instance if flag is PRIVATE, the notPRIVATE flag will
- * be set if PRIVATE is currently set.
- */
- final def setNotFlag(flag: Int) = if (hasFlag(flag)) setFlag((flag: @annotation.switch) match {
- case PRIVATE => notPRIVATE
- case PROTECTED => notPROTECTED
- case OVERRIDE => notOVERRIDE
- case _ => abort("setNotFlag on invalid flag: " + flag)
- })
+ protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol =
+ new ModuleClassSymbol(this, pos, name) initFlags newFlags
+
+ protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol =
+ new PackageClassSymbol(this, pos, name) initFlags newFlags
+
+ protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol =
+ new RefinementClassSymbol(this, pos) initFlags newFlags
+
+ protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol =
+ new PackageObjectClassSymbol(this, pos) initFlags newFlags
+
+ protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol =
+ new ClassSymbol(this, pos, name) with ImplClassSymbol initFlags newFlags
+
+ protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol =
+ new TermSymbol(this, pos, name) initFlags newFlags
+
+ protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol =
+ new MethodSymbol(this, pos, name) initFlags newFlags
+
+ protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol =
+ new ModuleSymbol(this, pos, name) initFlags newFlags
+
+ protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol =
+ new PackageSymbol(this, pos, name) initFlags newFlags
+
+ protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol =
+ new TermSymbol(this, pos, name) initFlags newFlags
+
+ protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol =
+ new TermSymbol(this, pos, name) initFlags newFlags
/** The class or term up to which this symbol is accessible,
* or RootClass if it is public. As java protected statics are
@@ -969,6 +1122,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ------ info and type -------------------------------------------------------------------
private[Symbols] var infos: TypeHistory = null
+ def originalInfo = {
+ if (infos eq null) null
+ else {
+ var is = infos
+ while (is.prev ne null) { is = is.prev }
+ is.info
+ }
+ }
/** Get type. The type of a symbol is:
* for a type symbol, the type corresponding to the symbol itself,
@@ -993,7 +1154,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
val tp = infos.info
//if (settings.debug.value) System.out.println("completing " + this.rawname + tp.getClass());//debug
- if ((rawflags & LOCKED) != 0L) { // rolled out once for performance
+ if ((_rawflags & LOCKED) != 0L) { // rolled out once for performance
lock {
setInfo(ErrorType)
throw CyclicReference(this, tp)
@@ -1051,8 +1212,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Set new info valid from start of this phase. */
def updateInfo(info: Type): Symbol = {
- assert(phaseId(infos.validFrom) <= phase.id)
- if (phaseId(infos.validFrom) == phase.id) infos = infos.prev
+ val pid = phaseId(infos.validFrom)
+ assert(pid <= phase.id, (pid, phase.id))
+ if (pid == phase.id) infos = infos.prev
infos = TypeHistory(currentPeriod, info, infos)
_validTo = if (info.isComplete) currentPeriod else NoPeriod
this
@@ -1182,7 +1344,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* which immediately follows any of parser, namer, typer, or erasure.
* In effect that means this will return one of:
*
- * - packageobjects (follows namer)
+ * - packageobjects (follows namer)
* - superaccessors (follows typer)
* - lazyvals (follows erasure)
* - null
@@ -1192,9 +1354,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
while (ph.prev.keepsTypeParams)
ph = ph.prev
- if (ph ne phase)
- debuglog("checking unsafeTypeParams(" + this + ") at: " + phase + " reading at: " + ph)
-
ph
}
/** The type parameters of this symbol, without ensuring type completion.
@@ -1225,7 +1384,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The value parameter sections of this symbol.
*/
def paramss: List[List[Symbol]] = info.paramss
- def hasParamWhich(cond: Symbol => Boolean) = paramss exists (_ exists cond)
+ def hasParamWhich(cond: Symbol => Boolean) = mexists(paramss)(cond)
/** The least proper supertype of a class; includes all parent types
* and refinement where needed. You need to compute that in a situation like this:
@@ -1398,15 +1557,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ------ cloneing -------------------------------------------------------------------
/** A clone of this symbol. */
- final def cloneSymbol: Symbol =
+ final def cloneSymbol: TypeOfClonedSymbol =
cloneSymbol(owner)
/** A clone of this symbol, but with given owner. */
- final def cloneSymbol(newOwner: Symbol): Symbol =
- cloneSymbol(newOwner, this.rawflags)
- final def cloneSymbol(newOwner: Symbol, newFlags: Long): Symbol =
- cloneSymbol(newOwner, newFlags, nme.NO_NAME)
- final def cloneSymbol(newOwner: Symbol, newFlags: Long, newName: Name): Symbol = {
+ final def cloneSymbol(newOwner: Symbol): TypeOfClonedSymbol =
+ cloneSymbol(newOwner, _rawflags)
+ final def cloneSymbol(newOwner: Symbol, newFlags: Long): TypeOfClonedSymbol =
+ cloneSymbol(newOwner, newFlags, null)
+ final def cloneSymbol(newOwner: Symbol, newFlags: Long, newName: Name): TypeOfClonedSymbol = {
val clone = cloneSymbolImpl(newOwner, newFlags)
( clone
setPrivateWithin privateWithin
@@ -1415,15 +1574,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
if (clone.thisSym != clone)
clone.typeOfThis = (clone.typeOfThis cloneInfo clone)
- if (newName != nme.NO_NAME)
- clone.name = newName
+
+ if (newName ne null)
+ clone setName asNameType(newName)
clone
}
/** Internal method to clone a symbol's implementation with the given flags and no info. */
- def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol
- def cloneSymbolImpl(owner: Symbol): Symbol = cloneSymbolImpl(owner, 0L)
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeOfClonedSymbol
// ------ access to related symbols --------------------------------------------------
@@ -1434,14 +1593,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod
/** The primary constructor of a class. */
- def primaryConstructor: Symbol = {
- var c = info.decl(
- if (isTrait || isImplClass) nme.MIXIN_CONSTRUCTOR
- else nme.CONSTRUCTOR)
- c = if (c hasFlag OVERLOADED) c.alternatives.head else c
- //assert(c != NoSymbol)
- c
- }
+ def primaryConstructor: Symbol = NoSymbol
/** The self symbol (a TermSymbol) of a class with explicit self type, or else the
* symbol itself (a TypeSymbol).
@@ -1503,7 +1655,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* symbol with the same owner, and the name of this symbol with $class
* appended to it.
*/
- final def implClass: Symbol = owner.info.decl(nme.implClassName(name))
+ final def implClass: Symbol = owner.info.decl(tpnme.implClassName(name))
/** The class that is logically an outer class of given `clazz`.
* This is the enclosing class, except for classes defined locally to constructors,
@@ -1551,13 +1703,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The package class containing this symbol, or NoSymbol if there
* is not one. */
- def enclosingPackageClass: Symbol =
- if (this == NoSymbol) this else {
- var packSym = this.owner
- while (packSym != NoSymbol && !packSym.isPackageClass)
- packSym = packSym.owner
- packSym
- }
+ def enclosingPackageClass: Symbol = {
+ var packSym = this.owner
+ while (packSym != NoSymbol && !packSym.isPackageClass)
+ packSym = packSym.owner
+ packSym
+ }
/** The package containing this symbol, or NoSymbol if there
* is not one. */
@@ -1621,7 +1772,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
} else owner.enclosingTopLevelClass
/** Is this symbol defined in the same scope and compilation unit as `that` symbol? */
- def isCoDefinedWith(that: Symbol) = (
+ def isCoDefinedWith(that: Symbol) = {
+ import language.reflectiveCalls
(this.rawInfo ne NoType) &&
(this.effectiveOwner == that.effectiveOwner) && {
!this.effectiveOwner.isPackageClass ||
@@ -1640,7 +1792,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
false
}
}
- )
+ }
/** The internal representation of classes and objects:
*
@@ -1668,21 +1820,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* Note: does not work for classes owned by methods, see Namers.companionClassOf
*
* object Foo . companionClass --> class Foo
+ *
+ * !!! linkedClassOfClass depends on companionClass on the module class getting
+ * to the class. As presently implemented this potentially returns class for
+ * any symbol except NoSymbol.
*/
- final def companionClass: Symbol = {
- if (this != NoSymbol)
- flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this)
- else NoSymbol
- }
-
- /** A helper method that factors the common code used the discover a
- * companion module of a class. If a companion module exists, its symbol is
- * returned, otherwise, `NoSymbol` is returned. The method assumes that
- * `this` symbol has already been checked to be a class (using `isClass`).
- */
- private final def companionModule0: Symbol =
- flatOwnerInfo.decl(name.toTermName).suchThat(
- sym => sym.hasFlag(MODULE) && (sym isCoDefinedWith this) && !sym.isMethod)
+ def companionClass: Symbol = flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this)
/** For a class: the module or case class factory with the same name in the same package.
* For all others: NoSymbol
@@ -1690,9 +1833,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*
* class Foo . companionModule --> object Foo
*/
- final def companionModule: Symbol =
- if (isClass && !isRefinementClass) companionModule0
- else NoSymbol
+ def companionModule: Symbol = NoSymbol
/** For a module: its linked class
* For a plain class: its linked module or case factory.
@@ -1700,18 +1841,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*
* class Foo <-- companionSymbol --> object Foo
*/
- final def companionSymbol: Symbol =
- if (isTerm) companionClass
- else if (isClass) companionModule0
- else NoSymbol
+ def companionSymbol: Symbol = NoSymbol
/** For a module class: its linked class
* For a plain class: the module class of its linked module.
*
* class Foo <-- linkedClassOfClass --> class Foo$
*/
- final def linkedClassOfClass: Symbol =
- if (isModuleClass) companionClass else companionModule.moduleClass
+ def linkedClassOfClass: Symbol = NoSymbol
/**
* Returns the rawInfo of the owner. If the current phase has flat classes,
@@ -1724,7 +1861,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* symbol B in the decls of p. So to find a linked symbol ("object B" or "class B")
* we need to apply flatten to B first. Fixes #2470.
*/
- private final def flatOwnerInfo: Type = {
+ protected final def flatOwnerInfo: Type = {
if (needsFlatClasses)
info
owner.rawInfo
@@ -1738,18 +1875,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* This only works for implementation classes owned by other classes or traits.
* !!! Why?
*/
- final def toInterface: Symbol =
- if (isImplClass) {
- val result =
- if (phase.next.erasedTypes) {
- assert(!tpe.parents.isEmpty, this)
- tpe.parents.last.typeSymbol
- } else {
- owner.info.decl(nme.interfaceName(name))
- }
- assert(result != NoSymbol, this)
- result
- } else this
+ def toInterface: Symbol = this
/** The module class corresponding to this module.
*/
@@ -1770,7 +1896,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
site.nonPrivateMemberAdmitting(name, admit).filter(sym =>
!sym.isTerm || (site.memberType(this) matches site.memberType(sym)))
- /** The symbol overridden by this symbol in given class `ofclazz`.
+ /** The symbol, in class `ofclazz`, that is overridden by this symbol.
*
* @param ofclazz is a base class of this symbol's owner.
*/
@@ -1872,7 +1998,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def unpackLocation: AnyRef = null
/** Remove private modifier from symbol `sym`s definition. If `sym` is a
- * term symbol rename it by expanding its name to avoid name clashes
+ * is not a constructor nor a static module rename it by expanding its name to avoid name clashes
+ * @param base the fully qualified name of this class will be appended if name expansion is needed
*/
final def makeNotPrivate(base: Symbol) {
if (this.isPrivate) {
@@ -1902,23 +2029,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case p :: _ => p
case _ => NoSymbol
}
-
- /** change name by appending $$<fully-qualified-name-of-class `base`>
- * Do the same for any accessed symbols or setters/getters
- */
- def expandName(base: Symbol) {
- if (this.isTerm && this != NoSymbol && !hasFlag(EXPANDEDNAME)) {
- setFlag(EXPANDEDNAME)
- if (hasAccessorFlag && !isDeferred) {
- accessed.expandName(base)
- } else if (hasGetter) {
- getter(owner).expandName(base)
- setter(owner).expandName(base)
- }
- name = nme.expandedName(name.toTermName, base)
- if (isType) name = name
- }
- }
/* code for fixing nested objects
def expandModuleClassName() {
name = newTypeName(name.toString + "$")
@@ -1943,7 +2053,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this
- def orElse[T](alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt
+ @inline final def orElse[T](alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt
// ------ toString -------------------------------------------------------------------
@@ -1975,8 +2085,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private case class SymbolKind(accurate: String, sanitized: String, abbreviation: String)
private def symbolKind: SymbolKind = {
- val kind =
- if (isInstanceOf[FreeVar]) ("free variable", "free variable", "FV")
+ var kind =
+ if (isTermMacro) ("macro method", "macro method", "MAC")
+ else if (isInstanceOf[FreeTerm]) ("free term", "free term", "FTE")
+ else if (isInstanceOf[FreeType]) ("free type", "free type", "FTY")
else if (isPackage) ("package", "package", "PK")
else if (isPackageClass) ("package class", "package", "PKC")
else if (isPackageObject) ("package object", "package", "PKO")
@@ -1997,6 +2109,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isSourceMethod) ("method", "method", "METH")
else if (isTerm) ("value", "value", "VAL")
else ("", "", "???")
+ if (isSkolem) kind = (kind._1, kind._2, kind._3 + "#SKO")
SymbolKind(kind._1, kind._2, kind._3)
}
@@ -2044,7 +2157,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def fullNameString: String = {
def recur(sym: Symbol): String = {
- if (sym.isRoot || sym.isRootPackage || sym == NoSymbol) sym.nameString
+ if (sym.isRootSymbol || sym == NoSymbol) sym.nameString
else if (sym.owner.isEffectiveRoot) sym.nameString
else recur(sym.effectiveOwner.enclClass) + "." + sym.nameString
}
@@ -2094,7 +2207,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case rt => " <: " + rt
}
)
- else if (isModule) moduleClass.infoString(tp)
+ else if (isModule) "" // avoid "object X of type X.type"
else tp match {
case PolyType(tparams, res) => typeParamsString(tp) + infoString(res)
case NullaryMethodType(res) => infoString(res)
@@ -2105,32 +2218,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def infosString = infos.toString
def debugLocationString = fullLocationString + " " + debugFlagString
- def debugFlagString = hasFlagsToString(-1L)
- def hasFlagsToString(mask: Long): String = flagsToString(
- flags & mask,
- if (hasAccessBoundary) privateWithin.toString else ""
- )
-
- /** String representation of symbol's variance */
- def varianceString: String =
- if (variance == 1) "+"
- else if (variance == -1) "-"
- else ""
-
- def defaultFlagMask =
- if (settings.debug.value) -1L
- else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE
- else ExplicitFlags
-
- // make the error message more googlable
- def flagsExplanationString =
- if (isGADTSkolem) " (this is a GADT skolem)"
- else ""
- def accessString = hasFlagsToString(PRIVATE | PROTECTED | LOCAL)
- def defaultFlagString = hasFlagsToString(defaultFlagMask)
private def defStringCompose(infoString: String) = compose(
- defaultFlagString,
+ flagString,
keyString,
varianceString + nameString + infoString + flagsExplanationString
)
@@ -2153,26 +2243,88 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** String representation of existentially bound variable */
def existentialToString =
if (isSingletonExistential && !settings.debug.value)
- "val " + nme.dropSingletonName(name) + ": " + dropSingletonType(info.bounds.hi)
+ "val " + tpnme.dropSingletonName(name) + ": " + dropSingletonType(info.bounds.hi)
else defString
}
/** A class for term symbols */
class TermSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
- extends Symbol(initOwner, initPos, initName) {
+ extends Symbol(initOwner, initPos, initName) with TermSymbolApi {
+ private[this] var _referenced: Symbol = NoSymbol
+ privateWithin = NoSymbol
+
+ final type NameType = TermName
+ type TypeOfClonedSymbol = TermSymbol
+
+ private[this] var _rawname: TermName = initName
+ def rawname = _rawname
+ def name = _rawname
+ def name_=(name: Name) {
+ if (name != rawname) {
+ log("Renaming %s %s %s to %s".format(shortSymbolClass, debugFlagString, rawname, name))
+ changeNameInOwners(name)
+ _rawname = name.toTermName
+ }
+ }
+ final def asNameType(n: Name) = n.toTermName
+
final override def isTerm = true
- override def name: TermName = rawname.toTermName
- privateWithin = NoSymbol
+ /** Term symbols with the exception of static parts of Java classes and packages.
+ */
+ override def isValue = !(isModule && hasFlag(PACKAGE | JAVA))
+ override def isVariable = isMutable && !isMethod
+ override def isTermMacro = hasFlag(MACRO)
- private[this] var _referenced: Symbol = NoSymbol
+ // interesting only for lambda lift. Captured variables are accessed from inner lambdas.
+ override def isCapturedVariable = hasAllFlags(MUTABLE | CAPTURED) && !hasFlag(METHOD)
+
+ override def companionSymbol: Symbol = companionClass
+ override def moduleClass = if (isModule) referenced else NoSymbol
+
+ override def hasDefault = this hasFlag DEFAULTPARAM // overloaded with TRAIT
+ override def isBridge = this hasFlag BRIDGE
+ override def isEarlyInitialized = this hasFlag PRESUPER
+ override def isMethod = this hasFlag METHOD
+ override def isModule = this hasFlag MODULE
+ override def isOverloaded = this hasFlag OVERLOADED
+ override def isPackage = this hasFlag PACKAGE
+ override def isValueParameter = this hasFlag PARAM
+
+ override def isSetterParameter = isValueParameter && owner.isSetter
+ override def isAccessor = this hasFlag ACCESSOR
+ override def isGetter = isAccessor && !isSetter
+ override def isSetter = isAccessor && nme.isSetterName(name) // todo: make independent of name, as this can be forged.
+ override def isLocalDummy = nme.isLocalDummyName(name)
+ override def isClassConstructor = name == nme.CONSTRUCTOR
+ override def isMixinConstructor = name == nme.MIXIN_CONSTRUCTOR
+ override def isConstructor = nme.isConstructorName(name)
+
+ override def isPackageObject = isModule && (name == nme.PACKAGE)
+ override def isStable = !isUnstable
+ private def isUnstable = (
+ isMutable
+ || (hasFlag(METHOD | BYNAMEPARAM) && !hasFlag(STABLE))
+ || (tpe.isVolatile && !hasAnnotation(uncheckedStableClass))
+ )
+
+ // The name in comments is what it is being disambiguated from.
+ // TODO - rescue CAPTURED from BYNAMEPARAM so we can see all the names.
+ override def resolveOverloadedFlag(flag: Long) = flag match {
+ case DEFAULTPARAM => "<defaultparam>" // TRAIT
+ case MIXEDIN => "<mixedin>" // EXISTENTIAL
+ case LABEL => "<label>" // CONTRAVARIANT / INCONSTRUCTOR
+ case PRESUPER => "<presuper>" // IMPLCLASS
+ case BYNAMEPARAM => if (this.isValueParameter) "<bynameparam>" else "<captured>" // COVARIANT
+ case _ => super.resolveOverloadedFlag(flag)
+ }
def referenced: Symbol = _referenced
def referenced_=(x: Symbol) { _referenced = x }
def existentialBound = singletonBounds(this.tpe)
- def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): TermSymbol =
owner.newTermSymbol(name, pos, newFlags).copyAttrsFrom(this)
def copyAttrsFrom(original: TermSymbol): this.type = {
@@ -2196,14 +2348,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
override def outerSource: Symbol =
- if (name endsWith nme.OUTER) initialize.referenced
+ if (originalName == nme.OUTER) initialize.referenced
else NoSymbol
- override def moduleClass: Symbol =
- if (hasFlag(MODULE)) referenced else NoSymbol
-
def setModuleClass(clazz: Symbol): TermSymbol = {
- assert(hasFlag(MODULE), this)
+ assert(isModule, this)
referenced = clazz
this
}
@@ -2219,6 +2368,23 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
referenced
}
+ /** change name by appending $$<fully-qualified-name-of-class `base`>
+ * Do the same for any accessed symbols or setters/getters
+ */
+ override def expandName(base: Symbol) {
+ if (!hasFlag(EXPANDEDNAME)) {
+ setFlag(EXPANDEDNAME)
+ if (hasAccessorFlag && !isDeferred) {
+ accessed.expandName(base)
+ }
+ else if (hasGetter) {
+ getter(owner).expandName(base)
+ setter(owner).expandName(base)
+ }
+ name = nme.expandedName(name.toTermName, base)
+ }
+ }
+
protected def doCookJavaRawInfo() {
def cook(sym: Symbol) {
require(sym.isJavaDefined, sym)
@@ -2252,9 +2418,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A class for module symbols */
class ModuleSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
- extends TermSymbol(initOwner, initPos, initName) {
+ extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag with ModuleSymbolApi {
+ def distinguishingFlag = MODULE
private var flatname: TermName = null
+ override def isModule = true
+ override def moduleClass = referenced
+ override def companionClass =
+ flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this)
+
override def owner = (
if (!isMethod && needsFlatClasses) rawowner.owner
else rawowner
@@ -2266,23 +2438,41 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
flatname
}
- else rawname.toTermName
+ else rawname
)
+ }
- override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
- owner.newModuleSymbol(name, pos, newFlags).copyAttrsFrom(this)
+ class PackageSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TermName)
+ extends ModuleSymbol(owner0, pos0, name0) with DistinguishingFlag with PackageSymbolApi {
+ override def distinguishingFlag = super.distinguishingFlag | PACKAGE
+ override def isPackage = true
}
/** A class for method symbols */
class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
- extends TermSymbol(initOwner, initPos, initName) {
- private var mtpePeriod = NoPeriod
- private var mtpePre: Type = _
- private var mtpeResult: Type = _
- private var mtpeInfo: Type = _
-
- override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
- owner.newMethodSymbol(name, pos, newFlags).copyAttrsFrom(this)
+ extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag with MethodSymbolApi {
+ def distinguishingFlag = METHOD
+ // MethodSymbols pick up MODULE when trait-owned object accessors are cloned
+ // during mixin composition.
+ override protected def neverHasFlags = super.neverHasFlags & ~MODULE
+
+ private[this] var mtpePeriod = NoPeriod
+ private[this] var mtpePre: Type = _
+ private[this] var mtpeResult: Type = _
+ private[this] var mtpeInfo: Type = _
+
+ override def isMethod = true
+ override def isLabel = this hasFlag LABEL
+ override def isVarargsMethod = this hasFlag VARARGS
+ override def isLiftedMethod = this hasFlag LIFTED
+
+ // TODO - this seems a strange definition for "isSourceMethod", given that
+ // it does not make any specific effort to exclude synthetics. Figure out what
+ // this method is really for and what logic makes sense.
+ override def isSourceMethod = !(this hasFlag STABLE) // exclude all accessors
+ // unfortunately having the CASEACCESSOR flag does not actually mean you
+ // are a case accessor (you can also be a field.)
+ override def isCaseAccessorMethod = isCaseAccessor
def typeAsMemberOf(pre: Type): Type = {
if (mtpePeriod == currentPeriod) {
@@ -2302,73 +2492,80 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName)
extends TypeSymbol(initOwner, initPos, initName) {
- // Temporary programmatic help tracking down who might do such a thing
- override def setFlag(mask: Long): this.type = {
- if (isSetting(DEFERRED, mask)) {
- println("Setting DEFERRED on alias at")
- (new Throwable).printStackTrace
- }
- super.setFlag(mask)
- }
+ type TypeOfClonedSymbol = TypeSymbol
final override def isAliasType = true
- override def cloneSymbolImpl(owner: Symbol, newFlags: Long): AliasTypeSymbol =
- owner.newAliasTypeSymbol(name, pos, newFlags)
- }
-
- class AbstractTypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
- extends TypeSymbol(initOwner, initPos, initName) with AbstractTypeMixin {
- override def cloneSymbolImpl(owner: Symbol, newFlags: Long): AbstractTypeSymbol =
- owner.newAbstractTypeSymbol(name, pos, newFlags)
+ final override def dealias = info.typeSymbol.dealias
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSymbol =
+ owner.newNonClassSymbol(name, pos, newFlags)
}
- /** Might be mixed into TypeSymbol or TypeSkolem.
- */
- trait AbstractTypeMixin extends TypeSymbol {
- override def resetFlag(mask: Long): this.type = {
- // Temporary programmatic help tracking down who might do such a thing
- if (settings.debug.value) {
- if (isClearing(DEFERRED, mask)) {
- println("Clearing DEFERRED on abstract type at")
- (new Throwable).printStackTrace
- }
- }
- super.resetFlag(mask)
- }
+ class AbstractTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName)
+ extends TypeSymbol(initOwner, initPos, initName) {
+ type TypeOfClonedSymbol = TypeSymbol
final override def isAbstractType = true
override def existentialBound = this.info
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSymbol =
+ owner.newNonClassSymbol(name, pos, newFlags)
}
/** A class of type symbols. Alias and abstract types are direct instances
* of this class. Classes are instances of a subclass.
*/
- abstract class TypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends Symbol(initOwner, initPos, initName) {
+ abstract class TypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName)
+ extends Symbol(initOwner, initPos, initName) with TypeSymbolApi {
privateWithin = NoSymbol
+ private[this] var _rawname: TypeName = initName
+
+ final type NameType = TypeName
+ type TypeOfClonedSymbol >: Null <: TypeSymbol
+ // cloneSymbolImpl still abstract in TypeSymbol.
+
+ def rawname = _rawname
+ def name = _rawname
+ final def asNameType(n: Name) = n.toTypeName
+
+ final override def isType = true
+ override def isNonClassType = true
+ override def isTypeMacro = hasFlag(MACRO)
+
+ override def resolveOverloadedFlag(flag: Long) = flag match {
+ case TRAIT => "<trait>" // DEFAULTPARAM
+ case EXISTENTIAL => "<existential>" // MIXEDIN
+ case COVARIANT => "<covariant>" // BYNAMEPARAM / CAPTURED
+ case CONTRAVARIANT => "<contravariant>" // LABEL / INCONSTRUCTOR (overridden again in ClassSymbol)
+ case _ => super.resolveOverloadedFlag(flag)
+ }
+
private var tyconCache: Type = null
private var tyconRunId = NoRunId
private var tpeCache: Type = _
private var tpePeriod = NoPeriod
+ override def isAbstractType = this hasFlag DEFERRED
+ override def isContravariant = this hasFlag CONTRAVARIANT
+ override def isCovariant = this hasFlag COVARIANT
+ override def isExistentialQuantified = isExistentiallyBound && !isSkolem
+ override def isExistentiallyBound = this hasFlag EXISTENTIAL
+ override def isTypeParameter = isTypeParameterOrSkolem && !isSkolem
+ override def isTypeParameterOrSkolem = this hasFlag PARAM
+
/** Overridden in subclasses for which it makes sense.
*/
def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+debugLocationString)
- override def name: TypeName = super.name.toTypeName
- final override def isType = true
- override def isNonClassType = true
- override def isAbstractType = {
- if (settings.debug.value) {
- if (isDeferred) {
- println("TypeSymbol claims to be abstract type: " + this.getClass + " " + debugFlagString + " at ")
- (new Throwable).printStackTrace
- }
+ // TODO - don't allow names to be renamed in this unstructured a fashion.
+ // Rename as little as possible. Enforce invariants on all renames.
+ def name_=(name: Name) {
+ if (name != rawname) {
+ log("Renaming %s %s %s to %s".format(shortSymbolClass, debugFlagString, rawname, name))
+ changeNameInOwners(name)
+ _rawname = name.toTypeName
}
- isDeferred
- }
- private def newTypeRef(targs: List[Type]) = {
- val pre = if (hasFlag(PARAM | EXISTENTIAL)) NoPrefix else owner.thisType
- typeRef(pre, this, targs)
}
+ private def newPrefix = if (this hasFlag EXISTENTIAL | PARAM) NoPrefix else owner.thisType
+ private def newTypeRef(targs: List[Type]) = typeRef(newPrefix, this, targs)
+
/** Let's say you have a type definition
*
* {{{
@@ -2460,9 +2657,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
- def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
- owner.newTypeSymbol(name, pos, newFlags)
-
incCounter(typeSymbolCount)
}
@@ -2481,12 +2675,22 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
class TypeSkolem protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName, origin: AnyRef)
extends TypeSymbol(initOwner, initPos, initName) {
-
+ type TypeOfClonedSymbol = TypeSkolem
/** The skolemization level in place when the skolem was constructed */
val level = skolemizationLevel
final override def isSkolem = true
+ // a type symbol bound by an existential type, for instance the T in
+ // List[T] forSome { type T }
+ override def isExistentialSkolem = this hasFlag EXISTENTIAL
+ override def isGADTSkolem = this hasFlag CASEACCESSOR | SYNTHETIC
+ override def isTypeSkolem = this hasFlag PARAM
+ override def isAbstractType = this hasFlag DEFERRED
+
+ override def isExistentialQuantified = false
+ override def existentialBound = if (isAbstractType) this.info else super.existentialBound
+
/** If typeskolem comes from a type parameter, that parameter, otherwise skolem itself */
override def deSkolemize = origin match {
case s: Symbol => s
@@ -2499,7 +2703,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
//@M! (not deSkolemize.typeParams!!), also can't leave superclass definition: use info, not rawInfo
override def typeParams = info.typeParams
- override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSkolem =
owner.newTypeSkolemSymbol(name, origin, pos, newFlags)
override def nameString: String =
@@ -2509,18 +2713,110 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A class for class symbols */
class ClassSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName)
- extends TypeSymbol(initOwner, initPos, initName) {
- private[this] var flatname: TypeName = null
- private[this] var source: AbstractFileType = null
- private[this] var thissym: Symbol = this
+ extends TypeSymbol(initOwner, initPos, initName) with ClassSymbolApi {
+ type TypeOfClonedSymbol = ClassSymbol
+
+ private[this] var flatname: TypeName = _
+ private[this] var source: AbstractFileType = _
+ private[this] var thissym: Symbol = this
+
+ private[this] var thisTypeCache: Type = _
+ private[this] var thisTypePeriod = NoPeriod
+
+ override protected def alwaysHasFlags: Long = 0L
+ override protected def neverHasFlags: Long = 0L
+
+ override def resolveOverloadedFlag(flag: Long) = flag match {
+ case INCONSTRUCTOR => "<inconstructor>" // INCONSTRUCTOR / CONTRAVARIANT / LABEL
+ case EXISTENTIAL => "<existential>" // EXISTENTIAL / MIXEDIN
+ case IMPLCLASS => "<implclass>" // IMPLCLASS / PRESUPER
+ case _ => super.resolveOverloadedFlag(flag)
+ }
final override def isClass = true
final override def isNonClassType = false
final override def isAbstractType = false
final override def isAliasType = false
+ override def isAbstractClass = this hasFlag ABSTRACT
+ override def isCaseClass = this hasFlag CASE
+ override def isClassLocalToConstructor = this hasFlag INCONSTRUCTOR
+ override def isImplClass = this hasFlag IMPLCLASS
+ override def isModuleClass = this hasFlag MODULE
+ override def isPackageClass = this hasFlag PACKAGE
+ override def isTrait = this hasFlag TRAIT
+
+ override def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
+ override def isAnonymousClass = name containsName tpnme.ANON_CLASS_NAME
+ override def isConcreteClass = !(this hasFlag ABSTRACT | TRAIT)
+ override def isJavaInterface = hasAllFlags(JAVA | TRAIT)
+ override def isNestedClass = !owner.isPackageClass
+ override def isNumericValueClass = definitions.isNumericValueClass(this)
+ override def isPackageObjectClass = isModuleClass && (name == tpnme.PACKAGE)
+ override def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this)
+
+ // The corresponding interface is the last parent by convention.
+ private def lastParent = if (tpe.parents.isEmpty) NoSymbol else tpe.parents.last.typeSymbol
+ override def toInterface: Symbol = (
+ if (isImplClass) {
+ if (phase.next.erasedTypes) lastParent
+ else owner.info.decl(tpnme.interfaceName(name))
+ }
+ else super.toInterface
+ )
+
+ /** Is this class locally defined?
+ * A class is local, if
+ * - it is anonymous, or
+ * - its owner is a value
+ * - it is defined within a local class
+ */
+ override def isLocalClass = (
+ isAnonOrRefinementClass
+ || isLocal
+ || !owner.isPackageClass && owner.isLocalClass
+ )
+ override def isStableClass = (this hasFlag STABLE) || checkStable()
+
+ private def checkStable() = {
+ def hasNoAbstractTypeMember(clazz: Symbol): Boolean =
+ (clazz hasFlag STABLE) || {
+ var e = clazz.info.decls.elems
+ while ((e ne null) && !(e.sym.isAbstractType && info.member(e.sym.name) == e.sym))
+ e = e.next
+ e == null
+ }
+ (info.baseClasses forall hasNoAbstractTypeMember) && {
+ setFlag(STABLE)
+ true
+ }
+ }
+
+ override def enclClassChain = this :: owner.enclClassChain
+
+ /** A helper method that factors the common code used the discover a
+ * companion module of a class. If a companion module exists, its symbol is
+ * returned, otherwise, `NoSymbol` is returned.
+ */
+ protected final def companionModule0: Symbol =
+ flatOwnerInfo.decl(name.toTermName).suchThat(
+ sym => sym.hasFlag(MODULE) && (sym isCoDefinedWith this) && !sym.isMethod)
+
+ override def companionModule = companionModule0
+ override def companionSymbol = companionModule0
+ override def linkedClassOfClass = companionModule.moduleClass
+
+ override def sourceModule = if (isModuleClass) companionModule else NoSymbol
+
override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound))
+ def primaryConstructorName = if (this hasFlag TRAIT | IMPLCLASS) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR
+
+ override def primaryConstructor = {
+ val c = info decl primaryConstructorName
+ if (c.isOverloaded) c.alternatives.head else c
+ }
+
override def sourceFile =
if (owner.isPackageClass) source
else super.sourceFile
@@ -2531,12 +2827,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
thissym = this
}
- private var thisTypeCache: Type = _
- private var thisTypePeriod = NoPeriod
-
- private var typeOfThisCache: Type = _
- private var typeOfThisPeriod = NoPeriod
-
/** the type this.type in this class */
override def thisType: Type = {
val period = thisTypePeriod
@@ -2549,6 +2839,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def owner: Symbol =
if (needsFlatClasses) rawowner.owner else rawowner
+
override def name: TypeName = (
if (needsFlatClasses) {
if (flatname eq null)
@@ -2556,47 +2847,28 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
flatname
}
- else rawname.toTypeName
+ else rawname
)
/** A symbol carrying the self type of the class as its type */
override def thisSym: Symbol = thissym
- /** the self type of an object foo is foo.type, not class<foo>.this.type
- */
- override def typeOfThis: Type = {
- if (getFlag(MODULE | IMPLCLASS) == MODULE.toLong && owner != NoSymbol) {
- val period = typeOfThisPeriod
- if (period != currentPeriod) {
- typeOfThisPeriod = currentPeriod
- if (!isValid(period))
- typeOfThisCache = singleType(owner.thisType, sourceModule)
- }
- typeOfThisCache
- }
- else thisSym.tpe
- }
-
/** Sets the self type of the class */
override def typeOfThis_=(tp: Type) {
- thissym = newThisSym(pos).setInfo(tp)
+ thissym = newThisSym(nme.this_, pos).setInfo(tp)
}
- override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = {
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): ClassSymbol = {
val clone = owner.newClassSymbol(name, pos, newFlags)
if (thisSym != this) {
clone.typeOfThis = typeOfThis
- clone.thisSym.name = thisSym.name
+ clone.thisSym setName thisSym.name
}
clone
}
- override def sourceModule =
- if (isModuleClass) companionModule else NoSymbol
-
override def firstParamAccessor =
- info.decls.find(m => (m hasFlag PARAMACCESSOR) && m.isMethod) getOrElse NoSymbol
-
+ info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse NoSymbol
private[this] var childSet: Set[Symbol] = Set()
override def children = childSet
@@ -2610,12 +2882,32 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* plain class symbols!
*/
class ModuleClassSymbol protected[Symbols] (owner: Symbol, pos: Position, name: TypeName)
- extends ClassSymbol(owner, pos, name) {
- private var module: Symbol = null
- private var implicitMembersCacheValue: List[Symbol] = List()
+ extends ClassSymbol(owner, pos, name) with DistinguishingFlag {
+ private[this] var module: Symbol = _
+ private[this] var typeOfThisCache: Type = _
+ private[this] var typeOfThisPeriod = NoPeriod
+
+ def distinguishingFlag = MODULE
+
+ private var implicitMembersCacheValue: List[Symbol] = Nil
private var implicitMembersCacheKey1: Type = NoType
private var implicitMembersCacheKey2: ScopeEntry = null
+ override def isModuleClass = true
+ override def linkedClassOfClass = companionClass
+
+ /** the self type of an object foo is foo.type, not class<foo>.this.type
+ */
+ override def typeOfThis = {
+ val period = typeOfThisPeriod
+ if (period != currentPeriod) {
+ typeOfThisPeriod = currentPeriod
+ if (!isValid(period))
+ typeOfThisCache = singleType(owner.thisType, sourceModule)
+ }
+ typeOfThisCache
+ }
+
def implicitMembers: List[Symbol] = {
val tp = info
if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) {
@@ -2629,20 +2921,79 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
implicitMembersCacheValue
}
- override def sourceModule = module
+ // The null check seems to be necessary for the reifier.
+ override def sourceModule = if (module ne null) module else companionModule
override def sourceModule_=(module: Symbol) { this.module = module }
}
- class FreeVar(name0: TermName, val value: Any) extends TermSymbol(NoSymbol, NoPosition, name0) {
- override def hashCode = if (value == null) 0 else value.hashCode
- override def equals(other: Any): Boolean = other match {
- case that: FreeVar => this.value.asInstanceOf[AnyRef] eq that.value.asInstanceOf[AnyRef]
- case _ => false
+ class PackageObjectClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position)
+ extends ModuleClassSymbol(owner0, pos0, tpnme.PACKAGE) {
+ final override def isPackageObjectClass = true
+ final override def isPackageObjectOrClass = true
+ final override def skipPackageObject = owner
+ final override def setName(name: Name): this.type = {
+ abort("Can't rename a package object to " + name)
}
}
+ trait ImplClassSymbol extends ClassSymbol {
+ override def sourceModule = companionModule
+ // override def isImplClass = true
+ override def typeOfThis = thisSym.tpe // don't use the ModuleClassSymbol typeOfThisCache.
+ }
+
+ class PackageClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TypeName)
+ extends ModuleClassSymbol(owner0, pos0, name0) with DistinguishingFlag {
+ override def distinguishingFlag = super.distinguishingFlag | PACKAGE
+ override def sourceModule = companionModule
+ override def enclClassChain = Nil
+ override def isPackageClass = true
+ }
+
+ class RefinementClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position)
+ extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) {
+ override def name_=(name: Name) {
+ assert(false, "Cannot set name of RefinementClassSymbol to " + name)
+ super.name_=(name)
+ }
+ override def isRefinementClass = true
+ override def isAnonOrRefinementClass = true
+ override def isLocalClass = true
+ override def hasMeaninglessName = true
+ override def companionModule: Symbol = NoSymbol
+
+ /** The mentioned twist. A refinement class has transowner X
+ * if any of its parents has transowner X.
+ */
+ override def hasTransOwner(sym: Symbol) = (
+ super.hasTransOwner(sym)
+ || info.parents.exists(_.typeSymbol hasTransOwner sym)
+ )
+ }
+
+ trait FreeSymbol extends Symbol {
+ def origin: String
+ }
+ class FreeTerm(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) with FreeSymbol {
+ def value = value0
+ override def isFreeTerm = true
+ }
+
+ class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol {
+ def value = value0
+ override def isFreeType = true
+ }
+
/** An object representing a missing symbol */
class NoSymbol protected[Symbols]() extends Symbol(null, NoPosition, nme.NO_NAME) {
+ final type NameType = TermName
+ type TypeOfClonedSymbol = NoSymbol
+
+ def asNameType(n: Name) = n.toTermName
+ def rawname = nme.NO_NAME
+ def name = nme.NO_NAME
+ def name_=(n: Name) = abort("Cannot set NoSymbol's name to " + n)
+
synchronized {
setInfo(NoType)
privateWithin = this
@@ -2652,12 +3003,20 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
unlock()
validTo = currentPeriod
}
+ override def flagMask = AllFlags
+ override def exists = false
+ override def isHigherOrderTypeParameter = false
+ override def companionClass = NoSymbol
+ override def companionModule = NoSymbol
+ override def companionSymbol = NoSymbol
override def isSubClass(that: Symbol) = false
override def filter(cond: Symbol => Boolean) = this
override def defString: String = toString
override def locationString: String = ""
+ override def enclClassChain = Nil
override def enclClass: Symbol = this
override def enclosingTopLevelClass: Symbol = this
+ override def enclosingPackageClass: Symbol = this
override def enclMethod: Symbol = this
override def sourceFile: AbstractFileType = null
override def ownerChain: List[Symbol] = List()
@@ -2669,7 +3028,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def rawInfo: Type = NoType
protected def doCookJavaRawInfo() {}
override def accessBoundary(base: Symbol): Symbol = RootClass
- def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = abort("NoSymbol.clone()")
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long) = abort("NoSymbol.clone()")
override def originalEnclosingMethod = this
override def owner: Symbol =
@@ -2678,9 +3037,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
abort("no-symbol does not have a type constructor (this may indicate scalac cannot find fundamental classes)")
}
- protected def makeNoSymbol = new NoSymbol
+ protected def makeNoSymbol: NoSymbol = new NoSymbol
- lazy val NoSymbol = makeNoSymbol
+ lazy val NoSymbol: NoSymbol = makeNoSymbol
/** Derives a new list of symbols from the given list by mapping the given
* list across the given function. Then fixes the info of all the new symbols
@@ -2758,20 +3117,22 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (settings.debug.value) printStackTrace()
}
- case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable(
+ case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable({
+ import language.reflectiveCalls
"Companions '" + sym1 + "' and '" + sym2 + "' must be defined in same file:\n" +
" Found in " + sym1.sourceFile.canonicalPath + " and " + sym2.sourceFile.canonicalPath
- ) {
+ }) {
override def toString = getMessage
}
/** A class for type histories */
private sealed case class TypeHistory(var validFrom: Period, info: Type, prev: TypeHistory) {
assert((prev eq null) || phaseId(validFrom) > phaseId(prev.validFrom), this)
- assert(validFrom != NoPeriod)
+ assert(validFrom != NoPeriod, this)
+
override def toString() =
"TypeHistory(" + phaseOf(validFrom)+":"+runId(validFrom) + "," + info + "," + prev + ")"
-
+
def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList )
}
}
diff --git a/src/compiler/scala/reflect/internal/TreeBuildUtil.scala b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala
new file mode 100644
index 0000000000..d4d4652e91
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala
@@ -0,0 +1,66 @@
+package scala.reflect
+package internal
+
+import Flags._
+
+trait TreeBuildUtil extends api.TreeBuildUtil { self: SymbolTable =>
+
+ // ``staticClass'' and ``staticModule'' rely on ClassLoaders
+ // which are implementation-specific for different Universes
+
+ def staticClassIfDefined(fullName: String): Symbol =
+ try staticClass(fullName)
+ catch { case _: MissingRequirementError => NoSymbol }
+
+ def staticModuleIfDefined(fullName: String): Symbol =
+ try staticModule(fullName)
+ catch { case _: MissingRequirementError => NoSymbol }
+
+ def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.thisType
+
+ def selectType(owner: Symbol, name: String): Symbol =
+ owner.info.decl(newTypeName(name)) orElse {
+ MissingRequirementError.notFound("type %s in %s".format(name, owner.fullName))
+ }
+
+ def selectTypeIfDefined(owner: Symbol, name: String): Symbol =
+ try selectType(owner, name)
+ catch { case _: MissingRequirementError => NoSymbol }
+
+// try getModule(fullname.toTermName)
+// catch { case _: MissingRequirementError => NoSymbol }
+
+ def selectTerm(owner: Symbol, name: String): Symbol = {
+ val sym = owner.info.decl(newTermName(name))
+ val result =
+ if (sym.isOverloaded) sym suchThat (!_.isMethod)
+ else sym
+ result orElse {
+ MissingRequirementError.notFound("term %s in %s".format(name, owner.fullName))
+ }
+ }
+
+ def selectTermIfDefined(owner: Symbol, name: String): Symbol =
+ try selectTerm(owner, name)
+ catch { case _: MissingRequirementError => NoSymbol }
+
+ def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol =
+ owner.info.decl(newTermName(name)).alternatives(index) orElse {
+ MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName))
+ }
+
+ def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol =
+ try selectOverloadedMethod(owner, name, index)
+ catch { case _: MissingRequirementError => NoSymbol }
+
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTermSymbol(newTermName(name), info, value, flags, origin)
+
+ def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) PARAM else flags) | DEFERRED, origin)
+
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null) = newFreeTypeSymbol(newTypeName(name), info, value, (if (flags == 0L) EXISTENTIAL else flags) | DEFERRED, origin)
+
+ def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers =
+ Modifiers(flags, privateWithin, annotations)
+
+ val gen: TreeGen { val global: TreeBuildUtil.this.type }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala
index 141ff12f8a..f30ec67c7e 100644
--- a/src/compiler/scala/reflect/internal/TreeGen.scala
+++ b/src/compiler/scala/reflect/internal/TreeGen.scala
@@ -1,7 +1,7 @@
package scala.reflect
package internal
-abstract class TreeGen {
+abstract class TreeGen extends api.AbsTreeGen {
val global: SymbolTable
import global._
@@ -48,6 +48,9 @@ abstract class TreeGen {
def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree =
Apply(mkTypeApply(target, targs map TypeTree), args)
+ def mkNullaryCall(method: Symbol, targs: List[Type]): Tree =
+ mkTypeApply(mkAttributedRef(method), targs map TypeTree)
+
/** Builds a reference to value whose type is given stable prefix.
* The type must be suitable for this. For example, it
* must not be a TypeRef pointing to an abstract type variable.
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index ce3de94335..f4878139e9 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -531,4 +531,214 @@ abstract class TreeInfo {
case _ => None
}
}
+
+ def isApplyDynamicName(name: Name) = (name == nme.updateDynamic) || (name == nme.selectDynamic) || (name == nme.applyDynamic) || (name == nme.applyDynamicNamed)
+
+ class DynamicApplicationExtractor(nameTest: Name => Boolean) {
+ def unapply(tree: Tree) = tree match {
+ case Apply(TypeApply(Select(qual, oper), _), List(Literal(Constant(name)))) if nameTest(oper) => Some((qual, name))
+ case Apply(Select(qual, oper), List(Literal(Constant(name)))) if nameTest(oper) => Some((qual, name))
+ case Apply(Ident(oper), List(Literal(Constant(name)))) if nameTest(oper) => Some((EmptyTree, name))
+ case _ => None
+ }
+ }
+ object DynamicUpdate extends DynamicApplicationExtractor(_ == nme.updateDynamic)
+ object DynamicApplication extends DynamicApplicationExtractor(isApplyDynamicName)
+ object DynamicApplicationNamed extends DynamicApplicationExtractor(_ == nme.applyDynamicNamed)
+
+
+ // domain-specific extractors for reification
+
+ import definitions._
+
+ object TypedOrAnnotated {
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case ty @ Typed(_, _) =>
+ Some(ty)
+ case at @ Annotated(_, _) =>
+ Some(at)
+ case _ =>
+ None
+ }
+ }
+
+ object TreeSplice {
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case Select(splicee, _) if tree.symbol == ExprEval || tree.symbol == ExprValue =>
+ Some(splicee)
+ case _ =>
+ None
+ }
+ }
+
+ object EvalSplice {
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case Select(splicee, _) if tree.symbol == ExprEval =>
+ Some(splicee)
+ case _ =>
+ None
+ }
+ }
+
+ object ValueSplice {
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case Select(splicee, _) if tree.symbol == ExprValue =>
+ Some(splicee)
+ case _ =>
+ None
+ }
+ }
+
+ object Reified {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match {
+ case ReifiedTree(reifee, symbolTable, reified, _) =>
+ Some(reifee, symbolTable, reified)
+ case ReifiedType(reifee, symbolTable, reified) =>
+ Some(reifee, symbolTable, reified)
+ case _ =>
+ None
+ }
+ }
+
+ object ReifiedTree {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree)] = tree match {
+ case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(Apply(_, List(tree)), List(Apply(_, tpe :: _)))) if mrDef.name == nme.MIRROR_SHORT =>
+ Some(reifee, symbolTable, tree, tpe)
+ case _ =>
+ None
+ }
+ }
+
+ object InlineableTreeSplice {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree, Symbol)] = tree match {
+ case select @ Select(ReifiedTree(splicee, symbolTable, tree, tpe), _) if select.symbol == ExprEval || select.symbol == ExprValue =>
+ Some(splicee, symbolTable, tree, tpe, select.symbol)
+ case _ =>
+ None
+ }
+ }
+
+ object InlinedTreeSplice {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree, Tree)] = tree match {
+ case Select(ReifiedTree(splicee, symbolTable, tree, tpe), name) if name == ExprTree.name =>
+ Some(splicee, symbolTable, tree, tpe)
+ case _ =>
+ None
+ }
+ }
+
+ object ReifiedType {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match {
+ case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, tpe :: _)) if mrDef.name == nme.MIRROR_SHORT =>
+ Some(reifee, symbolTable, tpe)
+ case _ =>
+ None
+ }
+ }
+
+ object InlinedTypeSplice {
+ def unapply(tree: Tree): Option[(Tree, List[Tree], Tree)] = tree match {
+ case Select(ReifiedType(splicee, symbolTable, tpe), name) if name == TypeTagTpe.name =>
+ Some(splicee, symbolTable, tpe)
+ case _ =>
+ None
+ }
+ }
+
+ object FreeDef {
+ def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
+ case FreeTermDef(mrRef, name, binding, flags, origin) =>
+ Some(mrRef, name, binding, flags, origin)
+ case FreeTypeDef(mrRef, name, binding, flags, origin) =>
+ Some(mrRef, name, binding, flags, origin)
+ case _ =>
+ None
+ }
+ }
+
+ object FreeTermDef {
+ lazy val newFreeTermMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeTerm)
+
+ def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
+ case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(flags: Long)), Literal(Constant(origin: String)))))
+ if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == newFreeTermMethod.name =>
+ Some(mrRef, name, binding, flags, origin)
+ case _ =>
+ None
+ }
+ }
+
+ object FreeTypeDef {
+ lazy val newFreeExistentialMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType)
+ lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeExistential)
+
+ def unapply(tree: Tree): Option[(Tree, TermName, Tree, Long, String)] = tree match {
+ case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(flags: Long)), Literal(Constant(origin: String)))))
+ if mrRef1.name == nme.MIRROR_SHORT && (newFreeType == newFreeTypeMethod.name || newFreeType == newFreeExistentialMethod.name) =>
+ value match {
+ case Apply(TypeApply(Select(Select(mrRef2 @ Ident(_), typeTag), apply), List(binding)), List(Literal(Constant(null)), _))
+ if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag && apply == nme.apply =>
+ Some(mrRef1, name, binding, flags, origin)
+ case Apply(TypeApply(Select(mrRef2 @ Ident(_), typeTag), List(binding)), List(Literal(Constant(null)), _))
+ if mrRef2.name == nme.MIRROR_SHORT && typeTag == nme.TypeTag =>
+ Some(mrRef1, name, binding, flags, origin)
+ case _ =>
+ throw new Error("unsupported free type def: %s%n%s".format(value, showRaw(value)))
+ }
+ case _ =>
+ None
+ }
+ }
+
+ object FreeRef {
+ def unapply(tree: Tree): Option[(Tree, TermName)] = tree match {
+ case Apply(Select(mrRef @ Ident(_), ident), List(Ident(name: TermName))) if ident == nme.Ident && name.startsWith(nme.MIRROR_FREE_PREFIX) =>
+ Some(mrRef, name)
+ case _ =>
+ None
+ }
+ }
+
+ object TypeRefToFreeType {
+ def unapply(tree: Tree): Option[TermName] = tree match {
+ case Apply(Select(Select(mrRef @ Ident(_), typeRef), apply), List(Select(_, noSymbol), Ident(freeType: TermName), nil))
+ if (mrRef.name == nme.MIRROR_SHORT && typeRef == nme.TypeRef && noSymbol == nme.NoSymbol && freeType.startsWith(nme.MIRROR_FREE_PREFIX)) =>
+ Some(freeType)
+ case _ =>
+ None
+ }
+ }
+
+ object NestedExpr {
+ def unapply(tree: Tree): Option[(Tree, Tree, Tree)] = tree match {
+ case Apply(Apply(factory @ Select(expr, apply), List(tree)), List(typetag)) if expr.symbol == ExprModule && apply == nme.apply =>
+ Some(factory, tree, typetag)
+ case _ =>
+ None
+ }
+ }
+
+ object BoundTerm {
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case Ident(name) if name.isTermName =>
+ Some(tree)
+ case This(_) =>
+ Some(tree)
+ case _ =>
+ None
+ }
+ }
+
+ object BoundType {
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case Select(_, name) if name.isTypeName =>
+ Some(tree)
+ case SelectFromTypeTree(_, name) if name.isTypeName =>
+ Some(tree)
+ case Ident(name) if name.isTypeName =>
+ Some(tree)
+ case _ =>
+ None
+ }
+ }
}
diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala
index 8ed0ee6357..3093bb049a 100644
--- a/src/compiler/scala/reflect/internal/TreePrinters.scala
+++ b/src/compiler/scala/reflect/internal/TreePrinters.scala
@@ -23,6 +23,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
else s
}
def quotedName(name: Name): String = quotedName(name, false)
+ def quotedName(name: String): String = quotedName(newTermName(name), false)
private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = {
val sym = tree.symbol
@@ -31,7 +32,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
var suffix = ""
if (settings.uniqid.value) suffix += ("#" + sym.id)
if (settings.Yshowsymkinds.value) suffix += ("#" + sym.abbreviatedKindString)
- prefix + tree.symbol.decodedName + suffix
+ prefix + quotedName(tree.symbol.decodedName) + suffix
} else {
quotedName(name, decoded)
}
@@ -64,7 +65,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
def indent() = indentMargin += indentStep
def undent() = indentMargin -= indentStep
- def printPosition(tree: Tree) = if (doPrintPositions) print(showPos(tree.pos))
+ def printPosition(tree: Tree) = if (doPrintPositions) print(tree.pos.show)
def println() {
out.println()
@@ -102,6 +103,16 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
}
}
+ def printLabelParams(ps: List[Ident]) {
+ print("(")
+ printSeq(ps){printLabelParam}{print(", ")}
+ print(")")
+ }
+
+ def printLabelParam(p: Ident) {
+ print(symName(p, p.name)); printOpt(": ", TypeTree() setType p.tpe)
+ }
+
def printValueParams(ts: List[ValDef]) {
print("(")
if (!ts.isEmpty) printFlags(ts.head.mods.flags & IMPLICIT, "")
@@ -175,7 +186,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
printAnnotations(tree)
printModifiers(tree, mods)
val word =
- if (mods.hasTraitFlag) "trait"
+ if (mods.isTrait) "trait"
else if (ifSym(tree, _.isModuleClass)) "object"
else "class"
@@ -218,7 +229,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
}
case LabelDef(name, params, rhs) =>
- print(symName(tree, name)); printRow(params, "(", ",", ")"); printBlock(rhs)
+ print(symName(tree, name)); printLabelParams(params); printBlock(rhs)
case Import(expr, selectors) =>
// Is this selector remapping a name (i.e, {name1 => name2})
@@ -362,6 +373,9 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
case Select(qualifier, name) =>
print(backquotedPath(qualifier), ".", symName(tree, name))
+ case bqid: BackQuotedIdent =>
+ print("`%s`" format symName(tree, bqid.name))
+
case Ident(name) =>
print(symName(tree, name))
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 1a40e0105c..5f1a8f3fbe 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -42,7 +42,6 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
/* Abstract types from HasFlags. */
- type FlagsType = Long
type AccessBoundaryType = Name
type AnnotationType = Tree
@@ -57,11 +56,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
def hasAccessBoundary = privateWithin != tpnme.EMPTY
def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask
def hasFlag(flag: Long) = (flag & flags) != 0L
- def hasFlagsToString(mask: Long): String = flagsToString(
- flags & mask,
- if (hasAccessBoundary) privateWithin.toString else ""
- )
- def defaultFlagString = hasFlagsToString(-1L)
+
def & (flag: Long): Modifiers = {
val flags1 = flags & flag
if (flags1 == flags) this
@@ -91,7 +86,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers =
Modifiers(flags, privateWithin, f(annotations)) setPositions positions
- override def toString = "Modifiers(%s, %s, %s)".format(defaultFlagString, annotations mkString ", ", positions)
+ override def toString = "Modifiers(%s, %s, %s)".format(flagString, annotations mkString ", ", positions)
}
def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List())
@@ -108,9 +103,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
// --- extension methods --------------------------------------------------------
- implicit def treeOps(tree: Tree): TreeOps = new TreeOps(tree)
-
- class TreeOps(tree: Tree) {
+ implicit class TreeOps(tree: Tree) {
def isErroneous = (tree.tpe ne null) && tree.tpe.isErroneous
def isTyped = (tree.tpe ne null) && !tree.tpe.isErroneous
@@ -151,11 +144,9 @@ trait Trees extends api.Trees { self: SymbolTable =>
* less than the whole tree.
*/
def summaryString: String = tree match {
- case Select(qual, name) => qual.summaryString + "." + name.decode
- case Ident(name) => name.longString
case Literal(const) => "Literal(" + const + ")"
- case t: DefTree => t.shortClass + " `" + t.name.decode + "`"
- case t: RefTree => t.shortClass + " `" + t.name.longString + "`"
+ case Select(qual, name) => qual.summaryString + "." + name.decode
+ case t: NameTree => t.name.longString
case t =>
t.shortClass + (
if (t.symbol != null && t.symbol != NoSymbol) " " + t.symbol
@@ -189,7 +180,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
def ValDef(sym: Symbol, rhs: Tree): ValDef =
atPos(sym.pos) {
ValDef(Modifiers(sym.flags), sym.name.toTermName,
- TypeTree(sym.tpe) setPos focusPos(sym.pos),
+ TypeTree(sym.tpe) setPos sym.pos.focus,
rhs) setSymbol sym
}
@@ -208,7 +199,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
sym.name.toTermName,
sym.typeParams map TypeDef,
vparamss,
- TypeTree(sym.tpe.finalResultType) setPos focusPos(sym.pos),
+ TypeTree(sym.tpe.finalResultType) setPos sym.pos.focus,
rhs) setSymbol sym
}
@@ -240,7 +231,8 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
/** casedef shorthand */
- def CaseDef(pat: Tree, body: Tree): CaseDef = CaseDef(pat, EmptyTree, body)
+ def CaseDef(pat: Tree, body: Tree): CaseDef =
+ CaseDef(pat, EmptyTree, body)
def Bind(sym: Symbol, body: Tree): Bind =
Bind(sym.name, body) setSymbol sym
@@ -254,10 +246,39 @@ trait Trees extends api.Trees { self: SymbolTable =>
def Apply(sym: Symbol, args: Tree*): Tree =
Apply(Ident(sym), args.toList)
+ /** Factory method for object creation `new tpt(args_1)...(args_n)`
+ * A `New(t, as)` is expanded to: `(new t).<init>(as)`
+ */
+ def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match {
+ case Nil => new ApplyConstructor(tpt, Nil)
+ case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply)
+ }
+
+ /** 0-1 argument list new, based on a type.
+ */
+ def New(tpe: Type, args: Tree*): Tree =
+ new ApplyConstructor(TypeTree(tpe), args.toList)
+
def New(sym: Symbol, args: Tree*): Tree =
New(sym.tpe, args: _*)
- def Super(sym: Symbol, mix: TypeName): Tree = Super(This(sym), mix)
+ def Super(sym: Symbol, mix: TypeName): Tree =
+ Super(This(sym), mix)
+
+ def This(sym: Symbol): Tree =
+ This(sym.name.toTypeName) setSymbol sym
+
+ def Select(qualifier: Tree, name: String): Select =
+ Select(qualifier, newTermName(name))
+
+ def Select(qualifier: Tree, sym: Symbol): Select =
+ Select(qualifier, sym.name) setSymbol sym
+
+ def Ident(name: String): Ident =
+ Ident(newTermName(name))
+
+ def Ident(sym: Symbol): Ident =
+ Ident(sym.name) setSymbol sym
/** Block factory that flattens directly nested blocks.
*/
@@ -271,6 +292,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
// --- specific traversers and transformers
+ // todo. move these into scala.reflect.api
protected[scala] def duplicateTree(tree: Tree): Tree = duplicator transform tree
@@ -278,44 +300,11 @@ trait Trees extends api.Trees { self: SymbolTable =>
override val treeCopy = newStrictTreeCopier
override def transform(t: Tree) = {
val t1 = super.transform(t)
- if ((t1 ne t) && isRangePos(t1.pos)) t1 setPos focusPos(t.pos)
+ if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus
t1
}
}
- trait PosAssigner extends Traverser {
- var pos: Position
- }
- protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner
-
- protected class DefaultPosAssigner extends PosAssigner {
- var pos: Position = _
- override def traverse(t: Tree) {
- if (t eq EmptyTree) ()
- else if (t.pos == NoPosition) {
- t.setPos(pos)
- super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
- // @PP: it's pruning whenever it encounters a node with a
- // position, which I interpret to mean that (in the author's
- // mind at least) either the children of a positioned node will
- // already be positioned, or the children of a positioned node
- // do not merit positioning.
- //
- // Whatever the author's rationale, it does seem like a bad idea
- // to press on through a positioned node to find unpositioned
- // children beneath it and then to assign whatever happens to
- // be in `pos` to such nodes. There are supposed to be some
- // position invariants which I can't imagine surviving that.
- }
- }
- }
-
- def atPos[T <: Tree](pos: Position)(tree: T): T = {
- posAssigner.pos = pos
- posAssigner.traverse(tree)
- tree
- }
-
class ForeachPartialTreeTraverser(pf: PartialFunction[Tree, Tree]) extends Traverser {
override def traverse(tree: Tree) {
val t = if (pf isDefinedAt tree) pf(tree) else tree
@@ -368,7 +357,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def toString = substituterString("Symbol", "Tree", from, to)
}
- /** Substitute clazz.this with `to`. `to` must be an attributed tree.
+ /** Substitute clazz.this with `to`. `to` must be an attributed tree.
*/
class ThisSubstituter(clazz: Symbol, to: => Tree) extends Transformer {
val newtpe = to.tpe
@@ -435,4 +424,3 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def toString() = "TreeSymSubstituter/" + substituterString("Symbol", "Symbol", from, to)
}
}
-
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index a20853adc8..2fe7dfda17 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -97,7 +97,7 @@ trait Types extends api.Types { self: SymbolTable =>
*/
private final val propagateParameterBoundsToTypeVars = sys.props contains "scalac.debug.prop-constraints"
- protected val enableTypeVarExperimentals = settings.Xexperimental.value
+ protected val enableTypeVarExperimentals = settings.Xexperimental.value || !settings.XoldPatmat.value
/** Empty immutable maps to avoid allocations. */
private val emptySymMap = immutable.Map[Symbol, Symbol]()
@@ -254,7 +254,9 @@ trait Types extends api.Types { self: SymbolTable =>
case object UnmappableTree extends TermTree {
override def toString = "<unmappable>"
super.tpe_=(NoType)
- override def tpe_=(t: Type) = if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
+ override def tpe_=(t: Type) = if (t != NoType) {
+ throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
+ }
}
abstract class AbsTypeImpl extends AbsType { this: Type =>
@@ -262,8 +264,53 @@ trait Types extends api.Types { self: SymbolTable =>
def nonPrivateDeclaration(name: Name): Symbol = nonPrivateDecl(name)
def declarations = decls
def typeArguments = typeArgs
- def erasedType = transformedType(this)
+ def erasure = this match {
+ case ConstantType(value) => widen.erasure // [Eugene to Martin] constant types are unaffected by erasure. weird.
+ case _ =>
+ var result = transformedType(this)
+ result = result.normalize match { // necessary to deal with erasures of HK types, typeConstructor won't work
+ case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result
+ case _ => result
+ }
+ // [Eugene] erasure screws up all ThisTypes for modules into PackageTypeRefs
+ // we need to unscrew them, or certain typechecks will fail mysteriously
+ // http://groups.google.com/group/scala-internals/browse_thread/thread/6d3277ae21b6d581
+ result = result.map(tpe => tpe match {
+ case tpe: PackageTypeRef => ThisType(tpe.sym)
+ case _ => tpe
+ })
+ result
+ }
def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to)
+
+ // [Eugene] to be discussed and refactored
+ def isConcrete = {
+ def notConcreteSym(sym: Symbol) =
+ sym.isAbstractType && !sym.isExistential
+
+ def notConcreteTpe(tpe: Type): Boolean = tpe match {
+ case ThisType(_) => false
+ case SuperType(_, _) => false
+ case SingleType(pre, sym) => notConcreteSym(sym)
+ case ConstantType(_) => false
+ case TypeRef(_, sym, args) => notConcreteSym(sym) || (args exists (arg => notConcreteTpe(arg)))
+ case RefinedType(_, _) => false
+ case ExistentialType(_, _) => false
+ case AnnotatedType(_, tp, _) => notConcreteTpe(tp)
+ case _ => true
+ }
+
+ !notConcreteTpe(this)
+ }
+
+ // [Eugene] is this comprehensive?
+ // the only thingies that we want to splice are: 1) type parameters, 2) type members
+ // the thingies that we don't want to splice are: 1) concrete types (obviously), 2) existential skolems
+ // this check seems to cover them all, right?
+ // todo. after we discuss this, move the check to subclasses
+ def isSpliceable = {
+ this.isInstanceOf[TypeRef] && typeSymbol.isAbstractType && !typeSymbol.isExistential
+ }
}
/** The base class for all types */
@@ -448,7 +495,7 @@ trait Types extends api.Types { self: SymbolTable =>
def resultType(actuals: List[Type]) = this
/** Only used for dependent method types. */
- def resultApprox: Type = ApproximateDependentMap(resultType) // if (!settings.YdepMethTpes.value) resultType else
+ def resultApprox: Type = ApproximateDependentMap(resultType)
/** If this is a TypeRef `clazz`[`T`], return the argument `T`
* otherwise return this type
@@ -710,7 +757,9 @@ trait Types extends api.Types { self: SymbolTable =>
/** Returns all parts of this type which satisfy predicate `p` */
def filter(p: Type => Boolean): List[Type] = new FilterTypeCollector(p) collect this
- def withFilter(p: Type => Boolean) = new FilterTypeCollector(p) {
+ def withFilter(p: Type => Boolean) = new FilterMapForeach(p)
+
+ class FilterMapForeach(p: Type => Boolean) extends FilterTypeCollector(p){
def foreach[U](f: Type => U): Unit = collect(Type.this) foreach f
def map[T](f: Type => T): List[T] = collect(Type.this) map f
}
@@ -723,6 +772,9 @@ trait Types extends api.Types { self: SymbolTable =>
/** Apply `f` to each part of this type */
def foreach(f: Type => Unit) { new ForEachTypeTraverser(f).traverse(this) }
+ /** Apply `pf' to each part of this type on which the function is defined */
+ def collect[T](pf: PartialFunction[Type, T]): List[T] = new CollectTypeCollector(pf).collect(this)
+
/** Apply `f` to each part of this type; children get mapped before their parents */
def map(f: Type => Type): Type = new TypeMap {
def apply(x: Type) = f(mapOver(x))
@@ -904,14 +956,16 @@ trait Types extends api.Types { self: SymbolTable =>
else str
}
- /** A test whether a type contains any unification type variables. */
+ /** The string representation of this type when the direct object in a sentence.
+ * Normally this is no different from the regular representation, but modules
+ * read better as "object Foo" here and "Foo.type" the rest of the time.
+ */
+ def directObjectString = safeToString
+
+ /** A test whether a type contains any unification type variables.
+ * Overridden with custom logic except where trivially true.
+ */
def isGround: Boolean = this match {
- case TypeVar(_, constr) =>
- constr.instValid && constr.inst.isGround
- case TypeRef(pre, sym, args) =>
- sym.isPackageClass || pre.isGround && (args forall (_.isGround))
- case SingleType(pre, sym) =>
- sym.isPackageClass || pre.isGround
case ThisType(_) | NoPrefix | WildcardType | NoType | ErrorType | ConstantType(_) =>
true
case _ =>
@@ -1188,6 +1242,8 @@ trait Types extends api.Types { self: SymbolTable =>
override def kind = "BoundedWildcardType"
}
+ object BoundedWildcardType extends BoundedWildcardTypeExtractor
+
/** An object representing a non-existing type */
case object NoType extends Type {
override def isTrivial: Boolean = true
@@ -1224,8 +1280,7 @@ trait Types extends api.Types { self: SymbolTable =>
else if (sym.isModuleClass) sym.fullNameString + "."
else sym.nameString + ".this."
override def safeToString: String =
- if (sym.isRoot) "<root>"
- else if (sym.isEmptyPackageClass) "<empty>"
+ if (sym.isEffectiveRoot) "" + sym.name
else super.safeToString
override def narrow: Type = this
override def kind = "ThisType"
@@ -1246,6 +1301,8 @@ trait Types extends api.Types { self: SymbolTable =>
*/
abstract case class SingleType(pre: Type, sym: Symbol) extends SingletonType {
override val isTrivial: Boolean = pre.isTrivial
+ override def isGround = sym.isPackageClass || pre.isGround
+
// override def isNullable = underlying.isNullable
override def isNotNull = underlying.isNotNull
private[reflect] var underlyingCache: Type = NoType
@@ -1301,7 +1358,8 @@ trait Types extends api.Types { self: SymbolTable =>
if (period != currentPeriod) {
tpe.underlyingPeriod = currentPeriod
if (!isValid(period)) {
- tpe.underlyingCache = tpe.pre.memberType(tpe.sym).resultType;
+ // [Eugene to Paul] needs review
+ tpe.underlyingCache = if (tpe.sym == NoSymbol) ThisType(RootClass) else tpe.pre.memberType(tpe.sym).resultType;
assert(tpe.underlyingCache ne tpe, tpe)
}
}
@@ -1451,7 +1509,8 @@ trait Types extends api.Types { self: SymbolTable =>
case tv: TypeVar => tvs += tv
case _ =>
}
- val varToParamMap: Map[Type, Symbol] = tvs map (tv => tv -> tv.origin.typeSymbol.cloneSymbol) toMap
+ val varToParamMap: Map[Type, Symbol] =
+ mapFrom[TypeVar, Type, Symbol](tvs.toList)(_.origin.typeSymbol.cloneSymbol)
val paramToVarMap = varToParamMap map (_.swap)
val varToParam = new TypeMap {
def apply(tp: Type) = varToParamMap get tp match {
@@ -1817,7 +1876,35 @@ trait Types extends api.Types { self: SymbolTable =>
object ConstantType extends ConstantTypeExtractor {
def apply(value: Constant): ConstantType = {
- unique(new UniqueConstantType(value)).asInstanceOf[ConstantType]
+ val tpe = new UniqueConstantType(value)
+ if (value.tag == ClazzTag) {
+ // if we carry a classOf, we might be in trouble
+ // http://groups.google.com/group/scala-internals/browse_thread/thread/45185b341aeb6a30
+ // I don't have time for a thorough fix, so I put a hacky workaround here
+ val alreadyThere = uniques findEntry tpe
+ if ((alreadyThere ne null) && (alreadyThere ne tpe) && (alreadyThere.toString != tpe.toString)) {
+ // we need to remove a stale type that has the same hashcode as we do
+ // HashSet doesn't support removal, and this makes our task non-trivial
+ // also we cannot simply recreate it, because that'd skew hashcodes (that change over time, omg!)
+ // the only solution I can see is getting into the underlying array and sneakily manipulating it
+ val ftable = uniques.getClass.getDeclaredFields().find(f => f.getName endsWith "table").get
+ ftable.setAccessible(true)
+ val table = ftable.get(uniques).asInstanceOf[Array[AnyRef]]
+ def overwrite(hc: Int, x: Type) {
+ def index(x: Int): Int = math.abs(x % table.length)
+ var h = index(hc)
+ var entry = table(h)
+ while (entry ne null) {
+ if (x == entry)
+ table(h) = x
+ h = index(h + 1)
+ entry = table(h)
+ }
+ }
+ overwrite(tpe.##, tpe)
+ }
+ }
+ unique(tpe).asInstanceOf[ConstantType]
}
}
@@ -1851,6 +1938,35 @@ trait Types extends api.Types { self: SymbolTable =>
// advantage to call TypeRef directly.
override def typeConstructor = TypeRef(pre, sym, Nil)
}
+
+ class ModuleTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) with ClassTypeRef {
+ require(sym.isModuleClass, sym)
+ private[this] var narrowedCache: Type = _
+ override def isStable = true
+ override def narrow = {
+ if (narrowedCache eq null)
+ narrowedCache = singleType(pre, sym.sourceModule)
+
+ narrowedCache
+ }
+ final override def isNotNull = true
+ override protected def finishPrefix(rest: String) = objectPrefix + rest
+ override def directObjectString = super.safeToString
+ override def toLongString = toString
+ override def safeToString = narrow.toString
+ }
+ class PackageTypeRef(pre0: Type, sym0: Symbol) extends ModuleTypeRef(pre0, sym0) {
+ require(sym.isPackageClass, sym)
+ override protected def finishPrefix(rest: String) = packagePrefix + rest
+ }
+ class RefinementTypeRef(sym0: Symbol) extends NoArgsTypeRef(NoType, sym0) with ClassTypeRef {
+ require(sym.isRefinementClass, sym)
+
+ // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
+ override protected def normalizeImpl: Type = sym.info.normalize
+ override protected def finishPrefix(rest: String) = "" + thisInfo
+ }
+
class NoArgsTypeRef(pre0: Type, sym0: Symbol) extends TypeRef(pre0, sym0, Nil) with UniqueType {
// A reference (in a Scala program) to a type that has type parameters, but where the reference
// does not include type arguments. Note that it doesn't matter whether the symbol refers
@@ -1898,10 +2014,6 @@ trait Types extends api.Types { self: SymbolTable =>
// !!! There are scaladoc-created symbols arriving which violate this require.
// require(sym.isClass, sym)
- override protected def normalizeImpl: Type =
- if (sym.isRefinementClass) sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
- else super.normalizeImpl
-
override def baseType(clazz: Symbol): Type =
if (sym == clazz) this
else transform(sym.info.baseType(clazz))
@@ -1988,7 +2100,7 @@ trait Types extends api.Types { self: SymbolTable =>
// TODO: is there another way a typeref's symbol can refer to a symbol defined in its pre?
case _ => sym
}
-
+ override def kind = "AliasTypeRef"
}
trait AbstractTypeRef extends NonClassTypeRef {
@@ -2041,6 +2153,7 @@ trait Types extends api.Types { self: SymbolTable =>
override def bounds = thisInfo.bounds
// def transformInfo(tp: Type): Type = appliedType(tp.asSeenFrom(pre, sym.owner), typeArgsOrDummies)
override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this
+ override def kind = "AbstractTypeRef"
}
/** A class for named types of the form
@@ -2078,6 +2191,11 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
+ override def isGround = (
+ sym.isPackageClass
+ || pre.isGround && args.forall(_.isGround)
+ )
+
def etaExpand: Type = {
// must initialise symbol, see test/files/pos/ticket0137.scala
val tpars = initializedTypeParams
@@ -2147,12 +2265,15 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
- private def preString = (
- // ensure that symbol is not a local copy with a name coincidence
- if (!settings.debug.value && shorthands(sym.fullName) && sym.ownerChain.forall(_.isClass)) ""
- else pre.prefixString
+ // ensure that symbol is not a local copy with a name coincidence
+ private def needsPreString = (
+ settings.debug.value
+ || !shorthands(sym.fullName)
+ || sym.ownerChain.exists(s => !s.isClass)
)
+ private def preString = if (needsPreString) pre.prefixString else ""
private def argsString = if (args.isEmpty) "" else args.mkString("[", ",", "]")
+
def refinementString = (
if (sym.isStructuralRefinement) (
decls filter (sym => sym.isPossibleInRefinement && sym.isPublic)
@@ -2162,25 +2283,23 @@ trait Types extends api.Types { self: SymbolTable =>
else ""
)
- private def finishPrefix(rest: String) = (
- if (sym.isPackageClass) packagePrefix + rest
- else if (sym.isModuleClass) objectPrefix + rest
- else if (!sym.isInitialized) rest
- else if (sym.isAnonymousClass && !phase.erasedTypes) parentsString(thisInfo.parents) + refinementString
- else if (sym.isRefinementClass) "" + thisInfo
+ protected def finishPrefix(rest: String) = (
+ if (sym.isInitialized && sym.isAnonymousClass && !phase.erasedTypes)
+ parentsString(thisInfo.parents) + refinementString
else rest
)
- private def customToString = this match {
- case TypeRef(_, RepeatedParamClass, arg :: _) => arg + "*"
- case TypeRef(_, ByNameParamClass, arg :: _) => "=> " + arg
- case _ =>
+ private def customToString = sym match {
+ case RepeatedParamClass => args.head + "*"
+ case ByNameParamClass => "=> " + args.head
+ case _ =>
+ def targs = normalize.typeArgs
+
if (isFunctionType(this)) {
- val targs = normalize.typeArgs
// Aesthetics: printing Function1 as T => R rather than (T) => R
// ...but only if it's not a tuple, so ((T1, T2)) => R is distinguishable
// from (T1, T2) => R.
targs match {
- case in :: out :: Nil if !isTupleTypeOrSubtype(in) =>
+ case in :: out :: Nil if !isTupleType(in) =>
// A => B => C should be (A => B) => C or A => (B => C)
val in_s = if (isFunctionType(in)) "(" + in + ")" else "" + in
val out_s = if (isFunctionType(out)) "(" + out + ")" else "" + out
@@ -2189,9 +2308,9 @@ trait Types extends api.Types { self: SymbolTable =>
xs.init.mkString("(", ", ", ")") + " => " + xs.last
}
}
- else if (isTupleTypeOrSubtype(this))
- normalize.typeArgs.mkString("(", ", ", if (hasLength(normalize.typeArgs, 1)) ",)" else ")")
- else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic) && (normalize ne this))
+ else if (isTupleType(this))
+ targs.mkString("(", ", ", if (hasLength(targs, 1)) ",)" else ")")
+ else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic) && (this ne this.normalize))
"" + normalize
else
""
@@ -2209,7 +2328,7 @@ trait Types extends api.Types { self: SymbolTable =>
else if (sym.isPackageClass || sym.isPackageObjectOrClass)
sym.skipPackageObject.fullName + "."
else if (isStable && nme.isSingletonName(sym.name))
- nme.dropSingletonName(sym.name) + "."
+ tpnme.dropSingletonName(sym.name) + "."
else
super.prefixString
)
@@ -2226,6 +2345,9 @@ trait Types extends api.Types { self: SymbolTable =>
else {
if (sym.isAliasType) new NoArgsTypeRef(pre, sym) with AliasTypeRef
else if (sym.isAbstractType) new NoArgsTypeRef(pre, sym) with AbstractTypeRef
+ else if (sym.isRefinementClass) new RefinementTypeRef(sym)
+ else if (sym.isPackageClass) new PackageTypeRef(pre, sym)
+ else if (sym.isModuleClass) new ModuleTypeRef(pre, sym)
else new NoArgsTypeRef(pre, sym) with ClassTypeRef
}
})
@@ -2268,7 +2390,7 @@ trait Types extends api.Types { self: SymbolTable =>
override def isTrivial: Boolean = isTrivial0 && (resultType eq resultType.withoutAnnotations)
private lazy val isTrivial0 =
resultType.isTrivial && params.forall{p => p.tpe.isTrivial && (
- /*!settings.YdepMethTpes.value ||*/ !(params.exists(_.tpe.contains(p)) || resultType.contains(p)))
+ !(params.exists(_.tpe.contains(p)) || resultType.contains(p)))
}
def isImplicit = params.nonEmpty && params.head.isImplicit
@@ -2292,8 +2414,9 @@ trait Types extends api.Types { self: SymbolTable =>
}
else existentialAbstraction(params, resultType)
- // implicit args can only be depended on in result type: TODO this may be generalised so that the only constraint is dependencies are acyclic
- def approximate: MethodType = MethodType(params, resultApprox) // if (!settings.YdepMethTpes.value) this else
+ // implicit args can only be depended on in result type:
+ //TODO this may be generalised so that the only constraint is dependencies are acyclic
+ def approximate: MethodType = MethodType(params, resultApprox)
override def finalResultType: Type = resultType.finalResultType
@@ -2445,39 +2568,46 @@ trait Types extends api.Types { self: SymbolTable =>
override def skolemizeExistential(owner: Symbol, origin: AnyRef) =
deriveType(quantified, tparam => (owner orElse tparam.owner).newExistentialSkolem(tparam, origin))(underlying)
- private def wildcardArgsString(available: Set[Symbol], args: List[Type]): List[String] = args match {
- case TypeRef(_, sym, _) :: args1 if (available contains sym) =>
- ("_"+sym.infoString(sym.info)) :: wildcardArgsString(available - sym, args1)
- case arg :: args1 if !(quantified exists (arg contains _)) =>
- arg.toString :: wildcardArgsString(available, args1)
- case _ =>
- List()
+ private def wildcardArgsString(qset: Set[Symbol], args: List[Type]): List[String] = args map {
+ case TypeRef(_, sym, _) if (qset contains sym) =>
+ "_"+sym.infoString(sym.info)
+ case arg =>
+ arg.toString
}
+
/** An existential can only be printed with wildcards if:
* - the underlying type is a typeref
- * - where there is a 1-to-1 correspondence between underlying's typeargs and quantified
- * - and none of the existential parameters is referenced from anywhere else in the type
- * - and none of the existential parameters are singleton types
+ * - every quantified variable appears at most once as a type argument and
+ * nowhere inside a type argument
+ * - no quantified type argument contains a quantified variable in its bound
+ * - the typeref's symbol is not itself quantified
+ * - the prefix is not quanitified
*/
- private def isRepresentableWithWildcards = !settings.debug.value && {
+ def isRepresentableWithWildcards = {
val qset = quantified.toSet
- !qset.exists(_.isSingletonExistential) && (underlying match {
- case TypeRef(_, sym, args) =>
- sameLength(args, quantified) && {
- args forall { arg =>
- qset(arg.typeSymbol) && !qset.exists(arg.typeSymbol.info.bounds contains _)
- }
+ underlying match {
+ case TypeRef(pre, sym, args) =>
+ def isQuantified(tpe: Type): Boolean = {
+ (tpe exists (t => qset contains t.typeSymbol)) ||
+ tpe.typeSymbol.isRefinementClass && (tpe.parents exists isQuantified)
}
+ val (wildcardArgs, otherArgs) = args partition (arg => qset contains arg.typeSymbol)
+ wildcardArgs.distinct == wildcardArgs &&
+ !(otherArgs exists (arg => isQuantified(arg))) &&
+ !(wildcardArgs exists (arg => isQuantified(arg.typeSymbol.info.bounds))) &&
+ !(qset contains sym) &&
+ !isQuantified(pre)
case _ => false
- })
}
+ }
+
override def safeToString: String = {
def clauses = {
val str = quantified map (_.existentialToString) mkString (" forSome { ", "; ", " }")
if (settings.explaintypes.value) "(" + str + ")" else str
}
underlying match {
- case TypeRef(pre, sym, args) if isRepresentableWithWildcards =>
+ case TypeRef(pre, sym, args) if !settings.debug.value && isRepresentableWithWildcards =>
"" + TypeRef(pre, sym, Nil) + wildcardArgsString(quantified.toSet, args).mkString("[", ", ", "]")
case MethodType(_, _) | NullaryMethodType(_) | PolyType(_, _) =>
"(" + underlying + ")" + clauses
@@ -2605,21 +2735,35 @@ trait Types extends api.Types { self: SymbolTable =>
else new TypeConstraint
}
def unapply(tv: TypeVar): Some[(Type, TypeConstraint)] = Some((tv.origin, tv.constr))
+ def untouchable(tparam: Symbol): TypeVar = createTypeVar(tparam, untouchable = true)
+ def apply(tparam: Symbol): TypeVar = createTypeVar(tparam, untouchable = false)
def apply(origin: Type, constr: TypeConstraint): TypeVar = apply(origin, constr, Nil, Nil)
- def apply(tparam: Symbol): TypeVar = apply(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams)
+ def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol]): TypeVar =
+ createTypeVar(origin, constr, args, params, untouchable = false)
/** This is the only place TypeVars should be instantiated.
*/
- def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol]): TypeVar = {
+ private def createTypeVar(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol], untouchable: Boolean): TypeVar = {
val tv = (
- if (args.isEmpty && params.isEmpty) new TypeVar(origin, constr)
- else if (args.size == params.size) new AppliedTypeVar(origin, constr, params zip args)
- else if (args.isEmpty) new HKTypeVar(origin, constr, params)
+ if (args.isEmpty && params.isEmpty) {
+ if (untouchable) new TypeVar(origin, constr) with UntouchableTypeVar
+ else new TypeVar(origin, constr)
+ }
+ else if (args.size == params.size) {
+ if (untouchable) new AppliedTypeVar(origin, constr, params zip args) with UntouchableTypeVar
+ else new AppliedTypeVar(origin, constr, params zip args)
+ }
+ else if (args.isEmpty) {
+ if (untouchable) new HKTypeVar(origin, constr, params) with UntouchableTypeVar
+ else new HKTypeVar(origin, constr, params)
+ }
else throw new Error("Invalid TypeVar construction: " + ((origin, constr, args, params)))
)
trace("create", "In " + tv.originLocation)(tv)
}
+ private def createTypeVar(tparam: Symbol, untouchable: Boolean): TypeVar =
+ createTypeVar(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams, untouchable)
}
/** Repack existential types, otherwise they sometimes get unpacked in the
@@ -2668,6 +2812,23 @@ trait Types extends api.Types { self: SymbolTable =>
)
}
+ trait UntouchableTypeVar extends TypeVar {
+ override def untouchable = true
+ override def isGround = true
+ override def registerTypeEquality(tp: Type, typeVarLHS: Boolean) = tp match {
+ case t: TypeVar if !t.untouchable =>
+ t.registerTypeEquality(this, !typeVarLHS)
+ case _ =>
+ super.registerTypeEquality(tp, typeVarLHS)
+ }
+ override def registerBound(tp: Type, isLowerBound: Boolean, isNumericBound: Boolean = false): Boolean = tp match {
+ case t: TypeVar if !t.untouchable =>
+ t.registerBound(this, !isLowerBound, isNumericBound)
+ case _ =>
+ super.registerBound(tp, isLowerBound, isNumericBound)
+ }
+ }
+
/** A class representing a type variable: not used after phase `typer`.
*
* A higher-kinded TypeVar has params (Symbols) and typeArgs (Types).
@@ -2681,6 +2842,7 @@ trait Types extends api.Types { self: SymbolTable =>
val origin: Type,
val constr0: TypeConstraint
) extends Type {
+ def untouchable = false // by other typevars
override def params: List[Symbol] = Nil
override def typeArgs: List[Type] = Nil
override def isHigherKinded = false
@@ -2693,6 +2855,7 @@ trait Types extends api.Types { self: SymbolTable =>
*/
var constr = constr0
def instValid = constr.instValid
+ override def isGround = instValid && constr.inst.isGround
/** The variable's skolemization level */
val level = skolemizationLevel
@@ -2861,14 +3024,13 @@ trait Types extends api.Types { self: SymbolTable =>
// would be pointless. In this case, each check we perform causes us to lose specificity: in
// the end the best we'll do is the least specific type we tested against, since the typevar
// does not see these checks as "probes" but as requirements to fulfill.
- // TODO: the `suspended` flag can be used to poke around with leaving a trace
+ // TODO: can the `suspended` flag be used to poke around without leaving a trace?
//
// So the strategy used here is to test first the type, then the direct parents, and finally
// to fall back on the individual base types. This warrants eventual re-examination.
// AM: I think we could use the `suspended` flag to avoid side-effecting during unification
-
- if (suspended) // constraint accumulation is disabled
+ if (suspended) // constraint accumulation is disabled
checkSubtype(tp, origin)
else if (constr.instValid) // type var is already set
checkSubtype(tp, constr.inst)
@@ -2966,7 +3128,7 @@ trait Types extends api.Types { self: SymbolTable =>
override def safeToString = (
if ((constr eq null) || (constr.inst eq null)) "TVar<" + originName + "=null>"
else if (constr.inst ne NoType) "" + constr.inst
- else "?" + levelString + originName
+ else (if(untouchable) "!?" else "?") + levelString + originName
)
override def kind = "TypeVar"
@@ -3297,6 +3459,10 @@ trait Types extends api.Types { self: SymbolTable =>
case _ => abort(debugString(tycon))
}
+ /** Very convenient. */
+ def appliedType(tyconSym: Symbol, args: Type*): Type =
+ appliedType(tyconSym.typeConstructor, args.toList)
+
/** A creator for existential types where the type arguments,
* rather than being applied directly, are interpreted as the
* upper bounds of unknown types. For instance if the type argument
@@ -3308,7 +3474,7 @@ trait Types extends api.Types { self: SymbolTable =>
case TypeRef(pre, sym, _) if sameLength(sym.typeParams, args) =>
val eparams = typeParamsToExistentials(sym)
val bounds = args map (TypeBounds upper _)
- (eparams, bounds).zipped foreach (_ setInfo _)
+ foreach2(eparams, bounds)(_ setInfo _)
newExistentialType(eparams, typeRef(pre, sym, eparams map (_.tpe)))
case _ =>
@@ -3490,7 +3656,7 @@ trait Types extends api.Types { self: SymbolTable =>
else owner.newValueParameter(name.toTermName)
paramStack = newParams :: paramStack
try {
- (newParams, ptypes).zipped foreach ((p, t) => p setInfo this(t))
+ foreach2(newParams, ptypes)((p, t) => p setInfo this(t))
val restpe1 = this(restpe)
if (isType) PolyType(newParams, restpe1)
else MethodType(newParams, restpe1)
@@ -3614,6 +3780,23 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
+ class TypeUnwrapper(poly: Boolean, existential: Boolean, annotated: Boolean, nullary: Boolean) extends (Type => Type) {
+ def apply(tp: Type): Type = tp match {
+ case AnnotatedType(_, underlying, _) if annotated => apply(underlying)
+ case ExistentialType(_, underlying) if existential => apply(underlying)
+ case PolyType(_, underlying) if poly => apply(underlying)
+ case NullaryMethodType(underlying) if nullary => apply(underlying)
+ case tp => tp
+ }
+ }
+ class ClassUnwrapper(existential: Boolean) extends TypeUnwrapper(poly = true, existential, annotated = true, nullary = false) {
+ override def apply(tp: Type) = super.apply(tp.normalize)
+ }
+
+ object unwrapToClass extends ClassUnwrapper(existential = true) { }
+ object unwrapToStableClass extends ClassUnwrapper(existential = false) { }
+ object unwrapWrapperTypes extends TypeUnwrapper(true, true, true, true) { }
+
trait AnnotationFilter extends TypeMap {
def keepAnnotation(annot: AnnotationInfo): Boolean
@@ -3695,6 +3878,8 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
+ // todo. move these into scala.reflect.api
+
/** A prototype for mapping a function over all possible types
*/
abstract class TypeMap extends (Type => Type) {
@@ -4507,6 +4692,16 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
+ /** A map to implement the `collect` method. */
+ class CollectTypeCollector[T](pf: PartialFunction[Type, T]) extends TypeCollector[List[T]](Nil) {
+ override def collect(tp: Type) = super.collect(tp).reverse
+
+ def traverse(tp: Type) {
+ if (pf.isDefinedAt(tp)) result ::= pf(tp)
+ mapOver(tp)
+ }
+ }
+
class ForEachTypeTraverser(f: Type => Unit) extends TypeTraverser {
def traverse(tp: Type) {
f(tp)
@@ -4584,31 +4779,22 @@ trait Types extends api.Types { self: SymbolTable =>
object adaptToNewRunMap extends TypeMap {
private def adaptToNewRun(pre: Type, sym: Symbol): Symbol = {
- if (phase.flatClasses) {
+ if (phase.flatClasses || sym.isRootSymbol || (pre eq NoPrefix) || (pre eq NoType) || sym.isPackageClass)
sym
- } else if (sym == definitions.RootClass) {
- definitions.RootClass
- } else if (sym == definitions.RootPackage) {
- definitions.RootPackage
- } else if (sym.isModuleClass) {
+ else if (sym.isModuleClass) {
val sourceModule1 = adaptToNewRun(pre, sym.sourceModule)
- var result = sourceModule1.moduleClass
- if (result == NoSymbol) result = sourceModule1.initialize.moduleClass
- if (result != NoSymbol) result
- else {
+
+ sourceModule1.moduleClass orElse sourceModule1.initialize.moduleClass orElse {
val msg = "Cannot adapt module class; sym = %s, sourceModule = %s, sourceModule.moduleClass = %s => sourceModule1 = %s, sourceModule1.moduleClass = %s"
debuglog(msg.format(sym, sym.sourceModule, sym.sourceModule.moduleClass, sourceModule1, sourceModule1.moduleClass))
sym
}
- } else if ((pre eq NoPrefix) || (pre eq NoType) || sym.isPackageClass) {
- sym
- } else {
- var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true)
- if (rebind0 == NoSymbol) {
+ }
+ else {
+ var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true) orElse {
if (sym.isAliasType) throw missingAliasException
debugwarn(pre+"."+sym+" does no longer exist, phase = "+phase)
throw new MissingTypeControl // For build manager and presentation compiler purposes
- //assert(false, pre+"."+sym+" does no longer exist, phase = "+phase)
}
/** The two symbols have the same fully qualified name */
def corresponds(sym1: Symbol, sym2: Symbol): Boolean =
@@ -4627,12 +4813,10 @@ trait Types extends api.Types { self: SymbolTable =>
", rebind = " + rebind0.fullLocationString
)
}
- val rebind = rebind0.suchThat(sym => sym.isType || sym.isStable)
- if (rebind == NoSymbol) {
+ rebind0.suchThat(sym => sym.isType || sym.isStable) orElse {
debuglog("" + phase + " " +phase.flatClasses+sym.owner+sym.name+" "+sym.isType)
throw new MalformedType(pre, sym.nameString)
}
- rebind
}
}
def apply(tp: Type): Type = tp match {
@@ -4641,7 +4825,7 @@ trait Types extends api.Types { self: SymbolTable =>
val sym1 = adaptToNewRun(sym.owner.thisType, sym)
if (sym1 == sym) tp else ThisType(sym1)
} catch {
- case ex: MissingTypeControl =>
+ case ex: MissingTypeControl =>
tp
}
case SingleType(pre, sym) =>
@@ -5018,6 +5202,8 @@ trait Types extends api.Types { self: SymbolTable =>
case (_, tv @ TypeVar(_,_)) => tv.registerTypeSelection(tr2.sym, tr1)
case _ => false
})
+ case _: SingleType =>
+ return isSameType2(tp2, tp1) // put singleton type on the left, caught below
case _ =>
}
case tt1: ThisType =>
@@ -5030,6 +5216,8 @@ trait Types extends api.Types { self: SymbolTable =>
tp2 match {
case st2: SingleType =>
if (equalSymsAndPrefixes(st1.sym, st1.pre, st2.sym, st2.pre)) return true
+ case TypeRef(pre2, sym2, Nil) =>
+ if (sym2.isModuleClass && equalSymsAndPrefixes(st1.sym, st1.pre, sym2.sourceModule, pre2)) return true
case _ =>
}
case ct1: ConstantType =>
@@ -5440,7 +5628,7 @@ trait Types extends api.Types { self: SymbolTable =>
* - handle typerefs, refined types, notnull and singleton types.
*/
def fourthTry = tp1 match {
- case tr1 @ TypeRef(_, sym1, _) =>
+ case tr1 @ TypeRef(pre1, sym1, _) =>
sym1 match {
case NothingClass => true
case NullClass =>
@@ -5453,9 +5641,14 @@ trait Types extends api.Types { self: SymbolTable =>
case _: ClassSymbol =>
if (isRaw(sym1, tr1.args))
isSubType(rawToExistential(tp1), tp2, depth)
- else
- sym1.name == tpnme.REFINE_CLASS_NAME &&
+ else if (sym1.isModuleClass) tp2 match {
+ case SingleType(pre2, sym2) => equalSymsAndPrefixes(sym1.sourceModule, pre1, sym2, pre2)
+ case _ => false
+ }
+ else if (sym1.isRefinementClass)
isSubType(sym1.info, tp2, depth)
+ else false
+
case _: TypeSymbol =>
if (sym1 hasFlag DEFERRED) {
val tp1a = tp1.bounds.hi
@@ -5943,8 +6136,9 @@ trait Types extends api.Types { self: SymbolTable =>
def stripType(tp: Type) = tp match {
case ExistentialType(_, res) =>
res
- case TypeVar(_, constr) =>
- if (constr.instValid) constr.inst
+ case tv@TypeVar(_, constr) =>
+ if (tv.instValid) constr.inst
+ else if (tv.untouchable) tv
else abort("trying to do lub/glb of typevar "+tp)
case t => t
}
@@ -6505,6 +6699,16 @@ trait Types extends api.Types { self: SymbolTable =>
try { explainSwitch = true; op } finally { explainSwitch = s }
}
+ def isUnboundedGeneric(tp: Type) = tp match {
+ case t @ TypeRef(_, sym, _) => sym.isAbstractType && !(t <:< AnyRefClass.tpe)
+ case _ => false
+ }
+ def isBoundedGeneric(tp: Type) = tp match {
+ case TypeRef(_, sym, _) if sym.isAbstractType => (tp <:< AnyRefClass.tpe)
+ case TypeRef(_, sym, _) => !isPrimitiveValueClass(sym)
+ case _ => false
+ }
+
def objToAny(tp: Type): Type =
if (!phase.erasedTypes && tp.typeSymbol == ObjectClass) AnyClass.tpe
else tp
diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
index f1ec64bda9..fd3fac1b37 100644
--- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
@@ -257,12 +257,11 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
}
def isModuleFlag = (flags & MODULE) != 0L
- def isMethodFlag = (flags & METHOD) != 0L
def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner)
def isModuleRoot = (name == moduleRoot.name) && (owner == moduleRoot.owner)
+ def pflags = flags & PickledFlags
def finishSym(sym: Symbol): Symbol = {
- sym.flags = flags & PickledFlags
sym.privateWithin = privateWithin
sym.info = (
if (atEnd) {
@@ -282,27 +281,27 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
}
finishSym(tag match {
- case TYPEsym => owner.newAbstractType(name.toTypeName)
- case ALIASsym => owner.newAliasType(name.toTypeName)
+ case TYPEsym | ALIASsym =>
+ owner.newNonClassSymbol(name.toTypeName, NoPosition, pflags)
case CLASSsym =>
- val sym = (isClassRoot, isModuleFlag) match {
- case (true, true) => moduleRoot.moduleClass
- case (true, false) => classRoot
- case (false, true) => owner.newModuleClass(name.toTypeName)
- case (false, false) => owner.newClass(name.toTypeName)
- }
+ val sym = (
+ if (isClassRoot) {
+ if (isModuleFlag) moduleRoot.moduleClass setFlag pflags
+ else classRoot setFlag pflags
+ }
+ else owner.newClassSymbol(name.toTypeName, NoPosition, pflags)
+ )
if (!atEnd)
sym.typeOfThis = newLazyTypeRef(readNat())
sym
case MODULEsym =>
val clazz = at(inforef, () => readType()).typeSymbol // after the NMT_TRANSITION period, we can leave off the () => ... ()
- if (isModuleRoot) moduleRoot
- else owner.newLinkedModule(clazz)
+ if (isModuleRoot) moduleRoot setFlag pflags
+ else owner.newLinkedModule(clazz, pflags)
case VALsym =>
if (isModuleRoot) { assert(false); NoSymbol }
- else if (isMethodFlag) owner.newMethod(name.toTermName)
- else owner.newValue(name.toTermName)
+ else owner.newTermSymbol(name.toTermName, NoPosition, pflags)
case _ =>
errorBadSignature("bad symbol tag: " + tag)
@@ -448,7 +447,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
private def readArrayAnnot() = {
readByte() // skip the `annotargarray` tag
val end = readNat() + readIndex
- until(end, () => readClassfileAnnotArg(readNat())).toArray(classfileAnnotArgManifest)
+ until(end, () => readClassfileAnnotArg(readNat())).toArray(classfileAnnotArgTag)
}
protected def readClassfileAnnotArg(i: Int): ClassfileAnnotArg = bytes(index(i)) match {
case ANNOTINFO => NestedAnnotArg(at(i, readAnnotation))
@@ -817,16 +816,10 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
protected def errorMissingRequirement(name: Name, owner: Symbol): Symbol =
- missingHook(owner, name) orElse {
- val what = if (name.isTypeName) "type" else "value"
- MissingRequirementError.notFound(
- "while unpickling %s, reference %s %s of %s/%s/%s".format(
- filename,
- what, name.decode, owner.tpe.widen,
- owner.tpe.typeSymbol.ownerChain,
- owner.info.members.mkString("\n ", "\n ", ""))
- )
- }
+ missingHook(owner, name) orElse MissingRequirementError.notFound(
+ "bad reference while unpickling %s: %s not found in %s".format(
+ filename, name.longString, owner.tpe.widen)
+ )
def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) {} // can't do it; need a compiler for that.
@@ -850,7 +843,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
atPhase(p) (sym setInfo tp)
if (currentRunId != definedAtRunId)
sym.setInfo(adaptToNewRunMap(tp))
- }
+ }
catch {
case e: MissingRequirementError => throw toTypeError(e)
}
diff --git a/src/compiler/scala/reflect/internal/settings/MutableSettings.scala b/src/compiler/scala/reflect/internal/settings/MutableSettings.scala
index 0092f73fe3..45ba4ed3e6 100644
--- a/src/compiler/scala/reflect/internal/settings/MutableSettings.scala
+++ b/src/compiler/scala/reflect/internal/settings/MutableSettings.scala
@@ -43,4 +43,5 @@ abstract class MutableSettings extends AbsSettings {
def Yrecursion: IntSetting
def maxClassfileName: IntSetting
def Xexperimental: BooleanSetting
+ def XoldPatmat: BooleanSetting
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala
index e87de8db80..1b323f839b 100644
--- a/src/compiler/scala/reflect/internal/transform/Erasure.scala
+++ b/src/compiler/scala/reflect/internal/transform/Erasure.scala
@@ -69,6 +69,9 @@ trait Erasure {
clazz.firstParamAccessor.tpe.resultType
abstract class ErasureMap extends TypeMap {
+ private lazy val ObjectArray = arrayType(ObjectClass.tpe)
+ private lazy val ErasedObject = erasedTypeRef(ObjectClass)
+
def mergeParents(parents: List[Type]): Type
def eraseNormalClassRef(pre: Type, clazz: Symbol): Type =
@@ -87,7 +90,7 @@ trait Erasure {
if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe
else if (args.head.typeSymbol.isBottomClass) ObjectArray
else typeRef(apply(pre), sym, args map applyInArray)
- else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) erasedTypeRef(ObjectClass)
+ else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) ErasedObject
else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass)
else if (sym.isRefinementClass) apply(mergeParents(tp.parents))
else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(sym)
@@ -111,7 +114,7 @@ trait Erasure {
case ClassInfoType(parents, decls, clazz) =>
ClassInfoType(
if (clazz == ObjectClass || isPrimitiveValueClass(clazz)) Nil
- else if (clazz == ArrayClass) List(erasedTypeRef(ObjectClass))
+ else if (clazz == ArrayClass) List(ErasedObject)
else removeLaterObjects(parents map this),
decls, clazz)
case _ =>
diff --git a/src/compiler/scala/reflect/internal/transform/UnCurry.scala b/src/compiler/scala/reflect/internal/transform/UnCurry.scala
index fd6d4e177d..0c1640ceb9 100644
--- a/src/compiler/scala/reflect/internal/transform/UnCurry.scala
+++ b/src/compiler/scala/reflect/internal/transform/UnCurry.scala
@@ -12,14 +12,8 @@ trait UnCurry {
private def expandAlias(tp: Type): Type = if (!tp.isHigherKinded) tp.normalize else tp
- private def isUnboundedGeneric(tp: Type) = tp match {
- case t @ TypeRef(_, sym, _) => sym.isAbstractType && !(t <:< AnyRefClass.tpe)
- case _ => false
- }
-
val uncurry: TypeMap = new TypeMap {
def apply(tp0: Type): Type = {
- // tp0.typeSymbolDirect.initialize
val tp = expandAlias(tp0)
tp match {
case MethodType(params, MethodType(params1, restpe)) =>
@@ -31,13 +25,13 @@ trait UnCurry {
apply(MethodType(h.cloneSymbol.resetFlag(IMPLICIT) :: t, restpe))
case NullaryMethodType(restpe) =>
apply(MethodType(List(), restpe))
- case TypeRef(pre, ByNameParamClass, List(arg)) =>
+ case TypeRef(pre, ByNameParamClass, arg :: Nil) =>
apply(functionType(List(), arg))
- case TypeRef(pre, RepeatedParamClass, args) =>
- apply(appliedType(SeqClass.typeConstructor, args))
- case TypeRef(pre, JavaRepeatedParamClass, args) =>
+ case TypeRef(pre, RepeatedParamClass, arg :: Nil) =>
+ apply(seqType(arg))
+ case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) =>
apply(arrayType(
- if (isUnboundedGeneric(args.head)) ObjectClass.tpe else args.head))
+ if (isUnboundedGeneric(arg)) ObjectClass.tpe else arg))
case _ =>
expandAlias(mapOver(tp))
}
diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala
index d26a1abadb..2e119f8ccc 100644
--- a/src/compiler/scala/reflect/internal/util/Collections.scala
+++ b/src/compiler/scala/reflect/internal/util/Collections.scala
@@ -10,6 +10,8 @@ import scala.annotation.tailrec
import mutable.ListBuffer
/** Profiler driven changes.
+ * TODO - inlining doesn't work from here because of the bug that
+ * methods in traits aren't inlined.
*/
trait Collections {
/** True if all three arguments have the same number of elements and
@@ -22,18 +24,21 @@ trait Collections {
)
/** All these mm methods are "deep map" style methods for
- * mapping etc. on a list of lists.
+ * mapping etc. on a list of lists while avoiding unnecessary
+ * intermediate structures like those created via flatten.
*/
final def mexists[A](xss: List[List[A]])(p: A => Boolean) =
xss exists (_ exists p)
+ final def mforall[A](xss: List[List[A]])(p: A => Boolean) =
+ xss forall (_ forall p)
final def mmap[A, B](xss: List[List[A]])(f: A => B) =
xss map (_ map f)
final def mforeach[A](xss: List[List[A]])(f: A => Unit) =
xss foreach (_ foreach f)
final def mfind[A](xss: List[List[A]])(p: A => Boolean): Option[A] = {
- for (xs <- xss; x <- xs)
- if (p(x)) return Some(x)
- None
+ var res: Option[A] = null
+ mforeach(xss)(x => if ((res eq null) && p(x)) res = Some(x))
+ if (res eq null) None else res
}
final def mfilter[A](xss: List[List[A]])(p: A => Boolean) =
for (xs <- xss; x <- xs; if p(x)) yield x
@@ -64,6 +69,31 @@ trait Collections {
}
lb.toList
}
+
+ final def flatCollect[A, B](elems: List[A])(pf: PartialFunction[A, Traversable[B]]): List[B] = {
+ val lb = new ListBuffer[B]
+ for (x <- elems ; if pf isDefinedAt x)
+ lb ++= pf(x)
+
+ lb.toList
+ }
+
+ final def distinctBy[A, B](xs: List[A])(f: A => B): List[A] = {
+ val buf = new ListBuffer[A]
+ val seen = mutable.Set[B]()
+ xs foreach { x =>
+ val y = f(x)
+ if (!seen(y)) {
+ buf += x
+ seen += y
+ }
+ }
+ buf.toList
+ }
+
+ @tailrec final def flattensToEmpty(xss: Seq[Seq[_]]): Boolean = {
+ xss.isEmpty || xss.head.isEmpty && flattensToEmpty(xss.tail)
+ }
final def foreachWithIndex[A, B](xs: List[A])(f: (A, Int) => Unit) {
var index = 0
@@ -75,10 +105,15 @@ trait Collections {
}
}
- @inline final def findOrElse[A](xs: TraversableOnce[A])(p: A => Boolean)(orElse: => A): A = {
+ // @inline
+ final def findOrElse[A](xs: TraversableOnce[A])(p: A => Boolean)(orElse: => A): A = {
xs find p getOrElse orElse
}
+ final def mapFrom[A, A1 >: A, B](xs: List[A])(f: A => B): Map[A1, B] = {
+ Map[A1, B](xs map (x => (x, f(x))): _*)
+ }
+
final def mapWithIndex[A, B](xs: List[A])(f: (A, Int) => B): List[B] = {
val lb = new ListBuffer[B]
var index = 0
diff --git a/src/compiler/scala/reflect/internal/util/Origins.scala b/src/compiler/scala/reflect/internal/util/Origins.scala
index b9985c8f50..19b3adda9d 100644
--- a/src/compiler/scala/reflect/internal/util/Origins.scala
+++ b/src/compiler/scala/reflect/internal/util/Origins.scala
@@ -88,7 +88,7 @@ object Origins {
sys.addShutdownHook(counters foreach (_.purge()))
}
- def apply[T: Manifest](tag: String): Origins = apply(tag, manifest[T].erasure)
+ def apply[T: ClassTag](tag: String): Origins = apply(tag, classTag[T].erasure)
def apply(tag: String, clazz: Class[_]): Origins = apply(tag, new OneLine(clazz))
def apply(tag: String, orElse: => Origins): Origins = {
counters find (_.tag == tag) getOrElse {
diff --git a/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala b/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala
new file mode 100644
index 0000000000..eb384f9a85
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala
@@ -0,0 +1,168 @@
+package scala.reflect.internal
+package util
+
+import scala.collection.{ mutable, immutable }
+
+trait TraceSymbolActivity {
+ val global: SymbolTable
+ import global._
+
+ if (traceSymbolActivity)
+ scala.sys addShutdownHook showAllSymbols()
+
+ private type Set[T] = scala.collection.immutable.Set[T]
+ private val Set = scala.collection.immutable.Set
+
+ val allSymbols = mutable.Map[Int, Symbol]()
+ val allChildren = mutable.Map[Int, List[Int]]() withDefaultValue Nil
+ val prevOwners = mutable.Map[Int, List[(Int, Phase)]]() withDefaultValue Nil
+ val symsCaused = mutable.Map[Int, Int]() withDefaultValue 0
+ val allTrees = mutable.Set[Tree]()
+
+ def recordSymbolsInTree(tree: Tree) {
+ allTrees += tree
+ }
+
+ def recordNewSymbol(sym: Symbol) {
+ if (sym.id > 1) {
+ allSymbols(sym.id) = sym
+ allChildren(sym.owner.id) ::= sym.id
+ }
+ }
+ def recordNewSymbolOwner(sym: Symbol, newOwner: Symbol) {
+ val sid = sym.id
+ val oid = sym.owner.id
+ val nid = newOwner.id
+
+ prevOwners(sid) ::= (oid -> phase)
+ allChildren(oid) = allChildren(oid) filterNot (_ == sid)
+ allChildren(nid) ::= sid
+ }
+
+ /** TODO.
+ */
+ private def reachableDirectlyFromSymbol(sym: Symbol): List[Symbol] = (
+ List(sym.owner, sym.alias, sym.thisSym)
+ ++ sym.children
+ ++ sym.info.parents.map(_.typeSymbol)
+ ++ sym.typeParams
+ ++ sym.paramss.flatten
+ )
+ private def reachable[T](inputs: Traversable[T], mkSymbol: T => Symbol): Set[Symbol] = {
+ def loop(seen: Set[Symbol], remaining: List[Symbol]): Set[Symbol] = {
+ remaining match {
+ case Nil => seen
+ case head :: rest =>
+ if ((head eq null) || (head eq NoSymbol) || seen(head)) loop(seen, rest)
+ else loop(seen + head, rest ++ reachableDirectlyFromSymbol(head).filterNot(seen))
+ }
+ }
+ loop(immutable.Set(), inputs.toList map mkSymbol filterNot (_ eq null) distinct)
+ }
+ private def treeList(t: Tree) = {
+ val buf = mutable.ListBuffer[Tree]()
+ t foreach (buf += _)
+ buf.toList
+ }
+
+ private def reachableFromSymbol(root: Symbol): Set[Symbol] =
+ reachable[Symbol](List(root, root.info.typeSymbol), x => x)
+
+ private def reachableFromTree(tree: Tree): Set[Symbol] =
+ reachable[Tree](treeList(tree), _.symbol)
+
+ private def signature(id: Int) = runBeforeErasure(allSymbols(id).defString)
+
+ private def dashes(s: Any): String = ("" + s) map (_ => '-')
+ private def show(s1: Any, ss: Any*) {
+ println("%-12s".format(s1) +: ss mkString " ")
+ }
+ private def showHeader(s1: Any, ss: Any*) {
+ show(s1, ss: _*)
+ show(dashes(s1), ss map dashes: _*)
+ }
+ private def showSym(sym: Symbol) {
+ def prefix = (" " * (sym.ownerChain.length - 1)) + sym.id
+ try println("%s#%s %s".format(prefix, sym.accurateKindString, sym.name.decode))
+ catch {
+ case x => println(prefix + " failed: " + x)
+ }
+ allChildren(sym.id).sorted foreach showIdAndRemove
+ }
+ private def showIdAndRemove(id: Int) {
+ allSymbols remove id foreach showSym
+ }
+ private def symbolStr(id: Int): String = {
+ if (id == 1) "NoSymbol" else {
+ val sym = allSymbols(id)
+ sym.accurateKindString + " " + sym.name.decode
+ }
+ }
+ private def ownerStr(id: Int): String = {
+ val sym = allSymbols(id)
+ sym.name.decode + "#" + sym.id
+ }
+
+ private def freq[T, U](xs: collection.Traversable[T])(fn: T => U): List[(U, Int)] = {
+ val ys = xs groupBy fn mapValues (_.size)
+ ys.toList sortBy (-_._2)
+ }
+
+ private def showMapFreq[T](xs: collection.Map[T, Traversable[_]])(showFn: T => String) {
+ xs.mapValues(_.size).toList.sortBy(-_._2) take 100 foreach { case (k, size) =>
+ show(size, showFn(k))
+ }
+ println("\n")
+ }
+ private def showFreq[T, U](xs: Traversable[T])(groupFn: T => U, showFn: U => String = (x: U) => "" + x) = {
+ showMapFreq(xs.toList groupBy groupFn)(showFn)
+ }
+ private lazy val findErasurePhase: Phase = {
+ var ph = phase
+ while (ph != NoPhase && ph.name != "erasure") {
+ ph = ph.prev
+ }
+ ph
+ }
+ private def runBeforeErasure[T](body: => T): T = atPhase(findErasurePhase)(body)
+
+ def showAllSymbols() {
+ if (!traceSymbolActivity) return
+ allSymbols(1) = NoSymbol
+
+ println("" + allSymbols.size + " symbols created.")
+ println("")
+
+ showHeader("descendants", "symbol")
+ showFreq(allSymbols.values flatMap (_.ownerChain drop 1))(_.id, symbolStr)
+
+ showHeader("children", "symbol")
+ showMapFreq(allChildren)(symbolStr)
+
+ if (prevOwners.nonEmpty) {
+ showHeader("prev owners", "symbol")
+ showMapFreq(prevOwners) { k =>
+ val owners = (((allSymbols(k).owner.id, NoPhase)) :: prevOwners(k)) map {
+ case (oid, NoPhase) => "-> owned by " + ownerStr(oid)
+ case (oid, ph) => "-> owned by %s (until %s)".format(ownerStr(oid), ph)
+ }
+ signature(k) :: owners mkString "\n "
+ }
+ }
+
+ val nameFreq = allSymbols.values.toList groupBy (_.name)
+ showHeader("frequency", "%-15s".format("name"), "owners")
+ showMapFreq(nameFreq) { name =>
+ "%-15s %s".format(name.decode, {
+ val owners = freq(nameFreq(name))(_.owner)
+
+ "%4s owners (%s)".format(
+ owners.size,
+ owners.take(3).map({ case (k, v) => v + "/" + k }).mkString(", ") + ", ..."
+ )
+ })
+ }
+
+ allSymbols.keys.toList.sorted foreach showIdAndRemove
+ }
+}
diff --git a/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala b/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala
new file mode 100644
index 0000000000..d78eae9237
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala
@@ -0,0 +1,6 @@
+package scala.reflect.makro
+package runtime
+
+import scala.reflect.api.Position
+
+class AbortMacroException(val pos: Position, val msg: String) extends Throwable(msg)
diff --git a/src/compiler/scala/reflect/makro/runtime/Aliases.scala b/src/compiler/scala/reflect/makro/runtime/Aliases.scala
new file mode 100644
index 0000000000..a4f208ca34
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Aliases.scala
@@ -0,0 +1,21 @@
+package scala.reflect.makro
+package runtime
+
+trait Aliases {
+ self: Context =>
+
+ /** Aliases of mirror types */
+ override type Symbol = mirror.Symbol
+ override type Type = mirror.Type
+ override type Name = mirror.Name
+ override type Tree = mirror.Tree
+ override type Position = mirror.Position
+ override type Scope = mirror.Scope
+ override type Modifiers = mirror.Modifiers
+ override type Expr[+T] = mirror.Expr[T]
+ override type TypeTag[T] = mirror.TypeTag[T]
+
+ /** Creator/extractor objects for Expr and TypeTag values */
+ override val TypeTag = mirror.TypeTag
+ override val Expr = mirror.Expr
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala b/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala
new file mode 100644
index 0000000000..4e93d4e06d
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala
@@ -0,0 +1,14 @@
+package scala.reflect.makro
+package runtime
+
+trait CapturedVariables {
+ self: Context =>
+
+ import mirror._
+
+ def captureVariable(vble: Symbol): Unit = mirror.captureVariable(vble)
+
+ def referenceCapturedVariable(vble: Symbol): Tree = mirror.referenceCapturedVariable(vble)
+
+ def capturedVariableType(vble: Symbol): Type = mirror.capturedVariableType(vble)
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala
new file mode 100644
index 0000000000..ca02822788
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Context.scala
@@ -0,0 +1,27 @@
+package scala.reflect.makro
+package runtime
+
+import scala.tools.nsc.Global
+
+abstract class Context extends scala.reflect.makro.Context
+ with Aliases
+ with CapturedVariables
+ with Infrastructure
+ with Enclosures
+ with Names
+ with Reifiers
+ with FrontEnds
+ with Settings
+ with Symbols
+ with Typers
+ with Util
+ with Traces {
+
+ val mirror: Global
+
+ val callsiteTyper: mirror.analyzer.Typer
+
+ val prefix: Expr[PrefixType]
+
+ val expandee: Tree
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala
new file mode 100644
index 0000000000..ab38fc024d
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala
@@ -0,0 +1,23 @@
+package scala.reflect.makro
+package runtime
+
+trait Enclosures {
+ self: Context =>
+
+ import mirror._
+
+ private def site = callsiteTyper.context
+ private def enclTrees = site.enclosingContextChain map (_.tree)
+ private def enclPoses = enclosingMacros map (_.macroApplication.pos) filterNot (_ eq NoPosition)
+
+ // vals are eager to simplify debugging
+ // after all we wouldn't save that much time by making them lazy
+ val macroApplication: Tree = expandee
+ val enclosingApplication: Tree = enclTrees collectFirst { case t: Apply => t } getOrElse EmptyTree
+ val enclosingClass: Tree = site.enclClass.tree
+ val enclosingImplicits: List[(Type, Tree)] = site.openImplicits
+ val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros // include self
+ val enclosingMethod: Tree = site.enclMethod.tree
+ val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos
+ val enclosingUnit: CompilationUnit = currentRun.currentUnit
+}
diff --git a/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala b/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala
new file mode 100644
index 0000000000..7cfa8e80f3
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala
@@ -0,0 +1,44 @@
+package scala.reflect.makro
+package runtime
+
+trait FrontEnds {
+ self: Context =>
+
+ import mirror._
+
+ def frontEnd: FrontEnd = wrapReporter(mirror.reporter)
+
+ def setFrontEnd(frontEnd: FrontEnd): this.type = {
+ mirror.reporter = wrapFrontEnd(frontEnd)
+ this
+ }
+
+ def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T = {
+ val old = mirror.reporter
+ setFrontEnd(frontEnd)
+ try op
+ finally mirror.reporter = old
+ }
+
+ def echo(pos: Position, msg: String): Unit = mirror.reporter.echo(pos, msg)
+
+ def info(pos: Position, msg: String, force: Boolean): Unit = mirror.reporter.info(pos, msg, force)
+
+ def hasWarnings: Boolean = mirror.reporter.hasErrors
+
+ def hasErrors: Boolean = mirror.reporter.hasErrors
+
+ def warning(pos: Position, msg: String): Unit = callsiteTyper.context.warning(pos, msg)
+
+ def error(pos: Position, msg: String): Unit = callsiteTyper.context.error(pos, msg)
+
+ def abort(pos: Position, msg: String): Nothing = {
+ callsiteTyper.context.error(pos, msg)
+ throw new AbortMacroException(pos, msg)
+ }
+
+ def interactive(): Unit = mirror.reporter match {
+ case reporter: tools.nsc.reporters.AbstractReporter => reporter.displayPrompt()
+ case _ => ()
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala b/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala
new file mode 100644
index 0000000000..6d8e55cc35
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala
@@ -0,0 +1,34 @@
+package scala.reflect.makro
+package runtime
+
+trait Infrastructure {
+ self: Context =>
+
+ val forJVM: Boolean = mirror.forJVM
+
+ val forMSIL: Boolean = mirror.forMSIL
+
+ val forInteractive: Boolean = mirror.forInteractive
+
+ val forScaladoc: Boolean = mirror.forScaladoc
+
+ val currentRun: Run = mirror.currentRun
+
+ type Run = mirror.Run
+
+ object Run extends RunExtractor {
+ def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] = Some(run.currentUnit, run.units.toList)
+ }
+
+ type CompilationUnit = mirror.CompilationUnit
+
+ object CompilationUnit extends CompilationUnitExtractor {
+ def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] = Some(compilationUnit.source.file.file, compilationUnit.source.content, compilationUnit.body)
+ }
+
+ val currentMacro: Symbol = expandee.symbol
+
+ val globalCache: collection.mutable.Map[Any, Any] = mirror.analyzer.globalMacroCache
+
+ val cache: collection.mutable.Map[Any, Any] = mirror.analyzer.perRunMacroCache.getOrElseUpdate(currentMacro, collection.mutable.Map[Any, Any]())
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Names.scala b/src/compiler/scala/reflect/makro/runtime/Names.scala
new file mode 100644
index 0000000000..d8ecc2b89e
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Names.scala
@@ -0,0 +1,20 @@
+package scala.reflect.makro
+package runtime
+
+trait Names {
+ self: Context =>
+
+ lazy val freshNameCreator = callsiteTyper.context.unit.fresh
+
+ def fresh(): String = {
+ freshNameCreator.newName()
+ }
+
+ def fresh(name: String): String = {
+ freshNameCreator.newName(name)
+ }
+
+ def fresh(name: Name): Name = {
+ name.mapName(freshNameCreator.newName(_))
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
new file mode 100644
index 0000000000..1c5af4b752
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
@@ -0,0 +1,34 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Gilles Dubochet
+ */
+
+package scala.reflect.makro
+package runtime
+
+trait Reifiers {
+ self: Context =>
+
+ import mirror._
+ import definitions._
+
+ lazy val reflectMirrorPrefix: Tree = ReflectMirrorPrefix
+
+ def reifyTree(prefix: Tree, tree: Tree): Tree = {
+ val result = scala.reflect.reify.`package`.reifyTree(mirror)(callsiteTyper, prefix, tree)
+ logFreeVars(enclosingPosition, result)
+ result
+ }
+
+ def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Tree = {
+ val result = scala.reflect.reify.`package`.reifyType(mirror)(callsiteTyper, prefix, tpe, dontSpliceAtTopLevel, concrete)
+ logFreeVars(enclosingPosition, result)
+ result
+ }
+
+ def reifyErasure(tpe: Type, concrete: Boolean = true): Tree =
+ scala.reflect.reify.`package`.reifyErasure(mirror)(callsiteTyper, tpe, concrete)
+
+ def unreifyTree(tree: Tree): Tree =
+ Select(tree, definitions.ExprEval)
+}
diff --git a/src/compiler/scala/reflect/makro/runtime/Settings.scala b/src/compiler/scala/reflect/makro/runtime/Settings.scala
new file mode 100644
index 0000000000..32f7115db8
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Settings.scala
@@ -0,0 +1,36 @@
+package scala.reflect.makro
+package runtime
+
+trait Settings {
+ self: Context =>
+
+ def settings: List[String] = {
+ val optionName = mirror.settings.XmacroSettings.name
+ val settings = compilerSettings.find(opt => opt.startsWith(optionName)).map(opt => opt.substring(optionName.length + 1)).getOrElse("")
+ settings.split(",").toList
+ }
+
+ def compilerSettings: List[String] = mirror.settings.recreateArgs
+
+ def setCompilerSettings(options: String): this.type =
+ // todo. is not going to work with quoted arguments with embedded whitespaces
+ setCompilerSettings(options.split(" ").toList)
+
+ def setCompilerSettings(options: List[String]): this.type = {
+ val settings = new tools.nsc.Settings(_ => ())
+ // [Eugene] what settings should we exclude?
+ settings.copyInto(mirror.settings)
+ this
+ }
+
+ def withCompilerSettings[T](options: String)(op: => T): T =
+ // todo. is not going to work with quoted arguments with embedded whitespaces
+ withCompilerSettings(options.split(" ").toList)(op)
+
+ def withCompilerSettings[T](options: List[String])(op: => T): T = {
+ val old = options
+ setCompilerSettings(options)
+ try op
+ finally setCompilerSettings(old)
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Symbols.scala b/src/compiler/scala/reflect/makro/runtime/Symbols.scala
new file mode 100644
index 0000000000..6341523486
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Symbols.scala
@@ -0,0 +1,10 @@
+package scala.reflect.makro
+package runtime
+
+trait Symbols {
+ self: Context =>
+
+ def isLocatable(sym: Symbol) = sym.isLocatable
+
+ def isStatic(sym: Symbol) = sym.isStatic
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Traces.scala b/src/compiler/scala/reflect/makro/runtime/Traces.scala
new file mode 100644
index 0000000000..6b61842316
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Traces.scala
@@ -0,0 +1,8 @@
+package scala.reflect.makro
+package runtime
+
+trait Traces extends util.Traces {
+ self: Context =>
+
+ def globalSettings = mirror.settings
+}
diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala
new file mode 100644
index 0000000000..c61e492250
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala
@@ -0,0 +1,75 @@
+package scala.reflect.makro
+package runtime
+
+trait Typers {
+ self: Context =>
+
+ def openMacros: List[Context] = this :: mirror.analyzer.openMacros
+
+ def openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits
+
+ def typeCheck(tree: Tree, pt: Type = mirror.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled))
+ val wrapper1 = if (!withImplicitViewsDisabled) (callsiteTyper.context.withImplicitsEnabled[Tree] _) else (callsiteTyper.context.withImplicitsDisabled[Tree] _)
+ val wrapper2 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[Tree] _) else (callsiteTyper.context.withMacrosDisabled[Tree] _)
+ def wrapper (tree: => Tree) = wrapper1(wrapper2(tree))
+ // if you get a "silent mode is not available past typer" here
+ // don't rush to change the typecheck not to use the silent method when the silent parameter is false
+ // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time
+ // I'd advise fixing the root cause: finding why the context is not set to report errors
+ // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you)
+ wrapper(callsiteTyper.silent(_.typed(tree, mirror.analyzer.EXPRmode, pt)) match {
+ case mirror.analyzer.SilentResultValue(result) =>
+ macroLogVerbose(result)
+ result
+ case error @ mirror.analyzer.SilentTypeError(_) =>
+ macroLogVerbose(error.err.errMsg)
+ if (!silent) throw new mirror.TypeError(error.err.errPos, error.err.errMsg)
+ mirror.EmptyTree
+ })
+ }
+
+ def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = {
+ macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled))
+ import mirror.analyzer.SearchResult
+ val context = callsiteTyper.context
+ val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
+ def wrapper (inference: => SearchResult) = wrapper1(inference)
+ wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match {
+ case failure if failure.tree.isEmpty =>
+ macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
+ if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
+ mirror.EmptyTree
+ case success =>
+ success.tree
+ }
+ }
+
+ def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree = {
+ macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous))
+ import mirror.analyzer.SearchResult
+ val context = callsiteTyper.context
+ val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
+ def wrapper (inference: => SearchResult) = wrapper1(inference)
+ val fun1 = mirror.definitions.FunctionClass(1)
+ val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to))
+ wrapper(mirror.analyzer.inferImplicit(tree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match {
+ case failure if failure.tree.isEmpty =>
+ macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
+ if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
+ mirror.EmptyTree
+ case success =>
+ success.tree
+ }
+ }
+
+ type TypeError = mirror.TypeError
+
+ object TypeError extends TypeErrorExtractor {
+ def unapply(error: TypeError): Option[(Position, String)] = Some((error.pos, error.msg))
+ }
+
+ def resetAllAttrs[T <: Tree](tree: T): T = mirror.resetAllAttrs(tree)
+
+ def resetLocalAttrs[T <: Tree](tree: T): T = mirror.resetLocalAttrs(tree)
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Util.scala b/src/compiler/scala/reflect/makro/runtime/Util.scala
new file mode 100644
index 0000000000..2671155721
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Util.scala
@@ -0,0 +1,34 @@
+package scala.reflect.makro
+package runtime
+
+trait Util {
+ self: Context =>
+
+ import mirror._
+
+ def literalNull = Expr[Null](Literal(Constant(null)))(TypeTag.Null)
+
+ def literalUnit = Expr[Unit](Literal(Constant(())))(TypeTag.Unit)
+
+ def literalTrue = Expr[Boolean](Literal(Constant(true)))(TypeTag.Boolean)
+
+ def literalFalse = Expr[Boolean](Literal(Constant(false)))(TypeTag.Boolean)
+
+ def literal(x: Boolean) = Expr[Boolean](Literal(Constant(x)))(TypeTag.Boolean)
+
+ def literal(x: Byte) = Expr[Byte](Literal(Constant(x)))(TypeTag.Byte)
+
+ def literal(x: Short) = Expr[Short](Literal(Constant(x)))(TypeTag.Short)
+
+ def literal(x: Int) = Expr[Int](Literal(Constant(x)))(TypeTag.Int)
+
+ def literal(x: Long) = Expr[Long](Literal(Constant(x)))(TypeTag.Long)
+
+ def literal(x: Float) = Expr[Float](Literal(Constant(x)))(TypeTag.Float)
+
+ def literal(x: Double) = Expr[Double](Literal(Constant(x)))(TypeTag.Double)
+
+ def literal(x: String) = Expr[String](Literal(Constant(x)))(TypeTag.String)
+
+ def literal(x: Char) = Expr[Char](Literal(Constant(x)))(TypeTag.Char)
+}
diff --git a/src/compiler/scala/reflect/makro/util/Traces.scala b/src/compiler/scala/reflect/makro/util/Traces.scala
new file mode 100644
index 0000000000..2363cc4bac
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/util/Traces.scala
@@ -0,0 +1,18 @@
+package scala.reflect.makro
+package util
+
+trait Traces {
+ def globalSettings: tools.nsc.Settings
+
+ // [Eugene] lots of ways to log:
+ // 1) trace(...)
+ // 2) log(...)
+ // 3) if (foo) { doStuff(); includingSomeLogs(); }
+ // what is the conventional way of unifying this?
+ val macroDebugLite = globalSettings.YmacrodebugLite.value
+ val macroDebugVerbose = globalSettings.YmacrodebugVerbose.value
+ val macroTraceLite = scala.tools.nsc.util.trace when (macroDebugLite || macroDebugVerbose)
+ val macroTraceVerbose = scala.tools.nsc.util.trace when macroDebugVerbose
+ @inline final def macroLogLite(msg: => Any) { if (macroDebugLite || macroDebugVerbose) println(msg) }
+ @inline final def macroLogVerbose(msg: => Any) { if (macroDebugVerbose) println(msg) }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala
new file mode 100644
index 0000000000..4466f281b8
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/Errors.scala
@@ -0,0 +1,60 @@
+package scala.reflect
+package reify
+
+import scala.reflect.makro.ReificationError
+import scala.reflect.makro.UnexpectedReificationError
+
+trait Errors {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+
+ def defaultErrorPosition = analyzer.enclosingMacroPosition
+
+ // expected errors: these can happen if the user casually writes whatever.reify(...)
+ // hence we don't crash here, but nicely report a typechecking error and bail out asap
+
+ def CannotReifyReifeeThatHasTypeLocalToReifee(tree: Tree) = {
+ val msg = "implementation restriction: cannot reify block of type %s that involves a type declared inside the block being reified. consider casting the return value to a suitable type".format(tree.tpe)
+ throw new ReificationError(tree.pos, msg)
+ }
+
+ def CannotReifyType(tpe: Type) = {
+ val msg = "implementation restriction: cannot reify type %s (%s)".format(tpe, tpe.kind)
+ throw new ReificationError(defaultErrorPosition, msg)
+ }
+
+ def CannotReifySymbol(sym: Symbol) = {
+ val msg = "implementation restriction: cannot reify symbol %s (%s)".format(sym, sym.accurateKindString)
+ throw new ReificationError(defaultErrorPosition, msg)
+ }
+
+ def CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe: Type) = {
+ val msg = "cannot reify ConcreteTypeTag having unresolved type parameter %s".format(tpe)
+ throw new ReificationError(defaultErrorPosition, msg)
+ }
+
+ // unexpected errors: these can never happen under normal conditions unless there's a bug in the compiler (or in a compiler plugin or in a macro)
+ // hence, we fail fast and loudly and don't care about being nice - in this situation noone will appreciate our quiet nicety
+
+ def CannotReifyUntypedPrefix(prefix: Tree) = {
+ val msg = "internal error: untyped prefixes are not supported, consider typechecking the prefix before passing it to the reifier"
+ throw new UnexpectedReificationError(defaultErrorPosition, msg)
+ }
+
+ def CannotReifyUntypedReifee(reifee: Any) = {
+ val msg = "internal error: untyped trees are not supported, consider typechecking the reifee before passing it to the reifier"
+ throw new UnexpectedReificationError(defaultErrorPosition, msg)
+ }
+
+ def CannotReifyErroneousPrefix(prefix: Tree) = {
+ val msg = "internal error: erroneous prefixes are not supported, make sure that your prefix has typechecked successfully before passing it to the reifier"
+ throw new UnexpectedReificationError(defaultErrorPosition, msg)
+ }
+
+ def CannotReifyErroneousReifee(reifee: Any) = {
+ val msg = "internal error: erroneous reifees are not supported, make sure that your reifee has typechecked successfully before passing it to the reifier"
+ throw new UnexpectedReificationError(defaultErrorPosition, msg)
+ }
+}
diff --git a/src/compiler/scala/reflect/reify/NodePrinters.scala b/src/compiler/scala/reflect/reify/NodePrinters.scala
new file mode 100644
index 0000000000..eaca9a4968
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/NodePrinters.scala
@@ -0,0 +1,111 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package reify
+
+import scala.Array.canBuildFrom
+import scala.compat.Platform.EOL
+import scala.tools.nsc.symtab.Flags
+import scala.tools.nsc.Global
+
+trait NodePrinters { self: scala.tools.nsc.ast.NodePrinters =>
+
+ val global: Global
+ import global._
+
+ object reifiedNodeToString extends Function2[Tree, Tree, String] {
+ def apply(prefix: Tree, tree: Tree): String = {
+ import scala.reflect.api.Modifier
+ var modifierIsUsed = false
+ var flagsAreUsed = false
+
+ // @PP: I fervently hope this is a test case or something, not anything being
+ // depended upon. Of more fragile code I cannot conceive.
+ // @Eugene: This stuff is only needed to debug-print out reifications in human-readable format
+ // Rolling a full-fledged, robust TreePrinter would be several times more code.
+ val (List(mirror), reified) = (for (line <- (tree.toString.split(EOL).toList drop 1 dropRight 1)) yield {
+ var s = line.trim
+ s = s.replace("$mr.", "")
+ s = s.replace(".apply", "")
+ s = s.replace("scala.collection.immutable.", "")
+ s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List")
+ s = "List\\[.*?\\]".r.replaceAllIn(s, "List")
+ s = s.replace("immutable.this.Nil", "List()")
+ s = s.replace("modifiersFromInternalFlags", "Modifiers")
+ s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()")
+ s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => {
+ val buf = new collection.mutable.ListBuffer[String]
+
+ val annotations = m.group(3)
+ if (buf.nonEmpty || annotations.nonEmpty)
+ buf.append("List(" + annotations + ")")
+
+ val privateWithin = "" + m.group(2)
+ if (buf.nonEmpty || privateWithin != "")
+ buf.append("newTypeName(\"" + privateWithin + "\")")
+
+ val flags = m.group(1).toLong
+ val s_flags = Flags.modifiersOfFlags(flags) map (_.sourceString) mkString ", "
+ if (buf.nonEmpty || s_flags != "") {
+ modifierIsUsed = true
+ buf.append("Set(" + s_flags + ")")
+ }
+
+ "Modifiers(" + buf.reverse.mkString(", ") + ")"
+ })
+ s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => {
+ flagsAreUsed = true
+ val flags = m.group(1).toLong
+ val mods = Flags.modifiersOfFlags(flags) map (_.sourceString)
+ "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))"
+ })
+
+ s
+ }) splitAt 1
+
+ val printout = collection.mutable.ListBuffer(mirror);
+ printout += "import " + nme.MIRROR_SHORT + "._"
+ if (modifierIsUsed) printout += "import scala.reflect.api.Modifier._"
+ if (flagsAreUsed) printout += "import scala.reflect.internal.Flags._"
+ val body = reified dropWhile (_.startsWith("val"))
+ if (body.length > 0 && body(0).startsWith("Expr[")) {
+ if (reified(0) startsWith "val") {
+ printout += "val code = {"
+ printout ++= (reified map (" " + _))
+ printout += "}"
+ printout += "mkToolBox().runExpr(code)"
+ } else {
+ printout += "val code = " + reified(0)
+ printout ++= reified drop 1
+ printout += "mkToolBox().runExpr(code)"
+ }
+ try {
+ val prefix = Select(Select(Ident(definitions.ScalaPackage), newTermName("reflect")), newTermName("mirror"))
+ val tree1 = new global.Transformer {
+ override def transform(tree: Tree) = super.transform(tree match {
+ case Block(ValDef(_, mr, _, _) :: Nil, expr) if mr == nme.MIRROR_SHORT => transform(expr)
+ case Block(ValDef(_, mr, _, _) :: symbolTable, expr) if mr == nme.MIRROR_SHORT => transform(Block(symbolTable, expr))
+ case Select(Ident(mr), name) if mr == nme.MIRROR_SHORT => Select(prefix, name)
+ case tree => tree
+ })
+ }.transform(tree)
+ val stringified = mkToolBox().runExpr(tree1).toString
+ if (settings.Yreifydebug.value) printout += "*****************************"
+ printout += stringified
+ } catch {
+ case ex: Throwable =>
+// val realex = ReflectionUtils.unwrapThrowable(ex)
+// val message = new java.io.StringWriter()
+// realex.printStackTrace(new java.io.PrintWriter(message))
+// println(message)
+ }
+ } else {
+ printout ++= reified
+ }
+ printout mkString EOL
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/Phases.scala b/src/compiler/scala/reflect/reify/Phases.scala
new file mode 100644
index 0000000000..49d5a45e8e
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/Phases.scala
@@ -0,0 +1,42 @@
+package scala.reflect
+package reify
+
+import scala.reflect.reify.phases._
+
+trait Phases extends Calculate
+ with Reshape
+ with Metalevels
+ with Reify {
+
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+
+ private var alreadyRun = false
+
+ lazy val mkReificationPipeline: Tree => Tree = tree0 => {
+ assert(!alreadyRun, "reifier instance cannot be used more than once")
+ alreadyRun = true
+
+ var tree = tree0
+
+ if (reifyDebug) println("[calculate phase]")
+ calculate.traverse(tree)
+
+ if (reifyDebug) println("[reshape phase]")
+ tree = reshape.transform(tree)
+
+ if (reifyDebug) println("[metalevels phase]")
+ tree = metalevels.transform(tree)
+
+ if (reifyDebug) println("[interlude]")
+ if (reifyDebug) println("symbol table = " + (if (symbolTable.length == 0) "<empty>" else ""))
+ if (reifyDebug) symbolTable foreach (println(_))
+ if (reifyDebug) println("reifee = " + (if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString))
+ if (reifyDebug) println("[reify phase]")
+ var result = reify(tree)
+
+ result
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
new file mode 100644
index 0000000000..fea825358e
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -0,0 +1,164 @@
+package scala.reflect
+package reify
+
+import scala.tools.nsc.Global
+import scala.reflect.makro.ReificationError
+import scala.reflect.makro.UnexpectedReificationError
+
+/** Given a tree or a type, generate a tree that when executed at runtime produces the original tree or type.
+ * See more info in the comments to ``reify'' in scala.reflect.api.Universe.
+ *
+ * @author Martin Odersky
+ * @version 2.10
+ */
+abstract class Reifier extends Phases
+ with Errors {
+
+ val mirror: Global
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ val typer: mirror.analyzer.Typer
+ val prefix: Tree
+ val reifee: Any
+ val dontSpliceAtTopLevel: Boolean
+ val concrete: Boolean
+
+ /**
+ * For ``reifee'' and other reification parameters, generate a tree of the form
+ *
+ * {
+ * val $mr = <[ prefix ]>
+ * $mr.Expr[T](rtree) // if data is a Tree
+ * $mr.TypeTag[T](rtree) // if data is a Type
+ * }
+ *
+ * where
+ *
+ * - `prefix` is the tree that represents the universe
+ * the result will be bound to
+ * - `rtree` is code that generates `reifee` at runtime.
+ * - `T` is the type that corresponds to `data`.
+ *
+ * This is not a method, but a value to indicate the fact that Reifier instances are a one-off.
+ */
+ lazy val reified: Tree = {
+ try {
+ // [Eugene] conventional way of doing this?
+ if (prefix exists (_.isErroneous)) CannotReifyErroneousPrefix(prefix)
+ if (prefix.tpe == null) CannotReifyUntypedPrefix(prefix)
+
+ val rtree = reifee match {
+ case tree: Tree =>
+ reifyTrace("reifying = ")(if (opt.showTrees) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString)
+ reifyTrace("reifee is located at: ")(tree.pos)
+ reifyTrace("prefix = ")(prefix)
+ // [Eugene] conventional way of doing this?
+ if (tree exists (_.isErroneous)) CannotReifyErroneousReifee(prefix)
+ if (tree.tpe == null) CannotReifyUntypedReifee(tree)
+ val pipeline = mkReificationPipeline
+ val rtree = pipeline(tree)
+
+ // consider the following code snippet
+ //
+ // val x = reify { class C; new C }
+ //
+ // inferred type for x will be C
+ // but C ceases to exist after reification so this type is clearly incorrect
+ // however, reify is "just" a library function, so it cannot affect type inference
+ //
+ // hence we crash here even though the reification itself goes well
+ // fortunately, all that it takes to fix the error is to cast "new C" to Object
+ // so I'm not very much worried about introducing this restriction
+ if (tree.tpe exists (sub => sub.typeSymbol.isLocalToReifee))
+ CannotReifyReifeeThatHasTypeLocalToReifee(tree)
+
+ val taggedType = typer.packedType(tree, NoSymbol)
+ val tagModule = if (reificationIsConcrete) ConcreteTypeTagModule else TypeTagModule
+ val tagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(taggedType)))
+ val exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(taggedType)))
+ val tagArgs = List(reify(taggedType), reifyErasure(mirror)(typer, taggedType, concrete = false))
+ Apply(Apply(exprCtor, List(rtree)), List(Apply(tagCtor, tagArgs)))
+
+ case tpe: Type =>
+ reifyTrace("reifying = ")(tpe.toString)
+ reifyTrace("prefix = ")(prefix)
+ val rtree = reify(tpe)
+
+ val taggedType = tpe
+ val tagModule = if (reificationIsConcrete) ConcreteTypeTagModule else TypeTagModule
+ val ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(taggedType)))
+ val args = List(rtree, reifyErasure(mirror)(typer, taggedType, concrete = false))
+ Apply(ctor, args)
+
+ case _ =>
+ throw new Error("reifee %s of type %s is not supported".format(reifee, if (reifee == null) "null" else reifee.getClass.toString))
+ }
+
+ val mirrorAlias = ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(prefix), prefix)
+ val wrapped = Block(mirrorAlias :: symbolTable, rtree)
+
+ // todo. why do we resetAllAttrs?
+ //
+ // typically we do some preprocessing before reification and
+ // the code emitted/moved around during preprocessing is very hard to typecheck, so we leave it as it is
+ // however this "as it is" sometimes doesn't make any sense
+ //
+ // ===example 1===
+ // we move a freevar from a nested symbol table to a top-level symbol table,
+ // and then the reference to mr$ becomes screwed up, because nested symbol tables are already typechecked,
+ // so we have an mr$ symbol that points to the nested mr$ rather than to the top-level one.
+ //
+ // ===example 2===
+ // we inline a freevar by replacing a reference to it, e.g. $mr.Apply($mr.Select($mr.Ident($mr.newTermName("$mr")), $mr.newTermName("Ident")), List($mr.Ident($mr.newTermName("free$x"))))
+ // with its original binding (e.g. $mr.Ident("x"))
+ // we'd love to typecheck the result, but we cannot do this easily, because $mr is external to this tree
+ // what's even worse, sometimes $mr can point to the top-level symbol table's $mr, which doesn't have any symbol/type yet -
+ // it's just a ValDef that will be emitted only after the reification is completed
+ //
+ // hence, the simplest solution is to erase all attrs so that invalid (as well as non-existent) bindings get rebound correctly
+ // this is ugly, but it's the best we can do
+ //
+ // todo. this is a common problem with non-trivial macros in our current macro system
+ // needs to be solved some day
+ //
+ // list of non-hygienic transformations:
+ // 1) local freetype inlining in Nested
+ // 2) external freevar moving in Nested
+ // 3) local freeterm inlining in Metalevels
+ // 4) trivial tree splice inlining in Reify (Trees.scala)
+ // 5) trivial type splice inlining in Reify (Types.scala)
+ val freevarBindings = symbolTable collect { case entry @ FreeDef(_, _, binding, _, _) => binding.symbol } toSet
+ // [Eugene] yeah, ugly and extremely brittle, but we do need to do resetAttrs. will be fixed later
+ var importantSymbols = Set[Symbol](PredefModule, ScalaRunTimeModule)
+ importantSymbols ++= importantSymbols map (_.companionSymbol)
+ importantSymbols ++= importantSymbols map (_.moduleClass)
+ importantSymbols ++= importantSymbols map (_.linkedClassOfClass)
+ def importantSymbol(sym: Symbol): Boolean = sym != null && sym != NoSymbol && importantSymbols(sym)
+ val untyped = resetAllAttrs(wrapped, leaveAlone = {
+ case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true
+ case tree if freevarBindings contains tree.symbol => true
+ case tree if importantSymbol(tree.symbol) => true
+ case _ => false
+ })
+
+ if (reifyCopypaste) {
+ if (reifyDebug) println("=============================")
+ println(reifiedNodeToString(prefix, untyped))
+ if (reifyDebug) println("=============================")
+ } else {
+ reifyTrace("reified = ")(untyped)
+ }
+
+ untyped
+ } catch {
+ case ex: ReificationError =>
+ throw ex
+ case ex: UnexpectedReificationError =>
+ throw ex
+ case ex: Throwable =>
+ throw new UnexpectedReificationError(defaultErrorPosition, "reification crashed", ex)
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala b/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala
new file mode 100644
index 0000000000..1d218317dc
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala
@@ -0,0 +1,56 @@
+package scala.reflect.reify
+package codegen
+
+trait AnnotationInfos {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ // usually annotations are reified as their originals from Modifiers
+ // however, when reifying free and tough types, we're forced to reify annotation infos as is
+ // why is that bad? take a look inside
+ def reifyAnnotationInfo(ann: AnnotationInfo): Tree = {
+ val reifiedArgs = ann.args map { arg =>
+ val saved1 = reifyTreeSymbols
+ val saved2 = reifyTreeTypes
+
+ try {
+ // one more quirk of reifying annotations
+ //
+ // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs
+ // that's because a lot of logic expects post-typer trees to have non-null tpes
+ //
+ // Q: reified trees are pre-typer, so there's shouldn't be a problem.
+ // reflective typechecker will fill in missing symbols and types, right?
+ // A: actually, no. annotation ASTs live inside AnnotatedTypes,
+ // and insides of the types is the place where typechecker doesn't look.
+ reifyTreeSymbols = true
+ reifyTreeTypes = true
+
+ // todo. every AnnotationInfo is an island, entire of itself
+ // no regular Traverser or Transformer can reach it
+ // hence we need to run its contents through the entire reification pipeline
+ // e.g. to apply reshaping or to check metalevels
+ reify(arg)
+ } finally {
+ reifyTreeSymbols = saved1
+ reifyTreeTypes = saved2
+ }
+ }
+
+ def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match {
+ case LiteralAnnotArg(const) =>
+ mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const))
+ case ArrayAnnotArg(args) =>
+ mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*))
+ case NestedAnnotArg(ann) =>
+ mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann))
+ }
+
+ // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important
+ val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2)))
+ mirrorFactoryCall(nme.AnnotationInfo, reify(ann.atp), mkList(reifiedArgs), mkList(reifiedAssocs))
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/Names.scala b/src/compiler/scala/reflect/reify/codegen/Names.scala
new file mode 100644
index 0000000000..589f6355d0
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Names.scala
@@ -0,0 +1,15 @@
+package scala.reflect.reify
+package codegen
+
+trait Names {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ def reifyName(name: Name) = {
+ val factory = if (name.isTypeName) nme.nmeNewTypeName else nme.nmeNewTermName
+ mirrorCall(factory, Literal(Constant(name.toString)))
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/Positions.scala b/src/compiler/scala/reflect/reify/codegen/Positions.scala
new file mode 100644
index 0000000000..ac9195ef31
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Positions.scala
@@ -0,0 +1,18 @@
+package scala.reflect.reify
+package codegen
+
+trait Positions {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ // we do not reify positions because this inflates resulting trees, but doesn't buy as anything
+ // where would one use positions? right, in error messages
+ // but I can hardly imagine when one would need a position that points to the reified code
+ // usually reified trees are used to compose macro expansions or to be fed to the runtime compiler
+ // however both macros and toolboxes have their own means to report errors in synthetic trees
+ def reifyPosition(pos: Position): Tree =
+ reifyMirrorObject(NoPosition)
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/Symbols.scala b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
new file mode 100644
index 0000000000..21a08b7efb
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
@@ -0,0 +1,184 @@
+package scala.reflect.reify
+package codegen
+
+trait Symbols {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ /** Reify a reference to a symbol */
+ def reifySymRef(sym0: Symbol): Tree = {
+ assert(sym0 != null, "sym is null")
+ val sym = sym0.dealias
+
+ if (sym == NoSymbol)
+ mirrorSelect(nme.NoSymbol)
+ else if (sym == RootPackage)
+ Select(mirrorSelect(nme.definitions), nme.RootPackage)
+ else if (sym == RootClass)
+ Select(mirrorSelect(nme.definitions), nme.RootClass)
+ else if (sym == EmptyPackage)
+ Select(mirrorSelect(nme.definitions), nme.EmptyPackage)
+ else if (sym == EmptyPackageClass)
+ Select(mirrorSelect(nme.definitions), nme.EmptyPackageClass)
+ else if (sym.isModuleClass)
+ Select(reify(sym.sourceModule), nme.moduleClass)
+ else if (sym.isLocatable) {
+ // [Eugene] am I doing this right?
+// if (sym.isStaticOwner) { // no good for us, because it returns false for packages
+ if (sym.isStatic && (sym.isClass || sym.isModule)) {
+ val resolver = if (sym.isType) nme.staticClass else nme.staticModule
+ mirrorCall(resolver, reify(sym.fullName))
+ } else {
+ if (reifyDebug) println("Locatable: %s (%s) owned by %s (%s) at %s".format(sym, sym.accurateKindString, sym.owner, sym.owner.accurateKindString, sym.owner.fullNameString))
+ val rowner = reify(sym.owner)
+ val rname = reify(sym.name.toString)
+ if (sym.isType)
+ mirrorCall(nme.selectType, rowner, rname)
+ else if (sym.isMethod && sym.owner.isClass && sym.owner.info.decl(sym.name).isOverloaded) {
+ val index = sym.owner.info.decl(sym.name).alternatives indexOf sym
+ assert(index >= 0, sym)
+ mirrorCall(nme.selectOverloadedMethod, rowner, rname, reify(index))
+ } else
+ mirrorCall(nme.selectTerm, rowner, rname)
+ }
+ } else {
+ // todo. make sure that free methods and free local defs work correctly
+ if (sym.isTerm) reifyFreeTerm(sym, Ident(sym))
+ else reifyFreeType(sym, Ident(sym))
+ }
+ }
+
+ def reifyFreeTerm(sym: Symbol, value: Tree): Tree =
+ locallyReified get sym match {
+ case Some(reified) =>
+ reified
+ case None =>
+ if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym + "(" + sym.accurateKindString + ")")
+ var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name)
+ if (sym.isType) name = name.append(nme.MIRROR_FREE_THIS_SUFFIX)
+ if (sym.isCapturedVariable) {
+ assert(value.isInstanceOf[Ident], showRaw(value))
+ val capturedTpe = capturedVariableType(sym)
+ val capturedValue = referenceCapturedVariable(sym)
+ locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(sym.flags), reify(origin(sym))))
+ } else {
+ locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, reify(sym.flags), reify(origin(sym))))
+ }
+ }
+
+ def reifyFreeType(sym: Symbol, value: Tree): Tree =
+ locallyReified get sym match {
+ case Some(reified) =>
+ reified
+ case None =>
+ if (reifyDebug) println("Free type: %s (%s)".format(sym, sym.accurateKindString))
+ var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name)
+ val phantomTypeTag = Apply(TypeApply(Select(Ident(nme.MIRROR_SHORT), nme.TypeTag), List(value)), List(Literal(Constant(null)), Literal(Constant(null))))
+ val flavor = if (sym.isExistential) nme.newFreeExistential else nme.newFreeType
+ locallyReify(sym, name, mirrorCall(flavor, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(sym.flags), reify(origin(sym))))
+ }
+
+ def reifySymDef(sym: Symbol): Tree =
+ locallyReified get sym match {
+ case Some(reified) =>
+ reified
+ case None =>
+ if (reifyDebug) println("Sym def: %s (%s)".format(sym, sym.accurateKindString))
+ assert(!sym.isLocatable, sym) // if this assertion fires, then tough type reification needs to be rethought
+ sym.owner.ownersIterator find (!_.isLocatable) foreach reifySymDef
+ var name = newTermName(nme.MIRROR_SYMDEF_PREFIX + sym.name)
+ locallyReify(sym, name, Apply(Select(reify(sym.owner), nme.newNestedSymbol), List(reify(sym.name), reify(sym.pos), reify(sym.flags), reify(sym.isClass))))
+ }
+
+ // todo. very brittle abstraction, needs encapsulation
+ import scala.collection.mutable._
+ private val localReifications = ArrayBuffer[Tree]()
+ private val locallyReified = Map[Symbol, Tree]()
+ private var filledIn = false
+ def symbolTable: List[Tree] = { fillInSymbolTable(); localReifications.toList }
+ def symbolTable_=(newSymbolTable: List[Tree]): Unit = {
+ localReifications.clear()
+ locallyReified.clear()
+ filledIn = false
+ newSymbolTable foreach {
+ case entry =>
+ val att = entry.attachmentOpt[ReifyAttachment]
+ att match {
+ case Some(ReifyAttachment(sym)) =>
+ // don't duplicate reified symbols when merging inlined reifee
+ if (!(locallyReified contains sym)) {
+ val ValDef(_, name, _, _) = entry
+ localReifications += entry
+ locallyReified(sym) = Ident(name)
+ }
+ case other =>
+ // do nothing => symbol table fill-ins will be repopulated later
+ }
+ }
+ }
+
+ private def localName(name0: TermName): TermName = {
+ var name = name0.toString
+ name = name.replace(".type", "$type")
+ name = name.replace(" ", "$")
+ val fresh = typer.context.unit.fresh
+ newTermName(fresh.newName(name))
+ }
+
+ private def locallyReify(sym: Symbol, name0: TermName, reificode: => Tree): Tree = {
+ val reified = reificode
+ val name = localName(name0)
+ // todo. tried to declare a private class here to carry an attachment, but it's path-dependent
+ // so got troubles with exchanging free variables between nested and enclosing quasiquotes
+ // attaching just Symbol isn't good either, so we need to think of a principled solution
+ val local = ValDef(NoMods, name, TypeTree(), reified) withAttachment ReifyAttachment(sym)
+ localReifications += local
+ filledIn = false
+ locallyReified(sym) = Ident(name)
+ locallyReified(sym)
+ }
+
+ /** Sets type signatures and annotations for locally reified symbols */
+ private def fillInSymbolTable() = {
+ if (!filledIn) {
+ val fillIns = new ArrayBuffer[Tree]
+ var i = 0
+ while (i < localReifications.length) {
+ // fillInSymbol might create new locallyReified symbols, that's why this is done iteratively
+ val reified = localReifications(i)
+ val att = reified.attachmentOpt[ReifyAttachment]
+ att match {
+ case Some(ReifyAttachment(sym)) => fillIns += fillInSymbol(sym)
+ case other => // do nothing
+ }
+ i += 1
+ }
+
+ filledIn = true
+ localReifications ++= fillIns.toList
+ }
+ }
+
+ /** Generate code to add type and annotation info to a reified symbol */
+ private def fillInSymbol(sym: Symbol): Tree = {
+ if (reifyDebug) println("Filling in: %s (%s)".format(sym, sym.accurateKindString))
+ val isFree = locallyReified(sym) match { case Ident(name) => name startsWith nme.MIRROR_FREE_PREFIX }
+ if (isFree) {
+ if (sym.annotations.isEmpty) EmptyTree
+ else Apply(Select(locallyReified(sym), nme.setAnnotations), List(reify(sym.annotations)))
+ } else {
+ import scala.reflect.internal.Flags._
+ if (sym hasFlag LOCKED) {
+ // [Eugene] better to have a symbol without a type signature, than to crash with a CyclicReference
+ EmptyTree
+ } else {
+ val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reify(sym.info)))
+ if (sym.annotations.isEmpty) rset
+ else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations)))
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/Trees.scala b/src/compiler/scala/reflect/reify/codegen/Trees.scala
new file mode 100644
index 0000000000..c9f5fc5b8d
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala
@@ -0,0 +1,259 @@
+package scala.reflect.reify
+package codegen
+
+trait Trees {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+ import scala.reflect.api.Modifier
+
+ // unfortunately, these are necessary to reify AnnotatedTypes
+ // I'd gladly got rid of them, but I don't fancy making a metaprogramming API that doesn't work with annotated types
+ var reifyTreeSymbols = false
+ var reifyTreeTypes = false
+
+ /**
+ * Reify a tree.
+ * For internal use only, use ``reified'' instead.
+ */
+ def reifyTree(tree: Tree): Tree = {
+ assert(tree != null, "tree is null")
+
+ if (tree.isErroneous)
+ CannotReifyErroneousReifee(tree)
+
+ val splicedTree = spliceTree(tree)
+ if (splicedTree != EmptyTree)
+ return splicedTree
+
+ // the idea behind the new reincarnation of reifier is a simple maxim:
+ //
+ // never call ``reifyType'' to reify a tree
+ //
+ // this works because the stuff we are reifying was once represented with trees only
+ // and lexical scope information can be fully captured by reifying symbols
+ //
+ // to enable this idyll, we work hard in the ``Reshape'' phase
+ // which replaces all types with equivalent trees and works around non-idempotencies of the typechecker
+ //
+ // why bother? because this brings method to the madness
+ // the first prototype of reification reified all types and symbols for all trees => this quickly became unyieldy
+ // the second prototype reified external types, but avoided reifying local ones => this created an ugly irregularity
+ // current approach is uniform and compact
+ var rtree = tree match {
+ case mirror.EmptyTree =>
+ reifyMirrorObject(EmptyTree)
+ case mirror.emptyValDef =>
+ mirrorSelect(nme.emptyValDef)
+ case FreeDef(_, _, _, _, _) =>
+ reifyNestedFreeDef(tree)
+ case FreeRef(_, _) =>
+ reifyNestedFreeRef(tree)
+ case BoundTerm(tree) =>
+ reifyBoundTerm(tree)
+ case BoundType(tree) =>
+ reifyBoundType(tree)
+ case NestedExpr(_, _, _) =>
+ reifyNestedExpr(tree)
+ case Literal(const @ Constant(_)) =>
+ // [Eugene] was necessary when we reified erasures as normalized tycons
+ // now, when we do existentialAbstraction on normalizations, everything works great
+ // todo. find an explanation
+// if (const.tag == ClazzTag) {
+//// def preprocess(tpe: Type): Type = tpe.typeSymbol match {
+//// case ArrayClass => appliedType(ArrayClass, preprocess(tpe.typeArgs.head))
+//// case _ => tpe.typeConstructor
+//// }
+//// val tpe = preprocess(const.typeValue)
+// val tpe = const.typeValue
+// var reified = reify(tpe)
+// reified = mirrorCall(nme.Literal, mirrorCall(nme.Constant, reified))
+//// val skolems = ClassClass.typeParams map (_ => newTypeName(typer.context.unit.fresh.newName("_$")))
+//// var existential = mirrorCall(nme.AppliedTypeTree, mirrorCall(nme.TypeTree, reify(ClassClass.typeConstructor)), mkList(skolems map (skolem => mirrorCall(nme.Ident, reify(skolem)))))
+//// existential = mirrorCall(nme.ExistentialTypeTree, existential, reify(skolems map (skolem => TypeDef(Modifiers(Set(Modifier.deferred: Modifier)), skolem, Nil, TypeBoundsTree(Ident(NothingClass) setType NothingClass.tpe, Ident(AnyClass) setType AnyClass.tpe)))))
+//// reified = mirrorCall(nme.TypeApply, mirrorCall(nme.Select, reified, reify(nme.asInstanceOf_)), mkList(List(existential)))
+// // why is this required??
+//// reified = mirrorCall(nme.TypeApply, mirrorCall(nme.Select, reified, reify(nme.asInstanceOf_)), mkList(List(mirrorCall(nme.TypeTree, reify(appliedType(ClassClass.tpe, List(AnyClass.tpe)))))))
+// reified
+// } else {
+// mirrorCall(nme.Literal, reifyProduct(const))
+// }
+ mirrorCall(nme.Literal, reifyProduct(const))
+ case Import(expr, selectors) =>
+ mirrorCall(nme.Import, reify(expr), mkList(selectors map reifyProduct))
+ case _ =>
+ reifyProduct(tree)
+ }
+
+ // usually we don't reify symbols/types, because they can be re-inferred during subsequent reflective compilation
+ // however, reification of AnnotatedTypes is special. see ``reifyType'' to find out why.
+ if (reifyTreeSymbols && tree.hasSymbol) {
+ if (reifyDebug) println("reifying symbol %s for tree %s".format(tree.symbol, tree))
+ rtree = Apply(Select(rtree, nme.setSymbol), List(reify(tree.symbol)))
+ }
+ if (reifyTreeTypes && tree.tpe != null) {
+ if (reifyDebug) println("reifying type %s for tree %s".format(tree.tpe, tree))
+ rtree = Apply(Select(rtree, nme.setType), List(reify(tree.tpe)))
+ }
+
+ rtree
+ }
+
+ def reifyModifiers(m: mirror.Modifiers) =
+ mirrorCall("modifiersFromInternalFlags", reify(m.flags), reify(m.privateWithin), reify(m.annotations))
+
+ private def spliceTree(tree: Tree): Tree = {
+ tree match {
+ case EvalSplice(splicee) =>
+ if (reifyDebug) println("splicing eval " + tree)
+
+ // see ``Metalevels'' for more info about metalevel breaches
+ // and about how we deal with splices that contain them
+ if (splicee exists (sub => sub.hasSymbol && sub.symbol != NoSymbol && sub.symbol.metalevel > 0)) {
+ if (reifyDebug) println("splicing has failed: cannot splice when facing a metalevel breach")
+ EmptyTree
+ } else {
+ if (reifyDebug) println("splicing has succeeded")
+ var splice = Select(splicee, nme.tree)
+ splice match {
+ case InlinedTreeSplice(_, inlinedSymbolTable, tree, _) =>
+ if (reifyDebug) println("inlining the splicee")
+ // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels''
+ inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => assert(false, freedef) }
+ symbolTable ++= inlinedSymbolTable
+ tree
+ case tree =>
+ // we need to preserve types of exprs, because oftentimes they cannot be inferred later
+ // this circumvents regular reification scheme, therefore we go the extra mile here
+ new Transformer {
+ override def transform(tree: Tree) = super.transform(tree match {
+ case NestedExpr(factory, tree, typetag) =>
+ val typedFactory = TypeApply(factory, List(TypeTree(typetag.tpe.typeArgs(0))))
+ Apply(Apply(typedFactory, List(tree)), List(typetag))
+ case _ =>
+ tree
+ })
+ }.transform(tree)
+ }
+ }
+ case ValueSplice(splicee) =>
+ // todo. implement this
+ ???
+ case _ =>
+ EmptyTree
+ }
+ }
+
+ private def reifyBoundTerm(tree: Tree): Tree = tree match {
+ case tree @ This(_) if tree.symbol == NoSymbol =>
+ throw new Error("unexpected: bound term that doesn't have a symbol: " + showRaw(tree))
+ case tree @ This(_) if tree.symbol.isClass && !tree.symbol.isModuleClass && !tree.symbol.isLocalToReifee =>
+ val sym = tree.symbol
+ if (reifyDebug) println("This for %s, reified as freeVar".format(sym))
+ if (reifyDebug) println("Free: " + sym)
+ mirrorCall(nme.Ident, reifyFreeTerm(sym, This(sym)))
+ case tree @ This(_) if !tree.symbol.isLocalToReifee =>
+ if (reifyDebug) println("This for %s, reified as This".format(tree.symbol))
+ mirrorCall(nme.This, reify(tree.symbol))
+ case tree @ This(_) if tree.symbol.isLocalToReifee =>
+ mirrorCall(nme.This, reify(tree.qual))
+ case tree @ Ident(_) if tree.symbol == NoSymbol =>
+ // this sometimes happens, e.g. for binds that don't have a body
+ // or for untyped code generated during previous phases
+ // (see a comment in Reifiers about the latter, starting with "why do we resetAllAttrs?")
+ mirrorCall(nme.Ident, reify(tree.name))
+ case tree @ Ident(_) if !tree.symbol.isLocalToReifee =>
+ if (tree.symbol.isVariable && tree.symbol.owner.isTerm) {
+ captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reification here.
+ mirrorCall(nme.Select, mirrorCall(nme.Ident, reify(tree.symbol)), reify(nme.elem))
+ } else {
+ mirrorCall(nme.Ident, reify(tree.symbol))
+ }
+ case tree @ Ident(_) if tree.symbol.isLocalToReifee =>
+ mirrorCall(nme.Ident, reify(tree.name))
+ case _ =>
+ throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ }
+
+ private def reifyBoundType(tree: Tree): Tree = {
+ def reifyBoundType(tree: Tree): Tree = {
+ if (tree.tpe == null)
+ throw new Error("unexpected: bound type that doesn't have a tpe: " + showRaw(tree))
+
+ if (tree.symbol.isLocalToReifee)
+ reifyProduct(tree)
+ else {
+ val sym0 = tree.symbol
+ val sym = sym0.dealias
+ val tpe0 = tree.tpe
+ val tpe = tpe0.dealias
+ if (reifyDebug) println("reifying bound type %s (underlying type is %s, dealiased is %s)".format(sym0, tpe0, tpe))
+
+ if (tpe.isSpliceable) {
+ val spliced = spliceType(tpe)
+ if (spliced == EmptyTree) {
+ if (reifyDebug) println("splicing failed: reify as is")
+ mirrorCall(nme.TypeTree, reify(tpe))
+ } else {
+ spliced match {
+ case TypeRefToFreeType(freeType) =>
+ if (reifyDebug) println("splicing returned a free type: " + freeType)
+ Ident(freeType)
+ case _ =>
+ if (reifyDebug) println("splicing succeeded: " + spliced)
+ mirrorCall(nme.TypeTree, spliced)
+ }
+ }
+ } else {
+ if (sym.isLocatable) {
+ if (reifyDebug) println("tpe is locatable: reify as Ident(%s)".format(sym))
+ mirrorCall(nme.Ident, reify(sym))
+ } else {
+ if (reifyDebug) println("tpe is an alias, but not a locatable: reify as TypeTree(%s)".format(tpe))
+ mirrorCall(nme.TypeTree, reify(tpe))
+ }
+ }
+ }
+ }
+
+ tree match {
+ case Select(_, _) =>
+ reifyBoundType(tree)
+ case SelectFromTypeTree(_, _) =>
+ reifyBoundType(tree)
+ case Ident(_) =>
+ reifyBoundType(tree)
+ case _ =>
+ throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ }
+ }
+
+ private def reifyNestedFreeDef(tree: Tree): Tree = {
+ if (reifyDebug) println("nested free def: %s".format(showRaw(tree)))
+ reifyProduct(tree)
+ }
+
+ private def reifyNestedFreeRef(tree: Tree): Tree = tree match {
+ case Apply(Select(mrRef @ Ident(_), ident), List(Ident(name: TermName))) if ident == nme.Ident && name.startsWith(nme.MIRROR_FREE_PREFIX) =>
+ if (reifyDebug) println("nested free ref: %s".format(showRaw(tree)))
+ reifyProduct(tree)
+ case _ =>
+ throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ }
+
+ private def reifyNestedExpr(tree: Tree): Tree = tree match {
+ case NestedExpr(factory, tree, typetag) =>
+ // we need to preserve types of exprs, because oftentimes they cannot be inferred later
+ // this circumvents regular reification scheme, therefore we go through this crazy dance
+ if (reifyDebug) println("nested expr: %s".format(showRaw(tree)))
+ val rtype = mirrorCall(nme.TypeTree, reify(typetag.tpe.typeArgs(0)))
+ val rfactory = mirrorCall(nme.TypeApply, reify(factory), mkList(List(rtype)))
+ val rexpr = mirrorCall(nme.Apply, rfactory, reify(List(tree)))
+ val rwrapped = mirrorCall(nme.Apply, rexpr, reify(List(typetag)))
+ rwrapped
+ case _ =>
+ throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala
new file mode 100644
index 0000000000..1f336f4b0f
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Types.scala
@@ -0,0 +1,168 @@
+package scala.reflect.reify
+package codegen
+
+trait Types {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ /**
+ * Reify a type.
+ * For internal use only, use ``reified'' instead.
+ */
+ def reifyType(tpe0: Type): Tree = {
+ assert(tpe0 != null, "tpe is null")
+ val tpe = tpe0.dealias
+
+ if (tpe.isErroneous)
+ CannotReifyErroneousReifee(tpe)
+ if (tpe.isLocalToReifee)
+ CannotReifyType(tpe)
+
+ // [Eugene] how do I check that the substitution is legal w.r.t tpe.info?
+ val spliced = spliceType(tpe)
+ if (spliced != EmptyTree)
+ return spliced
+
+ val tsym = tpe.typeSymbol
+ if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic)
+ Select(reify(tpe.typeSymbol), nme.asTypeConstructor)
+ else tpe match {
+ case tpe @ NoType =>
+ reifyMirrorObject(tpe)
+ case tpe @ NoPrefix =>
+ reifyMirrorObject(tpe)
+ case tpe @ ThisType(root) if root == RootClass =>
+ mirrorSelect("definitions.RootClass.thisPrefix")
+ case tpe @ ThisType(empty) if empty == EmptyPackageClass =>
+ mirrorSelect("definitions.EmptyPackageClass.thisPrefix")
+ case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic =>
+ mirrorCall(nme.thisModuleType, reify(clazz.fullName))
+ case tpe @ ThisType(_) =>
+ reifyProduct(tpe)
+ case tpe @ SuperType(thistpe, supertpe) =>
+ reifyProduct(tpe)
+ case tpe @ SingleType(pre, sym) =>
+ reifyProduct(tpe)
+ case tpe @ ConstantType(value) =>
+ mirrorFactoryCall(nme.ConstantType, reifyProduct(value))
+ case tpe @ TypeRef(pre, sym, args) =>
+ reifyProduct(tpe)
+ case tpe @ TypeBounds(lo, hi) =>
+ reifyProduct(tpe)
+ case tpe @ NullaryMethodType(restpe) =>
+ reifyProduct(tpe)
+ case tpe @ AnnotatedType(anns, underlying, selfsym) =>
+ reifyAnnotatedType(tpe)
+ case _ =>
+ reifyToughType(tpe)
+ }
+ }
+
+ /** An obscure flag necessary for implicit TypeTag generation */
+ private var spliceTypesEnabled = !dontSpliceAtTopLevel
+
+ /** Keeps track of whether this reification contains abstract type parameters */
+ private var _reificationIsConcrete = true
+ def reificationIsConcrete = _reificationIsConcrete
+ def reificationIsConcrete_=(value: Boolean) {
+ _reificationIsConcrete = value
+ if (!value && concrete) {
+ assert(current.isInstanceOf[Type], current)
+ val offender = current.asInstanceOf[Type]
+ CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(offender)
+ }
+ }
+
+ private type SpliceCacheKey = (Symbol, Symbol)
+ private lazy val spliceCache: collection.mutable.Map[SpliceCacheKey, Tree] = {
+ val cache = analyzer.perRunMacroCache.getOrElseUpdate(MacroContextReify, collection.mutable.Map[Any, Any]())
+ cache.getOrElseUpdate("spliceCache", collection.mutable.Map[SpliceCacheKey, Tree]()).asInstanceOf[collection.mutable.Map[SpliceCacheKey, Tree]]
+ }
+
+ def spliceType(tpe: Type): Tree = {
+ // [Eugene] it seems that depending on the context the very same symbol can be either a spliceable tparam or a quantified existential. very weird!
+ val quantified = currentQuantified
+ if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) {
+ if (reifyDebug) println("splicing " + tpe)
+
+ if (spliceTypesEnabled) {
+ var tagClass = if (concrete) ConcreteTypeTagClass else TypeTagClass
+ val tagTpe = singleType(prefix.tpe, prefix.tpe member tagClass.name)
+
+ // [Eugene] this should be enough for an abstract type, right?
+ val key = (tagClass, tpe.typeSymbol)
+ if (reifyDebug && spliceCache.contains(key)) println("cache hit: " + spliceCache(key))
+ val result = spliceCache.getOrElseUpdate(key, {
+ // if this fails, it might produce the dreaded "erroneous or inaccessible type" error
+ // to find out the whereabouts of the error run scalac with -Ydebug
+ if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe))
+ typer.resolveTypeTag(defaultErrorPosition, prefix.tpe, tpe, concrete) match {
+ case failure if failure.isEmpty =>
+ if (reifyDebug) println("implicit search was fruitless")
+ EmptyTree
+ case success =>
+ if (reifyDebug) println("implicit search has produced a result: " + success)
+ reificationIsConcrete &= concrete
+ var splice = Select(success, nme.tpe)
+ splice match {
+ case InlinedTypeSplice(_, inlinedSymbolTable, tpe) =>
+ // all free vars local to the enclosing reifee should've already been inlined by ``Metalevels''
+ inlinedSymbolTable collect { case freedef @ FreeDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => assert(false, freedef) }
+ symbolTable ++= inlinedSymbolTable
+ reifyTrace("inlined the splicee: ")(tpe)
+ case tpe =>
+ tpe
+ }
+ }
+ })
+ if (result != EmptyTree) return result.duplicate
+ } else {
+ if (reifyDebug) println("splicing has been cancelled: spliceTypesEnabled = false")
+ }
+
+ reificationIsConcrete = false
+ }
+
+ spliceTypesEnabled = true
+ EmptyTree
+ }
+
+ /** Reify an annotated type, i.e. the one that makes us deal with AnnotationInfos */
+ private def reifyAnnotatedType(tpe: AnnotatedType): Tree = {
+ val AnnotatedType(anns, underlying, selfsym) = tpe
+ mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying), reify(selfsym))
+ }
+
+ /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */
+ private def reifyToughType(tpe: Type): Tree = {
+ if (reifyDebug) println("tough type: %s (%s)".format(tpe, tpe.kind))
+
+ def reifyScope(scope: Scope): Tree = {
+ scope foreach reifySymDef
+ mirrorCall(nme.newScopeWith, scope.toList map reify: _*)
+ }
+
+ tpe match {
+ case tpe @ RefinedType(parents, decls) =>
+ reifySymDef(tpe.typeSymbol)
+ mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
+ case tpe @ ExistentialType(tparams, underlying) =>
+ tparams foreach reifySymDef
+ mirrorFactoryCall(tpe, reify(tparams), reify(underlying))
+ case tpe @ ClassInfoType(parents, decls, clazz) =>
+ reifySymDef(clazz)
+ mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
+ case tpe @ MethodType(params, restpe) =>
+ params foreach reifySymDef
+ mirrorFactoryCall(tpe, reify(params), reify(restpe))
+ case tpe @ PolyType(tparams, underlying) =>
+ tparams foreach reifySymDef
+ mirrorFactoryCall(tpe, reify(tparams), reify(underlying))
+ case _ =>
+ throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind))
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/codegen/Util.scala b/src/compiler/scala/reflect/reify/codegen/Util.scala
new file mode 100644
index 0000000000..bb369a1adb
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Util.scala
@@ -0,0 +1,112 @@
+package scala.reflect.reify
+package codegen
+
+trait Util {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ val reifyDebug = settings.Yreifydebug.value
+ val reifyCopypaste = settings.Yreifycopypaste.value
+ val reifyTrace = scala.tools.nsc.util.trace when reifyDebug
+ object reifiedNodePrinters extends { val global: mirror.type = mirror } with tools.nsc.ast.NodePrinters with NodePrinters
+ val reifiedNodeToString = reifiedNodePrinters.reifiedNodeToString
+
+ def reifyList(xs: List[Any]): Tree =
+ mkList(xs map reify)
+
+ def reifyProduct(x: Product): Tree =
+ reifyProduct(x.productPrefix, x.productIterator.toList)
+
+ def reifyProduct(prefix: String, elements: List[Any]): Tree = {
+ // reflection would be more robust, but, hey, this is a hot path
+ if (prefix.startsWith("Tuple")) scalaFactoryCall(prefix, (elements map reify).toList: _*)
+ else mirrorCall(prefix, (elements map reify): _*)
+ }
+
+ // helper functions
+
+ /** Reify a case object defined in Mirror */
+ def reifyMirrorObject(name: String): Tree =
+ mirrorSelect(name)
+
+ def reifyMirrorObject(x: Product): Tree =
+ reifyMirrorObject(x.productPrefix)
+
+ def call(fname: String, args: Tree*): Tree =
+ Apply(termPath(fname), args.toList)
+
+ def mirrorSelect(name: String): Tree =
+ termPath(nme.MIRROR_PREFIX + name)
+
+ def mirrorCall(name: TermName, args: Tree*): Tree =
+ call("" + (nme.MIRROR_PREFIX append name), args: _*)
+
+ def mirrorCall(name: String, args: Tree*): Tree =
+ call(nme.MIRROR_PREFIX + name, args: _*)
+
+ def mirrorFactoryCall(value: Product, args: Tree*): Tree =
+ mirrorFactoryCall(value.productPrefix, args: _*)
+
+ def mirrorFactoryCall(prefix: String, args: Tree*): Tree =
+ mirrorCall(prefix, args: _*)
+
+ def scalaFactoryCall(name: String, args: Tree*): Tree =
+ call("scala." + name + ".apply", args: _*)
+
+ def mkList(args: List[Tree]): Tree =
+ scalaFactoryCall("collection.immutable.List", args: _*)
+
+ /**
+ * An (unreified) path that refers to definition with given fully qualified name
+ * @param mkName Creator for last portion of name (either TermName or TypeName)
+ */
+ def path(fullname: String, mkName: String => Name): Tree = {
+ val parts = fullname split "\\."
+ val prefixParts = parts.init
+ val lastName = mkName(parts.last)
+ if (prefixParts.isEmpty) Ident(lastName)
+ else {
+ val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail)(Select(_, _))
+ Select(prefixTree, lastName)
+ }
+ }
+
+ /** An (unreified) path that refers to term definition with given fully qualified name */
+ def termPath(fullname: String): Tree = path(fullname, newTermName)
+
+ /** An (unreified) path that refers to type definition with given fully qualified name */
+ def typePath(fullname: String): Tree = path(fullname, newTypeName)
+
+ def isTough(tpe: Type) = {
+ def isTough(tpe: Type) = tpe match {
+ case _: RefinedType => true
+ case _: ExistentialType => true
+ case _: ClassInfoType => true
+ case _: MethodType => true
+ case _: PolyType => true
+ case _ => false
+ }
+
+ tpe != null && (tpe exists isTough)
+ }
+
+ def isAnnotated(tpe: Type) = {
+ def isAnnotated(tpe: Type) = tpe match {
+ case _: AnnotatedType => true
+ case _ => false
+ }
+
+ tpe != null && (tpe exists isAnnotated)
+ }
+
+ def origin(sym: Symbol) = {
+ var origin = ""
+ if (sym.owner != NoSymbol) origin += "defined by %s".format(sym.owner.name)
+ if (sym.pos != NoPosition) origin += " in %s:%s:%s".format(sym.pos.source.file.name, sym.pos.line, sym.pos.column)
+ if (origin == "") origin = "of unknown origin"
+ origin
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala
new file mode 100644
index 0000000000..3f9d6200cd
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/package.scala
@@ -0,0 +1,58 @@
+package scala.reflect
+
+import scala.tools.nsc.Global
+import scala.reflect.makro.ReificationError
+import scala.reflect.makro.UnexpectedReificationError
+
+package object reify {
+ private def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Reifier { val mirror: global.type } = {
+ val typer1: typer.type = typer
+ val prefix1: prefix.type = prefix
+ val reifee1 = reifee
+ val dontSpliceAtTopLevel1 = dontSpliceAtTopLevel
+ val concrete1 = concrete
+
+ new {
+ val mirror: global.type = global
+ val typer = typer1
+ val prefix = prefix1
+ val reifee = reifee1
+ val dontSpliceAtTopLevel = dontSpliceAtTopLevel1
+ val concrete = concrete1
+ } with Reifier
+ }
+
+ def reifyTree(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, tree: global.Tree): global.Tree =
+ mkReifier(global)(typer, prefix, tree, false, false).reified.asInstanceOf[global.Tree]
+
+ def reifyType(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, tpe: global.Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): global.Tree =
+ mkReifier(global)(typer, prefix, tpe, dontSpliceAtTopLevel, concrete).reified.asInstanceOf[global.Tree]
+
+ def reifyErasure(global: Global)(typer0: global.analyzer.Typer, tpe: global.Type, concrete: Boolean = true): global.Tree = {
+ import global._
+ import definitions._
+ import analyzer.enclosingMacroPosition
+
+ def erasureTagInScope = typer0.context.withMacrosDisabled(typer0.resolveErasureTag(enclosingMacroPosition, tpe, concrete = concrete))
+ def arrayTagInScope = typer0.context.withMacrosDisabled(typer0.resolveArrayTag(enclosingMacroPosition, tpe))
+ val inScope = (erasureTagInScope, arrayTagInScope)
+
+ inScope match {
+ case (success, _) if !success.isEmpty =>
+ Select(success, nme.erasure)
+ case (_, success) if !success.isEmpty =>
+ gen.mkMethodCall(arrayElementClassMethod, List(success))
+ case _ =>
+ if (tpe.typeSymbol == ArrayClass) {
+ val componentTpe = tpe.typeArguments(0)
+ val componentErasure = reifyErasure(global)(typer0, componentTpe, concrete)
+ gen.mkMethodCall(arrayClassMethod, List(componentErasure))
+ } else {
+ if (tpe.isSpliceable && concrete) throw new ReificationError(enclosingMacroPosition, "tpe %s is an unresolved spliceable type".format(tpe))
+ var erasure = tpe.erasure
+ if (tpe.typeSymbol.isDerivedValueClass && global.phase.id < global.currentRun.erasurePhase.id) erasure = tpe
+ gen.mkNullaryCall(Predef_classOf, List(erasure))
+ }
+ }
+ }
+}
diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala
new file mode 100644
index 0000000000..93ef46472e
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala
@@ -0,0 +1,60 @@
+package scala.reflect.reify
+package phases
+
+trait Calculate {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ implicit class RichSymbol(sym: Symbol) {
+ def metalevel: Int = { assert(sym != NoSymbol); localSymbols.getOrElse(sym, 0) }
+ def isLocalToReifee = (localSymbols contains sym) // [Eugene] how do I account for local skolems?
+ }
+
+ implicit class RichType(tpe: Type) {
+ def isLocalToReifee = tpe != null && (tpe exists (tp => (localSymbols contains tp.typeSymbol) || (localSymbols contains tp.termSymbol)))
+ }
+
+ private var localSymbols = collection.mutable.Map[Symbol, Int]() // set of all symbols that are local to the tree to be reified
+ private def registerLocalSymbol(sym: Symbol, metalevel: Int): Unit =
+ if (sym != null && sym != NoSymbol) {
+ if (localSymbols contains sym)
+ assert(localSymbols(sym) == metalevel, "metalevel mismatch: expected %s, actual %s".format(localSymbols(sym), metalevel))
+ localSymbols(sym) = metalevel
+ }
+
+ /**
+ * Merely traverses the reifiee and records local symbols along with their metalevels.
+ */
+ val calculate = new Traverser {
+ // see the explanation of metalevels in ``Metalevels''
+ var currMetalevel = 1
+
+ override def traverse(tree: Tree): Unit = tree match {
+ case TreeSplice(_) =>
+ currMetalevel -= 1
+ try super.traverse(tree)
+ finally currMetalevel += 1
+ case tree if tree.isDef =>
+ if (reifyDebug) println("boundSym: %s of type %s".format(tree.symbol, (tree.productIterator.toList collect { case tt: TypeTree => tt } headOption).getOrElse(TypeTree(tree.tpe))))
+ registerLocalSymbol(tree.symbol, currMetalevel)
+
+ bindRelatedSymbol(tree.symbol.sourceModule, "sourceModule")
+ bindRelatedSymbol(tree.symbol.moduleClass, "moduleClass")
+ bindRelatedSymbol(tree.symbol.companionClass, "companionClass")
+ bindRelatedSymbol(tree.symbol.companionModule, "companionModule")
+ Some(tree.symbol) collect { case termSymbol: TermSymbol => bindRelatedSymbol(termSymbol.referenced, "referenced") }
+ Some(tree) collect { case labelDef: LabelDef => labelDef.params foreach (param => bindRelatedSymbol(param.symbol, "labelParam")) }
+ def bindRelatedSymbol(related: Symbol, name: String): Unit =
+ if (related != null && related != NoSymbol) {
+ if (reifyDebug) println("boundSym (" + name + "): " + related)
+ registerLocalSymbol(related, currMetalevel)
+ }
+ super.traverse(tree)
+ case _ =>
+ super.traverse(tree)
+ }
+ }
+}
diff --git a/src/compiler/scala/reflect/reify/phases/Metalevels.scala b/src/compiler/scala/reflect/reify/phases/Metalevels.scala
new file mode 100644
index 0000000000..206f3b1118
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala
@@ -0,0 +1,150 @@
+package scala.reflect.reify
+package phases
+
+trait Metalevels {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ /**
+ * Makes sense of cross-stage bindings.
+ *
+ * ================
+ *
+ * Analysis of cross-stage bindings becomes convenient if we introduce the notion of metalevels.
+ * Metalevel of a tree is a number that gets incremented every time you reify something and gets decremented when you splice something.
+ * Metalevel of a symbol is equal to the metalevel of its definition.
+ *
+ * Example 1. Consider the following snippet:
+ *
+ * reify {
+ * val x = 2 // metalevel of symbol x is 1, because it's declared inside reify
+ * val y = reify{x} // metalevel of symbol y is 1, because it's declared inside reify
+ * // metalevel of Ident(x) is 2, because it's inside two reifies
+ * y.eval // metalevel of Ident(y) is 0, because it's inside a designator of a splice
+ * }
+ *
+ * Cross-stage bindings are introduced when symbol.metalevel != curr_metalevel.
+ * Both bindings introduced in Example 1 are cross-stage.
+ *
+ * Depending on what side of the inequality is greater, the following situations might occur:
+ *
+ * 1) symbol.metalevel < curr_metalevel. In this case reifier will generate a free variable
+ * that captures both the name of the symbol (to be compiled successfully) and its value (to be run successfully).
+ * For example, x in Example 1 will be reified as follows: Ident(newFreeVar("x", IntClass.tpe, x))
+ *
+ * 2) symbol.metalevel > curr_metalevel. This leads to a metalevel breach that violates intuitive perception of splicing.
+ * As defined in macro spec, splicing takes a tree and inserts it into another tree - as simple as that.
+ * However, how exactly do we do that in the case of y.eval? In this very scenario we can use dataflow analysis and inline it,
+ * but what if y were a var, and what if it were calculated randomly at runtime?
+ *
+ * This question has a genuinely simple answer. Sure, we cannot resolve such splices statically (i.e. during macro expansion of ``reify''),
+ * but now we have runtime toolboxes, so noone stops us from picking up that reified tree and evaluating it at runtime
+ * (in fact, this is something that ``Expr.eval'' and ``Expr.value'' do transparently).
+ *
+ * This is akin to early vs late binding dilemma.
+ * The prior is faster, plus, the latter (implemented with reflection) might not work because of visibility issues or might be not available on all platforms.
+ * But the latter still has its uses, so I'm allowing metalevel breaches, but introducing the -Xlog-runtime-evals to log them.
+ *
+ * ================
+ *
+ * As we can see, the only problem is the fact that lhs'es of eval can be code blocks that can capture variables from the outside.
+ * Code inside the lhs of an eval is not reified, while the code from the enclosing reify is.
+ *
+ * Hence some bindings become cross-stage, which is not bad per se (in fact, some cross-stage bindings have sane semantics, as in the example above).
+ * However this affects freevars, since they are delicate inter-dimensional beings that refer to both current and next planes of existence.
+ * When splicing tears the fabric of the reality apart, some freevars have to go single-dimensional to retain their sanity.
+ *
+ * Example 2. Consider the following snippet:
+ *
+ * reify {
+ * val x = 2
+ * reify{x}.eval
+ * }
+ *
+ * Since the result of the inner reify is wrapped in an eval, it won't be reified
+ * together with the other parts of the outer reify, but will be inserted into that result verbatim.
+ *
+ * The inner reify produces an Expr[Int] that wraps Ident(freeVar("x", IntClass.tpe, x)).
+ * However the freevar the reification points to will vanish when the compiler processes the outer reify.
+ * That's why we need to replace that freevar with a regular symbol that will point to reified x.
+ *
+ * Example 3. Consider the following fragment:
+ *
+ * reify {
+ * val x = 2
+ * val y = reify{x}
+ * y.eval
+ * }
+ *
+ * In this case the inner reify doesn't appear next to eval, so it will be reified together with x.
+ * This means that no special processing is needed here.
+ *
+ * Example 4. Consider the following fragment:
+ *
+ * reify {
+ * val x = 2
+ * {
+ * val y = 2
+ * val z = reify{reify{x + y}}
+ * z.eval
+ * }.eval
+ * }
+ *
+ * The reasoning from Example 2 still holds here - we do need to inline the freevar that refers to x.
+ * However, we must not touch anything inside the eval'd block, because it's not getting reified.
+ */
+ var metalevels = new Transformer {
+ var insideSplice = false
+ var freedefsToInline = collection.mutable.Map[String, ValDef]()
+
+ def withinSplice[T](op: => T) = {
+ val old = insideSplice
+ insideSplice = true
+ try op
+ finally insideSplice = old
+ }
+
+ // Q: here we deal with all sorts of reified trees. what about ReifiedType(_, _, _, _)?
+ // A: nothing. reified trees give us problems because they sometimes create dimensional rifts as described above
+ // to the contrast, reified types (i.e. synthetic typetags materialized by Implicits.scala) always stay on the same metalevel as their enclosing code
+ override def transform(tree: Tree): Tree = tree match {
+ case InlineableTreeSplice(splicee, inlinedSymbolTable, _, _, flavor) =>
+ if (reifyDebug) println("entering inlineable splice: " + splicee)
+ val Block(mrDef :: symbolTable, expr) = splicee
+ // [Eugene] how to express the fact that a scrutinee is both of some type and matches an extractor?
+ val freedefsToInline = symbolTable collect { case freedef @ FreeTermDef(_, _, binding, _, _) if binding.symbol.isLocalToReifee => freedef.asInstanceOf[ValDef] }
+ freedefsToInline foreach (vdef => this.freedefsToInline(vdef.name) = vdef)
+ val symbolTable1 = symbolTable diff freedefsToInline
+ val tree1 = Select(Block(mrDef :: symbolTable1, expr), flavor)
+ if (reifyDebug) println("trimmed %s inlineable free defs from its symbol table: %s".format(freedefsToInline.length, freedefsToInline map (_.name) mkString(", ")))
+ withinSplice { super.transform(tree1) }
+ case TreeSplice(splicee) =>
+ if (reifyDebug) println("entering splice: " + splicee)
+ val hasBreaches = splicee exists (_.symbol.metalevel > 0)
+ if (!insideSplice && hasBreaches) {
+ if (settings.logRuntimeSplices.value) reporter.echo(tree.pos, "this splice cannot be resolved statically")
+ if (reifyDebug) println("metalevel breach in %s: %s".format(tree, (splicee filter (_.symbol.metalevel > 0) map (_.symbol) distinct) mkString ", "))
+ }
+ withinSplice { super.transform(tree) }
+ // todo. also inline usages of ``freedefsToInline'' in the symbolTable itself
+ // e.g. a free$Foo can well use free$x, if Foo is path-dependent w.r.t x
+ // FreeRef(_, _) check won't work, because metalevels of symbol table and body are different, hence, freerefs in symbol table look different from freerefs in body
+ // todo. also perform garbage collection on local symbols
+ // so that local symbols used only in type signatures of free vars get removed
+ // todo. same goes for auxiliary symbol defs reified to support tough types
+ // some of them need to be rebuilt, some of them need to be removed, because they're no longer necessary
+ case FreeRef(mr, name) if freedefsToInline contains name =>
+ if (reifyDebug) println("inlineable free ref: %s in %s".format(name, showRaw(tree)))
+ val freedef @ FreeDef(_, _, binding, _, _) = freedefsToInline(name)
+ if (reifyDebug) println("related definition: %s".format(showRaw(freedef)))
+ val inlined = reify(binding)
+ if (reifyDebug) println("verdict: inlined as %s".format(showRaw(inlined)))
+ inlined
+ case _ =>
+ super.transform(tree)
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala
new file mode 100644
index 0000000000..e03ff5832c
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/phases/Reify.scala
@@ -0,0 +1,65 @@
+package scala.reflect.reify
+package phases
+
+import scala.runtime.ScalaRunTime.isAnyVal
+import scala.runtime.ScalaRunTime.isTuple
+import scala.reflect.reify.codegen._
+
+trait Reify extends Symbols
+ with Types
+ with Names
+ with Trees
+ with AnnotationInfos
+ with Positions
+ with Util {
+
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ // `reify` looked so nice, I wanted to push the last bit of orthogonal
+ // logic out of it so you can see the improvement. There is no cost to
+ // wrapper methods of this form because the inliner will eliminate them,
+ // but they are very good at separating concerns like pushing/popping
+ // a stack, and they are great for composition and reuse.
+ //
+ // Also, please avoid public vars whenever possible.
+ private object reifyStack {
+ var currents: List[Any] = reifee :: Nil
+
+ @inline final def push[T](reifee: Any)(body: => T): T = {
+ currents ::= reifee
+ try body
+ finally currents = currents.tail
+ }
+ }
+ def currentQuantified = flatCollect(reifyStack.currents)({ case ExistentialType(quantified, _) => quantified })
+ def current = reifyStack.currents.head
+
+ /**
+ * Reifies any supported value.
+ * For internal use only, use ``reified'' instead.
+ */
+ def reify(reifee: Any): Tree = reifyStack.push(reifee)(reifee match {
+ // before adding some case here, in global scope, please, consider
+ // whether it can be localized like reifyAnnotationInfo or reifyScope
+ // this will help reification stay as sane as possible
+ case sym: Symbol => reifySymRef(sym)
+ case tpe: Type => reifyType(tpe)
+ case name: Name => reifyName(name)
+ case tree: Tree => reifyTree(tree)
+ // disabled because this is a very special case that I plan to remove later
+ // why do I dislike annotations? see comments to `reifyAnnotationInfo`
+// case ann: AnnotationInfo => reifyAnnotationInfo(ann)
+ case pos: Position => reifyPosition(pos)
+ case mods: mirror.Modifiers => reifyModifiers(mods)
+ case xs: List[_] => reifyList(xs)
+ case s: String => Literal(Constant(s))
+ case v if isAnyVal(v) => Literal(Constant(v))
+ case null => Literal(Constant(null))
+ case _ =>
+ throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass))
+ })
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala
new file mode 100644
index 0000000000..4ab306a13f
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala
@@ -0,0 +1,290 @@
+package scala.reflect.reify
+package phases
+
+import scala.tools.nsc.symtab.Flags._
+
+trait Reshape {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ /**
+ * Rolls back certain changes that were introduced during typechecking of the reifee.
+ *
+ * These include:
+ * * Replacing type trees with TypeTree(tpe)
+ * * Transforming Modifiers.annotations into Symbol.annotations
+ * * Transforming Annotated annotations into AnnotatedType annotations
+ * * Transforming Annotated(annot, expr) into Typed(expr, TypeTree(Annotated(annot, _))
+ * * Non-idempotencies of the typechecker: https://issues.scala-lang.org/browse/SI-5464
+ */
+ val reshape = new Transformer {
+ var currentSymbol: Symbol = NoSymbol
+
+ override def transform(tree: Tree) = {
+ currentSymbol = tree.symbol
+
+ val preTyper = tree match {
+ case tree if tree.isErroneous =>
+ tree
+ case tt @ TypeTree() =>
+ toPreTyperTypeTree(tt)
+ case toa @ TypedOrAnnotated(_) =>
+ toPreTyperTypedOrAnnotated(toa)
+ case ta @ TypeApply(hk, ts) =>
+ val discard = ts collect { case tt: TypeTree => tt } exists isDiscarded
+ if (reifyDebug && discard) println("discarding TypeApply: " + tree)
+ if (discard) hk else ta
+ case classDef @ ClassDef(mods, name, params, impl) =>
+ val Template(parents, self, body) = impl
+ var body1 = trimAccessors(classDef, body)
+ body1 = trimSyntheticCaseClassMembers(classDef, body1)
+ var impl1 = Template(parents, self, body1).copyAttrs(impl)
+ ClassDef(mods, name, params, impl1).copyAttrs(classDef)
+ case moduledef @ ModuleDef(mods, name, impl) =>
+ val Template(parents, self, body) = impl
+ var body1 = trimAccessors(moduledef, body)
+ body1 = trimSyntheticCaseClassMembers(moduledef, body1)
+ var impl1 = Template(parents, self, body1).copyAttrs(impl)
+ ModuleDef(mods, name, impl1).copyAttrs(moduledef)
+ case template @ Template(parents, self, body) =>
+ val discardedParents = parents collect { case tt: TypeTree => tt } filter isDiscarded
+ if (reifyDebug && discardedParents.length > 0) println("discarding parents in Template: " + discardedParents.mkString(", "))
+ val parents1 = parents diff discardedParents
+ val body1 = trimSyntheticCaseClassCompanions(body)
+ Template(parents1, self, body1).copyAttrs(template)
+ case block @ Block(stats, expr) =>
+ val stats1 = trimSyntheticCaseClassCompanions(stats)
+ Block(stats1, expr).copyAttrs(block)
+ case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isLazy =>
+ if (reifyDebug) println("dropping $lzy in lazy val's name: " + tree)
+ val name1 = if (name endsWith nme.LAZY_LOCAL) name dropRight nme.LAZY_LOCAL.length else name
+ ValDef(mods, name1, tpt, rhs).copyAttrs(valdef)
+ case unapply @ UnApply(fun, args) =>
+ def extractExtractor(tree: Tree): Tree = {
+ val Apply(fun, args) = tree
+ args match {
+ case List(Ident(special)) if special == nme.SELECTOR_DUMMY =>
+ val Select(extractor, flavor) = fun
+ assert(flavor == nme.unapply || flavor == nme.unapplySeq)
+ extractor
+ case _ =>
+ extractExtractor(fun)
+ }
+ }
+
+ if (reifyDebug) println("unapplying unapply: " + tree)
+ val fun1 = extractExtractor(fun)
+ Apply(fun1, args).copyAttrs(unapply)
+ case _ =>
+ tree
+ }
+
+ super.transform(preTyper)
+ }
+
+ override def transformModifiers(mods: Modifiers) = {
+ val mods1 = toPreTyperModifiers(mods, currentSymbol)
+ super.transformModifiers(mods1)
+ }
+
+ private def toPreTyperModifiers(mods: Modifiers, sym: Symbol) = {
+ if (!sym.annotations.isEmpty) {
+ val Modifiers(flags, privateWithin, annotations) = mods
+ val postTyper = sym.annotations filter (_.original != EmptyTree)
+ if (reifyDebug && !postTyper.isEmpty) println("reify symbol annotations for: " + sym)
+ if (reifyDebug && !postTyper.isEmpty) println("originals are: " + sym.annotations)
+ val preTyper = postTyper map toPreTyperAnnotation
+ mods.withAnnotations(preTyper)
+ } else {
+ mods
+ }
+ }
+
+ /** Restore pre-typer representation of a type.
+ *
+ * NB: This is the trickiest part of reification!
+ *
+ * In most cases, we're perfectly fine to reify a Type itself (see ``reifyType'').
+ * However if the type involves a symbol declared inside the quasiquote (i.e. registered in ``boundSyms''),
+ * then we cannot reify it, or otherwise subsequent reflective compilation will fail.
+ *
+ * Why will it fail? Because reified deftrees (e.g. ClassDef(...)) will generate fresh symbols during that compilation,
+ * so naively reified symbols will become out of sync, which brings really funny compilation errors and/or crashes, e.g.:
+ * https://issues.scala-lang.org/browse/SI-5230
+ *
+ * To deal with this unpleasant fact, we need to fall back from types to equivalent trees (after all, parser trees don't contain any types, just trees, so it should be possible).
+ * Luckily, these original trees get preserved for us in the ``original'' field when Trees get transformed into TypeTrees.
+ * And if an original of a type tree is empty, we can safely assume that this type is non-essential (e.g. was inferred/generated by the compiler).
+ * In that case the type can be omitted (e.g. reified as an empty TypeTree), since it will be inferred again later on.
+ *
+ * An important property of the original is that it isn't just a pre-typer tree.
+ * It's actually kind of a post-typer tree with symbols assigned to its Idents (e.g. Ident("List") will contain a symbol that points to immutable.this.List).
+ * This is very important, since subsequent reflective compilation won't have to resolve these symbols.
+ * In general case, such resolution cannot be performed, since reification doesn't preserve lexical context,
+ * which means that reflective compilation won't be aware of, say, imports that were provided when the reifee has been compiled.
+ *
+ * This workaround worked surprisingly well and allowed me to fix several important reification bugs, until the abstraction has leaked.
+ * Suddenly I found out that in certain contexts original trees do not contain symbols, but are just parser trees.
+ * To the moment I know only one such situation: typedAnnotations does not typecheck the annotation in-place, but rather creates new trees and typechecks them, so the original remains symless.
+ * Thus we apply a workaround for that in typedAnnotated. I hope this will be the only workaround in this department.
+ *
+ * upd. Recently I went ahead and started using original for all TypeTrees, regardless of whether they refer to local symbols or not.
+ * As a result, ``reifyType'' is never called directly by tree reification (and, wow, it seems to work great!).
+ * The only usage of ``reifyType'' now is for servicing typetags, however, I have some ideas how to get rid of that as well.
+ */
+ private def isDiscarded(tt: TypeTree) = tt.original == null
+ private def toPreTyperTypeTree(tt: TypeTree): Tree = {
+ if (tt.original != null) {
+ // here we rely on the fact that the originals that reach this point
+ // have all necessary symbols attached to them (i.e. that they can be recompiled in any lexical context)
+ // if this assumption fails, please, don't be quick to add postprocessing here (like I did before)
+ // but rather try to fix this in Typer, so that it produces quality originals (like it's done for typedAnnotated)
+ if (reifyDebug) println("TypeTree, essential: %s (%s)".format(tt.tpe, tt.tpe.kind))
+ if (reifyDebug) println("verdict: rolled back to original %s".format(tt.original))
+ transform(tt.original)
+ } else {
+ // type is deemed to be non-essential
+ // erase it and hope that subsequent reflective compilation will be able to recreate it again
+ if (reifyDebug) println("TypeTree, non-essential: %s (%s)".format(tt.tpe, tt.tpe.kind))
+ if (reifyDebug) println("verdict: discarded")
+ TypeTree()
+ }
+ }
+
+ private def toPreTyperTypedOrAnnotated(tree: Tree): Tree = tree match {
+ case ty @ Typed(expr1, tt @ TypeTree()) =>
+ if (reifyDebug) println("reify typed: " + tree)
+ val annotatedArg = {
+ def loop(tree: Tree): Tree = tree match {
+ case annotated1 @ Annotated(ann, annotated2 @ Annotated(_, _)) => loop(annotated2)
+ case annotated1 @ Annotated(ann, arg) => arg
+ case _ => EmptyTree
+ }
+
+ loop(tt.original)
+ }
+ if (annotatedArg != EmptyTree) {
+ if (annotatedArg.isType) {
+ if (reifyDebug) println("verdict: was an annotated type, reify as usual")
+ ty
+ } else {
+ if (reifyDebug) println("verdict: was an annotated value, equivalent is " + tt.original)
+ toPreTyperTypedOrAnnotated(tt.original)
+ }
+ } else {
+ if (reifyDebug) println("verdict: wasn't annotated, reify as usual")
+ ty
+ }
+ case at @ Annotated(annot, arg) =>
+ if (reifyDebug) println("reify type annotations for: " + tree)
+ assert(at.tpe.isInstanceOf[AnnotatedType], "%s (%s)".format(at.tpe, at.tpe.kind))
+ val annot1 = toPreTyperAnnotation(at.tpe.asInstanceOf[AnnotatedType].annotations(0))
+ if (reifyDebug) println("originals are: " + annot1)
+ Annotated(annot1, arg).copyAttrs(at)
+ }
+
+ /** Restore pre-typer representation of an annotation.
+ * The trick here is to retain the symbols that have been populated during typechecking of the annotation.
+ * If we do not do that, subsequent reflective compilation will fail.
+ */
+ private def toPreTyperAnnotation(ann: AnnotationInfo): Tree = {
+ val args = if (ann.assocs.isEmpty) {
+ ann.args
+ } else {
+ def toScalaAnnotation(jann: ClassfileAnnotArg): Tree = jann match {
+ case LiteralAnnotArg(const) =>
+ Literal(const)
+ case ArrayAnnotArg(arr) =>
+ Apply(Ident(definitions.ArrayModule), arr.toList map toScalaAnnotation)
+ case NestedAnnotArg(ann) =>
+ toPreTyperAnnotation(ann)
+ }
+
+ ann.assocs map { case (nme, arg) => AssignOrNamedArg(Ident(nme), toScalaAnnotation(arg)) }
+ }
+
+ def extractOriginal: PartialFunction[Tree, Tree] = { case Apply(Select(New(tpt), _), _) => tpt }
+ assert(extractOriginal.isDefinedAt(ann.original), showRaw(ann.original))
+ New(TypeTree(ann.atp) setOriginal extractOriginal(ann.original), List(args))
+ }
+
+ // [Eugene] is this implemented correctly?
+ private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = {
+ val symdefs = stats collect { case vodef: ValOrDefDef => vodef } map (vodeff => vodeff.symbol -> vodeff) toMap
+ val accessors = collection.mutable.Map[ValDef, List[DefDef]]()
+ stats collect { case ddef: DefDef => ddef } foreach (defdef => {
+ val valdef = symdefs get defdef.symbol.accessedOrSelf collect { case vdef: ValDef => vdef } getOrElse null
+ if (valdef != null) accessors(valdef) = accessors.getOrElse(valdef, Nil) :+ defdef
+
+ def detectBeanAccessors(prefix: String): Unit = {
+ if (defdef.name.startsWith(prefix)) {
+ var name = defdef.name.toString.substring(prefix.length)
+ def uncapitalize(s: String) = if (s.length == 0) "" else { val chars = s.toCharArray; chars(0) = chars(0).toLower; new String(chars) }
+ def findValDef(name: String) = symdefs.values collect { case vdef: ValDef if nme.dropLocalSuffix(vdef.name).toString == name => vdef } headOption;
+ val valdef = findValDef(name) orElse findValDef(uncapitalize(name)) orNull;
+ if (valdef != null) accessors(valdef) = accessors.getOrElse(valdef, Nil) :+ defdef
+ }
+ }
+ detectBeanAccessors("get")
+ detectBeanAccessors("set")
+ detectBeanAccessors("is")
+ });
+
+ var stats1 = stats flatMap {
+ case vdef @ ValDef(mods, name, tpt, rhs) =>
+ val mods1 = if (accessors.contains(vdef)) {
+ val ddef = accessors(vdef)(0) // any accessor will do
+ val Modifiers(flags, privateWithin, annotations) = mods
+ var flags1 = flags & ~LOCAL
+ if (!ddef.symbol.isPrivate) flags1 = flags1 & ~PRIVATE
+ val privateWithin1 = ddef.mods.privateWithin
+ val annotations1 = accessors(vdef).foldLeft(annotations)((curr, acc) => curr ++ (acc.symbol.annotations map toPreTyperAnnotation))
+ Modifiers(flags1, privateWithin1, annotations1) setPositions mods.positions
+ } else {
+ mods
+ }
+ val mods2 = toPreTyperModifiers(mods1, vdef.symbol)
+ val name1 = nme.dropLocalSuffix(name)
+ val vdef1 = ValDef(mods2, name1, tpt, rhs)
+ if (reifyDebug) println("resetting visibility of field: %s => %s".format(vdef, vdef1))
+ Some(vdef1) // no copyAttrs here, because new ValDef and old symbols are not out of sync
+ case ddef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ if (accessors.values.exists(_.contains(ddef))) {
+ if (reifyDebug) println("discarding accessor method: " + ddef)
+ None
+ } else {
+ Some(ddef)
+ }
+ case tree =>
+ Some(tree)
+ }
+
+ stats1
+ }
+
+ private def trimSyntheticCaseClassMembers(deff: Tree, stats: List[Tree]): List[Tree] =
+ stats filterNot (memberDef => memberDef.isDef && {
+ val isSynthetic = memberDef.symbol.isSynthetic
+ // this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass)
+ // that's why I replace the check with an assumption that all synthetic members are, in fact, generated of case classes
+ // val isCaseMember = deff.symbol.isCaseClass || deff.symbol.companionClass.isCaseClass
+ val isCaseMember = true
+ if (isSynthetic && isCaseMember && reifyDebug) println("discarding case class synthetic def: " + memberDef)
+ isSynthetic && isCaseMember
+ })
+
+ private def trimSyntheticCaseClassCompanions(stats: List[Tree]): List[Tree] =
+ stats diff (stats collect { case moddef: ModuleDef => moddef } filter (moddef => {
+ val isSynthetic = moddef.symbol.isSynthetic
+ // this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass)
+ // that's why I replace the check with an assumption that all synthetic modules are, in fact, companions of case classes
+ // val isCaseCompanion = moddef.symbol.companionClass.isCaseClass
+ val isCaseCompanion = true
+ if (isSynthetic && isCaseCompanion && reifyDebug) println("discarding synthetic case class companion: " + moddef)
+ isSynthetic && isCaseCompanion
+ }))
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/ClassLoaders.scala b/src/compiler/scala/reflect/runtime/ClassLoaders.scala
new file mode 100644
index 0000000000..b73d57c04d
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/ClassLoaders.scala
@@ -0,0 +1,25 @@
+package scala.reflect
+package runtime
+
+trait ClassLoaders extends internal.SymbolTable { self: SymbolTable =>
+
+ def staticClass(fullname: String) =
+ definitions.getRequiredClass(fullname)
+
+ def staticModule(fullname: String) =
+ definitions.getRequiredModule(fullname)
+
+ /** If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package
+ * <owner>.<name>, otherwise return NoSymbol.
+ * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead.
+ */
+ override def missingHook(owner: Symbol, name: Name): Symbol =
+ if (owner.isRoot && isJavaClass(name.toString))
+ definitions.EmptyPackageClass.info decl name
+ else if (name.isTermName && owner.hasPackageFlag && !owner.isEmptyPackageClass)
+ makeScalaPackage(if (owner.isRoot) name.toString else owner.fullName+"."+name).sourceModule
+ else {
+ info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass)
+ super.missingHook(owner, name)
+ }
+}
diff --git a/src/compiler/scala/reflect/runtime/ConversionUtil.scala b/src/compiler/scala/reflect/runtime/ConversionUtil.scala
index 8c32026e37..e45fc243c6 100644
--- a/src/compiler/scala/reflect/runtime/ConversionUtil.scala
+++ b/src/compiler/scala/reflect/runtime/ConversionUtil.scala
@@ -12,6 +12,7 @@ trait ConversionUtil { self: SymbolTable =>
/** A cache that maintains a bijection between Java reflection type `J`
* and Scala reflection type `S`.
*/
+ // todo. should be weak
protected class TwoWayCache[J, S] {
private val toScalaMap = new HashMap[J, S]
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
index 89fd6bab64..6688d77985 100644
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala
@@ -34,16 +34,42 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
val global: JavaToScala.this.type = self
}
- protected def defaultReflectiveClassLoader(): JClassLoader = {
- val cl = Thread.currentThread.getContextClassLoader
- if (cl == null) getClass.getClassLoader else cl
- }
+ /** Defines the classloader that will be used for all class resolution activities in this mirror.
+ * Is mutable, since sometimes we need to change it in flight (e.g. to make the default mirror work with REPL).
+ *
+ * If you want to have a mirror with non-standard class resolution, override this var
+ * (or, even simpler, use the `mkMirror` function from `scala.reflect` package)
+ *
+ * Be careful, though, since fancy stuff might happen.
+ * Here's one example:
+ *
+ * partest uses a URLClassLoader(urls, null) with custom classpath to run workers (in separate threads)
+ * however it doesn't set the context classloader for them, so they inherit the system classloader
+ * http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html
+ *
+ * Once upon a time, scala.reflect.mirror was loaded using getClass.getClassLoader,
+ * which also means that classOf[...] constructs such as:
+ *
+ * classOf[scala.reflect.ScalaSignature]
+ *
+ * in unpickleClass were also loaded by the URLClassLoader
+ *
+ * But mirror's classLoader used Thread.currentThread.getContextClassLoader,
+ * which introduced a subtle bug that made the following snippet incorrectly:
+ *
+ * jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature])
+ *
+ * Indeed, jclazz was loaded by context classloader, which defaulted to system classloader,
+ * while ScalaSignature class was loaded by getClass.getClassLoader, which was incompatible with system classloader.
+ * As a result, unpickler couldn't see the signature and that blew up the mirror.
+ */
+ var classLoader: ClassLoader
/** Paul: It seems the default class loader does not pick up root classes, whereas the system classloader does.
* Can you check with your newly acquired classloader fu whether this implementation makes sense?
*/
def javaClass(path: String): jClass[_] =
- javaClass(path, defaultReflectiveClassLoader())
+ javaClass(path, classLoader)
def javaClass(path: String, classLoader: JClassLoader): jClass[_] =
Class.forName(path, true, classLoader)
@@ -75,19 +101,70 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
(if (msg eq null) "reflection error while loading " + clazz.name
else "error while loading " + clazz.name) + ", " + msg)
}
- try {
- markAbsent(NoType)
- val ssig = jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature])
+ // don't use classOf[scala.reflect.ScalaSignature] here, because it will use getClass.getClassLoader, not mirror's classLoader
+ // don't use asInstanceOf either because of the same reason (lol, I cannot believe I fell for it)
+ // don't use structural types to simplify reflective invocations because of the same reason
+ // todo. test for this
+ def loadAnnotation(name: String): java.lang.annotation.Annotation = {
+ def inferClasspath(cl: ClassLoader) = cl match {
+ case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
+ case _ => "<unknown>"
+ }
+ def show(cl: ClassLoader) = cl match {
+ case cl if cl != null =>
+ "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl))
+ case null =>
+ import scala.tools.util.PathResolver.Environment._
+ "primordial classloader with boot classpath [%s]".format(javaBootClassPath)
+ }
+
+ try {
+ val cls_ann = Class.forName(name, true, classLoader)
+ val anns = jclazz.getAnnotations
+ val ann = anns find (_.annotationType == cls_ann) orNull;
+ if (ann == null && anns.find(_.annotationType.getName == name).isDefined) {
+ val msg = "Mirror classloader mismatch: %s (loaded by %s)%nis unrelated to the mirror's classloader (%s)"
+ throw new Error(msg.format(jclazz, show(jclazz.getClassLoader), show(classLoader)))
+ }
+ ann
+ } catch {
+ case ex: ClassNotFoundException =>
+ val msg = "Dysfunctional mirror classloader, cannot load %s: %s."
+ throw new Error(msg.format(name, show(classLoader)), ex)
+ }
+ }
+ def loadScalaSignature: Option[String] = {
+ val ssig = loadAnnotation("scala.reflect.ScalaSignature")
if (ssig != null) {
- info("unpickling Scala "+clazz + " and " + module+ ", owner = " + clazz.owner)
- val bytes = ssig.bytes.getBytes
- val len = ByteCodecs.decode(bytes)
- unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName)
+ val bytesMethod = ssig.annotationType.getMethod("bytes")
+ val result = bytesMethod.invoke(ssig)
+ Some(result.asInstanceOf[String])
} else {
- val slsig = jclazz.getAnnotation(classOf[scala.reflect.ScalaLongSignature])
- if (slsig != null) {
+ None
+ }
+ }
+ def loadScalaLongSignature: Option[Array[String]] = {
+ val slsig = loadAnnotation("scala.reflect.ScalaLongSignature")
+ if (slsig != null) {
+ val bytesMethod = slsig.annotationType.getMethod("bytes")
+ val result = bytesMethod.invoke(slsig)
+ Some(result.asInstanceOf[Array[String]])
+ } else {
+ None
+ }
+ }
+ try {
+ markAbsent(NoType)
+ val sigs = (loadScalaSignature, loadScalaLongSignature)
+ sigs match {
+ case (Some(ssig), _) =>
+ info("unpickling Scala "+clazz + " and " + module+ ", owner = " + clazz.owner)
+ val bytes = ssig.getBytes
+ val len = ByteCodecs.decode(bytes)
+ unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName)
+ case (_, Some(slsig)) =>
info("unpickling Scala "+clazz + " and " + module + " with long Scala signature")
- val byteSegments = slsig.bytes map (_.getBytes)
+ val byteSegments = slsig map (_.getBytes)
val lens = byteSegments map ByteCodecs.decode
val bytes = Array.ofDim[Byte](lens.sum)
var len = 0
@@ -96,10 +173,10 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
len += l
}
unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName)
- } else { // class does not have a Scala signature; it's a Java class
+ case (None, None) =>
+ // class does not have a Scala signature; it's a Java class
info("translating reflection info for Java " + jclazz) //debug
initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz))
- }
}
} catch {
case ex: MissingRequirementError =>
@@ -383,52 +460,70 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
*/
def classToScala(jclazz: jClass[_]): Symbol = classCache.toScala(jclazz) {
val jname = javaTypeName(jclazz)
- val owner = sOwner(jclazz)
- val simpleName = scalaSimpleName(jclazz)
-
- val sym = {
- def lookup = {
- def coreLookup(name: Name): Symbol = {
- val sym = owner.info.decl(name)
- sym orElse {
- if (name.startsWith(nme.NAME_JOIN_STRING))
- coreLookup(name.subName(1, name.length))
- else
- NoSymbol
+
+ val sym =
+ if (jname == fulltpnme.RuntimeNothing)
+ NothingClass
+ else if (jname == fulltpnme.RuntimeNull)
+ NullClass
+ else
+ {
+ val owner = sOwner(jclazz)
+ val simpleName = scalaSimpleName(jclazz)
+
+ def lookup = {
+ def coreLookup(name: Name): Symbol = {
+ val sym = owner.info.decl(name)
+ sym orElse {
+ if (name.startsWith(nme.NAME_JOIN_STRING))
+ coreLookup(name.subName(1, name.length))
+ else
+ NoSymbol
+ }
+ }
+
+ if (nme.isModuleName(simpleName)) {
+ val moduleName = nme.stripModuleSuffix(simpleName).toTermName
+ val sym = coreLookup(moduleName)
+ if (sym == NoSymbol) sym else sym.moduleClass
+ } else {
+ coreLookup(simpleName)
}
}
- if (nme.isModuleName(simpleName)) {
- val moduleName = nme.stripModuleSuffix(simpleName).toTermName
- val sym = coreLookup(moduleName)
- if (sym == NoSymbol) sym else sym.moduleClass
- } else {
- coreLookup(simpleName)
+ val sym = {
+ if (jclazz.isMemberClass && !nme.isImplClassName(jname)) {
+ lookup
+ } else if (jclazz.isLocalClass || invalidClassName(jname)) {
+ // local classes and implementation classes not preserved by unpickling - treat as Java
+ jclassAsScala(jclazz)
+ } else if (jclazz.isArray) {
+ ArrayClass
+ } else javaTypeToValueClass(jclazz) orElse {
+ // jclazz is top-level - get signature
+ lookup
+ // val (clazz, module) = createClassModule(
+ // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _))
+ // classCache enter (jclazz, clazz)
+ // clazz
+ }
}
- }
- if (jclazz.isMemberClass && !nme.isImplClassName(jname)) {
- lookup
- } else if (jclazz.isLocalClass || invalidClassName(jname)) {
- // local classes and implementation classes not preserved by unpickling - treat as Java
- jclassAsScala(jclazz)
- } else if (jclazz.isArray) {
- ArrayClass
- } else javaTypeToValueClass(jclazz) orElse {
- // jclazz is top-level - get signature
- lookup
- // val (clazz, module) = createClassModule(
- // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _))
- // classCache enter (jclazz, clazz)
- // clazz
- }
- }
+ if (!sym.isType) {
+ val classloader = jclazz.getClassLoader
+ println("classloader is: %s of type %s".format(classloader, classloader.getClass))
+ def inferClasspath(cl: ClassLoader) = cl match {
+ case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
+ case _ => "<unknown>"
+ }
+ println("classpath is: %s".format(inferClasspath(classloader)))
+ def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName)
+ def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName)
+ assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType)
+ }
- if (!sym.isType) {
- def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName)
- def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName)
- assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType)
- }
+ sym
+ }
sym.asInstanceOf[ClassSymbol]
}
diff --git a/src/compiler/scala/reflect/runtime/Memoizer.scala b/src/compiler/scala/reflect/runtime/Memoizer.scala
deleted file mode 100644
index 4c1b82ae6d..0000000000
--- a/src/compiler/scala/reflect/runtime/Memoizer.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package scala.reflect.runtime
-
-import collection.mutable.ArrayBuffer
-import Mirror.Type
-
-/** Class that can be used for memoizing types in reified trees */
-class Memoizer {
- private val mem = new ArrayBuffer[Mirror.Type]
- def get(n: Int): Type = mem(n)
- def add(n: Int, tpe: Type): Type = {
- while (mem.length <= n) mem += null
- mem(n) = tpe
- tpe
- }
-}
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
index d3e4dd7619..bf4bc83bea 100644
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ b/src/compiler/scala/reflect/runtime/Mirror.scala
@@ -1,31 +1,31 @@
package scala.reflect
package runtime
-import internal.{SomePhase, NoPhase, Phase, TreeGen}
import java.lang.reflect.Array
+import ReflectionUtils._
+import scala.tools.nsc.util.ScalaClassLoader._
/** The mirror for standard runtime reflection from Java.
*/
-class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxes with api.Mirror {
+class Mirror(var classLoader: ClassLoader) extends Universe with api.Mirror {
definitions.init()
-
import definitions._
def symbolForName(name: String): Symbol = {
- val clazz = javaClass(name, defaultReflectiveClassLoader())
+ val clazz = javaClass(name, classLoader)
classToScala(clazz)
}
def companionInstance(clazz: Symbol): AnyRef = {
- val singleton = ReflectionUtils.singletonInstance(clazz.fullName, defaultReflectiveClassLoader())
+ val singleton = singletonInstance(classLoader, clazz.fullName)
singleton
}
def symbolOfInstance(obj: Any): Symbol = classToScala(obj.getClass)
def typeOfInstance(obj: Any): Type = typeToScala(obj.getClass)
// to do add getClass/getType for instances of primitive types, probably like this:
- // def getClass[T <: AnyVal : Manifest](x: T): Symbol = manifest[T].getClass
+ // def getClass[T <: AnyVal : ClassTag](x: T): Symbol = classTag[T].sym
def getValueOfField(receiver: AnyRef, field: Symbol): Any = {
fieldToJava(field).get(receiver)
@@ -46,17 +46,31 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe
jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
}
- override def classToType(jclazz: java.lang.Class[_]): Type = typeToScala(jclazz)
- override def classToSymbol(jclazz: java.lang.Class[_]): Symbol = classToScala(jclazz)
+ private def validateIncomingClassLoader(wannabeCl: ClassLoader) = {
+ val ourCls = loaderChain(classLoader)
+ if (wannabeCl != null && !(ourCls contains wannabeCl))
+ throw new Error("class doesn't belong to the classloader chain of the mirror")
+ }
+
+ def classToType(jclazz: java.lang.Class[_]): Type = {
+ validateIncomingClassLoader(jclazz.getClassLoader)
+ typeToScala(jclazz)
+ }
+
+ def classToSymbol(jclazz: java.lang.Class[_]): Symbol = {
+ validateIncomingClassLoader(jclazz.getClassLoader)
+ classToScala(jclazz)
+ }
+
+ def typeToClass(tpe: Type): java.lang.Class[_] =
+ typeToJavaClass(tpe)
- override def typeToClass(tpe: Type): java.lang.Class[_] = typeToJavaClass(tpe)
- override def symbolToClass(sym: Symbol): java.lang.Class[_] = classToJava(sym)
+ def symbolToClass(sym: Symbol): java.lang.Class[_] =
+ classToJava(sym)
override def inReflexiveMirror = true
}
-object Mirror extends Mirror
-
/** test code; should go to tests once things settle down a bit
*
diff --git a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala b/src/compiler/scala/reflect/runtime/RuntimeTypes.scala
deleted file mode 100644
index 84d02ab7a0..0000000000
--- a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-package scala.reflect
-package runtime
-
-import collection.mutable.ListBuffer
-
-trait RuntimeTypes extends Universe with api.RuntimeTypes {
-
- /** To lift path dependent types into reflection, we use InstanceRefSymbols.
- * Two of these are equal if they point to the same object reference. Todo: remove
- */
- case class InstanceRefSymbol(value: AnyRef) extends TermSymbol(NoSymbol, NoPosition, nme.EMPTY)
- object InstanceRefSymbol extends InstanceRefSymbolExtractor
-
- override private[reflect] def namedType(pre: Type, sym: Symbol, args: List[Type]): Type = {
- val tparamBuf = new ListBuffer[Symbol]
- val args1 = for (arg <- args) yield arg match {
- case _: TypeBounds =>
- val ex = pre.typeSymbol.freshExistential("$ex") setInfo arg
- tparamBuf += ex
- TypeRef(NoPrefix, ex, List())
- case _ =>
- arg
- }
- existentialAbstraction(tparamBuf.toList, typeRef(pre, sym, args1))
- }
-
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/Settings.scala b/src/compiler/scala/reflect/runtime/Settings.scala
index b4f0123114..bbe4d60e9c 100644
--- a/src/compiler/scala/reflect/runtime/Settings.scala
+++ b/src/compiler/scala/reflect/runtime/Settings.scala
@@ -23,7 +23,6 @@ class Settings extends internal.settings.MutableSettings {
val overrideObjects = new BooleanSetting(false)
val debug = new BooleanSetting(false)
- // val YdepMethTpes = new BooleanSetting(true)
val Ynotnull = new BooleanSetting(false)
val explaintypes = new BooleanSetting(false)
val verbose = new BooleanSetting(false)
@@ -34,4 +33,6 @@ class Settings extends internal.settings.MutableSettings {
val Yrecursion = new IntSetting(0)
val maxClassfileName = new IntSetting(255)
val Xexperimental = new BooleanSetting(false)
+ val deepCloning = new BooleanSetting (false)
+ val XoldPatmat = new BooleanSetting(false)
}
diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala
index 4b35a5b37e..7c1cc16152 100644
--- a/src/compiler/scala/reflect/runtime/Loaders.scala
+++ b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala
@@ -5,7 +5,7 @@ import internal.Flags
import java.lang.{Class => jClass, Package => jPackage}
import collection.mutable
-trait Loaders { self: SymbolTable =>
+trait SymbolLoaders { self: SymbolTable =>
/** The lazy type for root.
*/
@@ -123,6 +123,11 @@ trait Loaders { self: SymbolTable =>
}
}
+ /** Assert that packages have package scopes */
+ override def validateClassInfo(tp: ClassInfoType) {
+ assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope])
+ }
+
override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass)
override def scopeTransform(owner: Symbol)(op: => Scope): Scope =
diff --git a/src/compiler/scala/reflect/runtime/SymbolTable.scala b/src/compiler/scala/reflect/runtime/SymbolTable.scala
index 5331f0a53e..64a5894d01 100644
--- a/src/compiler/scala/reflect/runtime/SymbolTable.scala
+++ b/src/compiler/scala/reflect/runtime/SymbolTable.scala
@@ -3,29 +3,10 @@ package runtime
/**
* This symbol table trait fills in the definitions so that class information is obtained by refection.
- * It can be used either from the reflexive mirror itself (class Universe), or else from
+ * It can be used either from the reflexive mirror itself (class Mirror), or else from
* a runtime compiler that uses reflection to get a class information (class scala.tools.nsc.ReflectGlobal)
*/
-trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with Loaders with SynchronizedOps {
-
- /** If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package
- * <owner>.<name>, otherwise return NoSymbol.
- * Exception: If owner is root and a java class with given name exists, create symbol in empty package instead.
- */
- override def missingHook(owner: Symbol, name: Name): Symbol =
- if (owner.isRoot && isJavaClass(name.toString))
- definitions.EmptyPackageClass.info decl name
- else if (name.isTermName && owner.hasPackageFlag && !owner.isEmptyPackageClass)
- makeScalaPackage(if (owner.isRoot) name.toString else owner.fullName+"."+name).sourceModule
- else {
- info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass)
- super.missingHook(owner, name)
- }
-
- /** Assert that packages have package scopes */
- override def validateClassInfo(tp: ClassInfoType) {
- assert(!tp.typeSymbol.isPackageClass || tp.decls.isInstanceOf[PackageScope])
- }
+trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with ClassLoaders with SymbolLoaders with SynchronizedOps {
def info(msg: => String) =
if (settings.verbose.value) println("[reflect-compiler] "+msg)
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedOps.scala b/src/compiler/scala/reflect/runtime/SynchronizedOps.scala
index dd806beb2a..907c0dd369 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedOps.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedOps.scala
@@ -39,7 +39,7 @@ trait SynchronizedOps extends internal.SymbolTable
trait SynchronizedScope extends Scope {
override def isEmpty: Boolean = synchronized { super.isEmpty }
override def size: Int = synchronized { super.size }
- override def enter(sym: Symbol) = synchronized { super.enter(sym) }
+ override def enter[T <: Symbol](sym: T): T = synchronized { super.enter(sym) }
override def rehash(sym: Symbol, newname: Name) = synchronized { super.rehash(sym, newname) }
override def unlink(e: ScopeEntry) = synchronized { super.unlink(e) }
override def unlink(sym: Symbol) = synchronized { super.unlink(sym) }
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
index 3f2fa30be2..4048e94d0f 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -14,19 +14,20 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol =
synchronized { super.connectModuleToClass(m, moduleClass) }
- override def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar =
- new FreeVar(name, value) with SynchronizedTermSymbol initFlags newFlags setInfo tpe
+ override def newFreeTermSymbol(name: TermName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeTerm =
+ new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags flags setInfo info
- override protected def makeNoSymbol = new NoSymbol with SynchronizedSymbol
+ override def newFreeTypeSymbol(name: TypeName, info: Type, value: => Any, flags: Long = 0L, origin: String = null): FreeType =
+ new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags flags setInfo info
+
+ override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol
trait SynchronizedSymbol extends Symbol {
- override def rawowner = synchronized { super.rawowner }
- override def rawname = synchronized { super.rawname }
override def rawflags = synchronized { super.rawflags }
+ override def rawflags_=(x: Long) = synchronized { super.rawflags_=(x) }
- override def rawflags_=(x: FlagsType) = synchronized { super.rawflags_=(x) }
- override def name_=(x: Name) = synchronized { super.name_=(x) }
+ override def rawowner = synchronized { super.rawowner }
override def owner_=(owner: Symbol) = synchronized { super.owner_=(owner) }
override def validTo = synchronized { super.validTo }
@@ -55,37 +56,55 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
// ------ creators -------------------------------------------------------------------
- override def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol =
- new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
-
- override def newAbstractTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol =
+ override protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol =
new AbstractTypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags
- override def newAliasTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol =
+ override protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol =
new AliasTypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags
- override def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
- new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
-
- override def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol =
- new MethodSymbol(this, pos, name) with SynchronizedMethodSymbol initFlags newFlags
+ override protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem =
+ new TypeSkolem(this, pos, name, origin) with SynchronizedTypeSymbol initFlags newFlags
- override def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol =
+ override protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol =
new ClassSymbol(this, pos, name) with SynchronizedClassSymbol initFlags newFlags
- override def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol =
+ override protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol =
new ModuleClassSymbol(this, pos, name) with SynchronizedModuleClassSymbol initFlags newFlags
- override def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem =
- if ((newFlags & DEFERRED) == 0L)
- new TypeSkolem(this, pos, name, origin) with SynchronizedTypeSymbol initFlags newFlags
- else
- new TypeSkolem(this, pos, name, origin) with AbstractTypeMixin with SynchronizedTypeSymbol initFlags newFlags
+ override protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol =
+ new PackageClassSymbol(this, pos, name) with SynchronizedModuleClassSymbol initFlags newFlags
+
+ override protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol =
+ new RefinementClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags
+
+ override protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol =
+ new ClassSymbol(this, pos, name) with ImplClassSymbol with SynchronizedClassSymbol initFlags newFlags
+
+ override protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol =
+ new PackageObjectClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags
+
+ override protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol =
+ new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
+
+ override protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol =
+ new MethodSymbol(this, pos, name) with SynchronizedMethodSymbol initFlags newFlags
+
+ override protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol =
+ new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
+
+ override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol =
+ new PackageSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
+
+ // TODO
+ // override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long)
+ // override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long)
}
// ------- subclasses ---------------------------------------------------------------------
trait SynchronizedTermSymbol extends TermSymbol with SynchronizedSymbol {
+ override def name_=(x: Name) = synchronized { super.name_=(x) }
+ override def rawname = synchronized { super.rawname }
override def referenced: Symbol = synchronized { super.referenced }
override def referenced_=(x: Symbol) = synchronized { super.referenced_=(x) }
}
@@ -95,6 +114,8 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
}
trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol {
+ override def name_=(x: Name) = synchronized { super.name_=(x) }
+ override def rawname = synchronized { super.rawname }
override def typeConstructor: Type = synchronized { super.typeConstructor }
override def tpe: Type = synchronized { super.tpe }
}
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
index 28f12b378f..7b1fc9fc0d 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
@@ -1,28 +1,27 @@
package scala.reflect
package runtime
-import scala.tools.nsc
-import scala.tools.nsc.reporters.Reporter
-import scala.tools.nsc.reporters.StoreReporter
-import scala.tools.nsc.reporters.AbstractReporter
+import scala.tools.nsc.reporters._
import scala.tools.nsc.ReflectGlobal
import scala.tools.nsc.CompilerCommand
import scala.tools.nsc.Global
import scala.tools.nsc.typechecker.Modes
import scala.tools.nsc.io.VirtualDirectory
import scala.tools.nsc.interpreter.AbstractFileClassLoader
-import reflect.{mirror => rm}
import scala.tools.nsc.util.FreshNameCreator
import scala.reflect.internal.Flags
import scala.tools.nsc.util.{NoSourceFile, NoFile}
import java.lang.{Class => jClass}
-import scala.tools.nsc.util.trace
+import scala.compat.Platform.EOL
trait ToolBoxes extends { self: Universe =>
- class ToolBox(val reporter: Reporter = new StoreReporter, val options: String = "") {
+ def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = "") = new ToolBox(frontEnd, options)
- class ToolBoxGlobal(settings0: nsc.Settings, reporter0: nsc.reporters.Reporter) extends ReflectGlobal(settings0, reporter0) {
+ class ToolBox(val frontEnd: FrontEnd, val options: String) extends AbsToolBox {
+
+ class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: Reporter)
+ extends ReflectGlobal(settings, reporter, ToolBox.this.classLoader) {
import definitions._
private val trace = scala.tools.nsc.util.trace when settings.debug.value
@@ -36,64 +35,7 @@ trait ToolBoxes extends { self: Universe =>
newTermName("__wrapper$" + wrapCount)
}
- private def moduleFileName(className: String) = className + "$"
-
- private def isFree(t: Tree) = t.isInstanceOf[Ident] && t.symbol.isInstanceOf[FreeVar]
-
- def typedTopLevelExpr(tree: Tree, pt: Type): Tree = {
- // !!! Why is this is in the empty package? If it's only to make
- // it inaccessible then please put it somewhere designed for that
- // rather than polluting the empty package with synthetics.
- trace("typing: ")(showAttributed(tree, true, true, settings.Yshowsymkinds.value))
- val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName("<expression-owner>"), List(ObjectClass.tpe), newScope)
- val owner = ownerClass.newLocalDummy(tree.pos)
- val ttree = typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt)
- trace("typed: ")(showAttributed(ttree, true, true, settings.Yshowsymkinds.value))
- ttree
- }
-
- def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match {
- case Some(sym) if sym != null && sym != NoSymbol => sym.owner
- case _ => NoSymbol
- }
-
- def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = {
- val obj = EmptyPackageClass.newModule(nextWrapperModuleName())
- val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass)
- obj.moduleClass setInfo minfo
- obj setInfo obj.moduleClass.tpe
- val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName))
- def makeParam(fv: Symbol) = meth.newValueParameter(fv.name.toTermName) setInfo fv.tpe
- meth setInfo MethodType(fvs map makeParam, AnyClass.tpe)
- minfo.decls enter meth
- trace("wrapping ")(defOwner(expr) -> meth)
- val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth))
- val moduledef = ModuleDef(
- obj,
- Template(
- List(TypeTree(ObjectClass.tpe)),
- emptyValDef,
- NoMods,
- List(),
- List(List()),
- List(methdef),
- NoPosition))
- trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value))
- val cleanedUp = resetLocalAttrs(moduledef)
- trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value))
- cleanedUp
- }
-
- def wrapInPackage(clazz: Tree): PackageDef =
- PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(clazz))
-
- def wrapInCompilationUnit(tree: Tree): CompilationUnit = {
- val unit = new CompilationUnit(NoSourceFile)
- unit.body = tree
- unit
- }
-
- def compileExpr(expr: Tree, fvs: List[Symbol]): String = {
+ def verifyExpr(expr: Tree): Unit = {
// Previously toolboxes used to typecheck their inputs before compiling.
// Actually, the initial demo by Martin first typechecked the reified tree,
// then ran it, which typechecked it again, and only then launched the
@@ -104,44 +46,186 @@ trait ToolBoxes extends { self: Universe =>
// That's why we cannot allow inputs of toolboxes to be typechecked,
// at least not until the aforementioned issue is closed.
val typed = expr filter (t => t.tpe != null && t.tpe != NoType && !t.isInstanceOf[TypeTree])
- if (!typed.isEmpty) {
- throw new Error("cannot compile trees that are already typed")
+ if (!typed.isEmpty) throw new ToolBoxError(ToolBox.this, "reflective toolbox has failed: cannot operate on trees that are already typed")
+
+ val freeTypes = this.freeTypes(expr)
+ if (freeTypes.length > 0) {
+ var msg = "reflective toolbox has failed:" + EOL
+ msg += "unresolved free type variables (namely: " + (freeTypes map (ft => "%s %s".format(ft.name, ft.origin)) mkString ", ") + "). "
+ msg += "have you forgot to use TypeTag annotations for type parameters external to a reifee? "
+ msg += "if you have troubles tracking free type variables, consider using -Xlog-free-types"
+ throw new ToolBoxError(ToolBox.this, msg)
}
+ }
- val mdef = wrapInObject(expr, fvs)
- val pdef = wrapInPackage(mdef)
- val unit = wrapInCompilationUnit(pdef)
- val run = new Run
- run.compileUnits(List(unit), run.namerPhase)
- mdef.symbol.fullName
+ def typeCheckExpr(expr0: Tree, pt: Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ verifyExpr(expr0)
+
+ // need to wrap the expr, because otherwise you won't be able to typecheck macros against something that contains free vars
+ // [Eugene] get rid of the copy/paste w.r.t compileExpr
+ val freeTerms = this.freeTerms(expr0)
+ val freeTermNames = collection.mutable.Map[Symbol, TermName]()
+ freeTerms foreach (ft => {
+ var name = ft.name.toString
+ val namesakes = freeTerms takeWhile (_ != ft) filter (ft2 => ft != ft2 && ft.name == ft2.name)
+ if (namesakes.length > 0) name += ("$" + (namesakes.length + 1))
+ freeTermNames += (ft -> newTermName(name + nme.MIRROR_FREE_VALUE_SUFFIX))
+ })
+ var expr = new Transformer {
+ override def transform(tree: Tree): Tree =
+ if (tree.hasSymbol && tree.symbol.isFreeTerm) {
+ tree match {
+ case Ident(_) =>
+ Ident(freeTermNames(tree.symbol))
+ case _ =>
+ throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ }
+ } else {
+ super.transform(tree)
+ }
+ }.transform(expr0)
+ val dummies = freeTerms map (freeTerm => ValDef(NoMods, freeTermNames(freeTerm), TypeTree(freeTerm.info), Select(Ident(PredefModule), newTermName("$qmark$qmark$qmark"))))
+ expr = Block(dummies, expr)
+
+ // [Eugene] how can we implement that?
+ // !!! Why is this is in the empty package? If it's only to make
+ // it inaccessible then please put it somewhere designed for that
+ // rather than polluting the empty package with synthetics.
+ val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName("<expression-owner>"), List(ObjectClass.tpe), newScope)
+ val owner = ownerClass.newLocalDummy(expr.pos)
+ var currentTyper = typer.atOwner(expr, owner)
+ val wrapper1 = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _)
+ val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _)
+ def wrapper (tree: => Tree) = wrapper1(wrapper2(tree))
+
+ phase = (new Run).typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled
+ currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions
+ reporter.reset()
+
+ trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value))
+ wrapper(currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match {
+ case analyzer.SilentResultValue(result) =>
+ trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value))
+ var Block(dummies, unwrapped) = result
+ var reversedFreeTermNames = freeTermNames map (_.swap)
+ // todo. also fixup singleton types
+ unwrapped = new Transformer {
+ override def transform(tree: Tree): Tree =
+ tree match {
+ case Ident(name) if reversedFreeTermNames contains name =>
+ Ident(reversedFreeTermNames(name)) setType tree.tpe
+ case _ =>
+ super.transform(tree)
+ }
+ }.transform(unwrapped)
+ new TreeTypeSubstituter(dummies map (_.symbol), dummies map (dummy => SingleType(NoPrefix, reversedFreeTermNames(dummy.symbol.name)))).traverse(unwrapped)
+ unwrapped
+ case error @ analyzer.SilentTypeError(_) =>
+ trace("failed: ")(error.err.errMsg)
+ if (!silent) throw new ToolBoxError(ToolBox.this, "reflective typecheck has failed: %s".format(error.err.errMsg))
+ EmptyTree
+ })
}
- private def getMethod(jclazz: jClass[_], name: String) =
- jclazz.getDeclaredMethods.find(_.getName == name).get
+ def compileExpr(expr: Tree): (Object, java.lang.reflect.Method) = {
+ verifyExpr(expr)
+
+ def wrapExpr(expr0: Tree): Tree = {
+ def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match {
+ case Some(sym) if sym != null && sym != NoSymbol => sym.owner
+ case _ => NoSymbol
+ }
+
+ val freeTerms = this.freeTerms(expr0)
+ val freeTermNames = collection.mutable.Map[Symbol, TermName]()
+ freeTerms foreach (ft => {
+ var name = ft.name.toString
+ val namesakes = freeTerms takeWhile (_ != ft) filter (ft2 => ft != ft2 && ft.name == ft2.name)
+ if (namesakes.length > 0) name += ("$" + (namesakes.length + 1))
+ freeTermNames += (ft -> newTermName(name + nme.MIRROR_FREE_VALUE_SUFFIX))
+ })
+ val expr = new Transformer {
+ override def transform(tree: Tree): Tree =
+ if (tree.hasSymbol && tree.symbol.isFreeTerm) {
+ tree match {
+ case Ident(_) =>
+ Apply(Ident(freeTermNames(tree.symbol)), List())
+ case _ =>
+ throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ }
+ } else {
+ super.transform(tree)
+ }
+ }.transform(expr0)
+
+ val obj = EmptyPackageClass.newModule(nextWrapperModuleName())
+ val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass)
+ obj.moduleClass setInfo minfo
+ obj setInfo obj.moduleClass.tpe
+ val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName))
+ def makeParam(fv: Symbol) = {
+ // [Eugene] conventional way of doing this?
+ val underlying = fv.tpe.resultType
+ val tpe = appliedType(definitions.FunctionClass(0).tpe, List(underlying))
+ meth.newValueParameter(freeTermNames(fv)) setInfo tpe
+ }
+ meth setInfo MethodType(freeTerms map makeParam, AnyClass.tpe)
+ minfo.decls enter meth
+ trace("wrapping ")(defOwner(expr) -> meth)
+ val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth))
+ val moduledef = ModuleDef(
+ obj,
+ Template(
+ List(TypeTree(ObjectClass.tpe)),
+ emptyValDef,
+ NoMods,
+ List(),
+ List(List()),
+ List(methdef),
+ NoPosition))
+ trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value))
+ var cleanedUp = resetLocalAttrs(moduledef)
+ trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value))
+ cleanedUp
+ }
- def runExpr(expr: Tree): Any = {
- val fvs = (expr filter isFree map (_.symbol)).distinct
+ val mdef = wrapExpr(expr)
+ val pdef = PackageDef(Ident(nme.EMPTY_PACKAGE_NAME), List(mdef))
+ val unit = new CompilationUnit(NoSourceFile)
+ unit.body = pdef
+ val run = new Run
reporter.reset()
- val className = compileExpr(expr, fvs)
- if (reporter.hasErrors) {
- throw new Error("reflective compilation has failed")
- }
+ run.compileUnits(List(unit), run.namerPhase)
+ throwIfErrors()
+ val className = mdef.symbol.fullName
if (settings.debug.value) println("generated: "+className)
+ def moduleFileName(className: String) = className + "$"
val jclazz = jClass.forName(moduleFileName(className), true, classLoader)
val jmeth = jclazz.getDeclaredMethods.find(_.getName == wrapperMethodName).get
val jfield = jclazz.getDeclaredFields.find(_.getName == NameTransformer.MODULE_INSTANCE_NAME).get
val singleton = jfield.get(null)
+ (singleton, jmeth)
+ }
+
+ def runExpr(expr: Tree, freeTypes: Map[TypeName, Type] = Map[TypeName, Type]()): Any = {
+ val freeTerms = this.freeTerms(expr) // need to calculate them here, because later on they will be erased
+ val thunks = freeTerms map (fte => () => fte.value) // need to be lazy in order not to distort evaluation order
+
// @odersky writes: Not sure we will be able to drop this. I forgot the reason why we dereference () functions,
// but there must have been one. So I propose to leave old version in comments to be resurrected if the problem resurfaces.
-// val result = jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*)
+ // @Eugene writes: this dates back to the days when one could only reify functions
+ // hence, blocks were translated into nullary functions, so
+ // presumably, it was useful to immediately evaluate them to get the result of a block
+// val result = jmeth.invoke(singleton, freeTerms map (sym => sym.asInstanceOf[FreeTermVar].value.asInstanceOf[AnyRef]): _*)
// if (etpe.typeSymbol != FunctionClass(0)) result
// else {
// val applyMeth = result.getClass.getMethod("apply")
// applyMeth.invoke(result)
// }
- jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*)
+ val (singleton, jmeth) = compileExpr(expr)
+ jmeth.invoke(singleton, thunks map (_.asInstanceOf[AnyRef]): _*)
}
def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = {
@@ -159,8 +243,18 @@ trait ToolBoxes extends { self: Universe =>
settings.Yshowsymkinds.value = saved3
}
}
+
+ // reporter doesn't accumulate errors, but the front-end does
+ def throwIfErrors() = {
+ if (frontEnd.hasErrors) {
+ var msg = "reflective compilation has failed: " + EOL + EOL
+ msg += frontEnd.infos map (_.msg) mkString EOL
+ throw new ToolBoxError(ToolBox.this, msg)
+ }
+ }
}
+ // todo. is not going to work with quoted arguments with embedded whitespaces
lazy val arguments = options.split(" ")
lazy val virtualDirectory =
@@ -170,49 +264,90 @@ trait ToolBoxes extends { self: Universe =>
}
lazy val compiler: ToolBoxGlobal = {
- val errorFn: String => Unit = reporter.error(scala.tools.nsc.util.NoPosition, _)
- val command = reporter match {
- case reporter: AbstractReporter => new CompilerCommand(arguments.toList, reporter.settings, errorFn)
- case _ => new CompilerCommand(arguments.toList, errorFn)
+ try {
+ val errorFn: String => Unit = msg => frontEnd.log(NoPosition, msg, frontEnd.ERROR)
+ val command = new CompilerCommand(arguments.toList, errorFn)
+ command.settings.outputDirs setSingleOutput virtualDirectory
+ val instance = new ToolBoxGlobal(command.settings, new FrontEndToReporterProxy(frontEnd) { val settings = command.settings })
+ if (frontEnd.hasErrors) {
+ var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL
+ msg += frontEnd.infos map (_.msg) mkString EOL
+ throw new ToolBoxError(this, msg)
+ }
+ instance.phase = (new instance.Run).typerPhase // need to manually set a phase, because otherwise TypeHistory will crash
+ instance
+ } catch {
+ case ex: Throwable =>
+ var msg = "reflective compilation has failed: cannot initialize the compiler due to %s".format(ex.toString)
+ throw new ToolBoxError(this, msg, ex)
}
-
- command.settings.outputDirs setSingleOutput virtualDirectory
- val instance = new ToolBoxGlobal(command.settings, reporter)
-
- // need to establish a run an phase because otherwise we run into an assertion in TypeHistory
- // that states that the period must be different from NoPeriod
- val run = new instance.Run
- instance.phase = run.refchecksPhase
- instance
}
- lazy val importer = new compiler.Importer {
- val from: self.type = self
- }
+ // @Eugene: how do I make this work without casts?
+ // lazy val importer = compiler.mkImporter(self)
+ lazy val importer = compiler.mkImporter(self).asInstanceOf[compiler.Importer { val from: self.type }]
lazy val exporter = importer.reverse
- lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, defaultReflectiveClassLoader)
+ lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, self.classLoader)
- def typeCheck(tree: rm.Tree, expectedType: rm.Type): rm.Tree = {
- if (compiler.settings.verbose.value) println("typing "+tree+", pt = "+expectedType)
- val ctree: compiler.Tree = importer.importTree(tree.asInstanceOf[Tree])
- val pt: compiler.Type = importer.importType(expectedType.asInstanceOf[Type])
- val ttree: compiler.Tree = compiler.typedTopLevelExpr(ctree, pt)
- val rmttree = exporter.importTree(ttree).asInstanceOf[rm.Tree]
+ def typeCheck(tree: Tree, expectedType: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ if (compiler.settings.verbose.value) println("typing "+tree+", expectedType = "+expectedType+", freeTypes = "+freeTypes)
+ var ctree: compiler.Tree = importer.importTree(tree)
+ var cexpectedType: compiler.Type = importer.importType(expectedType)
+
+ if (compiler.settings.verbose.value) println("substituting "+ctree+", expectedType = "+expectedType)
+ val cfreeTypes: Map[compiler.FreeType, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeType], importer.importType(v)) }
+ ctree = compiler.substituteFreeTypes(ctree, cfreeTypes)
+ cexpectedType = compiler.substituteFreeTypes(cexpectedType, cfreeTypes)
+
+ if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType)
+ val ttree: compiler.Tree = compiler.typeCheckExpr(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)
+ val rmttree = exporter.importTree(ttree)
rmttree
}
- def typeCheck(tree: rm.Tree): rm.Tree =
- typeCheck(tree, WildcardType.asInstanceOf[rm.Type])
+ def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree =
+ // todo. implement this
+ ???
+
+ def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree =
+ // todo. implement this
+ ???
+
+ def resetAllAttrs[T <: Tree](tree: T): T = {
+ val ctree: compiler.Tree = importer.importTree(tree)
+ val ttree: compiler.Tree = compiler.resetAllAttrs(ctree)
+ val rmttree = exporter.importTree(ttree)
+ rmttree.asInstanceOf[T]
+ }
+
+ def resetLocalAttrs[T <: Tree](tree: T): T = {
+ val ctree: compiler.Tree = importer.importTree(tree)
+ val ttree: compiler.Tree = compiler.resetLocalAttrs(ctree)
+ val rmttree = exporter.importTree(ttree)
+ rmttree.asInstanceOf[T]
+ }
+
+ def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String =
+ compiler.showAttributed(importer.importTree(tree), printTypes, printIds, printKinds)
+
+ def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = {
+ if (compiler.settings.verbose.value) println("running "+tree+", freeTypes = "+freeTypes)
+ var ctree: compiler.Tree = importer.importTree(tree)
- def showAttributed(tree: rm.Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String =
- compiler.showAttributed(importer.importTree(tree.asInstanceOf[Tree]), printTypes, printIds, printKinds)
+ if (compiler.settings.verbose.value) println("substituting "+ctree)
+ val cfreeTypes: Map[compiler.FreeType, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeType], importer.importType(v)) }
+ ctree = compiler.substituteFreeTypes(ctree, cfreeTypes)
- def runExpr(tree: rm.Tree): Any = {
- if (compiler.settings.verbose.value) println("running "+tree)
- val ctree: compiler.Tree = importer.importTree(tree.asInstanceOf[Tree])
+ if (compiler.settings.verbose.value) println("running "+ctree)
compiler.runExpr(ctree)
}
+
+ class ToolBoxError(val toolBox: ToolBox, val message: String, val cause: Throwable = null) extends Throwable(message, cause)
+
+ object ToolBoxError extends ToolBoxErrorExtractor {
+ def unapply(error: ToolBoxError): Option[(ToolBox, String)] = Some((error.toolBox, error.message))
+ }
}
}
diff --git a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
deleted file mode 100644
index 61001a4778..0000000000
--- a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
+++ /dev/null
@@ -1,49 +0,0 @@
-package scala.reflect
-package runtime
-
-trait TreeBuildUtil extends Universe with api.TreeBuildUtil {
- /** A comment to the effect of why initialize was added to all these
- * would be appreciated. (We may as well start somewhere.)
- */
- def staticClass(fullname: String) = definitions.getRequiredClass(fullname).initialize
- def staticModule(fullname: String) = definitions.getRequiredModule(fullname).initialize
- def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.initialize.thisType
-
- /** Selects type symbol with given name from the defined members of prefix type
- */
- def selectType(owner: Symbol, name: String): Symbol =
- owner.info.decl(newTypeName(name))
-
- /** Selects term symbol with given name and type from the defined members of prefix type
- * @pre The prefix type
- * @name The name of the selected member
- */
- def selectTerm(owner: Symbol, name: String): Symbol = {
- val sym = owner.info.decl(newTermName(name))
- if (sym.isOverloaded) sym suchThat (!_.isMethod)
- else sym
- }
-
- def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol =
- owner.info.decl(newTermName(name)).alternatives(index)
-
- def selectParam(owner: Symbol, idx: Int): Symbol = {
- def selectInList(params: List[Symbol], idx: Int, fallback: Type): Symbol = {
- if (params.isEmpty) selectIn(fallback, idx)
- else if (idx == 0) params.head
- else selectInList(params.tail, idx - 1, fallback)
- }
- def selectIn(tpe: Type, idx: Int): Symbol = tpe match {
- case PolyType(tparams, res) => selectInList(tparams, idx, res)
- case MethodType(params, res) => selectInList(params, idx, res)
- case _ => NoSymbol
- }
- selectIn(owner.info, idx)
- }
-
- def newFreeVar(name: String, info: Type, value: Any) = newFreeVar(newTermName(name), info, value)
-
- def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers =
- Modifiers(flags, privateWithin, annotations)
-
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala
index 324fee87ab..fd53308d0a 100644
--- a/src/compiler/scala/reflect/runtime/Universe.scala
+++ b/src/compiler/scala/reflect/runtime/Universe.scala
@@ -8,12 +8,14 @@ import internal.{SomePhase, NoPhase, Phase, TreeGen}
* It also provides methods to go from Java members to Scala members,
* using the code in JavaConversions.
*/
-class Universe extends SymbolTable {
+abstract class Universe extends SymbolTable with ToolBoxes {
type AbstractFileType = AbstractFile
def picklerPhase = SomePhase
+ type TreeGen = internal.TreeGen
+
val gen = new TreeGen { val global: Universe.this.type = Universe.this }
lazy val settings = new Settings
@@ -30,19 +32,12 @@ class Universe extends SymbolTable {
def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
- def focusPos(pos: Position) = pos
- def isRangePos(pos: Position) = false
- def showPos(pos: Position) = "<unknown position>"
-
- type Position = String // source file?
- val NoPosition = ""
-
definitions.AnyValClass // force it.
// establish root association to avoid cyclic dependency errors later
- classToScala(classOf[java.lang.Object]).initialize
+ // don't use classOf[...] here, because it gets serviced by getClass.getClassLoader!
+ classToScala(Class.forName("java.lang.Object", true, classLoader)).initialize
// println("initializing definitions")
definitions.init()
-
}
diff --git a/src/compiler/scala/reflect/runtime/package.scala b/src/compiler/scala/reflect/runtime/package.scala
new file mode 100644
index 0000000000..52ab2c5deb
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/package.scala
@@ -0,0 +1,5 @@
+package scala.reflect
+
+package object runtime {
+ def mkMirror(classLoader: ClassLoader): api.Mirror = new Mirror(classLoader)
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/ant/ScalaBazaar.scala b/src/compiler/scala/tools/ant/ScalaBazaar.scala
deleted file mode 100644
index fa44715c7f..0000000000
--- a/src/compiler/scala/tools/ant/ScalaBazaar.scala
+++ /dev/null
@@ -1,316 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala Ant Tasks **
-** / __/ __// _ | / / / _ | (c) 2005-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.tools
-package ant
-
-import scala.collection.DefaultMap
-import scala.collection.{ mutable, immutable }
-
-import java.io.{File, FileInputStream, FileOutputStream, FileWriter, StringReader}
-import java.util.zip.{ZipOutputStream, ZipEntry}
-
-import org.apache.tools.ant.{Project, Task}
-import org.apache.tools.ant.types.{FileSet, Path}
-import org.apache.tools.ant.util.FileUtils
-
-/** A set of files that can be installed at any relative location */
-class LooseFileSet {
- var destination: Option[String] = None
- def setDestination(dest: String) = {
- destination = Some(dest)
- }
-
- var fileset: Option[FileSet] = None
- def addConfiguredFileSet(fs: FileSet) = {
- fileset = Some(fs)
- }
-}
-
-/** An Ant task that generates a Scala Bazaars package (sbp file) along
- * with an advertisement of that package.
- *
- * This task can take the following parameters as attributes:
- * - `file` (mandatory),
- * - `adfile`,
- * - `name` (mandatory),
- * - `version` (mandatory),
- * - `depends`,
- * - `description`,
- * - `link`.
- *
- * @author Gilles Dubochet, Stephane Micheloud
- */
-class ScalaBazaar extends Task with ScalaTask {
-
- /** The unique Ant file utilities instance to use in this task. */
- private val fileUtils = FileUtils.getFileUtils()
-
-/******************************************************************************\
-** Ant user-properties **
-\******************************************************************************/
-
- /** The path to the archive file. */
- private var file: Option[File] = None
- /** The optional path to the advertisement file. */
- private var adfile: Option[File] = None
- /** The name of the package. */
- private var name: Option[String] = None
- /** The version number of the package. */
- private var version: Option[String] = None
- /** An (optional) list of names of the packages it depends of. */
- private var depends: List[String] = Nil
- /** An (optional) description of this package. */
- private var desc: Option[String] = None
- /** An (optional) URL link pointing to the location of the package */
- private var link: Option[String] = None
-
- /** The sets of files to include in the package */
- private object fileSetsMap extends DefaultMap[String, List[FileSet]] {
- private var content = new mutable.HashMap[String, List[FileSet]]()
- def get(key: String): Option[List[FileSet]] = content.get(key)
- override def size: Int = content.size
- def update(key: String, value: FileSet) {
- if (content.contains(key) && content(key) != Nil)
- content.update(key, value :: content(key))
- else content.update(key, List(value))
- }
- def fileSets = content.toList
- def iterator = content.iterator
- }
-
-/******************************************************************************\
-** Internal properties **
-\******************************************************************************/
-
-
-/******************************************************************************\
-** Properties setters **
-\******************************************************************************/
-
- /** Sets the file attribute. Used by [[http://ant.apache.org Ant]].
- * @param input The value of `file`.
- */
- def setFile(input: File) { file = Some(input) }
-
- /** Sets the advertisement file attribute. Used by [[http://ant.apache.org Ant]].
- * @param input The value of `adfile`.
- */
- def setAdfile(input: File) { adfile = Some(input) }
-
- /** Sets the name attribute of this package. Used by [[http://ant.apache.org Ant]].
- * @param input The value of `name`.
- */
- def setName(input: String) { name = Some(input) }
-
- /** Sets the version attribute of this package. Used by [[http://ant.apache.org Ant]].
- * @param input The value of `version`.
- */
- def setVersion(input: String) { version = Some(input) }
-
- /** Sets the depends attribute. Used by [[http://ant.apache.org Ant]].
- * @param input The value for `depends`.
- */
- def setDepends(input: String) = {
- depends = (input split ",").toList.flatMap { s: String =>
- val st = s.trim()
- (if (st != "") List(st) else Nil)
- }
- }
-
- /** Sets the description attribute of this package. Used by [[http://ant.apache.org Ant]].
- * @param input The value of `description`.
- */
- def setDesc(input: String) { desc = Some(input) }
-
- /** Sets the link attribute of this package. Used by [[http://ant.apache.org Ant]].
- * @param input The value of `link`.
- */
- def setLink(input: String) { link = Some(input) }
-
- def addConfiguredLibset(input: FileSet) =
- fileSetsMap.update("lib", input)
-
- def addConfiguredBinset(input: FileSet) =
- fileSetsMap.update("bin", input)
-
- def addConfiguredSrcset(input: FileSet) =
- fileSetsMap.update("src", input)
-
- def addConfiguredManset(input: FileSet) =
- fileSetsMap.update("man", input)
-
- def addConfiguredDocset(input: FileSet) =
- fileSetsMap.update("doc/" + getName, input)
-
- def addConfiguredMiscset(input: FileSet) =
- fileSetsMap.update("misc/" + getName, input)
-
- def addConfiguredLooseset(set: LooseFileSet) = {
- (set.destination, set.fileset) match {
- case (None, _) =>
- buildError("destination not specified for a loose file set")
-
- case (_, None) =>
- buildError("no files specified for a loose file set")
-
- case (Some(dest), Some(fileset)) =>
- fileSetsMap.update(dest, fileset)
- }
- }
-
-/******************************************************************************\
-** Properties getters **
-\******************************************************************************/
-
- /** Gets the value of the file attribute in a Scala-friendly form.
- * @return The file as a file.
- */
- private def getName: String =
- if (name.isEmpty) buildError("Name attribute must be defined first.")
- else name.get
-
- /** Gets the value of the file attribute in a Scala-friendly form.
- * @return The file as a file.
- */
- private def getFile: File =
- if (file.isEmpty) buildError("Member 'file' is empty.")
- else getProject resolveFile file.get.toString
-
- /** Gets the value of the adfile attribute in a Scala-friendly form.
- * @return The adfile as a file.
- */
- private def getAdfile: File =
- if (adfile.isEmpty) buildError("Member 'adfile' is empty.")
- else getProject resolveFile adfile.get.toString
-
-/******************************************************************************\
-** Compilation and support methods **
-\******************************************************************************/
-
- /** Transforms a string name into a file relative to the provided base
- * directory.
- * @param base A file pointing to the location relative to which the name
- * will be resolved.
- * @param name A relative or absolute path to the file as a string.
- * @return A file created from the name and the base file.
- */
- private def nameToFile(base: File)(name: String): File =
- existing(fileUtils.resolveFile(base, name))
-
- /** Transforms a string name into a file relative to the build advertDoc
- * directory.
- * @param name A relative or absolute path to the file as a string.
- * @return A file created from the name.
- */
- private def nameToFile(name: String): File =
- existing(getProject resolveFile name)
-
- /** Tests if a file exists and prints a warning in case it doesn't.
- * Always returns the file, even if it doesn't exist.
- * @param file A file to test for existance.
- * @return The same file.
- */
- private def existing(file: File): File = {
- if (!file.exists)
- log("Element '" + file.toString + "' does not exist.", Project.MSG_WARN)
- file
- }
-
- private def writeFile(file: File, content: String) {
- if (file.exists && !file.canWrite)
- buildError("File " + file + " is not writable")
- else {
- val writer = new FileWriter(file, false)
- writer write content
- writer.close()
- }
- }
-
-/******************************************************************************\
-** The big execute method **
-\******************************************************************************/
-
- /** Performs the compilation. */
- override def execute() {
- // Tests if all mandatory attributes are set and valid.
- if (file.isEmpty) buildError("Attribute 'file' is not set.")
- if (name.isEmpty) buildError("Attribute 'name' is not set.")
- if (version.isEmpty) buildError("Attribute 'version' is not set.")
-
- val pack = {
- <package>
- <name>{name.get}</name>
- <version>{version.get}</version>{
- if (!depends.isEmpty)
- <depends>{
- for (depend <- depends) yield
- <name>{depend}</name>
- }</depends>
- else Nil
- }{
- if (!desc.isEmpty)
- <description>{desc.get}</description>
- else Nil
- }
- </package>
- }
-
- log("Creating package '" + name.get + "'")
-
- // Creates the advert file
- val advert = {
- <availablePackage>
- {pack}
- {link match {
- case None => <link>INSERT LINK HERE</link>
- case Some(str) => <link>{str}</link>
- }}
- </availablePackage>
- }
-
- if (!adfile.isEmpty)
- writeFile(getAdfile, advert.toString)
-
- // Checks for new files and creates the ZIP
-
- val zipContent =
- for {
- (folder, fileSets) <- fileSetsMap.fileSets
- fileSet <- fileSets
- file <- fileSet.getDirectoryScanner(getProject).getIncludedFiles.toList
- } yield Triple(folder, fileSet.getDir(getProject), file)
- val zip = new ZipOutputStream(new FileOutputStream(file.get, false))
- if (!zipContent.isEmpty) {
- for (Triple(destFolder, srcFolder, file) <- zipContent) {
- log(file, Project.MSG_DEBUG)
- zip putNextEntry new ZipEntry(destFolder + "/" + file)
- val input = new FileInputStream(nameToFile(srcFolder)(file))
- val buf = new Array[Byte](10240)
- var n = input.read(buf, 0, buf.length)
- while (n >= 0) {
- zip.write (buf, 0, n)
- n = input.read(buf, 0, buf.length)
- }
- zip.closeEntry()
- input.close()
- }
- } else log("Archive contains no files.", Project.MSG_VERBOSE)
- zip putNextEntry new ZipEntry("meta/description")
- val packInput = new StringReader(pack.toString)
- var byte = packInput.read()
- while (byte != -1) {
- zip.write (byte)
- byte = packInput.read()
- }
- zip.closeEntry()
- packInput.close()
- zip.close()
- }
-
-}
diff --git a/src/compiler/scala/tools/ant/ScalaTool.scala b/src/compiler/scala/tools/ant/ScalaTool.scala
index 35e26bd9f5..3fdbcd1140 100644
--- a/src/compiler/scala/tools/ant/ScalaTool.scala
+++ b/src/compiler/scala/tools/ant/ScalaTool.scala
@@ -125,8 +125,7 @@ class ScalaTool extends ScalaMatchingTask {
* Adds an Ant Path reference to the tool's classpath.
* Note that all entries in the path must exist either relative to the project
* basedir or with an absolute path to a file in the filesystem. As a result,
- * this is not a mechanism for setting the classpath for more general use scripts,
- * such as those distributed within sbaz distribution packages.
+ * this is not a mechanism for setting the classpath for more general use scripts.
*/
def setClassPathRef(input: Reference) {
val tmpPath = emptyPath
diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala
index c92474b33e..daa08ef8a7 100644
--- a/src/compiler/scala/tools/ant/Scaladoc.scala
+++ b/src/compiler/scala/tools/ant/Scaladoc.scala
@@ -75,6 +75,11 @@ class Scaladoc extends ScalaMatchingTask {
*/
object Flag extends PermissibleValue {
val values = List("yes", "no", "on", "off")
+ def getBooleanValue(value: String, flagName: String): Boolean =
+ if (Flag.isPermissible(value))
+ return ("yes".equals(value) || "on".equals(value))
+ else
+ buildError("Unknown " + flagName + " flag '" + value + "'")
}
/** The directories that contain source files to compile. */
@@ -127,6 +132,25 @@ class Scaladoc extends ScalaMatchingTask {
/** Instruct the ant task not to fail in the event of errors */
private var nofail: Boolean = false
+ /** Instruct the scaladoc tool to document implicit conversions */
+ private var docImplicits: Boolean = false
+
+ /** Instruct the scaladoc tool to document all (including impossible) implicit conversions */
+ private var docImplicitsShowAll: Boolean = false
+
+ /** Instruct the scaladoc tool to output implicits debugging information */
+ private var docImplicitsDebug: Boolean = false
+
+ /** Instruct the scaladoc tool to create diagrams */
+ private var docDiagrams: Boolean = false
+
+ /** Instruct the scaladoc tool to output diagram creation debugging information */
+ private var docDiagramsDebug: Boolean = false
+
+ /** Instruct the scaladoc tool to use the binary given to create diagrams */
+ private var docDiagramsDotPath: Option[String] = None
+
+
/*============================================================================*\
** Properties setters **
\*============================================================================*/
@@ -361,12 +385,39 @@ class Scaladoc extends ScalaMatchingTask {
*
* @param input One of the flags `yes/no` or `on/off`. Default if no/off.
*/
- def setNoFail(input: String) {
- if (Flag.isPermissible(input))
- nofail = "yes".equals(input) || "on".equals(input)
- else
- buildError("Unknown nofail flag '" + input + "'")
- }
+ def setNoFail(input: String) =
+ nofail = Flag.getBooleanValue(input, "nofail")
+
+ /** Set the `implicits` info attribute.
+ * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */
+ def setImplicits(input: String) =
+ docImplicits = Flag.getBooleanValue(input, "implicits")
+
+ /** Set the `implicitsShowAll` info attribute to enable scaladoc to show all implicits, including those impossible to
+ * convert to from the default scope
+ * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */
+ def setImplicitsShowAll(input: String) =
+ docImplicitsShowAll = Flag.getBooleanValue(input, "implicitsShowAll")
+
+ /** Set the `implicitsDebug` info attribute so scaladoc outputs implicit conversion debug information
+ * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */
+ def setImplicitsDebug(input: String) =
+ docImplicitsDebug = Flag.getBooleanValue(input, "implicitsDebug")
+
+ /** Set the `diagrams` bit so Scaladoc adds diagrams to the documentation
+ * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */
+ def setDiagrams(input: String) =
+ docDiagrams = Flag.getBooleanValue(input, "diagrams")
+
+ /** Set the `diagramsDebug` bit so Scaladoc outputs diagram building debug information
+ * @param input One of the flags `yes/no` or `on/off`. Default if no/off. */
+ def setDiagramsDebug(input: String) =
+ docDiagramsDebug = Flag.getBooleanValue(input, "diagramsDebug")
+
+ /** Set the `diagramsDotPath` attribute to the path where graphviz dot can be found (including the binary file name,
+ * eg: /usr/bin/dot) */
+ def setDiagramsDotPath(input: String) =
+ docDiagramsDotPath = Some(input)
/*============================================================================*\
** Properties getters **
@@ -560,6 +611,13 @@ class Scaladoc extends ScalaMatchingTask {
docSettings.deprecation.value = deprecation
docSettings.unchecked.value = unchecked
+ docSettings.docImplicits.value = docImplicits
+ docSettings.docImplicitsDebug.value = docImplicitsDebug
+ docSettings.docImplicitsShowAll.value = docImplicitsShowAll
+ docSettings.docDiagrams.value = docDiagrams
+ docSettings.docDiagramsDebug.value = docDiagramsDebug
+ if(!docDiagramsDotPath.isEmpty) docSettings.docDiagramsDotPath.value = docDiagramsDotPath.get
+
if (!docgenerator.isEmpty) docSettings.docgenerator.value = docgenerator.get
if (!docrootcontent.isEmpty) docSettings.docRootContent.value = docrootcontent.get.getAbsolutePath()
log("Scaladoc params = '" + addParams + "'", Project.MSG_DEBUG)
diff --git a/src/compiler/scala/tools/ant/antlib.xml b/src/compiler/scala/tools/ant/antlib.xml
index bbdf1fc9db..78159e6d10 100644
--- a/src/compiler/scala/tools/ant/antlib.xml
+++ b/src/compiler/scala/tools/ant/antlib.xml
@@ -1,6 +1,4 @@
<antlib>
- <!--<taskdef name="scala"
- classname="scala.tools.ant.Scala"/>-->
<taskdef name="classloadVerify"
classname="scala.tools.ant.ClassloadVerify"/>
<taskdef name="fsc"
@@ -9,16 +7,12 @@
classname="scala.tools.ant.Scalac"/>
<taskdef name="scalascript"
classname="scala.tools.ant.ScalaTool"/>
- <taskdef name="sbaz"
- classname="scala.tools.ant.ScalaBazaar"/>
<taskdef name="scaladoc"
classname="scala.tools.ant.Scaladoc"/>
<taskdef name="scalatool"
classname="scala.tools.ant.ScalaTool"/>
<taskdef name="same"
classname="scala.tools.ant.Same"/>
- <!--<taskdef name="scalatest"
- classname="scala.tools.ant.ScalaDoc"/>-->
<taskdef name="pack200"
classname="scala.tools.ant.Pack200Task"/>
</antlib>
diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala
index e4504702d4..91356b3c19 100644
--- a/src/compiler/scala/tools/cmd/FromString.scala
+++ b/src/compiler/scala/tools/cmd/FromString.scala
@@ -7,19 +7,19 @@ package scala.tools
package cmd
import nsc.io.{ Path, File, Directory }
-import scala.reflect.OptManifest
+import scala.reflect.TypeTag
/** A general mechanism for defining how a command line argument
* (always a String) is transformed into an arbitrary type. A few
* example instances are in the companion object, but in general
* either IntFromString will suffice or you'll want custom transformers.
*/
-abstract class FromString[+T](implicit m: OptManifest[T]) extends scala.runtime.AbstractPartialFunction[String, T] {
+abstract class FromString[+T](implicit t: TypeTag[T]) extends PartialFunction[String, T] {
def apply(s: String): T
- def _isDefinedAt(s: String): Boolean = true
+ def isDefinedAt(s: String): Boolean = true
def zero: T = apply("")
- def targetString: String = m.toString
+ def targetString: String = t.toString
}
object FromString {
@@ -30,20 +30,20 @@ object FromString {
/** Path related stringifiers.
*/
val ExistingFile: FromString[File] = new FromString[File] {
- override def _isDefinedAt(s: String) = toFile(s).isFile
+ override def isDefinedAt(s: String) = toFile(s).isFile
def apply(s: String): File =
if (isDefinedAt(s)) toFile(s)
else cmd.runAndExit(println("'%s' is not an existing file." format s))
}
val ExistingDir: FromString[Directory] = new FromString[Directory] {
- override def _isDefinedAt(s: String) = toDir(s).isDirectory
+ override def isDefinedAt(s: String) = toDir(s).isDirectory
def apply(s: String): Directory =
if (isDefinedAt(s)) toDir(s)
else cmd.runAndExit(println("'%s' is not an existing directory." format s))
}
def ExistingDirRelativeTo(root: Directory) = new FromString[Directory] {
private def resolve(s: String) = toDir(s) toAbsoluteWithRoot root toDirectory
- override def _isDefinedAt(s: String) = resolve(s).isDirectory
+ override def isDefinedAt(s: String) = resolve(s).isDirectory
def apply(s: String): Directory =
if (isDefinedAt(s)) resolve(s)
else cmd.runAndExit(println("'%s' is not an existing directory." format resolve(s)))
@@ -65,7 +65,7 @@ object FromString {
/** Implicit as the most likely to be useful as-is.
*/
implicit val IntFromString: FromString[Int] = new FromString[Int] {
- override def _isDefinedAt(s: String) = safeToInt(s).isDefined
+ override def isDefinedAt(s: String) = safeToInt(s).isDefined
def apply(s: String) = safeToInt(s).get
def safeToInt(s: String): Option[Int] = try Some(java.lang.Integer.parseInt(s)) catch { case _: NumberFormatException => None }
}
diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala
index 0869350dd3..e8230b8ca4 100644
--- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala
+++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala
@@ -14,20 +14,34 @@ trait AnyValReps {
sealed abstract class AnyValNum(name: String, repr: Option[String], javaEquiv: String) extends AnyValRep(name,repr,javaEquiv) {
case class Op(val op : String, val doc : String)
+
+ private def companionCoercions(tos: String*) = {
+ tos.toList map (to =>
+ """implicit def %s2%s(x: %s): %s = x.to%s""".format(javaEquiv, to, name, to.capitalize, to.capitalize)
+ )
+ }
+ def implicitCoercions: List[String] = javaEquiv match {
+ case "byte" => companionCoercions("short", "int", "long", "float", "double")
+ case "short" | "char" => companionCoercions("int", "long", "float", "double")
+ case "int" => companionCoercions("long", "float", "double")
+ case "long" => companionCoercions("float", "double")
+ case "float" => companionCoercions("double")
+ case _ => Nil
+ }
def isCardinal: Boolean = isIntegerType(this)
def unaryOps = {
val ops = List(
Op("+", "/**\n" +
- " * @return this value, unmodified\n" +
+ " * Returns this value, unmodified.\n" +
" */"),
Op("-", "/**\n" +
- " * @return the negation of this value\n" +
+ " * Returns the negation of this value.\n" +
" */"))
if(isCardinal)
Op("~", "/**\n" +
- " * @return the bitwise negation of this value\n" +
+ " * Returns the bitwise negation of this value.\n" +
" * @example {{{\n" +
" * ~5 == -6\n" +
" * // in binary: ~00000101 ==\n" +
@@ -41,7 +55,7 @@ trait AnyValReps {
if (isCardinal)
List(
Op("|", "/**\n" +
- " * @return the bitwise OR of this value and x\n" +
+ " * Returns the bitwise OR of this value and `x`.\n" +
" * @example {{{\n" +
" * (0xf0 | 0xaa) == 0xfa\n" +
" * // in binary: 11110000\n" +
@@ -51,7 +65,7 @@ trait AnyValReps {
" * }}}\n" +
" */"),
Op("&", "/**\n" +
- " * @return the bitwise AND of this value and x\n" +
+ " * Returns the bitwise AND of this value and `x`.\n" +
" * @example {{{\n" +
" * (0xf0 & 0xaa) == 0xa0\n" +
" * // in binary: 11110000\n" +
@@ -61,7 +75,7 @@ trait AnyValReps {
" * }}}\n" +
" */"),
Op("^", "/**\n" +
- " * @return the bitwise XOR of this value and x\n" +
+ " * Returns the bitwise XOR of this value and `x`.\n" +
" * @example {{{\n" +
" * (0xf0 ^ 0xaa) == 0x5a\n" +
" * // in binary: 11110000\n" +
@@ -76,13 +90,13 @@ trait AnyValReps {
if (isCardinal)
List(
Op("<<", "/**\n" +
- " * @return this value bit-shifted left by the specified number of bits,\n" +
+ " * Returns this value bit-shifted left by the specified number of bits,\n" +
" * filling in the new right bits with zeroes.\n" +
" * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}\n" +
" */"),
Op(">>>", "/**\n" +
- " * @return this value bit-shifted right by the specified number of bits,\n" +
+ " * Returns this value bit-shifted right by the specified number of bits,\n" +
" * filling the new left bits with zeroes.\n" +
" * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}\n" +
" * @example {{{\n" +
@@ -93,7 +107,7 @@ trait AnyValReps {
" */"),
Op(">>", "/**\n" +
- " * @return this value bit-shifted left by the specified number of bits,\n" +
+ " * Returns this value bit-shifted left by the specified number of bits,\n" +
" * filling in the right bits with the same value as the left-most bit of this.\n" +
" * The effect of this is to retain the sign of the value.\n" +
" * @example {{{\n" +
@@ -105,19 +119,19 @@ trait AnyValReps {
else Nil
def comparisonOps = List(
- Op("==", "/**\n * @return `true` if this value is equal x, `false` otherwise\n */"),
- Op("!=", "/**\n * @return `true` if this value is not equal to x, `false` otherwise\n */"),
- Op("<", "/**\n * @return `true` if this value is less than x, `false` otherwise\n */"),
- Op("<=", "/**\n * @return `true` if this value is less than or equal to x, `false` otherwise\n */"),
- Op(">", "/**\n * @return `true` if this value is greater than x, `false` otherwise\n */"),
- Op(">=", "/**\n * @return `true` if this value is greater than or equal to x, `false` otherwise\n */"))
+ Op("==", "/**\n * Returns `true` if this value is equal to x, `false` otherwise.\n */"),
+ Op("!=", "/**\n * Returns `true` if this value is not equal to x, `false` otherwise.\n */"),
+ Op("<", "/**\n * Returns `true` if this value is less than x, `false` otherwise.\n */"),
+ Op("<=", "/**\n * Returns `true` if this value is less than or equal to x, `false` otherwise.\n */"),
+ Op(">", "/**\n * Returns `true` if this value is greater than x, `false` otherwise.\n */"),
+ Op(">=", "/**\n * Returns `true` if this value is greater than or equal to x, `false` otherwise.\n */"))
def otherOps = List(
- Op("+", "/**\n * @return the sum of this value and x\n */"),
- Op("-", "/**\n * @return the difference of this value and x\n */"),
- Op("*", "/**\n * @return the product of this value and x\n */"),
- Op("/", "/**\n * @return the quotient of this value and x\n */"),
- Op("%", "/**\n * @return the remainder of the division of this value by x\n */"))
+ Op("+", "/**\n * Returns the sum of this value and `x`.\n */"),
+ Op("-", "/**\n * Returns the difference of this value and `x`.\n */"),
+ Op("*", "/**\n * Returns the product of this value and `x`.\n */"),
+ Op("/", "/**\n * Returns the quotient of this value and `x`.\n */"),
+ Op("%", "/**\n * Returns the remainder of the division of this value by `x`.\n */"))
// Given two numeric value types S and T , the operation type of S and T is defined as follows:
// If both S and T are subrange types then the operation type of S and T is Int.
@@ -160,7 +174,7 @@ trait AnyValReps {
}
def objectLines = {
val comp = if (isCardinal) cardinalCompanion else floatingCompanion
- (comp + allCompanions).trim.lines map interpolate toList
+ ((comp + allCompanions).trim.lines map interpolate).toList ++ implicitCoercions
}
/** Makes a set of binary operations based on the given set of ops, args, and resultFn.
@@ -224,8 +238,8 @@ trait AnyValReps {
def classDoc = interpolate(classDocTemplate)
def objectDoc = ""
def mkImports = ""
- def mkClass = assemble("final class", "AnyVal", classLines) + "\n"
- def mkObject = assemble("object", "AnyValCompanion", objectLines) + "\n"
+ def mkClass = assemble("final class", "private", "AnyVal", classLines) + "\n"
+ def mkObject = assemble("object", "", "AnyValCompanion", objectLines) + "\n"
def make() = List[String](
headerTemplate,
mkImports,
@@ -235,8 +249,8 @@ trait AnyValReps {
mkObject
) mkString ""
- def assemble(what: String, parent: String, lines: List[String]): String = {
- val decl = "%s %s extends %s ".format(what, name, parent)
+ def assemble(what: String, ctor: String, parent: String, lines: List[String]): String = {
+ val decl = "%s %s %s extends %s ".format(what, name, ctor, parent)
val body = if (lines.isEmpty) "{ }\n\n" else lines map indent mkString ("{\n", "\n", "\n}\n")
decl + body
diff --git a/src/compiler/scala/tools/cmd/program/DumpClass.scala b/src/compiler/scala/tools/cmd/program/DumpClass.scala
new file mode 100644
index 0000000000..a583f1d3ea
--- /dev/null
+++ b/src/compiler/scala/tools/cmd/program/DumpClass.scala
@@ -0,0 +1,40 @@
+/* NEST (New Scala Test)
+ * Copyright 2007-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools
+package cmd
+package program
+
+import scala.reflect.internal.JvmClassInfo
+import scala.tools.nsc.io.Directory
+
+object DumpClass {
+ private val usage = """
+ |Usage: dump-class [options] <path> <path> ...
+ |
+ |Parses and dumps the bytecode of all classes found at the given paths.
+ |""".stripMargin
+
+ private val unaryOps = List(
+ "signatures" -> "dump signatures"
+ )
+ private val info = Simple.scalaProgramInfo("dump-class", usage)
+ private val spec = Simple(info, unaryOps, Nil, null)
+
+ def deepInfos(dir: String) = {
+ val files = Directory(dir).deepFiles.toList filter (_ hasExtension "class")
+ files.sortBy(_.path) map (f => (f.path, JvmClassInfo fromPath f.path))
+ }
+
+ def main(args: Array[String]): Unit = {
+ val runner = spec instance args
+ import runner._
+
+ if (args.isEmpty)
+ println(usage)
+ else
+ (residualArgs flatMap deepInfos) sortBy (_._1) map (_._2) foreach println
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/ClassLoaders.scala b/src/compiler/scala/tools/nsc/ClassLoaders.scala
new file mode 100644
index 0000000000..4058ee9324
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ClassLoaders.scala
@@ -0,0 +1,64 @@
+package scala.tools.nsc
+
+import util.ScalaClassLoader
+
+trait ClassLoaders { self: Global =>
+
+ def staticClass(fullname: String) = {
+ if (self.forMSIL)
+ throw new UnsupportedOperationException("Scala reflection not available on this platform")
+
+ getClass(newTypeName(fullname))
+ }
+
+ def staticModule(fullname: String) = {
+ if (self.forMSIL)
+ throw new UnsupportedOperationException("Scala reflection not available on this platform")
+
+ getModule(newTermName(fullname))
+ }
+
+ private def getClass(fullname: Name): Symbol = {
+ var result = getModuleOrClass(fullname.toTypeName)
+ while (result.isAliasType) result = result.info.typeSymbol
+ result
+ }
+
+ private def getModule(fullname: Name): Symbol =
+ getModuleOrClass(fullname.toTermName)
+
+ private def getModuleOrClass(path: Name): Symbol =
+ getModuleOrClass(path, path.length)
+
+ private def getModuleOrClass(path: Name, len: Int): Symbol = {
+ val point = path lastPos('.', len - 1)
+ val owner =
+ if (point > 0) getModuleOrClass(path.toTermName, point)
+ else definitions.RootClass
+ val name = path subName (point + 1, len)
+ val sym = owner.info member name
+ val result = if (path.isTermName) sym.suchThat(_ hasFlag symtab.Flags.MODULE) else sym
+ if (result != NoSymbol) result
+ else {
+ if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug
+ if (owner.isRoot && isJavaClass(name.toString))
+ definitions.EmptyPackageClass.info decl name
+ else {
+ def info(msg: => String) = if (settings.verbose.value) println(msg)
+ info("*** missing: "+name+"/"+name.isTermName+"/"+owner+"/"+owner.hasPackageFlag+"/"+owner.info.decls.getClass)
+ MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path)
+ }
+ }
+ }
+
+ private def isJavaClass(path: String): Boolean =
+ try {
+ val classpath = platform.classPath.asURLs
+ var classLoader = ScalaClassLoader.fromURLs(classpath)
+ Class.forName(path, true, classLoader)
+ true
+ } catch {
+ case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) =>
+ false
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index d6f57801e7..2f1e15168a 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -5,7 +5,7 @@
package scala.tools.nsc
-import util.{ FreshNameCreator, Position, NoPosition, SourceFile, NoSourceFile }
+import util.{ FreshNameCreator, Position, NoPosition, BatchSourceFile, SourceFile, NoSourceFile }
import scala.collection.mutable
import scala.collection.mutable.{ LinkedHashSet, ListBuffer }
@@ -61,6 +61,9 @@ trait CompilationUnits { self: Global =>
/** things to check at end of compilation unit */
val toCheck = new ListBuffer[() => Unit]
+ /** The features that were already checked for this unit */
+ var checkedFeatures = Set[Symbol]()
+
def position(pos: Int) = source.position(pos)
/** The position of a targeted type check
@@ -85,12 +88,13 @@ trait CompilationUnits { self: Global =>
reporter.warning(pos, msg)
def deprecationWarning(pos: Position, msg: String) =
- if (opt.deprecation) warning(pos, msg)
- else currentRun.deprecationWarnings ::= ((pos, msg))
+ currentRun.deprecationWarnings0.warn(pos, msg)
def uncheckedWarning(pos: Position, msg: String) =
- if (opt.unchecked) warning(pos, msg)
- else currentRun.uncheckedWarnings ::= ((pos, msg))
+ currentRun.uncheckedWarnings0.warn(pos, msg)
+
+ def inlinerWarning(pos: Position, msg: String) =
+ currentRun.inlinerWarnings.warn(pos, msg)
def incompleteInputError(pos: Position, msg:String) =
reporter.incompleteInputError(pos, msg)
@@ -104,10 +108,14 @@ trait CompilationUnits { self: Global =>
override def toString() = source.toString()
def clear() {
- fresh = null
- body = null
+ fresh = new FreshNameCreator.Default
+ body = EmptyTree
depends.clear()
defined.clear()
+ synthetics.clear()
+ toCheck.clear()
+ checkedFeatures = Set()
+ icode.clear()
}
}
}
diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala
index a0c39f71fb..a4a8e1fd11 100644
--- a/src/compiler/scala/tools/nsc/CompileSocket.scala
+++ b/src/compiler/scala/tools/nsc/CompileSocket.scala
@@ -93,7 +93,7 @@ class CompileSocket extends CompileOutputCommon {
/** Start a new server. */
private def startNewServer(vmArgs: String) = {
- val cmd = serverCommand(vmArgs split " " toSeq)
+ val cmd = serverCommand((vmArgs split " ").toSeq)
info("[Executing command: %s]" format cmd.mkString(" "))
// Hiding inadequate daemonized implementation from public API for now
@@ -206,7 +206,7 @@ class CompileSocket extends CompileOutputCommon {
Thread sleep 100
ff.length
}
- if (Iterator continually check take 50 find (_ > 0) isEmpty) {
+ if ((Iterator continually check take 50 find (_ > 0)).isEmpty) {
ff.delete()
fatal("Unable to establish connection to server.")
}
diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala
index 54bc218912..4c8a27083a 100644
--- a/src/compiler/scala/tools/nsc/CompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala
@@ -47,7 +47,7 @@ class CompilerCommand(arguments: List[String], val settings: Settings) {
/** Creates a help message for a subset of options based on cond */
def createUsageMsg(cond: Setting => Boolean): String = {
val baseList = (settings.visibleSettings filter cond).toList sortBy (_.name)
- val width = baseList map (_.helpSyntax.length) max
+ val width = (baseList map (_.helpSyntax.length)).max
def format(s: String) = ("%-" + width + "s") format s
def helpStr(s: Setting) = {
val str = format(s.helpSyntax) + " " + s.helpDescription
diff --git a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
index b9e9a14adf..f91cb854c6 100644
--- a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
+++ b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
@@ -8,7 +8,7 @@ package scala.tools.nsc
import scala.tools.util.PathResolver
class GenericRunnerSettings(error: String => Unit) extends Settings(error) {
- def classpathURLs = new PathResolver(this) asURLs
+ def classpathURLs = new PathResolver(this).asURLs
val howtorun =
ChoiceSetting(
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 9ccd0c28db..8c6c927640 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -8,7 +8,6 @@ package scala.tools.nsc
import java.io.{ File, FileOutputStream, PrintWriter, IOException, FileNotFoundException }
import java.nio.charset.{ Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException }
import compat.Platform.currentTime
-
import scala.tools.util.{ Profiling, PathResolver }
import scala.collection.{ mutable, immutable }
import io.{ SourceReader, AbstractFile, Path }
@@ -16,7 +15,6 @@ import reporters.{ Reporter, ConsoleReporter }
import util.{ NoPosition, Exceptional, ClassPath, SourceFile, NoSourceFile, Statistics, StatisticsInfo, BatchSourceFile, ScriptSourceFile, ShowPickled, ScalaClassLoader, returning }
import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat }
import settings.{ AestheticSettings }
-
import symtab.{ Flags, SymbolTable, SymbolLoaders, SymbolTrackers }
import symtab.classfile.Pickler
import dependencies.DependencyAnalysis
@@ -25,26 +23,28 @@ import ast._
import ast.parser._
import typechecker._
import transform._
-
import backend.icode.{ ICodes, GenICode, ICodeCheckers }
import backend.{ ScalaPrimitives, Platform, MSILPlatform, JavaPlatform }
import backend.jvm.GenJVM
import backend.opt.{ Inliners, InlineExceptionHandlers, ClosureElimination, DeadCodeElimination }
import backend.icode.analysis._
+import language.postfixOps
+import reflect.internal.StdAttachments
class Global(var currentSettings: Settings, var reporter: Reporter) extends SymbolTable
- with CompilationUnits
- with Plugins
- with PhaseAssembly
- with Trees
- with Reifiers
- with TreePrinters
- with DocComments
- with MacroContext
- with symtab.Positions {
+ with ClassLoaders
+ with ToolBoxes
+ with CompilationUnits
+ with Plugins
+ with PhaseAssembly
+ with Trees
+ with FreeVars
+ with TreePrinters
+ with DocComments
+ with Positions {
override def settings = currentSettings
-
+
import definitions.{ findNamedMember, findMemberFromRoot }
// alternate constructors ------------------------------------------
@@ -61,7 +61,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
type AbstractFileType = scala.tools.nsc.io.AbstractFile
def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = gen.mkAttributedQualifier(tpe, termSym)
-
+
def picklerPhase: Phase = if (currentRun.isDefined) currentRun.picklerPhase else NoPhase
// platform specific elements
@@ -78,6 +78,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
// sub-components --------------------------------------------------
/** Generate ASTs */
+ type TreeGen = scala.tools.nsc.ast.TreeGen
+
object gen extends {
val global: Global.this.type = Global.this
} with TreeGen {
@@ -127,17 +129,26 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** Print tree in detailed form */
object nodePrinters extends {
val global: Global.this.type = Global.this
- } with NodePrinters with ReifyPrinters {
+ } with NodePrinters {
infolevel = InfoLevel.Verbose
}
+ def withInfoLevel[T](infolevel: nodePrinters.InfoLevel.Value)(op: => T) = {
+ val saved = nodePrinters.infolevel
+ try {
+ nodePrinters.infolevel = infolevel
+ op
+ } finally {
+ nodePrinters.infolevel = saved
+ }
+ }
+
/** Representing ASTs as graphs */
object treeBrowsers extends {
val global: Global.this.type = Global.this
} with TreeBrowsers
val nodeToString = nodePrinters.nodeToString
- val reifiedNodeToString = nodePrinters.reifiedNodeToString
val treeBrowser = treeBrowsers.create()
// ------------ Hooks for interactive mode-------------------------
@@ -215,15 +226,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def logAfterEveryPhase[T](msg: String)(op: => T) {
log("Running operation '%s' after every phase.\n".format(msg) + describeAfterEveryPhase(op))
}
-
+
def shouldLogAtThisPhase = (
(settings.log.isSetByUser)
&& ((settings.log containsPhase globalPhase) || (settings.log containsPhase phase))
)
- def atPhaseStackMessage = atPhaseStack match {
- case Nil => ""
- case ps => ps.reverseMap("->" + _).mkString("(", " ", ")")
- }
// Over 200 closure objects are eliminated by inlining this.
@inline final def log(msg: => AnyRef) {
if (shouldLogAtThisPhase)
@@ -323,7 +330,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def showNames = List(showClass, showObject).flatten
def showPhase = isActive(settings.Yshow)
def showSymbols = settings.Yshowsyms.value
- def showTrees = settings.Xshowtrees.value
+ def showTrees = settings.Xshowtrees.value || settings.XshowtreesCompact.value || settings.XshowtreesStringified.value
val showClass = optSetting[String](settings.Xshowcls) map (x => splitClassAndPhase(x, false))
val showObject = optSetting[String](settings.Xshowobj) map (x => splitClassAndPhase(x, true))
@@ -348,7 +355,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
override protected val etaExpandKeepsStar = settings.etaExpandKeepsStar.value
// Here comes another one...
override protected val enableTypeVarExperimentals = (
- settings.Xexperimental.value || settings.YvirtPatmat.value
+ settings.Xexperimental.value || !settings.XoldPatmat.value
)
// True if -Xscript has been set, indicating a script run.
@@ -940,6 +947,22 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
inform("[running phase " + ph.name + " on " + currentRun.size + " compilation units]")
}
+ /** Collects for certain classes of warnings during this run. */
+ class ConditionalWarning(what: String, option: Settings#BooleanSetting) {
+ val warnings = new mutable.ListBuffer[(Position, String)]
+ def warn(pos: Position, msg: String) =
+ if (option.value) reporter.warning(pos, msg)
+ else warnings += ((pos, msg))
+ def summarize() =
+ if (option.isDefault && warnings.nonEmpty)
+ reporter.warning(NoPosition, "there were %d %s warnings; re-run with %s for details".format(warnings.size, what, option.name))
+ }
+
+ def newUnitParser(code: String) = new syntaxAnalyzer.UnitParser(newCompilationUnit(code))
+ def newUnitScanner(code: String) = new syntaxAnalyzer.UnitScanner(newCompilationUnit(code))
+ def newCompilationUnit(code: String) = new CompilationUnit(newSourceFile(code))
+ def newSourceFile(code: String) = new BatchSourceFile("<console>", code)
+
/** A Run is a single execution of the compiler on a sets of units
*/
class Run {
@@ -951,9 +974,19 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** The currently compiled unit; set from GlobalPhase */
var currentUnit: CompilationUnit = NoCompilationUnit
- /** Counts for certain classes of warnings during this run. */
- var deprecationWarnings: List[(Position, String)] = Nil
- var uncheckedWarnings: List[(Position, String)] = Nil
+ // This change broke sbt; I gave it the thrilling name of uncheckedWarnings0 so
+ // as to recover uncheckedWarnings for its ever-fragile compiler interface.
+ val deprecationWarnings0 = new ConditionalWarning("deprecation", settings.deprecation)
+ val uncheckedWarnings0 = new ConditionalWarning("unchecked", settings.unchecked)
+ val featureWarnings = new ConditionalWarning("feature", settings.feature)
+ val inlinerWarnings = new ConditionalWarning("inliner", settings.YinlinerWarnings)
+ val allConditionalWarnings = List(deprecationWarnings0, uncheckedWarnings0, featureWarnings, inlinerWarnings)
+
+ // for sbt's benefit
+ def uncheckedWarnings: List[(Position, String)] = uncheckedWarnings0.warnings.toList
+ def deprecationWarnings: List[(Position, String)] = deprecationWarnings0.warnings.toList
+
+ var reportedFeature = Set[Symbol]()
/** A flag whether macro expansions failed */
var macroExpansionFailed = false
@@ -1006,7 +1039,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** Set phase to a newly created syntaxAnalyzer and call definitions.init. */
val parserPhase: Phase = syntaxAnalyzer.newPhase(NoPhase)
phase = parserPhase
- definitions.init
+ definitions.init()
// Flush the cache in the terminal phase: the chain could have been built
// before without being used. (This happens in the interpreter.)
@@ -1112,7 +1145,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def phaseNamed(name: String): Phase =
findOrElse(firstPhase.iterator)(_.name == name)(NoPhase)
-
+
/** All phases as of 3/2012 here for handiness; the ones in
* active use uncommented.
*/
@@ -1243,12 +1276,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
}
}
else {
- def warn(count: Int, what: String, option: Settings#BooleanSetting) = (
- if (option.isDefault && count > 0)
- warning("there were %d %s warnings; re-run with %s for details".format(count, what, option.name))
- )
- warn(deprecationWarnings.size, "deprecation", settings.deprecation)
- warn(uncheckedWarnings.size, "unchecked", settings.unchecked)
+ allConditionalWarnings foreach (_.summarize)
+
if (macroExpansionFailed)
warning("some macros could not be expanded and code fell back to overridden methods;"+
"\nrecompiling with generated classfiles on the classpath might help.")
@@ -1266,7 +1295,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
// nothing to compile, but we should still report use of deprecated options
if (sources.isEmpty) {
- checkDeprecatedSettings(new CompilationUnit(new BatchSourceFile("<no file>", "")))
+ checkDeprecatedSettings(newCompilationUnit(""))
reportCompileErrors()
return
}
@@ -1356,6 +1385,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
inform(unitTimingsFormatted)
}
+ if (traceSymbolActivity)
+ units map (_.body) foreach (traceSymbols recordSymbolsInTree _)
+
// In case no phase was specified for -Xshow-class/object, show it now for sure.
if (opt.noShow)
showMembers()
@@ -1499,7 +1531,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** We resolve the class/object ambiguity by passing a type/term name.
*/
def showDef(fullName: Name, declsOnly: Boolean, ph: Phase) = {
- val boringOwners = Set(definitions.AnyClass, definitions.AnyRefClass, definitions.ObjectClass)
+ val boringOwners = Set[Symbol](definitions.AnyClass, definitions.AnyRefClass, definitions.ObjectClass)
def phased[T](body: => T): T = afterPhase(ph)(body)
def boringMember(sym: Symbol) = boringOwners(sym.owner)
def symString(sym: Symbol) = if (sym.isTerm) sym.defString else sym.toString
diff --git a/src/compiler/scala/tools/nsc/MacroContext.scala b/src/compiler/scala/tools/nsc/MacroContext.scala
deleted file mode 100644
index 9ea1f87125..0000000000
--- a/src/compiler/scala/tools/nsc/MacroContext.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-package scala.tools.nsc
-
-import symtab.Flags._
-
-trait MacroContext extends reflect.macro.Context { self: Global =>
-
- def captureVariable(vble: Symbol): Unit = vble setFlag CAPTURED
-
- def referenceCapturedVariable(id: Ident): Tree = ReferenceToBoxed(id)
-}
diff --git a/src/compiler/scala/tools/nsc/PhaseAssembly.scala b/src/compiler/scala/tools/nsc/PhaseAssembly.scala
index a627b982b6..a9e029e485 100644
--- a/src/compiler/scala/tools/nsc/PhaseAssembly.scala
+++ b/src/compiler/scala/tools/nsc/PhaseAssembly.scala
@@ -8,6 +8,7 @@ package scala.tools.nsc
import java.io.{ BufferedWriter, FileWriter }
import scala.collection.mutable
+import language.postfixOps
/**
* PhaseAssembly
diff --git a/src/compiler/scala/tools/nsc/Phases.scala b/src/compiler/scala/tools/nsc/Phases.scala
index d18495458c..aa0ea1bdd8 100644
--- a/src/compiler/scala/tools/nsc/Phases.scala
+++ b/src/compiler/scala/tools/nsc/Phases.scala
@@ -7,13 +7,14 @@ package scala.tools.nsc
import symtab.Flags
import util.TableDef
+import language.postfixOps
object Phases {
val MaxPhases = 64
/** A class for tracking something about each phase.
*/
- class Model[T: Manifest] {
+ class Model[T] {
case class Cell(ph: Phase, value: T) {
def name = ph.name
def id = ph.id
diff --git a/src/compiler/scala/tools/nsc/ReflectGlobal.scala b/src/compiler/scala/tools/nsc/ReflectGlobal.scala
index 3132a9987d..68a6a4d336 100644
--- a/src/compiler/scala/tools/nsc/ReflectGlobal.scala
+++ b/src/compiler/scala/tools/nsc/ReflectGlobal.scala
@@ -5,7 +5,7 @@ import reporters.Reporter
/** A version of Global that uses reflection to get class
* infos, instead of reading class or source files.
*/
-class ReflectGlobal(currentSettings: Settings, reporter: Reporter)
+class ReflectGlobal(currentSettings: Settings, reporter: Reporter, var classLoader: ClassLoader)
extends Global(currentSettings, reporter) with reflect.runtime.SymbolTable {
override def transformedType(sym: Symbol) =
@@ -13,4 +13,9 @@ class ReflectGlobal(currentSettings: Settings, reporter: Reporter)
uncurry.transformInfo(sym,
refChecks.transformInfo(sym, sym.info)))
+ override def staticClass(fullname: String) =
+ super[SymbolTable].staticClass(fullname)
+
+ override def staticModule(fullname: String) =
+ super[SymbolTable].staticModule(fullname)
}
diff --git a/src/compiler/scala/tools/nsc/ReflectMain.scala b/src/compiler/scala/tools/nsc/ReflectMain.scala
index 7167f5aa27..f9a18abc25 100644
--- a/src/compiler/scala/tools/nsc/ReflectMain.scala
+++ b/src/compiler/scala/tools/nsc/ReflectMain.scala
@@ -1,7 +1,16 @@
package scala.tools.nsc
+import util.ScalaClassLoader
+import tools.util.PathResolver
+import util.ClassPath.DefaultJavaContext
+
object ReflectMain extends Driver {
- override def newCompiler(): Global = new ReflectGlobal(settings, reporter)
+ private def reflectionClassloaderFromSettings(settings: Settings) = {
+ val classpath = new PathResolver(settings).result
+ ScalaClassLoader.fromURLs(classpath.asURLs, getClass.getClassLoader)
+ }
+
+ override def newCompiler(): Global = new ReflectGlobal(settings, reporter, reflectionClassloaderFromSettings(settings))
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ToolBoxes.scala b/src/compiler/scala/tools/nsc/ToolBoxes.scala
new file mode 100644
index 0000000000..5b2b5ff5e9
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ToolBoxes.scala
@@ -0,0 +1,83 @@
+package scala.tools.nsc
+
+import util.ScalaClassLoader
+
+trait ToolBoxes { self: Global =>
+
+ def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = "") = new ToolBox(frontEnd, options)
+
+ class ToolBox(val frontEnd: FrontEnd, val options: String) extends AbsToolBox {
+ def typeCheck(tree0: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ val tree = substituteFreeTypes(tree0, freeTypes)
+ val currentTyper = typer
+ val wrapper1 = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _)
+ val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _)
+ def wrapper (tree: => Tree) = wrapper1(wrapper2(tree))
+ wrapper(currentTyper.silent(_.typed(tree, analyzer.EXPRmode, pt)) match {
+ case analyzer.SilentResultValue(result) =>
+ result
+ case error @ analyzer.SilentTypeError(_) =>
+ if (!silent) throw new ToolBoxError(this, "reflective typecheck has failed: %s".format(error.err.errMsg))
+ EmptyTree
+ })
+ }
+
+ def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree =
+ // todo. implement this
+ ???
+
+ def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree =
+ // todo. implement this
+ ???
+
+ def resetAllAttrs[T <: Tree](tree: T): T =
+ self.resetAllAttrs(tree)
+
+ def resetLocalAttrs[T <: Tree](tree: T): T =
+ self.resetLocalAttrs(tree)
+
+ def runExpr(tree0: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = {
+ var tree = substituteFreeTypes(tree0, freeTypes)
+ // need to reset the tree, otherwise toolbox will refuse to work with it
+ tree = resetAllAttrs(tree0.duplicate)
+ val imported = importer.importTree(tree)
+ val toolBox = libraryClasspathMirror.mkToolBox(frontEnd.asInstanceOf[libraryClasspathMirror.FrontEnd], options)
+ try toolBox.runExpr(imported)
+ catch {
+ case ex: toolBox.ToolBoxError =>
+ throw new ToolBoxError(this, ex.message, ex.cause)
+ }
+ }
+
+ // [Eugene] how do I make this work without casts?
+ // private lazy val importer = libraryClasspathMirror.mkImporter(self)
+ private lazy val importer = libraryClasspathMirror.mkImporter(self).asInstanceOf[libraryClasspathMirror.Importer { val from: self.type }]
+
+ private lazy val libraryClasspathMirror = {
+ if (self.forMSIL)
+ throw new UnsupportedOperationException("Scala reflection not available on this platform")
+
+ val libraryClassLoader = {
+ val classpath = self.classPath.asURLs
+ var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
+
+ // [Eugene] a heuristic to detect REPL
+ if (self.settings.exposeEmptyPackage.value) {
+ import scala.tools.nsc.interpreter._
+ val virtualDirectory = self.settings.outputDirs.getSingleOutput.get
+ loader = new AbstractFileClassLoader(virtualDirectory, loader) {}
+ }
+
+ loader
+ }
+
+ new scala.reflect.runtime.Mirror(libraryClassLoader)
+ }
+
+ class ToolBoxError(val toolBox: ToolBox, val message: String, val cause: Throwable = null) extends Throwable(message, cause)
+
+ object ToolBoxError extends ToolBoxErrorExtractor {
+ def unapply(error: ToolBoxError): Option[(ToolBox, String)] = Some((error.toolBox, error.message))
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index 678f7b3028..b3ed446563 100755
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
@@ -7,7 +7,7 @@ package scala.tools.nsc
package ast
import symtab._
-import reporters.Reporter
+import reporters._
import util.{Position, NoPosition}
import util.DocStrings._
import scala.reflect.internal.Chars._
@@ -21,8 +21,6 @@ trait DocComments { self: Global =>
var cookedDocComments = Map[Symbol, String]()
- def reporter: Reporter
-
/** The raw doc comment map */
val docComments = mutable.HashMap[Symbol, DocComment]()
@@ -229,31 +227,36 @@ trait DocComments { self: Global =>
* 1. It takes longer to run compared to merge
* 2. The inheritdoc annotation should not be used very often, as building the comment from pieces severely
* impacts performance
+ *
+ * @param parent The source (or parent) comment
+ * @param child The child (overriding member or usecase) comment
+ * @param sym The child symbol
+ * @return The child comment with the inheritdoc sections expanded
*/
- def expandInheritdoc(src: String, dst: String, sym: Symbol): String =
- if (dst.indexOf("@inheritdoc") == -1)
- dst
+ def expandInheritdoc(parent: String, child: String, sym: Symbol): String =
+ if (child.indexOf("@inheritdoc") == -1)
+ child
else {
- val srcSections = tagIndex(src)
- val dstSections = tagIndex(dst)
- val srcTagMap = sectionTagMap(src, srcSections)
- val srcNamedParams = Map() +
- ("@param" -> paramDocs(src, "@param", srcSections)) +
- ("@tparam" -> paramDocs(src, "@tparam", srcSections)) +
- ("@throws" -> paramDocs(src, "@throws", srcSections))
+ val parentSections = tagIndex(parent)
+ val childSections = tagIndex(child)
+ val parentTagMap = sectionTagMap(parent, parentSections)
+ val parentNamedParams = Map() +
+ ("@param" -> paramDocs(parent, "@param", parentSections)) +
+ ("@tparam" -> paramDocs(parent, "@tparam", parentSections)) +
+ ("@throws" -> paramDocs(parent, "@throws", parentSections))
val out = new StringBuilder
- def replaceInheritdoc(src: String, dst: String) =
- if (dst.indexOf("@inheritdoc") == -1)
- dst
+ def replaceInheritdoc(childSection: String, parentSection: => String) =
+ if (childSection.indexOf("@inheritdoc") == -1)
+ childSection
else
- dst.replaceAllLiterally("@inheritdoc", src)
+ childSection.replaceAllLiterally("@inheritdoc", parentSection)
- def getSourceSection(section: (Int, Int)): String = {
+ def getParentSection(section: (Int, Int)): String = {
- def getSectionHeader = extractSectionTag(dst, section) match {
- case param@("@param"|"@tparam"|"@throws") => param + " " + extractSectionParam(dst, section)
+ def getSectionHeader = extractSectionTag(child, section) match {
+ case param@("@param"|"@tparam"|"@throws") => param + " " + extractSectionParam(child, section)
case other => other
}
@@ -261,17 +264,19 @@ trait DocComments { self: Global =>
paramMap.get(param) match {
case Some(section) =>
// Cleanup the section tag and parameter
- val sectionTextBounds = extractSectionText(src, section)
- cleanupSectionText(src.substring(sectionTextBounds._1, sectionTextBounds._2))
+ val sectionTextBounds = extractSectionText(parent, section)
+ cleanupSectionText(parent.substring(sectionTextBounds._1, sectionTextBounds._2))
case None =>
reporter.info(sym.pos, "The \"" + getSectionHeader + "\" annotation of the " + sym +
" comment contains @inheritdoc, but the corresponding section in the parent is not defined.", true)
"<invalid inheritdoc annotation>"
}
- dst.substring(section._1, section._1 + 7) match {
- case param@("@param "|"@tparam"|"@throws") => sectionString(extractSectionParam(dst, section), srcNamedParams(param.trim))
- case _ => sectionString(extractSectionTag(dst, section), srcTagMap)
+ child.substring(section._1, section._1 + 7) match {
+ case param@("@param "|"@tparam"|"@throws") =>
+ sectionString(extractSectionParam(child, section), parentNamedParams(param.trim))
+ case _ =>
+ sectionString(extractSectionTag(child, section), parentTagMap)
}
}
@@ -283,11 +288,11 @@ trait DocComments { self: Global =>
// Append main comment
out.append("/**")
- out.append(replaceInheritdoc(mainComment(src, srcSections), mainComment(dst, dstSections)))
+ out.append(replaceInheritdoc(mainComment(child, childSections), mainComment(parent, parentSections)))
// Append sections
- for (section <- dstSections)
- out.append(replaceInheritdoc(getSourceSection(section), dst.substring(section._1, section._2)))
+ for (section <- childSections)
+ out.append(replaceInheritdoc(child.substring(section._1, section._2), getParentSection(section)))
out.append("*/")
out.toString
@@ -360,7 +365,7 @@ trait DocComments { self: Global =>
case vname =>
lookupVariable(vname, site) match {
case Some(replacement) => replaceWith(replacement)
- case None => reporter.warning(sym.pos, "Variable " + vname + " undefined in comment for " + sym)
+ case None => reporter.warning(sym.pos, "Variable " + vname + " undefined in comment for " + sym + " in " + site)
}
}
}
@@ -488,8 +493,7 @@ trait DocComments { self: Global =>
val tpe = getType(repl.trim)
if (tpe != NoType) tpe
else {
- val alias1 = alias.cloneSymbol(definitions.RootClass)
- alias1.name = newTypeName(repl)
+ val alias1 = alias.cloneSymbol(definitions.RootClass, alias.rawflags, newTypeName(repl))
typeRef(NoPrefix, alias1, Nil)
}
case None =>
@@ -516,10 +520,9 @@ trait DocComments { self: Global =>
}
for (defn <- defined) yield {
- val useCase = defn.cloneSymbol
- useCase.owner = sym.owner
- useCase.flags = sym.flags
- useCase.setFlag(Flags.SYNTHETIC).setInfo(substAliases(defn.info).asSeenFrom(site.thisType, sym.owner))
+ defn.cloneSymbol(sym.owner, sym.flags | Flags.SYNTHETIC) modifyInfo (info =>
+ substAliases(info).asSeenFrom(site.thisType, sym.owner)
+ )
}
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/FreeVars.scala b/src/compiler/scala/tools/nsc/ast/FreeVars.scala
new file mode 100644
index 0000000000..a1983d1834
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ast/FreeVars.scala
@@ -0,0 +1,26 @@
+package scala.tools.nsc
+package ast
+
+trait FreeVars extends reflect.internal.FreeVars { self: Global =>
+
+ import self._
+ import definitions._
+ import treeInfo._
+
+ def logFreeVars(position: Position, reified: Tree): Unit = {
+ if (settings.logFreeTerms.value || settings.logFreeTypes.value) {
+ reified match {
+ case Reified(_, symbolTable, _) =>
+ // logging free vars only when they are untyped prevents avalanches of duplicate messages
+ symbolTable foreach {
+ case FreeTermDef(_, _, binding, _, origin) if settings.logFreeTerms.value && binding.tpe == null =>
+ reporter.echo(position, "free term: %s %s".format(showRaw(binding), origin))
+ case FreeTypeDef(_, _, binding, _, origin) if settings.logFreeTypes.value && binding.tpe == null =>
+ reporter.echo(position, "free type: %s %s".format(showRaw(binding), origin))
+ case _ =>
+ // do nothing
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
index acbdcd501f..5d849b9622 100644
--- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -8,6 +8,7 @@ package ast
import compat.Platform.EOL
import symtab.Flags._
+import language.postfixOps
/** The object `nodePrinter` converts the internal tree
* representation to a string.
@@ -27,24 +28,24 @@ abstract class NodePrinters {
def nodeToString: Tree => String =
if (sys.props contains "scala.colors") nodeToColorizedString
else nodeToRegularString
-
+
object nodeToRegularString extends DefaultPrintAST with (Tree => String) {
def apply(tree: Tree) = stringify(tree)
}
-
+
object nodeToColorizedString extends ColorPrintAST with (Tree => String) {
def apply(tree: Tree) = stringify(tree)
}
trait ColorPrintAST extends DefaultPrintAST {
import scala.tools.util.color._
-
+
def keywordColor = Cyan
def typeColor = Yellow
def termColor = Blue
def flagColor = Red
def literalColor = Green
-
+
override def showFlags(tree: MemberDef) =
super.showFlags(tree) in flagColor.bright
@@ -62,10 +63,14 @@ abstract class NodePrinters {
}
trait DefaultPrintAST extends PrintAST {
+ val printPos = settings.Xprintpos.value || settings.Yposdebug.value
+
+ def showNameAndPos(tree: NameTree) = showPosition(tree) + showName(tree.name)
def showDefTreeName(tree: DefTree) = showName(tree.name)
+ def showPosition(tree: Tree) = if (printPos) tree.pos.show else ""
def showFlags(tree: MemberDef) = flagsToString(tree.symbol.flags | tree.mods.flags)
- def showLiteral(lit: Literal) = lit.value.escapedStringValue
- def showTypeTree(tt: TypeTree) = "<tpt>" + emptyOrComment(showType(tt))
+ def showLiteral(lit: Literal) = showPosition(lit) + lit.value.escapedStringValue
+ def showTypeTree(tt: TypeTree) = showPosition(tt) + "<tpt>" + emptyOrComment(showType(tt))
def showName(name: Name) = name match {
case nme.EMPTY | tpnme.EMPTY => "<empty>"
case name => "\"" + name + "\""
@@ -81,7 +86,7 @@ abstract class NodePrinters {
if (tpe == null || tpe == NoType) ""
else "tree.tpe=" + tpe
}
-
+
def showAttributes(tree: Tree): String = {
if (infolevel == InfoLevel.Quiet) ""
else {
@@ -90,23 +95,27 @@ abstract class NodePrinters {
}
}
}
-
+
trait PrintAST {
private val buf = new StringBuilder
private var level = 0
def showName(name: Name): String
+ def showPosition(tree: Tree): String
+ def showNameAndPos(tree: NameTree): String
def showDefTreeName(defTree: DefTree): String
def showFlags(tree: MemberDef): String
def showLiteral(lit: Literal): String
def showTypeTree(tt: TypeTree): String
def showAttributes(tree: Tree): String // symbol and type
-
- def showRefTreeName(tree: Tree): String = tree match {
- case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name)
- case Select(qual, name) => showRefTreeName(qual) + "." + showName(name)
- case Ident(name) => showName(name)
- case _ => "" + tree
+
+ def showRefTreeName(tree: Tree): String = {
+ tree match {
+ case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name)
+ case Select(qual, name) => showRefTreeName(qual) + "." + showName(name)
+ case id @ Ident(name) => showNameAndPos(id)
+ case _ => "" + tree
+ }
}
def showRefTree(tree: RefTree): String = {
def prefix0 = showRefTreeName(tree.qualifier)
@@ -115,15 +124,21 @@ abstract class NodePrinters {
case Select(_, _) => prefix0 + "."
case _ => ""
})
- prefix + showName(tree.name) + emptyOrComment(showAttributes(tree))
+ prefix + showNameAndPos(tree) + emptyOrComment(showAttributes(tree))
}
def emptyOrComment(s: String) = if (s == "") "" else " // " + s
def stringify(tree: Tree): String = {
buf.clear()
- level = 0
- traverse(tree)
+ if (settings.XshowtreesStringified.value) buf.append(tree.toString + EOL)
+ if (settings.XshowtreesCompact.value) {
+ // todo. colors for compact representation
+ buf.append(showRaw(tree))
+ } else {
+ level = 0
+ traverse(tree)
+ }
buf.toString
}
def traverseAny(x: Any) {
@@ -134,7 +149,7 @@ abstract class NodePrinters {
}
}
def println(s: String) = printLine(s, "")
-
+
def printLine(value: String, comment: String) {
buf append " " * level
buf append value
@@ -183,9 +198,10 @@ abstract class NodePrinters {
traverseList("Nil", "argument")(args)
}
}
-
+
+ def treePrefix(tree: Tree) = showPosition(tree) + tree.printingPrefix
def printMultiline(tree: Tree)(body: => Unit) {
- printMultiline(tree.printingPrefix, showAttributes(tree))(body)
+ printMultiline(treePrefix(tree), showAttributes(tree))(body)
}
def printMultiline(prefix: String, comment: String)(body: => Unit) {
printLine(prefix + "(", comment)
@@ -211,10 +227,12 @@ abstract class NodePrinters {
}
def printSingle(tree: Tree, name: Name) {
- println(tree.printingPrefix + "(" + showName(name) + ")" + showAttributes(tree))
+ println(treePrefix(tree) + "(" + showName(name) + ")" + showAttributes(tree))
}
def traverse(tree: Tree) {
+ showPosition(tree)
+
tree match {
case AppliedTypeTree(tpt, args) => applyCommon(tree, tpt, args)
case ApplyDynamic(fun, args) => applyCommon(tree, fun, args)
@@ -223,6 +241,19 @@ abstract class NodePrinters {
case Throw(Ident(name)) =>
printSingle(tree, name)
+ case b @ Bind(name, body) =>
+ printMultiline(tree) {
+ println(showDefTreeName(b))
+ traverse(body)
+ }
+
+ case ld @ LabelDef(name, params, rhs) =>
+ printMultiline(tree) {
+ showNameAndPos(ld)
+ traverseList("()", "params")(params)
+ traverse(rhs)
+ }
+
case Function(vparams, body) =>
printMultiline(tree) {
traverseList("()", "parameter")(vparams)
@@ -299,10 +330,10 @@ abstract class NodePrinters {
}
case Template(parents, self, body) =>
printMultiline(tree) {
- val ps0 = parents map { p =>
+ val ps0 = parents map { p =>
if (p.tpe eq null) p match {
case x: RefTree => showRefTree(x)
- case x => "" + x
+ case x => showPosition(x) + x
}
else showName(newTypeName(p.tpe.typeSymbol.fullName))
}
@@ -339,14 +370,14 @@ abstract class NodePrinters {
traverseList("[]", "type parameter")(tparams)
traverse(rhs)
}
-
+
case PackageDef(pid, stats) =>
printMultiline("PackageDef", "")(pid :: stats foreach traverse)
case _ =>
tree match {
case t: RefTree => println(showRefTree(t))
- case t if t.productArity == 0 => println(tree.printingPrefix)
+ case t if t.productArity == 0 => println(treePrefix(t))
case t => printMultiline(tree)(tree.productIterator foreach traverseAny)
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala
new file mode 100644
index 0000000000..83a67cfbe3
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ast/Positions.scala
@@ -0,0 +1,44 @@
+package scala.tools.nsc
+package ast
+
+import scala.tools.nsc.util.{ SourceFile, Position, OffsetPosition, NoPosition }
+
+trait Positions extends scala.reflect.internal.Positions {
+ self: Global =>
+
+ def rangePos(source: SourceFile, start: Int, point: Int, end: Int) =
+ new OffsetPosition(source, point)
+
+ def validatePositions(tree: Tree) {}
+
+ // [Eugene] disabling this for now. imo it doesn't justify pollution of the public API
+ // override def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = {
+ // if (tree.pos != NoPosition && tree.pos != annot.pos) debugwarn("Overwriting annotation "+ tree.annotation +" of tree "+ tree +" with annotation "+ annot)
+ // // if ((tree.annotation.isInstanceOf[scala.tools.nsc.util.Position] || !annot.isInstanceOf[scala.tools.nsc.util.Position]) && tree.isInstanceOf[Block])
+ // // println("Updating block from "+ tree.annotation +" to "+ annot)
+ // }
+
+ class ValidatingPosAssigner extends PosAssigner {
+ var pos: Position = _
+ override def traverse(t: Tree) {
+ if (t eq EmptyTree) ()
+ else if (t.pos == NoPosition) super.traverse(t setPos pos)
+ else if (globalPhase.id <= currentRun.picklerPhase.id) {
+ // When we prune due to encountering a position, traverse the
+ // pruned children so we can warn about those lacking positions.
+ t.children foreach { c =>
+ if ((c eq EmptyTree) || (c eq emptyValDef)) ()
+ else if (c.pos == NoPosition) {
+ reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase)
+ inform("parent: " + treeSymStatus(t))
+ inform(" child: " + treeSymStatus(c) + "\n")
+ }
+ }
+ }
+ }
+ }
+
+ override protected[this] lazy val posAssigner: PosAssigner =
+ if (settings.Yrangepos.value && settings.debug.value || settings.Yposdebug.value) new ValidatingPosAssigner
+ else new DefaultPosAssigner
+}
diff --git a/src/compiler/scala/tools/nsc/ast/Reifiers.scala b/src/compiler/scala/tools/nsc/ast/Reifiers.scala
deleted file mode 100644
index 7ece8bbd31..0000000000
--- a/src/compiler/scala/tools/nsc/ast/Reifiers.scala
+++ /dev/null
@@ -1,761 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Gilles Dubochet
- */
-
-package scala.tools.nsc
-package ast
-
-import symtab._
-import Flags._
-import scala.reflect.api.Modifier._
-import scala.collection.{ mutable, immutable }
-import scala.collection.mutable.ListBuffer
-import scala.tools.nsc.util.FreshNameCreator
-import scala.runtime.ScalaRunTime.{ isAnyVal, isTuple }
-
-/** Given a tree or type, generate a tree that when executed at runtime produces the original tree or type.
- * See more info in the comments to `reify' in scala.reflect.macro.Context.
- *
- * @author Martin Odersky
- * @version 2.10
- */
-trait Reifiers { self: Global =>
-
- def reify(tree: Tree): Tree = {
- class Reifier {
- import definitions._
- import Reifier._
-
- final val scalaPrefix = "scala."
- final val localPrefix = "$local"
- final val memoizerName = "$memo"
-
- val reifyDebug = settings.Yreifydebug.value
-
- private val reifiableSyms = mutable.ArrayBuffer[Symbol]() // the symbols that are reified with the tree
- private val symIndex = mutable.HashMap[Symbol, Int]() // the index of a reifiable symbol in `reifiableSyms`
- private var boundSyms = Set[Symbol]() // set of all symbols that are bound in tree to be reified
-
- private def definedInLiftedCode(tpe: Type) =
- tpe exists (tp => boundSyms contains tp.typeSymbol)
-
- private def definedInLiftedCode(sym: Symbol) =
- boundSyms contains sym
-
- /**
- * Generate tree of the form
- *
- * { val $mr = scala.reflect.runtime.Mirror
- * $local1 = new TypeSymbol(owner1, NoPosition, name1)
- * ...
- * $localN = new TermSymbol(ownerN, NoPositiion, nameN)
- * $local1.setInfo(tpe1)
- * ...
- * $localN.setInfo(tpeN)
- * $localN.setAnnotations(annotsN)
- * rtree
- * }
- *
- * where
- *
- * - `$localI` are free type symbols in the environment, as well as local symbols
- * of refinement types.
- * - `tpeI` are the info's of `symI`
- * - `rtree` is code that generates `data` at runtime, maintaining all attributes.
- * - `data` is typically a tree or a type.
- */
- def reifyTopLevel(data: Any): Tree = {
- val rtree = reify(data)
- Block(mirrorAlias :: reifySymbolTableSetup, rtree)
- }
-
- private def isLocatable(sym: Symbol) =
- sym.isPackageClass || sym.owner.isClass || sym.isTypeParameter && sym.paramPos >= 0
-
- private def registerReifiableSymbol(sym: Symbol): Unit =
- if (!(symIndex contains sym)) {
- sym.owner.ownersIterator find (x => !isLocatable(x)) foreach registerReifiableSymbol
- symIndex(sym) = reifiableSyms.length
- reifiableSyms += sym
- }
-
- // helper methods
-
- private def localName(sym: Symbol): TermName =
- newTermName(localPrefix + symIndex(sym))
-
- private def call(fname: String, args: Tree*): Tree =
- Apply(termPath(fname), args.toList)
-
- private def mirrorSelect(name: String): Tree =
- termPath(nme.MIRROR_PREFIX + name)
-
- private def mirrorCall(name: TermName, args: Tree*): Tree =
- call("" + (nme.MIRROR_PREFIX append name), args: _*)
-
- private def mirrorCall(name: String, args: Tree*): Tree =
- call(nme.MIRROR_PREFIX + name, args: _*)
-
- private def mirrorFactoryCall(value: Product, args: Tree*): Tree =
- mirrorFactoryCall(value.productPrefix, args: _*)
-
- private def mirrorFactoryCall(prefix: String, args: Tree*): Tree =
- mirrorCall(prefix, args: _*)
-
- private def scalaFactoryCall(name: String, args: Tree*): Tree =
- call(scalaPrefix + name + ".apply", args: _*)
-
- private def mkList(args: List[Tree]): Tree =
- scalaFactoryCall("collection.immutable.List", args: _*)
-
- private def reifyModifiers(m: Modifiers) =
- mirrorCall("modifiersFromInternalFlags", reify(m.flags), reify(m.privateWithin), reify(m.annotations))
-
- private def reifyAggregate(name: String, args: Any*) =
- scalaFactoryCall(name, (args map reify).toList: _*)
-
- /**
- * Reify a list
- */
- private def reifyList(xs: List[Any]): Tree =
- mkList(xs map reify)
-
- /**
- * Reify an array
- */
- private def reifyArray(xs: Array[_]): Tree =
- // @xeno.by: doesn't work for Array(LiteralAnnotArg(...))
- // because we cannot generate manifests for path-dependent types
- scalaFactoryCall(nme.Array, xs map reify: _*)
-
- /** Reify a name */
- private def reifyName(name: Name) =
- mirrorCall(if (name.isTypeName) "newTypeName" else "newTermName", Literal(Constant(name.toString)))
-
- private def isFree(sym: Symbol) =
- !(symIndex contains sym)
-
- /**
- * Reify a reference to a symbol
- */
- private def reifySymRef(sym: Symbol): Tree = {
- symIndex get sym match {
- case Some(idx) =>
- Ident(localName(sym))
- case None =>
- if (sym == NoSymbol)
- mirrorSelect("NoSymbol")
- else if (sym == RootPackage)
- mirrorSelect("definitions.RootPackage")
- else if (sym == RootClass)
- mirrorSelect("definitions.RootClass")
- else if (sym == EmptyPackage)
- mirrorSelect("definitions.EmptyPackage")
- else if (sym.isModuleClass)
- Select(reifySymRef(sym.sourceModule), "moduleClass")
- else if (sym.isStatic && sym.isClass)
- mirrorCall("staticClass", reify(sym.fullName))
- else if (sym.isStatic && sym.isModule)
- mirrorCall("staticModule", reify(sym.fullName))
- else if (isLocatable(sym))
- if (sym.isTypeParameter)
- mirrorCall("selectParam", reify(sym.owner), reify(sym.paramPos))
- else {
- if (reifyDebug) println("locatable: " + sym + " " + sym.isPackageClass + " " + sym.owner + " " + sym.isTypeParameter)
- val rowner = reify(sym.owner)
- val rname = reify(sym.name.toString)
- if (sym.isType)
- mirrorCall("selectType", rowner, rname)
- else if (sym.isMethod && sym.owner.isClass && sym.owner.info.decl(sym.name).isOverloaded) {
- val index = sym.owner.info.decl(sym.name).alternatives indexOf sym
- assert(index >= 0, sym)
- mirrorCall("selectOverloadedMethod", rowner, rname, reify(index))
- } else
- mirrorCall("selectTerm", rowner, rname)
- }
- else {
- if (sym.isTerm) {
- if (reifyDebug) println("Free: " + sym)
- val symtpe = lambdaLift.boxIfCaptured(sym, sym.tpe, erasedTypes = false)
- def markIfCaptured(arg: Ident): Tree =
- if (sym.isCapturedVariable) referenceCapturedVariable(arg) else arg
- mirrorCall("newFreeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym)))
- } else {
- if (reifyDebug) println("Late local: " + sym)
- registerReifiableSymbol(sym)
- reifySymRef(sym)
- }
- }
- }
- }
-
- /**
- * reify the creation of a symbol
- */
- private def reifySymbolDef(sym: Symbol): Tree = {
- if (reifyDebug) println("reify sym def " + sym)
-
- ValDef(NoMods, localName(sym), TypeTree(),
- Apply(
- Select(reify(sym.owner), "newNestedSymbol"),
- List(reify(sym.name), reify(sym.pos), Literal(Constant(sym.flags)))
- )
- )
- }
-
- /**
- * Generate code to add type and annotation info to a reified symbol
- */
- private def fillInSymbol(sym: Symbol): Tree = {
- val rset = Apply(Select(reifySymRef(sym), nme.setTypeSignature), List(reifyType(sym.info)))
- if (sym.annotations.isEmpty) rset
- else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations)))
- }
-
- /** Reify a scope */
- private def reifyScope(scope: Scope): Tree = {
- scope foreach registerReifiableSymbol
- mirrorCall(nme.newScopeWith, scope.toList map reifySymRef: _*)
- }
-
- /** Reify a list of symbols that need to be created */
- private def reifySymbols(syms: List[Symbol]): Tree = {
- syms foreach registerReifiableSymbol
- mkList(syms map reifySymRef)
- }
-
- /** Reify a type that defines some symbols */
- private def reifyTypeBinder(value: Product, bound: List[Symbol], underlying: Type): Tree =
- mirrorFactoryCall(value, reifySymbols(bound), reify(underlying))
-
- /** Reify a type */
- private def reifyType(tpe0: Type): Tree = {
- val tpe = tpe0.normalize
-
- if (tpe.isErroneous)
- CannotReifyErroneousType(tpe)
- if (definedInLiftedCode(tpe))
- CannotReifyTypeInvolvingBoundType(tpe)
-
- val tsym = tpe.typeSymbol
- if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic)
- Select(reifySymRef(tpe.typeSymbol), nme.asTypeConstructor)
- else tpe match {
- case t @ NoType =>
- reifyMirrorObject(t)
- case t @ NoPrefix =>
- reifyMirrorObject(t)
- case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic =>
- mirrorCall(nme.thisModuleType, reify(clazz.fullName))
- case t @ RefinedType(parents, decls) =>
- registerReifiableSymbol(tpe.typeSymbol)
- mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol))
- case t @ ClassInfoType(parents, decls, clazz) =>
- registerReifiableSymbol(clazz)
- mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol))
- case t @ ExistentialType(tparams, underlying) =>
- reifyTypeBinder(t, tparams, underlying)
- case t @ PolyType(tparams, underlying) =>
- reifyTypeBinder(t, tparams, underlying)
- case t @ MethodType(params, restpe) =>
- reifyTypeBinder(t, params, restpe)
- case t @ AnnotatedType(anns, underlying, selfsym) =>
- val saved1 = reifySymbols
- val saved2 = reifyTypes
-
- try {
- // one more quirk of reifying annotations
- //
- // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs
- // that's because a lot of logic expects post-typer trees to have non-null tpes
- //
- // Q: reified trees are pre-typer, so there's shouldn't be a problem.
- // reflective typechecker will fill in missing symbols and types, right?
- // A: actually, no. annotation ASTs live inside AnnotatedTypes,
- // and insides of the types is the place where typechecker doesn't look.
- reifySymbols = true
- reifyTypes = true
- if (reifyDebug) println("reify AnnotatedType: " + tpe)
- reifyProductUnsafe(tpe)
- } finally {
- reifySymbols = saved1
- reifyTypes = saved2
- }
- case _ =>
- reifyProductUnsafe(tpe)
- }
- }
-
- var reifySymbols = false
- var reifyTypes = false
-
- /** Preprocess a tree before reification */
- private def trimTree(tree: Tree): Tree = {
- def trimSyntheticCaseClassMembers(deff: Tree, stats: List[Tree]) = {
- var stats1 = stats filterNot (stat => stat.isDef && {
- if (stat.symbol.isCaseAccessorMethod && reifyDebug) println("discarding case accessor method: " + stat)
- stat.symbol.isCaseAccessorMethod
- })
- stats1 = stats1 filterNot (memberDef => memberDef.isDef && {
- val isSynthetic = memberDef.symbol.isSynthetic
- // @xeno.by: this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass)
- // that's why I replace the check with an assumption that all synthetic members are, in fact, generated of case classes
-// val isCaseMember = deff.symbol.isCaseClass || deff.symbol.companionClass.isCaseClass
- val isCaseMember = true
- if (isSynthetic && isCaseMember && reifyDebug) println("discarding case class synthetic def: " + memberDef)
- isSynthetic && isCaseMember
- })
- stats1 = stats1 map {
- case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isCaseAccessor =>
- if (reifyDebug) println("resetting visibility of case accessor field: " + valdef)
- val Modifiers(flags, privateWithin, annotations) = mods
- val flags1 = flags & ~Flags.LOCAL & ~Flags.PRIVATE
- val mods1 = Modifiers(flags1, privateWithin, annotations)
- ValDef(mods1, name, tpt, rhs).copyAttrs(valdef)
- case stat =>
- stat
- }
- stats1
- }
-
- def trimSyntheticCaseClassCompanions(stats: List[Tree]) =
- stats diff (stats collect { case moddef: ModuleDef => moddef } filter (moddef => {
- val isSynthetic = moddef.symbol.isSynthetic
- // @xeno.by: this doesn't work for local classes, e.g. for ones that are top-level to a quasiquote (see comments to companionClass)
- // that's why I replace the check with an assumption that all synthetic modules are, in fact, companions of case classes
-// val isCaseCompanion = moddef.symbol.companionClass.isCaseClass
- val isCaseCompanion = true
- // @xeno.by: we also have to do this ugly hack for the very same reason described above
- // normally this sort of stuff is performed in reifyTree, which binds related symbols, however, local companions will be out of its reach
- if (reifyDebug) println("boundSym: "+ moddef.symbol)
- boundSyms += moddef.symbol
- if (isSynthetic && isCaseCompanion && reifyDebug) println("discarding synthetic case class companion: " + moddef)
- isSynthetic && isCaseCompanion
- }))
-
- tree match {
- case tree if tree.isErroneous =>
- tree
- case ta @ TypeApply(hk, ts) =>
- def isErased(tt: TypeTree) = tt.tpe != null && definedInLiftedCode(tt.tpe) && tt.original == null
- val discard = ts collect { case tt: TypeTree => tt } exists isErased
- if (reifyDebug && discard) println("discarding TypeApply: " + tree)
- if (discard) hk else ta
- case classDef @ ClassDef(mods, name, params, impl) =>
- val Template(parents, self, body) = impl
- val body1 = trimSyntheticCaseClassMembers(classDef, body)
- var impl1 = Template(parents, self, body1).copyAttrs(impl)
- ClassDef(mods, name, params, impl1).copyAttrs(classDef)
- case moduledef @ ModuleDef(mods, name, impl) =>
- val Template(parents, self, body) = impl
- val body1 = trimSyntheticCaseClassMembers(moduledef, body)
- var impl1 = Template(parents, self, body1).copyAttrs(impl)
- ModuleDef(mods, name, impl1).copyAttrs(moduledef)
- case template @ Template(parents, self, body) =>
- val body1 = trimSyntheticCaseClassCompanions(body)
- Template(parents, self, body1).copyAttrs(template)
- case block @ Block(stats, expr) =>
- val stats1 = trimSyntheticCaseClassCompanions(stats)
- Block(stats1, expr).copyAttrs(block)
- case valdef @ ValDef(mods, name, tpt, rhs) if valdef.symbol.isLazy =>
- if (reifyDebug) println("dropping $lzy in lazy val's name: " + tree)
- val name1 = if (name endsWith nme.LAZY_LOCAL) name dropRight nme.LAZY_LOCAL.length else name
- ValDef(mods, name1, tpt, rhs).copyAttrs(valdef)
- case unapply @ UnApply(fun, args) =>
- def extractExtractor(tree: Tree): Tree = {
- val Apply(fun, args) = tree
- args match {
- case List(Ident(special)) if special == nme.SELECTOR_DUMMY =>
- val Select(extractor, flavor) = fun
- assert(flavor == nme.unapply || flavor == nme.unapplySeq)
- extractor
- case _ =>
- extractExtractor(fun)
- }
- }
-
- if (reifyDebug) println("unapplying unapply: " + tree)
- val fun1 = extractExtractor(fun)
- Apply(fun1, args).copyAttrs(unapply)
- case _ =>
- tree
- }
- }
-
- /** Reify a tree */
- private def reifyTree(tree0: Tree): Tree = {
- val tree = trimTree(tree0)
-
- var rtree = tree match {
- case tree if tree.isErroneous =>
- CannotReifyErroneousTree(tree)
- case self.EmptyTree =>
- reifyMirrorObject(EmptyTree)
- case self.emptyValDef =>
- mirrorSelect(nme.emptyValDef)
- case This(_) if tree.symbol != NoSymbol && !(boundSyms contains tree.symbol) =>
- reifyFree(tree)
- case Ident(_) if tree.symbol != NoSymbol && !(boundSyms contains tree.symbol) =>
- if (tree.symbol.isVariable && tree.symbol.owner.isTerm) {
- if (reifyDebug) println("captured variable: " + tree.symbol)
- captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reifyTree here.
- mirrorCall("Select", reifyFree(tree), reifyName(nme.elem))
- } else reifyFree(tree)
- case tt: TypeTree if (tt.tpe != null) =>
- reifyTypeTree(tt)
- case Literal(constant @ Constant(tpe: Type)) if boundSyms exists (tpe contains _) =>
- CannotReifyClassOfBoundType(tree, tpe)
- case Literal(constant @ Constant(sym: Symbol)) if boundSyms contains sym =>
- CannotReifyClassOfBoundEnum(tree, constant.tpe)
- case tree if tree.isDef =>
- if (reifyDebug) println("boundSym: %s of type %s".format(tree.symbol, (tree.productIterator.toList collect { case tt: TypeTree => tt } headOption).getOrElse(TypeTree(tree.tpe))))
- boundSyms += tree.symbol
-
- bindRelatedSymbol(tree.symbol.sourceModule, "sourceModule")
- bindRelatedSymbol(tree.symbol.moduleClass, "moduleClass")
- bindRelatedSymbol(tree.symbol.companionClass, "companionClass")
- bindRelatedSymbol(tree.symbol.companionModule, "companionModule")
- Some(tree.symbol) collect { case termSymbol: TermSymbol => bindRelatedSymbol(termSymbol.referenced, "referenced") }
- def bindRelatedSymbol(related: Symbol, name: String): Unit =
- if (related != null && related != NoSymbol) {
- if (reifyDebug) println("boundSym (" + name + "): " + related)
- boundSyms += related
- }
-
- val prefix = tree.productPrefix
- val elements = (tree.productIterator map {
- // annotations exist in two flavors:
- // 1) pre-typer ones that populate: a) Modifiers, b) Annotated nodes (irrelevant in this context)
- // 2) post-typer ones that dwell inside: a) sym.annotations, b) AnnotatedTypes (irrelevant in this context)
- //
- // here we process Modifiers that are involved in deftrees
- // AnnotatedTypes get reified elsewhere (currently, in ``reifyTypeTree'')
- case Modifiers(flags, privateWithin, annotations) =>
- assert(annotations.isEmpty) // should've been eliminated by the typer
- val postTyper = tree.symbol.annotations filter (_.original != EmptyTree)
- if (reifyDebug && !postTyper.isEmpty) println("reify symbol annotations for %s: %s".format(tree.symbol, tree.symbol.annotations))
- val preTyper = postTyper map toPreTyperAnnotation
- Modifiers(flags, privateWithin, preTyper)
- case x =>
- x
- }).toList
- reifyProduct(prefix, elements)
- case _ =>
- reifyProduct(tree)
- }
-
- // usually we don't reify symbols/types, because they can be re-inferred during subsequent reflective compilation
- // however, reification of AnnotatedTypes is special. see ``reifyType'' to find out why.
- if (reifySymbols && tree.hasSymbol) {
- if (reifyDebug) println("reifying symbol %s for tree %s".format(tree.symbol, tree))
- rtree = Apply(Select(rtree, nme.setSymbol), List(reifySymRef(tree.symbol)))
- }
- if (reifyTypes && tree.tpe != null) {
- if (reifyDebug) println("reifying type %s for tree %s".format(tree.tpe, tree))
- rtree = Apply(Select(rtree, nme.setType), List(reifyType(tree.tpe)))
- }
-
- rtree
- }
-
- /** Reify pre-typer representation of a type.
- *
- * NB: This is the trickiest part of reification!
- *
- * In most cases, we're perfectly fine to reify a Type itself (see ``reifyType'').
- * However if the type involves a symbol declared inside the quasiquote (i.e. registered in ``boundSyms''),
- * then we cannot reify it, or otherwise subsequent reflective compilation will fail.
- *
- * Why will it fail? Because reified deftrees (e.g. ClassDef(...)) will generate fresh symbols during that compilation,
- * so naively reified symbols will become out of sync, which brings really funny compilation errors and/or crashes, e.g.:
- * https://issues.scala-lang.org/browse/SI-5230
- *
- * To deal with this unpleasant fact, we need to fall back from types to equivalent trees (after all, parser trees don't contain any types, just trees, so it should be possible).
- * Luckily, these original trees get preserved for us in the ``original'' field when Trees get transformed into TypeTrees.
- * And if an original of a type tree is empty, we can safely assume that this type is non-essential (e.g. was inferred/generated by the compiler).
- * In that case the type can be omitted (e.g. reified as an empty TypeTree), since it will be inferred again later on.
- *
- * An important property of the original is that it isn't just a pre-typer tree.
- * It's actually kind of a post-typer tree with symbols assigned to its Idents (e.g. Ident("List") will contain a symbol that points to immutable.this.List).
- * This is very important, since subsequent reflective compilation won't have to resolve these symbols.
- * In general case, such resolution cannot be performed, since reification doesn't preserve lexical context,
- * which means that reflective compilation won't be aware of, say, imports that were provided when the reifee has been compiled.
- *
- * This workaround worked surprisingly well and allowed me to fix several important reification bugs, until the abstraction has leaked.
- * Suddenly I found out that in certain contexts original trees do not contain symbols, but are just parser trees.
- * To the moment I know only one such situation: typedAnnotations does not typecheck the annotation in-place, but rather creates new trees and typechecks them, so the original remains symless.
- * This is laboriously worked around in the code below. I hope this will be the only workaround in this department.
- */
- private def reifyTypeTree(tt: TypeTree): Tree = {
- if (definedInLiftedCode(tt.tpe)) {
- if (reifyDebug) println("reifyTypeTree, defined in lifted code: " + tt.tpe)
- if (tt.original != null) {
- val annotations = tt.tpe filter { _.isInstanceOf[AnnotatedType] } collect { case atp: AnnotatedType => atp.annotations } flatten
- val annmap = annotations map { ann => (ann.original, ann) } toMap
-
- // annotations exist in two flavors:
- // 1) pre-typer ones that populate: a) Modifiers (irrelevant in this context), b) Annotated nodes
- // 2) post-typer ones that dwell inside: a) sym.annotations (irrelevant in this context), b) AnnotatedTypes
- //
- // here we process AnnotatedTypes, since only they can be involved in TypeTrees
- // Modifiers get reified elsewhere (currently, in the "isDef" case of ``reifyTree'')
- //
- // the problem with annotations is that their originals don't preserve any symbols at all
- // read the comment to this method to find out why it's bad
- // that's why we transplant typechecked, i.e. symful, annotations onto original trees
- class AnnotationFixup extends self.Transformer {
- override def transform(tree: Tree) = tree match {
- case Annotated(ann0, args) =>
- assert(annmap contains ann0)
- val ann1 = annmap(ann0)
- val ann = toPreTyperAnnotation(ann1)
- Annotated(ann, transform(args))
- case _ =>
- tree
- }
- }
-
- if (reifyDebug) println("verdict: essential, reify as original")
- val patchedOriginal = new AnnotationFixup().transform(tt.original)
- reifyTree(patchedOriginal)
- } else {
- // type is deemed to be non-essential
- // erase it and hope that subsequent reflective compilation will be able to recreate it again
- if (reifyDebug) println("verdict: non-essential, discard")
- mirrorCall("TypeTree")
- }
- } else {
- var rtt = mirrorCall(nme.TypeTree, reifyType(tt.tpe))
- // @xeno.by: temporarily disabling reification of originals
- // subsequent reflective compilation will try to typecheck them
- // and this means that the reifier has to do additional efforts to ensure that this will succeed
- // additional efforts + no clear benefit = will be implemented later
-// if (tt.original != null) {
-// val setOriginal = Select(rtt, newTermName("setOriginal"))
-// val reifiedOriginal = reify(tt.original)
-// rtt = Apply(setOriginal, List(reifiedOriginal))
-// }
- rtt
- }
- }
-
- /** Reify post-typer representation of an annotation */
- private def reifyAnnotation(ann: AnnotationInfo): Tree =
- // @xeno.by: if you reify originals, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important
- mirrorFactoryCall("AnnotationInfo", reifyType(ann.atp), reifyList(ann.args), reify(ann.assocs))
-
- /** Reify pre-typer representation of an annotation.
- * The trick here is to retain the symbols that have been populated during typechecking of the annotation.
- * If we do not do that, subsequent reflective compilation will fail.
- */
- private def toPreTyperAnnotation(ann: AnnotationInfo): Tree = {
- if (definedInLiftedCode(ann.atp)) {
- // todo. deconstruct reifiable tree from ann.original and ann.args+ann.assocs
- //
- // keep in mind that we can't simply use ann.original, because its args are symless
- // which means that any imported symbol (e.g. List) will crash subsequent reflective compilation
- // hint: if I had enough time, I'd try to extract reifiable annotation type from ann.original
- // and to apply its constructor to ann.args (that are symful, i.e. suitable for reification)
- //
- // also, if we pursue the route of reifying annotations defined in lifted code
- // we should think about how to provide types for all nodes of the return value
- // this will be necessary for reifying AnnotatedTypes, since ASTs inside ATs must all have non-null tpes
- // an alternative would be downgrading ATs to Annotated nodes, but this needs careful thinking
- // for now I just leave this as an implementation restriction
- CannotReifyAnnotationInvolvingBoundType(ann)
- } else {
- val args = if (ann.assocs.isEmpty) {
- ann.args
- } else {
- def toScalaAnnotation(jann: ClassfileAnnotArg): Tree = jann match {
- case LiteralAnnotArg(const) =>
- Literal(const)
- case ArrayAnnotArg(arr) =>
- Apply(Ident(definitions.ArrayModule), arr.toList map toScalaAnnotation)
- case NestedAnnotArg(ann) =>
- toPreTyperAnnotation(ann)
- }
-
- ann.assocs map { case (nme, arg) => AssignOrNamedArg(Ident(nme), toScalaAnnotation(arg)) }
- }
-
- New(ann.atp, args: _*)
- }
- }
-
- /**
- * Reify a free reference. The result will be either a mirror reference
- * to a global value, or else a mirror Literal.
- */
- private def reifyFree(tree: Tree): Tree = tree match {
- case This(_) if tree.symbol.isClass && !tree.symbol.isModuleClass =>
- val sym = tree.symbol
- if (reifyDebug) println("This for %s, reified as freeVar".format(sym))
- if (reifyDebug) println("Free: " + sym)
- val freeVar = mirrorCall("newFreeVar", reify(sym.name.toString), reify(sym.tpe), This(sym))
- mirrorCall(nme.Ident, freeVar)
- case This(_) =>
- if (reifyDebug) println("This for %s, reified as This".format(tree.symbol))
- mirrorCall(nme.This, reifySymRef(tree.symbol))
- case _ =>
- mirrorCall(nme.Ident, reifySymRef(tree.symbol))
- }
-
- // todo: consider whether we should also reify positions
- private def reifyPosition(pos: Position): Tree =
- reifyMirrorObject(NoPosition)
-
- // !!! we must eliminate these casts.
- private def reifyProductUnsafe(x: Any): Tree =
- if (x.isInstanceOf[Product]) reifyProduct(x.asInstanceOf[Product])
- else throw new Exception("%s of type %s cannot be cast to Product".format(x, x.getClass))
- private def reifyProduct(x: Product): Tree =
- reifyProduct(x.productPrefix, x.productIterator.toList)
- private def reifyProduct(prefix: String, elements: List[Any]): Tree = {
- // @xeno.by: reflection would be more robust, but, hey, this is a hot path
- if (prefix.startsWith("Tuple")) reifyAggregate(prefix, elements: _*)
- else mirrorCall(prefix, (elements map reify): _*)
- }
-
- /**
- * Reify a case object defined in Mirror
- */
- private def reifyMirrorObject(name: String): Tree = mirrorSelect(name)
- private def reifyMirrorObject(x: Product): Tree = reifyMirrorObject(x.productPrefix)
-
- private def isReifiableConstant(value: Any) = value match {
- case null => true // seems pretty reifable to me?
- case _: String => true
- case _ => isAnyVal(value)
- }
-
- /** Reify an arbitary value */
- private def reify(value: Any): Tree = value match {
- case tree: Tree => reifyTree(tree)
- case sym: Symbol => reifySymRef(sym)
- case tpe: Type => reifyType(tpe)
- case xs: List[_] => reifyList(xs)
- case xs: Array[_] => reifyArray(xs)
- case scope: Scope => reifyScope(scope)
- case x: Name => reifyName(x)
- case x: Position => reifyPosition(x)
- case x: Modifiers => reifyModifiers(x)
- case x: AnnotationInfo => reifyAnnotation(x)
- case _ =>
- if (isReifiableConstant(value)) Literal(Constant(value))
- else reifyProductUnsafe(value)
- }
-
- /**
- * An (unreified) path that refers to definition with given fully qualified name
- * @param mkName Creator for last portion of name (either TermName or TypeName)
- */
- private def path(fullname: String, mkName: String => Name): Tree = {
- val parts = fullname split "\\."
- val prefixParts = parts.init
- val lastName = mkName(parts.last)
- if (prefixParts.isEmpty) Ident(lastName)
- else {
- val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail)(Select(_, _))
- Select(prefixTree, lastName)
- }
- }
-
- /** An (unreified) path that refers to term definition with given fully qualified name */
- private def termPath(fullname: String): Tree = path(fullname, newTermName)
-
- /** An (unreified) path that refers to type definition with given fully qualified name */
- private def typePath(fullname: String): Tree = path(fullname, newTypeName)
-
- private def mirrorAlias =
- ValDef(NoMods, nme.MIRROR_SHORT, SingletonTypeTree(termPath(fullnme.MirrorPackage)), termPath(fullnme.MirrorPackage))
-
- /**
- * Generate code that generates a symbol table of all symbols registered in `reifiableSyms`
- */
- private def reifySymbolTableSetup: List[Tree] = {
- val symDefs, fillIns = new mutable.ArrayBuffer[Tree]
- var i = 0
- while (i < reifiableSyms.length) {
- // fillInSymbol might create new reifiableSyms, that's why this is done iteratively
- symDefs += reifySymbolDef(reifiableSyms(i))
- fillIns += fillInSymbol(reifiableSyms(i))
- i += 1
- }
-
- symDefs.toList ++ fillIns.toList
- }
- } // end of Reifier
-
- object Reifier {
- def CannotReifyPreTyperTree(tree: Tree) = {
- val msg = "pre-typer trees are not supported, consider typechecking the tree before passing it to the reifier"
- throw new ReifierError(tree.pos, msg)
- }
-
- def CannotReifyErroneousTree(tree: Tree) = {
- val msg = "erroneous trees are not supported, make sure that your tree typechecks successfully before passing it to the reifier"
- throw new ReifierError(tree.pos, msg)
- }
-
- def CannotReifyErroneousType(tpe: Type) = {
- val msg = "erroneous types are not supported, make sure that your tree typechecks successfully before passing it to the reifier"
- throw new ReifierError(NoPosition, msg)
- }
-
- def CannotReifyClassOfBoundType(tree: Tree, tpe: Type) = {
- val msg = "implementation restriction: cannot reify classOf[%s] which refers to a type declared inside the block being reified".format(tpe)
- throw new ReifierError(tree.pos, msg)
- }
-
- def CannotReifyClassOfBoundEnum(tree: Tree, tpe: Type) = {
- val msg = "implementation restriction: cannot reify classOf[%s] which refers to an enum declared inside the block being reified".format(tpe)
- throw new ReifierError(tree.pos, msg)
- }
-
- def CannotReifyTypeInvolvingBoundType(tpe: Type) = {
- val msg = "implementation restriction: cannot reify type %s which involves a symbol declared inside the block being reified".format(tpe)
- throw new ReifierError(NoPosition, msg)
- }
-
- def CannotReifyAnnotationInvolvingBoundType(ann: AnnotationInfo) = {
- val msg = "implementation restriction: cannot reify annotation @%s which involves a symbol declared inside the block being reified".format(ann)
- throw new ReifierError(ann.original.pos, msg)
- }
- } // end of Reifier
-
- // begin reify
- import Reifier._
- if (tree.tpe != null) {
- val saved = printTypings
- try {
- val reifyDebug = settings.Yreifydebug.value
- val debugTrace = util.trace when reifyDebug
- debugTrace("transforming = ")(if (settings.Xshowtrees.value) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString)
- debugTrace("transformed = ") {
- val reifier = new Reifier()
- val untyped = reifier.reifyTopLevel(tree)
-
- val reifyCopypaste = settings.Yreifycopypaste.value
- if (reifyCopypaste) {
- if (reifyDebug) println("=======================")
- println(reifiedNodeToString(untyped))
- if (reifyDebug) println("=======================")
- }
-
- untyped
- }
- } finally {
- printTypings = saved
- }
- } else {
- CannotReifyPreTyperTree(tree)
- }
- }
-
- /** A throwable signalling a reification error */
- class ReifierError(var pos: Position, val msg: String) extends Throwable(msg) {
- def this(msg: String) = this(NoPosition, msg)
- }
-}
diff --git a/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala b/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala
deleted file mode 100644
index fce59bb099..0000000000
--- a/src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala
+++ /dev/null
@@ -1,75 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Martin Odersky
- */
-
-package scala.tools.nsc
-package ast
-
-import compat.Platform.EOL
-import symtab._
-import Flags._
-
-trait ReifyPrinters { self: NodePrinters =>
-
- val global: Global
- import global._
-
- object reifiedNodeToString extends Function1[Tree, String] {
- def apply(tree: Tree): String = {
- import scala.reflect.api.Modifier
-
- // @PP: I fervently hope this is a test case or something, not anything being
- // depended upon. Of more fragile code I cannot conceive.
- // @eb: This stuff is only needed to debug-print out reifications in human-readable format
- // Rolling a full-fledged, robust TreePrinter would be several times more code.
- (for (line <- (tree.toString.split(EOL) drop 2 dropRight 1)) yield {
- var s = line.trim
- s = s.replace("$mr.", "")
- s = s.replace(".apply", "")
- s = s.replace("scala.collection.immutable.", "")
- s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List")
- s = "List\\[.*?\\]".r.replaceAllIn(s, "List")
- s = s.replace("immutable.this.Nil", "List()")
- s = s.replace("modifiersFromInternalFlags", "Modifiers")
- s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()")
- s = """Modifiers\((\d+)[lL], newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => {
- val buf = new collection.mutable.ListBuffer[String]
-
- val annotations = m.group(3)
- if (buf.nonEmpty || annotations.nonEmpty)
- buf.append("List(" + annotations + ")")
-
- val privateWithin = "" + m.group(2)
- if (buf.nonEmpty || privateWithin != "")
- buf.append("newTypeName(\"" + privateWithin + "\")")
-
- val flags = m.group(1).toLong
- val s_flags = Flags.modifiersOfFlags(flags) map (_.sourceString) mkString ", "
- if (buf.nonEmpty || s_flags != "")
- buf.append("Set(" + s_flags + ")")
-
- "Modifiers(" + buf.reverse.mkString(", ") + ")"
- })
- s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => {
- val flags = m.group(1).toLong
- val mods = Flags.modifiersOfFlags(flags) map (_.sourceString)
- "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))"
- })
-
- s
- }) mkString EOL
- }
- }
-
-
- def printReifyCopypaste(tree: Tree) {
- val reifyDebug = settings.Yreifydebug.value
- if (reifyDebug) println("=======================")
- printReifyCopypaste1(tree)
- if (reifyDebug) println("=======================")
- }
-
- def printReifyCopypaste1(tree: Tree) {
- }
-} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index 3302c11127..b4beb231ab 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -18,6 +18,7 @@ import scala.concurrent.Lock
import scala.text._
import symtab.Flags._
import symtab.SymbolTable
+import language.implicitConversions
/**
* Tree browsers can show the AST in a graphical and interactive
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index 0d19b781e2..283bdecf26 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -9,6 +9,7 @@ package ast
import PartialFunction._
import symtab.Flags
+import language.implicitConversions
/** A DSL for generating scala code. The goal is that the
* code generating code should look a lot like the code it
@@ -44,6 +45,11 @@ trait TreeDSL {
def NULL = LIT(null)
def UNIT = LIT(())
+ // for those preferring boring, predictable lives, without the thrills of tree-sharing
+ // (but with the perk of typed trees)
+ def TRUE_typed = LIT(true) setType ConstantType(Constant(true))
+ def FALSE_typed = LIT(false) setType ConstantType(Constant(false))
+
object WILD {
def empty = Ident(nme.WILDCARD)
def apply(tpe: Type) = Ident(nme.WILDCARD) setType tpe
@@ -287,7 +293,7 @@ trait TreeDSL {
def TRY(tree: Tree) = new TryStart(tree, Nil, EmptyTree)
def BLOCK(xs: Tree*) = Block(xs.init.toList, xs.last)
def NOT(tree: Tree) = Select(tree, Boolean_not)
- def SOME(xs: Tree*) = Apply(SomeModule, makeTupleTerm(xs.toList, true))
+ def SOME(xs: Tree*) = Apply(SomeClass.companionSymbol, makeTupleTerm(xs.toList, true))
/** Typed trees from symbols. */
def THIS(sym: Symbol) = gen.mkAttributedThis(sym)
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 6d95b6ffdd..978d83616b 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -9,6 +9,7 @@ package ast
import scala.collection.mutable.ListBuffer
import symtab.Flags._
import symtab.SymbolTable
+import language.postfixOps
/** XXX to resolve: TreeGen only assumes global is a SymbolTable, but
* TreeDSL at the moment expects a Global. Can we get by with SymbolTable?
@@ -65,22 +66,24 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
case _ => tree
}
- // must be kept in synch with the codegen in PatMatVirtualiser
- object VirtualCaseDef {
- def unapply(b: Block): Option[(Assign, Tree, Tree)] = b match {
- case Block(List(assign@Assign(keepGoingLhs, falseLit), matchRes), zero) => Some((assign, matchRes, zero)) // TODO: check tree annotation
- case _ => None
- }
+ def mkSynthSwitchSelector(expr: Tree): Tree = atPos(expr.pos) {
+ // This can't be "Annotated(New(SwitchClass), expr)" because annotations
+ // are very picky about things and it crashes the compiler with "unexpected new".
+ Annotated(Ident(nme.synthSwitch), expr)
}
+ def hasSynthCaseSymbol(t: Tree) = (t.symbol ne null) && (t.symbol hasFlag (CASE | SYNTHETIC))
+
// TODO: would be so much nicer if we would know during match-translation (i.e., type checking)
// whether we should emit missingCase-style apply (and isDefinedAt), instead of transforming trees post-factum
class MatchMatcher {
def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = unknownTree(orig)
def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = unknownTree(orig)
- def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree): Tree = unknownTree(orig)
+ def caseVirtualizedMatchOpt(orig: Tree, prologue: List[Tree], cases: List[Tree], matchEndDef: Tree, wrap: Tree => Tree): Tree = unknownTree(orig)
- def apply(matchExpr: Tree): Tree = (matchExpr: @unchecked) match {
+ def genVirtualizedMatch(prologue: List[Tree], cases: List[Tree], matchEndDef: Tree): Tree = Block(prologue ++ cases, matchEndDef)
+
+ def apply(matchExpr: Tree): Tree = matchExpr match {
// old-style match or virtpatmat switch
case Match(selector, cases) => // println("simple match: "+ (selector, cases) + "for:\n"+ matchExpr )
caseMatch(matchExpr, selector, cases, identity)
@@ -91,11 +94,15 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
case Apply(Apply(TypeApply(Select(tgt, nme.runOrElse), targs), List(scrut)), List(matcher)) if opt.virtPatmat => // println("virt match: "+ (tgt, targs, scrut, matcher) + "for:\n"+ matchExpr )
caseVirtualizedMatch(matchExpr, tgt, targs, scrut, matcher)
// optimized version of virtpatmat
- case Block((zero: ValDef) :: (x: ValDef) :: (matchRes: ValDef) :: (keepGoing: ValDef) :: stats, epilogue) if opt.virtPatmat => // TODO: check tree annotation // println("virtopt match: "+ (zero, x, matchRes, keepGoing, stats) + "for:\n"+ matchExpr )
- caseVirtualizedMatchOpt(matchExpr, zero, x, matchRes, keepGoing, stats, epilogue, identity)
+ case Block(stats, matchEndDef) if opt.virtPatmat && (stats forall hasSynthCaseSymbol) =>
+ // the assumption is once we encounter a case, the remainder of the block will consist of cases
+ // the prologue may be empty, usually it is the valdef that stores the scrut
+ val (prologue, cases) = stats span (s => !s.isInstanceOf[LabelDef])
+ caseVirtualizedMatchOpt(matchExpr, prologue, cases, matchEndDef, identity)
// optimized version of virtpatmat
- case Block(outerStats, orig@Block((zero: ValDef) :: (x: ValDef) :: (matchRes: ValDef) :: (keepGoing: ValDef) :: stats, epilogue)) if opt.virtPatmat => // TODO: check tree annotation // println("virt opt block match: "+ (zero, x, matchRes, keepGoing, stats, outerStats) + "for:\n"+ matchExpr )
- caseVirtualizedMatchOpt(matchExpr, zero, x, matchRes, keepGoing, stats, epilogue, m => copyBlock(matchExpr, outerStats, m))
+ case Block(outerStats, orig@Block(stats, matchEndDef)) if opt.virtPatmat && (stats forall hasSynthCaseSymbol) =>
+ val (prologue, cases) = stats span (s => !s.isInstanceOf[LabelDef])
+ caseVirtualizedMatchOpt(matchExpr, prologue, cases, matchEndDef, m => copyBlock(matchExpr, outerStats, m))
case other =>
unknownTree(other)
}
@@ -111,35 +118,6 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
}
}
- def withDefaultCase(matchExpr: Tree, defaultAction: Tree/*scrutinee*/ => Tree): Tree = {
- object withDefaultTransformer extends MatchMatcher {
- override def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = {
- val casesNoSynthCatchAll = dropSyntheticCatchAll(cases)
- if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) orig
- else {
- val defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, defaultAction(selector.duplicate))
- wrap(Match(selector, casesNoSynthCatchAll :+ defaultCase))
- }
- }
- override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = { import CODE._
- ((matcher APPLY (scrut)) DOT nme.getOrElse) APPLY (defaultAction(scrut.duplicate)) // TODO: pass targs
- }
- override def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree): Tree = { import CODE._
- wrap(Block(
- zero ::
- x ::
- matchRes ::
- keepGoing ::
- stats,
- // replace `if (keepGoing) throw new MatchError(...) else matchRes` by `if (keepGoing) ${defaultAction(`x`)} else matchRes`
- (IF (REF(keepGoing.symbol)) THEN defaultAction(x.rhs.duplicate) ELSE REF(matchRes.symbol))
- ))
- }
- }
- withDefaultTransformer(matchExpr)
- }
-
-
def mkCached(cvar: Symbol, expr: Tree): Tree = {
val cvarRef = mkUnattributedRef(cvar)
Block(
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
index 9f361e5bcc..569cb4977b 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -44,7 +44,7 @@ abstract class TreeInfo extends reflect.internal.TreeInfo {
}
def isInterface(mods: HasFlags, body: List[Tree]) =
- mods.hasTraitFlag && (body forall isInterfaceMember)
+ mods.isTrait && (body forall isInterfaceMember)
def isAllowedInUniversalTrait(stat: Tree): Boolean = stat match {
case _: ValDef => false
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 43c231cf2d..2bd1ba3fea 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -13,6 +13,7 @@ import scala.reflect.internal.Flags.PARAM
import scala.reflect.internal.Flags.PARAMACCESSOR
import scala.reflect.internal.Flags.PRESUPER
import scala.reflect.internal.Flags.TRAIT
+import scala.compat.Platform.EOL
trait Trees extends reflect.internal.Trees { self: Global =>
@@ -33,30 +34,6 @@ trait Trees extends reflect.internal.Trees { self: Global =>
)
}
- class ValidatingPosAssigner extends PosAssigner {
- var pos: Position = _
- override def traverse(t: Tree) {
- if (t eq EmptyTree) ()
- else if (t.pos == NoPosition) super.traverse(t setPos pos)
- else if (globalPhase.id <= currentRun.picklerPhase.id) {
- // When we prune due to encountering a position, traverse the
- // pruned children so we can warn about those lacking positions.
- t.children foreach { c =>
- if ((c eq EmptyTree) || (c eq emptyValDef)) ()
- else if (c.pos == NoPosition) {
- reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase)
- inform("parent: " + treeSymStatus(t))
- inform(" child: " + treeSymStatus(c) + "\n")
- }
- }
- }
- }
- }
-
- override protected[this] lazy val posAssigner: PosAssigner =
- if (settings.Yrangepos.value && settings.debug.value || settings.Yposdebug.value) new ValidatingPosAssigner
- else new DefaultPosAssigner
-
// --- additional cases --------------------------------------------------------
/** Only used during parsing */
case class Parens(args: List[Tree]) extends Tree
@@ -81,18 +58,11 @@ trait Trees extends reflect.internal.Trees { self: Global =>
case class InjectDerivedValue(arg: Tree)
extends SymTree
+ class PostfixSelect(qual: Tree, name: Name) extends Select(qual, name)
+
/** emitted by typer, eliminated by refchecks */
case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree
- /** Marks underlying reference to id as boxed.
- * @pre: id must refer to a captured variable
- * A reference such marked will refer to the boxed entity, no dereferencing
- * with `.elem` is done on it.
- * This tree node can be emitted by macros such as reify that call markBoxedReference.
- * It is eliminated in LambdaLift, where the boxing conversion takes place.
- */
- case class ReferenceToBoxed(idt: Ident) extends TermTree
-
// --- factory methods ----------------------------------------------------------
/** Generates a template with constructor corresponding to
@@ -116,13 +86,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
/* Add constructor to template */
// create parameters for <init> as synthetic trees.
- var vparamss1 =
- vparamss map (vps => vps.map { vd =>
- atPos(focusPos(vd.pos)) {
- ValDef(
- Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations,
- vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
- }})
+ var vparamss1 = mmap(vparamss) { vd =>
+ atPos(vd.pos.focus) {
+ val mods = Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR)
+ ValDef(mods withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
+ }
+ }
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val gvdefs = evdefs map {
@@ -130,7 +99,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
// !!! I know "atPos in case" wasn't intentionally planted to
// add an air of mystery to this file, but it is the sort of
// comment which only its author could love.
- tpt = atPos(focusPos(vdef.pos))(TypeTree() setOriginal tpt setPos focusPos(tpt.pos)), // atPos in case
+ tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus), // atPos in case
rhs = EmptyTree
)
}
@@ -173,11 +142,18 @@ trait Trees extends reflect.internal.Trees { self: Global =>
* @param body the template statements without primary constructor
* and value parameter fields.
*/
- def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef =
+ def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = {
+ // "if they have symbols they should be owned by `sym`"
+ assert(
+ mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)),
+ ((mmap(vparamss)(_.symbol), sym))
+ )
+
ClassDef(sym,
Template(sym.info.parents map TypeTree,
if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
constrMods, vparamss, argss, body, superPos))
+ }
// --- subcomponents --------------------------------------------------
@@ -198,8 +174,6 @@ trait Trees extends reflect.internal.Trees { self: Global =>
traverser.traverse(qualifier)
case InjectDerivedValue(arg) =>
traverser.traverse(arg)
- case ReferenceToBoxed(idt) =>
- traverser.traverse(idt)
case TypeTreeWithDeferredRefCheck() =>
// (and rewrap the result? how to update the deferred check? would need to store wrapped tree instead of returning it from check)
case _ => super.xtraverse(traverser, tree)
@@ -209,7 +183,6 @@ trait Trees extends reflect.internal.Trees { self: Global =>
def DocDef(tree: Tree, comment: DocComment, definition: Tree): DocDef
def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type): SelectFromArray
def InjectDerivedValue(tree: Tree, arg: Tree): InjectDerivedValue
- def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed
def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck
}
@@ -223,8 +196,6 @@ trait Trees extends reflect.internal.Trees { self: Global =>
new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree)
def InjectDerivedValue(tree: Tree, arg: Tree) =
new InjectDerivedValue(arg)
- def ReferenceToBoxed(tree: Tree, idt: Ident) =
- new ReferenceToBoxed(idt).copyAttrs(tree)
def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
case dc@TypeTreeWithDeferredRefCheck() => new TypeTreeWithDeferredRefCheck()(dc.check).copyAttrs(tree)
}
@@ -246,11 +217,6 @@ trait Trees extends reflect.internal.Trees { self: Global =>
if (arg0 == arg) => t
case _ => this.treeCopy.InjectDerivedValue(tree, arg)
}
- def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match {
- case t @ ReferenceToBoxed(idt0)
- if (idt0 == idt) => t
- case _ => this.treeCopy.ReferenceToBoxed(tree, idt)
- }
def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
case t @ TypeTreeWithDeferredRefCheck() => t
case _ => this.treeCopy.TypeTreeWithDeferredRefCheck(tree)
@@ -277,9 +243,6 @@ trait Trees extends reflect.internal.Trees { self: Global =>
case InjectDerivedValue(arg) =>
transformer.treeCopy.InjectDerivedValue(
tree, transformer.transform(arg))
- case ReferenceToBoxed(idt) =>
- transformer.treeCopy.ReferenceToBoxed(
- tree, transformer.transform(idt) match { case idt1: Ident => idt1 })
case TypeTreeWithDeferredRefCheck() =>
transformer.treeCopy.TypeTreeWithDeferredRefCheck(tree)
}
@@ -296,8 +259,9 @@ trait Trees extends reflect.internal.Trees { self: Global =>
// def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x }
// def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x }
- def resetAllAttrs[A<:Tree](x:A): A = new ResetAttrs(false).transform(x)
- def resetLocalAttrs[A<:Tree](x:A): A = new ResetAttrs(true).transform(x)
+ def resetAllAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(false, leaveAlone).transform(x)
+ def resetLocalAttrs[A <: Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(true, leaveAlone).transform(x)
+ def resetLocalAttrsKeepLabels[A<:Tree](x: A, leaveAlone: Tree => Boolean = null): A = new ResetAttrs(true, leaveAlone, true).transform(x)
/** A transformer which resets symbol and tpe fields of all nodes in a given tree,
* with special treatment of:
@@ -308,7 +272,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
*
* (bq:) This transformer has mutable state and should be discarded after use
*/
- private class ResetAttrs(localOnly: Boolean) {
+ private class ResetAttrs(localOnly: Boolean, leaveAlone: Tree => Boolean = null, keepLabels: Boolean = false) {
val debug = settings.debug.value
val trace = scala.tools.nsc.util.trace when debug
@@ -328,6 +292,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
registerLocal(sym)
registerLocal(sym.sourceModule)
registerLocal(sym.moduleClass)
+ registerLocal(sym.companionClass)
+ registerLocal(sym.companionModule)
+ sym match {
+ case sym: TermSymbol => registerLocal(sym.referenced)
+ case _ => ;
+ }
}
}
@@ -335,10 +305,8 @@ trait Trees extends reflect.internal.Trees { self: Global =>
tree match {
case _: DefTree | Function(_, _) | Template(_, _, _) =>
markLocal(tree)
- case _ if tree.symbol.isInstanceOf[FreeVar] =>
- markLocal(tree)
case _ =>
- ;
+ tree
}
super.traverse(tree)
@@ -346,43 +314,48 @@ trait Trees extends reflect.internal.Trees { self: Global =>
}
class Transformer extends self.Transformer {
- override def transform(tree: Tree): Tree = super.transform {
- tree match {
- case tpt: TypeTree =>
- if (tpt.original != null) {
- transform(tpt.original)
- } else {
- if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol))))
- tpt.tpe = null
- tree
+ override def transform(tree: Tree): Tree = {
+ if (leaveAlone != null && leaveAlone(tree))
+ tree
+ else
+ super.transform {
+ tree match {
+ case tpt: TypeTree =>
+ if (tpt.original != null) {
+ transform(tpt.original)
+ } else {
+ if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol))))
+ tpt.tpe = null
+ tree
+ }
+ case TypeApply(fn, args) if args map transform exists (_.isEmpty) =>
+ transform(fn)
+ case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
+ tree
+ case EmptyTree =>
+ tree
+ case _ =>
+ if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)) && !(keepLabels && tree.symbol.isLabel))
+ tree.symbol = NoSymbol
+ tree.tpe = null
+ tree
}
- case TypeApply(fn, args) if args map transform exists (_.isEmpty) =>
- transform(fn)
- case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
- tree
- case EmptyTree =>
- tree
- case _ =>
- if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)))
- tree.symbol = NoSymbol
- tree.tpe = null
- tree
- }
+ }
}
}
def transform[T <: Tree](x: T): T = {
+ if (localOnly)
new MarkLocals().traverse(x)
- if (debug) {
+ if (localOnly && debug) {
assert(locals.size == orderedLocals.size)
- val eoln = System.getProperty("line.separator")
- val msg = orderedLocals.toList filter {_ != NoSymbol} map {" " + _} mkString eoln
+ val msg = orderedLocals.toList filter {_ != NoSymbol} map {" " + _} mkString EOL
trace("locals (%d total): %n".format(orderedLocals.size))(msg)
}
val x1 = new Transformer().transform(x)
- assert(x.getClass isInstance x1)
+ assert(x.getClass isInstance x1, x1.getClass)
x1.asInstanceOf[T]
}
}
@@ -397,4 +370,4 @@ trait Trees extends reflect.internal.Trees { self: Global =>
*/
- } \ No newline at end of file
+ }
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index ccebcfa54d..bca1cc4596 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -70,6 +70,9 @@ trait ParsersCommon extends ScannersCommon {
@inline final def inBracesOrNil[T](body: => List[T]): List[T] = inBracesOrError(body, Nil)
@inline final def inBracesOrUnit[T](body: => Tree): Tree = inBracesOrError(body, Literal(Constant()))
+ @inline final def dropAnyBraces[T](body: => T): T =
+ if (in.token == LBRACE) inBraces(body)
+ else body
@inline final def inBrackets[T](body: => T): T = {
accept(LBRACKET)
@@ -249,7 +252,7 @@ self =>
final val InBlock = 1
final val InTemplate = 2
- lazy val ScalaValueClassNames: Set[Name] = definitions.scalaValueClassesSet map (_.name)
+ lazy val ScalaValueClassNames = tpnme.AnyVal :: definitions.ScalaValueClasses.map(_.name)
import nme.raw
@@ -314,7 +317,7 @@ self =>
* by compilationUnit().
*/
def scriptBody(): Tree = {
- val stmts = templateStatSeq(false)._2
+ val stmts = templateStats()
accept(EOF)
def mainModuleName = newTermName(settings.script.value)
@@ -1106,7 +1109,7 @@ self =>
* }}}
* @note The returned tree does not yet have a position
*/
- def literal(isNegated: Boolean = false): Tree = {
+ def literal(isNegated: Boolean = false, inPattern: Boolean = false): Tree = {
def finish(value: Any): Tree = {
val t = Literal(Constant(value))
in.nextToken()
@@ -1115,7 +1118,7 @@ self =>
if (in.token == SYMBOLLIT)
Apply(scalaDot(nme.Symbol), List(finish(in.strVal)))
else if (in.token == INTERPOLATIONID)
- interpolatedString()
+ interpolatedString(inPattern)
else finish(in.token match {
case CHARLIT => in.charVal
case INTLIT => in.intVal(isNegated).toInt
@@ -1141,7 +1144,7 @@ self =>
}
}
- private def interpolatedString(): Tree = atPos(in.offset) {
+ private def interpolatedString(inPattern: Boolean = false): Tree = atPos(in.offset) {
val start = in.offset
val interpolator = in.name
@@ -1151,8 +1154,11 @@ self =>
while (in.token == STRINGPART) {
partsBuf += literal()
exprBuf += {
- if (in.token == IDENTIFIER) atPos(in.offset)(Ident(ident()))
- else expr()
+ if (inPattern) dropAnyBraces(pattern())
+ else {
+ if (in.token == IDENTIFIER) atPos(in.offset)(Ident(ident()))
+ else expr()
+ }
}
}
if (in.token == STRINGLIT) partsBuf += literal()
@@ -1394,13 +1400,7 @@ self =>
}
}
} else if (in.token == MATCH) {
- t = atPos(t.pos.startOrPoint, in.skipToken()) {
- /** For debugging pattern matcher transition issues */
- if (settings.Ypmatnaive.value)
- makeSequencedMatch(stripParens(t), inBracesOrNil(caseClauses()))
- else
- Match(stripParens(t), inBracesOrNil(caseClauses()))
- }
+ t = atPos(t.pos.startOrPoint, in.skipToken())(Match(stripParens(t), inBracesOrNil(caseClauses())))
}
// in order to allow anonymous functions as statements (as opposed to expressions) inside
// templates, we have to disambiguate them from self type declarations - bug #1565
@@ -1462,11 +1462,12 @@ self =>
return reduceStack(true, base, top, 0, true)
top = next
} else {
+ // postfix expression
val topinfo = opstack.head
opstack = opstack.tail
val od = stripParens(reduceStack(true, base, topinfo.operand, 0, true))
return atPos(od.pos.startOrPoint, topinfo.offset) {
- Select(od, topinfo.operator.encode)
+ new PostfixSelect(od, topinfo.operator.encode)
}
}
}
@@ -1777,7 +1778,9 @@ self =>
* }}}
*/
def pattern2(): Tree = {
+ val nameOffset = in.offset
val p = pattern3()
+
if (in.token != AT) p
else p match {
case Ident(nme.WILDCARD) =>
@@ -1840,7 +1843,7 @@ self =>
case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT =>
t match {
case Ident(nme.MINUS) =>
- return atPos(start) { literal(isNegated = true) }
+ return atPos(start) { literal(isNegated = true, inPattern = true) }
case _ =>
}
case _ =>
@@ -1858,7 +1861,7 @@ self =>
atPos(start, start) { Ident(nme.WILDCARD) }
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT |
STRINGLIT | INTERPOLATIONID | SYMBOLLIT | TRUE | FALSE | NULL =>
- atPos(start) { literal() }
+ atPos(start) { literal(inPattern = true) }
case LPAREN =>
atPos(start)(makeParens(noSeq.patterns()))
case XMLSTART =>
@@ -2427,10 +2430,10 @@ self =>
*/
/** {{{
- * FunDef ::= FunSig `:' Type `=' Expr
- * | FunSig [nl] `{' Block `}'
- * | this ParamClause ParamClauses (`=' ConstrExpr | [nl] ConstrBlock)
- * | `macro' FunSig [`:' Type] `=' Expr
+ * FunDef ::= FunSig [`:' Type] `=' [`macro'] Expr
+ * | FunSig [nl] `{' Block `}'
+ * | `this' ParamClause ParamClauses
+ * (`=' ConstrExpr | [nl] ConstrBlock)
* FunDcl ::= FunSig [`:' Type]
* FunSig ::= id [FunTypeParamClause] ParamClauses
* }}}
@@ -2450,18 +2453,14 @@ self =>
}
else {
val nameOffset = in.offset
+ val isBackquoted = in.token == BACKQUOTED_IDENT
val name = ident()
- if (name == nme.macro_ && isIdent && settings.Xmacros.value)
- funDefRest(start, in.offset, mods | Flags.MACRO, ident())
- else
- funDefRest(start, nameOffset, mods, name)
+ funDefRest(start, nameOffset, mods, name)
}
}
def funDefRest(start: Int, nameOffset: Int, mods: Modifiers, name: Name): Tree = {
val result = atPos(start, if (name.toTermName == nme.ERROR) start else nameOffset) {
- val isMacro = mods hasFlag Flags.MACRO
- val isTypeMacro = isMacro && name.isTypeName
var newmods = mods
// contextBoundBuf is for context bounded type parameters of the form
// [T : B] or [T : => B]; it contains the equivalent implicit parameter type,
@@ -2469,12 +2468,10 @@ self =>
val contextBoundBuf = new ListBuffer[Tree]
val tparams = typeParamClauseOpt(name, contextBoundBuf)
val vparamss = paramClauses(name, contextBoundBuf.toList, false)
- if (!isMacro) newLineOptWhenFollowedBy(LBRACE)
- var restype = if (isTypeMacro) TypeTree() else fromWithinReturnType(typedOpt())
+ newLineOptWhenFollowedBy(LBRACE)
+ var restype = fromWithinReturnType(typedOpt())
val rhs =
- if (isMacro)
- equalsExpr()
- else if (isStatSep || in.token == RBRACE) {
+ if (isStatSep || in.token == RBRACE) {
if (restype.isEmpty) restype = scalaUnitConstr
newmods |= Flags.DEFERRED
EmptyTree
@@ -2482,10 +2479,17 @@ self =>
restype = scalaUnitConstr
blockExpr()
} else {
- if (name == nme.macro_ && isIdent && in.token != EQUALS) {
- warning("this syntactically invalid code resembles a macro definition. have you forgotten to enable -Xmacros?")
+ if (in.token == EQUALS) {
+ in.nextTokenAllow(nme.MACROkw)
+ if (settings.Xmacros.value && in.token == MACRO || // [Martin] Xmacros can be retired now
+ in.token == IDENTIFIER && in.name == nme.MACROkw) {
+ in.nextToken()
+ newmods |= Flags.MACRO
+ }
+ } else {
+ accept(EQUALS)
}
- equalsExpr()
+ expr()
}
DefDef(newmods, name, tparams, vparamss, restype, rhs)
}
@@ -2535,7 +2539,7 @@ self =>
/** {{{
* TypeDef ::= type Id [TypeParamClause] `=' Type
- * | `macro' FunSig `=' Expr
+ * | FunSig `=' Expr
* TypeDcl ::= type Id [TypeParamClause] TypeBounds
* }}}
*/
@@ -2543,22 +2547,20 @@ self =>
in.nextToken()
newLinesOpt()
atPos(start, in.offset) {
+ val nameOffset = in.offset
+ val isBackquoted = in.token == BACKQUOTED_IDENT
val name = identForType()
- if (name == nme.macro_.toTypeName && isIdent && settings.Xmacros.value) {
- funDefRest(start, in.offset, mods | Flags.MACRO, identForType())
- } else {
- // @M! a type alias as well as an abstract type may declare type parameters
- val tparams = typeParamClauseOpt(name, null)
- in.token match {
- case EQUALS =>
- in.nextToken()
- TypeDef(mods, name, tparams, typ())
- case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE =>
- TypeDef(mods | Flags.DEFERRED, name, tparams, typeBounds())
- case _ =>
- syntaxErrorOrIncomplete("`=', `>:', or `<:' expected", true)
- EmptyTree
- }
+ // @M! a type alias as well as an abstract type may declare type parameters
+ val tparams = typeParamClauseOpt(name, null)
+ in.token match {
+ case EQUALS =>
+ in.nextToken()
+ TypeDef(mods, name, tparams, typ())
+ case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE =>
+ TypeDef(mods | Flags.DEFERRED, name, tparams, typeBounds())
+ case _ =>
+ syntaxErrorOrIncomplete("`=', `>:', or `<:' expected", true)
+ EmptyTree
}
}
}
@@ -2605,25 +2607,24 @@ self =>
def classDef(start: Int, mods: Modifiers): ClassDef = {
in.nextToken
val nameOffset = in.offset
+ val isBackquoted = in.token == BACKQUOTED_IDENT
val name = identForType()
- def isTrait = mods.hasTraitFlag
-
atPos(start, if (name == tpnme.ERROR) start else nameOffset) {
savingClassContextBounds {
val contextBoundBuf = new ListBuffer[Tree]
val tparams = typeParamClauseOpt(name, contextBoundBuf)
classContextBounds = contextBoundBuf.toList
- val tstart = in.offset :: classContextBounds.map(_.pos.startOrPoint) min;
- if (!classContextBounds.isEmpty && isTrait) {
+ val tstart = (in.offset :: classContextBounds.map(_.pos.startOrPoint)).min
+ if (!classContextBounds.isEmpty && mods.isTrait) {
syntaxError("traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...'", false)
classContextBounds = List()
}
val constrAnnots = constructorAnnotations()
val (constrMods, vparamss) =
- if (isTrait) (Modifiers(Flags.TRAIT), List())
+ if (mods.isTrait) (Modifiers(Flags.TRAIT), List())
else (accessModifierOpt(), paramClauses(name, classContextBounds, mods.isCase))
var mods1 = mods
- if (isTrait) {
+ if (mods.isTrait) {
if (settings.YvirtClasses && in.token == SUBTYPE) mods1 |= Flags.DEFERRED
} else if (in.token == SUBTYPE) {
syntaxError("classes are not allowed to be virtual", false)
@@ -2647,6 +2648,7 @@ self =>
def objectDef(start: Int, mods: Modifiers): ModuleDef = {
in.nextToken
val nameOffset = in.offset
+ val isBackquoted = in.token == BACKQUOTED_IDENT
val name = ident()
val tstart = in.offset
atPos(start, if (name == nme.ERROR) start else nameOffset) {
@@ -2715,7 +2717,7 @@ self =>
}
def isInterface(mods: Modifiers, body: List[Tree]): Boolean =
- mods.hasTraitFlag && (body forall treeInfo.isInterfaceMember)
+ mods.isTrait && (body forall treeInfo.isInterfaceMember)
/** {{{
* ClassTemplateOpt ::= `extends' ClassTemplate | [[`extends'] TemplateBody]
@@ -2725,9 +2727,9 @@ self =>
*/
def templateOpt(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]], tstart: Int): Template = {
val (parents0, argss, self, body) = (
- if (in.token == EXTENDS || in.token == SUBTYPE && mods.hasTraitFlag) {
+ if (in.token == EXTENDS || in.token == SUBTYPE && mods.isTrait) {
in.nextToken()
- template(mods.hasTraitFlag)
+ template(mods.isTrait)
}
else {
newLineOptWhenFollowedBy(LBRACE)
@@ -2750,9 +2752,8 @@ self =>
val tstart0 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart
atPos(tstart0) {
- // [Martin to Paul: This needs to be refined. We should only include the 9 primitive classes,
- // not any other value classes that happen to be defined in the Scala package.
- if (inScalaRootPackage && (name == tpnme.AnyVal || (ScalaValueClassNames contains name)))
+ // Exclude only the 9 primitives plus AnyVal.
+ if (inScalaRootPackage && ScalaValueClassNames.contains(name))
Template(parents0, self, anyvalConstructor :: body)
else
Template(anyrefParents, self, constrMods, vparamss, argss, body, o2p(tstart))
@@ -2826,6 +2827,7 @@ self =>
* }}}
*/
def packaging(start: Int): Tree = {
+ val nameOffset = in.offset
val pkg = pkgQualId()
val stats = inBracesOrNil(topStatSeq())
makePackaging(start, pkg, stats)
@@ -2867,6 +2869,13 @@ self =>
stats.toList
}
+ /** Informal - for the repl and other direct parser accessors.
+ */
+ def templateStats(): List[Tree] = templateStatSeq(false)._2 match {
+ case Nil => List(EmptyTree)
+ case stats => stats
+ }
+
/** {{{
* TemplateStatSeq ::= [id [`:' Type] `=>'] TemplateStat {semi TemplateStat}
* TemplateStat ::= Import
@@ -3028,8 +3037,10 @@ self =>
ts ++= topStatSeq()
}
} else {
+ val nameOffset = in.offset
in.flushDoc
val pkg = pkgQualId()
+
if (in.token == EOF) {
ts += makePackaging(start, pkg, List())
} else if (isStatSep) {
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 2895d02dfe..87072f3172 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -113,10 +113,18 @@ trait Scanners extends ScannersCommon {
}
/** Clear buffer and set name and token */
- private def finishNamed() {
+ private def finishNamed(idtoken: Int = IDENTIFIER) {
name = newTermName(cbuf.toString)
- token = name2token(name)
cbuf.clear()
+ token = idtoken
+ if (idtoken == IDENTIFIER) {
+ val idx = name.start - kwOffset
+ if (idx >= 0 && idx < kwArray.length) {
+ token = kwArray(idx)
+ if (token == IDENTIFIER && allowIdent != name)
+ deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated")
+ }
+ }
}
/** Clear buffer and set string */
@@ -190,6 +198,20 @@ trait Scanners extends ScannersCommon {
off
}
+ /** Allow an otherwise deprecated ident here */
+ private var allowIdent: Name = nme.EMPTY
+
+ /** Get next token, and allow the otherwise deprecated ident `name` */
+ def nextTokenAllow(name: Name) = {
+ val prev = allowIdent
+ allowIdent = name
+ try {
+ nextToken()
+ } finally {
+ allowIdent = prev
+ }
+ }
+
/** Produce next token, filling TokenData fields of Scanner.
*/
def nextToken() {
@@ -231,6 +253,12 @@ trait Scanners extends ScannersCommon {
lastOffset -= 1
}
if (inStringInterpolation) fetchStringPart() else fetchToken()
+ if(token == ERROR) {
+ if (inMultiLineInterpolation)
+ sepRegions = sepRegions.tail.tail
+ else if (inStringInterpolation)
+ sepRegions = sepRegions.tail
+ }
} else {
this copyFrom next
next.token = EMPTY
@@ -328,7 +356,7 @@ trait Scanners extends ScannersCommon {
putChar(ch)
nextChar()
getIdentRest()
- if (ch == '"' && token == IDENTIFIER && settings.Xexperimental.value)
+ if (ch == '"' && token == IDENTIFIER)
token = INTERPOLATIONID
case '<' => // is XMLSTART?
val last = if (charOffset >= 2) buf(charOffset - 2) else ' '
@@ -562,9 +590,8 @@ trait Scanners extends ScannersCommon {
getLitChars('`')
if (ch == '`') {
nextChar()
- finishNamed()
+ finishNamed(BACKQUOTED_IDENT)
if (name.length == 0) syntaxError("empty quoted identifier")
- token = BACKQUOTED_IDENT
}
else syntaxError("unclosed quoted identifier")
}
@@ -697,7 +724,7 @@ trait Scanners extends ScannersCommon {
do {
putChar(ch)
nextRawChar()
- } while (Character.isUnicodeIdentifierPart(ch))
+ } while (ch != SU && Character.isUnicodeIdentifierPart(ch))
next.token = IDENTIFIER
next.name = newTermName(cbuf.toString)
cbuf.clear()
@@ -1124,8 +1151,9 @@ trait Scanners extends ScannersCommon {
nme.VIEWBOUNDkw -> VIEWBOUND,
nme.SUPERTYPEkw -> SUPERTYPE,
nme.HASHkw -> HASH,
- nme.ATkw -> AT
- )
+ nme.ATkw -> AT,
+ nme.MACROkw -> IDENTIFIER,
+ nme.THENkw -> IDENTIFIER)
private var kwOffset: Int = -1
private val kwArray: Array[Int] = {
@@ -1134,14 +1162,7 @@ trait Scanners extends ScannersCommon {
arr
}
- final val token2name = allKeywords map (_.swap) toMap
-
- /** Convert name to token */
- final def name2token(name: Name) = {
- val idx = name.start - kwOffset
- if (idx >= 0 && idx < kwArray.length) kwArray(idx)
- else IDENTIFIER
- }
+ final val token2name = (allKeywords map (_.swap)).toMap
// Token representation ----------------------------------------------------
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index 849437e4ff..b0204c5971 100755
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -11,6 +11,7 @@ import xml.{ EntityRef, Text }
import xml.XML.{ xmlns }
import symtab.Flags.MUTABLE
import scala.tools.util.StringOps.splitWhere
+import language.implicitConversions
/** This class builds instance of `Tree` that represent XML.
*
@@ -29,7 +30,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
private[parser] var isPattern: Boolean = _
- private trait XMLTypeNames extends TypeNames {
+ private object xmltypes extends TypeNames {
val _Comment: NameType = "Comment"
val _Elem: NameType = "Elem"
val _EntityRef: NameType = "EntityRef"
@@ -44,7 +45,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
val _UnprefixedAttribute: NameType = "UnprefixedAttribute"
}
- private trait XMLTermNames extends TermNames {
+ private object xmlterms extends TermNames {
val _Null: NameType = "Null"
val __Elem: NameType = "Elem"
val __Text: NameType = "Text"
@@ -56,15 +57,6 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
val _xml: NameType = "xml"
}
- private object xmltypes extends XMLTypeNames {
- type NameType = TypeName
- implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
- }
- private object xmlterms extends XMLTermNames {
- type NameType = TermName
- implicit def createNameType(name: String): TermName = newTermNameCached(name)
- }
-
import xmltypes.{_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer,
_PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
index fb4daefd57..a4a062609b 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
@@ -110,6 +110,8 @@ object Tokens extends Tokens {
final val MATCH = 58
final val FORSOME = 59
final val LAZY = 61
+ final val MACRO = 62 // not yet used in 2.10
+ final val THEN = 63 // not yet used in 2.10
def isKeyword(code: Int) =
code >= IF && code <= LAZY
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 0bc88d1efd..de7e6f9c7a 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -505,37 +505,6 @@ abstract class TreeBuilder {
def makePatDef(pat: Tree, rhs: Tree): List[Tree] =
makePatDef(Modifiers(0), pat, rhs)
- /** For debugging only. Desugar a match statement like so:
- * val x = scrutinee
- * x match {
- * case case1 => ...
- * case _ => x match {
- * case case2 => ...
- * case _ => x match ...
- * }
- * }
- *
- * This way there are never transitions between nontrivial casedefs.
- * Of course many things break: exhaustiveness and unreachable checking
- * do not work, no switches will be generated, etc.
- */
- def makeSequencedMatch(selector: Tree, cases: List[CaseDef]): Tree = {
- require(cases.nonEmpty)
-
- val selectorName = freshTermName()
- val valdef = atPos(selector.pos)(ValDef(Modifiers(PrivateLocal | SYNTHETIC), selectorName, TypeTree(), selector))
- val nselector = Ident(selectorName)
-
- def loop(cds: List[CaseDef]): Match = {
- def mkNext = CaseDef(Ident(nme.WILDCARD), EmptyTree, loop(cds.tail))
-
- if (cds.size == 1) Match(nselector, cds)
- else Match(selector, List(cds.head, mkNext))
- }
-
- Block(List(valdef), loop(cases))
- }
-
/** Create tree for pattern definition <mods val pat0 = rhs> */
def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree): List[Tree] = matchVarPattern(pat) match {
case Some((name, tpt)) =>
@@ -552,11 +521,29 @@ abstract class TreeBuilder {
// val/var x_1 = t$._1
// ...
// val/var x_N = t$._N
- val pat1 = patvarTransformer.transform(pat)
+
+ val rhsUnchecked = gen.mkUnchecked(rhs)
+
+ // TODO: clean this up -- there is too much information packked into makePatDef's `pat` argument
+ // when it's a simple identifier (case Some((name, tpt)) -- above),
+ // pat should have the type ascription that was specified by the user
+ // however, in `case None` (here), we must be careful not to generate illegal pattern trees (such as `(a, b): Tuple2[Int, String]`)
+ // i.e., this must hold: pat1 match { case Typed(expr, tp) => assert(expr.isInstanceOf[Ident]) case _ => }
+ // if we encounter such an erroneous pattern, we strip off the type ascription from pat and propagate the type information to rhs
+ val (pat1, rhs1) = patvarTransformer.transform(pat) match {
+ // move the Typed ascription to the rhs
+ case Typed(expr, tpt) if !expr.isInstanceOf[Ident] =>
+ val rhsTypedUnchecked =
+ if (tpt.isEmpty) rhsUnchecked
+ else Typed(rhsUnchecked, tpt) setPos (rhs.pos union tpt.pos)
+ (expr, rhsTypedUnchecked)
+ case ok =>
+ (ok, rhsUnchecked)
+ }
val vars = getVariables(pat1)
val matchExpr = atPos((pat1.pos union rhs.pos).makeTransparent) {
Match(
- gen.mkUnchecked(rhs),
+ rhs1,
List(
atPos(pat1.pos) {
CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))
diff --git a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
index 27df45b563..314a3b45a0 100644
--- a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
+++ b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
@@ -38,10 +38,10 @@ trait JavaPlatform extends Platform {
genJVM // generate .class files
) ++ depAnalysisPhase
- lazy val externalEquals = getMember(BoxesRunTimeClass, nme.equals_)
- lazy val externalEqualsNumNum = getMember(BoxesRunTimeClass, nme.equalsNumNum)
- lazy val externalEqualsNumChar = getMember(BoxesRunTimeClass, nme.equalsNumChar)
- lazy val externalEqualsNumObject = getMember(BoxesRunTimeClass, nme.equalsNumObject)
+ lazy val externalEquals = getDecl(BoxesRunTimeClass, nme.equals_)
+ lazy val externalEqualsNumNum = getDecl(BoxesRunTimeClass, nme.equalsNumNum)
+ lazy val externalEqualsNumChar = getDecl(BoxesRunTimeClass, nme.equalsNumChar)
+ lazy val externalEqualsNumObject = getDecl(BoxesRunTimeClass, nme.equalsNumObject)
/** We could get away with excluding BoxedBooleanClass for the
* purpose of equality testing since it need not compare equal
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index 68c4ac03f6..dcbabd6517 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
@@ -11,6 +11,7 @@ import scala.collection.{ mutable, immutable }
import mutable.{ ListBuffer, ArrayBuffer }
import util.{ Position, NoPosition }
import backend.icode.analysis.ProgramPoint
+import language.postfixOps
trait BasicBlocks {
self: ICodes =>
@@ -386,10 +387,16 @@ trait BasicBlocks {
def close() {
assert(!closed || ignore, this)
assert(instructionList.nonEmpty, "Empty block: " + this)
- closed = true
- setFlag(DIRTYSUCCS)
- instructionList = instructionList.reverse
- instrs = instructionList.toArray
+ 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)
+ // reversing the instructions when (closed && ignore) wreaks havoc for nested label jumps (see comments in genLoad)
+ } else {
+ closed = true
+ setFlag(DIRTYSUCCS)
+ instructionList = instructionList.reverse
+ instrs = instructionList.toArray
+ }
}
def open() {
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 9e801e3ea8..5e5b09405c 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -13,6 +13,7 @@ import scala.collection.mutable.{ ListBuffer, Buffer }
import scala.tools.nsc.symtab._
import scala.annotation.switch
import PartialFunction._
+import language.postfixOps
/** This class ...
*
@@ -868,6 +869,13 @@ abstract class GenICode extends SubComponent {
abort("Unknown label target: " + sym + " at: " + (fun.pos) + ": ctx: " + ctx)
}
})
+ // note: when one of the args to genLoadLabelArguments is a jump to a label,
+ // it will call back into genLoad and arrive at this case, which will then set ctx1.bb.ignore to true,
+ // this is okay, since we're jumping unconditionally, so the loads and jumps emitted by the outer
+ // call to genLoad (by calling genLoadLabelArguments and emitOnly) can safely be ignored,
+ // however, as emitOnly will close the block, which reverses its instructions (when it's still open),
+ // we better not reverse when the block has already been closed but is in ignore mode
+ // (if it's not in ignore mode, double-closing is an error)
val ctx1 = genLoadLabelArguments(args, label, ctx)
ctx1.bb.emitOnly(if (label.anchored) JUMP(label.block) else PJUMP(label))
ctx1.bb.enterIgnoreMode
@@ -937,11 +945,10 @@ abstract class GenICode extends SubComponent {
"Trying to access the this of another class: " +
"tree.symbol = " + tree.symbol + ", ctx.clazz.symbol = " + ctx.clazz.symbol + " compilation unit:"+unit)
if (tree.symbol.isModuleClass && tree.symbol != ctx.clazz.symbol) {
- debuglog("LOAD_MODULE from 'This': " + tree.symbol);
- assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- genLoadModule(ctx, tree.symbol, tree.pos)
+ genLoadModule(ctx, tree)
generatedType = REFERENCE(tree.symbol)
- } else {
+ }
+ else {
ctx.bb.emit(THIS(ctx.clazz.symbol), tree.pos)
generatedType = REFERENCE(
if (tree.symbol == ArrayClass) ObjectClass else ctx.clazz.symbol
@@ -954,11 +961,7 @@ abstract class GenICode extends SubComponent {
"Selection of non-module from empty package: " + tree +
" sym: " + tree.symbol + " at: " + (tree.pos)
)
- debuglog("LOAD_MODULE from Select(<emptypackage>): " + tree.symbol)
-
- assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- genLoadModule(ctx, tree.symbol, tree.pos)
- ctx
+ genLoadModule(ctx, tree)
case Select(qualifier, selector) =>
val sym = tree.symbol
@@ -966,14 +969,13 @@ abstract class GenICode extends SubComponent {
val hostClass = qualifier.tpe.typeSymbol.orElse(sym.owner)
if (sym.isModule) {
- debuglog("LOAD_MODULE from Select(qualifier, selector): " + sym)
- assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree)
- genLoadModule(ctx, sym, tree.pos)
- ctx
- } else if (sym.isStaticMember) {
+ genLoadModule(ctx, tree)
+ }
+ else if (sym.isStaticMember) {
ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos)
ctx
- } else {
+ }
+ else {
val ctx1 = genLoadQualifier(tree, ctx)
ctx1.bb.emit(LOAD_FIELD(sym, false) setHostClass hostClass, tree.pos)
ctx1
@@ -983,11 +985,10 @@ abstract class GenICode extends SubComponent {
val sym = tree.symbol
if (!sym.isPackage) {
if (sym.isModule) {
- debuglog("LOAD_MODULE from Ident(name): " + sym)
- assert(!sym.isPackageClass, "Cannot use package as value: " + tree)
- genLoadModule(ctx, sym, tree.pos)
+ genLoadModule(ctx, tree)
generatedType = toTypeKind(sym.info)
- } else {
+ }
+ else {
try {
val Some(l) = ctx.method.lookupLocal(sym)
ctx.bb.emit(LOAD_LOCAL(l), tree.pos)
@@ -1200,8 +1201,19 @@ abstract class GenICode extends SubComponent {
genLoad(arg, res, toTypeKind(tpe))
}
- private def genLoadModule(ctx: Context, sym: Symbol, pos: Position) {
- ctx.bb.emit(LOAD_MODULE(sym), pos)
+ private def genLoadModule(ctx: Context, tree: Tree): Context = {
+ // Working around SI-5604. Rather than failing the compile when we see
+ // a package here, check if there's a package object.
+ val sym = (
+ if (!tree.symbol.isPackageClass) tree.symbol
+ else tree.symbol.info.member(nme.PACKAGE) match {
+ case NoSymbol => assert(false, "Cannot use package as value: " + tree) ; NoSymbol
+ case s => Console.err.println("Bug: found package class where package object expected. Converting.") ; s.moduleClass
+ }
+ )
+ debuglog("LOAD_MODULE from %s: %s".format(tree.shortClass, sym))
+ ctx.bb.emit(LOAD_MODULE(sym), tree.pos)
+ ctx
}
def genConversion(from: TypeKind, to: TypeKind, ctx: Context, cast: Boolean) = {
@@ -1522,7 +1534,7 @@ abstract class GenICode extends SubComponent {
*/
def genEqEqPrimitive(l: Tree, r: Tree, ctx: Context)(thenCtx: Context, elseCtx: Context): Unit = {
def getTempLocal = ctx.method.lookupLocal(nme.EQEQ_LOCAL_VAR) getOrElse {
- ctx.makeLocal(l.pos, AnyRefClass.typeConstructor, nme.EQEQ_LOCAL_VAR)
+ ctx.makeLocal(l.pos, AnyRefClass.tpe, nme.EQEQ_LOCAL_VAR)
}
/** True if the equality comparison is between values that require the use of the rich equality
@@ -1560,9 +1572,10 @@ abstract class GenICode extends SubComponent {
val ctx1 = genLoad(l, ctx, ObjectReference)
val ctx2 = genLoad(r, ctx1, ObjectReference)
- ctx2.bb.emit(CALL_METHOD(equalsMethod, if (settings.optimise.value) Dynamic else Static(false)))
- ctx2.bb.emit(CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL))
- ctx2.bb.close
+ ctx2.bb.emitOnly(
+ CALL_METHOD(equalsMethod, if (settings.optimise.value) Dynamic else Static(false)),
+ CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL)
+ )
}
else {
if (isNull(l))
@@ -2212,7 +2225,7 @@ abstract class GenICode extends SubComponent {
* jumps to the given basic block.
*/
def patch(code: Code) {
- val map = toPatch map (i => (i -> patch(i))) toMap;
+ val map = mapFrom(toPatch)(patch)
code.blocks foreach (_ subst map)
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
index 36651541b2..71795a02aa 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
@@ -44,7 +44,7 @@ trait Members {
def blocksList: List[BasicBlock] = blocks.toList
def instructions = blocksList flatMap (_.iterator)
def blockCount = blocks.size
- def instructionCount = blocks map (_.length) sum
+ def instructionCount = (blocks map (_.length)).sum
def touched = _touched
def touched_=(b: Boolean): Unit = {
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index 2ff0c1926c..1ec2cf017a 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -44,7 +44,7 @@ trait TypeKinds { self: ICodes =>
}
/** Reverse map for toType */
private lazy val reversePrimitiveMap: Map[TypeKind, Symbol] =
- primitiveTypeMap map (_.swap) toMap
+ (primitiveTypeMap map (_.swap)).toMap
/** This class represents a type kind. Type kinds
* represent the types that the VM know (or the ICode
@@ -142,7 +142,7 @@ trait TypeKinds { self: ICodes =>
def lub0(tk1: TypeKind, tk2: TypeKind): Type = beforeUncurry {
import definitions._
val tp = global.lub(List(tk1.toType, tk2.toType))
- val (front, rest) = tp.parents span (_.typeSymbol.hasTraitFlag)
+ val (front, rest) = tp.parents span (_.typeSymbol.isTrait)
if (front.isEmpty || rest.isEmpty || rest.head.typeSymbol == ObjectClass) tp
else rest.head
@@ -420,7 +420,7 @@ trait TypeKinds { self: ICodes =>
// between "object PackratParsers$class" and "trait PackratParsers"
if (sym.isImplClass) {
// pos/spec-List.scala is the sole failure if we don't check for NoSymbol
- val traitSym = sym.owner.info.decl(nme.interfaceName(sym.name))
+ val traitSym = sym.owner.info.decl(tpnme.interfaceName(sym.name))
if (traitSym != NoSymbol)
return REFERENCE(traitSym)
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
index f5be82a776..4427da92c8 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
@@ -566,8 +566,8 @@ abstract class CopyPropagation {
method.blocks map { b =>
"\nIN(%s):\t Bindings: %s".format(b.label, in(b).bindings) +
"\nIN(%s):\t Stack: %s".format(b.label, in(b).stack)
- } mkString
- )
+ }
+ ).mkString
} /* class CopyAnalysis */
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
index 49f5b51d51..5f261ba05e 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
@@ -97,6 +97,6 @@ abstract class Liveness {
}
}
override def toString() =
- method.blocks map (b => "\nlive-in(%s)=%s\nlive-out(%s)=%s".format(b, in(b), b, out(b))) mkString
+ (method.blocks map (b => "\nlive-in(%s)=%s\nlive-out(%s)=%s".format(b, in(b), b, out(b)))).mkString
} /* Liveness analysis */
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
index c217869a48..0bc41b51bb 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
@@ -13,6 +13,7 @@ import scala.tools.nsc.util.ScalaClassLoader
import scala.tools.util.JavapClass
import java.util.jar.{ JarEntry, JarOutputStream, Attributes }
import Attributes.Name
+import language.postfixOps
/** For the last mile: turning generated bytecode in memory into
* something you can use. Has implementations for writing to class
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 4c77cb7082..f7898f2aa2 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -19,6 +19,7 @@ import JAccessFlags._
import JObjectType.{ JAVA_LANG_STRING, JAVA_LANG_OBJECT }
import java.util.jar.{ JarEntry, JarOutputStream }
import scala.tools.nsc.io.AbstractFile
+import language.postfixOps
/** This class ...
*
@@ -121,6 +122,9 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (settings.debug.value)
inform("[running phase " + name + " on icode]")
+ if (settings.Xverify.value && !SigParser.isParserAvailable)
+ global.warning("signature verification requested by signature parser unavailable: signatures not checked")
+
if (settings.Xdce.value)
for ((sym, cls) <- icodes.classes if inliner.isClosureClass(sym) && !deadCode.liveClosures(sym))
icodes.classes -= sym
@@ -285,6 +289,15 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val emitLines = debugLevel >= 2
val emitVars = debugLevel >= 3
+ // bug had phase with wrong name; leaving enabled for brief pseudo deprecation
+ private val checkSignatures = (
+ (settings.check containsName phaseName)
+ || (settings.check.value contains "genjvm") && {
+ global.warning("This option will be removed: please use -Ycheck:%s, not -Ycheck:genjvm." format phaseName)
+ true
+ }
+ )
+
/** For given symbol return a symbol corresponding to a class that should be declared as inner class.
*
* For example:
@@ -639,7 +652,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
case StringTag =>
buf put 's'.toByte
buf putShort cpool.addUtf8(const.stringValue).toShort
- case ClassTag =>
+ case ClazzTag =>
buf put 'c'.toByte
buf putShort cpool.addUtf8(javaType(const.typeValue).getSignature()).toShort
case EnumTag =>
@@ -726,10 +739,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
def addGenericSignature(jmember: JMember, sym: Symbol, owner: Symbol) {
if (needsGenericSignature(sym)) {
val memberTpe = beforeErasure(owner.thisType.memberInfo(sym))
- // println("addGenericSignature sym: " + sym.fullName + " : " + memberTpe + " sym.info: " + sym.info)
- // println("addGenericSignature: "+ (sym.ownerChain map (x => (x.name, x.isImplClass))))
+
erasure.javaSig(sym, memberTpe) foreach { sig =>
- debuglog("sig(" + jmember.getName + ", " + sym + ", " + owner + ") " + sig)
+ // This seems useful enough in the general case.
+ log(sig)
/** Since we're using a sun internal class for signature validation,
* we have to allow for it not existing or otherwise malfunctioning:
* in which case we treat every signature as valid. Medium term we
@@ -739,11 +752,11 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
clasz.cunit.warning(sym.pos,
"""|compiler bug: created invalid generic signature for %s in %s
|signature: %s
- |if this is reproducible, please report bug at http://lampsvn.epfl.ch/trac/scala
+ |if this is reproducible, please report bug at https://issues.scala-lang.org/
""".trim.stripMargin.format(sym, sym.owner.skipPackageObject.fullName, sig))
return
}
- if ((settings.check.value contains "genjvm")) {
+ if (checkSignatures) {
val normalizedTpe = beforeErasure(erasure.prepareSigMap(memberTpe))
val bytecodeTpe = owner.thisType.memberInfo(sym)
if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym)(normalizedTpe) =:= bytecodeTpe)) {
@@ -753,7 +766,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
|original type: %s
|normalized type: %s
|erasure type: %s
- |if this is reproducible, please report bug at http://lampsvn.epfl.ch/trac/scala
+ |if this is reproducible, please report bug at https://issues.scala-lang.org/
""".trim.stripMargin.format(sym, sym.owner.skipPackageObject.fullName, sig, memberTpe, normalizedTpe, bytecodeTpe))
return
}
@@ -871,7 +884,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
debuglog("Adding field: " + f.symbol.fullName)
val jfield = jclass.addNewField(
- javaFlags(f.symbol) | javaFieldFlags(f.symbol),
+ javaFieldFlags(f.symbol),
javaName(f.symbol),
javaType(f.symbol.tpe)
)
@@ -1010,7 +1023,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
serialVUID foreach { value =>
import Flags._, definitions._
val fieldName = "serialVersionUID"
- val fieldSymbol = clasz.symbol.newValue(newTermName(fieldName), NoPosition, STATIC | FINAL) setInfo longType
+ val fieldSymbol = clasz.symbol.newValue(newTermName(fieldName), NoPosition, STATIC | FINAL) setInfo LongClass.tpe
clasz addField new IField(fieldSymbol)
lastBlock emit CONSTANT(Constant(value))
lastBlock emit STORE_FIELD(fieldSymbol, true)
@@ -1269,7 +1282,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val jname = javaName(method)
val jtype = javaType(method).asInstanceOf[JMethodType]
- def debugMsg(invoke: String) {
+ def dbg(invoke: String) {
debuglog("%s %s %s.%s:%s".format(invoke, receiver.accessString, jowner, jname, jtype))
}
@@ -1287,14 +1300,14 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
style match {
- case Static(true) => jcode.emitINVOKESPECIAL (jowner, jname, jtype) ; debugMsg("invokespecial")
- case Static(false) => jcode.emitINVOKESTATIC (jowner, jname, jtype) ; debugMsg("invokestatic")
- case Dynamic if isInterfaceCall(receiver) => jcode.emitINVOKEINTERFACE(jowner, jname, jtype) ; debugMsg("invokinterface")
- case Dynamic => jcode.emitINVOKEVIRTUAL (jowner, jname, jtype) ; debugMsg("invokevirtual")
+ case Static(true) => dbg("invokespecial"); jcode.emitINVOKESPECIAL(jowner, jname, jtype)
+ case Static(false) => dbg("invokestatic"); jcode.emitINVOKESTATIC(jowner, jname, jtype)
+ case Dynamic if isInterfaceCall(receiver) => dbg("invokinterface"); jcode.emitINVOKEINTERFACE(jowner, jname, jtype)
+ case Dynamic => dbg("invokevirtual"); jcode.emitINVOKEVIRTUAL(jowner, jname, jtype)
case SuperCall(_) =>
+ dbg("invokespecial")
jcode.emitINVOKESPECIAL(jowner, jname, jtype)
initModule()
- debugMsg("invokespecial")
}
}
@@ -1915,16 +1928,30 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val privateFlag =
sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModule(sym.owner))
- // This does not check .isFinal (which checks flags for the FINAL flag),
- // instead checking rawflags for that flag so as to exclude symbols which
- // received lateFINAL. These symbols are eligible for inlining, but to
- // avoid breaking proxy software which depends on subclassing, we avoid
- // insisting on their finality in the bytecode.
+ // Final: the only fields which can receive ACC_FINAL are eager vals.
+ // Neither vars nor lazy vals can, because:
+ //
+ // Source: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3
+ // "Another problem is that the specification allows aggressive
+ // optimization of final fields. Within a thread, it is permissible to
+ // reorder reads of a final field with those modifications of a final
+ // field that do not take place in the constructor."
+ //
+ // A var or lazy val which is marked final still has meaning to the
+ // scala compiler. The word final is heavily overloaded unfortunately;
+ // for us it means "not overridable". At present you can't override
+ // vars regardless; this may change.
+ //
+ // The logic does not check .isFinal (which checks flags for the FINAL flag,
+ // and includes symbols marked lateFINAL) instead inspecting rawflags so
+ // we can exclude lateFINAL. Such symbols are eligible for inlining, but to
+ // avoid breaking proxy software which depends on subclassing, we do not
+ // emit ACC_FINAL.
val finalFlag = (
((sym.rawflags & (Flags.FINAL | Flags.MODULE)) != 0)
&& !sym.enclClass.isInterface
&& !sym.isClassConstructor
- && !sym.isMutable // fix for SI-3569, it is too broad?
+ && !sym.isMutable // lazy vals and vars both
)
mkFlags(
@@ -1939,13 +1966,13 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (sym.hasFlag(Flags.SYNCHRONIZED)) JAVA_ACC_SYNCHRONIZED else 0
)
}
- def javaFieldFlags(sym: Symbol) = {
- mkFlags(
+ def javaFieldFlags(sym: Symbol) = (
+ javaFlags(sym) | mkFlags(
if (sym hasAnnotation TransientAttr) ACC_TRANSIENT else 0,
if (sym hasAnnotation VolatileAttr) ACC_VOLATILE else 0,
if (sym.isMutable) 0 else ACC_FINAL
)
- }
+ )
def isTopLevelModule(sym: Symbol): Boolean =
afterPickler { sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass }
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
index b74981b999..807a3dd0bb 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
@@ -121,7 +121,7 @@ trait GenJVMUtil {
case DoubleTag => jcode emitPUSH const.doubleValue
case StringTag => jcode emitPUSH const.stringValue
case NullTag => jcode.emitACONST_NULL()
- case ClassTag =>
+ case ClazzTag =>
val kind = toTypeKind(const.typeValue)
val toPush =
if (kind.isValueType) classLiteral(kind)
diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
index 2fb615f893..66e7becb12 100644
--- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
+++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
@@ -15,6 +15,7 @@ import scala.tools.nsc.symtab._
import ch.epfl.lamp.compiler.msil.{Type => MsilType, _}
import ch.epfl.lamp.compiler.msil.emit._
import ch.epfl.lamp.compiler.msil.util.PECustomMod
+import language.postfixOps
abstract class GenMSIL extends SubComponent {
import global._
@@ -365,7 +366,7 @@ abstract class GenMSIL extends SubComponent {
arr.foreach(emitConst)
}
- // TODO: other Tags: NoTag, UnitTag, ClassTag, EnumTag, ArrayTag ???
+ // TODO: other Tags: NoTag, UnitTag, ClazzTag, EnumTag, ArrayTag ???
case _ => abort("could not handle attribute argument: " + const)
}
@@ -388,7 +389,7 @@ abstract class GenMSIL extends SubComponent {
case DoubleTag => buf.put(0x0d.toByte)
case StringTag => buf.put(0x0e.toByte)
- // TODO: other Tags: NoTag, UnitTag, ClassTag, EnumTag ???
+ // TODO: other Tags: NoTag, UnitTag, ClazzTag, EnumTag ???
// ArrayTag falls in here
case _ => abort("could not handle attribute argument: " + c)
@@ -968,7 +969,7 @@ abstract class GenMSIL extends SubComponent {
case DoubleTag => mcode.Emit(OpCodes.Ldc_R8, const.doubleValue)
case StringTag => mcode.Emit(OpCodes.Ldstr, const.stringValue)
case NullTag => mcode.Emit(OpCodes.Ldnull)
- case ClassTag =>
+ case ClazzTag =>
mcode.Emit(OpCodes.Ldtoken, msilType(const.typeValue))
mcode.Emit(OpCodes.Call, TYPE_FROM_HANDLE)
case _ => abort("Unknown constant value: " + const)
diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
index 95c371fa8b..d4ee9b6b48 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
@@ -82,7 +82,7 @@ abstract class DeadCodeElimination extends SubComponent {
mark
sweep(m)
accessedLocals = accessedLocals.distinct
- if (m.locals diff accessedLocals nonEmpty) {
+ if ((m.locals diff accessedLocals).nonEmpty) {
log("Removed dead locals: " + (m.locals diff accessedLocals))
m.locals = accessedLocals.reverse
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
index ec137203bf..0d47352215 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
@@ -360,7 +360,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
val caughtException = toTypeKind(caughtClass.tpe)
// copy the exception handler code once again, dropping the LOAD_EXCEPTION
val copy = handler.code.newBlock
- copy.emitOnly(handler.iterator drop dropCount toSeq: _*)
+ copy.emitOnly((handler.iterator drop dropCount).toSeq: _*)
// extend the handlers of the handler to the copy
for (parentHandler <- handler.method.exh ; if parentHandler covers handler) {
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index dfe9081ee5..05d8c632c0 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -135,7 +135,7 @@ abstract class Inliners extends SubComponent {
/** The current iclass */
private var currentIClazz: IClass = _
- private def warn(pos: Position, msg: String) = currentIClazz.cunit.warning(pos, msg)
+ private def warn(pos: Position, msg: String) = currentIClazz.cunit.inlinerWarning(pos, msg)
val recentTFAs = mutable.Map.empty[Symbol, Tuple2[Boolean, analysis.MethodTFA]]
private def getRecentTFA(incm: IMethod): (Boolean, analysis.MethodTFA) = {
@@ -759,12 +759,16 @@ abstract class Inliners extends SubComponent {
private def helperIsSafeToInline(stackLength: Int): Boolean = {
def makePublic(f: Symbol): Boolean =
- (inc.m.sourceFile ne NoSourceFile) && (f.isSynthetic || f.isParamAccessor) && {
- debuglog("Making not-private symbol out of synthetic: " + f)
+ /*
+ * Completely disabling member publifying. This shouldn't have been done in the first place. :|
+ */
+ false
+ // (inc.m.sourceFile ne NoSourceFile) && (f.isSynthetic || f.isParamAccessor) && {
+ // debuglog("Making not-private symbol out of synthetic: " + f)
- f setNotFlag Flags.PRIVATE
- true
- }
+ // f setNotFlag Flags.PRIVATE
+ // true
+ // }
if (!inc.m.hasCode || inc.isRecursive) { return false }
if (inc.m.symbol.hasFlag(Flags.SYNCHRONIZED)) { return false }
@@ -854,7 +858,7 @@ abstract class Inliners extends SubComponent {
def lookupIMethod(meth: Symbol, receiver: Symbol): Option[IMethod] = {
def tryParent(sym: Symbol) = icodes icode sym flatMap (_ lookupMethod meth)
- receiver.info.baseClasses.iterator map tryParent find (_.isDefined) flatten
+ (receiver.info.baseClasses.iterator map tryParent find (_.isDefined)).flatten
}
} /* class Inliner */
} /* class Inliners */
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
index 9a025b0d14..76a8b87ba7 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -8,7 +8,7 @@ package doc
import scala.util.control.ControlThrowable
import reporters.Reporter
-import util.NoPosition
+import util.{ NoPosition, BatchSourceFile}
import io.{ File, Directory }
import DocParser.Parsed
@@ -46,13 +46,19 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
override def forScaladoc = true
}
- /** Creates a scaladoc site for all symbols defined in this call's `files`,
- * as well as those defined in `files` of previous calls to the same processor.
+ /** Creates a scaladoc site for all symbols defined in this call's `source`,
+ * as well as those defined in `sources` of previous calls to the same processor.
* @param files The list of paths (relative to the compiler's source path,
* or absolute) of files to document. */
- def makeUniverse(files: List[String]): Option[Universe] = {
+ def makeUniverse(source: Either[List[String], String]): Option[Universe] = {
assert(settings.docformat.value == "html")
- new compiler.Run() compile files
+ source match {
+ case Left(files) =>
+ new compiler.Run() compile files
+ case Right(sourceCode) =>
+ new compiler.Run() compileSources List(new BatchSourceFile("newSource", sourceCode))
+ }
+
if (reporter.hasErrors)
return None
@@ -74,6 +80,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
val modelFactory = (
new { override val global: compiler.type = compiler }
with model.ModelFactory(compiler, settings)
+ with model.ModelFactoryImplicitSupport
with model.comment.CommentFactory
with model.TreeFactory {
override def templateShouldDocument(sym: compiler.Symbol) =
@@ -83,7 +90,8 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
modelFactory.makeModel match {
case Some(madeModel) =>
- println("model contains " + modelFactory.templatesCount + " documentable templates")
+ if (settings.reportModel)
+ println("model contains " + modelFactory.templatesCount + " documentable templates")
Some(madeModel)
case None =>
println("no documentable class found in compilation units")
@@ -111,7 +119,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
docletInstance match {
case universer: Universer =>
- val universe = makeUniverse(files) getOrElse { throw NoCompilerRunException }
+ val universe = makeUniverse(Left(files)) getOrElse { throw NoCompilerRunException }
universer setUniverse universe
docletInstance match {
diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala
index 6c74951156..d3a1d47de8 100644
--- a/src/compiler/scala/tools/nsc/doc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/doc/Settings.scala
@@ -8,6 +8,7 @@ package doc
import java.io.File
import java.lang.System
+import language.postfixOps
/** An extended version of compiler settings, with additional Scaladoc-specific options.
* @param error A function that prints a string to the appropriate error stream. */
@@ -87,6 +88,38 @@ class Settings(error: String => Unit) extends scala.tools.nsc.Settings(error) {
""
)
+ val docImplicits = BooleanSetting (
+ "-implicits",
+ "Document members inherited by implicit conversions."
+ )
+
+ val docImplicitsDebug = BooleanSetting (
+ "-implicits-debug",
+ "Show debugging information for members inherited by implicit conversions."
+ )
+
+ val docImplicitsShowAll = BooleanSetting (
+ "-implicits-show-all",
+ "Show members inherited by implicit conversions that are impossible in the default scope. " +
+ "(for example conversions that require Numeric[String] to be in scope)"
+ )
+
+ val docDiagrams = BooleanSetting (
+ "-diagrams",
+ "Create inheritance diagrams for classes, traits and packages."
+ )
+
+ val docDiagramsDebug = BooleanSetting (
+ "-diagrams-debug",
+ "Show debugging information for the diagram creation process."
+ )
+
+ val docDiagramsDotPath = PathSetting (
+ "-diagrams-dot-path",
+ "The path to the dot executable used to generate the inheritance diagrams. Ex: /usr/bin/dot",
+ "dot" // by default, just pick up the system-wide dot
+ )
+
// Somewhere slightly before r18708 scaladoc stopped building unless the
// self-type check was suppressed. I hijacked the slotted-for-removal-anyway
// suppress-vt-warnings option and renamed it for this purpose.
@@ -94,7 +127,105 @@ class Settings(error: String => Unit) extends scala.tools.nsc.Settings(error) {
// For improved help output.
def scaladocSpecific = Set[Settings#Setting](
- docformat, doctitle, docfooter, docversion, docUncompilable, docsourceurl, docgenerator
+ docformat, doctitle, docfooter, docversion, docUncompilable, docsourceurl, docgenerator, docRootContent, useStupidTypes,
+ docDiagrams, docDiagramsDebug, docDiagramsDotPath,
+ docImplicits, docImplicitsDebug, docImplicitsShowAll
)
val isScaladocSpecific: String => Boolean = scaladocSpecific map (_.name)
+
+ override def isScaladoc = true
+
+ // unset by the testsuite, we don't need to count the entities in the model
+ var reportModel = true
+
+ /**
+ * This is the hardcoded area of Scaladoc. This is where "undesirable" stuff gets eliminated. I know it's not pretty,
+ * but ultimately scaladoc has to be useful. :)
+ */
+ object hardcoded {
+
+ /** The common context bounds and some humanly explanations. Feel free to add more explanations
+ * `<root>.scala.package.Numeric` is the type class
+ * `tparam` is the name of the type parameter it gets (this only describes type classes with 1 type param)
+ * the function result should be a humanly-understandable description of the type class
+ */
+ val knownTypeClasses: Map[String, String => String] = Map() +
+ ("<root>.scala.package.Numeric" -> ((tparam: String) => tparam + " is a numeric class, such as Int, Long, Float or Double")) +
+ ("<root>.scala.package.Integral" -> ((tparam: String) => tparam + " is an integral numeric class, such as Int or Long")) +
+ ("<root>.scala.package.Fractional" -> ((tparam: String) => tparam + " is a fractional numeric class, such as Float or Double")) +
+ ("<root>.scala.reflect.Manifest" -> ((tparam: String) => tparam + " is accompanied by a Manifest, which is a runtime representation of its type that survives erasure")) +
+ ("<root>.scala.reflect.ClassManifest" -> ((tparam: String) => tparam + " is accompanied by a ClassManifest, which is a runtime representation of its type that survives erasure")) +
+ ("<root>.scala.reflect.OptManifest" -> ((tparam: String) => tparam + " is accompanied by an OptManifest, which can be either a runtime representation of its type or the NoManifest, which means the runtime type is not available")) +
+ ("<root>.scala.reflect.ClassTag" -> ((tparam: String) => tparam + " is accompanied by a ClassTag, which is a runtime representation of its type that survives erasure")) +
+ ("<root>.scala.reflect.TypeTag" -> ((tparam: String) => tparam + " is accompanied by a TypeTag, which is a runtime representation of its type that survives erasure")) +
+ ("<root>.scala.reflect.ConcreteTypeTag" -> ((tparam: String) => tparam + " is accompanied by an ConcreteTypeTag, which is a runtime representation of a concrete type that survives erasure"))
+
+ /**
+ * Set of classes to exclude from index and diagrams
+ * TODO: Should be configurable
+ */
+ def isExcluded(qname: String) = {
+ ( ( qname.startsWith("scala.Tuple") || qname.startsWith("scala.Product") ||
+ qname.startsWith("scala.Function") || qname.startsWith("scala.runtime.AbstractFunction")
+ ) && !(
+ qname == "scala.Tuple1" || qname == "scala.Tuple2" ||
+ qname == "scala.Product" || qname == "scala.Product1" || qname == "scala.Product2" ||
+ qname == "scala.Function" || qname == "scala.Function1" || qname == "scala.Function2" ||
+ qname == "scala.runtime.AbstractFunction0" || qname == "scala.runtime.AbstractFunction1" ||
+ qname == "scala.runtime.AbstractFunction2"
+ )
+ )
+ }
+
+ /** Common conversion targets that affect any class in Scala */
+ val commonConversionTargets = List(
+ "scala.Predef.any2stringfmt",
+ "scala.Predef.any2stringadd",
+ "scala.Predef.any2ArrowAssoc",
+ "scala.Predef.any2Ensuring")
+
+ /** There's a reason all these are specialized by hand but documenting each of them is beyond the point */
+ val arraySkipConversions = List(
+ "scala.Predef.refArrayOps",
+ "scala.Predef.intArrayOps",
+ "scala.Predef.doubleArrayOps",
+ "scala.Predef.longArrayOps",
+ "scala.Predef.floatArrayOps",
+ "scala.Predef.charArrayOps",
+ "scala.Predef.byteArrayOps",
+ "scala.Predef.shortArrayOps",
+ "scala.Predef.booleanArrayOps",
+ "scala.Predef.unitArrayOps",
+ "scala.LowPriorityImplicits.wrapRefArray",
+ "scala.LowPriorityImplicits.wrapIntArray",
+ "scala.LowPriorityImplicits.wrapDoubleArray",
+ "scala.LowPriorityImplicits.wrapLongArray",
+ "scala.LowPriorityImplicits.wrapFloatArray",
+ "scala.LowPriorityImplicits.wrapCharArray",
+ "scala.LowPriorityImplicits.wrapByteArray",
+ "scala.LowPriorityImplicits.wrapShortArray",
+ "scala.LowPriorityImplicits.wrapBooleanArray",
+ "scala.LowPriorityImplicits.wrapUnitArray",
+ "scala.LowPriorityImplicits.genericWrapArray")
+
+ // included as names as here we don't have access to a Global with Definitions :(
+ def valueClassList = List("unit", "boolean", "byte", "short", "char", "int", "long", "float", "double")
+ def valueClassFilterPrefixes = List("scala.LowPriorityImplicits", "scala.Predef")
+
+ /** Dirty, dirty, dirty hack: the value params conversions can all kick in -- and they are disambiguated by priority
+ * but showing priority in scaladoc would make no sense -- so we have to manually remove the conversions that we
+ * know will never get a chance to kick in. Anyway, DIRTY DIRTY DIRTY! */
+ def valueClassFilter(value: String, conversionName: String): Boolean = {
+ val valueName = value.toLowerCase
+ val otherValues = valueClassList.filterNot(_ == valueName)
+
+ for (prefix <- valueClassFilterPrefixes)
+ if (conversionName.startsWith(prefix))
+ for (otherValue <- otherValues)
+ if (conversionName.startsWith(prefix + "." + otherValue))
+ return false
+
+ true
+ }
+ }
}
diff --git a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala
index 9b29ebd745..8f426a443d 100644
--- a/src/compiler/scala/tools/nsc/doc/Uncompilable.scala
+++ b/src/compiler/scala/tools/nsc/doc/Uncompilable.scala
@@ -5,6 +5,8 @@
package scala.tools.nsc
package doc
+import language.implicitConversions
+import language.postfixOps
/** Some glue between DocParser (which reads source files which can't be compiled)
* and the scaladoc model.
@@ -14,7 +16,7 @@ trait Uncompilable {
val settings: Settings
import global.{ reporter, inform, warning, newTypeName, newTermName, Symbol, Name, DocComment, NoSymbol }
- import global.definitions.RootClass
+ import global.definitions.{ RootClass, AnyRefClass }
private implicit def translateName(name: Global#Name) =
if (name.isTypeName) newTypeName("" + name) else newTermName("" + name)
@@ -32,7 +34,7 @@ trait Uncompilable {
}
def files = settings.uncompilableFiles
def symbols = pairs map (_._1)
- def templates = symbols filter (x => x.isClass || x.isTrait) toSet
+ def templates = symbols filter (x => x.isClass || x.isTrait || x == AnyRefClass/* which is now a type alias */) toSet
def comments = {
if (settings.debug.value || settings.verbose.value)
inform("Found %d uncompilable files: %s".format(files.size, files mkString ", "))
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala
index 0116e02e0e..914824d523 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala
@@ -71,6 +71,7 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index) {
"signaturebg.gif",
"signaturebg2.gif",
"typebg.gif",
+ "conversionbg.gif",
"valuemembersbg.gif",
"navigation-li-a.png",
@@ -80,6 +81,8 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index) {
"selected.png",
"selected2-right.png",
"selected2.png",
+ "selected-right-implicits.png",
+ "selected-implicits.png",
"unselected.png"
)
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index 1544dafc69..e3da8bddea 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -23,7 +23,7 @@ abstract class HtmlPage extends Page { thisPage =>
protected def title: String
/** The page description */
- protected def description: String =
+ protected def description: String =
// unless overwritten, will display the title in a spaced format, keeping - and .
title.replaceAll("[^a-zA-Z0-9\\.\\-]+", " ").replaceAll("\\-+", " - ").replaceAll(" +", " ")
@@ -164,15 +164,15 @@ abstract class HtmlPage extends Page { thisPage =>
}
/** Returns the HTML code that represents the template in `tpl` as a hyperlinked name. */
- def templateToHtml(tpl: TemplateEntity) = tpl match {
+ def templateToHtml(tpl: TemplateEntity, name: String = null) = tpl match {
case dTpl: DocTemplateEntity =>
if (hasPage(dTpl)) {
- <a href={ relativeLinkTo(dTpl) } class="extype" name={ dTpl.qualifiedName }>{ dTpl.name }</a>
+ <a href={ relativeLinkTo(dTpl) } class="extype" name={ dTpl.qualifiedName }>{ if (name eq null) dTpl.name else name }</a>
} else {
- xml.Text(dTpl.name)
+ xml.Text(if (name eq null) dTpl.name else name)
}
case ndTpl: NoDocTemplate =>
- xml.Text(ndTpl.name)
+ xml.Text(if (name eq null) ndTpl.name else name)
}
/** Returns the HTML code that represents the templates in `tpls` as a list of hyperlinked names. */
@@ -192,6 +192,6 @@ abstract class HtmlPage extends Page { thisPage =>
else if (ety.isObject && !ety.companion.isEmpty && ety.companion.get.visibility.isPublic && ety.companion.get.inSource != None && ety.companion.get.isTrait) "object_to_trait_big.png"
else if (ety.isObject) "object_big.png"
else if (ety.isPackage) "package_big.png"
- else "class_big.png" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not
+ else "class_big.png" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala b/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala
index f67abc58da..3ff973ec66 100644
--- a/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/SyntaxHigh.scala
@@ -41,13 +41,13 @@ private[html] object SyntaxHigh {
/** Standard library classes/objects, sorted alphabetically */
val standards = Array (
"Any", "AnyRef", "AnyVal", "App", "Application", "Array",
- "Boolean", "Byte", "Char", "Class", "Console", "Double",
- "Enumeration", "Float", "Function", "Int",
+ "Boolean", "Byte", "Char", "Class", "ClassTag", "ClassManifest", "ConcreteTypeTag",
+ "Console", "Double", "Enumeration", "Float", "Function", "Int",
"List", "Long", "Manifest", "Map",
- "None", "Nothing", "Null", "Object", "Option",
+ "NoManifest", "None", "Nothing", "Null", "Object", "Option", "OptManifest",
"Pair", "Predef",
"Seq", "Set", "Short", "Some", "String", "Symbol",
- "Triple", "Unit")
+ "Triple", "TypeTag", "Unit")
def apply(data: String): NodeSeq = {
val buf = data.getBytes
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index bd5f98bab7..d3f42ffe6e 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -10,6 +10,7 @@ package page
import model._
import scala.xml.{ NodeSeq, Text, UnprefixedAttribute }
+import language.postfixOps
class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage {
@@ -35,7 +36,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</xml:group>
val valueMembers =
- tpl.methods.filterNot(_.isBridge) ++ tpl.values ++ tpl.templates.filter(x => x.isObject || x.isPackage) sorted
+ tpl.methods ++ tpl.values ++ tpl.templates.filter(x => x.isObject || x.isPackage) sorted
val (absValueMembers, nonAbsValueMembers) =
valueMembers partition (_.isAbstract)
@@ -88,21 +89,42 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
<div id="mbrsel">
<div id='textfilter'><span class='pre'/><span class='input'><input type='text' accesskey='/'/></span><span class='post'/></div>
- { if (tpl.linearizationTemplates.isEmpty) NodeSeq.Empty else
+ { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else
<div id="order">
<span class="filtertype">Ordering</span>
<ol><li class="alpha in"><span>Alphabetic</span></li><li class="inherit out"><span>By inheritance</span></li></ol>
</div>
}
- { if (tpl.linearizationTemplates.isEmpty) NodeSeq.Empty else
- <div id="ancestors">
- <span class="filtertype">Inherited</span>
- <ol><li class="hideall out"><span>Hide All</span></li>
- <li class="showall in"><span>Show all</span></li></ol>
- <ol id="linearization">{
- (tpl :: tpl.linearizationTemplates) map { wte => <li class="in" name={ wte.qualifiedName }><span>{ wte.name }</span></li> }
- }</ol>
- </div>
+ { if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else
+ {
+ if (!tpl.linearization.isEmpty)
+ <div id="ancestors">
+ <span class="filtertype">Inherited<br/>
+ </span>
+ <ol id="linearization">
+ { (tpl :: tpl.linearizationTemplates).map(wte => <li class="in" name={ wte.qualifiedName }><span>{ wte.name }</span></li>) }
+ </ol>
+ </div>
+ else NodeSeq.Empty
+ } ++ {
+ if (!tpl.conversions.isEmpty)
+ <div id="ancestors">
+ <span class="filtertype">Implicitly<br/>
+ </span>
+ <ol id="implicits">
+ { tpl.conversions.map(conv => <li class="in" name={ conv.conversionQualifiedName }><span>{ "by " + conv.conversionShortName }</span></li>) }
+ </ol>
+ </div>
+ else NodeSeq.Empty
+ } ++
+ <div id="ancestors">
+ <span class="filtertype"></span>
+ <ol>
+ <li class="hideall out"><span>Hide All</span></li>
+ <li class="showall in"><span>Show all</span></li>
+ </ol>
+ <a href="docs.scala-lang.org/overviews/scaladoc/usage.html#members" target="_blank">Learn more about member selection</a>
+ </div>
}
{
<div id="visbl">
@@ -152,23 +174,25 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
<div id="inheritedMembers">
{
+ // linearization
NodeSeq fromSeq (for ((superTpl, superType) <- (tpl.linearizationTemplates zip tpl.linearizationTypes)) yield
<div class="parent" name={ superTpl.qualifiedName }>
<h3>Inherited from {
- if (tpl.universe.settings.useStupidTypes.value)
- superTpl match {
- case dtpl: DocTemplateEntity =>
- val sig = signature(dtpl, false, true) \ "_"
- sig
- case tpl: TemplateEntity =>
- tpl.name
- }
- else
- typeToHtml(superType, true)
+ typeToHtmlWithStupidTypes(tpl, superTpl, superType)
}</h3>
</div>
)
}
+ {
+ // implicitly inherited
+ NodeSeq fromSeq (for (conversion <- (tpl.conversions)) yield
+ <div class="conversion" name={ conversion.conversionQualifiedName }>
+ <h3>Inherited by implicit conversion { conversion.conversionShortName } from
+ { typeToHtml(tpl.resultType, true) } to { typeToHtml(conversion.targetType, true) }
+ </h3>
+ </div>
+ )
+ }
</div>
</div>
@@ -219,11 +243,12 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
case d:MemberEntity with Def => defParamsToString(d)
case _ => ""
}
+ val memberComment = memberToCommentHtml(mbr, false)
<li name={ mbr.definitionName } visbl={ if (mbr.visibility.isProtected) "prt" else "pub" }
- data-isabs={ mbr.isAbstract.toString }>
+ data-isabs={ mbr.isAbstract.toString } fullComment={ if(memberComment.isEmpty) "no" else "yes" }>
<a id={ mbr.name +defParamsString +":"+ mbr.resultType.name}/>
{ signature(mbr, false) }
- { memberToCommentHtml(mbr, false) }
+ { memberComment }
</li>
}
@@ -275,6 +300,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
<p class="comment cmt">{ inlineToHtml(mbr.comment.get.short) }</p>
def memberToCommentBodyHtml(mbr: MemberEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = {
+
val memberComment =
if (mbr.comment.isEmpty) NodeSeq.Empty
else <div class="comment cmt">{ commentToHtml(mbr.comment) }</div>
@@ -326,6 +352,45 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
}
+ val implicitInformation = mbr.byConversion match {
+ case Some(conv) =>
+ <dt class="implicit">Implicit information</dt> ++
+ {
+ val targetType = typeToHtml(conv.targetType, true)
+ val conversionMethod = conv.convertorMethod match {
+ case Left(member) => Text(member.name)
+ case Right(name) => Text(name)
+ }
+
+ // strip off the package object endings, they make things harder to follow
+ val conversionOwnerQualifiedNane = conv.convertorOwner.qualifiedName.stripSuffix(".package")
+ val conversionOwner = templateToHtml(conv.convertorOwner, conversionOwnerQualifiedNane)
+
+ val constraintText = conv.constraints match {
+ case Nil =>
+ NodeSeq.Empty
+ case List(constraint) =>
+ xml.Text("This conversion will take place only if ") ++ constraintToHtml(constraint) ++ xml.Text(".")
+ case List(constraint1, constraint2) =>
+ xml.Text("This conversion will take place only if ") ++ constraintToHtml(constraint1) ++
+ xml.Text(" and at the same time ") ++ constraintToHtml(constraint2) ++ xml.Text(".")
+ case constraints =>
+ <br/> ++ "This conversion will take place only if all of the following constraints are met:" ++ <br/> ++ {
+ var index = 0
+ constraints map { constraint => xml.Text({ index += 1; index } + ". ") ++ constraintToHtml(constraint) ++ <br/> }
+ }
+ }
+
+ <dd>
+ This member is added by an implicit conversion from { typeToHtml(mbr.inTemplate.resultType, true) } to
+ { targetType } performed by method { conversionMethod } in { conversionOwner }.
+ { constraintText }
+ </dd>
+ }
+ case _ =>
+ NodeSeq.Empty
+ }
+
// --- start attributes block vals
val attributes: Seq[scala.xml.Node] = {
val fvs: List[comment.Paragraph] = visibility(mbr).toList
@@ -345,6 +410,17 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
}
+ val fullSignature: Seq[scala.xml.Node] = {
+ mbr match {
+ case nte: NonTemplateMemberEntity if nte.isUseCase =>
+ <div class="full-signature-block toggleContainer">
+ <span class="toggle">Full Signature</span>
+ <div class="hiddenContent full-signature-usecase">{ signature(nte.useCaseOf.get,true) }</div>
+ </div>
+ case _ => NodeSeq.Empty
+ }
+ }
+
val selfType: Seq[scala.xml.Node] = mbr match {
case dtpl: DocTemplateEntity if (isSelf && !dtpl.selfType.isEmpty && !isReduced) =>
<dt>Self Type</dt>
@@ -378,7 +454,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
case dtpl: DocTemplateEntity if (isSelf && dtpl.sourceUrl.isDefined && dtpl.inSource.isDefined && !isReduced) =>
val (absFile, line) = dtpl.inSource.get
<dt>Source</dt>
- <dd>{ <a href={ dtpl.sourceUrl.get.toString }>{ Text(absFile.file.getName) }</a> }</dd>
+ <dd>{ <a href={ dtpl.sourceUrl.get.toString } target="_blank">{ Text(absFile.file.getName) }</a> }</dd>
case _ => NodeSeq.Empty
}
@@ -466,7 +542,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
// end attributes block vals ---
- val attributesInfo = attributes ++ definitionClasses ++ selfType ++ annotations ++ deprecation ++ migration ++ sourceLink ++ mainComment
+ val attributesInfo = implicitInformation ++ attributes ++ definitionClasses ++ fullSignature ++ selfType ++ annotations ++ deprecation ++ migration ++ sourceLink ++ mainComment
val attributesBlock =
if (attributesInfo.isEmpty)
NodeSeq.Empty
@@ -550,12 +626,13 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</span>
<span class="symbol">
{
+ val nameClass = if (mbr.byConversion.isDefined) "implicit" else "name"
val nameHtml = {
val value = if (mbr.isConstructor) tpl.name else mbr.name
val span = if (mbr.deprecation.isDefined)
- <span class={"name deprecated"} title={"Deprecated: "+bodyToStr(mbr.deprecation.get)}>{ value }</span>
+ <span class={ nameClass + " deprecated"} title={"Deprecated: "+bodyToStr(mbr.deprecation.get)}>{ value }</span>
else
- <span class={"name"}>{ value }</span>
+ <span class={ nameClass }>{ value }</span>
val encoded = scala.reflect.NameTransformer.encode(value)
if (encoded != value) {
span % new UnprefixedAttribute("title",
@@ -754,4 +831,43 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
case _ => inl.toString
}
+ private def typeToHtmlWithStupidTypes(tpl: TemplateEntity, superTpl: TemplateEntity, superType: TypeEntity): NodeSeq =
+ if (tpl.universe.settings.useStupidTypes.value)
+ superTpl match {
+ case dtpl: DocTemplateEntity =>
+ val sig = signature(dtpl, false, true) \ "_"
+ sig
+ case tpl: TemplateEntity =>
+ Text(tpl.name)
+ }
+ else
+ typeToHtml(superType, true)
+
+ private def constraintToHtml(constraint: Constraint): NodeSeq = constraint match {
+ case ktcc: KnownTypeClassConstraint =>
+ xml.Text(ktcc.typeExplanation(ktcc.typeParamName) + " (" + ktcc.typeParamName + ": ") ++
+ templateToHtml(ktcc.typeClassEntity) ++ xml.Text(")")
+ case tcc: TypeClassConstraint =>
+ xml.Text(tcc.typeParamName + " is ") ++
+ <a href="http://stackoverflow.com/questions/2982276/what-is-a-context-bound-in-scala" target="_blank">
+ context-bounded</a> ++ xml.Text(" by " + tcc.typeClassEntity.qualifiedName + " (" + tcc.typeParamName + ": ") ++
+ templateToHtml(tcc.typeClassEntity) ++ xml.Text(")")
+ case impl: ImplicitInScopeConstraint =>
+ xml.Text("an implicit value of type ") ++ typeToHtml(impl.implicitType, true) ++ xml.Text(" is in scope")
+ case eq: EqualTypeParamConstraint =>
+ xml.Text(eq.typeParamName + " is " + eq.rhs.name + " (" + eq.typeParamName + " =:= ") ++
+ typeToHtml(eq.rhs, true) ++ xml.Text(")")
+ case bt: BoundedTypeParamConstraint =>
+ xml.Text(bt.typeParamName + " is a superclass of " + bt.lowerBound.name + " and a subclass of " +
+ bt.upperBound.name + " (" + bt.typeParamName + " >: ") ++
+ typeToHtml(bt.lowerBound, true) ++ xml.Text(" <: ") ++
+ typeToHtml(bt.upperBound, true) ++ xml.Text(")")
+ case lb: LowerBoundedTypeParamConstraint =>
+ xml.Text(lb.typeParamName + " is a superclass of " + lb.lowerBound.name + " (" + lb.typeParamName + " >: ") ++
+ typeToHtml(lb.lowerBound, true) ++ xml.Text(")")
+ case ub: UpperBoundedTypeParamConstraint =>
+ xml.Text(ub.typeParamName + " is a subclass of " + ub.upperBound.name + " (" + ub.typeParamName + " <: ") ++
+ typeToHtml(ub.upperBound, true) ++ xml.Text(")")
+ }
+
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif b/src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif
new file mode 100644
index 0000000000..4be145d0af
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/conversionbg.gif
Binary files differ
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png b/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png
new file mode 100644
index 0000000000..bc29efb3e6
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-implicits.png
Binary files differ
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png b/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png
new file mode 100644
index 0000000000..8313f4975b
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/selected-right-implicits.png
Binary files differ
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
index 4f552b7169..5a1779bba5 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
@@ -106,7 +106,7 @@ a[href]:hover {
font-size: 24pt;
text-shadow: black 0px 2px 0px;
/* text-shadow: black 0px 0px 0px;*/
-text-decoration: none;
+text-decoration: none;
}
#definition #owner {
@@ -162,7 +162,7 @@ text-decoration: none;
padding-left: 15px;
background: url("arrow-right.png") no-repeat 0 3px transparent;
}
-
+
.toggleContainer.open .toggle {
background: url("arrow-down.png") no-repeat 0 3px transparent;
}
@@ -205,6 +205,11 @@ dl.attributes > dt {
font-style: italic;
}
+dl.attributes > dt.implicit {
+ font-weight: bold;
+ color: darkgreen;
+}
+
dl.attributes > dd {
display: block;
padding-left: 10em;
@@ -241,6 +246,17 @@ dl.attributes > dd {
color: white;
}
+#inheritedMembers > div.conversion > h3 {
+ background: #dadada url("conversionbg.gif") repeat-x bottom left; /* gray */
+ height: 17px;
+ font-style: italic;
+ font-size: 12pt;
+}
+
+#inheritedMembers > div.conversion > h3 * {
+ color: white;
+}
+
/* Member cells */
div.members > ol {
@@ -310,10 +326,21 @@ div.members > ol > li:last-child {
font-weight: bold;
}
-.signature .symbol .params .implicit {
+.signature .symbol > .implicit {
+ display: inline-block;
+ font-weight: bold;
+ text-decoration: underline;
+ color: darkgreen;
+}
+
+.signature .symbol .params > .implicit {
font-style: italic;
}
+.signature .symbol .implicit.deprecated {
+ text-decoration: line-through;
+}
+
.signature .symbol .name.deprecated {
text-decoration: line-through;
}
@@ -340,20 +367,44 @@ div.members > ol > li:last-child {
color: darkgreen;
}
+.full-signature-usecase h4 span {
+ font-size: 10pt;
+}
+
+.full-signature-usecase > #signature {
+ padding-top: 0px;
+}
+
+#template .full-signature-usecase > .signature.closed {
+ background: none;
+}
+
+#template .full-signature-usecase > .signature.opened {
+ background: none;
+}
+
+.full-signature-block {
+ padding: 5px 0 0;
+ border-top: 1px solid #EBEBEB;
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
+
/* Comments text formating */
.cmt {}
.cmt p {
- margin: 0.7em 0;
+ margin: 0.7em 0;
}
.cmt p:first-child {
- margin-top: 0;
+ margin-top: 0;
}
.cmt p:last-child {
- margin-bottom: 0;
+ margin-bottom: 0;
}
.cmt h3,
@@ -515,7 +566,7 @@ div.fullcommenttop .block {
margin-bottom: 5px
}
-div.fullcomment div.block ol li p,
+div.fullcomment div.block ol li p,
div.fullcomment div.block ol li {
display:inline
}
@@ -559,10 +610,10 @@ div.fullcomment dl.paramcmts > dd {
/* Members filter tool */
#textfilter {
- position: relative;
- display: block;
+ position: relative;
+ display: block;
height: 20px;
- margin-bottom: 5px;
+ margin-bottom: 5px;
}
#textfilter > .pre {
@@ -576,7 +627,7 @@ div.fullcomment dl.paramcmts > dd {
}
#textfilter > .input {
- display: block;
+ display: block;
position: absolute;
top: 0;
right: 20px;
@@ -584,10 +635,10 @@ div.fullcomment dl.paramcmts > dd {
}
#textfilter > .input > input {
- height: 20px;
- padding: 1px;
- font-weight: bold;
- color: #000000;
+ height: 20px;
+ padding: 1px;
+ font-weight: bold;
+ color: #000000;
background: #ffffff url("filterboxbarbg.png") repeat-x top left;
width: 100%;
}
@@ -636,6 +687,13 @@ div.fullcomment dl.paramcmts > dd {
display: inline-block;
}
+#mbrsel > div > a {
+ position:relative;
+ top: -8px;
+ font-size: 11px;
+ text-shadow: #ffffff 0 1px 0;
+}
+
#mbrsel > div > ol#linearization {
display: table;
margin-left: 70px;
@@ -659,9 +717,32 @@ div.fullcomment dl.paramcmts > dd {
text-shadow: #ffffff 0 1px 0;
}
+#mbrsel > div > ol#implicits {
+ display: table;
+ margin-left: 70px;
+}
+
+#mbrsel > div > ol#implicits > li.in {
+ text-decoration: none;
+ float: left;
+ padding-right: 10px;
+ margin-right: 5px;
+ background: url(selected-right-implicits.png) no-repeat;
+ background-position: right 0px;
+}
+
+#mbrsel > div > ol#implicits > li.in > span{
+ color: #404040;
+ float: left;
+ padding: 1px 0 1px 10px;
+ background: url(selected-implicits.png) no-repeat;
+ background-position: 0px 0px;
+ text-shadow: #ffffff 0 1px 0;
+}
+
#mbrsel > div > ol > li {
/* padding: 3px 10px;*/
- line-height: 16pt;
+ line-height: 16pt;
display: inline-block;
cursor: pointer;
}
@@ -685,10 +766,10 @@ div.fullcomment dl.paramcmts > dd {
}
#mbrsel > div > ol > li.out {
- text-decoration: none;
- float: left;
- padding-right: 10px;
- margin-right: 5px;
+ text-decoration: none;
+ float: left;
+ padding-right: 10px;
+ margin-right: 5px;
}
#mbrsel > div > ol > li.out > span{
@@ -715,10 +796,10 @@ div.fullcomment dl.paramcmts > dd {
#mbrsel .showall {
color: #4C4C4C;
line-height: 16px;
- font-weight: bold;
+ font-weight: bold;
}
#mbrsel .showall span {
color: #4C4C4C;
- font-weight: bold;
+ font-weight: bold;
}*/ \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
index 3cdd9a7f27..fd5a981cb0 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
@@ -2,21 +2,23 @@
// code by Gilles Dubochet with contributions by Pedro Furlanetto
$(document).ready(function(){
- var isHiddenClass;
- if (document.title == 'scala.AnyRef') {
- isHiddenClass = function (name) {
- return name == 'scala.Any';
- };
- } else {
- isHiddenClass = function (name) {
- return name == 'scala.Any' || name == 'scala.AnyRef';
- };
- }
+ var isHiddenClass = function (name) {
+ return name == 'scala.Any' ||
+ name == 'scala.AnyRef' ||
+ name == 'scala.Predef.any2stringfmt' ||
+ name == 'scala.Predef.any2stringadd' ||
+ name == 'scala.Predef.any2ArrowAssoc' ||
+ name == 'scala.Predef.any2Ensuring'
+ };
+
+ $("#linearization li:gt(0)").filter(function(){
+ return isHiddenClass($(this).attr("name"));
+ }).removeClass("in").addClass("out");
- $("#linearization li").filter(function(){
+ $("#implicits li").filter(function(){
return isHiddenClass($(this).attr("name"));
}).removeClass("in").addClass("out");
-
+
// Pre-filter members
filter();
@@ -54,17 +56,38 @@ $(document).ready(function(){
};
filter();
});
- $("#ancestors > ol > li.hideall").click(function() {
+
+ $("#implicits li").click(function(){
+ if ($(this).hasClass("in")) {
+ $(this).removeClass("in");
+ $(this).addClass("out");
+ }
+ else if ($(this).hasClass("out")) {
+ $(this).removeClass("out");
+ $(this).addClass("in");
+ };
+ filter();
+ });
+
+ $("#mbrsel > div[id=ancestors] > ol > li.hideall").click(function() {
$("#linearization li.in").removeClass("in").addClass("out");
$("#linearization li:first").removeClass("out").addClass("in");
+ $("#implicits li.in").removeClass("in").addClass("out");
filter();
})
- $("#ancestors > ol > li.showall").click(function() {
- var filtered =
+ $("#mbrsel > div[id=ancestors] > ol > li.showall").click(function() {
+ var filteredLinearization =
$("#linearization li.out").filter(function() {
return ! isHiddenClass($(this).attr("name"));
});
- filtered.removeClass("out").addClass("in");
+ filteredLinearization.removeClass("out").addClass("in");
+
+ var filteredImplicits =
+ $("#implicits li.out").filter(function() {
+ return ! isHiddenClass($(this).attr("name"));
+ });
+ filteredImplicits.removeClass("out").addClass("in");
+
filter();
});
$("#visbl > ol > li.public").click(function() {
@@ -108,8 +131,10 @@ $(document).ready(function(){
});
/* Add toggle arrows */
- var docAllSigs = $("#template li").has(".fullcomment").find(".signature");
-
+ //var docAllSigs = $("#template li").has(".fullcomment").find(".signature");
+ // trying to speed things up a little bit
+ var docAllSigs = $("#template li[fullComment=yes] .signature");
+
function commentToggleFct(signature){
var parent = signature.parent();
var shortComment = $(".shortcomment", parent);
@@ -129,7 +154,7 @@ $(document).ready(function(){
docAllSigs.click(function() {
commentToggleFct($(this));
});
-
+
/* Linear super types and known subclasses */
function toggleShowContentFct(outerElement){
var content = $(".hiddenContent", outerElement);
@@ -148,20 +173,22 @@ $(document).ready(function(){
$(".toggleContainer").click(function() {
toggleShowContentFct($(this));
});
-
+
// Set parent window title
windowTitle();
});
function orderAlpha() {
$("#template > div.parent").hide();
- $("#ancestors").show();
+ $("#template > div.conversion").hide();
+ $("#mbrsel > div[id=ancestors]").show();
filter();
};
function orderInherit() {
$("#template > div.parent").show();
- $("#ancestors").hide();
+ $("#template > div.conversion").show();
+ $("#mbrsel > div[id=ancestors]").hide();
filter();
};
@@ -177,6 +204,9 @@ function initInherit() {
$("#inheritedMembers > div.parent").each(function(){
parents[$(this).attr("name")] = $(this);
});
+ $("#inheritedMembers > div.conversion").each(function(){
+ parents[$(this).attr("name")] = $(this);
+ });
$("#types > ol > li").each(function(){
var mbr = $(this);
this.mbrText = mbr.find("> .fullcomment .cmt").text();
@@ -216,6 +246,9 @@ function initInherit() {
$("#inheritedMembers > div.parent").each(function() {
if ($("> div.members", this).length == 0) { $(this).remove(); };
});
+ $("#inheritedMembers > div.conversion").each(function() {
+ if ($("> div.members", this).length == 0) { $(this).remove(); };
+ });
};
function filter(scrollToMember) {
@@ -224,13 +257,17 @@ function filter(scrollToMember) {
var queryRegExp = new RegExp(query, "i");
var privateMembersHidden = $("#visbl > ol > li.public").hasClass("in");
var orderingAlphabetic = $("#order > ol > li.alpha").hasClass("in");
- var hiddenSuperclassElements = orderingAlphabetic ? $("#linearization > li.out") : $("#linearization > li:gt(0)");
- var hiddenSuperclasses = hiddenSuperclassElements.map(function() {
+ var hiddenSuperclassElementsLinearization = orderingAlphabetic ? $("#linearization > li.out") : $("#linearization > li:gt(0)");
+ var hiddenSuperclassesLinearization = hiddenSuperclassElementsLinearization.map(function() {
+ return $(this).attr("name");
+ }).get();
+ var hiddenSuperclassElementsImplicits = orderingAlphabetic ? $("#implicits > li.out") : $("#implicits > li");
+ var hiddenSuperclassesImplicits = hiddenSuperclassElementsImplicits.map(function() {
return $(this).attr("name");
}).get();
var hideInheritedMembers;
-
+
if(orderingAlphabetic) {
$("#inheritedMembers").hide();
hideInheritedMembers = true;
@@ -242,9 +279,10 @@ function filter(scrollToMember) {
$("#allMembers > .members").each(filterFunc);
hideInheritedMembers = false;
$("#inheritedMembers > .parent > .members").each(filterFunc);
+ $("#inheritedMembers > .conversion > .members").each(filterFunc);
}
-
+
function filterFunc() {
var membersVisible = false;
var members = $(this);
@@ -262,12 +300,18 @@ function filter(scrollToMember) {
ownerIndex = name.lastIndexOf(".");
}
var owner = name.slice(0, ownerIndex);
- for (var i = 0; i < hiddenSuperclasses.length; i++) {
- if (hiddenSuperclasses[i] == owner) {
+ for (var i = 0; i < hiddenSuperclassesLinearization.length; i++) {
+ if (hiddenSuperclassesLinearization[i] == owner) {
mbr.hide();
return;
}
- }
+ };
+ for (var i = 0; i < hiddenSuperclassesImplicits.length; i++) {
+ if (hiddenSuperclassesImplicits[i] == owner) {
+ mbr.hide();
+ return;
+ }
+ };
}
if (query && !(queryRegExp.test(name) || queryRegExp.test(this.mbrText))) {
mbr.hide();
@@ -276,7 +320,7 @@ function filter(scrollToMember) {
mbr.show();
membersVisible = true;
});
-
+
if (membersVisible)
members.show();
else
diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
index 6eb14a4907..6488847049 100644
--- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
@@ -167,6 +167,8 @@ trait MemberEntity extends Entity {
/** Whether this member is abstract. */
def isAbstract: Boolean
+ /** If this member originates from an implicit conversion, we set the implicit information to the correct origin */
+ def byConversion: Option[ImplicitConversion]
}
object MemberEntity {
// Oh contravariance, contravariance, wherefore art thou contravariance?
@@ -246,6 +248,8 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
* other entity of the pair is the companion. */
def companion: Option[DocTemplateEntity]
+ /** The implicit conversions this template (class or trait, objects and packages are not affected) */
+ def conversions: List[ImplicitConversion]
}
@@ -413,3 +417,106 @@ trait Annotation extends Entity {
def arguments: List[ValueArgument]
}
+
+/** A trait that signals the member results from an implicit conversion */
+trait ImplicitConversion {
+
+ /** The source of the implicit conversion*/
+ def source: DocTemplateEntity
+
+ /** The result type after the conversion */
+ def targetType: TypeEntity
+
+ /** The entity for the method that performed the conversion, if it's documented (or just its name, otherwise) */
+ def convertorMethod: Either[MemberEntity, String]
+
+ /** A short name of the convertion */
+ def conversionShortName: String
+
+ /** A qualified name uniquely identifying the convertion (currently: the conversion method's qualified name) */
+ def conversionQualifiedName: String
+
+ /** The entity that performed the conversion */
+ def convertorOwner: TemplateEntity
+
+ /** The constraints that the transformations puts on the type parameters */
+ def constraints: List[Constraint]
+
+ /** The members inherited by this implicit conversion */
+ def members: List[MemberEntity]
+}
+
+/** A trait that encapsulates a constraint necessary for implicit conversion */
+trait Constraint {
+ // /** The implicit conversion during which this constraint appears */
+ // def conversion: ImplicitConversion
+}
+
+/** A constraint involving a type parameter which must be in scope */
+trait ImplicitInScopeConstraint extends Constraint {
+ /** The type of the implicit value required */
+ def implicitType: TypeEntity
+
+ /** toString for debugging */
+ override def toString = "an implicit _: " + implicitType.name + " must be in scope"
+}
+
+trait TypeClassConstraint extends ImplicitInScopeConstraint with TypeParamConstraint {
+ /** Type class name */
+ def typeClassEntity: TemplateEntity
+
+ /** toString for debugging */
+ override def toString = typeParamName + " is a class of type " + typeClassEntity.qualifiedName + " (" +
+ typeParamName + ": " + typeClassEntity.name + ")"
+}
+
+trait KnownTypeClassConstraint extends TypeClassConstraint {
+ /** Type explanation, takes the type parameter name and generates the explanation */
+ def typeExplanation: (String) => String
+
+ /** toString for debugging */
+ override def toString = typeExplanation(typeParamName) + " (" + typeParamName + ": " + typeClassEntity.name + ")"
+}
+
+/** A constraint involving a type parameter */
+trait TypeParamConstraint extends Constraint {
+ /** The type parameter involved */
+ def typeParamName: String
+}
+
+trait EqualTypeParamConstraint extends TypeParamConstraint {
+ /** The rhs */
+ def rhs: TypeEntity
+ /** toString for debugging */
+ override def toString = typeParamName + " is " + rhs.name + " (" + typeParamName + " =:= " + rhs.name + ")"
+}
+
+trait BoundedTypeParamConstraint extends TypeParamConstraint {
+ /** The lower bound */
+ def lowerBound: TypeEntity
+
+ /** The upper bound */
+ def upperBound: TypeEntity
+
+ /** toString for debugging */
+ override def toString = typeParamName + " is a superclass of " + lowerBound.name + " and a subclass of " +
+ upperBound.name + " (" + typeParamName + " >: " + lowerBound.name + " <: " + upperBound.name + ")"
+}
+
+trait LowerBoundedTypeParamConstraint extends TypeParamConstraint {
+ /** The lower bound */
+ def lowerBound: TypeEntity
+
+ /** toString for debugging */
+ override def toString = typeParamName + " is a superclass of " + lowerBound.name + " (" + typeParamName + " >: " +
+ lowerBound.name + ")"
+}
+
+trait UpperBoundedTypeParamConstraint extends TypeParamConstraint {
+ /** The lower bound */
+ def upperBound: TypeEntity
+
+ /** toString for debugging */
+ override def toString = typeParamName + " is a subclass of " + upperBound.name + " (" + typeParamName + " <: " +
+ upperBound.name + ")"
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
index ef3c2beffb..6392de22ff 100755
--- a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
@@ -8,6 +8,7 @@ package doc
package model
import scala.collection._
+import language.reflectiveCalls
object IndexModelFactory {
@@ -15,7 +16,7 @@ object IndexModelFactory {
lazy val firstLetterIndex: Map[Char, SymbolMap] = {
- val result = new mutable.HashMap[Char,SymbolMap] {
+ object result extends mutable.HashMap[Char,SymbolMap] {
/* Owner template ordering */
implicit def orderingSet = math.Ordering.String.on { x: MemberEntity => x.name.toLowerCase }
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 496d004fd8..a6728654cd 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -17,7 +17,7 @@ import model.{ RootPackage => RootPackageEntity }
/** This trait extracts all required information for documentation from compilation units */
class ModelFactory(val global: Global, val settings: doc.Settings) {
- thisFactory: ModelFactory with CommentFactory with TreeFactory =>
+ thisFactory: ModelFactory with ModelFactoryImplicitSupport with CommentFactory with TreeFactory =>
import global._
import definitions.{ ObjectClass, RootPackage, EmptyPackage, NothingClass, AnyClass, AnyValClass, AnyRefClass }
@@ -42,7 +42,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
memberSym.isOmittablePrefix || (closestPackage(memberSym) == closestPackage(templateSym))
}
- private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass)
+ private lazy val noSubclassCache = Set[Symbol](AnyClass, AnyRefClass, ObjectClass)
/** */
def makeModel: Option[Universe] = {
@@ -95,7 +95,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def isDocTemplate = false
}
- abstract class MemberImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity {
+ abstract class MemberImpl(sym: Symbol, implConv: ImplicitConversionImpl = null, inTpl: => DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity {
lazy val comment =
if (inTpl == null) None else thisFactory.comment(sym, inTpl)
override def inTemplate = inTpl
@@ -128,7 +128,14 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
if (sym.isImplicit) fgs += Paragraph(Text("implicit"))
if (sym.isSealed) fgs += Paragraph(Text("sealed"))
if (!sym.isTrait && (sym hasFlag Flags.ABSTRACT)) fgs += Paragraph(Text("abstract"))
- if (!sym.isTrait && (sym hasFlag Flags.DEFERRED)) fgs += Paragraph(Text("abstract"))
+ /* Resetting the DEFERRED flag is a little trick here for refined types: (example from scala.collections)
+ * {{{
+ * implicit def traversable2ops[T](t: collection.GenTraversableOnce[T]) = new TraversableOps[T] {
+ * def isParallel = ...
+ * }}}
+ * the type the method returns is TraversableOps, which has all-abstract symbols. But in reality, it couldn't have
+ * any abstract terms, otherwise it would fail compilation. So we reset the DEFERRED flag. */
+ if (!sym.isTrait && (sym hasFlag Flags.DEFERRED) && (implConv eq null)) fgs += Paragraph(Text("abstract"))
if (!sym.isModule && (sym hasFlag Flags.FINAL)) fgs += Paragraph(Text("final"))
fgs.toList
}
@@ -162,7 +169,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
case NullaryMethodType(res) => resultTpe(res)
case _ => tpe
}
- makeTypeInTemplateContext(resultTpe(sym.tpe), inTemplate, sym)
+ val tpe = if (implConv eq null) sym.tpe else implConv.toType memberInfo sym
+ makeTypeInTemplateContext(resultTpe(tpe), inTemplate, sym)
}
def isDef = false
def isVal = false
@@ -173,15 +181,17 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def isAliasType = false
def isAbstractType = false
def isAbstract =
- ((!sym.isTrait && ((sym hasFlag Flags.ABSTRACT) || (sym hasFlag Flags.DEFERRED))) ||
+ // for the explanation of implConv == null see comment on flags
+ ((!sym.isTrait && ((sym hasFlag Flags.ABSTRACT) || (sym hasFlag Flags.DEFERRED)) && (implConv == null)) ||
sym.isAbstractClass || sym.isAbstractType) && !sym.isSynthetic
def isTemplate = false
+ def byConversion = if (implConv ne null) Some(implConv) else None
}
/** The instantiation of `TemplateImpl` triggers the creation of the following entities:
* All ancestors of the template and all non-package members.
*/
- abstract class DocTemplateImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends MemberImpl(sym, inTpl) with TemplateImpl with HigherKindedImpl with DocTemplateEntity {
+ abstract class DocTemplateImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends MemberImpl(sym, null, inTpl) with TemplateImpl with HigherKindedImpl with DocTemplateEntity {
//if (inTpl != null) println("mbr " + sym + " in " + (inTpl.toRoot map (_.sym)).mkString(" > "))
if (settings.verbose.value)
inform("Creating doc template for " + sym)
@@ -245,16 +255,20 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
def subClasses = if (subClassesCache == null) Nil else subClassesCache.toList
- protected lazy val memberSyms =
+ val conversions = if (settings.docImplicits.value) makeImplicitConversions(sym, this) else Nil
+
+ lazy val memberSyms =
// Only this class's constructors are part of its members, inherited constructors are not.
- sym.info.members.filter(s => localShouldDocument(s) && (!s.isConstructor || s.owner == sym))
-
- val members = memberSyms flatMap (makeMember(_, this))
- val templates = members collect { case c: DocTemplateEntity => c }
- val methods = members collect { case d: Def => d }
- val values = members collect { case v: Val => v }
- val abstractTypes = members collect { case t: AbstractType => t }
- val aliasTypes = members collect { case t: AliasType => t }
+ sym.info.members.filter(s => localShouldDocument(s) && (!s.isConstructor || s.owner == sym) && !isPureBridge(sym) )
+
+ val members = (memberSyms.flatMap(makeMember(_, null, this))) :::
+ (conversions.flatMap((_.members))) // also take in the members from implicit conversions
+
+ val templates = members collect { case c: DocTemplateEntity => c }
+ val methods = members collect { case d: Def => d }
+ val values = members collect { case v: Val => v }
+ val abstractTypes = members collect { case t: AbstractType => t }
+ val aliasTypes = members collect { case t: AliasType => t }
override def isTemplate = true
def isDocTemplate = true
def companion = sym.companionSymbol match {
@@ -273,18 +287,22 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
abstract class RootPackageImpl(sym: Symbol) extends PackageImpl(sym, null) with RootPackageEntity
- abstract class NonTemplateMemberImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends MemberImpl(sym, inTpl) with NonTemplateMemberEntity {
+ abstract class NonTemplateMemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl) extends MemberImpl(sym, implConv, inTpl) with NonTemplateMemberEntity {
override def qualifiedName = optimize(inTemplate.qualifiedName + "#" + name)
- lazy val definitionName = optimize(inDefinitionTemplates.head.qualifiedName + "#" + name)
+ lazy val definitionName =
+ if (implConv == null) optimize(inDefinitionTemplates.head.qualifiedName + "#" + name)
+ else optimize(implConv.conversionQualifiedName + "#" + name)
def isUseCase = sym.isSynthetic
def isBridge = sym.isBridge
}
- abstract class NonTemplateParamMemberImpl(sym: Symbol, inTpl: => DocTemplateImpl) extends NonTemplateMemberImpl(sym, inTpl) {
- def valueParams =
- sym.paramss map { ps => (ps.zipWithIndex) map { case (p, i) =>
+ abstract class NonTemplateParamMemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl) extends NonTemplateMemberImpl(sym, implConv, inTpl) {
+ def valueParams = {
+ val info = if (implConv eq null) sym.info else implConv.toType memberInfo sym
+ info.paramss map { ps => (ps.zipWithIndex) map { case (p, i) =>
if (p.nameString contains "$") makeValueParam(p, inTpl, optimize("arg" + i)) else makeValueParam(p, inTpl)
}}
+ }
}
abstract class ParameterImpl(sym: Symbol, inTpl: => TemplateImpl) extends EntityImpl(sym, inTpl) with ParameterEntity {
@@ -356,7 +374,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
override def qualifiedName = "_root_"
override def inheritedFrom = Nil
override def isRootPackage = true
- override protected lazy val memberSyms =
+ override lazy val memberSyms =
(bSym.info.members ++ EmptyPackage.info.members) filter { s =>
s != EmptyPackage && s != RootPackage
}
@@ -380,11 +398,13 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
else if (bSym.isPackage)
makeTemplate(bSym.owner) match {
case inPkg: PackageImpl => makePackage(bSym, inPkg) getOrElse (new NoDocTemplateImpl(bSym, inPkg))
+ case inNoDocTpl: NoDocTemplateImpl => new NoDocTemplateImpl(bSym, inNoDocTpl)
case _ => throw new Error("'" + bSym + "' must be in a package")
}
else if (templateShouldDocument(bSym))
makeTemplate(bSym.owner) match {
case inDTpl: DocTemplateImpl => makeDocTemplate(bSym, inDTpl)
+ case inNoDocTpl: NoDocTemplateImpl => new NoDocTemplateImpl(bSym, inNoDocTpl)
case _ => throw new Error("'" + bSym + "' must be in documentable template")
}
else
@@ -454,18 +474,19 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
/** */
- def makeMember(aSym: Symbol, inTpl: => DocTemplateImpl): List[MemberImpl] = {
+ // TODO: Should be able to override the type
+ def makeMember(aSym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl): List[MemberImpl] = {
def makeMember0(bSym: Symbol, _useCaseOf: Option[MemberImpl]): Option[MemberImpl] = {
if (bSym.isGetter && bSym.isLazy)
- Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
+ Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val {
override lazy val comment = // The analyser does not duplicate the lazy val's DocDef when it introduces its accessor.
thisFactory.comment(bSym.accessed, inTpl) // This hack should be removed after analyser is fixed.
override def isLazyVal = true
override def useCaseOf = _useCaseOf
})
else if (bSym.isGetter && bSym.accessed.isMutable)
- Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
+ Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val {
override def isVar = true
override def useCaseOf = _useCaseOf
})
@@ -474,43 +495,43 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
if (bSym == definitions.Object_synchronized) {
val cSymInfo = (bSym.info: @unchecked) match {
case PolyType(ts, MethodType(List(bp), mt)) =>
- val cp = bp.cloneSymbol.setInfo(appliedType(definitions.ByNameParamClass.typeConstructor, List(bp.info)))
+ val cp = bp.cloneSymbol.setInfo(definitions.byNameType(bp.info))
PolyType(ts, MethodType(List(cp), mt))
}
bSym.cloneSymbol.setInfo(cSymInfo)
}
else bSym
}
- Some(new NonTemplateParamMemberImpl(cSym, inTpl) with HigherKindedImpl with Def {
+ Some(new NonTemplateParamMemberImpl(cSym, implConv, inTpl) with HigherKindedImpl with Def {
override def isDef = true
override def useCaseOf = _useCaseOf
})
}
- else if (bSym.isConstructor)
- Some(new NonTemplateParamMemberImpl(bSym, inTpl) with Constructor {
+ else if (bSym.isConstructor && (implConv == null))
+ Some(new NonTemplateParamMemberImpl(bSym, implConv, inTpl) with Constructor {
override def isConstructor = true
def isPrimary = sym.isPrimaryConstructor
override def useCaseOf = _useCaseOf
})
else if (bSym.isGetter) // Scala field accessor or Java field
- Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
+ Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val {
override def isVal = true
override def useCaseOf = _useCaseOf
})
else if (bSym.isAbstractType)
- Some(new NonTemplateMemberImpl(bSym, inTpl) with TypeBoundsImpl with HigherKindedImpl with AbstractType {
+ Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with TypeBoundsImpl with HigherKindedImpl with AbstractType {
override def isAbstractType = true
override def useCaseOf = _useCaseOf
})
- else if (bSym.isAliasType)
- Some(new NonTemplateMemberImpl(bSym, inTpl) with HigherKindedImpl with AliasType {
+ else if (bSym.isAliasType && bSym != AnyRefClass)
+ Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with HigherKindedImpl with AliasType {
override def isAliasType = true
def alias = makeTypeInTemplateContext(sym.tpe.dealias, inTpl, sym)
override def useCaseOf = _useCaseOf
})
else if (bSym.isPackage)
inTpl match { case inPkg: PackageImpl => makePackage(bSym, inPkg) }
- else if ((bSym.isClass || bSym.isModule) && templateShouldDocument(bSym))
+ else if ((bSym.isClass || bSym.isModule || bSym == AnyRefClass) && templateShouldDocument(bSym))
Some(makeDocTemplate(bSym, inTpl))
else
None
@@ -520,16 +541,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
Nil
else {
val allSyms = useCases(aSym, inTpl.sym) map { case (bSym, bComment, bPos) =>
- docComments.put(bSym, DocComment(bComment, bPos)) // put the comment in the list, don't parse it yet, closes SI-4898
+ docComments.put(bSym, DocComment(bComment, bPos)) // put the comment in the list, don't parse it yet, closes SI-4898
bSym
}
val member = makeMember0(aSym, None)
- if (allSyms.isEmpty)
- member.toList
- else
- // Use cases replace the original definitions - SI-5054
- allSyms flatMap { makeMember0(_, member) }
+ if (allSyms.isEmpty)
+ member.toList
+ else
+ // Use cases replace the original definitions - SI-5054
+ allSyms flatMap { makeMember0(_, member) }
}
}
@@ -620,7 +641,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
case tp: TypeRef if definitions.isByNameParamType(tp) =>
nameBuffer append "⇒ "
appendType0(tp.args.head)
- case tp: TypeRef if definitions.isTupleTypeOrSubtype(tp) =>
+ case tp: TypeRef if definitions.isTupleType(tp) =>
val args = tp.normalize.typeArgs
nameBuffer append '('
appendTypes0(args, ", ")
@@ -639,9 +660,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
// nameBuffer append stripPrefixes.foldLeft(pre.prefixString)(_ stripPrefix _)
// }
val bSym = normalizeTemplate(aSym)
- if (bSym.isNonClassType)
+ if (bSym.isNonClassType) {
nameBuffer append bSym.decodedName
- else {
+ } else {
val tpl = makeTemplate(bSym)
val pos0 = nameBuffer.length
refBuffer += pos0 -> (tpl, tpl.name.length)
@@ -654,7 +675,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
/* Refined types */
case RefinedType(parents, defs) =>
- val ignoreParents = Set(AnyClass, ObjectClass)
+ val ignoreParents = Set[Symbol](AnyClass, ObjectClass)
val filtParents = parents filterNot (x => ignoreParents(x.typeSymbol)) match {
case Nil => parents
case ps => ps
@@ -674,9 +695,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
nameBuffer append '⇒'
appendType0(result)
/* Polymorphic types */
- case PolyType(tparams, result) => assert(tparams nonEmpty)
+ case PolyType(tparams, result) => assert(tparams.nonEmpty)
// throw new Error("Polymorphic type '" + tpe + "' cannot be printed as a type")
- def typeParamsToString(tps: List[Symbol]): String = if(tps isEmpty) "" else
+ def typeParamsToString(tps: List[Symbol]): String = if (tps.isEmpty) "" else
tps.map{tparam =>
tparam.varianceString + tparam.name + typeParamsToString(tparam.typeParams)
}.mkString("[", ", ", "]")
@@ -692,8 +713,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
def templateShouldDocument(aSym: Symbol): Boolean = {
- // TODO: document sourceless entities (e.g., Any, etc), based on a new Setting to be added
- (aSym.isPackageClass || (aSym.sourceFile != null)) && localShouldDocument(aSym) &&
+ // TODO: document sourceless entities (e.g., Any, etc), based on a new Setting to be added
+ (aSym.isPackageClass || (aSym.sourceFile != null)) && localShouldDocument(aSym) &&
( aSym.owner == NoSymbol || templateShouldDocument(aSym.owner) ) && !isEmptyJavaObject(aSym)
}
@@ -705,4 +726,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def localShouldDocument(aSym: Symbol): Boolean = {
!aSym.isPrivate && (aSym.isProtected || aSym.privateWithin == NoSymbol) && !aSym.isSynthetic
}
+
+ /** Filter '@bridge' methods only if *they don't override non-bridge methods*. See SI-5373 for details */
+ def isPureBridge(sym: Symbol) = sym.isBridge && sym.allOverriddenSymbols.forall(_.isBridge)
}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
new file mode 100644
index 0000000000..61f3670f5f
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
@@ -0,0 +1,520 @@
+/* NSC -- new Scala compiler -- Copyright 2007-2012 LAMP/EPFL
+ *
+ * This trait finds implicit conversions for a class in the default scope and creates scaladoc entries for each of them.
+ *
+ * @author Vlad Ureche
+ * @author Adriaan Moors
+ */
+
+package scala.tools.nsc
+package doc
+package model
+
+import comment._
+
+import scala.collection._
+import scala.util.matching.Regex
+
+import symtab.Flags
+import io._
+
+import model.{ RootPackage => RootPackageEntity }
+
+/**
+ * This trait finds implicit conversions for a class in the default scope and creates scaladoc entries for each of them.
+ *
+ * Let's take this as an example:
+ * {{{
+ * object Test {
+ * class A
+ *
+ * class B {
+ * def foo = 1
+ * }
+ *
+ * class C extends B {
+ * def bar = 2
+ * class implicit
+ * }
+ *
+ * D def conv(a: A) = new C
+ * }
+ * }}}
+ *
+ * Overview:
+ * - scaladoc-ing the above classes, `A` will get two more methods: foo and bar, over its default methods
+ * - the nested classes (specifically `D` above), abstract types, type aliases and constructor members are not added to
+ * `A` (see makeMember0 in ModelFactory, last 3 cases)
+ * - the members added by implicit conversion are always listed under the implicit conversion, not under the class they
+ * actually come from (`foo` will be listed as coming from the implicit conversion to `C` instead of `B`) - see
+ * `definitionName` in MemberImpl
+ *
+ * Internals:
+ * TODO: Give an overview here
+ */
+trait ModelFactoryImplicitSupport {
+ thisFactory: ModelFactory with CommentFactory with TreeFactory =>
+
+ import global._
+ import global.analyzer._
+ import global.definitions._
+ import settings.hardcoded
+
+ // debugging:
+ val DEBUG: Boolean = settings.docImplicitsDebug.value
+ val ERROR: Boolean = true // currently we show all errors
+ @inline final def debug(msg: => String) = if (DEBUG) println(msg)
+ @inline final def error(msg: => String) = if (ERROR) println(msg)
+
+ /** This is a flag that indicates whether to eliminate implicits that cannot be satisfied within the current scope.
+ * For example, if an implicit conversion requires that there is a Numeric[T] in scope:
+ * {{{
+ * class A[T]
+ * class B extends A[Int]
+ * class C extends A[String]
+ * implicit def pimpA[T: Numeric](a: A[T]): D
+ * }}}
+ * For B, no constraints are generated as Numeric[Int] is already in the default scope. On the other hand, for the
+ * conversion from C to D, depending on -implicits-show-all, the conversion can:
+ * - not be generated at all, since there's no Numeric[String] in scope (if ran without -implicits-show-all)
+ * - generated with a *weird* constraint, Numeric[String] as the user might add it by hand (if flag is enabled)
+ */
+ val implicitsShowAll: Boolean = settings.docImplicitsShowAll.value
+ class ImplicitNotFound(tpe: Type) extends Exception("No implicit of type " + tpe + " found in scope.")
+
+ /* ============== IMPLEMENTATION PROVIDING ENTITY TYPES ============== */
+
+ class ImplicitConversionImpl(
+ val sym: Symbol,
+ val convSym: Symbol,
+ val toType: Type,
+ val constrs: List[Constraint],
+ inTpl: => DocTemplateImpl)
+ extends ImplicitConversion {
+
+ def source: DocTemplateEntity = inTpl
+
+ def targetType: TypeEntity = makeType(toType, inTpl)
+
+ def convertorOwner: TemplateEntity =
+ if (convSym != NoSymbol)
+ makeTemplate(convSym.owner)
+ else {
+ error("Scaladoc implicits: Implicit conversion from " + sym.tpe + " to " + toType + " done by " + convSym + " = NoSymbol!")
+ makeRootPackage.get // surely the root package was created :)
+ }
+
+ def convertorMethod: Either[MemberEntity, String] = {
+ var convertor: MemberEntity = null
+
+ convertorOwner match {
+ case doc: DocTemplateImpl =>
+ val convertors = members.collect { case m: MemberImpl if m.sym == convSym => m }
+ if (convertors.length == 1)
+ convertor = convertors.head
+ case _ =>
+ }
+ if (convertor ne null)
+ Left(convertor)
+ else
+ Right(convSym.nameString)
+ }
+
+ def conversionShortName = convSym.nameString
+
+ def conversionQualifiedName = convertorOwner.qualifiedName + "." + convSym.nameString
+
+ lazy val constraints: List[Constraint] = constrs
+
+ val members: List[MemberEntity] = {
+ // Obtain the members inherited by the implicit conversion
+ var memberSyms = toType.members.filter(implicitShouldDocument(_))
+ val existingMembers = sym.info.members
+
+ // Debugging part :)
+ debug(sym.nameString + "\n" + "=" * sym.nameString.length())
+ debug(" * conversion " + convSym + " from " + sym.tpe + " to " + toType)
+
+ // Members inherited by implicit conversions cannot override actual members
+ memberSyms = memberSyms.filterNot((sym1: Symbol) =>
+ existingMembers.exists(sym2 => sym1.name == sym2.name &&
+ !isDistinguishableFrom(toType.memberInfo(sym1), sym.info.memberInfo(sym2))))
+
+ debug(" -> full type: " + toType)
+ if (constraints.length != 0) {
+ debug(" -> constraints: ")
+ constraints foreach { constr => debug(" - " + constr) }
+ }
+ debug(" -> members:")
+ memberSyms foreach (sym => debug(" - "+ sym.decodedName +" : " + sym.info))
+ debug("")
+
+ memberSyms.flatMap((makeMember(_, this, inTpl)))
+ }
+ }
+
+ /* ============== MAKER METHODS ============== */
+
+ /**
+ * Make the implicit conversion objects
+ *
+ * A word about the scope of the implicit conversions: currently we look at a very basic context composed of the
+ * default Scala imports (Predef._ for example) and the companion object of the current class, if one exists. In the
+ * future we might want to extend this to more complex scopes.
+ */
+ def makeImplicitConversions(sym: Symbol, inTpl: => DocTemplateImpl): List[ImplicitConversion] =
+ // Nothing and Null are somewhat special -- they can be transformed by any implicit conversion available in scope.
+ // But we don't want that, so we'll simply refuse to find implicit conversions on for Nothing and Null
+ if (!(sym.isClass || sym.isTrait || sym == AnyRefClass) || sym == NothingClass || sym == NullClass) Nil
+ else {
+ var context: global.analyzer.Context = global.analyzer.rootContext(NoCompilationUnit)
+
+ val results = global.analyzer.allViewsFrom(sym.tpe, context, sym.typeParams)
+ var conversions = results.flatMap(result => makeImplicitConversion(sym, result._1, result._2, context, inTpl))
+ conversions = conversions.filterNot(_.members.isEmpty)
+
+ // Filter out specialized conversions from array
+ if (sym == ArrayClass)
+ conversions = conversions.filterNot((conv: ImplicitConversion) =>
+ hardcoded.arraySkipConversions.contains(conv.conversionQualifiedName))
+
+ // Filter out non-sensical conversions from value types
+ if (isScalaValueType(sym.tpe))
+ conversions = conversions.filter((ic: ImplicitConversion) =>
+ hardcoded.valueClassFilter(sym.nameString, ic.conversionQualifiedName))
+
+ // Put the class-specific conversions in front
+ val (ownConversions, commonConversions) =
+ conversions.partition(conv => !hardcoded.commonConversionTargets.contains(conv.conversionQualifiedName))
+
+ ownConversions ::: commonConversions
+ }
+
+ /** makeImplicitConversion performs the heavier lifting to get the implicit listing:
+ * - for each possible conversion function (also called view)
+ * * figures out the final result of the view (to what is our class transformed?)
+ * * figures out the necessary constraints on the type parameters (such as T <: Int) and the context (such as Numeric[T])
+ * * lists all inherited members
+ *
+ * What? in details:
+ * - say we start from a class A[T1, T2, T3, T4]
+ * - we have an implicit function (view) in scope:
+ * def pimpA[T3 <: Long, T4](a: A[Int, Foo[Bar[X]], T3, T4])(implicit ev1: TypeTag[T4], ev2: Numeric[T4]): PimpedA
+ * - A is converted to PimpedA ONLY if a couple of constraints are satisfied:
+ * * T1 must be equal to Int
+ * * T2 must be equal to Foo[Bar[X]]
+ * * T3 must be upper bounded by Long
+ * * there must be evidence of Numeric[T4] and a TypeTag[T4] within scope
+ * - the final type is PimpedA and A therefore inherits a couple of members from pimpedA
+ *
+ * How?
+ * some notes:
+ * - Scala's type inference will want to solve all type parameters down to actual types, but we only want constraints
+ * to maintain generality
+ * - therefore, allViewsFrom wraps type parameters into "untouchable" type variables that only gather constraints,
+ * but are never solved down to a type
+ * - these must be reverted back to the type parameters and the constraints must be extracted and simplified (this is
+ * done by the uniteConstraints and boundedTParamsConstraints. Be sure to check them out
+ * - we also need to transform implicit parameters in the view's signature into constraints, such that Numeric[T4]
+ * appears as a constraint
+ */
+ def makeImplicitConversion(sym: Symbol, result: SearchResult, constrs: List[TypeConstraint], context: Context, inTpl: => DocTemplateImpl): List[ImplicitConversion] =
+ if (result.tree == EmptyTree) Nil
+ else {
+ // `result` will contain the type of the view (= implicit conversion method)
+ // the search introduces untouchable type variables, but we want to get back to type parameters
+ val viewFullType = result.tree.tpe
+ // set the previously implicit parameters to being explicit
+
+ val (viewSimplifiedType, viewImplicitTypes) = removeImplicitParameters(viewFullType)
+
+ // TODO: Isolate this corner case :) - Predef.<%< and put it in the testsuite
+ if (viewSimplifiedType.params.length != 1) {
+ // This is known to be caused by the `<%<` object in Predef:
+ // {{{
+ // sealed abstract class <%<[-From, +To] extends (From => To) with Serializable
+ // object <%< {
+ // implicit def conformsOrViewsAs[A <% B, B]: A <%< B = new (A <%< B) {def apply(x: A) = x}
+ // }
+ // }}}
+ // so we just won't generate an implicit conversion for implicit methods that only take implicit parameters
+ return Nil
+ }
+
+ // type the view application so we get the exact type of the result (not the formal type)
+ val viewTree = result.tree.setType(viewSimplifiedType)
+ val appliedTree = new ApplyImplicitView(viewTree, List(Ident("<argument>") setType viewTree.tpe.paramTypes.head))
+ val appliedTreeTyped: Tree = {
+ val newContext = context.makeImplicit(context.ambiguousErrors)
+ newContext.macrosEnabled = false // [Eugene] I assume you want macro signature, not macro expansion
+ val newTyper = global.analyzer.newTyper(newContext)
+ newTyper.silent(_.typed(appliedTree, global.analyzer.EXPRmode, WildcardType), false) match {
+
+ case global.analyzer.SilentResultValue(t: Tree) => t
+ case global.analyzer.SilentTypeError(err) =>
+ global.reporter.warning(sym.pos, err.toString)
+ return Nil
+ }
+ }
+
+ // now we have the final type:
+ val toType = wildcardToNothing(typeVarToOriginOrWildcard(appliedTreeTyped.tpe.finalResultType))
+
+ try {
+ // Transform bound constraints into scaladoc constraints
+ val implParamConstraints = makeImplicitConstraints(viewImplicitTypes, sym, context, inTpl)
+ val boundsConstraints = makeBoundedConstraints(sym.typeParams, constrs, inTpl)
+ // TODO: no substitution constraints appear in the library and compiler scaladoc. Maybe they can be removed?
+ val substConstraints = makeSubstitutionConstraints(result.subst, inTpl)
+ val constraints = implParamConstraints ::: boundsConstraints ::: substConstraints
+
+ List(new ImplicitConversionImpl(sym, result.tree.symbol, toType, constraints, inTpl))
+ } catch {
+ case i: ImplicitNotFound =>
+ //println(" Eliminating: " + toType)
+ Nil
+ }
+ }
+
+ def makeImplicitConstraints(types: List[Type], sym: Symbol, context: Context, inTpl: => DocTemplateImpl): List[Constraint] =
+ types.flatMap((tpe:Type) => {
+ // TODO: Before creating constraints, map typeVarToOriginOrWildcard on the implicitTypes
+ val implType = typeVarToOriginOrWildcard(tpe)
+ val qualifiedName = implType.typeSymbol.ownerChain.reverse.map(_.nameString).mkString(".")
+
+ var available: Option[Boolean] = None
+
+ // see: https://groups.google.com/forum/?hl=en&fromgroups#!topic/scala-internals/gm_fr0RKzC4
+ //
+ // println(implType + " => " + implType.isTrivial)
+ // var tpes: List[Type] = List(implType)
+ // while (!tpes.isEmpty) {
+ // val tpe = tpes.head
+ // tpes = tpes.tail
+ // tpe match {
+ // case TypeRef(pre, sym, args) =>
+ // tpes = pre :: args ::: tpes
+ // println(tpe + " => " + tpe.isTrivial)
+ // case _ =>
+ // println(tpe + " (of type" + tpe.getClass + ") => " + tpe.isTrivial)
+ // }
+ // }
+ // println("\n")
+
+ // look for type variables in the type. If there are none, we can decide if the implicit is there or not
+ if (implType.isTrivial) {
+ try {
+ context.flushBuffer() /* any errors here should not prevent future findings */
+ // TODO: Not sure this is the right thing to do -- seems similar to what scalac should be doing
+ val context2 = context.make(context.unit, context.tree, sym.owner, context.scope, context.imports)
+ val search = inferImplicit(EmptyTree, tpe, false, false, context2, false)
+ context.flushBuffer() /* any errors here should not prevent future findings */
+
+ available = Some(search.tree != EmptyTree)
+ } catch {
+ case _ =>
+ }
+ }
+
+ available match {
+ case Some(true) =>
+ Nil
+ case Some(false) if (!implicitsShowAll) =>
+ // if -implicits-show-all is not set, we get rid of impossible conversions (such as Numeric[String])
+ throw new ImplicitNotFound(implType)
+ case _ =>
+ val typeParamNames = sym.typeParams.map(_.name)
+
+ // TODO: This is maybe the worst hack I ever did - it's as dirty as hell, but it seems to work, so until I
+ // learn more about symbols, it'll have to do.
+ implType match {
+ case TypeRef(pre, sym, List(TypeRef(NoPrefix, targ, Nil))) if (typeParamNames contains targ.name) =>
+ hardcoded.knownTypeClasses.get(qualifiedName) match {
+ case Some(explanation) =>
+ List(new KnownTypeClassConstraint {
+ val typeParamName = targ.nameString
+ val typeExplanation = explanation
+ val typeClassEntity = makeTemplate(sym)
+ val implicitType: TypeEntity = makeType(implType, inTpl)
+ })
+ case None =>
+ List(new TypeClassConstraint {
+ val typeParamName = targ.nameString
+ val typeClassEntity = makeTemplate(sym)
+ val implicitType: TypeEntity = makeType(implType, inTpl)
+ })
+ }
+ case _ =>
+ List(new ImplicitInScopeConstraint{
+ val implicitType: TypeEntity = makeType(implType, inTpl)
+ })
+ }
+ }
+ })
+
+ def makeSubstitutionConstraints(subst: TreeTypeSubstituter, inTpl: => DocTemplateImpl): List[Constraint] =
+ (subst.from zip subst.to) map {
+ case (from, to) =>
+ new EqualTypeParamConstraint {
+ error("Scaladoc implicits: Unexpected type substitution constraint from: " + from + " to: " + to)
+ val typeParamName = from.toString
+ val rhs = makeType(to, inTpl)
+ }
+ }
+
+ def makeBoundedConstraints(tparams: List[Symbol], constrs: List[TypeConstraint], inTpl: => DocTemplateImpl): List[Constraint] =
+ (tparams zip constrs) flatMap {
+ case (tparam, constr) => {
+ uniteConstraints(constr) match {
+ case (loBounds, upBounds) => (loBounds filter (_ != NothingClass.tpe), upBounds filter (_ != AnyClass.tpe)) match {
+ case (Nil, Nil) =>
+ Nil
+ case (List(lo), List(up)) if (lo == up) =>
+ List(new EqualTypeParamConstraint {
+ val typeParamName = tparam.nameString
+ val rhs = makeType(lo, inTpl)
+ })
+ case (List(lo), List(up)) =>
+ List(new BoundedTypeParamConstraint {
+ val typeParamName = tparam.nameString
+ val lowerBound = makeType(lo, inTpl)
+ val upperBound = makeType(up, inTpl)
+ })
+ case (List(lo), Nil) =>
+ List(new LowerBoundedTypeParamConstraint {
+ val typeParamName = tparam.nameString
+ val lowerBound = makeType(lo, inTpl)
+ })
+ case (Nil, List(up)) =>
+ List(new UpperBoundedTypeParamConstraint {
+ val typeParamName = tparam.nameString
+ val upperBound = makeType(up, inTpl)
+ })
+ case other =>
+ // this is likely an error on the lub/glb side
+ error("Scaladoc implicits: Error computing lub/glb for: " + (tparam, constr) + ":\n" + other)
+ Nil
+ }
+ }
+ }
+ }
+
+ /**
+ * uniteConstraints takes a TypeConstraint instance and simplifies the constraints inside
+ *
+ * Normally TypeConstraint contains multiple lower and upper bounds, and we want to reduce this to a lower and an
+ * upper bound. Here are a couple of catches we need to be aware of:
+ * - before finding a view (implicit method in scope that maps class A[T1,T2,.. Tn] to something else) the type
+ * parameters are transformed into "untouchable" type variables so that type inference does not attempt to
+ * fully solve them down to a type but rather constrains them on both sides just enough for the view to be
+ * applicable -- now, we want to transform those type variables back to the original type parameters
+ * - some of the bounds fail type inference and therefore refer to Nothing => when performing unification (lub, glb)
+ * they start looking ugly => we (unsoundly) transform Nothing to WildcardType so we fool the unification algorithms
+ * into thinking there's nothing there
+ * - we don't want the wildcard types surviving the unification so we replace them back to Nothings
+ */
+ def uniteConstraints(constr: TypeConstraint): (List[Type], List[Type]) =
+ try {
+ (List(wildcardToNothing(lub(constr.loBounds map typeVarToOriginOrWildcard))),
+ List(wildcardToNothing(glb(constr.hiBounds map typeVarToOriginOrWildcard))))
+ } catch {
+ // does this actually ever happen? (probably when type vars occur in the bounds)
+ case x: Throwable => (constr.loBounds.distinct, constr.hiBounds.distinct)
+ }
+
+ /**
+ * Make implicits explicit - Not used curently
+ */
+ object implicitToExplicit extends TypeMap {
+ def apply(tp: Type): Type = mapOver(tp) match {
+ case MethodType(params, resultType) =>
+ MethodType(params.map(param => if (param.isImplicit) param.cloneSymbol.resetFlag(Flags.IMPLICIT) else param), resultType)
+ case other =>
+ other
+ }
+ }
+
+ /**
+ * removeImplicitParameters transforms implicit parameters from the view result type into constraints and
+ * returns the simplified type of the view
+ *
+ * for the example view:
+ * implicit def pimpMyClass[T](a: MyClass[T])(implicit ev: Numeric[T]): PimpedMyClass[T]
+ * the implicit view result type is:
+ * (a: MyClass[T])(implicit ev: Numeric[T]): PimpedMyClass[T]
+ * and the simplified type will be:
+ * MyClass[T] => PimpedMyClass[T]
+ */
+ def removeImplicitParameters(viewType: Type): (Type, List[Type]) = {
+
+ val params = viewType.paramss.flatten
+ val (normalParams, implParams) = params.partition(!_.isImplicit)
+ val simplifiedType = MethodType(normalParams, viewType.finalResultType)
+ val implicitTypes = implParams.map(_.tpe)
+
+ (simplifiedType, implicitTypes)
+ }
+
+ /**
+ * typeVarsToOriginOrWildcard transforms the "untouchable" type variables into either their origins (the original
+ * type parameters) or into wildcard types if nothing matches
+ */
+ object typeVarToOriginOrWildcard extends TypeMap {
+ def apply(tp: Type): Type = mapOver(tp) match {
+ case tv: TypeVar =>
+ if (tv.constr.inst.typeSymbol == NothingClass)
+ WildcardType
+ else
+ tv.origin //appliedType(tv.origin.typeConstructor, tv.typeArgs map this)
+ case other =>
+ if (other.typeSymbol == NothingClass)
+ WildcardType
+ else
+ other
+ }
+ }
+
+ /**
+ * wildcardToNothing transforms wildcard types back to Nothing
+ */
+ object wildcardToNothing extends TypeMap {
+ def apply(tp: Type): Type = mapOver(tp) match {
+ case WildcardType =>
+ NothingClass.tpe
+ case other =>
+ other
+ }
+ }
+
+ /** implicitShouldDocument decides whether a member inherited by implicit conversion should be documented */
+ def implicitShouldDocument(aSym: Symbol): Boolean = {
+ // We shouldn't document:
+ // - constructors
+ // - common methods (in Any, AnyRef, Object) as they are automatically removed
+ // - private and protected members (not accessible following an implicit conversion)
+ // - members starting with _ (usually reserved for internal stuff)
+ localShouldDocument(aSym) && (!aSym.isConstructor) && (aSym.owner != ObjectClass) &&
+ (aSym.owner != AnyClass) && (aSym.owner != AnyRefClass) &&
+ (!aSym.isProtected) && (!aSym.isPrivate) && (!aSym.name.startsWith("_")) &&
+ (aSym.isMethod || aSym.isGetter || aSym.isSetter) &&
+ (aSym.nameString != "getClass")
+ }
+
+ /* To put it very bluntly: checks if you can call implicitly added method with t1 when t2 is already there in the
+ * class. We suppose the name of the two members coincides
+ *
+ * The trick here is that the resultType does not matter - the condition for removal it that paramss have the same
+ * structure (A => B => C may not override (A, B) => C) and that all the types involved are
+ * of the implcit conversion's member are subtypes of the parent members' parameters */
+ def isDistinguishableFrom(t1: Type, t2: Type): Boolean =
+ if (t1.paramss.map(_.length) == t2.paramss.map(_.length)) {
+ for ((t1p, t2p) <- t1.paramss.flatten zip t2.paramss.flatten)
+ if (!isSubType(t1 memberInfo t1p, t2 memberInfo t2p))
+ return true // if on the corresponding parameter you give a type that is in t1 but not in t2
+ // example:
+ // def foo(a: Either[Int, Double]): Int = 3
+ // def foo(b: Left[T1]): Int = 6
+ // a.foo(Right(4.5d)) prints out 3 :)
+ false
+ } else true // the member structure is different foo(3, 5) vs foo(3)(5)
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala b/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala
index 988f2e0ba9..f948d53c8b 100755
--- a/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/TreeFactory.scala
@@ -52,7 +52,7 @@ trait TreeFactory { thisTreeFactory: ModelFactory with TreeFactory =>
if (asym.isSetter) asym = asym.getter(asym.owner)
makeTemplate(asym.owner) match {
case docTmpl: DocTemplateImpl =>
- val mbrs: List[MemberImpl] = makeMember(asym,docTmpl)
+ val mbrs: List[MemberImpl] = makeMember(asym, null, docTmpl)
mbrs foreach { mbr => refs += ((start, (mbr,end))) }
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index bc5cd4a958..e6bc76f676 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -13,6 +13,7 @@ import scala.collection._
import scala.util.matching.Regex
import scala.annotation.switch
import util.{NoPosition, Position}
+import language.postfixOps
/** The comment parser transforms raw comment strings into `Comment` objects.
* Call `parse` to run the parser. Note that the parser is stateless and
diff --git a/src/compiler/scala/tools/nsc/interactive/BuildManager.scala b/src/compiler/scala/tools/nsc/interactive/BuildManager.scala
index 2ef34cdd96..0f89236861 100644
--- a/src/compiler/scala/tools/nsc/interactive/BuildManager.scala
+++ b/src/compiler/scala/tools/nsc/interactive/BuildManager.scala
@@ -13,6 +13,7 @@ import util.FakePos
import dependencies._
import io.AbstractFile
+import language.implicitConversions
trait BuildManager {
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 166b38f503..ec73af4dca 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -19,6 +19,7 @@ import scala.tools.nsc.io.Pickler._
import scala.tools.nsc.typechecker.DivergentImplicit
import scala.annotation.tailrec
import symtab.Flags.{ACCESSOR, PARAMACCESSOR}
+import language.implicitConversions
/** The main class of the presentation compiler in an interactive environment such as an IDE
*/
@@ -434,6 +435,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
private def newRunnerThread(): Thread = {
threadId += 1
compileRunner = new PresentationCompilerThread(this, projectName)
+ compileRunner.setDaemon(true)
compileRunner.start()
compileRunner
}
@@ -529,6 +531,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
unit.defined.clear()
unit.synthetics.clear()
unit.toCheck.clear()
+ unit.checkedFeatures = Set()
unit.targetPos = NoPosition
unit.contexts.clear()
unit.problems.clear()
@@ -956,7 +959,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
if (ownerTpe.isErroneous) List()
else new ImplicitSearch(
tree, functionType(List(ownerTpe), AnyClass.tpe), isView = true,
- context.makeImplicit(reportAmbiguousErrors = false)).allImplicits
+ context0 = context.makeImplicit(reportAmbiguousErrors = false)).allImplicits
for (view <- applicableViews) {
val vtree = viewApply(view)
val vpre = stabilizedType(vtree)
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 88e3827403..72e5ee42ed 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -6,7 +6,7 @@ package scala.tools.nsc
package interactive
import ast.Trees
-import symtab.Positions
+import ast.Positions
import scala.tools.nsc.util.{SourceFile, Position, RangePosition, NoPosition, WorkScheduler}
import scala.collection.mutable.ListBuffer
diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
index 34a0a4abb6..e2dcc48709 100644
--- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
@@ -79,7 +79,7 @@ trait ScratchPadMaker { self: Global =>
addSandbox(stat)
} else {
val resName = nextRes()
- val dispResName = resName filter ('$' !=)
+ val dispResName = resName filter ('$' != _)
patches += Patch(stat.pos.start, "val " + resName + " = ")
addSandbox(stat)
toPrint += resultString(nameType(dispResName, stat.tpe), resName)
diff --git a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala
index 7be115e777..9dc2a8de10 100644
--- a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala
+++ b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala
@@ -55,6 +55,7 @@ abstract class InteractiveTest
with AskShutdown
with AskReload
with AskLoadedTyped
+ with AskType
with PresentationCompilerInstance
with CoreTestDefs
with InteractiveTestSettings { self =>
diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala
index 35d6723818..657ef23eed 100644
--- a/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala
+++ b/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala
@@ -101,13 +101,13 @@ trait AskTypeAt extends AskCommand {
trait AskType extends AskCommand {
import compiler.Tree
- private[tests] def askType(source: SourceFile, forceReload: Boolean)(implicit reporter: Reporter): Response[Tree] = {
+ protected def askType(source: SourceFile, forceReload: Boolean)(implicit reporter: Reporter): Response[Tree] = {
ask {
compiler.askType(source, forceReload, _)
}
}
- private[tests] def askType(sources: Seq[SourceFile], forceReload: Boolean)(implicit reporter: Reporter): Seq[Response[Tree]] = {
+ protected def askType(sources: Seq[SourceFile], forceReload: Boolean)(implicit reporter: Reporter): Seq[Response[Tree]] = {
for(source <- sources) yield
askType(source, forceReload)
}
diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala
index 40bbd3fa8e..9646ee1cf0 100644
--- a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala
+++ b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala
@@ -81,7 +81,7 @@ private[tests] trait CoreTestDefs
else {
reporter.println("\naskHyperlinkPos for `" + tree.symbol.name + "` at " + format(pos) + " " + pos.source.file.name)
val r = new Response[Position]
- // `tree.symbol.sourceFile` was discovered to be null when testing -Yvirtpatmat on the akka presentation test, where a position had shifted to point to `Int`
+ // `tree.symbol.sourceFile` was discovered to be null when testing using virtpatmat on the akka presentation test, where a position had shifted to point to `Int`
// askHyperlinkPos for `Int` at (73,19) pi.scala --> class Int in package scala has null sourceFile!
val treePath = if (tree.symbol.sourceFile ne null) tree.symbol.sourceFile.path else null
val treeName = if (tree.symbol.sourceFile ne null) tree.symbol.sourceFile.name else null
@@ -90,8 +90,9 @@ private[tests] trait CoreTestDefs
compiler.askLinkPos(tree.symbol, source, r)
r.get match {
case Left(pos) =>
+ val resolvedPos = if (tree.symbol.pos.isDefined) tree.symbol.pos else pos
withResponseDelimiter {
- reporter.println("[response] found askHyperlinkPos for `" + tree.symbol.name + "` at " + format(pos) + " " + tree.symbol.sourceFile.name)
+ reporter.println("[response] found askHyperlinkPos for `" + tree.symbol.name + "` at " + format(resolvedPos) + " " + tree.symbol.sourceFile.name)
}
case Right(ex) =>
ex.printStackTrace()
diff --git a/src/compiler/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala b/src/compiler/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala
index 33ef4a432d..2f47685757 100644
--- a/src/compiler/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala
@@ -6,8 +6,8 @@
package scala.tools.nsc
package interpreter
-class AbstractOrMissingHandler[T](onError: String => Unit, value: T) extends scala.runtime.AbstractPartialFunction[Throwable, T] {
- def _isDefinedAt(t: Throwable) = t match {
+class AbstractOrMissingHandler[T](onError: String => Unit, value: T) extends PartialFunction[Throwable, T] {
+ def isDefinedAt(t: Throwable) = t match {
case _: AbstractMethodError => true
case _: NoSuchMethodError => true
case _: MissingRequirementError => true
diff --git a/src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala
index 42a47896a2..453b106808 100644
--- a/src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/CodeHandlers.scala
@@ -17,9 +17,7 @@ import scala.util.control.ControlThrowable
trait CodeHandlers[T] {
self =>
- // Expressions are composed of operators and operands.
- def expr(code: String): T
-
+/*
// A declaration introduces names and assigns them types.
// It can form part of a class definition (§5.1) or of a refinement in a compound type (§3.2.7).
// (Ed: aka abstract members.)
@@ -34,6 +32,10 @@ trait CodeHandlers[T] {
// ‘val’ PatDef | ‘var’ VarDef | ‘def’ FunDef | ‘type’ {nl} TypeDef |
// [‘case’] ‘class’ ClassDef | [‘case’] ‘object’ ObjectDef | ‘trait’ TraitDef
def defn(code: String): T
+*/
+
+ // Expressions are composed of operators and operands.
+ def expr(code: String): T
// An import clause has the form import p.I where p is a stable identifier (§3.1) and I is an import expression.
def impt(code: String): T
@@ -52,9 +54,9 @@ trait CodeHandlers[T] {
case _: NoSuccess => Nil
}
+ // def decl(code: String) = try Some(self.decl(code)) catch handler
+ // def defn(code: String) = try Some(self.defn(code)) catch handler
def expr(code: String) = try Some(self.expr(code)) catch handler
- def decl(code: String) = try Some(self.decl(code)) catch handler
- def defn(code: String) = try Some(self.defn(code)) catch handler
def impt(code: String) = try Some(self.impt(code)) catch handler
def stmt(code: String) = try Some(self.stmt(code)) catch handler
def stmts(code: String) = try (self.stmts(code) map (x => Some(x))) catch handlerSeq
diff --git a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala
index 015dc2a7f1..808f549304 100644
--- a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala
@@ -15,7 +15,7 @@ trait CompletionOutput {
val global: Global
import global._
- import definitions.{ isTupleTypeOrSubtype, isFunctionType, isRepeatedParamType }
+ import definitions.{ isTupleType, isFunctionType, isRepeatedParamType }
/** Reducing fully qualified noise for some common packages.
*/
@@ -48,11 +48,11 @@ trait CompletionOutput {
def typeToString(tp: Type): String = relativize(
tp match {
- case x if isFunctionType(x) => functionString(x)
- case x if isTupleTypeOrSubtype(x) => tupleString(x)
- case x if isRepeatedParamType(x) => typeToString(x.typeArgs.head) + "*"
- case mt @ MethodType(_, _) => methodTypeToString(mt)
- case x => x.toString
+ case x if isFunctionType(x) => functionString(x)
+ case x if isTupleType(x) => tupleString(x)
+ case x if isRepeatedParamType(x) => typeToString(x.typeArgs.head) + "*"
+ case mt @ MethodType(_, _) => methodTypeToString(mt)
+ case x => x.toString
}
)
diff --git a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala
index 68c8f2fdb8..0cd918b6a5 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala
@@ -22,8 +22,7 @@ trait ExprTyper {
object codeParser extends { val global: repl.global.type = repl.global } with CodeHandlers[Tree] {
def applyRule[T](code: String, rule: UnitParser => T): T = {
reporter.reset()
- val unit = new CompilationUnit(new BatchSourceFile("<console>", code))
- val scanner = new UnitParser(unit)
+ val scanner = newUnitParser(code)
val result = rule(scanner)
if (!reporter.hasErrors)
@@ -33,23 +32,17 @@ trait ExprTyper {
}
def tokens(code: String) = {
reporter.reset()
- val unit = new CompilationUnit(new BatchSourceFile("<tokens>", code))
- val in = new UnitScanner(unit)
+ val in = newUnitScanner(code)
in.init()
-
new Tokenizer(in) tokenIterator
}
- def decl(code: String) = CodeHandlers.fail("todo")
- def defn(code: String) = CodeHandlers.fail("todo")
+ def defns(code: String) = stmts(code) collect { case x: DefTree => x }
def expr(code: String) = applyRule(code, _.expr())
def impt(code: String) = applyRule(code, _.importExpr())
def impts(code: String) = applyRule(code, _.importClause())
- def stmts(code: String) = applyRule(code, _.templateStatSeq(false)._2)
- def stmt(code: String) = stmts(code) match {
- case List(t) => t
- case xs => CodeHandlers.fail("Not a single statement: " + xs.mkString(", "))
- }
+ def stmts(code: String) = applyRule(code, _.templateStats())
+ def stmt(code: String) = stmts(code).last // guaranteed nonempty
}
/** Parse a line into a sequence of trees. Returns None if the input is incomplete. */
@@ -62,77 +55,69 @@ trait ExprTyper {
else Some(trees)
}
}
- def tokens(line: String) = beQuietDuring(codeParser.tokens(line))
+ // def parsesAsExpr(line: String) = {
+ // import codeParser._
+ // (opt expr line).isDefined
+ // }
- // TODO: integrate these into a CodeHandler[Type].
+ def symbolOfLine(code: String): Symbol = {
+ def asExpr(): Symbol = {
+ val name = freshInternalVarName()
+ // Typing it with a lazy val would give us the right type, but runs
+ // into compiler bugs with things like existentials, so we compile it
+ // behind a def and strip the NullaryMethodType which wraps the expr.
+ val line = "def " + name + " = {\n" + code + "\n}"
+
+ interpretSynthetic(line) match {
+ case IR.Success =>
+ val sym0 = symbolOfTerm(name)
+ // drop NullaryMethodType
+ val sym = sym0.cloneSymbol setInfo afterTyper(sym0.info.finalResultType)
+ if (sym.info.typeSymbol eq UnitClass) NoSymbol
+ else sym
+ case _ => NoSymbol
+ }
+ }
+ def asDefn(): Symbol = {
+ val old = repl.definedSymbolList.toSet
+
+ interpretSynthetic(code) match {
+ case IR.Success =>
+ repl.definedSymbolList filterNot old match {
+ case Nil => NoSymbol
+ case sym :: Nil => sym
+ case syms => NoSymbol.newOverloaded(NoPrefix, syms)
+ }
+ case _ => NoSymbol
+ }
+ }
+ beQuietDuring(asExpr()) orElse beQuietDuring(asDefn())
+ }
- // XXX literals.
- // 1) Identifiers defined in the repl.
- // 2) A path loadable via getModule.
- // 3) Try interpreting it as an expression.
private var typeOfExpressionDepth = 0
def typeOfExpression(expr: String, silent: Boolean = true): Type = {
- repltrace("typeOfExpression(" + expr + ")")
if (typeOfExpressionDepth > 2) {
repldbg("Terminating typeOfExpression recursion for expression: " + expr)
return NoType
}
-
- def asQualifiedImport: Type = {
- val name = expr.takeWhile(_ != '.')
- typeOfExpression(importedTermNamed(name).fullName + expr.drop(name.length), true)
- }
- def asModule: Type = getModuleIfDefined(expr).tpe
- def asExpr: Type = {
- val lhs = freshInternalVarName()
- val line = "lazy val " + lhs + " =\n" + expr
-
- interpret(line, true) match {
- case IR.Success => typeOfExpression(lhs, true)
- case _ => NoType
- }
- }
-
- def evaluate(): Type = {
- typeOfExpressionDepth += 1
- try typeOfTerm(expr) orElse asModule orElse asExpr orElse asQualifiedImport
- finally typeOfExpressionDepth -= 1
- }
-
+ typeOfExpressionDepth += 1
// Don't presently have a good way to suppress undesirable success output
// while letting errors through, so it is first trying it silently: if there
// is an error, and errors are desired, then it re-evaluates non-silently
// to induce the error message.
- beSilentDuring(evaluate()) orElse beSilentDuring(typeOfDeclaration(expr)) orElse {
- if (!silent)
- evaluate()
-
- NoType
+ try beSilentDuring(symbolOfLine(expr).tpe) match {
+ case NoType if !silent => symbolOfLine(expr).tpe // generate error
+ case tpe => tpe
}
+ finally typeOfExpressionDepth -= 1
}
- // Since people will be giving us ":t def foo = 5" even though that is not an
- // expression, we have a means of typing declarations too.
- private def typeOfDeclaration(code: String): Type = {
- repltrace("typeOfDeclaration(" + code + ")")
- val obname = freshInternalVarName()
- interpret("object " + obname + " {\n" + code + "\n}\n", true) match {
- case IR.Success =>
- val sym = symbolOfTerm(obname)
- if (sym == NoSymbol) NoType else {
- // TODO: bitmap$n is not marked synthetic.
- val decls = sym.tpe.decls.toList filterNot (x => x.isConstructor || x.isPrivate || (x.name.toString contains "$"))
- repltrace("decls: " + decls)
- if (decls.isEmpty) NoType
- else typeCleanser(sym, decls.last.name)
- }
- case _ =>
- NoType
- }
- }
+ def tokens(line: String) = beQuietDuring(codeParser.tokens(line))
+
+ // In the todo column
+ //
// def compileAndTypeExpr(expr: String): Option[Typer] = {
// class TyperRun extends Run {
// override def stopPhase(name: String) = name == "superaccessors"
// }
- // }
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index e1ea69842f..297d6ad1b9 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -23,6 +23,7 @@ import scala.reflect.NameTransformer._
import util.ScalaClassLoader
import ScalaClassLoader._
import scala.tools.util._
+import language.{implicitConversions, existentials}
/** The Scala interactive shell. It provides a read-eval-print loop
* around the Interpreter class.
@@ -48,12 +49,60 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
var settings: Settings = _
var intp: IMain = _
- override def echoCommandMessage(msg: String): Unit =
- intp.reporter.printMessage(msg)
+ /** Having inherited the difficult "var-ness" of the repl instance,
+ * I'm trying to work around it by moving operations into a class from
+ * which it will appear a stable prefix.
+ */
+ private def onIntp[T](f: IMain => T): T = f(intp)
+
+ class IMainOps[T <: IMain](val intp: T) {
+ import intp._
+ import global._
+
+ def printAfterTyper(msg: => String) =
+ intp.reporter printUntruncatedMessage afterTyper(msg)
+
+ /** Strip NullaryMethodType artifacts. */
+ private def replInfo(sym: Symbol) = {
+ sym.info match {
+ case NullaryMethodType(restpe) if sym.isAccessor => restpe
+ case info => info
+ }
+ }
+ def echoTypeStructure(sym: Symbol) =
+ printAfterTyper("" + deconstruct.show(replInfo(sym)))
+
+ def echoTypeSignature(sym: Symbol, verbose: Boolean) = {
+ if (verbose) ILoop.this.echo("// Type signature")
+ printAfterTyper("" + replInfo(sym))
+
+ if (verbose) {
+ ILoop.this.echo("\n// Internal Type structure")
+ echoTypeStructure(sym)
+ }
+ }
+ }
+ implicit def stabilizeIMain(intp: IMain) = new IMainOps[intp.type](intp)
+
+ /** TODO -
+ * -n normalize
+ * -l label with case class parameter names
+ * -c complete - leave nothing out
+ */
+ private def typeCommandInternal(expr: String, verbose: Boolean): Result = {
+ onIntp { intp =>
+ val sym = intp.symbolOfLine(expr)
+ if (sym.exists) intp.echoTypeSignature(sym, verbose)
+ else ""
+ }
+ }
+
+ override def echoCommandMessage(msg: String) {
+ intp.reporter printUntruncatedMessage msg
+ }
def isAsync = !settings.Yreplsync.value
lazy val power = new Power(intp, new StdReplVals(this))
- lazy val NoType = intp.global.NoType
// TODO
// object opt extends AestheticSettings
@@ -248,7 +297,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
// nullary("reset", "reset the interpreter, forgetting session values but retaining session types", replay),
shCommand,
nullary("silent", "disable/enable automatic printing of results", verbosity),
- cmd("type", "<expr>", "display the type of an expression without evaluating it", typeCommand),
+ cmd("type", "[-v] <expr>", "display the type of an expression without evaluating it", typeCommand),
nullary("warnings", "show the suppressed warnings from the most recent line which had any", warningsCommand)
)
@@ -321,10 +370,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
}
- private def implicitsCommand(line: String): Result = {
- val intp = ILoop.this.intp
+ private def implicitsCommand(line: String): Result = onIntp { intp =>
import intp._
- import global.{ Symbol, afterTyper }
+ import global._
def p(x: Any) = intp.reporter.printMessage("" + x)
@@ -435,14 +483,14 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
private lazy val javap = substituteAndLog[Javap]("javap", NoJavap)(newJavap())
// Still todo: modules.
- private def typeCommand(line: String): Result = {
- if (line.trim == "") ":type <expression>"
- else {
- val tp = intp.typeOfExpression(line, false)
- if (tp == NoType) "" // the error message was already printed
- else intp.global.afterTyper(tp.toString)
+ private def typeCommand(line0: String): Result = {
+ line0.trim match {
+ case "" => ":type [-v] <expression>"
+ case s if s startsWith "-v " => typeCommandInternal(s stripPrefix "-v " trim, true)
+ case s => typeCommandInternal(s, false)
}
}
+
private def warningsCommand(): Result = {
intp.lastWarnings foreach { case (pos, msg) => intp.reporter.warning(pos, msg) }
}
@@ -470,33 +518,34 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
private def wrapCommand(line: String): Result = {
def failMsg = "Argument to :wrap must be the name of a method with signature [T](=> T): T"
- val intp = ILoop.this.intp
- val g: intp.global.type = intp.global
- import g._
-
- words(line) match {
- case Nil =>
- intp.executionWrapper match {
- case "" => "No execution wrapper is set."
- case s => "Current execution wrapper: " + s
- }
- case "clear" :: Nil =>
- intp.executionWrapper match {
- case "" => "No execution wrapper is set."
- case s => intp.clearExecutionWrapper() ; "Cleared execution wrapper."
- }
- case wrapper :: Nil =>
- intp.typeOfExpression(wrapper) match {
- case PolyType(List(targ), MethodType(List(arg), restpe)) =>
- intp setExecutionWrapper intp.pathToTerm(wrapper)
- "Set wrapper to '" + wrapper + "'"
- case tp =>
- failMsg + (
- if (tp == g.NoType) "\nFound: <unknown>"
- else "\nFound: <unknown>"
- )
- }
- case _ => failMsg
+ onIntp { intp =>
+ import intp._
+ import global._
+
+ words(line) match {
+ case Nil =>
+ intp.executionWrapper match {
+ case "" => "No execution wrapper is set."
+ case s => "Current execution wrapper: " + s
+ }
+ case "clear" :: Nil =>
+ intp.executionWrapper match {
+ case "" => "No execution wrapper is set."
+ case s => intp.clearExecutionWrapper() ; "Cleared execution wrapper."
+ }
+ case wrapper :: Nil =>
+ intp.typeOfExpression(wrapper) match {
+ case PolyType(List(targ), MethodType(List(arg), restpe)) =>
+ intp setExecutionWrapper intp.pathToTerm(wrapper)
+ "Set wrapper to '" + wrapper + "'"
+ case tp =>
+ failMsg + (
+ if (tp == NoType) "\nFound: <unknown>"
+ else "\nFound: <unknown>"
+ )
+ }
+ case _ => failMsg
+ }
}
}
@@ -797,6 +846,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
})
}
+ def runCompletion =
+ try in.completion execute code map (intp bindSyntheticValue _)
+ catch { case ex: Exception => None }
+
/** Here we place ourselves between the user and the interpreter and examine
* the input they are ostensibly submitting. We intervene in several cases:
*
@@ -814,27 +867,28 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
else if (Completion.looksLikeInvocation(code) && intp.mostRecentVar != "") {
interpretStartingWith(intp.mostRecentVar + code)
}
- else {
- def runCompletion = in.completion execute code map (intp bindValue _)
- /** Due to my accidentally letting file completion execution sneak ahead
- * of actual parsing this now operates in such a way that the scala
- * interpretation always wins. However to avoid losing useful file
- * completion I let it fail and then check the others. So if you
- * type /tmp it will echo a failure and then give you a Directory object.
- * It's not pretty: maybe I'll implement the silence bits I need to avoid
- * echoing the failure.
- */
- if (intp isParseable code) {
- val (code, result) = reallyInterpret
- if (power != null && code == IR.Error)
- runCompletion
-
- result
- }
- else runCompletion match {
- case Some(_) => None // completion hit: avoid the latent error
- case _ => reallyInterpret._2 // trigger the latent error
- }
+ else if (code.trim startsWith "//") {
+ // line comment, do nothing
+ None
+ }
+ /** Due to my accidentally letting file completion execution sneak ahead
+ * of actual parsing this now operates in such a way that the scala
+ * interpretation always wins. However to avoid losing useful file
+ * completion I let it fail and then check the others. So if you
+ * type /tmp it will echo a failure and then give you a Directory object.
+ * It's not pretty: maybe I'll implement the silence bits I need to avoid
+ * echoing the failure.
+ */
+ else if (intp isParseable code) {
+ val (code, result) = reallyInterpret
+ if (power != null && code == IR.Error)
+ runCompletion
+
+ result
+ }
+ else runCompletion match {
+ case Some(_) => None // completion hit: avoid the latent error
+ case _ => reallyInterpret._2 // trigger the latent error
}
}
@@ -881,6 +935,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
case x => x
}
}
+ // Bind intp somewhere out of the regular namespace where
+ // we can get at it in generated code.
+ addThunk(intp.quietBind("$intp" -> intp))
loadFiles(settings)
// it is broken on startup; go ahead and exit
@@ -996,11 +1053,11 @@ object ILoop {
// provide the enclosing type T
// in order to set up the interpreter's classpath and parent class loader properly
- def breakIf[T: Manifest](assertion: => Boolean, args: NamedParam*): Unit =
+ def breakIf[T: ClassTag](assertion: => Boolean, args: NamedParam*): Unit =
if (assertion) break[T](args.toList)
// start a repl, binding supplied args
- def break[T: Manifest](args: List[NamedParam]): Unit = savingContextLoader {
+ def break[T: ClassTag](args: List[NamedParam]): Unit = savingContextLoader {
val msg = if (args.isEmpty) "" else " Binding " + args.size + " value%s.".format(
if (args.size == 1) "" else "s"
)
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala b/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala
index 2f02748e8f..6a9654732b 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala
@@ -100,7 +100,7 @@ trait ILoopInit {
withLock { while (!initIsComplete) initLoopCondition.await() }
}
// private def warningsThunks = List(
- // () => intp.bind("lastWarnings", "" + manifest[List[(Position, String)]], intp.lastWarnings _),
+ // () => intp.bind("lastWarnings", "" + typeTag[List[(Position, String)]], intp.lastWarnings _),
// )
protected def postInitThunks = List[Option[() => Unit]](
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 9a12bc1471..a9c2ce0d09 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -23,6 +23,8 @@ import scala.collection.{ mutable, immutable }
import scala.util.control.Exception.{ ultimately }
import IMain._
import java.util.concurrent.Future
+import typechecker.Analyzer
+import language.implicitConversions
/** directory to save .class files to */
private class ReplVirtualDirectory(out: JPrintWriter) extends VirtualDirectory("(memory)", None) {
@@ -93,6 +95,11 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
private var _lineManager: Line.Manager = null // logic for individual lines
private val _compiler: Global = newCompiler(settings, reporter) // our private compiler
+ private val nextReqId = {
+ var counter = 0
+ () => { counter += 1 ; counter }
+ }
+
def compilerClasspath: Seq[URL] = (
if (isInitializeComplete) global.classPath.asURLs
else new PathResolver(settings).result.asURLs // the compiler's classpath
@@ -133,7 +140,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
lazy val formatting: Formatting = new Formatting {
val prompt = Properties.shellPromptString
}
- lazy val reporter: ConsoleReporter = new ReplReporter(this)
+ lazy val reporter: ReplReporter = new ReplReporter(this)
import formatting._
import reporter.{ printMessage, withoutTruncating }
@@ -149,6 +156,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
}
catch AbstractOrMissingHandler()
}
+ private def tquoted(s: String) = "\"\"\"" + s + "\"\"\""
+
// argument is a thunk to execute after init is done
def initialize(postInitSignal: => Unit) {
synchronized {
@@ -187,8 +196,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
import global._
import definitions.{
- ScalaPackage, JavaLangPackage, PredefModule, RootClass,
- getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass
+ ScalaPackage, JavaLangPackage, RootClass,
+ getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass,
+ termMember, typeMember
}
private implicit def privateTreeOps(t: Tree): List[Tree] = {
@@ -197,8 +207,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
}).toList
}
- implicit def installReplTypeOps(tp: Type): ReplTypeOps = new ReplTypeOps(tp)
- class ReplTypeOps(tp: Type) {
+ implicit class ReplTypeOps(tp: Type) {
def orElse(other: => Type): Type = if (tp ne NoType) tp else other
def andAlso(fn: Type => Type): Type = if (tp eq NoType) tp else fn(tp)
}
@@ -220,6 +229,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
}
import naming._
+ object deconstruct extends {
+ val global: imain.global.type = imain.global
+ } with StructuredTypeStrings
+
// object dossiers extends {
// val intp: imain.type = imain
// } with Dossiers { }
@@ -269,11 +282,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
protected def createLineManager(classLoader: ClassLoader): Line.Manager = new Line.Manager(classLoader)
/** Instantiate a compiler. Overridable. */
- protected def newCompiler(settings: Settings, reporter: Reporter) = {
+ protected def newCompiler(settings: Settings, reporter: Reporter): ReplGlobal = {
settings.outputDirs setSingleOutput virtualDirectory
settings.exposeEmptyPackage.value = true
-
- Global(settings, reporter)
+ new Global(settings, reporter) with ReplGlobal
}
/** Parent classloader. Overridable. */
@@ -335,7 +347,14 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def getInterpreterClassLoader() = classLoader
// Set the current Java "context" class loader to this interpreter's class loader
- def setContextClassLoader() = classLoader.setAsContext()
+ def setContextClassLoader() = {
+ classLoader.setAsContext()
+
+ // this is risky, but it's our only possibility to make default reflexive mirror to work with REPL
+ // so far we have only used the default mirror to create a few tags for the compiler
+ // so it shouldn't be in conflict with our classloader, especially since it respects its parent
+ scala.reflect.mirror.classLoader = classLoader
+ }
/** Given a simple repl-defined name, returns the real name of
* the class representing it, e.g. for "Bippy" it may return
@@ -350,7 +369,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def flatName(id: String) = optFlatName(id) getOrElse id
def optFlatName(id: String) = requestForIdent(id) map (_ fullFlatName id)
- def allDefinedNames = definedNameMap.keys.toList sortBy (_.toString)
+ def allDefinedNames = definedNameMap.keys.toList.sorted
def pathToType(id: String): String = pathToName(newTypeName(id))
def pathToTerm(id: String): String = pathToName(newTermName(id))
def pathToName(name: Name): String = {
@@ -457,7 +476,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
/** Build a request from the user. `trees` is `line` after being parsed.
*/
- private def buildRequest(line: String, trees: List[Tree]): Request = new Request(line, trees)
+ private def buildRequest(line: String, trees: List[Tree]): Request = {
+ executingRequest = new Request(line, trees)
+ executingRequest
+ }
// rewriting "5 // foo" to "val x = { 5 // foo }" creates broken code because
// the close brace is commented out. Strip single-line comments.
@@ -505,7 +527,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
trees.last match {
case _:Assign => // we don't want to include assignments
case _:TermTree | _:Ident | _:Select => // ... but do want other unnamed terms.
- val varName = if (synthetic) freshInternalVarName() else ("" + freshUserTermName())
+ val varName = if (synthetic) freshInternalVarName() else freshUserVarName()
val rewrittenLine = (
// In theory this would come out the same without the 1-specific test, but
// it's a cushion against any more sneaky parse-tree position vs. code mismatches:
@@ -556,17 +578,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
Right(buildRequest(line, trees))
}
- def typeCleanser(sym: Symbol, memberName: Name): Type = {
- // the types are all =>T; remove the =>
- val tp1 = afterTyper(sym.info.nonPrivateDecl(memberName).tpe match {
- case NullaryMethodType(tp) => tp
- case tp => tp
- })
- // normalize non-public types so we don't see protected aliases like Self
- afterTyper(tp1 match {
- case TypeRef(_, sym, _) if !sym.isPublic => tp1.normalize
- case tp => tp
- })
+ // normalize non-public types so we don't see protected aliases like Self
+ def normalizeNonPublic(tp: Type) = tp match {
+ case TypeRef(_, sym, _) if sym.isAliasType && !sym.isPublic => tp.normalize
+ case _ => tp
}
/**
@@ -578,6 +593,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
* e.g. that there were no parse errors.
*/
def interpret(line: String): IR.Result = interpret(line, false)
+ def interpretSynthetic(line: String): IR.Result = interpret(line, true)
def interpret(line: String, synthetic: Boolean): IR.Result = {
def loadAndRunReq(req: Request) = {
val (result, succeeded) = req.loadAndRun
@@ -623,7 +639,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
* @param value the object value to bind to it
* @return an indication of whether the binding succeeded
*/
- def bind(name: String, boundType: String, value: Any): IR.Result = {
+ def bind(name: String, boundType: String, value: Any, modifiers: List[String] = Nil): IR.Result = {
val bindRep = new ReadEvalPrint()
val run = bindRep.compile("""
|object %s {
@@ -639,7 +655,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
IR.Error
case Right(_) =>
- val line = "val %s = %s.value".format(name, bindRep.evalPath)
+ val line = "%sval %s = %s.value".format(modifiers map (_ + " ") mkString, name, bindRep.evalPath)
repldbg("Interpreting: " + line)
interpret(line)
}
@@ -651,7 +667,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
result
}
def directBind(p: NamedParam): IR.Result = directBind(p.name, p.tpe, p.value)
- def directBind[T: Manifest](name: String, value: T): IR.Result = directBind((name, value))
+ def directBind[T: ClassTag](name: String, value: T): IR.Result = directBind((name, value))
def rebind(p: NamedParam): IR.Result = {
val name = p.name
@@ -667,11 +683,12 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
if (ids.isEmpty) IR.Success
else interpret("import " + ids.mkString(", "))
- def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p))
- def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
- def bind[T: Manifest](name: String, value: T): IR.Result = bind((name, value))
- def bindValue(x: Any): IR.Result = bindValue("" + freshUserTermName(), x)
- def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x)
+ def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p))
+ def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
+ def bind[T: TypeTag](name: String, value: T): IR.Result = bind((name, value))
+ def bindSyntheticValue(x: Any): IR.Result = bindValue(freshInternalVarName(), x)
+ def bindValue(x: Any): IR.Result = bindValue(freshUserVarName(), x)
+ def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x)
/** Reset this interpreter, forgetting all user-specified requests. */
def reset() {
@@ -790,9 +807,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
*/
def resolvePathToSymbol(accessPath: String): Symbol = {
val readRoot = getRequiredModule(readPath) // the outermost wrapper
- (accessPath split '.').foldLeft(readRoot) { (sym, name) =>
- if (name == "") sym else
- afterTyper(sym.info member newTermName(name))
+ (accessPath split '.').foldLeft(readRoot: Symbol) {
+ case (sym, "") => sym
+ case (sym, name) => afterTyper(termMember(sym, name))
}
}
/** We get a bunch of repeated warnings for reasons I haven't
@@ -816,7 +833,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
}
def lastWarnings: List[(Position, String)] = (
if (lastRun == null) Nil
- else removeDupWarnings(lastRun.deprecationWarnings.reverse) ++ lastRun.uncheckedWarnings.reverse
+ else removeDupWarnings(lastRun.allConditionalWarnings flatMap (_.warnings))
)
private var lastRun: Run = _
private def evalMethod(name: String) = evalClass.getMethods filter (_.getName == name) match {
@@ -824,7 +841,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
case xs => sys.error("Internal error: eval object " + evalClass + ", " + xs.mkString("\n", "\n", ""))
}
private def compileAndSaveRun(label: String, code: String) = {
- showCodeIfDebugging(packaged(code))
+ showCodeIfDebugging(code)
val (success, run) = compileSourcesKeepingRun(new BatchSourceFile(label, packaged(code)))
lastRun = run
success
@@ -834,6 +851,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
/** One line of code submitted by the user for interpretation */
// private
class Request(val line: String, val trees: List[Tree]) {
+ val reqId = nextReqId()
val lineRep = new ReadEvalPrint()
private var _originalLine: String = null
@@ -842,6 +860,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
/** handlers for each tree in this request */
val handlers: List[MemberHandler] = trees map (memberHandlers chooseHandler _)
+ def defHandlers = handlers collect { case x: MemberDefHandler => x }
/** all (public) names defined by these statements */
val definedNames = handlers flatMap (_.definedNames)
@@ -853,6 +872,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def termNames = handlers flatMap (_.definesTerm)
def typeNames = handlers flatMap (_.definesType)
def definedOrImported = handlers flatMap (_.definedOrImported)
+ def definedSymbolList = defHandlers flatMap (_.definedSymbols)
+
+ def definedTypeSymbol(name: String) = definedSymbols(newTypeName(name))
+ def definedTermSymbol(name: String) = definedSymbols(newTermName(name))
/** Code to import bound names from previous lines - accessPath is code to
* append to objectName to access anything bound by request.
@@ -882,10 +905,25 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
/** generate the source code for the object that computes this request */
private object ObjectSourceCode extends CodeAssembler[MemberHandler] {
+ def path = pathToTerm("$intp")
+ def envLines = {
+ if (!isReplPower) Nil // power mode only for now
+ // $intp is not bound; punt, but include the line.
+ else if (path == "$intp") List(
+ "def $line = " + tquoted(originalLine),
+ "def $trees = Nil"
+ )
+ else List(
+ "def $line = " + tquoted(originalLine),
+ "def $req = %s.requestForReqId(%s).orNull".format(path, reqId),
+ "def $trees = if ($req eq null) Nil else $req.trees".format(lineRep.readName, path, reqId)
+ )
+ }
+
val preamble = """
|object %s {
- |%s%s
- """.stripMargin.format(lineRep.readName, importsPreamble, indentCode(toCompute))
+ |%s%s%s
+ """.stripMargin.format(lineRep.readName, envLines.map(" " + _ + ";\n").mkString, importsPreamble, indentCode(toCompute))
val postamble = importsTrailer + "\n}"
val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this
}
@@ -943,6 +981,16 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
typeOf
typesOfDefinedTerms
+ // Assign symbols to the original trees
+ // TODO - just use the new trees.
+ defHandlers foreach { dh =>
+ val name = dh.member.name
+ definedSymbols get name foreach { sym =>
+ dh.member setSymbol sym
+ repldbg("Set symbol of " + name + " to " + sym.defString)
+ }
+ }
+
// compile the result-extraction object
beQuietDuring {
savingSettings(_.nowarn.value = true) {
@@ -959,24 +1007,23 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def lookupTypeOf(name: Name) = typeOf.getOrElse(name, typeOf(global.encode(name.toString)))
def simpleNameOfType(name: TypeName) = (compilerTypeOf get name) map (_.typeSymbol.simpleName)
- private def typeMap[T](f: Type => T): Map[Name, T] =
- termNames ++ typeNames map (x => x -> f(typeCleanser(resultSymbol, x))) toMap
+ private def typeMap[T](f: Type => T) =
+ mapFrom[Name, Name, T](termNames ++ typeNames)(x => f(cleanMemberDecl(resultSymbol, x)))
/** Types of variables defined by this request. */
- lazy val compilerTypeOf = typeMap[Type](x => x)
+ lazy val compilerTypeOf = typeMap[Type](x => x) withDefaultValue NoType
/** String representations of same. */
lazy val typeOf = typeMap[String](tp => afterTyper(tp.toString))
// lazy val definedTypes: Map[Name, Type] = {
// typeNames map (x => x -> afterTyper(resultSymbol.info.nonPrivateDecl(x).tpe)) toMap
// }
- lazy val definedSymbols: Map[Name, Symbol] = (
+ lazy val definedSymbols = (
termNames.map(x => x -> applyToResultMember(x, x => x)) ++
- typeNames.map(x => x -> compilerTypeOf.get(x).map(_.typeSymbol).getOrElse(NoSymbol))
- ).toMap
+ typeNames.map(x => x -> compilerTypeOf(x).typeSymbol)
+ ).toMap[Name, Symbol] withDefaultValue NoSymbol
- lazy val typesOfDefinedTerms: Map[Name, Type] =
- termNames map (x => x -> applyToResultMember(x, _.tpe)) toMap
+ lazy val typesOfDefinedTerms = mapFrom[Name, Name, Type](termNames)(x => applyToResultMember(x, _.tpe))
/** load and run the code using reflection */
def loadAndRun: (String, Boolean) = {
@@ -1023,6 +1070,13 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
getOrElse Nil
)
+ def treesForRequestId(id: Int): List[Tree] =
+ requestForReqId(id).toList flatMap (_.trees)
+
+ def requestForReqId(id: Int): Option[Request] =
+ if (executingRequest != null && executingRequest.reqId == id) Some(executingRequest)
+ else prevRequests find (_.reqId == id)
+
def requestForName(name: Name): Option[Request] = {
assert(definedNameMap != null, "definedNameMap is null")
definedNameMap get name
@@ -1040,18 +1094,21 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
}
def valueOfTerm(id: String): Option[AnyRef] =
- requestForIdent(id) flatMap (_.getEval)
+ requestForName(newTermName(id)) flatMap (_.getEval)
def classOfTerm(id: String): Option[JClass] =
valueOfTerm(id) map (_.getClass)
def typeOfTerm(id: String): Type = newTermName(id) match {
case nme.ROOTPKG => definitions.RootClass.tpe
- case name => requestForName(name) flatMap (_.compilerTypeOf get name) getOrElse NoType
+ case name => requestForName(name).fold(NoType: Type)(_ compilerTypeOf name)
}
+ def symbolOfType(id: String): Symbol =
+ requestForName(newTypeName(id)).fold(NoSymbol: Symbol)(_ definedTypeSymbol id)
+
def symbolOfTerm(id: String): Symbol =
- requestForIdent(id) flatMap (_.definedSymbols get newTermName(id)) getOrElse NoSymbol
+ requestForIdent(newTermName(id)).fold(NoSymbol: Symbol)(_ definedTermSymbol id)
def runtimeClassAndTypeOfTerm(id: String): Option[(JClass, Type)] = {
classOfTerm(id) flatMap { clazz =>
@@ -1072,16 +1129,28 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
else NoType
}
}
+ def cleanMemberDecl(owner: Symbol, member: Name): Type = afterTyper {
+ normalizeNonPublic {
+ owner.info.nonPrivateDecl(member).tpe match {
+ case NullaryMethodType(tp) => tp
+ case tp => tp
+ }
+ }
+ }
object replTokens extends {
val global: imain.global.type = imain.global
} with ReplTokens { }
- private object exprTyper extends {
+ object exprTyper extends {
val repl: IMain.this.type = imain
} with ExprTyper { }
def parse(line: String): Option[List[Tree]] = exprTyper.parse(line)
+
+ def symbolOfLine(code: String): Symbol =
+ exprTyper.symbolOfLine(code)
+
def typeOfExpression(expr: String, silent: Boolean = true): Type =
exprTyper.typeOfExpression(expr, silent)
@@ -1091,14 +1160,15 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
protected def onlyTerms(xs: List[Name]) = xs collect { case x: TermName => x }
protected def onlyTypes(xs: List[Name]) = xs collect { case x: TypeName => x }
- def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalTermName
- def definedTypes = onlyTypes(allDefinedNames)
- def definedSymbols = prevRequests.toSet flatMap ((x: Request) => x.definedSymbols.values)
+ def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalTermName
+ def definedTypes = onlyTypes(allDefinedNames)
+ def definedSymbols = prevRequestList.flatMap(_.definedSymbols.values).toSet[Symbol]
+ def definedSymbolList = prevRequestList flatMap (_.definedSymbolList) filterNot (s => isInternalTermName(s.name))
// Terms with user-given names (i.e. not res0 and not synthetic)
def namedDefinedTerms = definedTerms filterNot (x => isUserVarName("" + x) || directlyBoundNames(x))
- private def findName(name: Name) = definedSymbols find (_.name == name)
+ private def findName(name: Name) = definedSymbols find (_.name == name) getOrElse NoSymbol
/** Translate a repl-defined identifier into a Symbol.
*/
@@ -1107,26 +1177,36 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def types(name: String): Symbol = {
val tpname = newTypeName(name)
- findName(tpname) getOrElse getClassIfDefined(tpname)
+ findName(tpname) orElse getClassIfDefined(tpname)
}
def terms(name: String): Symbol = {
val termname = newTypeName(name)
- findName(termname) getOrElse getModuleIfDefined(termname)
+ findName(termname) orElse getModuleIfDefined(termname)
}
- def types[T: ClassManifest] : Symbol = types(classManifest[T].erasure.getName)
- def terms[T: ClassManifest] : Symbol = terms(classManifest[T].erasure.getName)
- def apply[T: ClassManifest] : Symbol = apply(classManifest[T].erasure.getName)
+ // [Eugene to Paul] possibly you could make use of TypeTags here
+ def types[T: ClassTag] : Symbol = types(classTag[T].erasure.getName)
+ def terms[T: ClassTag] : Symbol = terms(classTag[T].erasure.getName)
+ def apply[T: ClassTag] : Symbol = apply(classTag[T].erasure.getName)
+
+ def classSymbols = allDefSymbols collect { case x: ClassSymbol => x }
+ def methodSymbols = allDefSymbols collect { case x: MethodSymbol => x }
/** the previous requests this interpreter has processed */
- private lazy val prevRequests = mutable.ListBuffer[Request]()
- private lazy val referencedNameMap = mutable.Map[Name, Request]()
- private lazy val definedNameMap = mutable.Map[Name, Request]()
- private lazy val directlyBoundNames = mutable.Set[Name]()
- protected def prevRequestList = prevRequests.toList
- private def allHandlers = prevRequestList flatMap (_.handlers)
- def allSeenTypes = prevRequestList flatMap (_.typeOf.values.toList) distinct
- def allImplicits = allHandlers filter (_.definesImplicit) flatMap (_.definedNames)
- def importHandlers = allHandlers collect { case x: ImportHandler => x }
+ private var executingRequest: Request = _
+ private val prevRequests = mutable.ListBuffer[Request]()
+ private val referencedNameMap = mutable.Map[Name, Request]()
+ private val definedNameMap = mutable.Map[Name, Request]()
+ private val directlyBoundNames = mutable.Set[Name]()
+
+ def allHandlers = prevRequestList flatMap (_.handlers)
+ def allDefHandlers = allHandlers collect { case x: MemberDefHandler => x }
+ def allDefSymbols = allDefHandlers map (_.symbol) filter (_ ne NoSymbol)
+
+ def lastRequest = if (prevRequests.isEmpty) null else prevRequests.last
+ def prevRequestList = prevRequests.toList
+ def allSeenTypes = prevRequestList flatMap (_.typeOf.values.toList) distinct
+ def allImplicits = allHandlers filter (_.definesImplicit) flatMap (_.definedNames)
+ def importHandlers = allHandlers collect { case x: ImportHandler => x }
def visibleTermNames: List[Name] = definedTerms ++ importedTerms distinct
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
index f9c1907696..795b2e3678 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -194,14 +194,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
// literal Ints, Strings, etc.
object literals extends CompletionAware {
- def simpleParse(code: String): Tree = {
- val unit = new CompilationUnit(new util.BatchSourceFile("<console>", code))
- val scanner = new syntaxAnalyzer.UnitParser(unit)
- val tss = scanner.templateStatSeq(false)._2
-
- if (tss.size == 1) tss.head else EmptyTree
- }
-
+ def simpleParse(code: String): Tree = newUnitParser(code).templateStats().last
def completions(verbosity: Int) = Nil
override def follow(id: String) = simpleParse(id) match {
@@ -287,7 +280,12 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
}
// chasing down results which won't parse
+ // This used to work fine, now it reports a type error before any
+ // exception gets to us. See SI-5657. Don't have time to deal with
+ // it, so disabling everything.
def execute(line: String): Option[ExecResult] = {
+ return None // disabled
+
val parsed = Parsed(line)
def noDotOrSlash = line forall (ch => ch != '.' && ch != '/')
diff --git a/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala b/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
index 9469baa4e2..3520a60ee5 100644
--- a/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
@@ -8,6 +8,7 @@ package interpreter
import collection.{ mutable, immutable }
import mutable.ListBuffer
+import language.implicitConversions
class ProcessResult(val line: String) {
import sys.process._
diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
index 68bfeafbc6..a29eb3ac6d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -9,6 +9,7 @@ package interpreter
import scala.collection.{ mutable, immutable }
import scala.PartialFunction.cond
import scala.reflect.internal.Chars
+import language.implicitConversions
trait MemberHandlers {
val intp: IMain
@@ -63,6 +64,7 @@ trait MemberHandlers {
}
sealed abstract class MemberDefHandler(override val member: MemberDef) extends MemberHandler(member) {
+ def symbol = if (member.symbol eq null) NoSymbol else member.symbol
def name: Name = member.name
def mods: Modifiers = member.mods
def keyword = member.keyword
@@ -71,6 +73,7 @@ trait MemberHandlers {
override def definesImplicit = member.mods.isImplicit
override def definesTerm: Option[TermName] = Some(name.toTermName) filter (_ => name.isTermName)
override def definesType: Option[TypeName] = Some(name.toTypeName) filter (_ => name.isTypeName)
+ override def definedSymbols = if (symbol eq NoSymbol) Nil else List(symbol)
}
/** Class to handle one member among all the members included
@@ -88,6 +91,7 @@ trait MemberHandlers {
def importedNames = List[Name]()
def definedNames = definesTerm.toList ++ definesType.toList
def definedOrImported = definedNames ++ importedNames
+ def definedSymbols = List[Symbol]()
def extraCodeToEvaluate(req: Request): String = ""
def resultExtractionCode(req: Request): String = ""
@@ -120,7 +124,7 @@ trait MemberHandlers {
private def vparamss = member.vparamss
private def isMacro = member.mods.hasFlag(scala.reflect.internal.Flags.MACRO)
// true if not a macro and 0-arity
- override def definesValue = !isMacro && (vparamss.isEmpty || vparamss.head.isEmpty)
+ override def definesValue = !isMacro && flattensToEmpty(vparamss)
override def resultExtractionCode(req: Request) =
if (mods.isPublic) codegenln(name, ": ", req.typeOf(name)) else ""
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala
index e92888d89b..a3cbfffc3b 100644
--- a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala
@@ -7,24 +7,25 @@ package scala.tools.nsc
package interpreter
import NamedParam._
+import language.implicitConversions
trait NamedParamCreator {
protected def freshName: () => String
def apply(name: String, tpe: String, value: Any): NamedParam = NamedParamClass(name, tpe, value)
- def apply[T: Manifest](name: String, x: T): NamedParam = new Typed[T](name, x)
- def apply[T: Manifest](x: T): NamedParam = apply(freshName(), x)
+ def apply[T: TypeTag](name: String, x: T): NamedParam = new Typed[T](name, x)
+ def apply[T: TypeTag](x: T): NamedParam = apply(freshName(), x)
def clazz(name: String, x: Any): NamedParam = new Untyped(name, x)
def clazz(x: Any): NamedParam = clazz(freshName(), x)
- implicit def namedValue[T: Manifest](name: String, x: T): NamedParam = apply(name, x)
- implicit def tuple[T: Manifest](pair: (String, T)): NamedParam = apply(pair._1, pair._2)
+ implicit def namedValue[T: TypeTag](name: String, x: T): NamedParam = apply(name, x)
+ implicit def tuple[T: TypeTag](pair: (String, T)): NamedParam = apply(pair._1, pair._2)
}
object NamedParam extends NamedParamCreator {
- class Typed[T: Manifest](val name: String, val value: T) extends NamedParam {
- val tpe = TypeStrings.fromManifest[T]
+ class Typed[T: TypeTag](val name: String, val value: T) extends NamedParam {
+ val tpe = TypeStrings.fromTag[T]
}
class Untyped(val name: String, val value: Any) extends NamedParam {
val tpe = TypeStrings.fromValue(value)
@@ -43,4 +44,4 @@ trait NamedParam {
def tpe: String
def value: Any
override def toString = name + ": " + tpe
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/interpreter/Naming.scala b/src/compiler/scala/tools/nsc/interpreter/Naming.scala
index 19266442cb..c3f51c74ec 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Naming.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Naming.scala
@@ -41,10 +41,10 @@ trait Naming {
private def removeIWPackages(s: String) = s.replaceAll("""\$iw[$.]""", "")
trait SessionNames {
- // All values are configurable by passing e.g. -Dscala.repl.naming.read=XXX
+ // All values are configurable by passing e.g. -Dscala.repl.name.read=XXX
final def propOr(name: String): String = propOr(name, "$" + name)
final def propOr(name: String, default: String): String =
- sys.props.getOrElse("scala.repl.naming." + name, default)
+ sys.props.getOrElse("scala.repl.name." + name, default)
// Prefixes used in repl machinery. Default to $line, $read, etc.
def line = propOr("line")
diff --git a/src/compiler/scala/tools/nsc/interpreter/Phased.scala b/src/compiler/scala/tools/nsc/interpreter/Phased.scala
index d164d1cbb0..f39c025a86 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Phased.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Phased.scala
@@ -7,6 +7,7 @@ package scala.tools.nsc
package interpreter
import scala.collection.{ mutable, immutable }
+import language.implicitConversions
/** Mix this into an object and use it as a phasing
* swiss army knife.
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index 14876425f4..659caad1e1 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -6,7 +6,6 @@
package scala.tools.nsc
package interpreter
-import scala.reflect.AnyValManifest
import scala.collection.{ mutable, immutable }
import scala.util.matching.Regex
import scala.tools.nsc.util.{ BatchSourceFile }
@@ -14,6 +13,7 @@ import session.{ History }
import scala.io.Codec
import java.net.{ URL, MalformedURLException }
import io.{ Path }
+import language.implicitConversions
/** Collecting some power mode examples.
@@ -42,10 +42,10 @@ Lost after 18/flatten {
/** A class for methods to be injected into the intp in power mode.
*/
-class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: ReplValsImpl) {
+class Power[ReplValsImpl <: ReplVals : TypeTag](val intp: IMain, replVals: ReplValsImpl) {
import intp.{ beQuietDuring, typeOfExpression, interpret, parse }
import intp.global._
- import definitions.{ manifestToType, manifestToSymbol, getClassIfDefined, getModuleIfDefined }
+ import definitions.{ compilerTypeFromTag, compilerSymbolFromTag, getClassIfDefined, getModuleIfDefined }
abstract class SymSlurper {
def isKeep(sym: Symbol): Boolean
@@ -162,7 +162,7 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl
}
trait LowPriorityInternalInfo {
- implicit def apply[T: Manifest] : InternalInfo[T] = new InternalInfo[T](None)
+ implicit def apply[T: TypeTag] : InternalInfo[T] = new InternalInfo[T](None)
}
object InternalInfo extends LowPriorityInternalInfo { }
@@ -173,21 +173,21 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl
* of the conveniences exist on that wrapper.
*/
trait LowPriorityInternalInfoWrapper {
- implicit def apply[T: Manifest] : InternalInfoWrapper[T] = new InternalInfoWrapper[T](None)
+ implicit def apply[T: TypeTag] : InternalInfoWrapper[T] = new InternalInfoWrapper[T](None)
}
object InternalInfoWrapper extends LowPriorityInternalInfoWrapper {
}
- class InternalInfoWrapper[T: Manifest](value: Option[T] = None) {
+ class InternalInfoWrapper[T: TypeTag](value: Option[T] = None) {
def ? : InternalInfo[T] = new InternalInfo[T](value)
}
/** Todos...
- * translate manifest type arguments into applied types
+ * translate tag type arguments into applied types
* customizable symbol filter (had to hardcode no-spec to reduce noise)
*/
- class InternalInfo[T: Manifest](value: Option[T] = None) {
- private def newInfo[U: Manifest](value: U): InternalInfo[U] = new InternalInfo[U](Some(value))
+ class InternalInfo[T: TypeTag](value: Option[T] = None) {
+ private def newInfo[U: TypeTag](value: U): InternalInfo[U] = new InternalInfo[U](Some(value))
private def isSpecialized(s: Symbol) = s.name.toString contains "$mc"
private def isImplClass(s: Symbol) = s.name.toString endsWith "$class"
@@ -198,8 +198,8 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl
|| s.isAnonOrRefinementClass
|| s.isAnonymousFunction
)
- def symbol = manifestToSymbol(fullManifest)
- def tpe = manifestToType(fullManifest)
+ def symbol = compilerSymbolFromTag(tag)
+ def tpe = compilerTypeFromTag(tag)
def name = symbol.name
def companion = symbol.companionSymbol
def info = symbol.info
@@ -226,19 +226,19 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl
def pkgClasses = pkgMembers filter (s => s.isClass && s.isDefinedInPackage)
def pkgSymbols = new PackageSlurper(pkgClass).slurp() filterNot excludeMember
- def fullManifest = manifest[T]
- def erasure = fullManifest.erasure
+ def tag = typeTag[T]
+ def erasure = tag.erasure
def shortClass = erasure.getName split "[$.]" last
def baseClasses = tpe.baseClasses
- def baseClassDecls = baseClasses map (x => (x, x.info.decls.toList.sortBy(_.name.toString))) toMap
+ def baseClassDecls = mapFrom(baseClasses)(_.info.decls.toList.sortBy(_.name))
def ancestors = baseClasses drop 1
def ancestorDeclares(name: String) = ancestors filter (_.info member newTermName(name) ne NoSymbol)
def baseTypes = tpe.baseTypeSeq.toList
- def <:<[U: Manifest](other: U) = tpe <:< newInfo(other).tpe
- def lub[U: Manifest](other: U) = intp.global.lub(List(tpe, newInfo(other).tpe))
- def glb[U: Manifest](other: U) = intp.global.glb(List(tpe, newInfo(other).tpe))
+ def <:<[U: TypeTag](other: U) = tpe <:< newInfo(other).tpe
+ def lub[U: TypeTag](other: U) = intp.global.lub(List(tpe, newInfo(other).tpe))
+ def glb[U: TypeTag](other: U) = intp.global.glb(List(tpe, newInfo(other).tpe))
override def toString = value match {
case Some(x) => "%s (%s)".format(x, shortClass)
@@ -362,11 +362,10 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl
else if (s1 isLess s2) -1
else 1
}
- implicit lazy val powerNameOrdering: Ordering[Name] = Ordering[String] on (_.toString)
implicit lazy val powerSymbolOrdering: Ordering[Symbol] = Ordering[Name] on (_.name)
implicit lazy val powerTypeOrdering: Ordering[Type] = Ordering[Symbol] on (_.typeSymbol)
- implicit def replInternalInfo[T: Manifest](x: T): InternalInfoWrapper[T] = new InternalInfoWrapper[T](Some(x))
+ implicit def replInternalInfo[T: TypeTag](x: T): InternalInfoWrapper[T] = new InternalInfoWrapper[T](Some(x))
implicit def replEnhancedStrings(s: String): RichReplString = new RichReplString(s)
implicit def replMultiPrinting[T: Prettifier](xs: TraversableOnce[T]): MultiPrettifierClass[T] =
new MultiPrettifierClass[T](xs.toSeq)
@@ -381,10 +380,13 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl
}
trait ReplUtilities {
- def module[T: Manifest] = getModuleIfDefined(manifest[T].erasure.getName stripSuffix nme.MODULE_SUFFIX_STRING)
- def clazz[T: Manifest] = getClassIfDefined(manifest[T].erasure.getName)
- def info[T: Manifest] = InternalInfo[T]
- def ?[T: Manifest] = InternalInfo[T]
+ // [Eugene to Paul] needs review!
+ // def module[T: TypeTag] = getModuleIfDefined(typeTag[T].erasure.getName stripSuffix nme.MODULE_SUFFIX_STRING)
+ // def clazz[T: TypeTag] = getClassIfDefined(typeTag[T].erasure.getName)
+ def module[T: TypeTag] = typeTag[T].sym.suchThat(_.isPackage)
+ def clazz[T: TypeTag] = typeTag[T].sym.suchThat(_.isClass)
+ def info[T: TypeTag] = InternalInfo[T]
+ def ?[T: TypeTag] = InternalInfo[T]
def url(s: String) = {
try new URL(s)
catch { case _: MalformedURLException =>
@@ -410,8 +412,8 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl
lazy val phased: Phased = new { val global: intp.global.type = intp.global } with Phased { }
def context(code: String) = analyzer.rootContext(unit(code))
- def source(code: String) = new BatchSourceFile("<console>", code)
- def unit(code: String) = new CompilationUnit(source(code))
+ def source(code: String) = newSourceFile(code)
+ def unit(code: String) = newCompilationUnit(code)
def trees(code: String) = parse(code) getOrElse Nil
def typeOf(id: String) = intp.typeOfExpression(id)
diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala b/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala
index 8c589eba60..0c26aa8b28 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala
@@ -27,6 +27,12 @@ trait ReplConfig {
try Console println msg
catch { case x: AssertionError => Console.println("Assertion error printing debugging output: " + x) }
+ private[nsc] def repldbgex(ex: Throwable): Unit = {
+ if (isReplDebug) {
+ echo("Caught/suppressing: " + ex)
+ ex.printStackTrace
+ }
+ }
private[nsc] def repldbg(msg: => String) = if (isReplDebug) echo(msg)
private[nsc] def repltrace(msg: => String) = if (isReplTrace) echo(msg)
private[nsc] def replinfo(msg: => String) = if (isReplInfo) echo(msg)
diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala b/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala
new file mode 100644
index 0000000000..05321dd7e6
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala
@@ -0,0 +1,57 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+import reporters._
+import typechecker.Analyzer
+
+/** A layer on top of Global so I can guarantee some extra
+ * functionality for the repl. It doesn't do much yet.
+ */
+trait ReplGlobal extends Global {
+ // This exists mostly because using the reporter too early leads to deadlock.
+ private def echo(msg: String) { Console println msg }
+
+ override def abort(msg: String): Nothing = {
+ echo("ReplGlobal.abort: " + msg)
+ super.abort(msg)
+ }
+
+ override lazy val analyzer = new {
+ val global: ReplGlobal.this.type = ReplGlobal.this
+ } with Analyzer {
+ override def newTyper(context: Context): Typer = new Typer(context) {
+ override def typed(tree: Tree, mode: Int, pt: Type): Tree = {
+ val res = super.typed(tree, mode, pt)
+ tree match {
+ case Ident(name) if !tree.symbol.hasPackageFlag && !name.toString.startsWith("$") =>
+ repldbg("typed %s: %s".format(name, res.tpe))
+ case _ =>
+ }
+ res
+ }
+ }
+ }
+
+ object replPhase extends SubComponent {
+ val global: ReplGlobal.this.type = ReplGlobal.this
+ val phaseName = "repl"
+ val runsAfter = List[String]("typer")
+ val runsRightAfter = None
+ def newPhase(_prev: Phase): StdPhase = new StdPhase(_prev) {
+ def apply(unit: CompilationUnit) {
+ repldbg("Running replPhase on " + unit.body)
+ // newNamer(rootContext(unit)).enterSym(unit.body)
+ }
+ }
+ }
+
+ override protected def computePhaseDescriptors: List[SubComponent] = {
+ addToPhasesSet(replPhase, "repl")
+ super.computePhaseDescriptors
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala b/src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala
index 130af990ad..fb61dfb672 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplReporter.scala
@@ -9,7 +9,11 @@ package interpreter
import reporters._
import IMain._
+/** Like ReplGlobal, a layer for ensuring extra functionality.
+ */
class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.in, new ReplStrippingWriter(intp)) {
+ def printUntruncatedMessage(msg: String) = withoutTruncating(printMessage(msg))
+
override def printMessage(msg: String) {
// Avoiding deadlock if the compiler starts logging before
// the lazy val is complete.
diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala b/src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala
index 1c7b256c33..e63fabf151 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala
@@ -9,6 +9,7 @@ package interpreter
import util.{ BatchSourceFile, Indenter }
import scala.tools.nsc.ast.parser.Tokens._
import java.lang.Integer.toOctalString
+import language.{implicitConversions, existentials}
/** This began as an attempt at a completely minimal
* pretty printer for a token stream, but as it turns out
diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
index a68392f0fb..280247f20c 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
@@ -6,6 +6,9 @@
package scala.tools.nsc
package interpreter
+import scala.reflect.{mirror => rm}
+import language.implicitConversions
+
/** A class which the repl utilizes to expose predefined objects.
* The base implementation is empty; the standard repl implementation
* is StdReplVals.
@@ -25,20 +28,24 @@ class StdReplVals(final val r: ILoop) extends ReplVals {
final lazy val phased = power.phased
final lazy val analyzer = global.analyzer
- final lazy val treedsl = new { val global: intp.global.type = intp.global } with ast.TreeDSL { }
+ object treedsl extends { val global: intp.global.type = intp.global } with ast.TreeDSL { }
+
final lazy val typer = analyzer.newTyper(
analyzer.rootContext(
power.unit("").asInstanceOf[analyzer.global.CompilationUnit]
)
)
+ def lastRequest = intp.lastRequest
- final lazy val replImplicits = new power.Implicits2 {
+ class ReplImplicits extends power.Implicits2 {
import intp.global._
- private val manifestFn = ReplVals.mkManifestToType[intp.global.type](global)
- implicit def mkManifestToType(sym: Symbol) = manifestFn(sym)
+ private val tagFn = ReplVals.mkCompilerTypeFromTag[intp.global.type](global)
+ implicit def mkCompilerTypeFromTag(sym: Symbol) = tagFn(sym)
}
+ final lazy val replImplicits = new ReplImplicits
+
def typed[T <: analyzer.global.Tree](tree: T): T = typer.typed(tree).asInstanceOf[T]
}
@@ -47,29 +54,29 @@ object ReplVals {
* not being seen as the same type as bar.global.Type even though
* the globals are the same. Dependent method types to the rescue.
*/
- def mkManifestToType[T <: Global](global: T) = {
+ def mkCompilerTypeFromTag[T <: Global](global: T) = {
import global._
import definitions._
- /** We can't use definitions.manifestToType directly because we're passing
+ /** We can't use definitions.compilerTypeFromTag directly because we're passing
* it to map and the compiler refuses to perform eta expansion on a method
* with a dependent return type. (Can this be relaxed?) To get around this
* I have this forwarder which widens the type and then cast the result back
* to the dependent type.
*/
- def manifestToType(m: OptManifest[_]): Global#Type =
- definitions.manifestToType(m)
+ def compilerTypeFromTag(t: rm.TypeTag[_]): Global#Type =
+ definitions.compilerTypeFromTag(t)
- class AppliedTypeFromManifests(sym: Symbol) {
- def apply[M](implicit m1: Manifest[M]): Type =
+ class AppliedTypeFromTags(sym: Symbol) {
+ def apply[M](implicit m1: rm.TypeTag[M]): Type =
if (sym eq NoSymbol) NoType
- else appliedType(sym.typeConstructor, List(m1) map (x => manifestToType(x).asInstanceOf[Type]))
+ else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type])
- def apply[M1, M2](implicit m1: Manifest[M1], m2: Manifest[M2]): Type =
+ def apply[M1, M2](implicit m1: rm.TypeTag[M1], m2: rm.TypeTag[M2]): Type =
if (sym eq NoSymbol) NoType
- else appliedType(sym.typeConstructor, List(m1, m2) map (x => manifestToType(x).asInstanceOf[Type]))
+ else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type], compilerTypeFromTag(m2).asInstanceOf[Type])
}
- (sym: Symbol) => new AppliedTypeFromManifests(sym)
+ (sym: Symbol) => new AppliedTypeFromTags(sym)
}
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala
index 5edc8fd202..2e735e3b9b 100644
--- a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala
@@ -7,18 +7,21 @@ package scala.tools.nsc
package interpreter
class RichClass[T](val clazz: Class[T]) {
- def toManifest: Manifest[T] = Manifest.classType(clazz)
+ def toTag: ClassTag[T] = ClassTag[T](clazz)
def toTypeString: String = TypeStrings.fromClazz(clazz)
// Sadly isAnonymousClass does not return true for scala anonymous
// classes because our naming scheme is not doing well against the
// jvm's many assumptions.
- def isScalaAnonymous = clazz.isAnonymousClass || (clazz.getName contains "$anon$")
+ def isScalaAnonymous = (
+ try clazz.isAnonymousClass || (clazz.getName contains "$anon$")
+ catch { case _: java.lang.InternalError => false } // good ol' "Malformed class name"
+ )
/** It's not easy... to be... me... */
- def supermans: List[Manifest[_]] = supers map (_.toManifest)
- def superNames: List[String] = supers map (_.getName)
- def interfaces: List[JClass] = supers filter (_.isInterface)
+ def supermans: List[ClassTag[_]] = supers map (_.toTag)
+ def superNames: List[String] = supers map (_.getName)
+ def interfaces: List[JClass] = supers filter (_.isInterface)
def hasAncestorName(f: String => Boolean) = superNames exists f
def hasAncestor(f: JClass => Boolean) = supers exists f
diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
index 6b56d881fc..5d5123811e 100644
--- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
@@ -10,6 +10,143 @@ import java.lang.{ reflect => r }
import r.TypeVariable
import scala.reflect.NameTransformer
import NameTransformer._
+import scala.reflect.{mirror => rm}
+import typechecker.DestructureTypes
+import scala.tools.util.StringOps.ojoin
+
+/** A more principled system for turning types into strings.
+ */
+trait StructuredTypeStrings extends DestructureTypes {
+ val global: Global
+ import global._
+ import definitions._
+
+ case class LabelAndType(label: String, typeName: String) { }
+ object LabelAndType {
+ val empty = LabelAndType("", "")
+ }
+ case class Grouping(ldelim: String, mdelim: String, rdelim: String, labels: Boolean) {
+ def join(elems: String*): String = (
+ if (elems.isEmpty) ""
+ else elems.mkString(ldelim, mdelim, rdelim)
+ )
+ }
+ val NoGrouping = Grouping("", "", "", false)
+ val ListGrouping = Grouping("(", ", ", ")", false)
+ val ProductGrouping = Grouping("(", ", ", ")", true)
+ val ParamGrouping = Grouping("(", ", ", ")", true)
+ val BlockGrouping = Grouping(" { ", "; ", "}", false)
+
+ private implicit def lowerName(n: Name): String = "" + n
+ private def str(level: Int)(body: => String): String = " " * level + body
+ private def block(level: Int, grouping: Grouping)(name: String, nodes: List[TypeNode]): String = {
+ val l1 = str(level)(name + grouping.ldelim)
+ val l2 = nodes.map(_ show level + 1)
+ val l3 = str(level)(grouping.rdelim)
+
+ l1 +: l2 :+ l3 mkString "\n"
+ }
+ private def maybeBlock(level: Int, grouping: Grouping)(name: String, nodes: List[TypeNode]): String = {
+ import grouping._
+ val threshold = 70
+
+ val try1 = str(level)(name + grouping.join(nodes map (_.show(0, grouping.labels)): _*))
+ if (try1.length < threshold) try1
+ else block(level, grouping)(name, nodes)
+ }
+ private def shortClass(x: Any) = {
+ if (opt.debug) {
+ val name = (x.getClass.getName split '.').last
+ val isAnon = name.reverse takeWhile (_ != '$') forall (_.isDigit)
+ val str = if (isAnon) name else (name split '$').last
+
+ " // " + str
+ }
+ else ""
+ }
+
+ sealed abstract class TypeNode {
+ def grouping: Grouping
+ def nodes: List[TypeNode]
+
+ def show(indent: Int, showLabel: Boolean): String = maybeBlock(indent, grouping)(mkPrefix(showLabel), nodes)
+ def show(indent: Int): String = show(indent, true)
+ def show(): String = show(0)
+
+ def withLabel(l: String): this.type = modifyNameInfo(_.copy(label = l))
+ def withType(t: String): this.type = modifyNameInfo(_.copy(typeName = t))
+
+ def label = nameInfo.label
+ def typeName = nameInfo.typeName
+
+ protected def mkPrefix(showLabel: Boolean) = {
+ val pre = if (showLabel && label != "") label + " = " else ""
+ pre + typeName
+ }
+ override def toString = show() // + "(toString)"
+ private var nameInfo: LabelAndType = LabelAndType.empty
+ private def modifyNameInfo(f: LabelAndType => LabelAndType): this.type = {
+ nameInfo = f(nameInfo)
+ this
+ }
+ }
+ case class TypeAtom[T](atom: T) extends TypeNode {
+ def grouping = NoGrouping
+ def nodes = Nil
+ override protected def mkPrefix(showLabel: Boolean) =
+ super.mkPrefix(showLabel) + atom + shortClass(atom)
+ }
+ case class TypeProduct(nodes: List[TypeNode]) extends TypeNode {
+ def grouping: Grouping = ProductGrouping
+ def emptyTypeName = ""
+ override def typeName = if (nodes.isEmpty) emptyTypeName else super.typeName
+ }
+
+ /** For a NullaryMethod, in = TypeEmpty; for MethodType(Nil, _) in = TypeNil */
+ class NullaryFunction(out: TypeNode) extends TypeProduct(List(out)) {
+ override def typeName = "NullaryMethodType"
+ }
+ class MonoFunction(in: TypeNode, out: TypeNode) extends TypeProduct(List(in, out)) {
+ override def typeName = "MethodType"
+ }
+ class PolyFunction(in: TypeNode, out: TypeNode) extends TypeProduct(List(in, out)) {
+ override def typeName = "PolyType"
+ }
+
+ class TypeList(nodes: List[TypeNode]) extends TypeProduct(nodes) {
+ override def grouping = ListGrouping
+ override def emptyTypeName = "Nil"
+ override def typeName = "List"
+ }
+ class TypeScope(nodes: List[TypeNode]) extends TypeProduct(nodes) {
+ override def grouping = BlockGrouping
+ override def typeName = "Scope"
+ override def emptyTypeName = "EmptyScope"
+ }
+
+ object TypeEmpty extends TypeNode {
+ override def grouping = NoGrouping
+ override def nodes = Nil
+ override def label = ""
+ override def typeName = ""
+ override def show(indent: Int, showLabel: Boolean) = ""
+ }
+
+ object intoNodes extends DestructureType[TypeNode] {
+ def withLabel(node: TypeNode, label: String): TypeNode = node withLabel label
+ def withType(node: TypeNode, typeName: String): TypeNode = node withType typeName
+
+ def wrapEmpty = TypeEmpty
+ def wrapSequence(nodes: List[TypeNode]) = new TypeList(nodes)
+ def wrapProduct(nodes: List[TypeNode]) = new TypeProduct(nodes)
+ def wrapPoly(in: TypeNode, out: TypeNode) = new PolyFunction(in, out)
+ def wrapMono(in: TypeNode, out: TypeNode) = if (in == wrapEmpty) new NullaryFunction(out) else new MonoFunction(in, out)
+ def wrapAtom[U](value: U) = new TypeAtom(value)
+ }
+
+ def show(tp: Type): String = intoNodes(tp).show
+}
+
/** Logic for turning a type into a String. The goal is to be
* able to take some arbitrary object 'x' and obtain the most precise
@@ -55,8 +192,8 @@ trait TypeStrings {
else enclClass.getName + "." + (name stripPrefix enclPre)
)
}
- def scalaName(m: ClassManifest[_]): String = scalaName(m.erasure)
- def anyClass(x: Any): JClass = if (x == null) null else x.getClass
+ def scalaName(m: ClassTag[_]): String = scalaName(m.erasure)
+ def anyClass(x: Any): JClass = if (x == null) null else x.getClass
private def brackets(tps: String*): String =
if (tps.isEmpty) ""
@@ -72,21 +209,25 @@ trait TypeStrings {
brackets(clazz.getTypeParameters map tvarString: _*)
}
- private def tparamString[T: Manifest] : String =
- brackets(manifest[T].typeArguments map (m => tvarString(List(m.erasure))): _*)
+ private def tparamString[T: TypeTag] : String = {
+ // [Eugene to Paul] needs review!!
+ def typeArguments: List[rm.Type] = typeTag[T].tpe.typeArguments
+ def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => rm.typeToClass(targ))
+ brackets(typeArguments map (jc => tvarString(List(jc))): _*)
+ }
/** Going for an overabundance of caution right now. Later these types
- * can be a lot more precise, but right now the manifests have a habit of
+ * can be a lot more precise, but right now the tags have a habit of
* introducing material which is not syntactically valid as scala source.
* When this happens it breaks the repl. It would be nice if we mandated
- * that manifest toString methods (or some other method, since it's bad
+ * that tag toString methods (or some other method, since it's bad
* practice to rely on toString for correctness) generated the VALID string
* representation of the type.
*/
- def fromTypedValue[T: Manifest](x: T): String = fromManifest[T]
- def fromValue(value: Any): String = if (value == null) "Null" else fromClazz(anyClass(value))
- def fromClazz(clazz: JClass): String = scalaName(clazz) + tparamString(clazz)
- def fromManifest[T: Manifest] : String = scalaName(manifest[T].erasure) + tparamString[T]
+ def fromTypedValue[T: TypeTag](x: T): String = fromTag[T]
+ def fromValue(value: Any): String = if (value == null) "Null" else fromClazz(anyClass(value))
+ def fromClazz(clazz: JClass): String = scalaName(clazz) + tparamString(clazz)
+ def fromTag[T: TypeTag] : String = scalaName(typeTag[T].erasure) + tparamString[T]
/** Reducing fully qualified noise for some common packages.
*/
diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala
index e78e92c8f8..7d2610e3c8 100644
--- a/src/compiler/scala/tools/nsc/interpreter/package.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/package.scala
@@ -5,6 +5,8 @@
package scala.tools.nsc
+import language.implicitConversions
+
/** The main REPL related classes and values are as follows.
* In addition to standard compiler classes Global and Settings, there are:
*
@@ -33,6 +35,8 @@ package object interpreter extends ReplConfig with ReplStrings {
val IR = Results
+ implicit def postfixOps = language.postfixOps // make all postfix ops in this package compile without warning
+
private[interpreter] implicit def javaCharSeqCollectionToScala(xs: JCollection[_ <: CharSequence]): List[String] = {
import collection.JavaConverters._
xs.asScala.toList map ("" + _)
diff --git a/src/compiler/scala/tools/nsc/interpreter/session/package.scala b/src/compiler/scala/tools/nsc/interpreter/session/package.scala
index 8fbba2f05e..4e5b08c8cb 100644
--- a/src/compiler/scala/tools/nsc/interpreter/session/package.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/session/package.scala
@@ -5,6 +5,7 @@
package scala.tools.nsc
package interpreter
+import language.implicitConversions
/** Files having to do with the state of a repl session:
* lines of text entered, types and terms defined, etc.
diff --git a/src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala b/src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala
index d0a0b17494..c9ed535841 100644
--- a/src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala
+++ b/src/compiler/scala/tools/nsc/io/ClassAndJarInfo.scala
@@ -13,9 +13,9 @@ import collection.JavaConverters._
/** A convenience class for finding the jar with the bytecode for
* a given Class object and similar common tasks.
*/
-class ClassAndJarInfo[T: ClassManifest] {
- val man = classManifest[T]
- def clazz = man.erasure
+class ClassAndJarInfo[T: ClassTag] {
+ val tag = classTag[T]
+ def clazz = tag.erasure
def internalName = clazz.getName.replace('.', '/')
def resourceURL = new URLClassLoader(Array[URL]()) getResource internalName + ".class"
diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala
index cc512493d9..06cb20e4ac 100644
--- a/src/compiler/scala/tools/nsc/io/File.scala
+++ b/src/compiler/scala/tools/nsc/io/File.scala
@@ -15,6 +15,7 @@ import java.io.{
BufferedInputStream, BufferedOutputStream, IOException, PrintStream, PrintWriter, Closeable => JCloseable }
import java.nio.channels.{ Channel, FileChannel }
import scala.io.Codec
+import language.{reflectiveCalls, implicitConversions}
object File {
def pathSeparator = java.io.File.pathSeparator
diff --git a/src/compiler/scala/tools/nsc/io/Jar.scala b/src/compiler/scala/tools/nsc/io/Jar.scala
index bbed5a9e20..b322df986c 100644
--- a/src/compiler/scala/tools/nsc/io/Jar.scala
+++ b/src/compiler/scala/tools/nsc/io/Jar.scala
@@ -11,6 +11,7 @@ import java.util.jar._
import collection.JavaConverters._
import Attributes.Name
import util.ClassPath
+import language.implicitConversions
// Attributes.Name instances:
//
diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala
index a1b8e5e4d5..b8cf15bfcf 100644
--- a/src/compiler/scala/tools/nsc/io/Path.scala
+++ b/src/compiler/scala/tools/nsc/io/Path.scala
@@ -11,6 +11,7 @@ import java.io.{
BufferedInputStream, BufferedOutputStream, RandomAccessFile }
import java.net.{ URI, URL }
import scala.util.Random.alphanumeric
+import language.implicitConversions
/** An abstraction for filesystem paths. The differences between
* Path, File, and Directory are primarily to communicate intent.
diff --git a/src/compiler/scala/tools/nsc/io/Pickler.scala b/src/compiler/scala/tools/nsc/io/Pickler.scala
index 80b6e086da..416b84eec6 100644
--- a/src/compiler/scala/tools/nsc/io/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/io/Pickler.scala
@@ -3,6 +3,7 @@ package scala.tools.nsc.io
import annotation.unchecked
import Lexer._
import java.io.Writer
+import language.implicitConversions
/** An abstract class for writing and reading Scala objects to and
* from a legible representation. The presesentation follows the following grammar:
@@ -168,14 +169,11 @@ object Pickler {
case class ~[+S, +T](fst: S, snd: T)
/** A wrapper class to be able to use `~` s an infix method */
- class TildeDecorator[S](x: S) {
+ implicit class TildeDecorator[S](x: S) {
/** Infix method that forms a `~`-pair. */
def ~ [T](y: T): S ~ T = new ~ (x, y)
}
- /** An implicit wrapper that adds `~` as a method to any value. */
- implicit def tildeDecorator[S](x: S): TildeDecorator[S] = new TildeDecorator(x)
-
/** A converter from binary functions to functions over `~`-pairs
*/
implicit def fromTilde[T1, T2, R](f: (T1, T2) => R): T1 ~ T2 => R = { case x1 ~ x2 => f(x1, x2) }
@@ -418,7 +416,7 @@ object Pickler {
iterPickler[T] .wrapped { Vector() ++ _ } { _.iterator } .labelled ("scala.Vector")
/** A pickler for array values */
- implicit def array[T : ClassManifest : Pickler]: Pickler[Array[T]] =
+ implicit def array[T : ClassTag : Pickler]: Pickler[Array[T]] =
iterPickler[T] .wrapped { _.toArray} { _.iterator } .labelled ("scala.Array")
}
diff --git a/src/compiler/scala/tools/nsc/io/package.scala b/src/compiler/scala/tools/nsc/io/package.scala
index 88679e6dce..52e6de0bed 100644
--- a/src/compiler/scala/tools/nsc/io/package.scala
+++ b/src/compiler/scala/tools/nsc/io/package.scala
@@ -8,8 +8,11 @@ package scala.tools.nsc
import java.util.concurrent.{ Future, Callable }
import java.util.{ Timer, TimerTask }
import java.util.jar.{ Attributes }
+import language.implicitConversions
package object io {
+ implicit def postfixOps = language.postfixOps // make all postfix ops in this package compile without warning
+
type JManifest = java.util.jar.Manifest
type JFile = java.io.File
@@ -41,4 +44,4 @@ package object io {
alarm.schedule(tt, seconds * 1000)
alarm
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 06b06c50a6..ca3f3ff635 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -12,6 +12,7 @@ import scala.tools.nsc.util.OffsetPosition
import scala.collection.mutable.ListBuffer
import symtab.Flags
import JavaTokens._
+import language.implicitConversions
trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
val global : Global
diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
index 45b63b0ca0..d47756e757 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
@@ -10,6 +10,7 @@ import scala.tools.nsc.util._
import scala.reflect.internal.Chars._
import JavaTokens._
import scala.annotation.switch
+import language.implicitConversions
// Todo merge these better with Scanners
trait JavaScanners extends ast.parser.ScannersCommon {
diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
index 371f4bc4d8..72e6f32af1 100644
--- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
@@ -10,6 +10,7 @@ import transform.ExplicitOuter
import ast.{ TreePrinters, Trees }
import java.io.{ StringWriter, PrintWriter }
import annotation.elidable
+import language.postfixOps
/** Ancillary bits of ParallelMatching which are better off
* out of the way.
@@ -29,11 +30,10 @@ trait MatchSupport extends ast.TreeDSL { self: ParallelMatching =>
object Types {
import definitions._
- implicit def enrichType(x: Type): RichType = new RichType(x)
- val subrangeTypes = Set(ByteClass, ShortClass, CharClass, IntClass)
+ val subrangeTypes = Set[Symbol](ByteClass, ShortClass, CharClass, IntClass)
- class RichType(undecodedTpe: Type) {
+ implicit class RichType(undecodedTpe: Type) {
def tpe = decodedEqualsType(undecodedTpe)
def isAnyRef = tpe <:< AnyRefClass.tpe
diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala
index e1ff88557e..b29fac225a 100644
--- a/src/compiler/scala/tools/nsc/matching/Matrix.scala
+++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala
@@ -9,6 +9,7 @@ package matching
import transform.ExplicitOuter
import symtab.Flags
import scala.collection.mutable
+import language.implicitConversions
trait Matrix extends MatrixAdditions {
self: ExplicitOuter with ParallelMatching =>
@@ -255,4 +256,4 @@ trait Matrix extends MatrixAdditions {
recordSyntheticSym(owner.newVariable(n, pos, flagsLong) setInfo tpe)
}
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index be5a9907b8..7346d9c59f 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -14,6 +14,7 @@ import transform.ExplicitOuter
import symtab.Flags
import mutable.ListBuffer
import annotation.elidable
+import language.postfixOps
trait ParallelMatching extends ast.TreeDSL
with MatchSupport
@@ -425,7 +426,7 @@ trait ParallelMatching extends ast.TreeDSL
// Should the given pattern join the expanded pivot in the success matrix? If so,
// this partial function will be defined for the pattern, and the result of the apply
// is the expanded sequence of new patterns.
- lazy val successMatrixFn = new scala.runtime.AbstractPartialFunction[Pattern, List[Pattern]] {
+ lazy val successMatrixFn = new PartialFunction[Pattern, List[Pattern]] {
private def seqIsDefinedAt(x: SequenceLikePattern) = (hasStar, x.hasStar) match {
case (true, true) => true
case (true, false) => pivotLen <= x.nonStarLength
@@ -433,7 +434,7 @@ trait ParallelMatching extends ast.TreeDSL
case (false, false) => pivotLen == x.nonStarLength
}
- def _isDefinedAt(pat: Pattern) = pat match {
+ def isDefinedAt(pat: Pattern) = pat match {
case x: SequenceLikePattern => seqIsDefinedAt(x)
case WildcardPattern() => true
case _ => false
diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
index 56297f0195..b2a721c586 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
@@ -8,6 +8,7 @@ package matching
import transform.ExplicitOuter
import PartialFunction._
+import language.postfixOps
trait PatternBindings extends ast.TreeDSL
{
@@ -133,4 +134,4 @@ trait PatternBindings extends ast.TreeDSL
}
val NoBinding: Bindings = new Bindings(Nil)
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 8bdf83fda4..bbe22ca314 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -187,9 +187,9 @@ trait Patterns extends ast.TreeDSL {
// As yet I can't testify this is doing any good relative to using
// tpt.tpe, but it doesn't seem to hurt either.
private lazy val packedType = global.typer.computeType(tpt, tpt.tpe)
- private lazy val consRef = appliedType(ConsClass.typeConstructor, List(packedType))
- private lazy val listRef = appliedType(ListClass.typeConstructor, List(packedType))
- private lazy val seqRef = appliedType(SeqClass.typeConstructor, List(packedType))
+ private lazy val consRef = appliedType(ConsClass, packedType)
+ private lazy val listRef = appliedType(ListClass, packedType)
+ private lazy val seqRef = appliedType(SeqClass, packedType)
private def thisSeqRef = {
val tc = (tree.tpe baseType SeqClass).typeConstructor
@@ -343,10 +343,9 @@ trait Patterns extends ast.TreeDSL {
def apply(x: Apply): Pattern = {
val Apply(fn, args) = x
def isModule = x.symbol.isModule || x.tpe.termSymbol.isModule
- def isTuple = isTupleTypeOrSubtype(fn.tpe)
if (fn.isType) {
- if (isTuple) TuplePattern(x)
+ if (isTupleType(fn.tpe)) TuplePattern(x)
else ConstructorPattern(x)
}
else if (args.isEmpty) {
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
index 9254ec8628..48c4a9b5b3 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
@@ -138,7 +138,7 @@ object Plugin {
} yield entry)).distinct
val loader = loaderFor(alljars)
- alljars map (loadFrom(_, loader)) flatten
+ (alljars map (loadFrom(_, loader))).flatten
}
/** Instantiate a plugin class, given the class and
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugins.scala b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
index da913a1601..ba042b7b78 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugins.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
@@ -70,7 +70,7 @@ trait Plugins {
}
}
- val plugs = pick(roughPluginsList, Set(), phasesSet map (_.phaseName) toSet)
+ val plugs = pick(roughPluginsList, Set(), (phasesSet map (_.phaseName)).toSet)
/** Verify requirements are present. */
for (req <- settings.require.value ; if !(plugs exists (_.name == req)))
@@ -112,5 +112,5 @@ trait Plugins {
def pluginOptionsHelp: String =
(for (plug <- roughPluginsList ; help <- plug.optionsHelp) yield {
"\nOptions for plugin '%s':\n%s\n".format(plug.name, help)
- }) mkString
+ }).mkString
}
diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
index 2ba8c8eb6b..ab8fe23909 100644
--- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
@@ -35,17 +35,22 @@ abstract class AbstractReporter extends Reporter {
else _severity
if (severity == INFO) {
- if (isVerbose || force)
+ if (isVerbose || force) {
+ severity.count += 1
display(pos, msg, severity)
+ }
}
else {
val hidden = testAndLog(pos, severity)
if (severity == WARNING && noWarnings) ()
else {
- if (!hidden || isPromptSet)
+ if (!hidden || isPromptSet) {
+ severity.count += 1
display(pos, msg, severity)
- else if (settings.debug.value)
+ } else if (settings.debug.value) {
+ severity.count += 1
display(pos, "[ suppressed ] " + msg, severity)
+ }
if (isPromptSet)
displayPrompt
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index f5335fb0f5..956c43c35a 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -75,7 +75,6 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
}
def display(pos: Position, msg: String, severity: Severity) {
- severity.count += 1
if (severity != ERROR || severity.count <= ERROR_LIMIT)
print(pos, msg, severity)
}
diff --git a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
index ff0f94d897..8a918a829c 100644
--- a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
+++ b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
@@ -28,7 +28,7 @@ object Executor {
Console.setOut(newOut)
Console.setErr(newOut)
try {
- singletonInstance(name, classLoader)
+ singletonInstance(classLoader, name)
} catch {
case ex: Throwable =>
unwrapThrowable(ex) match {
diff --git a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala
index 9cea935a63..c1dad2da82 100644
--- a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala
@@ -35,7 +35,7 @@ trait AbsSettings extends scala.reflect.internal.settings.AbsSettings {
case s: AbsSettings => this.userSetSettings == s.userSetSettings
case _ => false
}
- override def toString() = "Settings {\n%s}\n" format (userSetSettings map (" " + _ + "\n") mkString)
+ override def toString() = "Settings {\n%s}\n" format (userSetSettings map (" " + _ + "\n")).mkString
def toConciseString = userSetSettings.mkString("(", " ", ")")
def checkDependencies =
diff --git a/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala b/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala
index c010c6a3ea..63775ff1c5 100644
--- a/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/AestheticSettings.scala
@@ -23,6 +23,7 @@ trait AestheticSettings {
def deprecation = settings.deprecation.value
def experimental = settings.Xexperimental.value
def fatalWarnings = settings.fatalWarnings.value
+ def feature = settings.feature.value
def future = settings.future.value
def logClasspath = settings.Ylogcp.value
def printStats = settings.Ystatistics.value
@@ -30,7 +31,7 @@ trait AestheticSettings {
def target = settings.target.value
def unchecked = settings.unchecked.value
def verbose = settings.verbose.value
- def virtPatmat = settings.YvirtPatmat.value
+ def virtPatmat = !settings.XoldPatmat.value
/** Derived values */
def jvm = target startsWith "jvm"
diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
index e7959f36b2..c4dd9a2a36 100644
--- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
@@ -28,7 +28,7 @@ class MutableSettings(val errorFn: String => Unit)
settings
}
- protected def copyInto(settings: MutableSettings) {
+ def copyInto(settings: MutableSettings) {
allSettings foreach { thisSetting =>
val otherSetting = settings.allSettings find { _.name == thisSetting.name }
otherSetting foreach { otherSetting =>
@@ -136,7 +136,7 @@ class MutableSettings(val errorFn: String => Unit)
val (p, args) = StringOps.splitWhere(s, _ == ':', true) getOrElse (return None)
// any non-Nil return value means failure and we return s unmodified
- tryToSetIfExists(p, args split "," toList, (s: Setting) => s.tryToSetColon _)
+ tryToSetIfExists(p, (args split ",").toList, (s: Setting) => s.tryToSetColon _)
}
// if arg is of form -Xfoo or -Xfoo bar (name = "-Xfoo")
@@ -183,8 +183,8 @@ class MutableSettings(val errorFn: String => Unit)
* The class loader defining `T` should provide resources `app.class.path`
* and `boot.class.path`. These resources should contain the application
* and boot classpaths in the same form as would be passed on the command line.*/
- def embeddedDefaults[T: Manifest]: Unit =
- embeddedDefaults(implicitly[Manifest[T]].erasure.getClassLoader)
+ def embeddedDefaults[T: ClassTag]: Unit =
+ embeddedDefaults(classTag[T].erasure.getClassLoader)
/** Initializes these settings for embedded use by a class from the given class loader.
* The class loader for `T` should provide resources `app.class.path`
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 5f3c7ec32c..91e31cae97 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -11,6 +11,7 @@ package settings
import annotation.elidable
import scala.tools.util.PathResolver.Defaults
import scala.collection.mutable
+import language.{implicitConversions, existentials}
trait ScalaSettings extends AbsScalaSettings
with StandardScalaSettings
@@ -30,6 +31,22 @@ trait ScalaSettings extends AbsScalaSettings
*/
protected def defaultClasspath = sys.env.getOrElse("CLASSPATH", ".")
+ /** Enabled under -Xexperimental. */
+ protected def experimentalSettings = List[BooleanSetting](YmethodInfer, overrideObjects, overrideVars)
+
+ /** Enabled under -Xfuture. */
+ protected def futureSettings = List[BooleanSetting]()
+
+ /** Enabled under -optimise. */
+ protected def optimiseSettings = List[BooleanSetting](inline, inlineHandlers, Xcloselim, Xdce)
+
+ /** Internal use - syntax enhancements. */
+ private class EnableSettings[T <: Setting](val s: T) {
+ def enabling(toEnable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toEnable foreach (_.value = true))
+ def andThen(f: s.T => Unit): s.type = s withPostSetHook (setting => f(setting.value))
+ }
+ private implicit def installEnableSettings[T <: Setting](s: T) = new EnableSettings(s)
+
/** Disable a setting */
def disable(s: Setting) = allSettings -= s
@@ -43,13 +60,10 @@ trait ScalaSettings extends AbsScalaSettings
*/
// argfiles is only for the help message
val argfiles = BooleanSetting ("@<file>", "A text file containing compiler arguments (options and source files)")
- val classpath = PathSetting ("-classpath", "Specify where to find user class files.", defaultClasspath) .
- withAbbreviation ("-cp")
+ val classpath = PathSetting ("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp"
val d = OutputSetting (outputDirs, ".")
- val optimise = BooleanSetting ("-optimise", "Generates faster bytecode by applying optimisations to the program") .
- withAbbreviation("-optimize") .
- withPostSetHook(set => List(inline, inlineHandlers, Xcloselim, Xdce) foreach (_.value = set.value))
val nospecialization = BooleanSetting ("-no-specialization", "Ignore @specialize annotations.")
+ val language = MultiStringSetting("-language", "feature", "Enable one or more language features.")
/**
* -X "Advanced" settings
@@ -64,11 +78,13 @@ trait ScalaSettings extends AbsScalaSettings
val elidebelow = IntSetting ("-Xelide-below", "Calls to @elidable methods are omitted if method priority is lower than argument",
elidable.MINIMUM, None, elidable.byName get _)
val noForwarders = BooleanSetting ("-Xno-forwarders", "Do not generate static forwarders in mirror classes.")
- val future = BooleanSetting ("-Xfuture", "Turn on future language features.")
val genPhaseGraph = StringSetting ("-Xgenerate-phase-graph", "file", "Generate the phase graphs (outputs .dot files) to fileX.dot.", "")
val XlogImplicits = BooleanSetting ("-Xlog-implicits", "Show more detail on why some implicits are not applicable.")
val logImplicitConv = BooleanSetting ("-Xlog-implicit-conversions", "Print a message whenever an implicit conversion is inserted.")
val logReflectiveCalls = BooleanSetting("-Xlog-reflective-calls", "Print a message when a reflective method call is generated")
+ val logRuntimeSplices = BooleanSetting("-Xlog-runtime-splices", "Print a message when Expr.eval or Expr.value cannot be resolved statically.")
+ val logFreeTerms = BooleanSetting ("-Xlog-free-terms", "Print a message when reification creates a free term.")
+ val logFreeTypes = BooleanSetting ("-Xlog-free-types", "Print a message when reification resorts to generating a free type.")
val maxClassfileName = IntSetting ("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, Some((72, 255)), _ => None)
val Xmigration28 = BooleanSetting ("-Xmigration", "Warn about constructs whose behavior may have changed between 2.7 and 2.8.")
val nouescape = BooleanSetting ("-Xno-uescape", "Disable handling of \\u unicode escapes.")
@@ -92,11 +108,7 @@ trait ScalaSettings extends AbsScalaSettings
val showPhases = BooleanSetting ("-Xshow-phases", "Print a synopsis of compiler phases.")
val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "")
- // Experimental Extensions
- val Xexperimental = BooleanSetting ("-Xexperimental", "Enable experimental extensions.") .
- withPostSetHook(set => List(YmethodInfer, overrideObjects) foreach (_.value = set.value))
- // YdepMethTpes, YvirtClasses,
- val Xmacros = BooleanSetting ("-Xmacros", "Enable macros.")
+ val XoldPatmat = BooleanSetting ("-Xoldpatmat", "Use the pre-2.10 pattern matcher. Otherwise, the 'virtualizing' pattern matcher is used in 2.10.")
/** Compatibility stubs for options whose value name did
* not previously match the option name.
@@ -111,83 +123,95 @@ trait ScalaSettings extends AbsScalaSettings
/**
* -Y "Private" settings
*/
- val overrideObjects = BooleanSetting ("-Yoverride-objects", "Allow member objects to be overridden.")
- val Yhelp = BooleanSetting ("-Y", "Print a synopsis of private options.")
- val browse = PhasesSetting ("-Ybrowse", "Browse the abstract syntax tree after")
- val check = PhasesSetting ("-Ycheck", "Check the tree at the end of")
- val Yshow = PhasesSetting ("-Yshow", "(Requires -Xshow-class or -Xshow-object) Show after")
- val Xcloselim = BooleanSetting ("-Yclosure-elim", "Perform closure elimination.")
- val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees.")
- val noCompletion = BooleanSetting ("-Yno-completion", "Disable tab-completion in the REPL.")
- val Xdce = BooleanSetting ("-Ydead-code", "Perform dead code elimination.")
- val debug = BooleanSetting ("-Ydebug", "Increase the quantity of debugging output.")
- // val doc = BooleanSetting ("-Ydoc", "Generate documentation")
- val termConflict = ChoiceSetting ("-Yresolve-term-conflict", "strategy", "Resolve term conflicts",
- List("package", "object", "error"), "error")
- val inline = BooleanSetting ("-Yinline", "Perform inlining when possible.")
- val inlineHandlers= BooleanSetting ("-Yinline-handlers", "Perform exception handler inlining when possible.")
- val Xlinearizer = ChoiceSetting ("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo")
- val log = PhasesSetting ("-Ylog", "Log operations during")
- val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.")
- val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.")
- val noimports = BooleanSetting ("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.")
- val nopredef = BooleanSetting ("-Yno-predef", "Compile without importing Predef.")
- val noAdaptedArgs = BooleanSetting ("-Yno-adapted-args", "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.")
- val Yprofile = PhasesSetting ("-Yprofile", "(Requires jvm -agentpath to contain yjgpagent) Profile CPU usage of")
- val YprofileMem = BooleanSetting ("-Yprofile-memory", "Profile memory, get heap snapshot after each compiler run (requires yjpagent, see above).")
- val YprofileClass = StringSetting ("-Yprofile-class", "class", "Name of profiler class.", "scala.tools.util.YourkitProfiling")
- val Yrecursion = IntSetting ("-Yrecursion", "Set recursion depth used when locking symbols.", 0, Some((0, Int.MaxValue)), (_: String) => None)
- val selfInAnnots = BooleanSetting ("-Yself-in-annots", "Include a \"self\" identifier inside of annotations.")
- val Xshowtrees = BooleanSetting ("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs.")
- val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.")
- val Yshowsymkinds = BooleanSetting ("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.")
- val skip = PhasesSetting ("-Yskip", "Skip")
- val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "")
- val Ydumpclasses = StringSetting ("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "")
- val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.")
- val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") .
- withPostSetHook(set => util.Statistics.enabled = set.value)
- val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat
- val stopBefore = PhasesSetting ("-Ystop-before", "Stop before")
- val refinementMethodDispatch =
- ChoiceSetting ("-Ystruct-dispatch", "policy", "structural method dispatch policy",
- List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache")
- val globalClass = StringSetting ("-Yglobal-class", "class", "subclass of scala.tools.nsc.Global to use for compiler", "")
- val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.")
- val YrichExes = BooleanSetting ("-Yrich-exceptions",
- "Fancier exceptions. Set source search path with -D" +
- sys.SystemProperties.traceSourcePath.key)
- val Yidedebug = BooleanSetting ("-Yide-debug", "Generate, validate and output trees using the interactive compiler.")
- val Ybuilderdebug = ChoiceSetting ("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none")
- val Ybuildmanagerdebug =
- BooleanSetting ("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.")
- val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignments.")
- val Yposdebug = BooleanSetting ("-Ypos-debug", "Trace position validation.")
- val Yinferdebug = BooleanSetting ("-Yinfer-debug", "Trace type inference and implicit search.")
- val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.")
- val Yreifycopypaste =
- BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
- val Yreifydebug = BooleanSetting ("-Yreify-debug", "Trace reification.")
- val Ymacrodebug = BooleanSetting ("-Ymacro-debug", "Trace macro-related activities: generation of synthetics, expansion, exceptions.")
- val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup")
- val Yrepldebug = BooleanSetting ("-Yrepl-debug", "Trace all repl activity.") .
- withPostSetHook(_ => interpreter.replProps.debug setValue true)
- val Ycompletion = BooleanSetting ("-Ycompletion-debug", "Trace all tab completion activity.")
- val Ydocdebug = BooleanSetting ("-Ydoc-debug", "Trace all scaladoc activity.")
- val Ypmatnaive = BooleanSetting ("-Ypmat-naive", "Desugar matches as naively as possible.")
- val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.")
- // val YdepMethTpes = BooleanSetting ("-Ydependent-method-types", "Allow dependent method types.")
- val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.")
- val etaExpandKeepsStar = BooleanSetting("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.")
- val noSelfCheck = BooleanSetting ("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.")
- val YvirtPatmat = BooleanSetting ("-Yvirtpatmat", "Translate pattern matches into flatMap/orElse calls. See scala.MatchingStrategy.")
- val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes")
+ val overrideObjects = BooleanSetting ("-Yoverride-objects", "Allow member objects to be overridden.")
+ val overrideVars = BooleanSetting ("-Yoverride-vars", "Allow vars to be overridden.")
+ val Yhelp = BooleanSetting ("-Y", "Print a synopsis of private options.")
+ val browse = PhasesSetting ("-Ybrowse", "Browse the abstract syntax tree after")
+ val check = PhasesSetting ("-Ycheck", "Check the tree at the end of")
+ val Yshow = PhasesSetting ("-Yshow", "(Requires -Xshow-class or -Xshow-object) Show after")
+ val Xcloselim = BooleanSetting ("-Yclosure-elim", "Perform closure elimination.")
+ val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees.")
+ val noCompletion = BooleanSetting ("-Yno-completion", "Disable tab-completion in the REPL.")
+ val Xdce = BooleanSetting ("-Ydead-code", "Perform dead code elimination.")
+ val debug = BooleanSetting ("-Ydebug", "Increase the quantity of debugging output.")
+ //val doc = BooleanSetting ("-Ydoc", "Generate documentation")
+ val termConflict = ChoiceSetting ("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
+ val inline = BooleanSetting ("-Yinline", "Perform inlining when possible.")
+ val inlineHandlers = BooleanSetting ("-Yinline-handlers", "Perform exception handler inlining when possible.")
+ val YinlinerWarnings= BooleanSetting ("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)")
+ val Xlinearizer = ChoiceSetting ("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo")
+ val log = PhasesSetting ("-Ylog", "Log operations during")
+ val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.")
+ val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.")
+ val noimports = BooleanSetting ("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.")
+ val nopredef = BooleanSetting ("-Yno-predef", "Compile without importing Predef.")
+ val noAdaptedArgs = BooleanSetting ("-Yno-adapted-args", "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.")
+ val Yprofile = PhasesSetting ("-Yprofile", "(Requires jvm -agentpath to contain yjgpagent) Profile CPU usage of")
+ val YprofileMem = BooleanSetting ("-Yprofile-memory", "Profile memory, get heap snapshot after each compiler run (requires yjpagent, see above).")
+ val YprofileClass = StringSetting ("-Yprofile-class", "class", "Name of profiler class.", "scala.tools.util.YourkitProfiling")
+ val Yrecursion = IntSetting ("-Yrecursion", "Set recursion depth used when locking symbols.", 0, Some((0, Int.MaxValue)), (_: String) => None)
+ val selfInAnnots = BooleanSetting ("-Yself-in-annots", "Include a \"self\" identifier inside of annotations.")
+ val Xshowtrees = BooleanSetting ("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs in formatted form.")
+ val XshowtreesCompact
+ = BooleanSetting ("-Yshow-trees-compact", "(Requires -Xprint:) Print detailed ASTs in compact form.")
+ val XshowtreesStringified
+ = BooleanSetting ("-Yshow-trees-stringified", "(Requires -Xprint:) Print stringifications along with detailed ASTs.")
+ val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.")
+ val Yshowsymkinds = BooleanSetting ("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.")
+ val skip = PhasesSetting ("-Yskip", "Skip")
+ val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "")
+ val Ydumpclasses = StringSetting ("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "")
+ val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.")
+ val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") andThen (util.Statistics.enabled = _)
+ val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat
+ val stopBefore = PhasesSetting ("-Ystop-before", "Stop before")
+ val refinementMethodDispatch
+ = ChoiceSetting ("-Ystruct-dispatch", "policy", "structural method dispatch policy", List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache")
+ val globalClass = StringSetting ("-Yglobal-class", "class", "subclass of scala.tools.nsc.Global to use for compiler", "")
+ val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.")
+ val YrichExes = BooleanSetting ("-Yrich-exceptions", "Fancier exceptions. Set source search path with -D" + sys.SystemProperties.traceSourcePath.key)
+ val Ybuilderdebug = ChoiceSetting ("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none")
+ val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
+ val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup")
+ val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.")
+ val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.")
+ val etaExpandKeepsStar = BooleanSetting ("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.")
+ 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 exposeEmptyPackage = BooleanSetting("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly()
val YnoProductN = BooleanSetting ("-Yno-productN", "Do not add ProductN to case classes")
def stop = stopAfter
+ /** Area-specific debug output.
+ */
+ val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.")
+ val Ycompletion = BooleanSetting("-Ycompletion-debug", "Trace all tab completion activity.")
+ val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.")
+ val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.")
+ val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.")
+ val Yissuedebug = BooleanSetting("-Yissue-debug", "Print stack traces when a context issues an error.")
+ val YmacrodebugLite = BooleanSetting("-Ymacro-debug-lite", "Trace essential macro-related activities.")
+ val YmacrodebugVerbose = BooleanSetting("-Ymacro-debug-verbose", "Trace all macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions.")
+ val Ypmatdebug = BooleanSetting("-Ypmat-debug", "Trace all pattern matcher activity.")
+ val Yposdebug = BooleanSetting("-Ypos-debug", "Trace position validation.")
+ val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.")
+ val Yrepldebug = BooleanSetting("-Yrepl-debug", "Trace all repl activity.") andThen (interpreter.replProps.debug setValue _)
+ val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.")
+
+ /** Groups of Settings.
+ */
+ 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 Xexperimental = BooleanSetting("-Xexperimental", "Enable experimental extensions.") enabling experimentalSettings
+
+ // Feature extensions
+ val Xmacros = BooleanSetting("-Xmacros", "Enable macros.") // [Martin] Can be retired now.
+ val XmacroSettings = MultiStringSetting("-Xmacro-settings", "option", "Custom settings for macros.")
+ val XmacroPrimaryClasspath = PathSetting("-Xmacro-primary-classpath", "Classpath to load macros implementations from, defaults to compilation classpath (aka \"library classpath\".", "")
+ val XmacroFallbackClasspath = PathSetting("-Xmacro-fallback-classpath", "Classpath to load macros implementations from if they cannot be loaded from library classpath.", "")
+
/**
* IDE-specific settings
*/
@@ -204,4 +228,7 @@ trait ScalaSettings extends AbsScalaSettings
*/
val pluginOptions = MultiStringSetting("-P", "plugin:opt", "Pass an option to a plugin") .
withHelpSyntax("-P:<plugin>:<opt>")
+
+ /** Test whether this is scaladoc we're looking at */
+ def isScaladoc = false
}
diff --git a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
index c5b477c7bd..a69b88a5df 100644
--- a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
@@ -32,6 +32,7 @@ trait StandardScalaSettings {
val deprecation = BooleanSetting ("-deprecation", "Emit warning and location for usages of deprecated APIs.")
val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files.", Properties.sourceEncoding)
val explaintypes = BooleanSetting ("-explaintypes", "Explain type errors in more detail.")
+ val feature = BooleanSetting ("-feature", "Emit warning and location for usages of features that should be imported explicitly.")
val g = ChoiceSetting ("-g", "level", "Set level of generated debugging info.", List("none", "source", "line", "vars", "notailcalls"), "vars")
val help = BooleanSetting ("-help", "Print a synopsis of standard options")
val make = ChoiceSetting ("-make", "policy", "Recompilation detection policy", List("all", "changed", "immediate", "transitive", "transitivenocp"), "all")
diff --git a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
index 59342a36ef..5f7deb87bd 100644
--- a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
@@ -105,7 +105,7 @@ abstract class BrowsingLoaders extends SymbolLoaders {
*/
override def enterToplevelsFromSource(root: Symbol, name: String, src: AbstractFile) {
try {
- if (root == definitions.RootClass || root == definitions.EmptyPackageClass)
+ if (root.isEffectiveRoot) // RootClass or EmptyPackageClass
super.enterToplevelsFromSource(root, name, src)
else
browseTopLevel(root, src)
diff --git a/src/compiler/scala/tools/nsc/symtab/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala
deleted file mode 100644
index c96c709fb0..0000000000
--- a/src/compiler/scala/tools/nsc/symtab/Positions.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-package scala.tools.nsc
-package symtab
-
-import scala.tools.nsc.util.{ SourceFile, Position, OffsetPosition, NoPosition }
-
-trait Positions extends scala.reflect.internal.Positions {
-self: scala.tools.nsc.symtab.SymbolTable =>
-
- def rangePos(source: SourceFile, start: Int, point: Int, end: Int) =
- new OffsetPosition(source, point)
-
- def validatePositions(tree: Tree) {}
-
- type Position = scala.tools.nsc.util.Position
- val NoPosition = scala.tools.nsc.util.NoPosition
-
- def focusPos(pos: Position): Position = pos.focus
- def isRangePos(pos: Position): Boolean = pos.isRange
- def showPos(pos: Position): String = pos.show
-
-}
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 942ec1fa86..7eb04eaf40 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -30,15 +30,11 @@ abstract class SymbolLoaders {
member
}
- private def realOwner(root: Symbol): Symbol = {
- if (root.isRoot) definitions.EmptyPackageClass else root
- }
-
/** Enter class with given `name` into scope of `root`
* and give them `completer` as type.
*/
def enterClass(root: Symbol, name: String, completer: SymbolLoader): Symbol = {
- val owner = realOwner(root)
+ val owner = root.ownerOfNewSymbols
val clazz = owner.newClass(newTypeName(name))
clazz setInfo completer
enterIfNew(owner, clazz, completer)
@@ -48,7 +44,7 @@ abstract class SymbolLoaders {
* and give them `completer` as type.
*/
def enterModule(root: Symbol, name: String, completer: SymbolLoader): Symbol = {
- val owner = realOwner(root)
+ val owner = root.ownerOfNewSymbols
val module = owner.newModule(newTermName(name))
module setInfo completer
module.moduleClass setInfo moduleClassLoader
@@ -126,9 +122,13 @@ abstract class SymbolLoaders {
ok = false
if (settings.debug.value) ex.printStackTrace()
val msg = ex.getMessage()
- globalError(
- if (msg eq null) "i/o error while loading " + root.name
- else "error while loading " + root.name + ", " + msg);
+ // 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
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
index fb85ebeeb0..75b486ca7d 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
@@ -6,7 +6,4 @@
package scala.tools.nsc
package symtab
-import ast.{Trees, TreePrinters, DocComments}
-import util._
-
abstract class SymbolTable extends reflect.internal.SymbolTable \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
index e62070a239..3cf5cc2f54 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
@@ -7,6 +7,8 @@ package scala.tools.nsc
package symtab
import scala.collection.{ mutable, immutable }
+import language.implicitConversions
+import language.postfixOps
/** Printing the symbol graph (for those symbols attached to an AST node)
* after each phase.
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 1cd4ab21ea..3d3cea75d6 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -433,10 +433,7 @@ abstract class ClassfileParser {
sym.info.decl(part.encode)
}//.suchThat(module == _.isModule)
- sym = (
- if (sym1 ne NoSymbol) sym1
- else sym.info.decl(part.encode.toTypeName)
- )
+ sym = sym1 orElse sym.info.decl(part.encode.toTypeName)
}
}
sym
@@ -446,7 +443,11 @@ abstract class ClassfileParser {
def classNameToSymbol(name: Name): Symbol = {
def loadClassSymbol(name: Name): Symbol = {
val file = global.classPath findSourceFile ("" +name) getOrElse {
- warning("Class " + name + " not found - continuing with a stub.")
+ // 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)
+ warning("Class " + name + " not found - continuing with a stub.")
return NoSymbol.newClass(name.toTypeName)
}
val completer = new global.loaders.ClassfileLoader(file)
@@ -775,7 +776,8 @@ abstract class ClassfileParser {
// with arrays of primitive types.
if (elemtp.typeSymbol.isAbstractType && !(elemtp <:< definitions.ObjectClass.tpe))
elemtp = intersectionType(List(elemtp, definitions.ObjectClass.tpe))
- appliedType(definitions.ArrayClass.tpe, List(elemtp))
+
+ definitions.arrayType(elemtp)
case '(' =>
// we need a method symbol. given in line 486 by calling getType(methodSym, ..)
assert(sym ne null, sig)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 68af518d3a..862a3ffdc7 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -165,7 +165,7 @@ abstract class ICodeReader extends ClassfileParser {
else if (name == fulltpnme.RuntimeNull)
definitions.NullClass
else if (nme.isImplClassName(name)) {
- val iface = definitions.getClass(nme.interfaceName(name))
+ val iface = definitions.getClass(tpnme.interfaceName(name))
log("forcing " + iface.owner + " at phase: " + phase + " impl: " + iface.implClass)
iface.owner.info // force the mixin type-transformer
definitions.getClass(name)
@@ -625,11 +625,11 @@ abstract class ICodeReader extends ClassfileParser {
* such as Int.box(5).
*/
def isBox(m: Symbol): Boolean =
- (m.owner == definitions.BoxesRunTimeClass.moduleClass
+ (m.owner == definitions.BoxesRunTimeClass
&& m.name.startsWith("boxTo"))
def isUnbox(m: Symbol): Boolean =
- (m.owner == definitions.BoxesRunTimeClass.moduleClass
+ (m.owner == definitions.BoxesRunTimeClass
&& m.name.startsWith("unboxTo"))
/** Return the icode class that should include members with the given flags.
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 758f870d6b..192cc94b90 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -62,9 +62,16 @@ abstract class Pickler extends SubComponent {
// when we pickle it: so let's report an error instead. We know next
// to nothing about what happened, but our supposition is a lot better
// than "bad type: <error>" in terms of explanatory power.
- for (t <- unit.body ; if t.isErroneous) {
- unit.error(t.pos, "erroneous or inaccessible type")
- return
+ for (t <- unit.body) {
+ if (t.isErroneous) {
+ unit.error(t.pos, "erroneous or inaccessible type")
+ return
+ }
+
+ if (!t.isDef && t.hasSymbol && t.symbol.isTermMacro) {
+ unit.error(t.pos, "macro has not been expanded")
+ return
+ }
}
pickle(unit.body)
@@ -149,7 +156,7 @@ abstract class Pickler extends SubComponent {
putChildren(sym, children.toList sortBy (_.sealedSortName))
}
- for (annot <- sym.annotations filter (ann => ann.isStatic && !ann.isErroneous) reverse)
+ for (annot <- (sym.annotations filter (ann => ann.isStatic && !ann.isErroneous)).reverse)
putAnnotation(sym, annot)
}
else if (sym != NoSymbol) {
@@ -425,7 +432,7 @@ abstract class Pickler extends SubComponent {
private def putConstant(c: Constant) {
if (putEntry(c)) {
if (c.tag == StringTag) putEntry(newTermName(c.stringValue))
- else if (c.tag == ClassTag) putType(c.typeValue)
+ else if (c.tag == ClazzTag) putType(c.typeValue)
else if (c.tag == EnumTag) putSymbol(c.symbolValue)
}
}
@@ -606,7 +613,7 @@ abstract class Pickler extends SubComponent {
else if (c.tag == FloatTag) writeLong(floatToIntBits(c.floatValue))
else if (c.tag == DoubleTag) writeLong(doubleToLongBits(c.doubleValue))
else if (c.tag == StringTag) writeRef(newTermName(c.stringValue))
- else if (c.tag == ClassTag) writeRef(c.typeValue)
+ else if (c.tag == ClazzTag) writeRef(c.typeValue)
else if (c.tag == EnumTag) writeRef(c.symbolValue)
LITERAL + c.tag // also treats UnitTag, NullTag; no value required
case AnnotatedType(annotations, tp, selfsym) =>
@@ -1059,7 +1066,7 @@ abstract class Pickler extends SubComponent {
else if (c.tag == FloatTag) print("Float "+c.floatValue)
else if (c.tag == DoubleTag) print("Double "+c.doubleValue)
else if (c.tag == StringTag) { print("String "); printRef(newTermName(c.stringValue)) }
- else if (c.tag == ClassTag) { print("Class "); printRef(c.typeValue) }
+ else if (c.tag == ClazzTag) { print("Class "); printRef(c.typeValue) }
else if (c.tag == EnumTag) { print("Enum "); printRef(c.symbolValue) }
case AnnotatedType(annots, tp, selfsym) =>
if (settings.selfInAnnots.value) {
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index 4b847fa94a..028d6f2484 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -12,6 +12,7 @@ import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute,
import scala.collection.{ mutable, immutable }
import scala.reflect.internal.pickling.UnPickler
import ch.epfl.lamp.compiler.msil.Type.TMVarUsage
+import language.implicitConversions
/**
* @author Nikolay Mihaylov
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 39e2cbe694..3581f1b923 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -43,11 +43,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
*/
private def isInterfaceMember(sym: Symbol) = (
sym.isType || {
- // !!! Shouldn't the following code be equivalent to leaving
- // out the "sym.info" call and starting with "sym.initialize.isMethod" ?
- // Because, it is not, which I found a little disturbing. The compiler
- // fails to bootstrap with an error somewhere.
- sym.info // initialize to set lateMETHOD flag if necessary
+ sym.info // initialize to set lateMETHOD flag if necessary
( sym.isMethod
&& !sym.isLabel
@@ -68,57 +64,60 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
def implClassPhase = currentRun.erasurePhase.next
- /** Return the implementation class of a trait; create a new one of one does not yet exist */
- def implClass(iface: Symbol): Symbol = {
- iface.info
-
- implClassMap.getOrElse(iface, {
- atPhase(implClassPhase) {
- if (iface.implClass ne NoSymbol)
- log("%s.implClass == %s".format(iface, iface.implClass))
+ private def newImplClass(iface: Symbol): Symbol = {
+ val inClass = iface.owner.isClass
+ val implName = tpnme.implClassName(iface.name)
+ val implFlags = (iface.flags & ~(INTERFACE | lateINTERFACE)) | IMPLCLASS
- val implName = nme.implClassName(iface.name)
- var impl = if (iface.owner.isClass) iface.owner.info.decl(implName) else NoSymbol
-
- // !!! Why does forcing the impl's info here lead to a crash?
- // See test case pos/trait-force-info.scala for a minimization.
- // It crashes like this:
- //
- // [log lazyvals] trait ContextTrees.implClass == class ContextTrees$class
- // error: java.lang.AssertionError: assertion failed: (scala.tools.nsc.typechecker.Contexts$NoContext$,scala.tools.nsc.typechecker.Contexts,NoContext$,trait Contexts in package typechecker) / while parsing (/scala/trunk/build/pack/lib/scala-compiler.jar(scala/tools/nsc/interactive/ContextTrees$class.class),Some(class ContextTrees$class))trait Contexts.NoContext$ linkedModule: <none>List()
-
- val originalImpl = impl
- if (impl != NoSymbol) {
+ val impl0 = (
+ if (!inClass) NoSymbol
+ else iface.owner.info.decl(implName) match {
+ case NoSymbol => NoSymbol
+ case implSym =>
// Unlink a pre-existing symbol only if the implementation class is
// visible on the compilation classpath. In general this is true under
// -optimise and not otherwise, but the classpath can use arbitrary
// logic so the classpath must be queried.
if (classPath.context.isValidName(implName + ".class")) {
- log("unlinking impl class " + impl)
- iface.owner.info.decls.unlink(impl)
- impl = NoSymbol
+ log("unlinking impl class " + implSym)
+ iface.owner.info.decls unlink implSym
+ NoSymbol
+ }
+ else {
+ log("not unlinking existing " + implSym + " as the impl class is not visible on the classpath.")
+ implSym
}
- else log("not unlinking existing " + impl + " as the impl class is not visible on the classpath.")
- }
- if (impl == NoSymbol) {
- impl = iface.cloneSymbolImpl(iface.owner)
- impl.name = implName
- impl.sourceFile = iface.sourceFile
- if (iface.owner.isClass)
- iface.owner.info.decls enter impl
- }
- if (currentRun.compiles(iface)) currentRun.symSource(impl) = iface.sourceFile
- impl setPos iface.pos
- impl.flags = iface.flags & ~(INTERFACE | lateINTERFACE) | IMPLCLASS
- impl setInfo new LazyImplClassType(iface)
- implClassMap(iface) = impl
- debuglog(
- "generating impl class " + impl.debugLocationString + " in " + iface.owner + (
- if (originalImpl == NoSymbol) "" else " (cloned from " + originalImpl.debugLocationString + ")"
- )
- )
- impl
}
+ )
+ val impl = impl0 orElse {
+ val impl = iface.owner.newImplClass(implName, iface.pos, implFlags)
+ if (iface.thisSym != iface) {
+ impl.typeOfThis = iface.typeOfThis
+ impl.thisSym setName iface.thisSym.name
+ }
+ impl.sourceFile = iface.sourceFile
+ if (inClass)
+ iface.owner.info.decls enter impl
+
+ impl
+ }
+ if (currentRun compiles iface)
+ currentRun.symSource(impl) = iface.sourceFile
+
+ implClassMap(iface) = impl
+ impl setInfo new LazyImplClassType(iface)
+ }
+
+ /** Return the implementation class of a trait; create a new one of one does not yet exist */
+ def implClass(iface: Symbol): Symbol = {
+ iface.info
+
+ implClassMap.getOrElse(iface, atPhase(implClassPhase) {
+ log("Creating implClass for " + iface)
+ if (iface.implClass ne NoSymbol)
+ log("%s.implClass already exists: %s".format(iface, iface.implClass))
+
+ newImplClass(iface)
})
}
@@ -138,22 +137,31 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
* given the decls ifaceDecls of its interface.
*/
private def implDecls(implClass: Symbol, ifaceDecls: Scope): Scope = {
+ log("LazyImplClassType calculating decls for " + implClass)
+
val decls = newScope
- if ((ifaceDecls lookup nme.MIXIN_CONSTRUCTOR) == NoSymbol)
+ if ((ifaceDecls lookup nme.MIXIN_CONSTRUCTOR) == NoSymbol) {
+ log("Adding mixin constructor to " + implClass)
+
decls enter (
implClass.newMethod(nme.MIXIN_CONSTRUCTOR, implClass.pos)
setInfo MethodType(Nil, UnitClass.tpe)
)
+ }
- for (sym <- ifaceDecls.iterator) {
+ for (sym <- ifaceDecls) {
if (isInterfaceMember(sym)) {
if (needsImplMethod(sym)) {
- val impl = sym.cloneSymbol(implClass).resetFlag(lateDEFERRED)
- if (currentRun.compiles(implClass)) implMethodMap(sym) = impl
- decls enter impl
+ log("Cloning " + sym + " for implementation method in " + implClass)
+ val clone = sym.cloneSymbol(implClass).resetFlag(lateDEFERRED)
+ if (currentRun.compiles(implClass)) implMethodMap(sym) = clone
+ decls enter clone
sym setFlag lateDEFERRED
}
- } else {
+ else log(sym + " needs no implementation method in " + implClass)
+ }
+ else {
+ log("Destructively modifying owner of %s from %s to %s".format(sym, sym.owner, implClass))
sym.owner = implClass
// note: OK to destructively modify the owner here,
// because symbol will not be accessible from outside the sourcefile.
@@ -161,14 +169,17 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
decls enter sym
}
}
+
decls
}
- override def complete(sym: Symbol) {
+ override def complete(implSym: Symbol) {
+ log("LazyImplClassType completing " + implSym)
+
/** If `tp` refers to a non-interface trait, return a
* reference to its implementation class. Otherwise return `tp`.
*/
- def mixinToImplClass(tp: Type): Type = erasure(sym) {
+ def mixinToImplClass(tp: Type): Type = AddInterfaces.this.erasure(implSym) {
tp match { //@MATN: no normalize needed (comes after erasure)
case TypeRef(pre, sym, _) if sym.needsImplClass =>
typeRef(pre, implClass(sym), Nil)
@@ -179,15 +190,13 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
def implType(tp: Type): Type = tp match {
case ClassInfoType(parents, decls, _) =>
assert(phase == implClassPhase, tp)
- ClassInfoType(
- ObjectClass.tpe +: (parents.tail map mixinToImplClass filter (_.typeSymbol != ObjectClass)) :+ iface.tpe,
- implDecls(sym, decls),
- sym
- )
+ // Impl class parents: Object first, matching interface last.
+ val implParents = ObjectClass.tpe +: (parents.tail map mixinToImplClass filter (_.typeSymbol != ObjectClass)) :+ iface.tpe
+ ClassInfoType(implParents, implDecls(implSym, decls), implSym)
case PolyType(_, restpe) =>
implType(restpe)
}
- sym setInfo implType(beforeErasure(iface.info))
+ implSym setInfo implType(beforeErasure(iface.info))
}
override def load(clazz: Symbol) { complete(clazz) }
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index b21fa4bc83..bf01e142c9 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -9,6 +9,7 @@ package transform
import symtab._
import Flags._
import scala.collection._
+import language.postfixOps
abstract class CleanUp extends Transform with ast.TreeDSL {
import global._
@@ -299,11 +300,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def testForName(name: Name): Tree => Tree = t => (
if (nme.CommonOpNames(name))
- gen.mkMethodCall(getMember(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean), t :: Nil)
+ gen.mkMethodCall(definitions.Boxes_isNumberOrBool, t :: Nil)
else if (nme.BooleanOpNames(name))
t IS_OBJ BoxedBooleanClass.tpe
else
- gen.mkMethodCall(getMember(BoxesRunTimeClass, nme.isBoxedNumber), t :: Nil)
+ gen.mkMethodCall(definitions.Boxes_isNumber, t :: Nil)
)
/** The Tree => Tree function in the return is necessary to prevent the original qual
@@ -318,8 +319,10 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
else if (params.tail.isEmpty) nme.primitiveInfixMethodName(name)
else nme.NO_NAME
)
- if (methodName == nme.NO_NAME) None
- else Some((getMember(BoxesRunTimeClass, methodName), testForName(name)))
+ definitions.getDeclIfDefined(BoxesRunTimeClass, methodName) match {
+ case NoSymbol => None
+ case sym => assert(!sym.isOverloaded, sym) ; Some((sym, testForName(name)))
+ }
}
/* ### BOXING PARAMS & UNBOXING RESULTS ### */
@@ -540,7 +543,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
if (forMSIL) savingStatics( transformTemplate(tree) )
else transformTemplate(tree)
- case Literal(c) if (c.tag == ClassTag) && !forMSIL=>
+ case Literal(c) if (c.tag == ClazzTag) && !forMSIL=>
val tpe = c.typeValue
typedWithPos(tree.pos) {
if (isPrimitiveValueClass(tpe.typeSymbol)) {
@@ -608,7 +611,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val ntree = typedWithPos(tree.pos)(safeREF(staticFieldSym))
super.transform(ntree)
- // This transform replaces Array(Predef.wrapArray(Array(...)), <manifest>)
+ // This transform replaces Array(Predef.wrapArray(Array(...)), <tag>)
// with just Array(...)
case Apply(appMeth, List(Apply(wrapRefArrayMeth, List(array)), _))
if (wrapRefArrayMeth.symbol == Predef_wrapRefArray &&
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index a98cd5c6b1..338c39dc5f 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -210,7 +210,7 @@ abstract class Erasure extends AddInterfaces
}
else parents
)
- ps map boxedSig mkString
+ (ps map boxedSig).mkString
}
def boxedSig(tp: Type) = jsig(tp, primitiveOK = false)
def boundsSig(bounds: List[Type]) = traceSig("boundsSig", bounds) {
@@ -407,6 +407,102 @@ abstract class Erasure extends AddInterfaces
}
}
+ class ComputeBridges(owner: Symbol) {
+ assert(phase == currentRun.erasurePhase, phase)
+
+ var toBeRemoved = immutable.Set[Symbol]()
+ val site = owner.thisType
+ val bridgesScope = newScope
+ val bridgeTarget = mutable.HashMap[Symbol, Symbol]()
+ var bridges = List[Tree]()
+
+ val opc = beforeExplicitOuter {
+ new overridingPairs.Cursor(owner) {
+ override def parents = List(owner.info.firstParent)
+ override def exclude(sym: Symbol) = !sym.isMethod || sym.isPrivate || super.exclude(sym)
+ }
+ }
+
+ def compute(): (List[Tree], immutable.Set[Symbol]) = {
+ while (opc.hasNext) {
+ val member = opc.overriding
+ val other = opc.overridden
+ //println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString)//DEBUG
+ if (beforeExplicitOuter(!member.isDeferred))
+ checkPair(member, other)
+
+ opc.next
+ }
+ (bridges, toBeRemoved)
+ }
+
+ def checkPair(member: Symbol, other: Symbol) {
+ val otpe = erasure(owner)(other.tpe)
+ val bridgeNeeded = afterErasure (
+ !(other.tpe =:= member.tpe) &&
+ !(deconstMap(other.tpe) =:= deconstMap(member.tpe)) &&
+ { var e = bridgesScope.lookupEntry(member.name)
+ while ((e ne null) && !((e.sym.tpe =:= otpe) && (bridgeTarget(e.sym) == member)))
+ e = bridgesScope.lookupNextEntry(e)
+ (e eq null)
+ }
+ )
+ if (!bridgeNeeded)
+ return
+
+ val newFlags = (member.flags | BRIDGE) & ~(ACCESSOR | DEFERRED | LAZY | lateDEFERRED)
+ val bridge = other.cloneSymbolImpl(owner, newFlags) setPos owner.pos
+
+ debuglog("generating bridge from %s (%s): %s to %s: %s".format(
+ other, flagsToString(newFlags),
+ otpe + other.locationString, member,
+ erasure(owner)(member.tpe) + member.locationString)
+ )
+
+ // the parameter symbols need to have the new owner
+ bridge setInfo (otpe cloneInfo bridge)
+ bridgeTarget(bridge) = member
+ afterErasure(owner.info.decls enter bridge)
+ if (other.owner == owner) {
+ afterErasure(owner.info.decls.unlink(other))
+ toBeRemoved += other
+ }
+ bridgesScope enter bridge
+ bridges ::= makeBridgeDefDef(bridge, member, other)
+ }
+
+ def makeBridgeDefDef(bridge: Symbol, member: Symbol, other: Symbol) = afterErasure {
+ // type checking ensures we can safely call `other`, but unless `member.tpe <:< other.tpe`,
+ // calling `member` is not guaranteed to succeed in general, there's
+ // nothing we can do about this, except for an unapply: when this subtype test fails,
+ // return None without calling `member`
+ //
+ // TODO: should we do this for user-defined unapplies as well?
+ // does the first argument list have exactly one argument -- for user-defined unapplies we can't be sure
+ def maybeWrap(bridgingCall: Tree): Tree = {
+ val canReturnNone = ( // can't statically know which member is going to be selected, so don't let this depend on member.isSynthetic
+ (member.name == nme.unapply || member.name == nme.unapplySeq)
+ && !afterErasure((member.tpe <:< other.tpe))) // no static guarantees (TODO: is the subtype test ever true?)
+
+ if (canReturnNone) {
+ import CODE._
+ val typeTest = gen.mkIsInstanceOf(REF(bridge.firstParam), member.tpe.params.head.tpe)
+ IF (typeTest) THEN bridgingCall ELSE REF(NoneModule)
+ }
+ else bridgingCall
+ }
+ val rhs = member.tpe match {
+ case MethodType(Nil, ConstantType(c)) => Literal(c)
+ case _ =>
+ val sel: Tree = Select(This(owner), member)
+ val bridgingCall = (sel /: bridge.paramss)((fun, vparams) => Apply(fun, vparams map Ident))
+
+ maybeWrap(bridgingCall)
+ }
+ atPos(bridge.pos)(DefDef(bridge, rhs))
+ }
+ }
+
/** The modifier typer which retypes with erased types. */
class Eraser(_context: Context) extends Typer(_context) {
@@ -521,8 +617,12 @@ abstract class Erasure extends AddInterfaces
// See SI-4731 for one example of how this occurs.
log("Attempted to cast to Unit: " + tree)
tree.duplicate setType pt
- }
- else gen.mkAttributedCast(tree, pt)
+ } else if (tree.tpe != null && tree.tpe.typeSymbol == ArrayClass && pt.typeSymbol == ArrayClass) {
+ // See SI-2386 for one example of when this might be necessary.
+ val needsExtraCast = isScalaValueType(tree.tpe.typeArgs.head) && !isScalaValueType(pt.typeArgs.head)
+ val tree1 = if (needsExtraCast) gen.mkRuntimeCall(nme.toObjectArray, List(tree)) else tree
+ gen.mkAttributedCast(tree1, pt)
+ } else gen.mkAttributedCast(tree, pt)
}
/** Adapt `tree` to expected type `pt`.
@@ -568,6 +668,7 @@ abstract class Erasure extends AddInterfaces
*/
private def adaptMember(tree: Tree): Tree = {
//Console.println("adaptMember: " + tree);
+ val x = 2 + 2
tree match {
case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List())
if tree.symbol == Any_asInstanceOf =>
@@ -637,7 +738,7 @@ abstract class Erasure extends AddInterfaces
/** A replacement for the standard typer's `typed1` method.
*/
- override protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = {
+ override def typed1(tree: Tree, mode: Int, pt: Type): Tree = {
val tree1 = try {
tree match {
case InjectDerivedValue(arg) =>
@@ -790,93 +891,10 @@ abstract class Erasure extends AddInterfaces
* type of `m1` in the template.
*/
private def bridgeDefs(owner: Symbol): (List[Tree], immutable.Set[Symbol]) = {
- var toBeRemoved: immutable.Set[Symbol] = immutable.Set()
- debuglog("computing bridges for " + owner)//DEBUG
assert(phase == currentRun.erasurePhase, phase)
- val site = owner.thisType
- val bridgesScope = newScope
- val bridgeTarget = new mutable.HashMap[Symbol, Symbol]
- var bridges: List[Tree] = List()
- val opc = beforeExplicitOuter {
- new overridingPairs.Cursor(owner) {
- override def parents: List[Type] = List(owner.info.firstParent)
- override def exclude(sym: Symbol): Boolean =
- !sym.isMethod || sym.isPrivate || super.exclude(sym)
- }
- }
- while (opc.hasNext) {
- val member = opc.overriding
- val other = opc.overridden
- //println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString)//DEBUG
- if (beforeExplicitOuter(!member.isDeferred)) {
- val otpe = erasure(owner)(other.tpe)
- val bridgeNeeded = afterErasure (
- !(other.tpe =:= member.tpe) &&
- !(deconstMap(other.tpe) =:= deconstMap(member.tpe)) &&
- { var e = bridgesScope.lookupEntry(member.name)
- while ((e ne null) && !((e.sym.tpe =:= otpe) && (bridgeTarget(e.sym) == member)))
- e = bridgesScope.lookupNextEntry(e)
- (e eq null)
- }
- );
- if (bridgeNeeded) {
- val newFlags = (member.flags | BRIDGE) & ~(ACCESSOR | DEFERRED | LAZY | lateDEFERRED)
- val bridge = other.cloneSymbolImpl(owner, newFlags) setPos owner.pos
- // the parameter symbols need to have the new owner
- bridge.setInfo(otpe.cloneInfo(bridge))
- bridgeTarget(bridge) = member
- afterErasure { owner.info.decls.enter(bridge) }
- if (other.owner == owner) {
- //println("bridge to same: "+other+other.locationString)//DEBUG
- afterErasure { owner.info.decls.unlink(other) }
- toBeRemoved += other
- }
- bridgesScope enter bridge
- bridges =
- afterErasure {
- atPos(bridge.pos) {
- val bridgeDef =
- DefDef(bridge,
- member.tpe match {
- case MethodType(List(), ConstantType(c)) => Literal(c)
- case _ =>
- val bridgingCall = (((Select(This(owner), member): Tree) /: bridge.paramss)
- ((fun, vparams) => Apply(fun, vparams map Ident)))
- // type checking ensures we can safely call `other`, but unless `member.tpe <:< other.tpe`, calling `member` is not guaranteed to succeed
- // in general, there's nothing we can do about this, except for an unapply: when this subtype test fails, return None without calling `member`
- if ( member.isSynthetic // TODO: should we do this for user-defined unapplies as well?
- && ((member.name == nme.unapply) || (member.name == nme.unapplySeq))
- // && (bridge.paramss.nonEmpty && bridge.paramss.head.nonEmpty && bridge.paramss.head.tail.isEmpty) // does the first argument list has exactly one argument -- for user-defined unapplies we can't be sure
- && !(afterErasure(member.tpe <:< other.tpe))) { // no static guarantees (TODO: is the subtype test ever true?)
- import CODE._
- val typeTest = gen.mkIsInstanceOf(REF(bridge.firstParam), member.tpe.params.head.tpe, any = true, wrapInApply = true) // any = true since we're before erasure (?), wrapInapply is true since we're after uncurry
- // println("unapp type test: "+ typeTest)
- IF (typeTest) THEN bridgingCall ELSE REF(NoneModule)
- } else bridgingCall
- });
- debuglog("generating bridge from " + other + "(" + Flags.flagsToString(bridge.flags) + ")" + ":" + otpe + other.locationString + " to " + member + ":" + erasure(owner)(member.tpe) + member.locationString + " =\n " + bridgeDef);
- bridgeDef
- }
- } :: bridges
- }
- }
- opc.next
- }
- (bridges, toBeRemoved)
+ debuglog("computing bridges for " + owner)
+ new ComputeBridges(owner) compute()
}
-/*
- for (bc <- site.baseClasses.tail; other <- bc.info.decls.toList) {
- if (other.isMethod && !other.isConstructor) {
- for (member <- site.nonPrivateMember(other.name).alternatives) {
- if (member != other &&
- !(member hasFlag DEFERRED) &&
- (site.memberType(member) matches site.memberType(other)) &&
- !(site.parents exists (p =>
- (p.symbol isSubClass member.owner) && (p.symbol isSubClass other.owner)))) {
-...
- }
- }
-*/
def addBridges(stats: List[Tree], base: Symbol): List[Tree] =
if (base.isTrait) stats
@@ -979,7 +997,7 @@ abstract class Erasure extends AddInterfaces
}
// Rewrite 5.getClass to ScalaRunTime.anyValClass(5)
else if (isPrimitiveValueClass(qual.tpe.typeSymbol))
- global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual)))
+ global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveErasureTag(tree.pos, qual.tpe.widen, true))))
else
tree
@@ -1076,7 +1094,7 @@ abstract class Erasure extends AddInterfaces
case Match(selector, cases) =>
Match(Typed(selector, TypeTree(selector.tpe)), cases)
- case Literal(ct) if ct.tag == ClassTag
+ case Literal(ct) if ct.tag == ClazzTag
&& ct.typeValue.typeSymbol != definitions.UnitClass =>
val erased = ct.typeValue match {
case TypeRef(pre, clazz, args) if clazz.isDerivedValueClass => scalaErasure.eraseNormalClassRef(pre, clazz)
@@ -1120,10 +1138,10 @@ abstract class Erasure extends AddInterfaces
*/
override def transform(tree: Tree): Tree = {
val tree1 = preTransformer.transform(tree)
- log("tree after pretransform: "+tree1)
+ // log("tree after pretransform: "+tree1)
afterErasure {
val tree2 = mixinTransformer.transform(tree1)
- debuglog("tree after addinterfaces: \n" + tree2)
+ // debuglog("tree after addinterfaces: \n" + tree2)
newTyper(rootContext(unit, tree, true)).typed(tree2)
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 595c1486b6..8daad8a2ac 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -93,7 +93,7 @@ abstract class ExplicitOuter extends InfoTransform
}
def newOuterAccessor(clazz: Symbol) = {
val accFlags = SYNTHETIC | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 )
- val sym = clazz.newMethodSymbol(nme.OUTER, clazz.pos, accFlags)
+ val sym = clazz.newMethod(nme.OUTER, clazz.pos, accFlags)
val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType
sym expandName clazz
@@ -357,7 +357,7 @@ abstract class ExplicitOuter extends InfoTransform
*/
def mixinOuterAccessorDef(mixinClass: Symbol): Tree = {
val outerAcc = outerAccessor(mixinClass) overridingSymbol currentClass
- def mixinPrefix = currentClass.thisType baseType mixinClass prefix;
+ def mixinPrefix = (currentClass.thisType baseType mixinClass).prefix
assert(outerAcc != NoSymbol, "No outer accessor for inner mixin " + mixinClass + " in " + currentClass)
// I added the mixinPrefix.typeArgs.nonEmpty condition to address the
// crash in SI-4970. I feel quite sure this can be improved.
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 4c3972519a..007457ef7b 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -28,6 +28,9 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
/** the following two members override abstract members in Transform */
val phaseName: String = "extmethods"
+ /** The following flags may be set by this phase: */
+ override def phaseNewFlags: Long = notPRIVATE
+
def newTransformer(unit: CompilationUnit): Transformer =
new Extender(unit)
@@ -47,7 +50,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
val index = alts indexOf imeth
assert(index >= 0, alts+" does not contain "+imeth)
def altName(index: Int) = newTermName("extension"+index+"$"+imeth.name)
- altName(index) #:: ((0 until alts.length).toStream filter (index !=) map altName)
+ altName(index) #:: ((0 until alts.length).toStream filter (index != _) map altName)
case tpe =>
assert(tpe != NoType, imeth.name+" not found in "+imeth.owner+"'s decls: "+imeth.owner.info.decls)
Stream(newTermName("extension$"+imeth.name))
@@ -65,7 +68,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
private def normalize(stpe: Type, clazz: Symbol): Type = stpe match {
case PolyType(tparams, restpe) =>
- GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe, clazz))
+ GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe.substSym(tparams takeRight clazz.typeParams.length, clazz.typeParams), clazz))
case MethodType(tparams, restpe) =>
restpe
case _ =>
@@ -101,6 +104,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
case Template(_, _, _) =>
if (currentOwner.isDerivedValueClass) {
extensionDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree]
+ currentOwner.primaryConstructor.makeNotPrivate(NoSymbol)
super.transform(tree)
} else if (currentOwner.isStaticOwner) {
super.transform(tree)
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index 8856024a30..c8de25b2ea 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -27,6 +27,7 @@ abstract class Flatten extends InfoTransform {
scope unlink old
scope enter sym
+ log("lifted " + sym.fullLocationString)
old
}
@@ -36,7 +37,7 @@ abstract class Flatten extends InfoTransform {
debuglog("re-enter " + sym.fullLocationString)
val old = replaceSymbolInCurrentScope(sym)
if (old ne NoSymbol)
- debuglog("lifted " + sym.fullLocationString + ", unlinked " + old)
+ log("unlinked " + old.fullLocationString + " after lifting " + sym)
}
}
private def liftSymbol(sym: Symbol) {
@@ -108,7 +109,7 @@ abstract class Flatten extends InfoTransform {
tree match {
case PackageDef(_, _) =>
liftedDefs(tree.symbol.moduleClass) = new ListBuffer
- case Template(_, _, _) if tree.symbol.owner.hasPackageFlag =>
+ case Template(_, _, _) if tree.symbol.isDefinedInPackage =>
liftedDefs(tree.symbol.owner) = new ListBuffer
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 13ca8e55bc..618a1cbba4 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -19,19 +19,6 @@ abstract class LambdaLift extends InfoTransform {
/** the following two members override abstract members in Transform */
val phaseName: String = "lambdalift"
- /** Converts types of captured variables to *Ref types.
- */
- def boxIfCaptured(sym: Symbol, tpe: Type, erasedTypes: Boolean) =
- if (sym.isCapturedVariable) {
- val symClass = tpe.typeSymbol
- def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) =
- if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe
- else if (erasedTypes) objectRefClass.tpe
- else appliedType(objectRefClass.typeConstructor, List(tpe))
- if (sym.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass)
- else refType(refClass, ObjectRefClass)
- } else tpe
-
private val lifted = new TypeMap {
def apply(tp: Type): Type = tp match {
case TypeRef(NoPrefix, sym, Nil) if sym.isClass && !sym.isPackageClass =>
@@ -46,7 +33,8 @@ abstract class LambdaLift extends InfoTransform {
}
def transformInfo(sym: Symbol, tp: Type): Type =
- boxIfCaptured(sym, lifted(tp), erasedTypes = true)
+ if (sym.isCapturedVariable) capturedVariableType(sym, tpe = lifted(tp), erasedTypes = true)
+ else lifted(tp)
protected def newTransformer(unit: CompilationUnit): Transformer =
new LambdaLifter(unit)
@@ -171,7 +159,7 @@ abstract class LambdaLift extends InfoTransform {
// for that failure. There should be exactly one method for any given
// entity which always gives the right answer.
if (sym.isImplClass)
- localImplClasses((sym.owner, nme.interfaceName(sym.name))) = sym
+ localImplClasses((sym.owner, tpnme.interfaceName(sym.name))) = sym
else {
renamable addEntry sym
if (sym.isTrait)
@@ -229,10 +217,10 @@ abstract class LambdaLift extends InfoTransform {
sym.owner.name + nme.NAME_JOIN_STRING
else ""
)
- sym.name =
+ sym setName (
if (sym.name.isTypeName) unit.freshTypeName(base)
else unit.freshTermName(base)
-
+ )
debuglog("renaming in %s: %s => %s".format(sym.owner.fullLocationString, originalName, sym.name))
}
@@ -241,7 +229,7 @@ abstract class LambdaLift extends InfoTransform {
def renameTrait(traitSym: Symbol, implSym: Symbol) {
val originalImplName = implSym.name
renameSym(traitSym)
- implSym.name = nme.implClassName(traitSym.name)
+ implSym setName tpnme.implClassName(traitSym.name)
debuglog("renaming impl class in step with %s: %s => %s".format(traitSym, originalImplName, implSym.name))
}
@@ -471,6 +459,8 @@ abstract class LambdaLift extends InfoTransform {
private def preTransform(tree: Tree) = super.transform(tree) setType lifted(tree.tpe)
override def transform(tree: Tree): Tree = tree match {
+ case Select(ReferenceToBoxed(idt), elem) if elem == nme.elem =>
+ postTransform(preTransform(idt), isBoxedRef = false)
case ReferenceToBoxed(idt) =>
postTransform(preTransform(idt), isBoxedRef = true)
case _ =>
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index adbb7d43d0..19f32a5411 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -123,7 +123,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
*/
private def rebindSuper(base: Symbol, member: Symbol, mixinClass: Symbol): Symbol =
afterPickler {
- var bcs = base.info.baseClasses.dropWhile(mixinClass !=).tail
+ var bcs = base.info.baseClasses.dropWhile(mixinClass != _).tail
var sym: Symbol = NoSymbol
debuglog("starting rebindsuper " + base + " " + member + ":" + member.tpe +
" " + mixinClass + " " + base.info.baseClasses + "/" + bcs)
@@ -136,7 +136,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
sym = member.matchingSymbol(bcs.head, base.thisType).suchThat(sym => !sym.hasFlag(DEFERRED | BRIDGE))
bcs = bcs.tail
}
- assert(sym != NoSymbol, member)
sym
}
@@ -339,8 +338,14 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
else if (mixinMember.isSuperAccessor) { // mixin super accessors
val superAccessor = addMember(clazz, mixinMember.cloneSymbol(clazz)) setPos clazz.pos
assert(superAccessor.alias != NoSymbol, superAccessor)
- val alias1 = rebindSuper(clazz, mixinMember.alias, mixinClass)
- superAccessor.asInstanceOf[TermSymbol] setAlias alias1
+
+ rebindSuper(clazz, mixinMember.alias, mixinClass) match {
+ case NoSymbol =>
+ unit.error(clazz.pos, "Member %s of mixin %s is missing a concrete super implementation.".format(
+ mixinMember.alias, mixinClass))
+ case alias1 =>
+ superAccessor.asInstanceOf[TermSymbol] setAlias alias1
+ }
}
else if (mixinMember.isMethod && mixinMember.isModule && mixinMember.hasNoFlags(LIFTED | BRIDGE)) {
// mixin objects: todo what happens with abstract objects?
@@ -384,11 +389,14 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
var sourceModule = clazz.owner.info.decls.lookup(sym.name.toTermName)
if (sourceModule != NoSymbol) {
sourceModule setPos sym.pos
- sourceModule.flags = MODULE | FINAL
+ if (sourceModule.flags != MODULE) {
+ log("!!! Directly setting sourceModule flags from %s to MODULE".format(flagsToString(sourceModule.flags)))
+ sourceModule.flags = MODULE
+ }
}
else {
sourceModule = (
- clazz.owner.newModuleSymbol(sym.name.toTermName, sym.pos, MODULE | FINAL)
+ clazz.owner.newModuleSymbol(sym.name.toTermName, sym.pos, MODULE)
setModuleClass sym.asInstanceOf[ClassSymbol]
)
clazz.owner.info.decls enter sourceModule
@@ -770,7 +778,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
val fields0 = usedBits(cl)
if (requiredBitmaps(fields0) < bitmapNum) {
- val fields1 = cl.info.decls filter isNonLocalFieldWithBitmap size;
+ val fields1 = (cl.info.decls filter isNonLocalFieldWithBitmap).size
return {
if (requiredBitmaps(fields0 + fields1) >= bitmapNum)
Some(bitmapFor(cl, offset, valSym, false))
@@ -930,7 +938,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
private def checkedGetter(lhs: Tree) = {
val sym = clazz.info decl lhs.symbol.getterName suchThat (_.isGetter)
if (needsInitAndHasOffset(sym)) {
- debuglog("adding checked getter for: " + sym + " " + lhs.symbol.defaultFlagString)
+ debuglog("adding checked getter for: " + sym + " " + lhs.symbol.flagString)
List(localTyper typed mkSetFlag(clazz, fieldOffset(sym), sym))
}
else Nil
@@ -1077,7 +1085,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// add forwarders
assert(sym.alias != NoSymbol, sym)
// debuglog("New forwarder: " + sym.defString + " => " + sym.alias.defString)
- addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident)))
+ if (!sym.isTermMacro) addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident)))
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 7b0f5254b6..1fb7fac184 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -8,6 +8,7 @@ package transform
import scala.tools.nsc.symtab.Flags
import scala.collection.{ mutable, immutable }
+import language.postfixOps
/** Specialize code on types.
*
@@ -67,8 +68,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
import definitions.{
RootClass, BooleanClass, UnitClass, ArrayClass,
ScalaValueClasses, isPrimitiveValueClass, isScalaValueType,
- SpecializedClass, RepeatedParamClass, JavaRepeatedParamClass,
- AnyRefClass, ObjectClass, AnyRefModule,
+ SpecializedClass, AnyRefClass, ObjectClass, AnyRefModule,
GroupOfSpecializable, uncheckedVarianceClass, ScalaInlineClass
}
@@ -99,9 +99,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Concrete methods that use a specialized type, or override such methods. */
private val concreteSpecMethods = perRunCaches.newWeakSet[Symbol]()
- private def isSpecialized(sym: Symbol) = sym hasAnnotation SpecializedClass
- private def hasSpecializedFlag(sym: Symbol) = sym hasFlag SPECIALIZED
- private def specializedTypes(tps: List[Symbol]) = tps filter isSpecialized
+ private def specializedTypes(tps: List[Symbol]) = tps filter (_.isSpecialized)
private def specializedOn(sym: Symbol): List[Symbol] = {
sym getAnnotation SpecializedClass match {
case Some(AnnotationInfo(_, Nil, _)) => specializableTypes.map(_.typeSymbol)
@@ -128,21 +126,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
isBoundedGeneric(tp)
//(tp <:< AnyRefClass.tpe)
}
- private def isBoundedGeneric(tp: Type) = tp match {
- case TypeRef(_, sym, _) if sym.isAbstractType => (tp <:< AnyRefClass.tpe)
- case TypeRef(_, sym, _) => !isPrimitiveValueClass(sym)
- case _ => false
- }
-
- def unspecializedSymbol(sym: Symbol): Symbol = {
- if (sym hasFlag SPECIALIZED) {
- // add initialization from its generic class constructor
- val genericName = nme.unspecializedName(sym.name)
- val member = sym.owner.info.decl(genericName.toTypeName)
- member
- }
- else NoSymbol
- }
object TypeEnv {
/** Return a new type environment binding specialized type parameters of sym to
@@ -151,7 +134,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
def fromSpecialization(sym: Symbol, args: List[Type]): TypeEnv = {
ifDebug(assert(sym.info.typeParams.length == args.length, sym + " args: " + args))
- emptyEnv ++ collectMap2(sym.info.typeParams, args)((k, v) => isSpecialized(k))
+ emptyEnv ++ collectMap2(sym.info.typeParams, args)((k, v) => k.isSpecialized)
}
/** Does typeenv `t1` include `t2`? All type variables in `t1`
@@ -176,7 +159,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
def isValid(env: TypeEnv, sym: Symbol): Boolean = {
env forall { case (tvar, tpe) =>
- isSpecialized(tvar) && (concreteTypes(tvar) contains tpe) && {
+ tvar.isSpecialized && (concreteTypes(tvar) contains tpe) && {
(sym.typeParams contains tvar) ||
(sym.owner != RootClass && (sym.owner.typeParams contains tvar))
}
@@ -188,7 +171,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* 'sClass' itself if sClass is not a specialized subclass.
*/
def genericClass(sClass: Symbol): Symbol =
- if (hasSpecializedFlag(sClass)) sClass.superClass
+ if (sClass.isSpecialized) sClass.superClass
else sClass
case class Overload(sym: Symbol, env: TypeEnv) {
@@ -253,7 +236,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Type bounds of a @specialized type var are now in the environment. */
override def typeBoundsIn(env: TypeEnv): Boolean = {
target.info.typeParams exists { tvar =>
- isSpecialized(tvar) && (specializedTypeVars(tvar.info.bounds) exists env.isDefinedAt)
+ tvar.isSpecialized && (specializedTypeVars(tvar.info.bounds) exists env.isDefinedAt)
}
}
@@ -269,21 +252,21 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Has `clazz` any type parameters that need be specialized? */
def hasSpecializedParams(clazz: Symbol) =
- clazz.info.typeParams exists isSpecialized
+ clazz.info.typeParams exists (_.isSpecialized)
/** Return specialized type parameters. */
def specializedParams(sym: Symbol): List[Symbol] =
- sym.info.typeParams filter isSpecialized
+ sym.info.typeParams filter (_.isSpecialized)
def splitParams(tps: List[Symbol]) =
- tps partition isSpecialized
+ tps partition (_.isSpecialized)
/** Given an original class symbol and a list of types its type parameters are instantiated at
* returns a list of type parameters that should remain in the TypeRef when instantiating a
* specialized type.
*/
def survivingArgs(sym: Symbol, args: List[Type]): List[Type] =
- for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !isSpecialized(tvar) || !isScalaValueType(tpe))
+ for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !tvar.isSpecialized || !isScalaValueType(tpe))
yield tpe
val specializedType = new TypeMap {
@@ -318,7 +301,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
else specializedTypeVars(sym).intersect(env.keySet)
)
val (methparams, others) = tvars.toList sortBy ("" + _.name) partition (_.owner.isMethod)
- debuglog("specName(" + sym + ") env: " + env + " tvars: " + tvars)
+ // debuglog("specName(" + sym + ") env: " + env + " tvars: " + tvars)
specializedName(sym.name, methparams map env, others map env)
}
@@ -357,7 +340,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* These are in a meaningful order for stability purposes.
*/
def concreteTypes(sym: Symbol): List[Type] = {
- val types = if (!isSpecialized(sym))
+ val types = if (!sym.isSpecialized)
Nil // no @specialized Annotation
else
specializedOn(sym) map (s => specializesClass(s).tpe) sorted
@@ -373,7 +356,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
private def specializations(tps: List[Symbol]): List[TypeEnv] = {
// the keys in each TypeEnv
- val keys: List[Symbol] = tps filter isSpecialized
+ val keys: List[Symbol] = tps filter (_.isSpecialized)
// creating each permutation of concrete types
def loop(ctypes: List[List[Type]]): List[List[Type]] = ctypes match {
case Nil => Nil
@@ -394,11 +377,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
private def needsSpecialization(env: TypeEnv, sym: Symbol): Boolean = {
specializedTypeVars(sym).intersect(env.keySet).diff(wasSpecializedForTypeVars(sym)).nonEmpty ||
- (sym.isClassConstructor && (sym.enclClass.typeParams exists isSpecialized)) ||
+ (sym.isClassConstructor && (sym.enclClass.typeParams exists (_.isSpecialized))) ||
(isNormalizedMember(sym) && info(sym).typeBoundsIn(env))
}
- def isNormalizedMember(m: Symbol) = hasSpecializedFlag(m) && (info get m exists {
+ def isNormalizedMember(m: Symbol) = m.isSpecialized && (info get m exists {
case NormalizedMember(_) => true
case _ => false
})
@@ -419,14 +402,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case TypeRef(pre, sym, args) =>
if (sym.isAliasType)
specializedTypeVars(tpe.normalize)
- else if (sym.isTypeParameter && isSpecialized(sym) || (sym.isTypeSkolem && isSpecialized(sym.deSkolemize)))
+ else if (sym.isTypeParameter && sym.isSpecialized || (sym.isTypeSkolem && sym.deSkolemize.isSpecialized))
Set(sym)
else if (sym == ArrayClass)
specializedTypeVars(args)
else if (args.isEmpty)
Set()
else
- specializedTypeVars(sym.typeParams zip args collect { case (tp, arg) if isSpecialized(tp) => arg })
+ specializedTypeVars(sym.typeParams zip args collect { case (tp, arg) if tp.isSpecialized => arg })
case PolyType(tparams, resTpe) => specializedTypeVars(resTpe :: tparams.map(_.info))
// since this method may be run at phase typer (before uncurry, where NMTs are eliminated)
@@ -460,7 +443,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Type parameters that survive when specializing in the specified environment. */
def survivingParams(params: List[Symbol], env: TypeEnv) =
- params.filter(p => !isSpecialized(p) || !isScalaValueType(env(p)))
+ params.filter(p => !p.isSpecialized || !isScalaValueType(env(p)))
/** Produces the symbols from type parameters `syms` of the original owner,
* in the given type environment `env`. The new owner is `nowner`.
@@ -518,13 +501,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// better evaluate it before creating the new class symbol
val clazzName = specializedName(clazz, env0).toTypeName
val bytecodeClazz = clazz.owner.info.decl(clazzName)
- debuglog("Specializing " + clazz + " found " + bytecodeClazz + " already there")
+ // debuglog("Specializing " + clazz + ", but found " + bytecodeClazz + " already there")
bytecodeClazz.info
val sClass = clazz.owner.newClass(clazzName, clazz.pos, (clazz.flags | SPECIALIZED) & ~CASE)
- def cloneInSpecializedClass(member: Symbol, flagFn: Long => Long) =
- member.cloneSymbol(sClass, flagFn(member.flags | SPECIALIZED))
+ def cloneInSpecializedClass(member: Symbol, flagFn: Long => Long, newName: Name = null) =
+ member.cloneSymbol(sClass, flagFn(member.flags | SPECIALIZED), newName)
sClass.sourceFile = clazz.sourceFile
currentRun.symSource(sClass) = clazz.sourceFile // needed later on by mixin
@@ -574,7 +557,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
parents = parents.head.parents.head :: parents
val extraSpecializedMixins = specializedParents(clazz.info.parents map applyContext)
if (extraSpecializedMixins.nonEmpty)
- debuglog("specializeClass on " + clazz + " founds extra specialized mixins: " + extraSpecializedMixins.mkString(", "))
+ debuglog("extra specialized mixins for %s: %s".format(clazz.name.decode, extraSpecializedMixins.mkString(", ")))
// If the class being specialized has a self-type, the self type may
// require specialization. First exclude classes whose self types have
// the same type constructor as the class itself, since they will
@@ -652,7 +635,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val NormalizedMember(original) = info(m)
if (nonConflicting(env ++ typeEnv(m))) {
if (info(m).degenerate) {
- debuglog("degenerate normalized member " + m + " info(m): " + info(m))
+ debuglog("degenerate normalized member " + m.defString)
val specMember = enterMember(cloneInSpecializedClass(m, _ & ~DEFERRED))
info(specMember) = Implementation(original)
@@ -660,7 +643,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
else debuglog({
val om = forwardToOverload(m)
- "normalizedMember " + m + " om: " + om + " typeEnv(om): " + typeEnv(om)
+ "normalizedMember " + m + " om: " + om + " " + pp(typeEnv(om))
})
}
else
@@ -668,7 +651,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
else if (m.isDeferred) { // abstract methods
val specMember = enterMember(cloneInSpecializedClass(m, _ | DEFERRED))
- debuglog("deferred " + specMember.fullName + " remains abstract")
+ // debuglog("deferred " + specMember.fullName + " remains abstract")
info(specMember) = new Abstract(specMember)
// was: new Forward(specMember) {
@@ -698,20 +681,21 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
enterMember(specVal)
// create accessors
- debuglog("m: " + m + " isLocal: " + nme.isLocalName(m.name) + " specVal: " + specVal.name + " isLocal: " + nme.isLocalName(specVal.name))
+ // debuglog("m: " + m + " isLocal: " + nme.isLocalName(m.name) + " specVal: " + specVal.name + " isLocal: " + nme.isLocalName(specVal.name))
+
if (nme.isLocalName(m.name)) {
val specGetter = mkAccessor(specVal, nme.localToGetter(specVal.name)) setInfo MethodType(Nil, specVal.info)
val origGetter = overrideIn(sClass, m.getter(clazz))
info(origGetter) = Forward(specGetter)
enterMember(specGetter)
enterMember(origGetter)
- debuglog("created accessors: " + specGetter + " orig: " + origGetter)
+ debuglog("specialize accessor in %s: %s -> %s".format(sClass.name.decode, origGetter.name.decode, specGetter.name.decode))
clazz.caseFieldAccessors.find(_.name.startsWith(m.name)) foreach { cfa =>
val cfaGetter = overrideIn(sClass, cfa)
info(cfaGetter) = SpecializedAccessor(specVal)
enterMember(cfaGetter)
- debuglog("found case field accessor for " + m + " added override " + cfaGetter);
+ debuglog("override case field accessor %s -> %s".format(m.name.decode, cfaGetter.name.decode))
}
if (specVal.isVariable && m.setter(clazz) != NoSymbol) {
@@ -724,14 +708,18 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
enterMember(specSetter)
enterMember(origSetter)
}
- } else { // if there are no accessors, specialized methods will need to access this field in specialized subclasses
+ }
+ else { // if there are no accessors, specialized methods will need to access this field in specialized subclasses
m.resetFlag(PRIVATE)
specVal.resetFlag(PRIVATE)
+ debuglog("no accessors for %s/%s, specialized methods must access field in subclass".format(
+ m.name.decode, specVal.name.decode))
}
- } else if (m.isClass) {
+ }
+ else if (m.isClass) {
val specClass: Symbol = cloneInSpecializedClass(m, x => x)
typeEnv(specClass) = fullEnv
- specClass.name = specializedName(specClass, fullEnv).toTypeName
+ specClass setName specializedName(specClass, fullEnv).toTypeName
enterMember(specClass)
debuglog("entered specialized class " + specClass.fullName)
info(specClass) = SpecializedInnerClass(m, fullEnv)
@@ -787,10 +775,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* // etc.
*/
private def normalizeMember(owner: Symbol, sym: Symbol, outerEnv: TypeEnv): List[Symbol] = {
- debuglog("normalizeMember: " + sym.fullName)
sym :: (
if (!sym.isMethod || beforeTyper(sym.typeParams.isEmpty)) Nil
else {
+ // debuglog("normalizeMember: " + sym.fullNameAsName('.').decode)
var specializingOn = specializedParams(sym)
val unusedStvars = specializingOn filterNot specializedTypeVars(sym.info)
@@ -809,8 +797,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val env = mapAnyRefsInSpecSym(env0, sym, specMember)
val (keys, vals) = env.toList.unzip
- specMember.name = specializedName(sym, env)
- debuglog("normalizing: " + sym + " to " + specMember + " with params " + tps)
+ specMember setName specializedName(sym, env)
+ // debuglog("%s normalizes to %s%s".format(sym, specMember,
+ // if (tps.isEmpty) "" else " with params " + tps.mkString(", ")))
typeEnv(specMember) = outerEnv ++ env
val tps1 = produceTypeParameters(tps, specMember, env)
@@ -820,11 +809,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val methodType = sym.info.resultType.instantiateTypeParams(keys ++ tps, vals ++ tps1.map(_.tpe)).cloneInfo(specMember)
specMember setInfo GenPolyType(tps1, methodType)
- debuglog("expanded member: " + sym + ": " + sym.info +
- " -> " + specMember +
- ": " + specMember.info +
- " env: " + env
- )
+ debuglog("%s expands to %s in %s".format(sym, specMember.name.decode, pp(env)))
info(specMember) = NormalizedMember(sym)
overloads(sym) ::= Overload(specMember, env)
specMember
@@ -833,6 +818,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
)
}
+ // concise printing of type env
+ private def pp(env: TypeEnv): String = {
+ env.toList.sortBy(_._1.name) map {
+ case (k, v) =>
+ val vsym = v.typeSymbol
+ if (k == vsym) "" + k.name
+ else k.name + ":" + vsym.name
+
+ } mkString ("env(", ", ", ")")
+ }
+
/** Specialize member `m` w.r.t. to the outer environment and the type
* parameters of the innermost enclosing class.
*
@@ -841,47 +837,49 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* Return a list of symbols that are specializations of 'sym', owned by 'owner'.
*/
private def specializeMember(owner: Symbol, sym: Symbol, outerEnv: TypeEnv, tps: List[Symbol]): List[Symbol] = {
- def specializeOn(tparams: List[Symbol]): List[Symbol] =
- for (spec0 <- specializations(tparams)) yield {
- val spec = mapAnyRefsInOrigCls(spec0, owner)
- if (sym.isPrivate/* || sym.isProtected*/) {
- //sym.privateWithin = sym.enclosingPackage
- sym.resetFlag(PRIVATE).setFlag(PROTECTED)
- debuglog("-->d SETTING PRIVATE WITHIN TO " + sym.enclosingPackage + " for " + sym)
- }
+ def specializeOn(tparams: List[Symbol]): List[Symbol] = specializations(tparams) map { spec0 =>
+ val spec = mapAnyRefsInOrigCls(spec0, owner)
+ if (sym.isPrivate) {
+ sym.resetFlag(PRIVATE).setFlag(PROTECTED)
+ debuglog("Set %s to private[%s]".format(sym, sym.enclosingPackage))
+ }
- val specMember = subst(outerEnv)(specializedOverload(owner, sym, spec))
- typeEnv(specMember) = typeEnv(sym) ++ outerEnv ++ spec
- wasSpecializedForTypeVars(specMember) ++= spec collect { case (s, tp) if s.tpe == tp => s }
+ val specMember = subst(outerEnv)(specializedOverload(owner, sym, spec))
+ typeEnv(specMember) = typeEnv(sym) ++ outerEnv ++ spec
+ wasSpecializedForTypeVars(specMember) ++= spec collect { case (s, tp) if s.tpe == tp => s }
- debuglog("sym " + specMember + " was specialized for type vars " + wasSpecializedForTypeVars(specMember))
- debuglog("added specialized overload: %s in env: %s".format(specMember, typeEnv(specMember)))
+ val wasSpec = wasSpecializedForTypeVars(specMember)
+ if (wasSpec.nonEmpty)
+ debuglog("specialized overload for %s in %s".format(specMember, pp(typeEnv(specMember))))
- overloads(sym) ::= Overload(specMember, spec)
- specMember
- }
+ overloads(sym) ::= Overload(specMember, spec)
+ info(specMember) = SpecialOverload(sym, typeEnv(specMember))
+
+ specMember
+ }
if (sym.isMethod) {
- debuglog("specializeMember %s with tps: %s stvars(sym): %s".format(sym, tps, specializedTypeVars(sym)))
+ val stvars = specializedTypeVars(sym)
+ if (stvars.nonEmpty)
+ debuglog("specialized %s on %s".format(sym.fullLocationString, stvars.map(_.name).mkString(", ")))
val tps1 = if (sym.isConstructor) tps filter (sym.info.paramTypes contains _) else tps
- val tps2 = tps1 intersect specializedTypeVars(sym).toList
+ val tps2 = tps1 filter stvars
if (!sym.isDeferred)
addConcreteSpecMethod(sym)
- val ms = specializeOn(tps2)
- ms foreach (m => info(m) = SpecialOverload(sym, typeEnv(m)))
- ms
+ specializeOn(tps2)
}
else Nil
}
/** Return the specialized overload of `m`, in the given environment. */
private def specializedOverload(owner: Symbol, sym: Symbol, env: TypeEnv): Symbol = {
+ val newFlags = (sym.flags | SPECIALIZED) & ~(DEFERRED | CASEACCESSOR | ACCESSOR | LAZY)
// this method properly duplicates the symbol's info
- val specMember = sym.cloneSymbol(owner, (sym.flags | SPECIALIZED) & ~(DEFERRED | CASEACCESSOR | ACCESSOR | LAZY))
- specMember.name = specializedName(sym, env)
- specMember modifyInfo (info => subst(env, info.asSeenFrom(owner.thisType, sym.owner)))
+ ( sym.cloneSymbol(owner, newFlags, specializedName(sym, env))
+ modifyInfo (info => subst(env, info.asSeenFrom(owner.thisType, sym.owner)))
+ )
}
/** For each method m that overrides an inherited method m', add a special
@@ -894,7 +892,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*
* this method will return List('apply$mcII$sp')
*/
- private def specialOverrides(clazz: Symbol): List[Symbol] = {
+ private def specialOverrides(clazz: Symbol) = logResultIf[List[Symbol]]("specialOverrides(" + clazz + ")", _.nonEmpty) {
/** Return the overridden symbol in syms that needs a specialized overriding symbol,
* together with its specialization environment. The overridden symbol may not be
* the closest to 'overriding', in a given hierarchy.
@@ -917,24 +915,21 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
if (!overriding.isParamAccessor) {
for (overridden <- overriding.allOverriddenSymbols) {
- debuglog(
- "Overridden: " + overridden.fullName +
- ": " + overridden.info +
- "\n by " + overriding.fullName +
- ": " + overriding.info
- )
val stvars = specializedTypeVars(overridden.info)
if (stvars.nonEmpty) {
- debuglog("\t\tspecializedTVars: " + stvars)
+ debuglog("specialized override of %s by %s%s".format(overridden.fullLocationString, overriding.fullLocationString,
+ if (stvars.isEmpty) "" else stvars.map(_.name).mkString("(", ", ", ")")))
+
if (currentRun compiles overriding)
checkOverriddenTParams(overridden)
val env = unify(overridden.info, overriding.info, emptyEnv, false)
def atNext = afterSpecialize(overridden.owner.info.decl(specializedName(overridden, env)))
- debuglog("\t\tenv: " + env + "isValid: " + TypeEnv.isValid(env, overridden) + "found: " + atNext)
- if (TypeEnv.restrict(env, stvars).nonEmpty && TypeEnv.isValid(env, overridden) && atNext != NoSymbol)
+ if (TypeEnv.restrict(env, stvars).nonEmpty && TypeEnv.isValid(env, overridden) && atNext != NoSymbol) {
+ debuglog(" " + pp(env) + " found " + atNext)
return (overridden, env)
+ }
}
}
}
@@ -945,7 +940,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case (NoSymbol, _) => None
case (overridden, env) =>
val om = specializedOverload(clazz, overridden, env)
- debuglog("Added specialized overload %s for %s in env: %s with type: %s".format(om, overriding.fullName, env, om.info))
+ debuglog("specialized overload %s for %s in %s: %s".format(om, overriding.name.decode, pp(env), om.info))
typeEnv(om) = env
addConcreteSpecMethod(overriding)
info(om) = (
@@ -992,8 +987,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* If `strict` is true, a UnifyError is thrown if unification is impossible.
*/
private def unify(tp1: Type, tp2: Type, env: TypeEnv, strict: Boolean): TypeEnv = (tp1, tp2) match {
- case (TypeRef(_, sym1, _), _) if isSpecialized(sym1) =>
- debuglog("Unify - basic case: " + tp1 + ", " + tp2)
+ case (TypeRef(_, sym1, _), _) if sym1.isSpecialized =>
+ debuglog("Unify " + tp1 + ", " + tp2)
if (isPrimitiveValueClass(tp2.typeSymbol) || isSpecializedAnyRefSubtype(tp2, sym1))
env + ((sym1, tp2))
else if (isSpecializedAnyRefSubtype(tp2, sym1))
@@ -1003,19 +998,21 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
else
env
case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) =>
- debuglog("Unify TypeRefs: " + tp1 + " and " + tp2 + " with args " + (args1, args2) + " - ")
+ if (args1.nonEmpty || args2.nonEmpty)
+ debuglog("Unify types " + tp1 + " and " + tp2)
+
if (strict && args1.length != args2.length) unifyError(tp1, tp2)
val e = unify(args1, args2, env, strict)
- debuglog("unified to: " + e)
+ if (e.nonEmpty) debuglog("unified to: " + e)
e
case (TypeRef(_, sym1, _), _) if sym1.isTypeParameterOrSkolem =>
env
case (MethodType(params1, res1), MethodType(params2, res2)) =>
if (strict && params1.length != params2.length) unifyError(tp1, tp2)
- debuglog("Unify MethodTypes: " + tp1 + " and " + tp2)
+ debuglog("Unify methods " + tp1 + " and " + tp2)
unify(res1 :: (params1 map (_.tpe)), res2 :: (params2 map (_.tpe)), env, strict)
case (PolyType(tparams1, res1), PolyType(tparams2, res2)) =>
- debuglog("Unify PolyTypes: " + tp1 + " and " + tp2)
+ debuglog("Unify polytypes " + tp1 + " and " + tp2)
if (strict && tparams1.length != tparams2.length)
unifyError(tp1, tp2)
else
@@ -1123,11 +1120,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
if (tparams.isEmpty)
afterSpecialize(parents map (_.typeSymbol.info))
- val parents1 = parents map specializedType
- debuglog("transformInfo %s %s with parents1 %s ph: %s".format(
- if (tparams.nonEmpty) " (poly)" else "",
- clazz, parents1, phase)
- )
+ val parents1 = parents mapConserve specializedType
+ if (parents ne parents1) {
+ debuglog("specialization transforms %s%s parents to %s".format(
+ if (tparams.nonEmpty) "(poly) " else "", clazz, parents1)
+ )
+ }
val newScope = newScopeWith(specializeClass(clazz, typeEnv(clazz)) ++ specialOverrides(clazz): _*)
// If tparams.isEmpty, this is just the ClassInfoType.
GenPolyType(tparams, ClassInfoType(parents1, newScope, clazz))
@@ -1230,13 +1228,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Return the generic class corresponding to this specialized class. */
def originalClass(clazz: Symbol): Symbol =
- if (hasSpecializedFlag(clazz)) {
+ if (clazz.isSpecialized) {
val (originalName, _, _) = nme.splitSpecializedName(clazz.name)
clazz.owner.info.decl(originalName).suchThat(_.isClass)
} else NoSymbol
def illegalSpecializedInheritance(clazz: Symbol): Boolean = (
- hasSpecializedFlag(clazz)
+ clazz.isSpecialized
&& originalClass(clazz).parentSymbols.exists(p => hasSpecializedParams(p) && !p.isTrait)
)
@@ -1253,7 +1251,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
override def traverse(tree: Tree) = tree match {
case DefDef(_, _, _, vparams :: Nil, _, rhs) =>
if (concreteSpecMethods(tree.symbol) || tree.symbol.isConstructor) {
- debuglog("!!! adding body of a defdef %s, symbol %s: %s".format(tree, tree.symbol, rhs))
+ // debuglog("!!! adding body of a defdef %s, symbol %s: %s".format(tree, tree.symbol, rhs))
body(tree.symbol) = rhs
// body(tree.symbol) = tree // whole method
parameters(tree.symbol) = vparams.map(_.symbol)
@@ -1330,7 +1328,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
} else super.transform(tree)
- case TypeApply(Select(qual, name), targs)
+ case TypeApply(sel @ Select(qual, name), targs)
if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) =>
debuglog("checking typeapp for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe)
val qual1 = transform(qual)
@@ -1344,14 +1342,20 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val residualTargs = symbol.info.typeParams zip targs collect {
case (tvar, targ) if !env.contains(tvar) || !isPrimitiveValueClass(env(tvar).typeSymbol) => targ
}
+ // See SI-5583. Don't know why it happens now if it didn't before.
+ if (specMember.info.typeParams.isEmpty && residualTargs.nonEmpty) {
+ log("!!! Type args to be applied, but symbol says no parameters: " + ((specMember.defString, residualTargs)))
+ localTyper.typed(sel)
+ }
+ else {
+ ifDebug(assert(residualTargs.length == specMember.info.typeParams.length,
+ "residual: %s, tparams: %s, env: %s".format(residualTargs, specMember.info.typeParams, env))
+ )
- ifDebug(assert(residualTargs.length == specMember.info.typeParams.length,
- "residual: %s, tparams: %s, env: %s".format(residualTargs, symbol.info.typeParams, env))
- )
-
- val tree1 = gen.mkTypeApply(Select(qual1, specMember), residualTargs)
- debuglog("rewrote " + tree + " to " + tree1)
- localTyper.typedOperator(atPos(tree.pos)(tree1)) // being polymorphic, it must be a method
+ val tree1 = gen.mkTypeApply(Select(qual1, specMember), residualTargs)
+ debuglog("rewrote " + tree + " to " + tree1)
+ localTyper.typedOperator(atPos(tree.pos)(tree1)) // being polymorphic, it must be a method
+ }
case None => super.transform(tree)
}
@@ -1559,7 +1563,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val env = typeEnv(symbol)
val boundTvars = env.keySet
val origtparams = source.typeParams.filter(tparam => !boundTvars(tparam) || !isScalaValueType(env(tparam)))
- debuglog("substituting " + origtparams + " for " + symbol.typeParams)
+ if (origtparams.nonEmpty || symbol.typeParams.nonEmpty)
+ debuglog("substituting " + origtparams + " for " + symbol.typeParams)
// skolemize type parameters
val oldtparams = tparams map (_.symbol)
@@ -1656,7 +1661,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
buf +=
ClassDef(specCls, atPos(impl.pos)(Template(parents, emptyValDef, List()))
.setSymbol(specCls.newLocalDummy(sym1.pos))) setPos tree.pos
- debuglog("created synthetic class: " + specCls + " of " + sym1 + " in env: " + env)
+ debuglog("created synthetic class: " + specCls + " of " + sym1 + " in " + pp(env))
}
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 6ebecb02c6..9915f7e9fc 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -36,7 +36,7 @@ abstract class TailCalls extends Transform {
}
}
- private def hasSynthCaseSymbol(t: Tree) = (t.symbol ne null) && (t.symbol hasFlag (Flags.CASE | Flags.SYNTHETIC))
+ import gen.hasSynthCaseSymbol
/**
* A Tail Call Transformer
@@ -341,13 +341,18 @@ abstract class TailCalls extends Transform {
else if (fun.symbol.isLabel && args.nonEmpty && args.tail.isEmpty && ctx.tailLabels(fun.symbol)) {
// this is to detect tailcalls in translated matches
// it's a one-argument call to a label that is in a tailposition and that looks like label(x) {x}
- // thus, the argument to the call is in tailposition and we don't need to jump to the label, tail jump instead
+ // thus, the argument to the call is in tailposition
val saved = ctx.tailPos
ctx.tailPos = true
debuglog("in tailpos label: "+ args.head)
val res = transform(args.head)
ctx.tailPos = saved
- if (res ne args.head) res // we tail-called -- TODO: shield from false-positives where we rewrite but don't tail-call
+ if (res ne args.head) {
+ // we tail-called -- TODO: shield from false-positives where we rewrite but don't tail-call
+ // must leave the jump to the original tailpos-label (fun)!
+ // there might be *a* tailcall *in* res, but it doesn't mean res *always* tailcalls
+ treeCopy.Apply(tree, fun, List(res))
+ }
else rewriteApply(fun, fun, Nil, args)
} else rewriteApply(fun, fun, Nil, args)
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index e54e0289bb..35e26b39b5 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -8,6 +8,7 @@ package transform
import symtab.Flags._
import scala.collection.{ mutable, immutable }
+import language.postfixOps
/*<export> */
/** - uncurry all symbol and tree types (@see UnCurryPhase) -- this includes normalizing all proper types.
@@ -126,7 +127,7 @@ abstract class UnCurry extends InfoTransform
/** The type of a non-local return expression with given argument type */
private def nonLocalReturnExceptionType(argtype: Type) =
- appliedType(NonLocalReturnControlClass.typeConstructor, List(argtype))
+ appliedType(NonLocalReturnControlClass, argtype)
/** A hashmap from method symbols to non-local return keys */
private val nonLocalReturnKeys = perRunCaches.newMap[Symbol, Symbol]()
@@ -210,14 +211,15 @@ abstract class UnCurry extends InfoTransform
* body = expr match { case P_i if G_i => E_i }_i=1..n
* to:
*
+ //TODO: correct code template below
* class $anon() extends AbstractPartialFunction[T, R] with Serializable {
- * def apply(x: T): R = (expr: @unchecked) match {
+ * def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = (expr: @unchecked) match {
* case P_1 if G_1 => E_1
* ...
- * case P_n if G_n => true
- * case _ => this.missingCase(expr)
+ * case P_n if G_n => E_n
+ * case _ => default(expr)
* }
- * def _isDefinedAt(x: T): boolean = (x: @unchecked) match {
+ * def isDefinedAt(x: T): boolean = (x: @unchecked) match {
* case P_1 if G_1 => true
* ...
* case P_n if G_n => true
@@ -231,127 +233,233 @@ abstract class UnCurry extends InfoTransform
*
* def isDefinedAtCurrent(x: T): boolean = true
*/
- def transformFunction(fun: Function): Tree = {
- val fun1 = deEta(fun)
- def owner = fun.symbol.owner
- def targs = fun.tpe.typeArgs
- def isPartial = fun.tpe.typeSymbol == PartialFunctionClass
-
- // if the function was eta-expanded, it's not a match without a selector
- if (fun1 ne fun) fun1
- else {
- assert(!(opt.virtPatmat && isPartial)) // empty-selector matches have already been translated into instantiations of anonymous (partial) functions
- val (formals, restpe) = (targs.init, targs.last)
- val anonClass = owner.newAnonymousFunctionClass(fun.pos, inConstructorFlag)
- def parents =
- if (isFunctionType(fun.tpe)) List(abstractFunctionForFunctionType(fun.tpe), SerializableClass.tpe)
- else if (isPartial) List(appliedType(AbstractPartialFunctionClass.typeConstructor, targs), SerializableClass.tpe)
- else List(ObjectClass.tpe, fun.tpe, SerializableClass.tpe)
-
- anonClass setInfo ClassInfoType(parents, newScope, anonClass)
- val applyMethod = anonClass.newMethod(nme.apply, fun.pos, FINAL)
- applyMethod setInfoAndEnter MethodType(applyMethod newSyntheticValueParams formals, restpe)
- anonClass addAnnotation serialVersionUIDAnnotation
-
- fun.vparams foreach (_.symbol.owner = applyMethod)
- fun.body.changeOwner(fun.symbol -> applyMethod)
-
- def missingCaseCall(scrutinee: Tree): Tree = Apply(Select(This(anonClass), nme.missingCase), List(scrutinee))
-
- def applyMethodDef() = {
- val body = localTyper.typedPos(fun.pos) {
- if (isPartial) gen.mkUncheckedMatch(gen.withDefaultCase(fun.body, missingCaseCall))
- else fun.body
- }
- // Have to repack the type to avoid mismatches when existentials
- // appear in the result - see SI-4869.
- val applyResultType = localTyper.packedType(body, applyMethod)
- DefDef(Modifiers(FINAL), nme.apply, Nil, List(fun.vparams), TypeTree(applyResultType), body) setSymbol applyMethod
- }
- def isDefinedAtMethodDef() = {
- val isDefinedAtName = {
- if (anonClass.info.member(nme._isDefinedAt) != NoSymbol) nme._isDefinedAt
- else nme.isDefinedAt
- }
- val m = anonClass.newMethod(isDefinedAtName, fun.pos, FINAL)
- val params = m newSyntheticValueParams formals
- m setInfoAndEnter MethodType(params, BooleanClass.tpe)
+ def transformFunction(fun: Function): Tree =
+ deEta(fun) match {
+ // nullary or parameterless
+ case fun1 if fun1 ne fun => fun1
+ case _ =>
+ def owner = fun.symbol.owner
+ def targs = fun.tpe.typeArgs
+ def isPartial = fun.tpe.typeSymbol == PartialFunctionClass
- val substParam = new TreeSymSubstituter(fun.vparams map (_.symbol), params)
- def substTree[T <: Tree](t: T): T = substParam(resetLocalAttrs(t))
+ def parents =
+ if (isFunctionType(fun.tpe)) List(abstractFunctionForFunctionType(fun.tpe), SerializableClass.tpe)
+ else if (isPartial) List(appliedType(AbstractPartialFunctionClass, targs: _*), SerializableClass.tpe)
+ else List(ObjectClass.tpe, fun.tpe, SerializableClass.tpe)
- object isDefinedAtTransformer extends gen.MatchMatcher {
- // TODO: optimize duplication, but make sure ValDef's introduced by wrap are treated correctly
- override def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = {
- def transformCase(cdef: CaseDef): CaseDef =
- CaseDef(cdef.pat, cdef.guard, Literal(Constant(true)))
+ val anonClass = owner newAnonymousFunctionClass(fun.pos, inConstructorFlag) addAnnotation serialVersionUIDAnnotation
+ anonClass setInfo ClassInfoType(parents, newScope, anonClass)
- def defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false)))
+ val (formals, restpe) = (targs.init, targs.last)
-// val casesNoSynthCatchAll = dropSyntheticCatchAll(cases)
+ def applyMethodDef = {
+ val methSym = anonClass.newMethod(nme.apply, fun.pos, FINAL)
+ methSym setInfoAndEnter MethodType(methSym newSyntheticValueParams formals, restpe)
- gen.mkUncheckedMatch(
- if (cases exists treeInfo.isDefaultCase) Literal(Constant(true))
- else substTree(wrap(Match(selector, (cases map transformCase) :+ defaultCase)).duplicate)
- )
+ fun.vparams foreach (_.symbol.owner = methSym)
+ fun.body changeOwner (fun.symbol -> methSym)
+
+ val body = localTyper.typedPos(fun.pos)(fun.body)
+ val methDef = DefDef(methSym, List(fun.vparams), body)
+
+ // Have to repack the type to avoid mismatches when existentials
+ // appear in the result - see SI-4869.
+ methDef.tpt setType localTyper.packedType(body, methSym)
+ methDef
+ }
+
+ // def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 =
+ def applyOrElseMethodDef = {
+ val methSym = anonClass.newMethod(fun.pos, nme.applyOrElse) setFlag (FINAL | OVERRIDE)
+
+ val List(argtpe) = formals
+ val A1 = methSym newTypeParameter(newTypeName("A1")) setInfo TypeBounds.upper(argtpe)
+ val B1 = methSym newTypeParameter(newTypeName("B1")) setInfo TypeBounds.lower(restpe)
+ val methFormals = List(A1.tpe, functionType(List(A1.tpe), B1.tpe))
+ val params@List(x, default) = methSym newSyntheticValueParams methFormals
+ methSym setInfoAndEnter polyType(List(A1, B1), MethodType(params, B1.tpe))
+
+ val substParam = new TreeSymSubstituter(fun.vparams map (_.symbol), List(x))
+ val body = localTyper.typedPos(fun.pos) { import CODE._
+ def defaultAction(scrut: Tree) = REF(default) APPLY (REF(x))
+
+ object withDefaultTransformer extends gen.MatchMatcher {
+ override def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = {
+ val casesNoSynthCatchAll = dropSyntheticCatchAll(cases)
+ if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) orig
+ else {
+ val defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, defaultAction(selector.duplicate))
+ wrap(Match(/*gen.mkUnchecked*/(selector), casesNoSynthCatchAll :+ defaultCase))
+ }
+ }
+ override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = { import CODE._
+ ((matcher APPLY (scrut)) DOT nme.getOrElse) APPLY (defaultAction(scrut.duplicate)) // TODO: pass targs
+ }
+ override def caseVirtualizedMatchOpt(orig: Tree, prologue: List[Tree], cases: List[Tree], matchEndDef: Tree, wrap: Tree => Tree): Tree = { import CODE._
+ val scrutRef = REF(prologue.head.symbol) // scrut valdef is always emitted (except for nested matchers that handle alternatives)
+
+ val casesNewSynthCatchAll = cases.init :+ (deriveLabelDef(cases.last){
+ case Apply(matchEnd, List(Throw(Apply(Select(New(exTpt), nme.CONSTRUCTOR), _)))) if exTpt.tpe.typeSymbol eq MatchErrorClass =>
+ assert(matchEnd.symbol == matchEndDef.symbol, "matchEnd discrepancy "+(matchEnd, matchEndDef))
+ matchEnd APPLY (defaultAction(scrutRef))
+ case x => x
+ } setSymbol cases.last.symbol setType null)
+
+ val LabelDef(_, List(matchRes), rhs) = matchEndDef
+ val matchEnd = matchEndDef.symbol
+ matchRes setType B1.tpe
+ rhs setType B1.tpe
+ matchEndDef setType B1.tpe
+ matchRes.symbol setInfo B1.tpe
+ matchEnd setInfo MethodType(List(matchRes.symbol), B1.tpe)
+ cases foreach (c => c.symbol setInfo MethodType(List(), B1.tpe))
+
+ wrap(Block(prologue ++ casesNewSynthCatchAll, matchEndDef))
+ }
+ }
+
+ withDefaultTransformer(substParam(fun.body))
}
+ body.changeOwner(fun.symbol -> methSym)
- override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = {assert(false); orig}
- // {
- // object noOne extends Transformer {
- // override val treeCopy = newStrictTreeCopier // must duplicate everything
- // val one = _match.tpe member newTermName("one")
- // override def transform(tree: Tree): Tree = tree match {
- // case Apply(fun, List(a)) if fun.symbol == one =>
- // // blow one's argument away since all we want to know is whether the match succeeds or not
- // // (the alternative, making `one` CBN, would entail moving away from Option)
- // Apply(fun.duplicate, List(gen.mkZeroContravariantAfterTyper(a.tpe)))
- // case _ =>
- // super.transform(tree)
- // }
- // }
- // substTree(Apply(Apply(TypeApply(Select(_match.duplicate, _match.tpe.member(newTermName("isSuccess"))), targs map (_.duplicate)), List(scrut.duplicate)), List(noOne.transform(matcher))))
- // }
-
- override def caseVirtualizedMatchOpt(orig: Tree, zero: ValDef, x: ValDef, matchRes: ValDef, keepGoing: ValDef, stats: List[Tree], epilogue: Tree, wrap: Tree => Tree) = {assert(false); orig}
- // {
- // object dropMatchResAssign extends Transformer {
- // // override val treeCopy = newStrictTreeCopier // will duplicate below
- // override def transform(tree: Tree): Tree = tree match {
- // // don't compute the result of the match -- remove the block for the RHS (emitted by pmgen.one), except for the assignment to keepGoing
- // case gen.VirtualCaseDef(assignKeepGoing, matchRes, zero) if assignKeepGoing.lhs.symbol eq keepGoing.symbol =>
- // Block(List(assignKeepGoing), zero)
- // case _ =>
- // super.transform(tree)
- // }
- // }
- // val statsNoMatchRes: List[Tree] = stats map (dropMatchResAssign.transform) toList
- // val idaBlock = wrap(Block(
- // zero ::
- // x ::
- // /* drop matchRes def */
- // keepGoing ::
- // statsNoMatchRes,
- // NOT(REF(keepGoing.symbol)) // replace `if (keepGoing) throw new MatchError(...) else matchRes` epilogue by `!keepGoing`
- // ))
- // substTree(idaBlock.duplicate) // duplicate on block as a whole to ensure valdefs are properly cloned and substed
- // }
+ val methDef = DefDef(methSym, body)
+
+ // Have to repack the type to avoid mismatches when existentials
+ // appear in the result - see SI-4869.
+ methDef.tpt setType localTyper.packedType(body, methSym)
+ methDef
}
- DefDef(m, isDefinedAtTransformer(fun.body))
- }
+ // duplicate before applyOrElseMethodDef is run so that it does not mess up our trees and label symbols (we have a fresh set)
+ // otherwise `TreeSymSubstituter(fun.vparams map (_.symbol), params)` won't work as the subst has been run already
+ val bodyForIDA = {
+ val duped = fun.body.duplicate
+ val oldParams = new mutable.ListBuffer[Symbol]()
+ val newParams = new mutable.ListBuffer[Symbol]()
+
+ val oldSyms0 =
+ duped filter {
+ case l@LabelDef(_, params, _) =>
+ params foreach {p =>
+ val oldSym = p.symbol
+ p.symbol = oldSym.cloneSymbol
+ oldParams += oldSym
+ newParams += p.symbol
+ }
+ true
+ case _ => false
+ } map (_.symbol)
+ val oldSyms = oldParams.toList ++ oldSyms0
+ val newSyms = newParams.toList ++ (oldSyms0 map (_.cloneSymbol))
+ // println("duping "+ oldSyms +" --> "+ (newSyms map (_.ownerChain)))
- val members =
- if (isPartial) List(applyMethodDef, isDefinedAtMethodDef)
- else List(applyMethodDef)
+ val substLabels = new TreeSymSubstituter(oldSyms, newSyms)
+
+ substLabels(duped)
+ }
- localTyper.typedPos(fun.pos) {
- Block(
- List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, fun.pos)),
- Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
+ def isDefinedAtMethodDef = {
+ val methSym = anonClass.newMethod(nme.isDefinedAt, fun.pos, FINAL)
+ val params = methSym newSyntheticValueParams formals
+ methSym setInfoAndEnter MethodType(params, BooleanClass.tpe)
+
+ val substParam = new TreeSymSubstituter(fun.vparams map (_.symbol), params)
+ def doSubst(x: Tree) = substParam(resetLocalAttrsKeepLabels(x)) // see pos/t1761 for why `resetLocalAttrs`, but must keep label symbols around
+
+ object isDefinedAtTransformer extends gen.MatchMatcher {
+ // TODO: optimize duplication, but make sure ValDef's introduced by wrap are treated correctly
+ override def caseMatch(orig: Tree, selector: Tree, cases: List[CaseDef], wrap: Tree => Tree): Tree = { import CODE._
+ val casesNoSynthCatchAll = dropSyntheticCatchAll(cases)
+ if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) TRUE_typed
+ else
+ doSubst(wrap(
+ Match(/*gen.mkUnchecked*/(selector),
+ (casesNoSynthCatchAll map (c => deriveCaseDef(c)(x => TRUE_typed))) :+ (
+ DEFAULT ==> FALSE_typed)
+ )))
+ }
+ override def caseVirtualizedMatch(orig: Tree, _match: Tree, targs: List[Tree], scrut: Tree, matcher: Tree): Tree = {
+ object noOne extends Transformer {
+ override val treeCopy = newStrictTreeCopier // must duplicate everything
+ val one = _match.tpe member newTermName("one")
+ override def transform(tree: Tree): Tree = tree match {
+ case Apply(fun, List(a)) if fun.symbol == one =>
+ // blow one's argument away since all we want to know is whether the match succeeds or not
+ // (the alternative, making `one` CBN, would entail moving away from Option)
+ Apply(fun.duplicate, List(gen.mkZeroContravariantAfterTyper(a.tpe)))
+ case _ =>
+ super.transform(tree)
+ }
+ }
+ doSubst(Apply(Apply(TypeApply(Select(_match.duplicate, _match.tpe.member(newTermName("isSuccess"))), targs map (_.duplicate)), List(scrut.duplicate)), List(noOne.transform(matcher))))
+ }
+
+ override def caseVirtualizedMatchOpt(orig: Tree, prologue: List[Tree], cases: List[Tree], matchEndDef: Tree, wrap: Tree => Tree) = {
+ val matchEnd = matchEndDef.symbol
+ val LabelDef(_, List(matchRes), rhs) = matchEndDef
+ matchRes setType BooleanClass.tpe
+ rhs setType BooleanClass.tpe
+ matchEndDef setType BooleanClass.tpe
+ matchRes.symbol setInfo BooleanClass.tpe
+ matchEnd setInfo MethodType(List(matchRes.symbol), BooleanClass.tpe)
+ cases foreach (c => c.symbol setInfo MethodType(List(), BooleanClass.tpe))
+ // println("matchEnd: "+ matchEnd)
+
+ // when the type of the selector contains a skolem owned by the applyOrElseMethod, should reskolemize everything,
+ // for now, just cast the RHS (since we're just trying to keep the typer happy, the cast is meaningless)
+ // ARGH -- this is why I would prefer the typedMatchAnonFun approach (but alas, CPS blocks that)
+ val newPrologue = prologue match {
+ case List(vd@ValDef(mods, name, tpt, rhs)) => List(treeCopy.ValDef(vd, mods, name, tpt, gen.mkAsInstanceOf(rhs, tpt.tpe, true, false)))
+ case _ => prologue
+ }
+ object casesReturnTrue extends Transformer {
+ // override val treeCopy = newStrictTreeCopier // will duplicate below
+ override def transform(tree: Tree): Tree = tree match {
+ // don't compute the result of the match, return true instead
+ case Apply(fun, List(res)) if fun.symbol eq matchEnd =>
+ // println("matchend call "+ fun.symbol)
+ Apply(fun, List(TRUE_typed)) setType BooleanClass.tpe
+ case _ => super.transform(tree)
+ }
+ }
+ val newCatchAll = cases.last match {
+ case LabelDef(n, ps, Apply(matchEnd1, List(Throw(Apply(Select(New(exTpt), nme.CONSTRUCTOR), _))))) if exTpt.tpe.typeSymbol eq MatchErrorClass =>
+ assert(matchEnd1.symbol == matchEnd, "matchEnd discrepancy "+(matchEnd, matchEndDef))
+ List(treeCopy.LabelDef(cases.last, n, ps, matchEnd APPLY (FALSE_typed)) setSymbol cases.last.symbol)
+ case x => Nil
+ }
+ val casesWithoutCatchAll = if(newCatchAll.isEmpty) cases else cases.init
+ doSubst(wrap(Block(newPrologue ++ casesReturnTrue.transformTrees(casesWithoutCatchAll) ++ newCatchAll, matchEndDef)))
+
+ // val duped = idaBlock //.duplicate // TODO: duplication of labeldefs is BROKEN
+ // duped foreach {
+ // case l@LabelDef(name, params, rhs) if gen.hasSynthCaseSymbol(l) => println("newInfo"+ l.symbol.info)
+ // case _ =>
+ // }
+ }
+ }
+
+ val body = isDefinedAtTransformer(bodyForIDA)
+ body.changeOwner(fun.symbol -> methSym)
+
+ DefDef(methSym, body)
+ }
+
+ val members =
+ if (isPartial) {
+ assert(!opt.virtPatmat, "PartialFunction should have been synthesized during typer "+ fun);
+ List(applyOrElseMethodDef, isDefinedAtMethodDef)
+ } else List(applyMethodDef)
+
+ // println("MEMBERS "+ members)
+ val res = localTyper.typedPos(fun.pos) {
+ Block(
+ List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, fun.pos)),
+ Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
+ }
+ // println("MEMBERS TYPED "+ members)
+ res
}
- }
- }
def transformArgs(pos: Position, fun: Symbol, args: List[Tree], formals: List[Type]) = {
val isJava = fun.isJavaDefined
@@ -377,18 +485,18 @@ abstract class UnCurry extends InfoTransform
def sequenceToArray(tree: Tree) = {
val toArraySym = tree.tpe member nme.toArray
assert(toArraySym != NoSymbol)
- def getManifest(tp: Type): Tree = {
- val manifestOpt = localTyper.findManifest(tp, false)
+ def getClassTag(tp: Type): Tree = {
+ val tag = localTyper.resolveArrayTag(tree.pos, tp)
// Don't want bottom types getting any further than this (SI-4024)
- if (tp.typeSymbol.isBottomClass) getManifest(AnyClass.tpe)
- else if (!manifestOpt.tree.isEmpty) manifestOpt.tree
- else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi)
- else localTyper.getManifestTree(tree, tp, false)
+ if (tp.typeSymbol.isBottomClass) getClassTag(AnyClass.tpe)
+ else if (!tag.isEmpty) tag
+ else if (tp.bounds.hi ne tp) getClassTag(tp.bounds.hi)
+ else localTyper.TyperErrorGen.MissingClassTagError(tree, tp)
}
afterUncurry {
localTyper.typedPos(pos) {
Apply(gen.mkAttributedSelect(tree, toArraySym),
- List(getManifest(tree.tpe.baseType(TraversableClass).typeArgs.head)))
+ List(getClassTag(tree.tpe.baseType(TraversableClass).typeArgs.head)))
}
}
}
@@ -513,6 +621,12 @@ abstract class UnCurry extends InfoTransform
}
val sym = tree.symbol
+ // Take a pass looking for @specialize annotations and set all
+ // their SPECIALIZE flags for cheaper recognition.
+ if ((sym ne null) && (sym.isClass || sym.isMethod)) {
+ for (tp <- sym.typeParams ; if tp hasAnnotation SpecializedClass)
+ tp setFlag SPECIALIZED
+ }
val result = (
// TODO - settings.noassertions.value temporarily retained to avoid
// breakage until a reasonable interface is settled upon.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
index 18c7635b1e..a77df71312 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
@@ -24,6 +24,7 @@ trait Analyzer extends AnyRef
with NamesDefaults
with TypeDiagnostics
with ContextErrors
+ with StdAttachments
{
val global : Global
import global._
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index e37f5784c9..2d1369b11d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -129,11 +129,11 @@ trait ContextErrors {
val retyped = typed (tree.duplicate setType null)
val foundDecls = retyped.tpe.decls filter (sym => !sym.isConstructor && !sym.isSynthetic)
- if (foundDecls.isEmpty) found
+ if (foundDecls.isEmpty || (found.typeSymbol eq NoSymbol)) found
else {
// The members arrive marked private, presumably because there was no
// expected type and so they're considered members of an anon class.
- foundDecls foreach (_ resetFlag (PRIVATE | PROTECTED))
+ foundDecls foreach (_.makePublic)
// TODO: if any of the found parents match up with required parents after normalization,
// print the error so that they match. The major beneficiary there would be
// java.lang.Object vs. AnyRef.
@@ -277,11 +277,6 @@ trait ContextErrors {
setError(tree)
}
- def MultiDimensionalArrayError(tree: Tree) = {
- issueNormalTypeError(tree, "cannot create a generic multi-dimensional array of more than "+ definitions.MaxArrayDims+" dimensions")
- setError(tree)
- }
-
//typedSuper
def MixinMissingParentClassNameError(tree: Tree, mix: Name, clazz: Symbol) =
issueNormalTypeError(tree, mix+" does not name a parent class of "+clazz)
@@ -317,7 +312,7 @@ trait ContextErrors {
}
withAddendum(qual.pos)(
if (name == nme.CONSTRUCTOR) target + " does not have a constructor"
- else nameString + " is not a member of " + targetKindString + target + addendum
+ else nameString + " is not a member of " + targetKindString + target.directObjectString + addendum
)
}
issueNormalTypeError(sel, errMsg)
@@ -344,6 +339,16 @@ trait ContextErrors {
setError(tree)
}
+ def MacroEtaError(tree: Tree) = {
+ issueNormalTypeError(tree, "macros cannot be eta-expanded")
+ setError(tree)
+ }
+
+ def MacroPartialApplicationError(tree: Tree) = {
+ issueNormalTypeError(tree, "macros cannot be partially applied")
+ setError(tree)
+ }
+
//typedReturn
def ReturnOutsideOfDefError(tree: Tree) = {
issueNormalTypeError(tree, "return outside method definition")
@@ -376,21 +381,16 @@ trait ContextErrors {
setError(tree)
}
- def MissingParameterTypeError(fun: Tree, vparam: ValDef, pt: Type) = {
- def anonMessage = (
- "\nThe argument types of an anonymous function must be fully known. (SLS 8.5)" +
- "\nExpected type was: " + pt.toLongString
- )
-
- val suffix =
- if (!vparam.mods.isSynthetic) ""
- else " for expanded function" + (fun match {
- case Function(_, Match(_, _)) => anonMessage
- case _ => " " + fun
- })
+ def MissingParameterTypeError(fun: Tree, vparam: ValDef, pt: Type) =
+ if (vparam.mods.isSynthetic) fun match {
+ case Function(_, Match(_, _)) => MissingParameterTypeAnonMatchError(vparam, pt)
+ case _ => issueNormalTypeError(vparam, "missing parameter type for expanded function " + fun)
+ } else issueNormalTypeError(vparam, "missing parameter type")
- issueNormalTypeError(vparam, "missing parameter type" + suffix)
- }
+ def MissingParameterTypeAnonMatchError(vparam: Tree, pt: Type) =
+ issueNormalTypeError(vparam, "missing parameter type for expanded function\n"+
+ "The argument types of an anonymous function must be fully known. (SLS 8.5)\n"+
+ "Expected type was: " + pt.toLongString)
def ConstructorsOrderError(tree: Tree) = {
issueNormalTypeError(tree, "called constructor's definition must precede calling constructor's definition")
@@ -458,6 +458,9 @@ trait ContextErrors {
// doTypeApply
//tryNamesDefaults
+ def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) =
+ NormalTypeError(tree, "macros application do not support named and/or default arguments")
+
def WrongNumberOfArgsError(tree: Tree, fun: Tree) =
NormalTypeError(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun))
@@ -485,7 +488,7 @@ trait ContextErrors {
val keep = missing take 3 map (_.name)
".\nUnspecified value parameter%s %s".format(
if (missing.tail.isEmpty) "" else "s",
- if (missing drop 3 nonEmpty) (keep :+ "...").mkString(", ")
+ if ((missing drop 3).nonEmpty) (keep :+ "...").mkString(", ")
else keep.mkString("", ", ", ".")
)
}
@@ -506,6 +509,9 @@ trait ContextErrors {
def ApplyWithoutArgsError(tree: Tree, fun: Tree) =
NormalTypeError(tree, fun.tpe+" does not take parameters")
+ def DynamicVarArgUnsupported(tree: Tree, name: String) =
+ issueNormalTypeError(tree, name+ " does not support passing a vararg parameter")
+
//checkClassType
def TypeNotAStablePrefixError(tpt: Tree, pre: Type) = {
issueNormalTypeError(tpt, "type "+pre+" is not a stable prefix")
@@ -586,9 +592,9 @@ trait ContextErrors {
def AbstractExistentiallyOverParamerizedTpeError(tree: Tree, tp: Type) =
issueNormalTypeError(tree, "can't existentially abstract over parameterized type " + tp)
- //manifestTreee
- def MissingManifestError(tree: Tree, full: Boolean, tp: Type) = {
- issueNormalTypeError(tree, "cannot find "+(if (full) "" else "class ")+"manifest for element type "+tp)
+ // classTagTree
+ def MissingClassTagError(tree: Tree, tp: Type) = {
+ issueNormalTypeError(tree, "cannot find class tag for element type "+tp)
setError(tree)
}
@@ -627,7 +633,6 @@ trait ContextErrors {
def DefDefinedTwiceError(sym0: Symbol, sym1: Symbol) = {
val isBug = sym0.isAbstractType && sym1.isAbstractType && (sym0.name startsWith "_$")
issueSymbolTypeError(sym0, sym1+" is defined twice in " + context0.unit
- + ( if (sym0.isMacro && sym1.isMacro) "\n(note that macros cannot be overloaded)" else "" )
+ ( if (isBug) "\n(this error is likely due to a bug in the scala compiler involving wildcards in package objects)" else "" )
)
}
@@ -647,7 +652,7 @@ trait ContextErrors {
private def applyErrorMsg(tree: Tree, msg: String, argtpes: List[Type], pt: Type) = {
def asParams(xs: List[Any]) = xs.mkString("(", ", ", ")")
- def resType = if (pt isWildcard) "" else " with expected result type " + pt
+ def resType = if (pt.isWildcard) "" else " with expected result type " + pt
def allTypes = (alternatives(tree) flatMap (_.paramTypes)) ++ argtpes :+ pt
def locals = alternatives(tree) flatMap (_.typeParams)
@@ -666,7 +671,7 @@ trait ContextErrors {
}
private def ambiguousErrorMsgPos(pos: Position, pre: Type, sym1: Symbol, sym2: Symbol, rest: String) =
- if (sym1.hasDefaultFlag && sym2.hasDefaultFlag && sym1.enclClass == sym2.enclClass) {
+ if (sym1.hasDefault && sym2.hasDefault && sym1.enclClass == sym2.enclClass) {
val methodName = nme.defaultGetterToMethod(sym1.name)
(sym1.enclClass.pos,
"in "+ sym1.enclClass +", multiple overloaded alternatives of " + methodName +
@@ -682,7 +687,7 @@ trait ContextErrors {
def AccessError(tree: Tree, sym: Symbol, pre: Type, owner0: Symbol, explanation: String) = {
def errMsg = {
- val location = if (sym.isClassConstructor) owner0 else pre.widen
+ val location = if (sym.isClassConstructor) owner0 else pre.widen.directObjectString
underlyingSymbol(sym).fullLocationString + " cannot be accessed in " +
location + explanation
@@ -837,7 +842,7 @@ trait ContextErrors {
implicit val context0 = context
object SymValidateErrors extends Enumeration {
- val ImplicitConstr, ImplicitNotTerm, ImplicitTopObject,
+ val ImplicitConstr, ImplicitNotTermOrClass, ImplicitAtToplevel,
OverrideClass, SealedNonClass, AbstractNonClass,
OverrideConstr, AbstractOverride, LazyAndEarlyInit,
ByNameParameter, AbstractVar = Value
@@ -853,6 +858,19 @@ trait ContextErrors {
def TypeSigError(tree: Tree, ex: TypeError) = {
ex match {
+ case CyclicReference(_, _) if tree.symbol.isTermMacro =>
+ // say, we have a macro def `foo` and its macro impl `impl`
+ // if impl: 1) omits return type, 2) has anything implicit in its body, 3) sees foo
+ //
+ // then implicit search will trigger an error
+ // (note that this is not a compilation error, it's an artifact of implicit search algorithm)
+ // normally, such "errors" are discarded by `isCyclicOrErroneous` in Implicits.scala
+ // but in our case this won't work, because isCyclicOrErroneous catches CyclicReference exceptions
+ // while our error will present itself as a "recursive method needs a return type"
+ //
+ // hence we (together with reportTypeError in TypeDiagnostics) make sure that this CyclicReference
+ // evades all the handlers on its way and successfully reaches `isCyclicOrErroneous` in Implicits
+ throw ex
case CyclicReference(sym, info: TypeCompleter) =>
issueNormalTypeError(tree, typer.cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
case _ =>
@@ -903,10 +921,10 @@ trait ContextErrors {
case ImplicitConstr =>
"`implicit' modifier not allowed for constructors"
- case ImplicitNotTerm =>
- "`implicit' modifier can be used only for values, variables and methods"
+ case ImplicitNotTermOrClass =>
+ "`implicit' modifier can be used only for values, variables, methods and classes"
- case ImplicitTopObject =>
+ case ImplicitAtToplevel =>
"`implicit' modifier cannot be used for top-level objects"
case OverrideClass =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index a1ba8a2982..e2d4efab83 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -67,6 +67,7 @@ trait Contexts { self: Analyzer =>
val c = sc.make(unit, tree, sc.owner, sc.scope, sc.imports)
if (erasedTypes) c.setThrowErrors() else c.setReportErrors()
c.implicitsEnabled = !erasedTypes
+ c.enrichmentEnabled = c.implicitsEnabled
c
}
@@ -105,7 +106,7 @@ trait Contexts { self: Analyzer =>
// not inherited to child contexts
var depth: Int = 0
var imports: List[ImportInfo] = List() // currently visible imports
- var openImplicits: List[(Type,Symbol)] = List() // types for which implicit arguments
+ var openImplicits: List[(Type,Tree)] = List() // types for which implicit arguments
// are currently searched
// for a named application block (Tree) the corresponding NamedApplyInfo
var namedApplyBlockInfo: Option[(Tree, NamedApplyInfo)] = None
@@ -119,6 +120,8 @@ trait Contexts { self: Analyzer =>
var diagnostic: List[String] = Nil // these messages are printed when issuing an error
var implicitsEnabled = false
+ var macrosEnabled = true
+ var enrichmentEnabled = false // to selectively allow enrichment in patterns, where other kinds of implicit conversions are not allowed
var checking = false
var retyping = false
@@ -181,11 +184,49 @@ trait Contexts { self: Analyzer =>
def logError(err: AbsTypeError) = buffer += err
+ def withImplicitsEnabled[T](op: => T): T = {
+ val saved = implicitsEnabled
+ implicitsEnabled = true
+ try op
+ finally implicitsEnabled = saved
+ }
+
def withImplicitsDisabled[T](op: => T): T = {
val saved = implicitsEnabled
implicitsEnabled = false
+ val savedP = enrichmentEnabled
+ enrichmentEnabled = false
try op
- finally implicitsEnabled = saved
+ finally {
+ implicitsEnabled = saved
+ enrichmentEnabled = savedP
+ }
+ }
+
+ def withImplicitsDisabledAllowEnrichment[T](op: => T): T = {
+ val saved = implicitsEnabled
+ implicitsEnabled = false
+ val savedP = enrichmentEnabled
+ enrichmentEnabled = true
+ try op
+ finally {
+ implicitsEnabled = saved
+ enrichmentEnabled = savedP
+ }
+ }
+
+ def withMacrosEnabled[T](op: => T): T = {
+ val saved = macrosEnabled
+ macrosEnabled = true
+ try op
+ finally macrosEnabled = saved
+ }
+
+ def withMacrosDisabled[T](op: => T): T = {
+ val saved = macrosEnabled
+ macrosEnabled = false
+ try op
+ finally macrosEnabled = saved
}
def make(unit: CompilationUnit, tree: Tree, owner: Symbol,
@@ -223,6 +264,8 @@ trait Contexts { self: Analyzer =>
c.diagnostic = this.diagnostic
c.typingIndentLevel = typingIndentLevel
c.implicitsEnabled = this.implicitsEnabled
+ c.macrosEnabled = this.macrosEnabled
+ c.enrichmentEnabled = this.enrichmentEnabled
c.checking = this.checking
c.retyping = this.retyping
c.openImplicits = this.openImplicits
@@ -237,6 +280,7 @@ trait Contexts { self: Analyzer =>
val c = make(unit, EmptyTree, owner, scope, imports)
c.setReportErrors()
c.implicitsEnabled = true
+ c.macrosEnabled = true
c
}
@@ -274,6 +318,7 @@ trait Contexts { self: Analyzer =>
def makeImplicit(reportAmbiguousErrors: Boolean) = {
val c = makeSilent(reportAmbiguousErrors)
c.implicitsEnabled = false
+ c.enrichmentEnabled = false
c
}
@@ -312,6 +357,7 @@ trait Contexts { self: Analyzer =>
def issue(err: AbsTypeError) {
debugwarn("issue error: " + err.errMsg)
+ if (settings.Yissuedebug.value) (new Exception).printStackTrace()
if (reportErrors) unitError(err.errPos, addDiagString(err.errMsg))
else if (bufferErrors) { buffer += err }
else throw new TypeError(err.errPos, err.errMsg)
@@ -319,6 +365,7 @@ trait Contexts { self: Analyzer =>
def issueAmbiguousError(pre: Type, sym1: Symbol, sym2: Symbol, err: AbsTypeError) {
debugwarn("issue ambiguous error: " + err.errMsg)
+ if (settings.Yissuedebug.value) (new Exception).printStackTrace()
if (ambiguousErrors) {
if (!pre.isErroneous && !sym1.isErroneous && !sym2.isErroneous)
unitError(err.errPos, err.errMsg)
@@ -328,6 +375,7 @@ trait Contexts { self: Analyzer =>
def issueAmbiguousError(err: AbsTypeError) {
debugwarn("issue ambiguous error: " + err.errMsg)
+ if (settings.Yissuedebug.value) (new Exception).printStackTrace()
if (ambiguousErrors)
unitError(err.errPos, addDiagString(err.errMsg))
else if (bufferErrors) { buffer += err }
@@ -664,7 +712,7 @@ trait Contexts { self: Analyzer =>
case List(ImportSelector(nme.WILDCARD, _, _, _)) => List(sym)
case ImportSelector(from, _, to, _) :: _ if from == sym.name =>
if (to == nme.WILDCARD) List()
- else { val sym1 = sym.cloneSymbol; sym1.name = to; List(sym1) }
+ else List(sym.cloneSymbol(sym.owner, sym.rawflags, to))
case _ :: rest => transformImport(rest, sym)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala
new file mode 100644
index 0000000000..0b414801d6
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/DestructureTypes.scala
@@ -0,0 +1,206 @@
+/* NSC -- new Scala compiler
+* Copyright 2005-2012 LAMP/EPFL
+* @author Paul Phillips
+*/
+
+package scala.tools.nsc
+package typechecker
+
+/** A generic means of breaking down types into their subcomponents.
+ * Types are decomposed top down, and recognizable substructure is
+ * dispatched via self-apparently named methods. Those methods can
+ * be overridden for custom behavior, but only the abstract methods
+ * require implementations, each of which must create some unknown
+ * "Node" type from its inputs.
+ *
+ * - wrapProduct create Node from a product of Nodes
+ * - wrapSequence create Node from a sequence of Nodes
+ * - wrapAtom create Node from an arbitrary value
+ *
+ * This is a work in progress.
+ */
+trait DestructureTypes {
+ val global: Global
+ import global._
+ import definitions.{ NothingClass, AnyClass }
+
+ trait DestructureType[Node] extends (Type => Node) {
+ def withLabel(node: Node, label: String): Node
+ def withType(node: Node, typeName: String): Node
+
+ def wrapEmpty: Node
+ def wrapPoly(in: Node, out: Node): Node
+ def wrapMono(in: Node, out: Node): Node
+ def wrapProduct(nodes: List[Node]): Node
+ def wrapSequence(nodes: List[Node]): Node
+ def wrapAtom[U](value: U): Node
+
+ private implicit def liftToTerm(name: String): TermName = newTermName(name)
+
+ private val openSymbols = collection.mutable.Set[Symbol]()
+
+ private def nodeList[T](elems: List[T], mkNode: T => Node): Node =
+ if (elems.isEmpty) wrapEmpty else list(elems map mkNode)
+
+ private def scopeMemberList(elems: List[Symbol]): Node = nodeList(elems, wrapAtom)
+ private def typeList(elems: List[Type]): Node = nodeList(elems, this)
+ private def symbolList(elems: List[Symbol]): Node = nodeList(elems, wrapSymbolInfo)
+ private def treeList(elems: List[Tree]): Node = nodeList(elems, wrapTree)
+ private def annotationList(annots: List[AnnotationInfo]): Node = nodeList(annots, annotation)
+
+ private def assocsNode(ann: AnnotationInfo): Node = {
+ val (names, args) = ann.assocs.toIndexedSeq.unzip
+ if (names.isEmpty) wrapEmpty
+ else node("assocs", nodeList(names.indices.toList, (i: Int) => atom(names(i).toString, args(i))))
+ }
+ private def typeTypeName(tp: Type) = tp match {
+ case mt @ MethodType(_, _) if mt.isImplicit => "ImplicitMethodType"
+ case TypeRef(_, sym, _) => typeRefType(sym)
+ case _ => tp.kind
+ }
+
+ def wrapTree(tree: Tree): Node = withType(
+ tree match {
+ case x: NameTree => atom(x.name.toString, x)
+ case _ => wrapAtom(tree)
+ },
+ tree.printingPrefix
+ )
+ def wrapSymbol(label: String, sym: Symbol): Node = {
+ if (sym eq NoSymbol) wrapEmpty
+ else atom(label, sym)
+ }
+ def wrapInfo(sym: Symbol) = sym.info match {
+ case TypeBounds(lo, hi) => typeBounds(lo, hi)
+ case PolyType(tparams, restpe) => polyFunction(tparams, restpe)
+ case _ => wrapEmpty
+ }
+ def wrapSymbolInfo(sym: Symbol): Node = {
+ if ((sym eq NoSymbol) || openSymbols(sym)) wrapEmpty
+ else {
+ openSymbols += sym
+ try product(symbolType(sym), wrapAtom(sym.defString))
+ finally openSymbols -= sym
+ }
+ }
+
+ def list(nodes: List[Node]): Node = wrapSequence(nodes)
+ def product(tp: Type, nodes: Node*): Node = product(typeTypeName(tp), nodes: _*)
+ def product(typeName: String, nodes: Node*): Node = (
+ nodes.toList filterNot (_ == wrapEmpty) match {
+ case Nil => wrapEmpty
+ case xs => withType(wrapProduct(xs), typeName)
+ }
+ )
+
+ def atom[U](label: String, value: U): Node = node(label, wrapAtom(value))
+ def constant(label: String, const: Constant): Node = atom(label, const)
+
+ def scope(decls: Scope): Node = node("decls", scopeMemberList(decls.toList))
+ def const[T](named: (String, T)): Node = constant(named._1, Constant(named._2))
+
+ def resultType(restpe: Type): Node = this("resultType", restpe)
+ def typeParams(tps: List[Symbol]): Node = node("typeParams", symbolList(tps))
+ def valueParams(params: List[Symbol]): Node = node("params", symbolList(params))
+ def typeArgs(tps: List[Type]): Node = node("args", typeList(tps))
+ def parentList(tps: List[Type]): Node = node("parents", typeList(tps))
+
+ def polyFunction(tparams: List[Symbol], restpe: Type): Node = wrapPoly(typeParams(tparams), resultType(restpe))
+ def monoFunction(params: List[Symbol], restpe: Type): Node = wrapMono(valueParams(params), resultType(restpe))
+ def nullaryFunction(restpe: Type): Node = wrapMono(wrapEmpty, this(restpe))
+
+ def prefix(pre: Type): Node = pre match {
+ case NoPrefix => wrapEmpty
+ case _ => this("pre", pre)
+ }
+ def typeBounds(lo0: Type, hi0: Type): Node = {
+ val lo = if ((lo0 eq WildcardType) || (lo0.typeSymbol eq NothingClass)) wrapEmpty else this("lo", lo0)
+ val hi = if ((hi0 eq WildcardType) || (hi0.typeSymbol eq AnyClass)) wrapEmpty else this("hi", hi0)
+
+ product("TypeBounds", lo, hi)
+ }
+
+ def annotation(ann: AnnotationInfo): Node = product(
+ "AnnotationInfo",
+ this("atp", ann.atp),
+ node("args", treeList(ann.args)),
+ assocsNode(ann)
+ )
+ def typeConstraint(constr: TypeConstraint): Node = product(
+ "TypeConstraint",
+ node("lo", typeList(constr.loBounds)),
+ node("hi", typeList(constr.hiBounds)),
+ this("inst", constr.inst)
+ )
+ def annotatedType(annotations: List[AnnotationInfo], underlying: Type) = product(
+ "AnnotatedType",
+ node("annotations", annotationList(annotations)),
+ this("underlying", underlying)
+ )
+
+ /** This imposes additional structure beyond that which is visible in
+ * the case class hierarchy. In particular, (too) many different constructs
+ * are encoded in TypeRefs; here they are partitioned somewhat before
+ * being dispatched.
+ *
+ * For example, a typical type parameter is encoded as TypeRef(NoPrefix, sym, Nil)
+ * with its upper and lower bounds stored in the info of the symbol. Viewing the
+ * TypeRef naively we are treated to both too much information (useless prefix, usually
+ * empty args) and too little (bounds hidden behind indirection.) So drop the prefix
+ * and promote the bounds.
+ */
+ def typeRef(tp: TypeRef) = {
+ val TypeRef(pre, sym, args) = tp
+ // Filtered down to elements with "interesting" content
+ product(
+ tp,
+ if (sym.isDefinedInPackage) wrapEmpty else prefix(pre),
+ wrapSymbolInfo(sym),
+ typeArgs(args),
+ if (tp ne tp.normalize) this("normalize", tp.normalize) else wrapEmpty
+ )
+ }
+
+ def symbolType(sym: Symbol) = (
+ if (sym.isRefinementClass) "Refinement"
+ else if (sym.isAliasType) "Alias"
+ else if (sym.isTypeSkolem) "TypeSkolem"
+ else if (sym.isTypeParameter) "TypeParam"
+ else if (sym.isAbstractType) "AbstractType"
+ else if (sym.isType) "TypeSymbol"
+ else "TermSymbol"
+ )
+ def typeRefType(sym: Symbol) = (
+ if (sym.isRefinementClass) "RefinementTypeRef"
+ else if (sym.isAliasType) "AliasTypeRef"
+ else if (sym.isTypeSkolem) "SkolemTypeRef"
+ else if (sym.isTypeParameter) "TypeParamTypeRef"
+ else if (sym.isAbstractType) "AbstractTypeRef"
+ else "TypeRef"
+ ) + ( if (sym.isFBounded) "(F-Bounded)" else "" )
+
+ def node(label: String, node: Node): Node = withLabel(node, label)
+ def apply(label: String, tp: Type): Node = withLabel(this(tp), label)
+
+ def apply(tp: Type): Node = tp match {
+ case AntiPolyType(pre, targs) => product(tp, prefix(pre), typeArgs(targs))
+ case ClassInfoType(parents, decls, clazz) => product(tp, parentList(parents), scope(decls), wrapAtom(clazz))
+ case ConstantType(const) => product(tp, constant("value", const))
+ case DeBruijnIndex(level, index, args) => product(tp, const("level" -> level), const("index" -> index), typeArgs(args))
+ case OverloadedType(pre, alts) => product(tp, prefix(pre), node("alts", typeList(alts map pre.memberType)))
+ case RefinedType(parents, decls) => product(tp, parentList(parents), scope(decls))
+ case SingleType(pre, sym) => product(tp, prefix(pre), wrapAtom(sym))
+ case SuperType(thistp, supertp) => product(tp, this("this", thistp), this("super", supertp))
+ case ThisType(clazz) => product(tp, wrapAtom(clazz))
+ case TypeVar(inst, constr) => product(tp, this("inst", inst), typeConstraint(constr))
+ case AnnotatedType(annotations, underlying, _) => annotatedType(annotations, underlying)
+ case ExistentialType(tparams, underlying) => polyFunction(tparams, underlying)
+ case PolyType(tparams, restpe) => polyFunction(tparams, restpe)
+ case MethodType(params, restpe) => monoFunction(params, restpe)
+ case NullaryMethodType(restpe) => nullaryFunction(restpe)
+ case TypeBounds(lo, hi) => typeBounds(lo, hi)
+ case tr @ TypeRef(pre, sym, args) => typeRef(tr)
+ case _ => wrapAtom(tp) // XXX see what this is
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index eb0d489901..2574a1d241 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -79,7 +79,17 @@ abstract class Duplicators extends Analyzer {
override def mapOver(tpe: Type): Type = tpe match {
case TypeRef(NoPrefix, sym, args) if sym.isTypeParameterOrSkolem =>
- val sym1 = context.scope.lookup(sym.name)
+ var sym1 = context.scope.lookup(sym.name)
+ if (sym1 eq NoSymbol) {
+ // try harder (look in outer scopes)
+ // with virtpatmat, this can happen when the sym is referenced in the scope of a LabelDef but is defined in the scope of an outer DefDef (e.g., in AbstractPartialFunction's andThen)
+ BodyDuplicator.super.silent(_.typedType(Ident(sym.name))) match {
+ case SilentResultValue(t) =>
+ sym1 = t.symbol
+ debuglog("fixed by trying harder: "+(sym, sym1, context))
+ case _ =>
+ }
+ }
// assert(sym1 ne NoSymbol, tpe)
if ((sym1 ne NoSymbol) && (sym1 ne sym)) {
debuglog("fixing " + sym + " -> " + sym1)
@@ -176,7 +186,7 @@ abstract class Duplicators extends Analyzer {
oldClassOwner = oldThis
newClassOwner = newThis
invalidate(ddef.tparams)
- for (vdef <- ddef.vparamss.flatten) {
+ mforeach(ddef.vparamss) { vdef =>
invalidate(vdef)
vdef.tpe = null
}
@@ -255,7 +265,10 @@ abstract class Duplicators extends Analyzer {
case ldef @ LabelDef(name, params, rhs) =>
// log("label def: " + ldef)
+ // in case the rhs contains any definitions -- TODO: is this necessary?
+ invalidate(rhs)
ldef.tpe = null
+
// since typer does not create the symbols for a LabelDef's params,
// we do that manually here -- we should really refactor LabelDef to be a subclass of DefDef
def newParam(p: Tree): Ident = {
@@ -265,6 +278,7 @@ abstract class Duplicators extends Analyzer {
val params1 = params map newParam
val rhs1 = (new TreeSubstituter(params map (_.symbol), params1) transform rhs) // TODO: duplicate?
rhs1.tpe = null
+
super.typed(treeCopy.LabelDef(tree, name, params1, rhs1), mode, pt)
case Bind(name, _) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 7d1198a4a2..0d7ef71193 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -32,7 +32,10 @@ trait Implicits {
import global.typer.{ printTyping, deindentTyping, indentTyping, printInference }
def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context): SearchResult =
- inferImplicit(tree, pt, reportAmbiguous, isView, context, true)
+ inferImplicit(tree, pt, reportAmbiguous, isView, context, true, tree.pos)
+
+ def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult =
+ inferImplicit(tree, pt, reportAmbiguous, isView, context, saveAmbiguousDivergent, tree.pos)
/** Search for an implicit value. See the comment on `result` at the end of class `ImplicitSearch`
* for more info how the search is conducted.
@@ -48,9 +51,12 @@ trait Implicits {
* @param saveAmbiguousDivergent False if any divergent/ambiguous errors should be ignored after
* implicits search,
* true if they should be reported (used in further typechecking).
+ * @param pos Position that is should be used for tracing and error reporting
+ * (useful when we infer synthetic stuff and pass EmptyTree in the `tree` argument)
+ * If it's set NoPosition, then position-based services will use `tree.pos`
* @return A search result
*/
- def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult = {
+ def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean, pos: Position): SearchResult = {
printInference("[infer %s] %s with pt=%s in %s".format(
if (isView) "view" else "implicit",
tree, pt, context.owner.enclClass)
@@ -71,9 +77,11 @@ trait Implicits {
if (printInfers && !tree.isEmpty && !context.undetparams.isEmpty)
printTyping("typing implicit: %s %s".format(tree, context.undetparamsString))
val implicitSearchContext = context.makeImplicit(reportAmbiguous)
- val result = new ImplicitSearch(tree, pt, isView, implicitSearchContext).bestImplicit
- if (saveAmbiguousDivergent && implicitSearchContext.hasErrors)
+ val result = new ImplicitSearch(tree, pt, isView, implicitSearchContext, pos).bestImplicit
+ if (saveAmbiguousDivergent && implicitSearchContext.hasErrors) {
context.updateBuffer(implicitSearchContext.errBuffer.filter(err => err.kind == ErrorKinds.Ambiguous || err.kind == ErrorKinds.Divergent))
+ debugwarn("update buffer: " + implicitSearchContext.errBuffer)
+ }
printInference("[infer implicit] inferred " + result)
context.undetparams = context.undetparams filterNot result.subst.from.contains
@@ -86,6 +94,27 @@ trait Implicits {
result
}
+ /** Find all views from type `tp` (in which `tpars` are free)
+ *
+ * Note that the trees in the search results in the returned list share the same type variables.
+ * Ignore their constr field! The list of type constraints returned along with each tree specifies the constraints that
+ * must be met by the corresponding type parameter in `tpars` (for the returned implicit view to be valid).
+ *
+ * @arg tp from-type for the implicit conversion
+ * @arg context search implicits here
+ * @arg tpars symbols that should be considered free type variables
+ * (implicit search should not try to solve them, just track their constraints)
+ */
+ def allViewsFrom(tp: Type, context: Context, tpars: List[Symbol]): List[(SearchResult, List[TypeConstraint])] = {
+ // my untouchable typevars are better than yours (they can't be constrained by them)
+ val tvars = tpars map (TypeVar untouchable _)
+ val tpSubsted = tp.subst(tpars, tvars)
+
+ val search = new ImplicitSearch(EmptyTree, functionType(List(tpSubsted), AnyClass.tpe), true, context.makeImplicit(false))
+
+ search.allImplicitsPoly(tvars)
+ }
+
private final val sizeLimit = 50000
private type Infos = List[ImplicitInfo]
private type Infoss = List[List[ImplicitInfo]]
@@ -100,8 +129,6 @@ trait Implicits {
improvesCache.clear()
}
- private val ManifestSymbols = Set(PartialManifestClass, FullManifestClass, OptManifestClass)
-
/* Map a polytype to one in which all type parameters and argument-dependent types are replaced by wildcards.
* Consider `implicit def b(implicit x: A): x.T = error("")`. We need to approximate DebruijnIndex types
* when checking whether `b` is a valid implicit, as we haven't even searched a value for the implicit arg `x`,
@@ -139,7 +166,7 @@ trait Implicits {
}
def isCyclicOrErroneous =
- try containsError(tpe)
+ try sym.hasFlag(LOCKED) || containsError(tpe)
catch { case _: CyclicReference => true }
var useCountArg: Int = 0
@@ -251,8 +278,11 @@ trait Implicits {
* @param pt The original expected type of the implicit.
* @param isView We are looking for a view
* @param context0 The context used for the implicit search
+ * @param pos0 Position that is preferable for use in tracing and error reporting
+ * (useful when we infer synthetic stuff and pass EmptyTree in the `tree` argument)
+ * If it's set to NoPosition, then position-based services will use `tree.pos`
*/
- class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context)
+ class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context, pos0: Position = NoPosition)
extends Typer(context0) with ImplicitsContextErrors {
printTyping(
ptBlock("new ImplicitSearch",
@@ -264,6 +294,13 @@ trait Implicits {
)
)
// assert(tree.isEmpty || tree.pos.isDefined, tree)
+ def pos = if (pos0 != NoPosition) pos0 else tree.pos
+
+ def failure(what: Any, reason: String, pos: Position = this.pos): SearchResult = {
+ if (settings.XlogImplicits.value)
+ reporter.echo(pos, what+" is not a valid implicit value for "+pt+" because:\n"+reason)
+ SearchFailure
+ }
import infer._
/** Is implicit info `info1` better than implicit info `info2`?
@@ -351,18 +388,18 @@ trait Implicits {
* @pre `info.tpe` does not contain an error
*/
private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean): SearchResult = {
- (context.openImplicits find { case (tp, sym) => sym == tree.symbol && dominates(pt, tp)}) match {
+ (context.openImplicits find { case (tp, tree1) => tree1.symbol == tree.symbol && dominates(pt, tp)}) match {
case Some(pending) =>
- // println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG
+ //println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG
throw DivergentImplicit
case None =>
try {
- context.openImplicits = (pt, tree.symbol) :: context.openImplicits
+ context.openImplicits = (pt, tree) :: context.openImplicits
// println(" "*context.openImplicits.length+"typed implicit "+info+" for "+pt) //@MDEBUG
typedImplicit0(info, ptChecked)
} catch {
case ex: DivergentImplicit =>
- // println("DivergentImplicit for pt:"+ pt +", open implicits:"+context.openImplicits) //@MDEBUG
+ //println("DivergentImplicit for pt:"+ pt +", open implicits:"+context.openImplicits) //@MDEBUG
if (context.openImplicits.tail.isEmpty) {
if (!(pt.isErroneous))
DivergingImplicitExpansionError(tree, pt, info.sym)(context)
@@ -494,7 +531,7 @@ trait Implicits {
private def typedImplicit0(info: ImplicitInfo, ptChecked: Boolean): SearchResult = {
incCounter(plausiblyCompatibleImplicits)
- printTyping(
+ printTyping (
ptBlock("typedImplicit0",
"info.name" -> info.name,
"ptChecked" -> ptChecked,
@@ -515,7 +552,7 @@ trait Implicits {
private def typedImplicit1(info: ImplicitInfo): SearchResult = {
incCounter(matchingImplicits)
- val itree = atPos(tree.pos.focus) {
+ val itree = atPos(pos.focus) {
if (info.pre == NoPrefix) Ident(info.name)
else Select(gen.mkAttributedQualifier(info.pre), info.name)
}
@@ -523,11 +560,7 @@ trait Implicits {
typeDebug.ptTree(itree), wildPt, info.name, info.tpe)
)
- def fail(reason: String): SearchResult = {
- if (settings.XlogImplicits.value)
- inform(itree+" is not a valid implicit value for "+pt+" because:\n"+reason)
- SearchFailure
- }
+ def fail(reason: String): SearchResult = failure(itree, reason)
try {
val itree1 =
if (isView) {
@@ -600,6 +633,7 @@ trait Implicits {
else {
val subst = new TreeTypeSubstituter(okParams, okArgs)
subst traverse itree2
+ notifyUndetparamsInferred(okParams, okArgs)
subst
}
@@ -677,7 +711,7 @@ trait Implicits {
def comesBefore(sym: Symbol, owner: Symbol) = {
val ownerPos = owner.pos.pointOrElse(Int.MaxValue)
sym.pos.pointOrElse(0) < ownerPos && (
- if (sym hasAccessorFlag) {
+ if (sym.hasAccessorFlag) {
val symAcc = sym.accessed // #3373
symAcc.pos.pointOrElse(0) < ownerPos &&
!(owner.ownerChain exists (o => (o eq sym) || (o eq symAcc))) // probably faster to iterate only once, don't feel like duplicating hasTransOwner for this case
@@ -707,6 +741,7 @@ trait Implicits {
info.isCyclicOrErroneous
|| isView && isPredefMemberNamed(info.sym, nme.conforms)
|| isShadowed(info.name)
+ || (!context.macrosEnabled && info.sym.isTermMacro)
)
/** True if a given ImplicitInfo (already known isValid) is eligible.
@@ -796,7 +831,7 @@ trait Implicits {
/** Returns all eligible ImplicitInfos and their SearchResults in a map.
*/
- def findAll() = eligible map (info => (info, typedImplicit(info, false))) toMap
+ def findAll() = mapFrom(eligible)(typedImplicit(_, false))
/** Returns the SearchResult of the best match.
*/
@@ -825,7 +860,7 @@ trait Implicits {
throw DivergentImplicit
if (invalidImplicits.nonEmpty)
- setAddendum(tree.pos, () =>
+ setAddendum(pos, () =>
"\n Note: implicit "+invalidImplicits.head+" is not applicable here"+
" because it comes after the application point and it lacks an explicit result type")
}
@@ -1085,6 +1120,62 @@ trait Implicits {
implicitInfoss1
}
+ private def TagSymbols = TagMaterializers.keySet
+ private val TagMaterializers = Map[Symbol, Symbol](
+ ArrayTagClass -> MacroInternal_materializeArrayTag,
+ ErasureTagClass -> MacroInternal_materializeErasureTag,
+ ClassTagClass -> MacroInternal_materializeClassTag,
+ TypeTagClass -> MacroInternal_materializeTypeTag,
+ ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag
+ )
+
+ /** Creates a tree will produce a tag of the requested flavor.
+ * An EmptyTree is returned if materialization fails.
+ */
+ private def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = {
+ def success(arg: Tree) =
+ try {
+ val tree1 = typed(atPos(pos.focus)(arg))
+ def isErroneous = tree exists (_.isErroneous)
+ if (context.hasErrors) failure(tp, "failed to typecheck the materialized typetag: %n%s".format(context.errBuffer.head.errMsg), context.errBuffer.head.errPos)
+ else new SearchResult(tree1, EmptyTreeTypeSubstituter)
+ } catch {
+ case ex: TypeError =>
+ failure(arg, "failed to typecheck the materialized typetag: %n%s".format(ex.msg), ex.pos)
+ }
+
+ val prefix = (
+ // ClassTags only exist for scala.reflect.mirror, so their materializer
+ // doesn't care about prefixes
+ if ((tagClass eq ArrayTagClass) || (tagClass eq ErasureTagClass) || (tagClass eq ClassTagClass)) ReflectMirrorPrefix
+ else pre match {
+ // [Eugene to Martin] this is the crux of the interaction between
+ // implicits and reifiers here we need to turn a (supposedly
+ // path-dependent) type into a tree that will be used as a prefix I'm
+ // not sure if I've done this right - please, review
+ case SingleType(prePre, preSym) =>
+ gen.mkAttributedRef(prePre, preSym) setType pre
+ // necessary only to compile typetags used inside the Universe cake
+ case ThisType(thisSym) =>
+ gen.mkAttributedThis(thisSym)
+ case _ =>
+ // if ``pre'' is not a PDT, e.g. if someone wrote
+ // implicitly[scala.reflect.makro.Context#TypeTag[Int]]
+ // then we need to fail, because we don't know the prefix to use during type reification
+ return failure(tp, "tag error: unsupported prefix type %s (%s)".format(pre, pre.kind))
+ }
+ )
+ // todo. migrate hardcoded materialization in Implicits to corresponding implicit macros
+ var materializer = atPos(pos.focus)(
+ gen.mkMethodCall(TagMaterializers(tagClass), List(tp), List(prefix))
+ )
+ if (settings.XlogImplicits.value) println("materializing requested %s.%s[%s] using %s".format(pre, tagClass.name, tp, materializer))
+ if (context.macrosEnabled) success(materializer)
+ else failure(materializer, "macros are disabled")
+ }
+
+ private val ManifestSymbols = Set[Symbol](PartialManifestClass, FullManifestClass, OptManifestClass)
+
/** Creates a tree that calls the relevant factory method in object
* reflect.Manifest for type 'tp'. An EmptyTree is returned if
* no manifest is found. todo: make this instantiate take type params as well?
@@ -1107,7 +1198,7 @@ trait Implicits {
/** Re-wraps a type in a manifest before calling inferImplicit on the result */
def findManifest(tp: Type, manifestClass: Symbol = if (full) FullManifestClass else PartialManifestClass) =
- inferImplicit(tree, appliedType(manifestClass.typeConstructor, List(tp)), true, false, context).tree
+ inferImplicit(tree, appliedType(manifestClass, tp), true, false, context).tree
def findSubManifest(tp: Type) = findManifest(tp, if (full) FullManifestClass else OptManifestClass)
def mot(tp0: Type, from: List[Symbol], to: List[Type]): SearchResult = {
@@ -1174,32 +1265,45 @@ trait Implicits {
}
}
- mot(tp, Nil, Nil)
+ val tagInScope =
+ if (full) context.withMacrosDisabled(resolveTypeTag(pos, ReflectMirrorPrefix.tpe, tp, true))
+ else context.withMacrosDisabled(resolveArrayTag(pos, tp))
+ if (tagInScope.isEmpty) mot(tp, Nil, Nil)
+ else {
+ val interop =
+ if (full) gen.mkMethodCall(ReflectPackage, nme.concreteTypeTagToManifest, List(tp), List(tagInScope))
+ else gen.mkMethodCall(ReflectPackage, nme.arrayTagToClassManifest, List(tp), List(tagInScope))
+ wrapResult(interop)
+ }
}
def wrapResult(tree: Tree): SearchResult =
if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter)
- /** The manifest corresponding to type `pt`, provided `pt` is an instance of Manifest.
+ /** The tag corresponding to type `pt`, provided `pt` is a flavor of a tag.
*/
- private def implicitManifestOrOfExpectedType(pt: Type): SearchResult = pt.dealias match {
- case TypeRef(_, sym, args) if ManifestSymbols(sym) =>
- manifestOfType(args.head, sym == FullManifestClass) match {
+ private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match {
+ case TypeRef(pre, sym, arg :: Nil) if ManifestSymbols(sym) =>
+ manifestOfType(arg, sym == FullManifestClass) match {
case SearchFailure if sym == OptManifestClass => wrapResult(gen.mkAttributedRef(NoManifest))
case result => result
}
+ case TypeRef(pre, sym, arg :: Nil) if TagSymbols(sym) =>
+ tagOfType(pre, arg, sym)
case tp@TypeRef(_, sym, _) if sym.isAbstractType =>
- implicitManifestOrOfExpectedType(tp.bounds.lo) // #3977: use tp (==pt.dealias), not pt (if pt is a type alias, pt.bounds.lo == pt)
+ implicitTagOrOfExpectedType(tp.bounds.lo) // #3977: use tp (==pt.dealias), not pt (if pt is a type alias, pt.bounds.lo == pt)
case _ =>
searchImplicit(implicitsOfExpectedType, false)
// shouldn't we pass `pt` to `implicitsOfExpectedType`, or is the recursive case
- // for an abstract type really only meant for manifests?
+ // for an abstract type really only meant for tags?
}
/** The result of the implicit search:
* First search implicits visible in current context.
* If that fails, search implicits in expected type `pt`.
- * If that fails, and `pt` is an instance of Manifest, try to construct a manifest.
+ * // [Eugene] the following two lines should be deleted after we migrate delegate tag materialization to implicit macros
+ * If that fails, and `pt` is an instance of a ClassTag, try to construct a class tag.
+ * If that fails, and `pt` is an instance of a TypeTag, try to construct a type tag.
* If all fails return SearchFailure
*/
def bestImplicit: SearchResult = {
@@ -1219,7 +1323,7 @@ trait Implicits {
val failstart = startTimer(oftypeFailNanos)
val succstart = startTimer(oftypeSucceedNanos)
- result = implicitManifestOrOfExpectedType(pt)
+ result = implicitTagOrOfExpectedType(pt)
if (result == SearchFailure) {
context.updateBuffer(previousErrs)
@@ -1240,6 +1344,26 @@ trait Implicits {
def search(iss: Infoss, isLocal: Boolean) = applicableInfos(iss, isLocal).values
(search(context.implicitss, true) ++ search(implicitsOfExpectedType, false)).toList.filter(_.tree ne EmptyTree)
}
+
+ // find all implicits for some type that contains type variables
+ // collect the constraints that result from typing each implicit
+ def allImplicitsPoly(tvars: List[TypeVar]): List[(SearchResult, List[TypeConstraint])] = {
+ def resetTVars() = tvars foreach { _.constr = new TypeConstraint }
+
+ def eligibleInfos(iss: Infoss, isLocal: Boolean) = new ImplicitComputation(iss, if (isLocal) util.HashSet[Name](512) else null).eligible
+ val allEligibleInfos = (eligibleInfos(context.implicitss, true) ++ eligibleInfos(implicitsOfExpectedType, false)).toList
+
+ allEligibleInfos flatMap { ii =>
+ // each ImplicitInfo contributes a distinct set of constraints (generated indirectly by typedImplicit)
+ // thus, start each type var off with a fresh for every typedImplicit
+ resetTVars()
+ // any previous errors should not affect us now
+ context.flushBuffer()
+ val res = typedImplicit(ii, false)
+ if (res.tree ne EmptyTree) List((res, tvars map (_.constr)))
+ else Nil
+ }
+ }
}
object ImplicitNotFoundMsg {
@@ -1248,7 +1372,7 @@ trait Implicits {
// where `X` refers to a type parameter of `sym`
def check(sym: Symbol): Option[String] =
sym.getAnnotation(ImplicitNotFoundClass).flatMap(_.stringArg(0) match {
- case Some(m) => new Message(sym, m) validate
+ case Some(m) => new Message(sym, m).validate
case None => Some("Missing argument `msg` on implicitNotFound annotation.")
})
@@ -1273,7 +1397,7 @@ trait Implicits {
val decls = typeParamNames.toSet
(refs &~ decls) match {
- case s if s isEmpty => None
+ case s if s.isEmpty => None
case unboundNames =>
val singular = unboundNames.size == 1
Some("The type parameter"+( if(singular) " " else "s " )+ unboundNames.mkString(", ") +
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index a59622d4df..fb0616c890 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -67,7 +67,7 @@ trait Infer {
*/
def freshVar(tparam: Symbol): TypeVar = TypeVar(tparam)
- private class NoInstance(msg: String) extends Throwable(msg) with ControlThrowable { }
+ class NoInstance(msg: String) extends Throwable(msg) with ControlThrowable { }
private class DeferredNoInstance(getmsg: () => String) extends NoInstance("") {
override def getMessage(): String = getmsg()
}
@@ -83,7 +83,7 @@ trait Infer {
def apply(tp: Type): Type = tp match {
case WildcardType | BoundedWildcardType(_) | NoType =>
throw new NoInstance("undetermined type")
- case tv @ TypeVar(origin, constr) =>
+ case tv @ TypeVar(origin, constr) if !tv.untouchable =>
if (constr.inst == NoType) {
throw new DeferredNoInstance(() =>
"no unique instantiation of type variable " + origin + " could be found")
@@ -196,10 +196,12 @@ trait Infer {
/* -- Error Messages --------------------------------------------------- */
def setError[T <: Tree](tree: T): T = {
- if (settings.debug.value) { // DEBUG
- println("set error: "+tree);
- throw new Error()
- }
+ debuglog("set error: "+ tree)
+ // this breaks -Ydebug pretty radically
+ // if (settings.debug.value) { // DEBUG
+ // println("set error: "+tree);
+ // throw new Error()
+ // }
def name = newTermName("<error: " + tree.symbol + ">")
def errorClass = if (context.reportErrors) context.owner.newErrorClass(name.toTypeName) else stdErrorClass
def errorValue = if (context.reportErrors) context.owner.newErrorValue(name) else stdErrorValue
@@ -265,6 +267,16 @@ trait Infer {
setError(tree)
}
else {
+ if (context.owner.isTermMacro && (sym1 hasFlag LOCKED)) {
+ // we must not let CyclicReference to be thrown from sym1.info
+ // because that would mark sym1 erroneous, which it is not
+ // but if it's a true CyclicReference then macro def will report it
+ // see comments to TypeSigError for an explanation of this special case
+ // [Eugene] is there a better way?
+ val dummy = new TypeCompleter { val tree = EmptyTree; override def complete(sym: Symbol) {} }
+ throw CyclicReference(sym1, dummy)
+ }
+
if (sym1.isTerm)
sym1.cookJavaRawInfo() // xform java rawtypes into existentials
@@ -308,6 +320,8 @@ trait Infer {
/** Like weakly compatible but don't apply any implicit conversions yet.
* Used when comparing the result type of a method with its prototype.
+ * [Martin] I think Infer is also created by Erasure, with the default
+ * implementation of isCoercible
*/
def isConservativelyCompatible(tp: Type, pt: Type): Boolean =
context.withImplicitsDisabled(isWeaklyCompatible(tp, pt))
@@ -424,12 +438,15 @@ trait Infer {
tvars map (tvar => WildcardType)
}
+ /** [Martin] Can someone comment this please? I have no idea what it's for
+ * and the code is not exactly readable.
+ */
object AdjustedTypeArgs {
val Result = collection.mutable.LinkedHashMap
type Result = collection.mutable.LinkedHashMap[Symbol, Option[Type]]
def unapply(m: Result): Some[(List[Symbol], List[Type])] = Some(toLists(
- m collect {case (p, Some(a)) => (p, a)} unzip ))
+ (m collect {case (p, Some(a)) => (p, a)}).unzip ))
object Undets {
def unapply(m: Result): Some[(List[Symbol], List[Type], List[Symbol])] = Some(toLists{
@@ -482,8 +499,7 @@ trait Infer {
else Some(
if (targ.typeSymbol == RepeatedParamClass) targ.baseType(SeqClass)
else if (targ.typeSymbol == JavaRepeatedParamClass) targ.baseType(ArrayClass)
- // this infers Foo.type instead of "object Foo" (see also widenIfNecessary)
- else if (targ.typeSymbol.isModuleClass || ((opt.experimental || opt.virtPatmat) && tvar.constr.avoidWiden)) targ
+ else if ((opt.experimental || opt.virtPatmat) && tvar.constr.avoidWiden) targ
else targ.widen
)
))
@@ -698,7 +714,7 @@ trait Infer {
case NamedType(name, _) => Some(name)
case _ => None
})._1
- if (missing forall (_.hasDefaultFlag)) {
+ if (missing forall (_.hasDefault)) {
// add defaults as named arguments
val argtpes1 = argtpes0 ::: (missing map (p => NamedType(p.name, p.tpe)))
isApplicable(undetparams, ftpe, argtpes1, pt)
@@ -750,7 +766,7 @@ trait Infer {
isAsSpecific(res, ftpe2)
case mt: MethodType if mt.isImplicit =>
isAsSpecific(ftpe1.resultType, ftpe2)
- case MethodType(params, _) if params nonEmpty =>
+ case MethodType(params, _) if params.nonEmpty =>
var argtpes = params map (_.tpe)
if (isVarArgsList(params) && isVarArgsList(ftpe2.params))
argtpes = argtpes map (argtpe =>
@@ -760,7 +776,7 @@ trait Infer {
isAsSpecific(PolyType(tparams, res), ftpe2)
case PolyType(tparams, mt: MethodType) if mt.isImplicit =>
isAsSpecific(PolyType(tparams, mt.resultType), ftpe2)
- case PolyType(_, MethodType(params, _)) if params nonEmpty =>
+ case PolyType(_, MethodType(params, _)) if params.nonEmpty =>
isApplicable(List(), ftpe2, params map (_.tpe), WildcardType)
// case NullaryMethodType(res) =>
// isAsSpecific(res, ftpe2)
@@ -991,6 +1007,7 @@ trait Infer {
PolymorphicExpressionInstantiationError(tree, undetparams, pt)
} else {
new TreeTypeSubstituter(undetparams, targs).traverse(tree)
+ notifyUndetparamsInferred(undetparams, targs)
}
}
@@ -1027,6 +1044,7 @@ trait Infer {
if (checkBounds(fn, NoPrefix, NoSymbol, undetparams, allargs, "inferred ")) {
val treeSubst = new TreeTypeSubstituter(okparams, okargs)
treeSubst traverseTrees fn :: args
+ notifyUndetparamsInferred(okparams, okargs)
leftUndet match {
case Nil => Nil
@@ -1115,6 +1133,7 @@ trait Infer {
(inferFor(pt) orElse inferForApproxPt) map { targs =>
new TreeTypeSubstituter(undetparams, targs).traverse(tree)
+ notifyUndetparamsInferred(undetparams, targs)
} getOrElse {
debugwarn("failed inferConstructorInstance for "+ tree +" : "+ tree.tpe +" under "+ undetparams +" pt = "+ pt +(if(isFullyDefined(pt)) " (fully defined)" else " (not fully defined)"))
// if (settings.explaintypes.value) explainTypes(resTp.instantiateTypeParams(undetparams, tvars), pt)
@@ -1170,6 +1189,50 @@ trait Infer {
}
}
+ /** Does `tp` contain any types that cannot be checked at run-time (i.e., after erasure, will isInstanceOf[erased(tp)] imply conceptualIsInstanceOf[tp]?)
+ * we should find a way to ask erasure: hey, is `tp` going to make it through you with all of its isInstanceOf resolving powers intact?
+ * TODO: at the very least, reduce duplication wrt checkCheckable
+ */
+ def containsUnchecked(tp: Type): Boolean = {
+ def check(tp: Type, bound: List[Symbol]): Boolean = {
+ def isSurroundingTypeParam(sym: Symbol) = {
+ val e = context.scope.lookupEntry(sym.name)
+ ( (e ne null)
+ && (e.sym == sym )
+ && !e.sym.isTypeParameterOrSkolem
+ && (e.owner == context.scope)
+ )
+ }
+ def isLocalBinding(sym: Symbol) = (
+ sym.isAbstractType && (
+ (bound contains sym)
+ || (sym.name == tpnme.WILDCARD)
+ || isSurroundingTypeParam(sym)
+ )
+ )
+ tp.normalize match {
+ case SingleType(pre, _) =>
+ check(pre, bound)
+ case TypeRef(_, ArrayClass, arg :: _) =>
+ check(arg, bound)
+ case tp @ TypeRef(pre, sym, args) =>
+ ( (sym.isAbstractType && !isLocalBinding(sym))
+ || (args exists (x => !isLocalBinding(x.typeSymbol)))
+ || check(pre, bound)
+ )
+ // case RefinedType(_, decls) if decls.nonEmpty =>
+ // patternWarning(tp, "refinement ")
+ case RefinedType(parents, _) =>
+ parents exists (p => check(p, bound))
+ case ExistentialType(quantified, tp1) =>
+ check(tp1, bound ::: quantified)
+ case _ =>
+ false
+ }
+ }
+ check(tp, Nil)
+ }
+
def checkCheckable(tree: Tree, tp: Type, kind: String) {
def patternWarning(tp0: Type, prefix: String) = {
context.unit.uncheckedWarning(tree.pos, prefix+tp0+" in type "+kind+tp+" is unchecked since it is eliminated by erasure")
@@ -1567,9 +1630,9 @@ trait Infer {
else infer
}
- /** Assign <code>tree</code> the type of unique polymorphic alternative
+ /** Assign <code>tree</code> the type of all polymorphic alternatives
* with <code>nparams</code> as the number of type parameters, if it exists.
- * If several or none such polymorphic alternatives exist, error.
+ * If no such polymorphic alternative exist, error.
*
* @param tree ...
* @param nparams ...
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index e43b1fab0b..1b8a43bf27 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -3,288 +3,1288 @@ package typechecker
import symtab.Flags._
import scala.tools.nsc.util._
+import scala.tools.nsc.util.ClassPath._
import scala.reflect.ReflectionUtils
+import scala.collection.mutable.ListBuffer
+import scala.compat.Platform.EOL
+import scala.reflect.makro.runtime.{Context => MacroContext}
+import scala.reflect.runtime.Mirror
+import util.Statistics._
+import scala.reflect.makro.util._
+
+/**
+ * Code to deal with macros, namely with:
+ * * Compilation of macro definitions
+ * * Expansion of macro applications
+ *
+ * Say we have in a class C:
+ *
+ * def foo[T](xs: List[T]): T = macro fooBar
+ *
+ * Then fooBar needs to point to a static method of the following form:
+ *
+ * def fooBar[T: c.TypeTag]
+ * (c: scala.reflect.makro.Context)
+ * (xs: c.Expr[List[T]])
+ * : c.mirror.Tree = {
+ * ...
+ * }
+ *
+ * Then, if foo is called in qual.foo[Int](elems), where qual: D,
+ * the macro application is expanded to a reflective invocation of fooBar with parameters
+ *
+ * (simpleMacroContext{ type PrefixType = D; val prefix = qual })
+ * (Expr(elems))
+ * (TypeTag(Int))
+ */
+trait Macros extends Traces {
+ self: Analyzer =>
-trait Macros { self: Analyzer =>
import global._
import definitions._
+ def globalSettings = global.settings
+
+ val globalMacroCache = collection.mutable.Map[Any, Any]()
+ val perRunMacroCache = perRunCaches.newMap[Symbol, collection.mutable.Map[Any, Any]]
+
+ /** A list of compatible macro implementation signatures.
+ *
+ * In the example above:
+ * (c: scala.reflect.makro.Context)(xs: c.Expr[List[T]]): c.Expr[T]
+ *
+ * @param macroDef The macro definition symbol
+ * @param tparams The type parameters of the macro definition
+ * @param vparamss The value parameters of the macro definition
+ * @param retTpe The return type of the macro definition
+ */
+ private def macroImplSigs(macroDef: Symbol, tparams: List[TypeDef], vparamss: List[List[ValDef]], retTpe: Type): (List[List[List[Symbol]]], Type) = {
+ // had to move method's body to an object because of the recursive dependencies between sigma and param
+ object SigGenerator {
+ val hasThis = macroDef.owner.isClass
+ val ownerTpe = macroDef.owner match {
+ case owner if owner.isModuleClass => new UniqueThisType(macroDef.owner)
+ case owner if owner.isClass => macroDef.owner.tpe
+ case _ => NoType
+ }
+ val hasTparams = !tparams.isEmpty
+
+ def sigma(tpe: Type): Type = {
+ class SigmaTypeMap extends TypeMap {
+ def apply(tp: Type): Type = tp match {
+ case TypeRef(pre, sym, args) =>
+ val pre1 = pre match {
+ case ThisType(sym) if sym == macroDef.owner =>
+ SingleType(SingleType(SingleType(NoPrefix, paramsCtx(0)), MacroContextPrefix), ExprValue)
+ case SingleType(NoPrefix, sym) =>
+ mfind(vparamss)(_.symbol == sym) match {
+ case Some(macroDefParam) =>
+ SingleType(SingleType(NoPrefix, param(macroDefParam)), ExprValue)
+ case _ =>
+ pre
+ }
+ case _ =>
+ pre
+ }
+ val args1 = args map mapOver
+ TypeRef(pre1, sym, args1)
+ case _ =>
+ mapOver(tp)
+ }
+ }
+
+ new SigmaTypeMap() apply tpe
+ }
- def macroMeth(mac: Symbol): Symbol = {
- var owner = mac.owner
- if (!owner.isModuleClass) owner = owner.companionModule.moduleClass
- owner.info.decl(nme.macroMethodName(mac.name))
+ def makeParam(name: Name, pos: Position, tpe: Type, flags: Long = 0L) =
+ macroDef.newValueParameter(name, pos, flags) setInfo tpe
+ val ctxParam = makeParam(nme.macroContext, macroDef.pos, MacroContextClass.tpe, SYNTHETIC)
+ def implType(isType: Boolean, origTpe: Type): Type =
+ if (isRepeatedParamType(origTpe))
+ appliedType(
+ RepeatedParamClass.typeConstructor,
+ List(implType(isType, sigma(origTpe.typeArgs.head))))
+ else {
+ val tsym = getMember(MacroContextClass, if (isType) tpnme.TypeTag else tpnme.Expr)
+ typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(origTpe)))
+ }
+ val paramCache = collection.mutable.Map[Symbol, Symbol]()
+ def param(tree: Tree): Symbol =
+ paramCache.getOrElseUpdate(tree.symbol, {
+ // [Eugene] deskolemization became necessary once I implemented inference of macro def return type
+ // please, verify this solution, but for now I'll leave it here - cargo cult for the win
+ val sym = tree.symbol.deSkolemize
+ val sigParam = makeParam(sym.name, sym.pos, implType(sym.isType, sym.tpe))
+ if (sym.isSynthetic) sigParam.flags |= SYNTHETIC
+ sigParam
+ })
+
+ val paramsCtx = List(ctxParam)
+ val paramsThis = List(makeParam(nme.macroThis, macroDef.pos, implType(false, ownerTpe), SYNTHETIC))
+ val paramsTparams = tparams map param
+ val paramssParams = mmap(vparamss)(param)
+
+ var paramsss = List[List[List[Symbol]]]()
+ // tparams are no longer part of a signature, they get into macro implementations via context bounds
+// if (hasTparams && hasThis) paramsss :+= paramsCtx :: paramsThis :: paramsTparams :: paramssParams
+// if (hasTparams) paramsss :+= paramsCtx :: paramsTparams :: paramssParams
+ // _this params are no longer part of a signature, its gets into macro implementations via Context.prefix
+// if (hasThis) paramsss :+= paramsCtx :: paramsThis :: paramssParams
+ paramsss :+= paramsCtx :: paramssParams
+
+ val tsym = getMember(MacroContextClass, tpnme.Expr)
+ val implRetTpe = typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(retTpe)))
+ }
+
+ import SigGenerator._
+ macroTraceVerbose("generating macroImplSigs for: ")(macroDef)
+ macroTraceVerbose("tparams are: ")(tparams)
+ macroTraceVerbose("vparamss are: ")(vparamss)
+ macroTraceVerbose("retTpe is: ")(retTpe)
+ macroTraceVerbose("macroImplSigs are: ")(paramsss, implRetTpe)
}
- def macroArgs(tree: Tree): (List[List[Tree]]) = tree match {
- case Apply(fn, args) =>
- macroArgs(fn) :+ args
- case TypeApply(fn, args) =>
- macroArgs(fn) :+ args
- case Select(qual, name) =>
- List(List(qual))
- case _ =>
- List(List())
+ private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Option[Symbol]): List[List[Symbol]] = {
+ if (paramss.length == 0)
+ return paramss
+
+ val wannabe = if (paramss.head.length == 1) paramss.head.head else NoSymbol
+ val contextParam = if (wannabe != NoSymbol && wannabe.tpe <:< definitions.MacroContextClass.tpe) wannabe else NoSymbol
+
+ val lastParamList0 = paramss.lastOption getOrElse Nil
+ val lastParamList = lastParamList0 flatMap (param => param.tpe match {
+ case TypeRef(SingleType(NoPrefix, contextParam), sym, List(tparam)) =>
+ var wannabe = sym
+ while (wannabe.isAliasType) wannabe = wannabe.info.typeSymbol
+ if (wannabe != definitions.TypeTagClass && wannabe != definitions.ConcreteTypeTagClass)
+ List(param)
+ else
+ transform(param, tparam.typeSymbol) map (_ :: Nil) getOrElse Nil
+ case _ =>
+ List(param)
+ })
+
+ var result = paramss.dropRight(1) :+ lastParamList
+ if (lastParamList0.isEmpty ^ lastParamList.isEmpty) {
+ result = result dropRight 1
+ }
+
+ result
}
- /**
- * The definition of the method implementing a macro. Example:
- * Say we have in a class C
- *
- * def macro foo[T](xs: List[T]): T = expr
- *
- * Then the following macro method is generated for `foo`:
- *
- * def defmacro$foo
- * (_context: scala.reflect.macro.Context)
- * (_this: _context.Tree)
- * (T: _context.TypeTree)
- * (xs: _context.Tree): _context.Tree = {
- * import _context._ // this means that all methods of Context can be used unqualified in macro's body
- * expr
- * }
+ /** As specified above, body of a macro definition must reference its implementation.
+ * This function verifies that the body indeed refers to a method, and that
+ * the referenced macro implementation is compatible with the given macro definition.
*
- * If macro has no type arguments, the third parameter list is omitted (it's not empty, but omitted altogether).
+ * This means that macro implementation (fooBar in example above) must:
+ * 1) Refer to a statically accessible, non-overloaded method.
+ * 2) Have the right parameter lists as outlined in the SIP / in the doc comment of this class.
*
- * To find out the desugared representation of your particular macro, compile it with -Ymacro-debug.
+ * @return typechecked rhs of the given macro definition
*/
- def macroMethDef(mdef: DefDef): Tree = {
- def paramDef(name: Name, tpt: Tree) = ValDef(Modifiers(PARAM), name, tpt, EmptyTree)
- val contextType = TypeTree(ReflectMacroContext.tpe)
- val globParamSec = List(paramDef(nme.macroContext, contextType))
- def globSelect(name: Name) = Select(Ident(nme.macroContext), name)
- def globTree = globSelect(tpnme.Tree)
- def globTypeTree = globSelect(tpnme.TypeTree)
- val thisParamSec = List(paramDef(newTermName(nme.macroThis), globTree))
- def tparamInMacro(tdef: TypeDef) = paramDef(tdef.name.toTermName, globTypeTree)
- def vparamInMacro(vdef: ValDef): ValDef = paramDef(vdef.name, vdef.tpt match {
- case tpt @ AppliedTypeTree(hk, _) if treeInfo.isRepeatedParamType(tpt) => AppliedTypeTree(hk, List(globTree))
- case _ => globTree
- })
- def wrapImplicit(tree: Tree) = atPos(tree.pos) {
- // implicit hasn't proven useful so far, so I'm disabling it
- //val implicitDecl = ValDef(Modifiers(IMPLICIT), nme.macroContextImplicit, SingletonTypeTree(Ident(nme.macroContext)), Ident(nme.macroContext))
- val importGlob = Import(Ident(nme.macroContext), List(ImportSelector(nme.WILDCARD, -1, null, -1)))
- Block(List(importGlob), tree)
- }
- var formals = (mdef.vparamss map (_ map vparamInMacro))
- if (mdef.tparams.nonEmpty) formals = (mdef.tparams map tparamInMacro) :: formals
-
- atPos(mdef.pos) {
- new DefDef( // can't call DefDef here; need to find out why
- mods = mdef.mods &~ MACRO &~ OVERRIDE,
- name = nme.macroMethodName(mdef.name),
- tparams = List(),
- vparamss = globParamSec :: thisParamSec :: formals,
- tpt = globTree,
- wrapImplicit(mdef.rhs))
+ def typedMacroBody(typer: Typer, ddef: DefDef): Tree = {
+ import typer.context
+ macroLogVerbose("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos))
+
+ if (!typer.checkFeature(ddef.pos, MacrosFeature, immediate = true)) {
+ ddef.symbol setFlag IS_ERROR
+ return EmptyTree
+ }
+
+ implicit class AugmentedString(s: String) {
+ def abbreviateCoreAliases: String = { // hack!
+ var result = s
+ result = result.replace("c.mirror.TypeTag", "c.TypeTag")
+ result = result.replace("c.mirror.Expr", "c.Expr")
+ result
+ }
}
- }
- def addMacroMethods(templ: Template, namer: Namer): Unit = {
- for (ddef @ DefDef(mods, _, _, _, _, _) <- templ.body if mods hasFlag MACRO) {
- val trace = scala.tools.nsc.util.trace when settings.Ymacrodebug.value
- val sym = namer.enterSyntheticSym(trace("macro def: ")(macroMethDef(ddef)))
- trace("added to "+namer.context.owner.enclClass+": ")(sym)
+ var hasErrors = false
+ def reportError(pos: Position, msg: String) = {
+ hasErrors = true
+ context.error(pos, msg)
}
- }
- lazy val mirror = new scala.reflect.runtime.Mirror {
- lazy val libraryClassLoader = {
- // todo. this is more or less okay, but not completely correct
- // see https://issues.scala-lang.org/browse/SI-5433 for more info
- val classpath = global.classPath.asURLs
- var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
-
- // an heuristic to detect REPL
- if (global.settings.exposeEmptyPackage.value) {
- import scala.tools.nsc.interpreter._
- val virtualDirectory = global.settings.outputDirs.getSingleOutput.get
- loader = new AbstractFileClassLoader(virtualDirectory, loader) {}
+ val macroDef = ddef.symbol
+ val defpos = macroDef.pos
+ val implpos = ddef.rhs.pos
+ assert(macroDef.isTermMacro, ddef)
+
+ def invalidBodyError() =
+ reportError(defpos,
+ "macro body has wrong shape:" +
+ "\n required: macro <reference to implementation object>.<implementation method name>" +
+ "\n or : macro <implementation method name>")
+ def validatePreTyper(rhs: Tree): Unit = rhs match {
+ // we do allow macro invocations inside macro bodies
+ // personally I don't mind if pre-typer tree is a macro invocation
+ // that later resolves to a valid reference to a macro implementation
+ // however, I don't think that invalidBodyError() should hint at that
+ // let this be an Easter Egg :)
+ case Apply(_, _) => ;
+ case TypeApply(_, _) => ;
+ case Super(_, _) => ;
+ case This(_) => ;
+ case Ident(_) => ;
+ case Select(_, _) => ;
+ case _ => invalidBodyError()
+ }
+ def validatePostTyper(rhs1: Tree): Unit = {
+ def loop(tree: Tree): Unit = {
+ def errorNotStatic() =
+ reportError(implpos, "macro implementation must be in statically accessible object")
+
+ def ensureRoot(sym: Symbol) =
+ if (!sym.isModule && !sym.isModuleClass) errorNotStatic()
+
+ def ensureModule(sym: Symbol) =
+ if (!sym.isModule) errorNotStatic()
+
+ tree match {
+ case TypeApply(fun, _) =>
+ loop(fun)
+ case Super(qual, _) =>
+ ensureRoot(macroDef.owner)
+ loop(qual)
+ case This(_) =>
+ ensureRoot(tree.symbol)
+ case Select(qual, name) if name.isTypeName =>
+ loop(qual)
+ case Select(qual, name) if name.isTermName =>
+ if (tree.symbol != rhs1.symbol) ensureModule(tree.symbol)
+ loop(qual)
+ case Ident(name) if name.isTypeName =>
+ ;
+ case Ident(name) if name.isTermName =>
+ if (tree.symbol != rhs1.symbol) ensureModule(tree.symbol)
+ case _ =>
+ invalidBodyError()
+ }
}
- loader
+ loop(rhs1)
}
- override def defaultReflectiveClassLoader() = libraryClassLoader
- }
+ val rhs = ddef.rhs
+ validatePreTyper(rhs)
+ if (hasErrors) macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef)
- /** Return optionally address of companion object and implementation method symbol
- * of given macro; or None if implementation classfile cannot be loaded or does
- * not contain the macro implementation.
- */
- def macroImpl(mac: Symbol): Option[(AnyRef, mirror.Symbol)] = {
- val debug = settings.Ymacrodebug.value
- val trace = scala.tools.nsc.util.trace when debug
- trace("looking for macro implementation: ")(mac.fullNameString)
+ // we use typed1 instead of typed, because otherwise adapt is going to mess us up
+ // if adapt sees <qualifier>.<method>, it will want to perform eta-expansion and will fail
+ // unfortunately, this means that we have to manually trigger macro expansion
+ // because it's adapt which is responsible for automatic expansion during typechecking
+ def typecheckRhs(rhs: Tree): Tree = {
+ try {
+ val prevNumErrors = reporter.ERROR.count // [Eugene] funnily enough, the isErroneous check is not enough
+ var rhs1 = if (hasErrors) EmptyTree else typer.typed1(rhs, EXPRmode, WildcardType)
+ def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors
+ def rhsNeedsMacroExpansion = rhs1.symbol != null && rhs1.symbol.isTermMacro && !rhs1.symbol.isErroneous
+ while (!typecheckedWithErrors && rhsNeedsMacroExpansion) {
+ rhs1 = macroExpand1(typer, rhs1) match {
+ case Success(expanded) =>
+ try {
+ val typechecked = typer.typed1(expanded, EXPRmode, WildcardType)
+ macroLogVerbose("typechecked1:%n%s%n%s".format(typechecked, showRaw(typechecked)))
+ typechecked
+ } finally {
+ openMacros = openMacros.tail
+ }
+ case Fallback(fallback) =>
+ typer.typed1(fallback, EXPRmode, WildcardType)
+ case Other(result) =>
+ result
+ }
+ }
+ rhs1
+ } catch {
+ case ex: TypeError =>
+ typer.reportTypeError(context, rhs.pos, ex)
+ typer.infer.setError(rhs)
+ }
+ }
- try {
- val mmeth = macroMeth(mac)
- trace("found implementation at: ")(mmeth.fullNameString)
+ val prevNumErrors = reporter.ERROR.count // funnily enough, the isErroneous check is not enough
+ var rhs1 = typecheckRhs(rhs)
+ def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors
+ hasErrors = hasErrors || typecheckedWithErrors
+ if (typecheckedWithErrors) macroTraceVerbose("body of a macro def failed to typecheck: ")(ddef)
- if (mmeth == NoSymbol) None
- else {
- trace("loading implementation class: ")(mmeth.owner.fullName)
- trace("classloader is: ")("%s of type %s".format(mirror.libraryClassLoader, mirror.libraryClassLoader.getClass))
- def inferClasspath(cl: ClassLoader) = cl match {
- case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
- case _ => "<unknown>"
+ val macroImpl = rhs1.symbol
+ macroDef withAnnotation AnnotationInfo(MacroImplAnnotation.tpe, List(rhs1), Nil)
+ if (!hasErrors) {
+ if (macroImpl == null) {
+ invalidBodyError()
+ } else {
+ if (!macroImpl.isMethod)
+ invalidBodyError()
+ if (macroImpl.isOverloaded)
+ reportError(implpos, "macro implementation cannot be overloaded")
+ if (!macroImpl.typeParams.isEmpty && (!rhs1.isInstanceOf[TypeApply]))
+ reportError(implpos, "macro implementation reference needs type arguments")
+ if (!hasErrors)
+ validatePostTyper(rhs1)
+ }
+ if (hasErrors)
+ macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef)
+ }
+
+ if (!hasErrors) {
+ def checkCompatibility(reqparamss: List[List[Symbol]], actparamss: List[List[Symbol]], reqres: Type, actres: Type): List[String] = {
+ var hasErrors = false
+ var errors = List[String]()
+ def compatibilityError(msg: String) {
+ hasErrors = true
+ errors :+= msg
}
- trace("classpath is: ")(inferClasspath(mirror.libraryClassLoader))
-
- // @xeno.by: relies on the fact that macros can only be defined in static classes
- def classfile(sym: Symbol): String = {
- def recur(sym: Symbol): String = sym match {
- case sym if sym.owner.isPackageClass =>
- val suffix = if (sym.isModuleClass) "$" else ""
- sym.fullName + suffix
- case sym =>
- val separator = if (sym.owner.isModuleClass) "" else "$"
- recur(sym.owner) + separator + sym.javaSimpleName.toString
+
+ val flatreqparams = reqparamss.flatten
+ val flatactparams = actparamss.flatten
+ val tparams = macroImpl.typeParams
+ val tvars = tparams map freshVar
+ def lengthMsg(which: String, extra: Symbol) =
+ "parameter lists have different length, "+which+" extra parameter "+extra.defString
+ if (actparamss.length != reqparamss.length)
+ compatibilityError("number of parameter sections differ")
+
+ def checkSubType(slot: String, reqtpe: Type, acttpe: Type): Unit = {
+ val ok = if (macroDebugVerbose) {
+ if (reqtpe eq acttpe) println(reqtpe + " <: " + acttpe + "?" + EOL + "true")
+ withTypesExplained(reqtpe <:< acttpe)
+ } else reqtpe <:< acttpe
+ if (!ok) {
+ compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, reqtpe.toString.abbreviateCoreAliases, acttpe.toString.abbreviateCoreAliases))
}
+ }
- if (sym.isClass || sym.isModule) recur(sym)
- else recur(sym.enclClass)
+ if (!hasErrors) {
+ try {
+ for ((rparams, aparams) <- reqparamss zip actparamss) {
+ if (rparams.length < aparams.length)
+ compatibilityError(lengthMsg("found", aparams(rparams.length)))
+ if (aparams.length < rparams.length)
+ compatibilityError(lengthMsg("required", rparams(aparams.length)).abbreviateCoreAliases)
+ }
+ // if the implementation signature is already deemed to be incompatible, we bail out
+ // otherwise, high-order type magic employed below might crash in weird ways
+ if (!hasErrors) {
+ for ((rparams, aparams) <- reqparamss zip actparamss) {
+ for ((rparam, aparam) <- rparams zip aparams) {
+ def isRepeated(param: Symbol) = param.tpe.typeSymbol == RepeatedParamClass
+ if (rparam.name != aparam.name && !rparam.isSynthetic) {
+ val rparam1 = rparam
+ val aparam1 = aparam
+ compatibilityError("parameter names differ: "+rparam.name+" != "+aparam.name)
+ }
+ if (isRepeated(rparam) && !isRepeated(aparam))
+ compatibilityError("types incompatible for parameter "+rparam.name+": corresponding is not a vararg parameter")
+ if (!isRepeated(rparam) && isRepeated(aparam))
+ compatibilityError("types incompatible for parameter "+aparam.name+": corresponding is not a vararg parameter")
+ if (!hasErrors) {
+ var atpe = aparam.tpe.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars)
+ atpe = atpe.dealias // SI-5706
+ // strip the { type PrefixType = ... } refinement off the Context or otherwise we get compatibility errors
+ atpe = atpe match {
+ case RefinedType(List(tpe), Scope(sym)) if tpe == MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe
+ case _ => atpe
+ }
+ checkSubType("parameter " + rparam.name, rparam.tpe, atpe)
+ }
+ }
+ }
+ }
+ if (!hasErrors) {
+ val atpe = actres.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars)
+ checkSubType("return type", atpe, reqres)
+ }
+ if (!hasErrors) {
+ val targs = solvedTypes(tvars, tparams, tparams map varianceInType(actres), false,
+ lubDepth(flatactparams map (_.tpe)) max lubDepth(flatreqparams map (_.tpe)))
+ val boundsOk = typer.silent(_.infer.checkBounds(ddef, NoPrefix, NoSymbol, tparams, targs, ""))
+ boundsOk match {
+ case SilentResultValue(true) => ;
+ case SilentResultValue(false) | SilentTypeError(_) =>
+ val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds)
+ compatibilityError("type arguments " + targs.mkString("[", ",", "]") +
+ " do not conform to " + tparams.head.owner + "'s type parameter bounds " +
+ (tparams map (_.defString)).mkString("[", ",", "]"))
+ }
+ }
+ } catch {
+ case ex: NoInstance =>
+ compatibilityError(
+ "type parameters "+(tparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+
+ ex.getMessage)
+ }
}
- // @xeno.by: this doesn't work for inner classes
- // neither does mmeth.owner.javaClassName, so I had to roll my own implementation
- //val receiverName = mmeth.owner.fullName
- val receiverName = classfile(mmeth.owner)
- val receiverClass: mirror.Symbol = mirror.symbolForName(receiverName)
+ errors.toList
+ }
+
+ var actparamss = macroImpl.paramss
+ actparamss = transformTypeTagEvidenceParams(actparamss, (param, tparam) => None)
+
+ val rettpe = if (!ddef.tpt.isEmpty) typer.typedType(ddef.tpt).tpe else computeMacroDefTypeFromMacroImpl(ddef, macroDef, macroImpl)
+ val (reqparamsss0, reqres0) = macroImplSigs(macroDef, ddef.tparams, ddef.vparamss, rettpe)
+ var reqparamsss = reqparamsss0
- if (debug) {
- println("receiverClass is: " + receiverClass.fullNameString)
+ // prohibit implicit params on macro implementations
+ // we don't have to do this, but it appears to be more clear than allowing them
+ val implicitParams = actparamss.flatten filter (_.isImplicit)
+ if (implicitParams.length > 0) {
+ reportError(implicitParams.head.pos, "macro implementations cannot have implicit parameters other than TypeTag evidences")
+ macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef)
+ }
- val jreceiverClass = mirror.classToJava(receiverClass)
- val jreceiverSource = jreceiverClass.getProtectionDomain.getCodeSource
- println("jreceiverClass is %s from %s".format(jreceiverClass, jreceiverSource))
- println("jreceiverClassLoader is %s with classpath %s".format(jreceiverClass.getClassLoader, inferClasspath(jreceiverClass.getClassLoader)))
+ if (!hasErrors) {
+ val reqres = reqres0
+ val actres = macroImpl.tpe.finalResultType
+ def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = {
+ var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString
+ if (abbreviate) argsPart = argsPart.abbreviateCoreAliases
+ var retPart = restpe.toString
+ if (abbreviate || ddef.tpt.tpe == null) retPart = retPart.abbreviateCoreAliases
+ argsPart + ": " + retPart
}
+ def compatibilityError(addendum: String) =
+ reportError(implpos,
+ "macro implementation has wrong shape:"+
+ "\n required: "+showMeth(reqparamsss.head, reqres, true) +
+ (reqparamsss.tail map (paramss => "\n or : "+showMeth(paramss, reqres, true)) mkString "")+
+ "\n found : "+showMeth(actparamss, actres, false)+
+ "\n"+addendum)
- val receiverObj = receiverClass.companionModule
- trace("receiverObj is: ")(receiverObj.fullNameString)
+ macroTraceVerbose("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name)
+ val results = reqparamsss map (checkCompatibility(_, actparamss, reqres, actres))
+ if (macroDebugVerbose) (reqparamsss zip results) foreach { case (reqparamss, result) =>
+ println("%s %s".format(if (result.isEmpty) "[ OK ]" else "[FAILED]", reqparamss))
+ result foreach (errorMsg => println(" " + errorMsg))
+ }
- if (receiverObj == mirror.NoSymbol) None
- else {
- // @xeno.by: yet another reflection method that doesn't work for inner classes
- //val receiver = mirror.companionInstance(receiverClass)
- val clazz = java.lang.Class.forName(receiverName, true, mirror.libraryClassLoader)
- val receiver = clazz getField "MODULE$" get null
-
- val rmeth = receiverObj.info.member(mirror.newTermName(mmeth.name.toString))
- if (debug) {
- println("rmeth is: " + rmeth.fullNameString)
- println("jrmeth is: " + mirror.methodToJava(rmeth))
+ if (results forall (!_.isEmpty)) {
+ var index = reqparamsss indexWhere (_.length == actparamss.length)
+ if (index == -1) index = 0
+ val mostRelevantMessage = results(index).head
+ compatibilityError(mostRelevantMessage)
+ } else {
+ assert((results filter (_.isEmpty)).length == 1, results)
+ if (macroDebugVerbose) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) =>
+ println("typechecked macro impl as: " + reqparamss)
}
+ }
+ }
+ }
+
+ // if this macro definition is erroneous, then there's no sense in expanding its usages
+ // in the previous prototype macro implementations were magically generated from macro definitions
+ // so macro definitions and its usages couldn't be compiled in the same compilation run
+ // however, now definitions and implementations are decoupled, so it's everything is possible
+ // hence, we now use IS_ERROR flag to serve as an indicator that given macro definition is broken
+ if (hasErrors) {
+ macroDef setFlag IS_ERROR
+ }
- if (rmeth == mirror.NoSymbol) None
- else {
- Some((receiver, rmeth))
+ rhs1
+ }
+
+ def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroDef: Symbol, macroImpl: Symbol): Type = {
+ // get return type from method type
+ def unwrapRet(tpe: Type): Type = {
+ def loop(tpe: Type) = tpe match {
+ case NullaryMethodType(ret) => ret
+ case mtpe @ MethodType(_, ret) => unwrapRet(ret)
+ case _ => tpe
+ }
+
+ tpe match {
+ case PolyType(_, tpe) => loop(tpe)
+ case _ => loop(tpe)
+ }
+ }
+ var metaType = unwrapRet(macroImpl.tpe)
+
+ // downgrade from metalevel-0 to metalevel-1
+ def inferRuntimeType(metaType: Type): Type = metaType match {
+ case TypeRef(pre, sym, args) if sym.name == tpnme.Expr && args.length == 1 =>
+ args.head
+ case _ =>
+ AnyClass.tpe
+ }
+ var runtimeType = inferRuntimeType(metaType)
+
+ // transform type parameters of a macro implementation into type parameters of a macro definition
+ runtimeType = runtimeType map {
+ case TypeRef(pre, sym, args) =>
+ // [Eugene] not sure which of these deSkolemizes are necessary
+ // sym.paramPos is unreliable (see another case below)
+ val tparams = macroImpl.typeParams map (_.deSkolemize)
+ val paramPos = tparams indexOf sym.deSkolemize
+ val sym1 = if (paramPos == -1) sym else {
+ val ann = macroDef.getAnnotation(MacroImplAnnotation)
+ ann match {
+ case Some(ann) =>
+ val TypeApply(_, implRefTargs) = ann.args(0)
+ val implRefTarg = implRefTargs(paramPos).tpe.typeSymbol
+ implRefTarg
+ case None =>
+ sym
}
}
+ TypeRef(pre, sym1, args)
+ case tpe =>
+ tpe
+ }
+
+ // as stated in the spec, before being matched to macroimpl, type and value parameters of macrodef
+ // undergo a special transformation, sigma, that adapts them to the different metalevel macroimpl lives in
+ // as a result, we need to reverse this transformation when inferring macrodef ret from macroimpl ret
+ def unsigma(tpe: Type): Type = {
+ // unfortunately, we cannot dereference ``paramss'', because we're in the middle of inferring a type for ``macroDef''
+// val defParamss = macroDef.paramss
+ val defParamss = mmap(macroDdef.vparamss)(_.symbol)
+ var implParamss = macroImpl.paramss
+ implParamss = transformTypeTagEvidenceParams(implParamss, (param, tparam) => None)
+
+ val implCtxParam = if (implParamss.length > 0 && implParamss(0).length > 0) implParamss(0)(0) else null
+ def implParamToDefParam(implParam: Symbol): Symbol = {
+ val indices = (((implParamss drop 1).zipWithIndex) map { case (implParams, index) => (index, implParams indexOf implParam) } filter (_._2 != -1)).headOption
+ val defParam = indices flatMap {
+ case (plistIndex, pIndex) =>
+ if (defParamss.length <= plistIndex) None
+ else if (defParamss(plistIndex).length <= pIndex) None
+ else Some(defParamss(plistIndex)(pIndex))
+ }
+ defParam.orNull
}
- } catch {
- case ex: ClassNotFoundException =>
- trace("implementation class failed to load: ")(ex.toString)
- None
+
+ class UnsigmaTypeMap extends TypeMap {
+ def apply(tp: Type): Type = tp match {
+ case TypeRef(pre, sym, args) =>
+ val pre1 = pre match {
+ case SingleType(SingleType(SingleType(NoPrefix, param), prefix), value) if param == implCtxParam && prefix == MacroContextPrefix && value == ExprValue =>
+ ThisType(macroDef.owner)
+ case SingleType(SingleType(NoPrefix, param), value) if implParamToDefParam(param) != null && value == ExprValue =>
+ val macroDefParam = implParamToDefParam(param)
+ SingleType(NoPrefix, macroDefParam)
+ case _ =>
+ pre
+ }
+ val args1 = args map mapOver
+ TypeRef(pre1, sym, args1)
+ case _ =>
+ mapOver(tp)
+ }
+ }
+
+ new UnsigmaTypeMap() apply tpe
}
+ runtimeType = unsigma(runtimeType)
+
+ runtimeType
}
- /** Return result of macro expansion.
- * Or, if that fails, and the macro overrides a method return
- * tree that calls this method instead of the macro.
+ /** Primary mirror that is used to resolve and run macro implementations.
+ * Loads classes from -Xmacro-primary-classpath, or from -cp if the option is not specified.
*/
- def macroExpand(tree: Tree, typer: Typer): Option[Any] = {
- val trace = scala.tools.nsc.util.trace when settings.Ymacrodebug.value
- trace("macroExpand: ")(tree)
-
- val macroDef = tree.symbol
- macroImpl(macroDef) match {
- case Some((receiver, rmeth)) =>
- val argss = List(global) :: macroArgs(tree)
- val paramss = macroMeth(macroDef).paramss
- trace("paramss: ")(paramss)
- val rawArgss = for ((as, ps) <- argss zip paramss) yield {
- if (isVarArgsList(ps)) as.take(ps.length - 1) :+ as.drop(ps.length - 1)
- else as
+ private lazy val primaryMirror: Mirror = {
+ if (global.forMSIL)
+ throw new UnsupportedOperationException("Scala reflection not available on this platform")
+
+ val libraryClassLoader = {
+ if (settings.XmacroPrimaryClasspath.value != "") {
+ macroLogVerbose("primary macro mirror: initializing from -Xmacro-primary-classpath: %s".format(settings.XmacroPrimaryClasspath.value))
+ val classpath = toURLs(settings.XmacroFallbackClasspath.value)
+ ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
+ } else {
+ macroLogVerbose("primary macro mirror: initializing from -cp: %s".format(global.classPath.asURLs))
+ val classpath = global.classPath.asURLs
+ var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
+
+ // [Eugene] a heuristic to detect REPL
+ if (global.settings.exposeEmptyPackage.value) {
+ import scala.tools.nsc.interpreter._
+ val virtualDirectory = global.settings.outputDirs.getSingleOutput.get
+ loader = new AbstractFileClassLoader(virtualDirectory, loader) {}
}
- val rawArgs: Seq[Any] = rawArgss.flatten
- trace("rawArgs: ")(rawArgs)
- val savedInfolevel = nodePrinters.infolevel
- try {
- // @xeno.by: InfoLevel.Verbose examines and prints out infos of symbols
- // by the means of this'es these symbols can climb up the lexical scope
- // when these symbols will be examined by a node printer
- // they will enumerate and analyze their children (ask for infos and tpes)
- // if one of those children involves macro expansion, things might get nasty
- // that's why I'm temporarily turning this behavior off
- nodePrinters.infolevel = nodePrinters.InfoLevel.Quiet
- val expanded = mirror.invoke(receiver, rmeth)(rawArgs: _*)
- expanded match {
- case expanded: Tree =>
- val expectedTpe = tree.tpe
- val typed = typer.typed(expanded, EXPRmode, expectedTpe)
- Some(typed)
- case expanded if expanded.isInstanceOf[Tree] =>
- typer.context.unit.error(tree.pos, "macro must return a compiler-specific tree; returned value is Tree, but it doesn't belong to this compiler's universe")
- None
- case expanded =>
- typer.context.unit.error(tree.pos, "macro must return a compiler-specific tree; returned value is of class: " + expanded.getClass)
+
+ loader
+ }
+ }
+
+ new Mirror(libraryClassLoader) { override def toString = "<primary macro mirror>" }
+ }
+
+ /** Fallback mirror that is used to resolve and run macro implementations.
+ * Loads classes from -Xmacro-fallback-classpath aka "macro fallback classpath".
+ */
+ private lazy val fallbackMirror: Mirror = {
+ if (global.forMSIL)
+ throw new UnsupportedOperationException("Scala reflection not available on this platform")
+
+ val fallbackClassLoader = {
+ macroLogVerbose("fallback macro mirror: initializing from -Xmacro-fallback-classpath: %s".format(settings.XmacroFallbackClasspath.value))
+ val classpath = toURLs(settings.XmacroFallbackClasspath.value)
+ ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
+ }
+
+ new Mirror(fallbackClassLoader) { override def toString = "<fallback macro mirror>" }
+ }
+
+ /** Produces a function that can be used to invoke macro implementation for a given macro definition:
+ * 1) Looks up macro implementation symbol in this universe.
+ * 2) Loads its enclosing class from the primary mirror.
+ * 3) Loads the companion of that enclosing class from the primary mirror.
+ * 4) Resolves macro implementation within the loaded companion.
+ * 5) If 2-4 fails, repeats them for the fallback mirror.
+ *
+ * @return Some(runtime) if macro implementation can be loaded successfully from either of the mirrors,
+ * None otherwise.
+ */
+ private type MacroRuntime = List[Any] => Any
+ private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, Option[MacroRuntime]]
+ private def macroRuntime(macroDef: Symbol): Option[MacroRuntime] =
+ macroRuntimesCache.getOrElseUpdate(macroDef, {
+ val runtime = {
+ macroTraceVerbose("looking for macro implementation: ")(macroDef)
+ macroTraceVerbose("macroDef is annotated with: ")(macroDef.annotations)
+
+ val ann = macroDef.getAnnotation(MacroImplAnnotation)
+ if (ann == None) {
+ macroTraceVerbose("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef)
+ return None
+ }
+
+ val macroImpl = ann.get.args(0).symbol
+ if (macroImpl == NoSymbol) {
+ macroTraceVerbose("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef)
+ return None
+ }
+
+ macroLogVerbose("resolved implementation %s at %s".format(macroImpl, macroImpl.pos))
+ if (macroImpl.isErroneous) {
+ macroTraceVerbose("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef)
+ return None
+ }
+
+ def loadMacroImpl(macroMirror: Mirror): Option[(Object, macroMirror.Symbol)] = {
+ try {
+ // this logic relies on the assumptions that were valid for the old macro prototype
+ // namely that macro implementations can only be defined in top-level classes and modules
+ // with the new prototype that materialized in a SIP, macros need to be statically accessible, which is different
+ // for example, a macro def could be defined in a trait that is implemented by an object
+ // there are some more clever cases when seemingly non-static method ends up being statically accessible
+ // however, the code below doesn't account for these guys, because it'd take a look of time to get it right
+ // for now I leave it as a todo and move along to more the important stuff
+
+ macroTraceVerbose("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName)
+ macroTraceVerbose("classloader is: ")("%s of type %s".format(macroMirror.classLoader, if (macroMirror.classLoader != null) macroMirror.classLoader.getClass.toString else "primordial classloader"))
+ def inferClasspath(cl: ClassLoader) = cl match {
+ case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
+ case null => "[" + scala.tools.util.PathResolver.Environment.javaBootClassPath + "]"
+ case _ => "<unknown>"
+ }
+ macroTraceVerbose("classpath is: ")(inferClasspath(macroMirror.classLoader))
+
+ // [Eugene] relies on the fact that macro implementations can only be defined in static classes
+ // [Martin to Eugene] There's similar logic buried in Symbol#flatname. Maybe we can refactor?
+ def classfile(sym: Symbol): String = {
+ def recur(sym: Symbol): String = sym match {
+ case sym if sym.owner.isPackageClass =>
+ val suffix = if (sym.isModuleClass) "$" else ""
+ sym.fullName + suffix
+ case sym =>
+ val separator = if (sym.owner.isModuleClass) "" else "$"
+ recur(sym.owner) + separator + sym.javaSimpleName.toString
+ }
+
+ if (sym.isClass || sym.isModule) recur(sym)
+ else recur(sym.enclClass)
+ }
+
+ // [Eugene] this doesn't work for inner classes
+ // neither does macroImpl.owner.javaClassName, so I had to roll my own implementation
+ //val receiverName = macroImpl.owner.fullName
+ val implClassName = classfile(macroImpl.owner)
+ val implClassSymbol: macroMirror.Symbol = macroMirror.symbolForName(implClassName)
+
+ if (macroDebugVerbose) {
+ println("implClassSymbol is: " + implClassSymbol.fullNameString)
+
+ if (implClassSymbol != macroMirror.NoSymbol) {
+ val implClass = macroMirror.classToJava(implClassSymbol)
+ val implSource = implClass.getProtectionDomain.getCodeSource
+ println("implClass is %s from %s".format(implClass, implSource))
+ println("implClassLoader is %s with classpath %s".format(implClass.getClassLoader, inferClasspath(implClass.getClassLoader)))
+ }
+ }
+
+ val implObjSymbol = implClassSymbol.companionModule
+ macroTraceVerbose("implObjSymbol is: ")(implObjSymbol.fullNameString)
+
+ if (implObjSymbol == macroMirror.NoSymbol) None
+ else {
+ // yet another reflection method that doesn't work for inner classes
+ //val receiver = macroMirror.companionInstance(receiverClass)
+ val implObj = try {
+ val implObjClass = java.lang.Class.forName(implClassName, true, macroMirror.classLoader)
+ implObjClass getField "MODULE$" get null
+ } catch {
+ case ex: NoSuchFieldException => macroTraceVerbose("exception when loading implObj: ")(ex); null
+ case ex: NoClassDefFoundError => macroTraceVerbose("exception when loading implObj: ")(ex); null
+ case ex: ClassNotFoundException => macroTraceVerbose("exception when loading implObj: ")(ex); null
+ }
+
+ if (implObj == null) None
+ else {
+ val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString))
+ macroLogVerbose("implMethSymbol is: " + implMethSymbol.fullNameString)
+ macroLogVerbose("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol))
+
+ if (implMethSymbol == macroMirror.NoSymbol) None
+ else {
+ macroLogVerbose("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol))
+ Some((implObj, implMethSymbol))
+ }
+ }
+ }
+ } catch {
+ case ex: ClassNotFoundException =>
+ macroTraceVerbose("implementation class failed to load: ")(ex.toString)
None
}
- } catch {
- case ex =>
- val realex = ReflectionUtils.unwrapThrowable(ex)
- val msg = if (settings.Ymacrodebug.value) {
- val stacktrace = new java.io.StringWriter()
- realex.printStackTrace(new java.io.PrintWriter(stacktrace))
- System.getProperty("line.separator") + stacktrace
+ }
+
+ val primary = loadMacroImpl(primaryMirror)
+ primary match {
+ case Some((implObj, implMethSymbol)) =>
+ def runtime(args: List[Any]) = primaryMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any]
+ Some(runtime _)
+ case None =>
+ if (settings.XmacroFallbackClasspath.value != "") {
+ macroLogVerbose("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value))
+ val fallback = loadMacroImpl(fallbackMirror)
+ fallback match {
+ case Some((implObj, implMethSymbol)) =>
+ def runtime(args: List[Any]) = fallbackMirror.invoke(implObj, implMethSymbol)(args: _*).asInstanceOf[Any]
+ Some(runtime _)
+ case None =>
+ None
+ }
} else {
- realex.getMessage
+ None
}
- typer.context.unit.error(tree.pos, "exception during macro expansion: " + msg)
- None
- } finally {
- nodePrinters.infolevel = savedInfolevel
}
- case None =>
- def notFound() = {
- typer.context.unit.error(tree.pos, "macro implementation not found: " + macroDef.name)
- None
+ }
+
+ if (runtime == None) macroDef setFlag IS_ERROR
+ runtime
+ })
+
+ /** Should become private again once we're done with migrating typetag generation from implicits */
+ def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext { val mirror: global.type } =
+ new {
+ val mirror: global.type = global
+ val callsiteTyper: mirror.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer]
+ // todo. infer precise typetag for this Expr, namely the PrefixType member of the Context refinement
+ val prefix = Expr(prefixTree)(TypeTag.Nothing)
+ val expandee = expandeeTree
+ } with MacroContext {
+ override def toString = "MacroContext(%s@%s +%d)".format(expandee.symbol.name, expandee.pos, enclosingMacros.length - 1 /* exclude myself */)
+ }
+
+ /** Calculate the arguments to pass to a macro implementation when expanding the provided tree.
+ *
+ * This includes inferring the exact type and instance of the macro context to pass, and also
+ * allowing for missing parameter sections in macro implementation (see ``macroImplParamsss'' for more info).
+ *
+ * @return list of runtime objects to pass to the implementation obtained by ``macroRuntime''
+ */
+ private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = {
+ val macroDef = expandee.symbol
+ val runtime = macroRuntime(macroDef) orElse { return None }
+ var prefixTree: Tree = EmptyTree
+ var typeArgs = List[Tree]()
+ val exprArgs = ListBuffer[List[Expr[_]]]()
+
+ def collectMacroArgs(tree: Tree): Unit = tree match {
+ case Apply(fn, args) =>
+ // todo. infer precise typetag for this Expr, namely the declared type of the corresponding macro impl argument
+ exprArgs.prepend(args map (Expr(_)(TypeTag.Nothing)))
+ collectMacroArgs(fn)
+ case TypeApply(fn, args) =>
+ typeArgs = args
+ collectMacroArgs(fn)
+ case Select(qual, name) =>
+ prefixTree = qual
+ case _ =>
+ }
+ collectMacroArgs(expandee)
+ val context = expandee.attachmentOpt[MacroAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee))
+ var argss: List[List[Any]] = List(context) :: exprArgs.toList
+ macroTraceVerbose("argss: ")(argss)
+
+ val ann = macroDef.getAnnotation(MacroImplAnnotation).getOrElse(throw new Error("assertion failed. %s: %s".format(macroDef, macroDef.annotations)))
+ val macroImpl = ann.args(0).symbol
+ var paramss = macroImpl.paramss
+ val tparams = macroImpl.typeParams
+ macroTraceVerbose("paramss: ")(paramss)
+
+ // we need to take care of all possible combos of nullary/empty-paramlist macro defs vs nullary/empty-arglist invocations
+ // nullary def + nullary invocation => paramss and argss match, everything is okay
+ // nullary def + empty-arglist invocation => illegal Scala code, impossible, everything is okay
+ // empty-paramlist def + nullary invocation => uh-oh, we need to append a List() to argss
+ // empty-paramlist def + empty-arglist invocation => paramss and argss match, everything is okay
+ // that's almost it, but we need to account for the fact that paramss might have context bounds that mask the empty last paramlist
+ val paramss_without_evidences = transformTypeTagEvidenceParams(paramss, (param, tparam) => None)
+ val isEmptyParamlistDef = paramss_without_evidences.nonEmpty && paramss_without_evidences.last.isEmpty
+ val isEmptyArglistInvocation = argss.nonEmpty && argss.last.isEmpty
+ if (isEmptyParamlistDef && !isEmptyArglistInvocation) {
+ macroLogVerbose("isEmptyParamlistDef && !isEmptyArglistInvocation: appending a List() to argss")
+ argss = argss :+ Nil
+ }
+
+ // nb! check partial application against paramss without evidences
+ val numParamLists = paramss_without_evidences.length
+ val numArgLists = argss.length
+ if (numParamLists != numArgLists) {
+ typer.TyperErrorGen.MacroPartialApplicationError(expandee)
+ return None
+ }
+
+ // if paramss have typetag context bounds, add an arglist to argss if necessary and instantiate the corresponding evidences
+ // consider the following example:
+ //
+ // class D[T] {
+ // class C[U] {
+ // def foo[V] = macro Impls.foo[T, U, V]
+ // }
+ // }
+ //
+ // val outer1 = new D[Int]
+ // val outer2 = new outer1.C[String]
+ // outer2.foo[Boolean]
+ //
+ // then T and U need to be inferred from the lexical scope of the call using ``asSeenFrom''
+ // whereas V won't be resolved by asSeenFrom and need to be loaded directly from ``expandee'' which needs to contain a TypeApply node
+ // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim
+ val resolved = collection.mutable.Map[Symbol, Type]()
+ paramss = transformTypeTagEvidenceParams(paramss, (param, tparam) => {
+ val TypeApply(_, implRefTargs) = ann.args(0)
+ var implRefTarg = implRefTargs(tparam.paramPos).tpe.typeSymbol
+ val tpe = if (implRefTarg.isTypeParameterOrSkolem) {
+ if (implRefTarg.owner == macroDef) {
+ // [Eugene] doesn't work when macro def is compiled separately from its usages
+ // then implRefTarg is not a skolem and isn't equal to any of macroDef.typeParams
+// val paramPos = implRefTarg.deSkolemize.paramPos
+ val paramPos = macroDef.typeParams.indexWhere(_.name == implRefTarg.name)
+ typeArgs(paramPos).tpe
+ } else
+ implRefTarg.tpe.asSeenFrom(
+ if (prefixTree == EmptyTree) macroDef.owner.tpe else prefixTree.tpe,
+ macroDef.owner)
+ } else
+ implRefTarg.tpe
+ macroLogVerbose("resolved tparam %s as %s".format(tparam, tpe))
+ resolved(tparam) = tpe
+ param.tpe.typeSymbol match {
+ case definitions.TypeTagClass =>
+ // do nothing
+ case definitions.ConcreteTypeTagClass =>
+ if (!tpe.isConcrete) context.abort(context.enclosingPosition, "cannot create ConcreteTypeTag from a type %s having unresolved type parameters".format(tpe))
+ // otherwise do nothing
+ case _ =>
+ throw new Error("unsupported tpe: " + tpe)
+ }
+ Some(tparam)
+ })
+ val tags = paramss.last takeWhile (_.isType) map (resolved(_)) map (tpe => {
+ // generally speaking, it's impossible to calculate erasure from a tpe here
+ // the tpe might be compiled by this run, so its jClass might not exist yet
+ // hence I just pass `null` instead and leave this puzzle to macro programmers
+ val ttag = TypeTag(tpe, null)
+ if (ttag.isConcrete) ttag.toConcrete else ttag
+ })
+ if (paramss.lastOption map (params => !params.isEmpty && params.forall(_.isType)) getOrElse false) argss = argss :+ Nil
+ argss = argss.dropRight(1) :+ (tags ++ argss.last) // todo. add support for context bounds in argss
+
+ assert(argss.length == paramss.length, "argss: %s, paramss: %s".format(argss, paramss))
+ val rawArgss = for ((as, ps) <- argss zip paramss) yield {
+ if (isVarArgsList(ps)) as.take(ps.length - 1) :+ as.drop(ps.length - 1)
+ else as
+ }
+ val rawArgs = rawArgss.flatten
+ macroTraceVerbose("rawArgs: ")(rawArgs)
+ Some(rawArgs)
+ }
+
+ /** Keeps track of macros in-flight.
+ * See more informations in comments to ``openMacros'' in ``scala.reflect.makro.Context''.
+ */
+ var openMacros = List[MacroContext]()
+ def enclosingMacroPosition = openMacros map (_.macroApplication.pos) find (_ ne NoPosition) getOrElse NoPosition
+
+ /** Performs macro expansion:
+ * 1) Checks whether the expansion needs to be delayed (see ``mustDelayMacroExpansion'')
+ * 2) Loads macro implementation using ``macroMirror''
+ * 3) Synthesizes invocation arguments for the macro implementation
+ * 4) Checks that the result is a tree bound to this universe
+ * 5) Typechecks the result against the return type of the macro definition
+ *
+ * If -Ymacro-debug-lite is enabled, you will get basic notifications about macro expansion
+ * along with macro expansions logged in the form that can be copy/pasted verbatim into REPL.
+ *
+ * If -Ymacro-debug-verbose is enabled, you will get detailed log of how exactly this function
+ * performs class loading and method resolution in order to load the macro implementation.
+ * The log will also include other non-trivial steps of macro expansion.
+ *
+ * @return
+ * the expansion result if the expansion has been successful,
+ * the fallback method invocation if the expansion has been unsuccessful, but there is a fallback,
+ * the expandee unchanged if the expansion has been delayed,
+ * the expandee fully expanded if the expansion has been delayed before and has been expanded now,
+ * the expandee with an error marker set if the expansion has been cancelled due malformed arguments or implementation
+ * the expandee with an error marker set if there has been an error
+ */
+ def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = {
+ def fail(what: String, tree: Tree): Tree = {
+ val err = typer.context.errBuffer.head
+ this.fail(typer, tree, "failed to %s: %s at %s".format(what, err.errMsg, err.errPos))
+ return expandee
+ }
+ val start = startTimer(macroExpandNanos)
+ incCounter(macroExpandCount)
+ try {
+ macroExpand1(typer, expandee) match {
+ case Success(expanded) =>
+ try {
+ var expectedTpe = expandee.tpe
+
+ // [Eugene] weird situation. what's the conventional way to deal with it?
+ val isNullaryInvocation = expandee match {
+ case TypeApply(Select(_, _), _) => true
+ case TypeApply(Ident(_), _) => true
+ case Select(_, _) => true
+ case Ident(_) => true
+ case _ => false
+ }
+ if (isNullaryInvocation) expectedTpe match {
+ case NullaryMethodType(restpe) =>
+ macroTraceVerbose("nullary invocation of a nullary method. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe)
+ expectedTpe = restpe
+ case MethodType(Nil, restpe) =>
+ macroTraceVerbose("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe)
+ expectedTpe = restpe
+ case _ => ;
+ }
+
+ macroLogVerbose("typechecking1 against %s: %s".format(expectedTpe, expanded))
+ var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe))
+ if (typer.context.hasErrors) fail("typecheck against macro def return type", expanded)
+ macroLogVerbose("typechecked1:%n%s%n%s".format(typechecked, showRaw(typechecked)))
+
+ macroLogVerbose("typechecking2 against %s: %s".format(pt, expanded))
+ typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt))
+ if (typer.context.hasErrors) fail("typecheck against expected type", expanded)
+ macroLogVerbose("typechecked2:%n%s%n%s".format(typechecked, showRaw(typechecked)))
+
+ typechecked
+ } finally {
+ openMacros = openMacros.tail
+ }
+ case Fallback(fallback) =>
+ typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt))
+ case Other(result) =>
+ result
+ }
+ } finally {
+ stopTimer(macroExpandNanos, start)
+ }
+ }
+
+ private sealed abstract class MacroExpansionResult extends Product with Serializable
+ private case class Success(expanded: Tree) extends MacroExpansionResult
+ private case class Fallback(fallback: Tree) extends MacroExpansionResult
+ private case class Other(result: Tree) extends MacroExpansionResult
+ private def Delay(expanded: Tree) = Other(expanded)
+ private def Skip(expanded: Tree) = Other(expanded)
+ private def Cancel(expandee: Tree) = Other(expandee)
+ private def Failure(expandee: Tree) = Other(expandee)
+ private def fail(typer: Typer, expandee: Tree, msg: String = null) = {
+ def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg
+ macroLogVerbose("macro expansion has failed: %s".format(msgForLog))
+ val pos = if (expandee.pos != NoPosition) expandee.pos else enclosingMacroPosition
+ if (msg != null) typer.context.error(pos, msg)
+ typer.infer.setError(expandee)
+ Failure(expandee)
+ }
+
+ /** Does the same as ``macroExpand'', but without typechecking the expansion
+ * Meant for internal use within the macro infrastructure, don't use it elsewhere.
+ */
+ private def macroExpand1(typer: Typer, expandee: Tree): MacroExpansionResult =
+ // InfoLevel.Verbose examines and prints out infos of symbols
+ // by the means of this'es these symbols can climb up the lexical scope
+ // when these symbols will be examined by a node printer
+ // they will enumerate and analyze their children (ask for infos and tpes)
+ // if one of those children involves macro expansion, things might get nasty
+ // that's why I'm temporarily turning this behavior off
+ withInfoLevel(nodePrinters.InfoLevel.Quiet) {
+ // if a macro implementation is incompatible or any of the arguments are erroneous
+ // there is no sense to expand the macro itself => it will only make matters worse
+ if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) {
+ val reason = if (expandee.symbol.isErroneous) "incompatible macro implementation" else "erroneous arguments"
+ macroTraceVerbose("cancelled macro expansion because of %s: ".format(reason))(expandee)
+ return Cancel(typer.infer.setError(expandee))
+ }
+
+ macroRuntime(expandee.symbol) match {
+ case Some(runtime) =>
+ macroExpandWithRuntime(typer, expandee, runtime)
+ case None =>
+ macroExpandWithoutRuntime(typer, expandee)
+ }
+ }
+
+ /** Expands a macro when a runtime (i.e. the macro implementation) can be successfully loaded
+ * Meant for internal use within the macro infrastructure, don't use it elsewhere.
+ */
+ private def macroExpandWithRuntime(typer: Typer, expandee: Tree, runtime: MacroRuntime): MacroExpansionResult = {
+ def issueFreeError(sym: FreeSymbol) = {
+ val template = (
+ "Macro expansion contains free @kind@ variable %s. Have you forgotten to use %s? "
+ + "If you have troubles tracking free @kind@ variables, consider using -Xlog-free-@kind@s"
+ )
+ val forgotten = (
+ if (sym.isTerm) "eval when splicing this variable into a reifee"
+ else "c.TypeTag annotation for this type parameter"
+ )
+ typer.context.error(expandee.pos,
+ template.replaceAllLiterally("@kind@", sym.name.nameKind).format(
+ sym.name + " " + sym.origin, forgotten)
+ )
+ }
+ def macroExpandInternal = {
+ val wasDelayed = isDelayed(expandee)
+ val undetparams = calculateUndetparams(expandee)
+ val nowDelayed = !typer.context.macrosEnabled || undetparams.nonEmpty
+
+ def failExpansion(msg: String = null) = fail(typer, expandee, msg)
+ def performExpansion(args: List[Any]): MacroExpansionResult = {
+ val numErrors = reporter.ERROR.count
+ def hasNewErrors = reporter.ERROR.count > numErrors
+
+ val expanded = runtime(args)
+
+ if (hasNewErrors)
+ failExpansion() // errors have been reported by the macro itself
+ else expanded match {
+ case expanded: Expr[_] =>
+ macroLogVerbose("original:")
+ macroLogVerbose("" + expanded.tree + "\n" + showRaw(expanded.tree))
+
+ freeTerms(expanded.tree) foreach issueFreeError
+ freeTypes(expanded.tree) foreach issueFreeError
+ if (hasNewErrors) failExpansion()
+
+ // inherit the position from the first position-ful expandee in macro callstack
+ // this is essential for sane error messages
+ // now macro expansion gets typechecked against the macro definition return type
+ // however, this happens in macroExpand, not here in macroExpand1
+ else Success(atPos(enclosingMacroPosition.focus)(expanded.tree))
+ case _ =>
+ failExpansion(
+ "macro must return a compiler-specific expr; returned value is " + (
+ if (expanded.isInstanceOf[Expr[_]]) " Expr, but it doesn't belong to this compiler's universe"
+ else " of " + expanded.getClass
+ )
+ )
}
- def fallBackToOverridden(tree: Tree): Option[Tree] = {
- tree match {
- case Select(qual, name) if (macroDef.isMacro) =>
- macroDef.allOverriddenSymbols match {
- case first :: _ =>
- Some(Select(qual, name) setPos tree.pos setSymbol first)
- case _ =>
- trace("macro is not overridden: ")(tree)
- notFound()
- }
- case Apply(fn, args) =>
- fallBackToOverridden(fn) match {
- case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos)
- case _ => None
+ }
+
+ if (wasDelayed) {
+ if (nowDelayed) Delay(expandee)
+ else Skip(macroExpandAll(typer, expandee))
+ }
+ else {
+ macroLogVerbose("typechecking macro expansion %s at %s".format(expandee, expandee.pos))
+ macroArgs(typer, expandee).fold(failExpansion(): MacroExpansionResult) {
+ case args @ ((context: MacroContext) :: _) =>
+ if (nowDelayed) {
+ macroLogVerbose("macro expansion is delayed: %s".format(expandee))
+ delayed += expandee -> undetparams
+ // need to save typer context for `macroExpandAll`
+ // need to save macro context to preserve enclosures
+ expandee attach MacroAttachment(delayed = true, typerContext = typer.context, macroContext = Some(context))
+ Delay(expandee)
+ }
+ else {
+ // adding stuff to openMacros is easy, but removing it is a nightmare
+ // it needs to be sprinkled over several different code locations
+ // why? https://github.com/scala/scala/commit/bd3eacbae21f39b1ac7fe8ade4ed71fa98e1a28d#L2R1137
+ // todo. will be improved
+ openMacros ::= context
+ var isSuccess = false
+ try performExpansion(args) match {
+ case x: Success => isSuccess = true ; x
+ case x => x
}
- case TypeApply(fn, args) =>
- fallBackToOverridden(fn) match {
- case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos)
- case _ => None
+ finally {
+ expandee.detach(classOf[MacroAttachment])
+ if (!isSuccess) openMacros = openMacros.tail
}
+ }
+ }
+ }
+ }
+
+ try macroExpandInternal
+ catch { case ex => handleMacroExpansionException(typer, expandee, ex) }
+ }
+
+ private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroExpansionResult = {
+ val macroDef = expandee.symbol
+ def notFound() = {
+ typer.context.error(expandee.pos, "macro implementation not found: " + macroDef.name + " " +
+ "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)\n" +
+ "if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath " +
+ "in the second phase pointing to the output of the first phase")
+ None
+ }
+ def fallBackToOverridden(tree: Tree): Option[Tree] = {
+ tree match {
+ case Select(qual, name) if (macroDef.isTermMacro) =>
+ macroDef.allOverriddenSymbols match {
+ case first :: _ =>
+ Some(Select(qual, name) setPos tree.pos setSymbol first)
case _ =>
- trace("unexpected tree in fallback: ")(tree)
+ macroTraceVerbose("macro is not overridden: ")(tree)
notFound()
}
- }
- fallBackToOverridden(tree) match {
- case Some(tree1) =>
- trace("falling back to ")(tree1)
- currentRun.macroExpansionFailed = true
- Some(tree1)
- case None =>
- None
- }
+ case Apply(fn, args) =>
+ fallBackToOverridden(fn) match {
+ case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos)
+ case _ => None
+ }
+ case TypeApply(fn, args) =>
+ fallBackToOverridden(fn) match {
+ case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos)
+ case _ => None
+ }
+ case _ =>
+ macroTraceVerbose("unexpected tree in fallback: ")(tree)
+ notFound()
+ }
+ }
+ fallBackToOverridden(expandee) match {
+ case Some(tree1) =>
+ macroTraceVerbose("falling back to: ")(tree1)
+ currentRun.macroExpansionFailed = true
+ Fallback(tree1)
+ case None =>
+ fail(typer, expandee)
+ }
+ }
+
+ private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = {
+ // [Eugene] any ideas about how to improve this one?
+ val realex = ReflectionUtils.unwrapThrowable(ex)
+ realex match {
+ case realex: reflect.makro.runtime.AbortMacroException =>
+ macroLogVerbose("macro expansion has failed: %s".format(realex.msg))
+ fail(typer, expandee) // error has been reported by abort
+ case err: TypeError =>
+ macroLogVerbose("macro expansion has failed: %s at %s".format(err.msg, err.pos))
+ throw err // error should be propagated, don't report
+ case _ =>
+ val message = {
+ try {
+ // [Eugene] is there a better way?
+ // [Paul] See Exceptional.scala and Origins.scala.
+ val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == "macroExpand1")
+ if (relevancyThreshold == -1) None
+ else {
+ var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1)
+ var framesTillReflectiveInvocationOfMacroImpl = relevantElements.reverse.indexWhere(_.isNativeMethod) + 1
+ relevantElements = relevantElements dropRight framesTillReflectiveInvocationOfMacroImpl
+
+ realex.setStackTrace(relevantElements)
+ val message = new java.io.StringWriter()
+ realex.printStackTrace(new java.io.PrintWriter(message))
+ Some(EOL + message)
+ }
+ } catch {
+ // if the magic above goes boom, just fall back to uninformative, but better than nothing, getMessage
+ case ex: Throwable =>
+ None
+ }
+ } getOrElse realex.getMessage
+ fail(typer, expandee, "exception during macro expansion: " + message)
}
}
+
+ /** Without any restrictions on macro expansion, macro applications will expand at will,
+ * and when type inference is involved, expansions will end up using yet uninferred type params.
+ *
+ * For some macros this might be ok (thanks to TreeTypeSubstituter that replaces
+ * the occurrences of undetparams with their inferred values), but in general case this won't work.
+ * E.g. for reification simple substitution is not enough - we actually need to re-reify inferred types.
+ *
+ * Luckily, there exists a very simple way to fix the problem: delay macro expansion until everything is inferred.
+ * Here are the exact rules. Macro application gets delayed if any of its subtrees contain:
+ * 1) type vars (tpe.isInstanceOf[TypeVar]) // [Eugene] this check is disabled right now, because TypeVars seem to be created from undetparams anyways
+ * 2) undetparams (sym.isTypeParameter && !sym.isSkolem)
+ */
+ var hasPendingMacroExpansions = false
+ private val delayed = perRunCaches.newWeakMap[Tree, collection.mutable.Set[Int]]
+ private def isDelayed(expandee: Tree) = delayed contains expandee
+ private def calculateUndetparams(expandee: Tree): collection.mutable.Set[Int] =
+ delayed.get(expandee).getOrElse {
+ val calculated = collection.mutable.Set[Symbol]()
+ expandee foreach (sub => {
+ def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym
+ if (sub.symbol != null) traverse(sub.symbol)
+ if (sub.tpe != null) sub.tpe foreach (sub => traverse(sub.typeSymbol))
+ })
+ macroLogVerbose("calculateUndetparams: %s".format(calculated))
+ calculated map (_.id)
+ }
+ private val undetparams = perRunCaches.newSet[Int]
+ def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = {
+ undetparams ++= newUndets map (_.id)
+ if (macroDebugVerbose) newUndets foreach (sym => println("undetParam added: %s".format(sym)))
+ }
+ def notifyUndetparamsInferred(undetNoMore: List[Symbol], inferreds: List[Type]): Unit = {
+ undetparams --= undetNoMore map (_.id)
+ if (macroDebugVerbose) (undetNoMore zip inferreds) foreach { case (sym, tpe) => println("undetParam inferred: %s as %s".format(sym, tpe))}
+ if (!delayed.isEmpty)
+ delayed.toList foreach {
+ case (expandee, undetparams) if !undetparams.isEmpty =>
+ undetparams --= undetNoMore map (_.id)
+ if (undetparams.isEmpty) {
+ hasPendingMacroExpansions = true
+ macroTraceVerbose("macro expansion is pending: ")(expandee)
+ }
+ case _ =>
+ // do nothing
+ }
+ }
+
+ /** Performs macro expansion on all subtrees of a given tree.
+ * Innermost macros are expanded first, outermost macros are expanded last.
+ * See the documentation for ``macroExpand'' for more information.
+ */
+ def macroExpandAll(typer: Typer, expandee: Tree): Tree =
+ new Transformer {
+ override def transform(tree: Tree) = super.transform(tree match {
+ // todo. expansion should work from the inside out
+ case wannabe if (delayed contains wannabe) && calculateUndetparams(wannabe).isEmpty =>
+ val context = wannabe.attachment[MacroAttachment].typerContext
+ delayed -= wannabe
+ context.implicitsEnabled = typer.context.implicitsEnabled
+ context.enrichmentEnabled = typer.context.enrichmentEnabled
+ context.macrosEnabled = typer.context.macrosEnabled
+ macroExpand(newTyper(context), wannabe, EXPRmode, WildcardType)
+ case _ =>
+ tree
+ })
+ }.transform(expandee)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index f32ad9293c..4c71772929 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -8,6 +8,8 @@ package typechecker
import symtab.Flags._
import scala.collection.{ mutable, immutable }
import scala.tools.util.StringOps.{ ojoin }
+import scala.reflect.{ mirror => rm }
+import language.higherKinds
/** Logic related to method synthesis which involves cooperation between
* Namer and Typer.
@@ -20,52 +22,72 @@ trait MethodSynthesis {
import CODE._
object synthesisUtil {
- type M[T] = Manifest[T]
- type CM[T] = ClassManifest[T]
+ type CTT[T] = rm.ConcreteTypeTag[T]
+ type CT[T] = ClassTag[T]
def ValOrDefDef(sym: Symbol, body: Tree) =
if (sym.isLazy) ValDef(sym, body)
else DefDef(sym, body)
- def applyTypeInternal(manifests: List[M[_]]): Type = {
- val symbols = manifests map manifestToSymbol
+ def applyTypeInternal(tags: List[CTT[_]]): Type = {
+ // [Eugene to Paul] needs review!!
+ val symbols = tags map compilerSymbolFromTag
val container :: args = symbols
val tparams = container.typeConstructor.typeParams
// Conservative at present - if manifests were more usable this could do a lot more.
- require(symbols forall (_ ne NoSymbol), "Must find all manifests: " + symbols)
+ // [Eugene to Paul] all right, they are now. what do you have in mind?
+ require(symbols forall (_ ne NoSymbol), "Must find all tags: " + symbols)
require(container.owner.isPackageClass, "Container must be a top-level class in a package: " + container)
require(tparams.size == args.size, "Arguments must match type constructor arity: " + tparams + ", " + args)
- typeRef(container.typeConstructor.prefix, container, args map (_.tpe))
+ appliedType(container, args map (_.tpe): _*)
}
- def companionType[T](implicit m: M[T]) =
+ def companionType[T](implicit m: CTT[T]) =
getRequiredModule(m.erasure.getName).tpe
// Use these like `applyType[List, Int]` or `applyType[Map, Int, String]`
- def applyType[CC](implicit m1: M[CC]): Type =
+ def applyType[CC](implicit m1: CTT[CC]): Type =
applyTypeInternal(List(m1))
- def applyType[CC[X1], X1](implicit m1: M[CC[_]], m2: M[X1]): Type =
+ def applyType[CC[X1], X1](implicit m1: CTT[CC[_]], m2: CTT[X1]): Type =
applyTypeInternal(List(m1, m2))
- def applyType[CC[X1, X2], X1, X2](implicit m1: M[CC[_,_]], m2: M[X1], m3: M[X2]): Type =
+ def applyType[CC[X1, X2], X1, X2](implicit m1: CTT[CC[_,_]], m2: CTT[X1], m3: CTT[X2]): Type =
applyTypeInternal(List(m1, m2, m3))
- def applyType[CC[X1, X2, X3], X1, X2, X3](implicit m1: M[CC[_,_,_]], m2: M[X1], m3: M[X2], m4: M[X3]): Type =
+ def applyType[CC[X1, X2, X3], X1, X2, X3](implicit m1: CTT[CC[_,_,_]], m2: CTT[X1], m3: CTT[X2], m4: CTT[X3]): Type =
applyTypeInternal(List(m1, m2, m3, m4))
- def newMethodType[F](owner: Symbol)(implicit m: Manifest[F]): Type = {
- val fnSymbol = manifestToSymbol(m)
- assert(fnSymbol isSubClass FunctionClass(m.typeArguments.size - 1), (owner, m))
- val symbols = m.typeArguments map (m => manifestToSymbol(m))
- val formals = symbols.init map (_.typeConstructor)
+ def newMethodType[F](owner: Symbol)(implicit t: CTT[F]): Type = {
+ val fnSymbol = compilerSymbolFromTag(t)
+ assert(fnSymbol isSubClass FunctionClass(t.tpe.typeArguments.size - 1), (owner, t))
+ // [Eugene to Paul] needs review!!
+ // val symbols = m.typeArguments map (m => manifestToSymbol(m))
+ // val formals = symbols.init map (_.typeConstructor)
+ val formals = compilerTypeFromTag(t).typeArguments
val params = owner newSyntheticValueParams formals
-
- MethodType(params, symbols.last.typeConstructor)
+ MethodType(params, formals.last)
}
- }
+
+ /** The annotations amongst those found on the original symbol which
+ * should be propagated to this kind of accessor.
+ */
+ def deriveAnnotations(initial: List[AnnotationInfo], category: Symbol, keepClean: Boolean): List[AnnotationInfo] = {
+ initial filter { ann =>
+ // There are no meta-annotation arguments attached to `ann`
+ if (ann.metaAnnotations.isEmpty) {
+ // A meta-annotation matching `annotKind` exists on `ann`'s definition.
+ (ann.defaultTargets contains category) ||
+ // `ann`'s definition has no meta-annotations, and `keepClean` is true.
+ (ann.defaultTargets.isEmpty && keepClean)
+ }
+ // There are meta-annotation arguments, and one of them matches `annotKind`
+ else ann.metaAnnotations exists (_ matches category)
+ }
+ }
+ }
import synthesisUtil._
class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) {
@@ -96,8 +118,7 @@ trait MethodSynthesis {
finishMethod(m setInfoAndEnter infoFn(m), f)
}
private def cloneInternal(original: Symbol, f: Symbol => Tree, name: Name): Tree = {
- val m = original.cloneSymbol(clazz, newMethodFlags(original)) setPos clazz.pos.focus
- m.name = name
+ val m = original.cloneSymbol(clazz, newMethodFlags(original), name) setPos clazz.pos.focus
finishMethod(clazz.info.decls enter m, f)
}
@@ -156,13 +177,14 @@ trait MethodSynthesis {
/** There are two key methods in here.
*
- * 1) enterGetterSetter is called from Namer with a ValDef which
- * may need accessors. Some setup is performed. In general this
- * creates symbols and enters them into the scope of the owner.
+ * 1) Enter methods such as enterGetterSetterare called
+ * from Namer with a tree which may generate further trees such as accessors or
+ * implicit wrappers. Some setup is performed. In general this creates symbols
+ * and enters them into the scope of the owner.
*
- * 2) finishGetterSetter is called from Typer when a Template is typed.
+ * 2) addDerivedTrees is called from Typer when a Template is typed.
* It completes the job, returning a list of trees with their symbols
- * set to those created in enterGetterSetter. Those trees then become
+ * set to those created in the enter methods. Those trees then become
* part of the typed template.
*/
trait MethodSynth {
@@ -170,6 +192,10 @@ trait MethodSynthesis {
import NamerErrorGen._
+ def enterImplicitWrapper(tree: ClassDef) {
+ ImplicitClassWrapper(tree).createAndEnterSymbol()
+ }
+
def enterGetterSetter(tree: ValDef) {
val ValDef(mods, name, _, _) = tree
if (nme.isSetterName(name))
@@ -194,21 +220,28 @@ trait MethodSynthesis {
enterBeans(tree)
}
- def finishGetterSetter(typer: Typer, stat: Tree): List[Tree] = stat match {
- case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) =>
+
+ def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match {
+ case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) && !vd.symbol.isLazy =>
// If we don't save the annotations, they seem to wander off.
val annotations = stat.symbol.initialize.annotations
- val trees = (
- allValDefDerived(vd)
- map (acc => atPos(vd.pos.focus)(acc derive annotations))
- filterNot (_ eq EmptyTree)
+ ( allValDefDerived(vd)
+ map (acc => atPos(vd.pos.focus)(acc derive annotations))
+ filterNot (_ eq EmptyTree)
)
- // log(trees.mkString("Accessor trees:\n ", "\n ", "\n"))
- if (vd.symbol.isLazy) List(stat)
- else trees
+ case cd @ ClassDef(mods, _, _, _) if mods.isImplicit =>
+ val annotations = stat.symbol.initialize.annotations
+ // TODO: need to shuffle annotations between wrapper and class.
+ val wrapper = ImplicitClassWrapper(cd)
+ val meth = wrapper.derivedSym
+ val mdef = context.unit.synthetics(meth)
+ context.unit.synthetics -= meth
+ meth setAnnotations deriveAnnotations(annotations, MethodTargetClass, false)
+ cd.symbol setAnnotations deriveAnnotations(annotations, ClassTargetClass, true)
+ List(cd, mdef)
case _ =>
List(stat)
- }
+ }
def standardAccessors(vd: ValDef): List[DerivedFromValDef] = (
if (vd.mods.isMutable && !vd.mods.isLazy) List(Getter(vd), Setter(vd))
@@ -229,30 +262,67 @@ trait MethodSynthesis {
field ::: standardAccessors(vd) ::: beanAccessors(vd)
}
+ /** This trait assembles what's needed for synthesizing derived methods.
+ * Important: Typically, instances of this trait are created TWICE for each derived
+ * symbol; once form Namers in an enter method, and once from Typers in addDerivedTrees.
+ * So it's important that creating an instance of Derived does not have a side effect,
+ * or if it has a side effect, control that it is done only once.
+ */
trait Derived {
+
+ /** The tree from which we are deriving a synthetic member. Typically, that's
+ * given as an argument of the instance. */
+ def tree: Tree
+
+ /** The name of the method */
def name: TermName
+
+ /** The flags that are retained from the original symbol */
+
def flagsMask: Long
+
+ /** The flags that the derived symbol has in addition to those retained from
+ * the original symbol*/
def flagsExtra: Long
+
+ /** type completer for the synthetic member.
+ */
def completer(sym: Symbol): Type
+
+ /** The derived symbol. It is assumed that this symbol already exists and has been
+ * entered in the parent scope when derivedSym is called */
+ def derivedSym: Symbol
+
+ /** The definition tree of the derived symbol. */
+ def derivedTree: Tree
}
- trait DerivedFromValDef extends Derived {
- /** The declaration from which we are deriving.
- */
+
+ trait DerivedFromMemberDef extends Derived {
+ def tree: MemberDef
+ def enclClass: Symbol
+
+ // Final methods to make the rest easier to reason about.
+ final def mods = tree.mods
+ final def basisSym = tree.symbol
+ final def derivedFlags: Long = basisSym.flags & flagsMask | flagsExtra
+ }
+
+ trait DerivedFromClassDef extends DerivedFromMemberDef {
+ def tree: ClassDef
+ final def enclClass = basisSym.owner.enclClass
+ }
+
+ trait DerivedFromValDef extends DerivedFromMemberDef {
def tree: ValDef
+ final def enclClass = basisSym.enclClass
/** Which meta-annotation is associated with this kind of entity.
* Presently one of: field, getter, setter, beanGetter, beanSetter, param.
*/
def category: Symbol
- // Final methods to make the rest easier to reason about.
- final def mods = tree.mods
- final def basisSym = tree.symbol
- final def enclClass = basisSym.enclClass
-
final def completer(sym: Symbol) = namerOf(sym).accessorTypeCompleter(tree, isSetter)
final def fieldSelection = Select(This(enclClass), basisSym)
- final def derivedFlags: Long = basisSym.flags & flagsMask | flagsExtra
final def derivedMods: Modifiers = mods & flagsMask | flagsExtra mapAnnotations (_ => Nil)
def derivedSym: Symbol = tree.symbol
@@ -268,31 +338,15 @@ trait MethodSynthesis {
enterInScope(sym)
sym setInfo completer(sym)
}
- /** The annotations amongst those found on the original symbol which
- * should be propagated to this kind of accessor.
- */
- private def deriveAnnotations(initial: List[AnnotationInfo]): List[AnnotationInfo] = {
- initial filter { ann =>
- // There are no meta-annotation arguments attached to `ann`
- if (ann.metaAnnotations.isEmpty) {
- // A meta-annotation matching `annotKind` exists on `ann`'s definition.
- (ann.defaultTargets contains category) ||
- // `ann`'s definition has no meta-annotations, and `keepClean` is true.
- (ann.defaultTargets.isEmpty && keepClean)
- }
- // There are meta-annotation arguments, and one of them matches `annotKind`
- else ann.metaAnnotations exists (_ matches category)
- }
- }
private def logDerived(result: Tree): Tree = {
- debuglog("[+derived] " + ojoin(mods.defaultFlagString, basisSym.accurateKindString, basisSym.getterName.decode)
+ debuglog("[+derived] " + ojoin(mods.flagString, basisSym.accurateKindString, basisSym.getterName.decode)
+ " (" + derivedSym + ")\n " + result)
result
}
final def derive(initial: List[AnnotationInfo]): Tree = {
validate()
- derivedSym setAnnotations deriveAnnotations(initial)
+ derivedSym setAnnotations deriveAnnotations(initial, category, keepClean)
logDerived(derivedTree)
}
}
@@ -312,6 +366,25 @@ trait MethodSynthesis {
private def setterDef = DefDef(derivedSym, setterRhs)
override def derivedTree: Tree = if (setterParam == NoSymbol) EmptyTree else setterDef
}
+
+ /** A synthetic method which performs the implicit conversion implied by
+ * the declaration of an implicit class. Yet to be written.
+ */
+ case class ImplicitClassWrapper(tree: ClassDef) extends DerivedFromClassDef {
+ def completer(sym: Symbol): Type = ??? // not needed
+ def createAndEnterSymbol(): Symbol = enterSyntheticSym(derivedTree)
+ def derivedSym: Symbol = {
+ val result = enclClass.info decl name
+ assert(result != NoSymbol, "not found: "+name+" in "+enclClass+" "+enclClass.info.decls)
+ result
+ }
+ def derivedTree: DefDef =
+ factoryMeth(mods & flagsMask | flagsExtra, name, tree, symbolic = false)
+ def flagsExtra: Long = METHOD | IMPLICIT | SYNTHETIC
+ def flagsMask: Long = AccessFlags
+ def name: TermName = tree.name.toTermName
+ }
+
case class Getter(tree: ValDef) extends DerivedGetter {
def name = tree.name
def category = GetterTargetClass
@@ -342,7 +415,7 @@ trait MethodSynthesis {
case ExistentialType(_, _) => TypeTree()
case tp => TypeTree(tp)
}
- tpt setPos focusPos(derivedSym.pos)
+ tpt setPos derivedSym.pos.focus
// keep type tree of original abstract field
if (mods.isDeferred)
tpt setOriginal tree.tpt
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index c5fb13a5a9..ffd00751e0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -99,7 +99,7 @@ trait Namers extends MethodSynthesis {
owner.unsafeTypeParams foreach (paramContext.scope enter _)
newNamer(paramContext)
}
-
+
def enclosingNamerWithScope(scope: Scope) = {
var cx = context
while (cx != NoContext && cx.scope != scope) cx = cx.outer
@@ -315,9 +315,10 @@ trait Namers extends MethodSynthesis {
case DefDef(_, _, _, _, _, _) => owner.newMethod(name.toTermName, pos, flags)
case ClassDef(_, _, _, _) => owner.newClassSymbol(name.toTypeName, pos, flags)
case ModuleDef(_, _, _) => owner.newModule(name, pos, flags)
- case ValDef(_, _, _, _) if isParameter => owner.newValueParameter(name, pos, flags)
case PackageDef(pid, _) => createPackageSymbol(pos, pid)
- case ValDef(_, _, _, _) => owner.newValue(name, pos, flags)
+ case ValDef(_, _, _, _) =>
+ if (isParameter) owner.newValueParameter(name, pos, flags)
+ else owner.newValue(name, pos, flags)
}
}
private def createFieldSymbol(tree: ValDef): TermSymbol =
@@ -528,7 +529,7 @@ trait Namers extends MethodSynthesis {
def enterCopyMethodOrGetter(tree: Tree, tparams: List[TypeDef]): Symbol = {
val sym = tree.symbol
val lazyType = completerOf(tree, tparams)
- def completeCopyFirst = sym.isSynthetic && (!sym.hasDefaultFlag || sym.owner.info.member(nme.copy).isSynthetic)
+ def completeCopyFirst = sym.isSynthetic && (!sym.hasDefault || sym.owner.info.member(nme.copy).isSynthetic)
def completeCopyMethod(clazz: Symbol) {
// the 'copy' method of case classes needs a special type completer to make
// bug0054.scala (and others) work. the copy method has to take exactly the same
@@ -623,11 +624,6 @@ trait Namers extends MethodSynthesis {
enterCopyMethodOrGetter(tree, tparams)
else
sym setInfo completerOf(tree, tparams)
-
- if (mods hasFlag MACRO) {
- if (!(sym.owner.isClass && sym.owner.isStatic))
- context.error(tree.pos, "macro definition must appear in globally accessible class")
- }
}
def enterClassDef(tree: ClassDef) {
@@ -650,14 +646,6 @@ trait Namers extends MethodSynthesis {
val m = ensureCompanionObject(tree)
classAndNamerOfModule(m) = (tree, null)
}
- val hasMacro = impl.body exists {
- case DefDef(mods, _, _, _, _, _) => mods hasFlag MACRO
- case _ => false
- }
- if (hasMacro) {
- val m = ensureCompanionObject(tree)
- classOfModuleClass(m.moduleClass) = new WeakReference(tree)
- }
val owner = tree.symbol.owner
if (owner.isPackageObjectClass) {
context.unit.warning(tree.pos,
@@ -665,6 +653,12 @@ trait Namers extends MethodSynthesis {
"If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead."
)
}
+
+ // Suggested location only.
+ if (mods.isImplicit) {
+ log("enter implicit wrapper "+tree+", owner = "+owner)
+ enterImplicitWrapper(tree)
+ }
}
// this logic is needed in case typer was interrupted half
@@ -679,7 +673,7 @@ trait Namers extends MethodSynthesis {
val acc = sym.lazyAccessor
if (acc != NoSymbol) enterIfNotThere(acc)
}
- defaultParametersOfMethod(sym) foreach enterIfNotThere
+ defaultParametersOfMethod(sym) foreach { symRef => enterIfNotThere(symRef()) }
}
this.context
}
@@ -788,10 +782,7 @@ trait Namers extends MethodSynthesis {
val tpe1 = dropRepeatedParamType(tpe.deconst)
val tpe2 = tpe1.widen
- // This infers Foo.type instead of "object Foo"
- // See Infer#adjustTypeArgs for the polymorphic case.
- if (tpe.typeSymbolDirect.isModuleClass) tpe1
- else if (sym.isVariable || sym.isMethod && !sym.hasAccessorFlag)
+ if (sym.isVariable || sym.isMethod && !sym.hasAccessorFlag)
if (tpe2 <:< pt) tpe2 else tpe1
else if (isHidden(tpe)) tpe2
// In an attempt to make pattern matches involving method local vals
@@ -807,7 +798,9 @@ trait Namers extends MethodSynthesis {
*/
private def assignTypeToTree(tree: ValOrDefDef, defnTyper: Typer, pt: Type): Type = {
// compute result type from rhs
- val typedBody = defnTyper.computeType(tree.rhs, pt)
+ val typedBody =
+ if (tree.symbol.isTermMacro) defnTyper.computeMacroDefType(tree, pt)
+ else defnTyper.computeType(tree.rhs, pt)
val sym = if (owner.isMethod) owner else tree.symbol
val typedDefn = widenIfNecessary(sym, typedBody, pt)
assignTypeToTree(tree, typedDefn)
@@ -829,19 +822,17 @@ trait Namers extends MethodSynthesis {
if (!hasType)
tpt defineType NoType
- if (hasType || hasName) {
- owner.typeOfThis =
- if (hasType) selfTypeCompleter(tpt)
- else owner.tpe
- }
val sym = (
- if (hasType) owner.thisSym setPos self.pos
- else if (hasName) owner.thisSym
- else owner.newThisSym(self.pos) setInfo owner.tpe
+ if (hasType || hasName) {
+ owner.typeOfThis = if (hasType) selfTypeCompleter(tpt) else owner.tpe
+ val selfSym = owner.thisSym setPos self.pos
+ if (hasName) selfSym setName name else selfSym
+ }
+ else {
+ val symName = if (name != nme.WILDCARD) name else nme.this_
+ owner.newThisSym(symName, owner.pos) setInfo owner.tpe
+ }
)
- if (hasName)
- sym.name = name
-
self.symbol = context.scope enter sym
}
@@ -871,10 +862,8 @@ trait Namers extends MethodSynthesis {
Namers.this.classOfModuleClass get clazz foreach { cdefRef =>
val cdef = cdefRef()
if (cdef.mods.isCase) addApplyUnapply(cdef, templateNamer)
- if (settings.Xmacros.value) addMacroMethods(cdef.impl, templateNamer)
classOfModuleClass -= clazz
}
- if (settings.Xmacros.value) addMacroMethods(templ, templateNamer)
}
// add the copy method to case classes; this needs to be done here, not in SyntheticMethods, because
@@ -1029,12 +1018,20 @@ trait Namers extends MethodSynthesis {
}
addDefaultGetters(meth, vparamss, tparams, overriddenSymbol)
+ // macro defs need to be typechecked in advance
+ // because @macroImpl annotation only gets assigned during typechecking
+ // otherwise we might find ourselves in the situation when we specified -Xmacro-fallback-classpath
+ // but macros still don't expand
+ // that might happen because macro def doesn't have its link a macro impl yet
+ if (ddef.symbol.isTermMacro) {
+ val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol))
+ typer.computeMacroDefType(ddef, pt)
+ }
+
thisMethodType({
val rt = (
if (!tpt.isEmpty) {
typer.typedType(tpt).tpe
- } else if (meth.isMacro) {
- assignTypeToTree(ddef, AnyClass.tpe)
} else {
// replace deSkolemized symbols with skolemized ones
// (for resultPt computed by looking at overridden symbol, right?)
@@ -1043,7 +1040,7 @@ trait Namers extends MethodSynthesis {
}
)
// #2382: return type of default getters are always @uncheckedVariance
- if (meth.hasDefaultFlag)
+ if (meth.hasDefault)
rt.withAnnotation(AnnotationInfo(uncheckedVarianceClass.tpe, List(), List()))
else rt
})
@@ -1093,8 +1090,8 @@ trait Namers extends MethodSynthesis {
for (vparam <- vparams) {
val sym = vparam.symbol
// true if the corresponding parameter of the base class has a default argument
- val baseHasDefault = overrides && baseParams.head.hasDefaultFlag
- if (sym.hasDefaultFlag) {
+ val baseHasDefault = overrides && baseParams.head.hasDefault
+ if (sym.hasDefault) {
// generate a default getter for that argument
val oflag = if (baseHasDefault) OVERRIDE else 0
val name = nme.defaultGetterName(meth.name, posCounter)
@@ -1161,7 +1158,7 @@ trait Namers extends MethodSynthesis {
// 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.
- defaultParametersOfMethod(meth) += default
+ defaultParametersOfMethod(meth) += new WeakReference(default)
}
} else if (baseHasDefault) {
// the parameter does not have a default itself, but the
@@ -1360,7 +1357,7 @@ trait Namers extends MethodSynthesis {
}
}
private val logDefinition = new LogTransitions[Symbol](
- sym => "[define] >> " + sym.defaultFlagString + " " + sym.fullLocationString,
+ sym => "[define] >> " + sym.flagString + " " + sym.fullLocationString,
sym => "[define] << " + sym
)
private def logAndValidate(sym: Symbol)(body: => Unit) {
@@ -1404,10 +1401,10 @@ trait Namers extends MethodSynthesis {
if (sym.isImplicit) {
if (sym.isConstructor)
fail(ImplicitConstr)
- if (!sym.isTerm)
- fail(ImplicitNotTerm)
+ if (!(sym.isTerm || (sym.isClass && !sym.isTrait)))
+ fail(ImplicitNotTermOrClass)
if (sym.owner.isPackageClass)
- fail(ImplicitTopObject)
+ fail(ImplicitAtToplevel)
}
if (sym.isClass) {
if (sym.isAnyOverride && !sym.hasFlag(TRAIT))
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index c621497618..3d9fc67389 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -8,6 +8,7 @@ package typechecker
import symtab.Flags._
import scala.collection.mutable
+import scala.ref.WeakReference
/**
* @author Lukas Rytz
@@ -20,7 +21,7 @@ trait NamesDefaults { self: Analyzer =>
import NamesDefaultsErrorsGen._
val defaultParametersOfMethod =
- perRunCaches.newWeakMap[Symbol, Set[Symbol]]() withDefaultValue Set()
+ perRunCaches.newWeakMap[Symbol, Set[WeakReference[Symbol]]]() withDefaultValue Set()
case class NamedApplyInfo(
qual: Option[Tree],
@@ -38,16 +39,16 @@ trait NamesDefaults { self: Analyzer =>
def isNamed(arg: Tree) = nameOf(arg).isDefined
/** @param pos maps indices from old to new */
- def reorderArgs[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = {
+ def reorderArgs[T: ArrayTag](args: List[T], pos: Int => Int): List[T] = {
val res = new Array[T](args.length)
foreachWithIndex(args)((arg, index) => res(pos(index)) = arg)
res.toList
}
/** @param pos maps indices from new to old (!) */
- def reorderArgsInv[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = {
+ def reorderArgsInv[T: ArrayTag](args: List[T], pos: Int => Int): List[T] = {
val argsArray = args.toArray
- argsArray.indices map (i => argsArray(pos(i))) toList
+ (argsArray.indices map (i => argsArray(pos(i)))).toList
}
/** returns `true` if every element is equal to its index */
@@ -377,7 +378,7 @@ trait NamesDefaults { self: Analyzer =>
pos: util.Position, context: Context): (List[Tree], List[Symbol]) = {
if (givenArgs.length < params.length) {
val (missing, positional) = missingParams(givenArgs, params)
- if (missing forall (_.hasDefaultFlag)) {
+ if (missing forall (_.hasDefault)) {
val defaultArgs = missing flatMap (p => {
val defGetter = defaultGetter(p, context)
// TODO #3649 can create spurious errors when companion object is gone (because it becomes unlinked from scope)
@@ -399,7 +400,7 @@ trait NamesDefaults { self: Analyzer =>
}
})
(givenArgs ::: defaultArgs, Nil)
- } else (givenArgs, missing filterNot (_.hasDefaultFlag))
+ } else (givenArgs, missing filterNot (_.hasDefault))
} else (givenArgs, Nil)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index de7f03dc62..e5dc8e9ca9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -8,6 +8,7 @@ package typechecker
import symtab._
import Flags.{MUTABLE, METHOD, LABEL, SYNTHETIC}
+import language.postfixOps
/** Translate pattern matching into method calls (these methods form a zero-plus monad), similar in spirit to how for-comprehensions are compiled.
*
@@ -21,7 +22,7 @@ import Flags.{MUTABLE, METHOD, LABEL, SYNTHETIC}
* - Array patterns
* - implement spec more closely (see TODO's)
* - DCE
- * - use manifests for type testing
+ * - use TypeTags for type testing
*
* (longer-term) TODO:
* - user-defined unapplyProd
@@ -32,6 +33,8 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
import global._
import definitions._
+ val SYNTH_CASE = Flags.CASE | SYNTHETIC
+
object vpmName {
val one = newTermName("one")
val drop = newTermName("drop")
@@ -43,7 +46,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
val outer = newTermName("<outer>")
val runOrElse = newTermName("runOrElse")
val zero = newTermName("zero")
- val _match = newTermName("__match") // don't call it __match, since that will trigger virtual pattern matching...
+ val _match = newTermName("__match") // don't call the val __match, since that will trigger virtual pattern matching...
def counted(str: String, i: Int) = newTermName(str+i)
}
@@ -116,6 +119,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
trait MatchTranslation extends MatchMonadInterface { self: TreeMakers with CodegenCore =>
import typer.{typed, context, silent, reallyExists}
+ // import typer.infer.containsUnchecked
/** Implement a pattern match by turning its cases (including the implicit failure case)
* into the corresponding (monadic) extractors, and combining them with the `orElse` combinator.
@@ -128,12 +132,12 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
* this could probably optimized... (but note that the matchStrategy must be solved for each nested patternmatch)
*/
def translateMatch(scrut: Tree, cases: List[CaseDef], pt: Type, scrutType: Type, matchFailGenOverride: Option[Tree => Tree] = None): Tree = {
- // we don't transform after typers
- // (that would require much more sophistication when generating trees,
+ // we don't transform after uncurry
+ // (that would require more sophistication when generating trees,
// and the only place that emits Matches after typers is for exception handling anyway)
- assert(phase.id <= currentRun.typerPhase.id, phase)
-
- val scrutSym = freshSym(scrut.pos, pureType(scrutType)) setFlag (Flags.CASE | SYNTHETIC) // the flags allow us to detect generated matches by looking at the scrutinee's symbol (needed to avoid recursing endlessly on generated switches)
+ if(phase.id >= currentRun.uncurryPhase.id) debugwarn("running translateMatch at "+ phase +" on "+ scrut +" match "+ cases)
+ // println("translating "+ cases.mkString("{", "\n", "}"))
+ val scrutSym = freshSym(scrut.pos, pureType(scrutType)) setFlag SYNTH_CASE
// pt = Any* occurs when compiling test/files/pos/annotDepMethType.scala with -Xexperimental
combineCases(scrut, scrutSym, cases map translateCase(scrutSym, pt), pt, matchOwner, matchFailGenOverride)
}
@@ -147,7 +151,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
// if they're already simple enough to be handled by the back-end, we're done
if (caseDefs forall treeInfo.isCatchCase) caseDefs
else {
- val switch = {
+ val swatches = { // switch-catches
val bindersAndCases = caseDefs map { caseDef =>
// generate a fresh symbol for each case, hoping we'll end up emitting a type-switch (we don't have a global scrut there)
// if we fail to emit a fine-grained switch, have to do translateCase again with a single scrutSym (TODO: uniformize substitution on treemakers so we can avoid this)
@@ -155,10 +159,12 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
(caseScrutSym, propagateSubstitution(translateCase(caseScrutSym, pt)(caseDef), EmptySubstitution))
}
- (emitTypeSwitch(bindersAndCases, pt) map (_.map(fixerUpper(matchOwner, pos).apply(_).asInstanceOf[CaseDef])))
+ for(cases <- emitTypeSwitch(bindersAndCases, pt).toList;
+ if cases forall treeInfo.isCatchCase; // must check again, since it's not guaranteed -- TODO: can we eliminate this? e.g., a type test could test for a trait or a non-trivial prefix, which are not handled by the back-end
+ cse <- cases) yield fixerUpper(matchOwner, pos)(cse).asInstanceOf[CaseDef]
}
- val catches = switch getOrElse {
+ val catches = if (swatches.nonEmpty) swatches else {
val scrutSym = freshSym(pos, pureType(ThrowableClass.tpe))
val casesNoSubstOnly = caseDefs map { caseDef => (propagateSubstitution(translateCase(scrutSym, pt)(caseDef), EmptySubstitution))}
@@ -254,10 +260,11 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
* @arg patBinder symbol used to refer to the result of the previous pattern's extractor (will later be replaced by the outer tree with the correct tree to refer to that patterns result)
*/
def unapply(tree: Tree): Option[(Symbol, Type)] = tree match {
- case Bound(subpatBinder, typed@Typed(expr, tpt)) => Some((subpatBinder, typed.tpe))
- case Bind(_, typed@Typed(expr, tpt)) => Some((patBinder, typed.tpe))
- case Typed(expr, tpt) => Some((patBinder, tree.tpe))
- case _ => None
+ // the Ident subpattern can be ignored, subpatBinder or patBinder tell us all we need to know about it
+ case Bound(subpatBinder, typed@Typed(Ident(_), tpt)) if typed.tpe ne null => Some((subpatBinder, typed.tpe))
+ case Bind(_, typed@Typed(Ident(_), tpt)) if typed.tpe ne null => Some((patBinder, typed.tpe))
+ case Typed(Ident(_), tpt) if tree.tpe ne null => Some((patBinder, tree.tpe))
+ case _ => None
}
}
@@ -815,13 +822,35 @@ class Foo(x: Other) { x._1 } // no error in this order
cond
}
- // TODO: also need to test when erasing pt loses crucial information (and if we can recover it using a manifest)
- def needsTypeTest(tp: Type, pt: Type) = !(tp <:< pt)
- private def typeTest(binder: Symbol, pt: Type) = maybeWithOuterCheck(binder, pt)(codegen._isInstanceOf(binder, pt))
+ // containsUnchecked: also need to test when erasing pt loses crucial information (maybe we can recover it using a TypeTag)
+ def needsTypeTest(tp: Type, pt: Type): Boolean = !(tp <:< pt) // || containsUnchecked(pt)
+ // TODO: try to find the TypeTag for the binder's type and the expected type, and if they exists,
+ // check that the TypeTag of the binder's type conforms to the TypeTag of the expected type
+ private def typeTest(binderToTest: Symbol, expectedTp: Type, disableOuterCheck: Boolean = false, dynamic: Boolean = false): Tree = { import CODE._
+ // def coreTest =
+ if (disableOuterCheck) codegen._isInstanceOf(binderToTest, expectedTp) else maybeWithOuterCheck(binderToTest, expectedTp)(codegen._isInstanceOf(binderToTest, expectedTp))
+ // [Eugene to Adriaan] use `resolveErasureTag` instead of `findManifest`. please, provide a meaningful position
+ // if (opt.experimental && containsUnchecked(expectedTp)) {
+ // if (dynamic) {
+ // val expectedTpTagTree = findManifest(expectedTp, true)
+ // if (!expectedTpTagTree.isEmpty)
+ // ((expectedTpTagTree DOT "erasure".toTermName) DOT "isAssignableFrom".toTermName)(REF(binderToTest) DOT nme.getClass_)
+ // else
+ // coreTest
+ // } else {
+ // val expectedTpTagTree = findManifest(expectedTp, true)
+ // val binderTpTagTree = findManifest(binderToTest.info, true)
+ // if(!(expectedTpTagTree.isEmpty || binderTpTagTree.isEmpty))
+ // coreTest AND (binderTpTagTree DOT nme.CONFORMS)(expectedTpTagTree)
+ // else
+ // coreTest
+ // }
+ // } else coreTest
+ }
// need to substitute since binder may be used outside of the next extractor call (say, in the body of the case)
case class TypeTestTreeMaker(prevBinder: Symbol, nextBinderTp: Type, pos: Position) extends CondTreeMaker {
- val cond = typeTest(prevBinder, nextBinderTp)
+ val cond = typeTest(prevBinder, nextBinderTp, dynamic = true)
val res = codegen._asInstanceOf(prevBinder, nextBinderTp)
override def toString = "TT"+(prevBinder, nextBinderTp)
}
@@ -861,7 +890,7 @@ class Foo(x: Other) { x._1 } // no error in this order
// TODO: `null match { x : T }` will yield a check that (indirectly) tests whether `null ne null`
// don't bother (so that we don't end up with the warning "comparing values of types Null and Null using `ne' will always yield false")
def genEqualsAndInstanceOf(sym: Symbol): Tree
- = codegen._equals(REF(sym), patBinder) AND codegen._isInstanceOf(patBinder, pt.widen)
+ = codegen._equals(REF(sym), patBinder) AND typeTest(patBinder, pt.widen, disableOuterCheck = true)
def isRefTp(tp: Type) = tp <:< AnyRefClass.tpe
@@ -869,7 +898,7 @@ class Foo(x: Other) { x._1 } // no error in this order
def isMatchUnlessNull = isRefTp(pt) && !needsTypeTest(patBinderTp, pt)
// TODO: [SPEC] type test for Array
- // TODO: use manifests to improve tests (for erased types we can do better when we have a manifest)
+ // TODO: use TypeTags to improve tests (for erased types we can do better when we have a TypeTag)
pt match {
case SingleType(_, sym) /*this implies sym.isStable*/ => genEqualsAndInstanceOf(sym) // TODO: [SPEC] the spec requires `eq` instead of `==` here
case ThisType(sym) if sym.isModule => genEqualsAndInstanceOf(sym) // must use == to support e.g. List() == Nil
@@ -914,10 +943,10 @@ class Foo(x: Other) { x._1 } // no error in this order
// one alternative may still generate multiple trees (e.g., an extractor call + equality test)
// (for now,) alternatives may not bind variables (except wildcards), so we don't care about the final substitution built internally by makeTreeMakers
val combinedAlts = altss map (altTreeMakers =>
- ((casegen: Casegen) => combineExtractors(altTreeMakers :+ TrivialTreeMaker(casegen.one(TRUE)))(casegen))
+ ((casegen: Casegen) => combineExtractors(altTreeMakers :+ TrivialTreeMaker(casegen.one(TRUE_typed)))(casegen))
)
- val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanClass.tpe)(combinedAlts, Some(x => FALSE))
+ val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanClass.tpe)(combinedAlts, Some(x => FALSE_typed))
codegenAlt.ifThenElseZero(findAltMatcher, substitution(next))
}
}
@@ -958,6 +987,7 @@ class Foo(x: Other) { x._1 } // no error in this order
fixerUpper(owner, scrut.pos){
val ptDefined = if (isFullyDefined(pt)) pt else NoType
def matchFailGen = (matchFailGenOverride orElse Some(CODE.MATCHERROR(_: Tree)))
+ // println("combining cases: "+ (casesNoSubstOnly.map(_.mkString(" >> ")).mkString("{", "\n", "}")))
emitSwitch(scrut, scrutSym, casesNoSubstOnly, pt, matchFailGenOverride).getOrElse{
if (casesNoSubstOnly nonEmpty) {
@@ -1037,7 +1067,7 @@ class Foo(x: Other) { x._1 } // no error in this order
// assert(owner ne null); assert(owner ne NoSymbol)
def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x") =
- NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo /*repackExistential*/(tp)
+ NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo tp
// codegen relevant to the structure of the translation (how extractors are combined)
trait AbsCodegen {
@@ -1078,22 +1108,16 @@ class Foo(x: Other) { x._1 } // no error in this order
def _equals(checker: Tree, binder: Symbol): Tree = checker MEMBER_== REF(binder) // NOTE: checker must be the target of the ==, that's the patmat semantics for ya
def and(a: Tree, b: Tree): Tree = a AND b
- // the force is needed mainly to deal with the GADT typing hack (we can't detect it otherwise as tp nor pt need contain an abstract type, we're just casting wildly)
- def _asInstanceOf(t: Tree, tp: Type, force: Boolean = false): Tree = { val tpX = /*repackExistential*/(tp)
- if (!force && (t.tpe ne NoType) && t.isTyped && typesConform(t.tpe, tpX)) t //{ println("warning: emitted redundant asInstanceOf: "+(t, t.tpe, tp)); t } //.setType(tpX)
- else gen.mkAsInstanceOf(t, tpX, true, false)
- }
+ // drop annotations generated by CPS plugin etc, since its annotationchecker rejects T @cps[U] <: Any
+ // let's assume for now annotations don't affect casts, drop them there, and bring them back using the outer Typed tree
+ private def mkCast(t: Tree, tp: Type) =
+ Typed(gen.mkAsInstanceOf(t, tp.withoutAnnotations, true, false), TypeTree() setType tp)
- def _isInstanceOf(b: Symbol, tp: Type): Tree = gen.mkIsInstanceOf(REF(b), /*repackExistential*/(tp), true, false)
- // { val tpX = /*repackExistential*/(tp)
+ // the force is needed mainly to deal with the GADT typing hack (we can't detect it otherwise as tp nor pt need contain an abstract type, we're just casting wildly)
+ def _asInstanceOf(t: Tree, tp: Type, force: Boolean = false): Tree = if (!force && (t.tpe ne NoType) && t.isTyped && typesConform(t.tpe, tp)) t else mkCast(t, tp)
+ def _asInstanceOf(b: Symbol, tp: Type): Tree = if (typesConform(b.info, tp)) REF(b) else mkCast(REF(b), tp)
+ def _isInstanceOf(b: Symbol, tp: Type): Tree = gen.mkIsInstanceOf(REF(b), tp.withoutAnnotations, true, false)
// if (typesConform(b.info, tpX)) { println("warning: emitted spurious isInstanceOf: "+(b, tp)); TRUE }
- // else gen.mkIsInstanceOf(REF(b), tpX, true, false)
- // }
-
- def _asInstanceOf(b: Symbol, tp: Type): Tree = { val tpX = /*repackExistential*/(tp)
- if (typesConform(b.info, tpX)) REF(b) //{ println("warning: emitted redundant asInstanceOf: "+(b, b.info, tp)); REF(b) } //.setType(tpX)
- else gen.mkAsInstanceOf(REF(b), tpX, true, false)
- }
// duplicated out of frustration with cast generation
def mkZero(tp: Type): Tree = {
@@ -1117,7 +1141,7 @@ class Foo(x: Other) { x._1 } // no error in this order
val matchStrategy: Tree
def inMatchMonad(tp: Type): Type = appliedType(oneSig, List(tp)).finalResultType
- def pureType(tp: Type): Type = appliedType(oneSig, List(tp)).paramTypes.head
+ def pureType(tp: Type): Type = appliedType(oneSig, List(tp)).paramTypes.headOption getOrElse NoType // fail gracefully (otherwise we get crashes)
protected def matchMonadSym = oneSig.finalResultType.typeSymbol
import CODE._
@@ -1549,7 +1573,7 @@ class Foo(x: Other) { x._1 } // no error in this order
// TODO: if patterns allow switch but the type of the scrutinee doesn't, cast (type-test) the scrutinee to the corresponding switchable type and switch on the result
if (regularSwitchMaker.switchableTpe(scrutSym.tpe)) {
val caseDefsWithDefault = regularSwitchMaker(cases map {c => (scrutSym, c)}, pt)
- if (caseDefsWithDefault isEmpty) None
+ if (caseDefsWithDefault.length <= 2) None // not worth emitting a switch... also, the optimizer has trouble digesting tiny switches, apparently, so let's be nice and not generate them
else {
// match on scrutSym -- converted to an int if necessary -- not on scrut directly (to avoid duplicating scrut)
val scrutToInt: Tree =
@@ -1557,7 +1581,7 @@ class Foo(x: Other) { x._1 } // no error in this order
else (REF(scrutSym) DOT (nme.toInt))
Some(BLOCK(
VAL(scrutSym) === scrut,
- Match(scrutToInt, caseDefsWithDefault)
+ Match(gen.mkSynthSwitchSelector(scrutToInt), caseDefsWithDefault) // add switch annotation
))
}
} else None
@@ -1630,22 +1654,26 @@ class Foo(x: Other) { x._1 } // no error in this order
* if keepGoing is false, the result Some(x) of the naive translation is encoded as matchRes == x
*/
def matcher(scrut: Tree, scrutSym: Symbol, restpe: Type)(cases: List[Casegen => Tree], matchFailGen: Option[Tree => Tree]): Tree = {
- val matchEnd = NoSymbol.newLabel(freshName("matchEnd"), NoPosition) setFlag (SYNTHETIC | Flags.CASE)
- val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe
+ val matchEnd = NoSymbol.newLabel(freshName("matchEnd"), NoPosition) setFlag SYNTH_CASE
+ val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe.withoutAnnotations //
matchEnd setInfo MethodType(List(matchRes), restpe)
- def newCaseSym = NoSymbol.newLabel(freshName("case"), NoPosition) setInfo MethodType(Nil, restpe) setFlag (SYNTHETIC | Flags.CASE)
+ def newCaseSym = NoSymbol.newLabel(freshName("case"), NoPosition) setInfo MethodType(Nil, restpe) setFlag SYNTH_CASE
var nextCase = newCaseSym
def caseDef(mkCase: Casegen => Tree): Tree = {
val currCase = nextCase
nextCase = newCaseSym
- val casegen = new OptimizedCasegen(matchEnd, nextCase)
+ val casegen = new OptimizedCasegen(matchEnd, nextCase, restpe)
LabelDef(currCase, Nil, mkCase(casegen))
}
def catchAll = matchFailGen map { matchFailGen =>
val scrutRef = if(scrutSym ne NoSymbol) REF(scrutSym) else EmptyTree // for alternatives
- LabelDef(nextCase, Nil, matchEnd APPLY (matchFailGen(scrutRef))) // need to jump to matchEnd with result generated by matchFailGen (could be `FALSE` for isDefinedAt)
+ // must jump to matchEnd, use result generated by matchFailGen (could be `FALSE` for isDefinedAt)
+ LabelDef(nextCase, Nil, matchEnd APPLY (matchFailGen(scrutRef)))
+ // don't cast the arg to matchEnd when using PartialFun synth in uncurry, since it won't detect the throw (see gen.withDefaultCase)
+ // the cast is necessary when using typedMatchAnonFun-style PartialFun synth:
+ // (_asInstanceOf(matchFailGen(scrutRef), restpe))
} toList
// catchAll.isEmpty iff no synthetic default case needed (the (last) user-defined case is a default)
// if the last user-defined case is a default, it will never jump to the next case; it will go immediately to matchEnd
@@ -1663,14 +1691,14 @@ class Foo(x: Other) { x._1 } // no error in this order
)
}
- class OptimizedCasegen(matchEnd: Symbol, nextCase: Symbol) extends CommonCodegen with Casegen {
+ class OptimizedCasegen(matchEnd: Symbol, nextCase: Symbol, restpe: Type) extends CommonCodegen with Casegen {
def matcher(scrut: Tree, scrutSym: Symbol, restpe: Type)(cases: List[Casegen => Tree], matchFailGen: Option[Tree => Tree]): Tree =
optimizedCodegen.matcher(scrut, scrutSym, restpe)(cases, matchFailGen)
// only used to wrap the RHS of a body
// res: T
// returns MatchMonad[T]
- def one(res: Tree): Tree = matchEnd APPLY (res)
+ def one(res: Tree): Tree = matchEnd APPLY (_asInstanceOf(res, restpe)) // need cast for GADT magic
protected def zero: Tree = nextCase APPLY ()
// prev: MatchMonad[T]
@@ -1709,7 +1737,7 @@ class Foo(x: Other) { x._1 } // no error in this order
def flatMapCondStored(cond: Tree, condSym: Symbol, res: Tree, nextBinder: Symbol, next: Tree): Tree =
ifThenElseZero(cond, BLOCK(
- condSym === TRUE,
+ condSym === TRUE_typed,
nextBinder === res,
next
))
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index d98d248231..21336c2375 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -10,6 +10,7 @@ import symtab.Flags._
import collection.{ mutable, immutable }
import transform.InfoTransform
import scala.collection.mutable.ListBuffer
+import language.postfixOps
/** <p>
* Post-attribution checking and transformation.
@@ -123,7 +124,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
defaultMethodNames.distinct foreach { name =>
val methods = clazz.info.findMember(name, 0L, METHOD, false).alternatives
- val haveDefaults = methods filter (sym => sym.hasParamWhich(_.hasDefaultFlag) && !nme.isProtectedAccessorName(sym.name))
+ val haveDefaults = methods filter (sym => sym.hasParamWhich(_.hasDefault) && !nme.isProtectedAccessorName(sym.name))
if (haveDefaults.lengthCompare(1) > 0) {
val owners = haveDefaults map (_.owner)
@@ -227,6 +228,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
* 1.8.1 M's type is a subtype of O's type, or
* 1.8.2 M is of type []S, O is of type ()T and S <: T, or
* 1.8.3 M is of type ()S, O is of type []T and S <: T, or
+ * 1.9. If M is a macro def, O cannot be deferred.
+ * 1.10. If M is not a macro def, O cannot be a macro def.
* 2. Check that only abstract classes have deferred members
* 3. Check that concrete classes do not have deferred definitions
* that are not implemented in a subclass.
@@ -267,6 +270,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
sym1.locationString +
(if (sym1.isAliasType) ", which equals "+self.memberInfo(sym1)
else if (sym1.isAbstractType) " with bounds"+self.memberInfo(sym1)
+ else if (sym1.isModule) ""
else if (sym1.isTerm) " of type "+self.memberInfo(sym1)
else "")
else "")
@@ -355,7 +359,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
/** Is the intersection between given two lists of overridden symbols empty?
*/
def intersectionIsEmpty(syms1: List[Symbol], syms2: List[Symbol]) =
- !(syms1 exists (syms2 contains))
+ !(syms1 exists (syms2 contains _))
if (typesOnly) checkOverrideTypes()
else {
@@ -380,7 +384,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
overrideError("cannot be used here - class definitions cannot be overridden");
} else if (!other.isDeferred && member.isClass) {
overrideError("cannot be used here - classes can only override abstract types");
- } else if (other.isFinal) { // (1.2)
+ } else if (other.isEffectivelyFinal) { // (1.2)
overrideError("cannot override final member");
// synthetic exclusion needed for (at least) default getters.
} else if (!other.isDeferred && !member.isAnyOverride && !member.isSynthetic) {
@@ -394,9 +398,14 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
overrideError("needs `override' modifier")
} else if (other.isAbstractOverride && other.isIncompleteIn(clazz) && !member.isAbstractOverride) {
overrideError("needs `abstract override' modifiers")
- } else if (member.isAnyOverride && (other hasFlag ACCESSOR) && other.accessed.isVariable && !other.accessed.isLazy) {
- overrideError("cannot override a mutable variable")
- } else if (member.isAnyOverride &&
+ }
+ else if (member.isAnyOverride && (other hasFlag ACCESSOR) && other.accessed.isVariable && !other.accessed.isLazy) {
+ // !?! this is not covered by the spec. We need to resolve this either by changing the spec or removing the test here.
+ // !!! is there a !?! convention? I'm !!!ing this to make sure it turns up on my searches.
+ if (!settings.overrideVars.value)
+ overrideError("cannot override a mutable variable")
+ }
+ else if (member.isAnyOverride &&
!(member.owner.thisType.baseClasses exists (_ isSubClass other.owner)) &&
!member.isDeferred && !other.isDeferred &&
intersectionIsEmpty(member.extendedOverriddenSymbols, other.extendedOverriddenSymbols)) {
@@ -410,6 +419,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
} else if (other.isValue && other.isLazy && !other.isSourceMethod && !other.isDeferred &&
member.isValue && !member.isLazy) {
overrideError("must be declared lazy to override a concrete lazy value")
+ } else if (other.isDeferred && member.isTermMacro) { // (1.9)
+ overrideError("cannot override an abstract method")
+ } else if (other.isTermMacro && !member.isTermMacro) { // (1.10)
+ overrideError("cannot override a macro")
} else {
checkOverrideTypes()
if (settings.warnNullaryOverride.value) {
@@ -656,7 +669,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
}
// Check the remainder for invalid absoverride.
- for (member <- rest ; if ((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(clazz))) {
+ for (member <- rest ; if (member.isAbstractOverride && member.isIncompleteIn(clazz))) {
val other = member.superSymbol(clazz)
val explanation =
if (other != NoSymbol) " and overrides incomplete superclass member " + infoString(other)
@@ -750,11 +763,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
// 4. Check that every defined member with an `override` modifier overrides some other member.
for (member <- clazz.info.decls)
- if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) &&
- !(clazz.thisType.baseClasses exists (hasMatchingSym(_, member)))) {
+ if (member.isAnyOverride && !(clazz.thisType.baseClasses exists (hasMatchingSym(_, member)))) {
// for (bc <- clazz.info.baseClasses.tail) Console.println("" + bc + " has " + bc.info.decl(member.name) + ":" + bc.info.decl(member.name).tpe);//DEBUG
unit.error(member.pos, member.toString() + " overrides nothing");
- member resetFlag OVERRIDE
+ member resetFlag (OVERRIDE | ABSOVERRIDE) // Any Override
}
}
@@ -945,17 +957,20 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
override def traverse(tree: Tree) {
tree match {
- case ClassDef(_, _, _, _) |
- TypeDef(_, _, _, _) =>
+ case ClassDef(_, _, _, _) | TypeDef(_, _, _, _) =>
validateVariance(tree.symbol)
super.traverse(tree)
// ModuleDefs need not be considered because they have been eliminated already
case ValDef(_, _, _, _) =>
- validateVariance(tree.symbol)
+ if (!tree.symbol.hasLocalFlag)
+ validateVariance(tree.symbol)
case DefDef(_, _, tparams, vparamss, _, _) =>
- validateVariance(tree.symbol)
- traverseTrees(tparams)
- traverseTreess(vparamss)
+ // No variance check for object-private/protected methods/values.
+ if (!tree.symbol.hasLocalFlag) {
+ validateVariance(tree.symbol)
+ traverseTrees(tparams)
+ traverseTreess(vparamss)
+ }
case Template(_, _, _) =>
super.traverse(tree)
case _ =>
@@ -1045,11 +1060,16 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
/** Symbols which limit the warnings we can issue since they may be value types */
val isMaybeValue = Set(AnyClass, AnyRefClass, AnyValClass, ObjectClass, ComparableClass, JavaSerializableClass)
- // Whether def equals(other: Any) is overridden or synthetic
+ // Whether def equals(other: Any) has known behavior: it is the default
+ // inherited from java.lang.Object, or it is a synthetically generated
+ // case equals. TODO - more cases are warnable if the target is a synthetic
+ // equals.
def isUsingWarnableEquals = {
val m = receiver.info.member(nme.equals_)
- (m == Object_equals) || (m == Any_equals) || (m.isSynthetic && m.owner.isCase)
+ ((m == Object_equals) || (m == Any_equals) || isMethodCaseEquals(m))
}
+ def isMethodCaseEquals(m: Symbol) = m.isSynthetic && m.owner.isCase
+ def isCaseEquals = isMethodCaseEquals(receiver.info.member(nme.equals_))
// Whether this == or != is one of those defined in Any/AnyRef or an overload from elsewhere.
def isUsingDefaultScalaOp = {
val s = fn.symbol
@@ -1072,9 +1092,11 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
val msg = alwaysEqual == (name == nme.EQ || name == nme.eq)
unit.warning(pos, "comparing "+what+" using `"+name.decode+"' will always yield " + msg)
}
-
def nonSensible(pre: String, alwaysEqual: Boolean) =
nonSensibleWarning(pre+"values of types "+typesString, alwaysEqual)
+ def nonSensiblyEq() = nonSensible("", true)
+ def nonSensiblyNeq() = nonSensible("", false)
+ def nonSensiblyNew() = nonSensibleWarning("a fresh object", false)
def unrelatedTypes() = {
val msg = if (name == nme.EQ || name == nme.eq)
@@ -1082,52 +1104,73 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
unit.warning(pos, typesString + " are unrelated: they will most likely " + msg)
}
- if (nullCount == 2)
- nonSensible("", true) // null == null
+ if (nullCount == 2) // null == null
+ nonSensiblyEq()
else if (nullCount == 1) {
if (onSyms(_ exists isPrimitiveValueClass)) // null == 5
- nonSensible("", false)
+ nonSensiblyNeq()
else if (onTrees( _ exists isNew)) // null == new AnyRef
- nonSensibleWarning("a fresh object", false)
+ nonSensiblyNew()
}
else if (isBoolean(receiver)) {
if (!isBoolean(actual) && !isMaybeValue(actual)) // true == 5
- nonSensible("", false)
+ nonSensiblyNeq()
}
else if (isUnit(receiver)) {
if (isUnit(actual)) // () == ()
- nonSensible("", true)
+ nonSensiblyEq()
else if (!isUnit(actual) && !isMaybeValue(actual)) // () == "abc"
- nonSensible("", false)
+ nonSensiblyNeq()
}
else if (isNumeric(receiver)) {
if (!isNumeric(actual) && !forMSIL)
if (isUnit(actual) || isBoolean(actual) || !isMaybeValue(actual)) // 5 == "abc"
- nonSensible("", false)
+ nonSensiblyNeq()
}
- else if (isWarnable) {
+ else if (isWarnable && !isCaseEquals) {
if (isNew(qual)) // new X == y
- nonSensibleWarning("a fresh object", false)
+ nonSensiblyNew()
else if (isNew(args.head) && (receiver.isEffectivelyFinal || isReferenceOp)) // object X ; X == new Y
- nonSensibleWarning("a fresh object", false)
+ nonSensiblyNew()
else if (receiver.isEffectivelyFinal && !(receiver isSubClass actual)) { // object X, Y; X == Y
if (isEitherNullable)
nonSensible("non-null ", false)
else
- nonSensible("", false)
+ nonSensiblyNeq()
}
}
// possibleNumericCount is insufficient or this will warn on e.g. Boolean == j.l.Boolean
if (isWarnable && nullCount == 0 && !(isSpecial(receiver) && isSpecial(actual))) {
- if (actual isSubClass receiver) ()
- else if (receiver isSubClass actual) ()
- // warn only if they have no common supertype below Object
- else {
+ // better to have lubbed and lost
+ def warnIfLubless(): Unit = {
val common = global.lub(List(actual.tpe, receiver.tpe))
if (ObjectClass.tpe <:< common)
unrelatedTypes()
}
+ def eitherSubclasses = (actual isSubClass receiver) || (receiver isSubClass actual)
+ // warn if actual has a case parent that is not same as receiver's;
+ // if actual is not a case, then warn if no common supertype, as below
+ if (isCaseEquals) {
+ def thisCase = receiver.info.member(nme.equals_).owner
+ actual.info.baseClasses.find(_.isCase) match {
+ case Some(p) if (p != thisCase) => nonSensible("case class ", false)
+ case None =>
+ // stronger message on (Some(1) == None)
+ //if (receiver.isCase && receiver.isEffectivelyFinal && !(receiver isSubClass actual)) nonSensiblyNeq()
+ //else
+ // if a class, it must be super to thisCase (and receiver) since not <: thisCase
+ if (!actual.isTrait && !(receiver isSubClass actual)) nonSensiblyNeq()
+ else if (!eitherSubclasses) warnIfLubless()
+ case _ =>
+ }
+ }
+ else if (actual isSubClass receiver) ()
+ else if (receiver isSubClass actual) ()
+ // warn only if they have no common supertype below Object
+ else {
+ warnIfLubless()
+ }
}
case _ =>
}
@@ -1248,9 +1291,9 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
}
List(tree1)
}
- case Import(_, _) => Nil
+ case Import(_, _) => Nil
case DefDef(mods, _, _, _, _, _) if (mods hasFlag MACRO) => Nil
- case _ => List(transform(tree))
+ case _ => List(transform(tree))
}
/* Check whether argument types conform to bounds of type parameters */
@@ -1625,12 +1668,19 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
case _ => tree
}
+ // skip refchecks in patterns....
result = result match {
case CaseDef(pat, guard, body) =>
inPattern = true
val pat1 = transform(pat)
inPattern = false
treeCopy.CaseDef(tree, pat1, transform(guard), transform(body))
+ case LabelDef(_, _, _) if gen.hasSynthCaseSymbol(result) =>
+ val old = inPattern
+ inPattern = true
+ val res = deriveLabelDef(result)(transform)
+ inPattern = old
+ res
case _ =>
super.transform(result)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
new file mode 100644
index 0000000000..329a247106
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -0,0 +1,10 @@
+package scala.tools.nsc
+package typechecker
+
+import scala.reflect.makro.runtime.{Context => MacroContext}
+
+trait StdAttachments {
+ self: Analyzer =>
+
+ case class MacroAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext])
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 4248b6f024..d327d9c397 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -121,7 +121,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
if (sym.isDeferred) {
val member = sym.overridingSymbol(clazz);
if (mix != tpnme.EMPTY || member == NoSymbol ||
- !((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(clazz)))
+ !(member.isAbstractOverride && member.isIncompleteIn(clazz)))
unit.error(sel.pos, ""+sym.fullLocationString+" is accessed from super. It may not be abstract "+
"unless it is overridden by a member declared `abstract' and `override'");
}
@@ -134,7 +134,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
// otherwise lead to either a compiler crash or runtime failure.
private lazy val isDisallowed = {
import definitions._
- Set(Any_isInstanceOf, Object_isInstanceOf, Any_asInstanceOf, Object_asInstanceOf, Object_==, Object_!=, Object_##)
+ Set[Symbol](Any_isInstanceOf, Object_isInstanceOf, Any_asInstanceOf, Object_asInstanceOf, Object_==, Object_!=, Object_##)
}
override def transform(tree: Tree): Tree = {
@@ -259,7 +259,8 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
case sel @ Select(Super(_, mix), name) =>
if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
- unit.error(tree.pos, "super may be not be used on "+ sym.accessedOrSelf)
+ if (!settings.overrideVars.value)
+ unit.error(tree.pos, "super may be not be used on "+ sym.accessedOrSelf)
}
else if (isDisallowed(sym)) {
unit.error(tree.pos, "super not allowed here: use this." + name.decode + " instead")
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index da87d38ab0..31d064c824 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -50,7 +50,7 @@ trait SyntheticMethods extends ast.TreeDSL {
import synthesizer._
if (clazz0 == AnyValClass || isPrimitiveValueClass(clazz0)) return {
- if (clazz0.info member nme.getClass_ isDeferred) {
+ if ((clazz0.info member nme.getClass_).isDeferred) {
// XXX dummy implementation for now
val getClassMethod = createMethod(nme.getClass_, getClassReturnType(clazz.tpe))(_ => NULL)
deriveTemplate(templ)(_ :+ getClassMethod)
@@ -74,7 +74,7 @@ trait SyntheticMethods extends ast.TreeDSL {
// Option[Int] { def productIterator: Iterator[String] }
//
// appearing legitimately, but this breaks invariant places
- // like Manifests and Arrays which are not robust and infer things
+ // like Tags and Arrays which are not robust and infer things
// which they shouldn't.
val accessorLub = (
if (opt.experimental) {
@@ -303,7 +303,7 @@ trait SyntheticMethods extends ast.TreeDSL {
lb += logResult("case accessor new")(newAcc)
}
- lb ++= templ.body ++= synthesize() toList
+ (lb ++= templ.body ++= synthesize()).toList
}
if (phase.id > currentRun.typerPhase.id) templ
diff --git a/src/compiler/scala/tools/nsc/typechecker/Taggings.scala b/src/compiler/scala/tools/nsc/typechecker/Taggings.scala
new file mode 100644
index 0000000000..d276b39f16
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/Taggings.scala
@@ -0,0 +1,71 @@
+package scala.tools.nsc
+package typechecker
+
+trait Taggings {
+ self: Analyzer =>
+
+ import global._
+ import definitions._
+
+ trait Tagging {
+ self: Typer =>
+
+ private def resolveTag(pos: Position, taggedTp: Type) = beforeTyper {
+ inferImplicit(
+ EmptyTree,
+ taggedTp,
+ /*reportAmbiguous =*/ true,
+ /*isView =*/ false,
+ /*context =*/ context,
+ /*saveAmbiguousDivergent =*/ true,
+ /*pos =*/ pos
+ ).tree
+ }
+
+ /** Finds in scope or materializes an ArrayTag.
+ * Should be used instead of ClassTag or ClassManifest every time compiler needs to create an array.
+ *
+ * @param pos Position for error reporting. Please, provide meaningful value.
+ * @param tp Type we're looking an ArrayTag for, e.g. resolveArrayTag(pos, IntClass.tpe) will look for ArrayTag[Int].
+ *
+ * @returns Tree that represents an `scala.reflect.ArrayTag` for `tp` if everything is okay.
+ * EmptyTree if the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
+ */
+ def resolveArrayTag(pos: Position, tp: Type): Tree = {
+ val taggedTp = appliedType(ArrayTagClass.typeConstructor, List(tp))
+ resolveTag(pos, taggedTp)
+ }
+
+ /** Finds in scope or materializes an ErasureTag (if `concrete` is false) or a ClassTag (if `concrete` is true).
+ * Should be used instead of ClassTag or ClassManifest every time compiler needs to persist an erasure.
+ *
+ * @param pos Position for error reporting. Please, provide meaningful value.
+ * @param tp Type we're looking an ErasureTag for, e.g. resolveErasureTag(pos, IntClass.tpe, true) will look for ClassTag[Int].
+ * @param concrete If true then the result must not contain unresolved (i.e. not spliced) type parameters and abstract type members.
+ * If false then the function will always succeed (abstract types will be erased to their upper bounds).
+ *
+ * @returns Tree that represents an `scala.reflect.ErasureTag` for `tp` if everything is okay.
+ * EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
+ */
+ def resolveErasureTag(pos: Position, tp: Type, concrete: Boolean): Tree = {
+ val taggedTp = appliedType(if (concrete) ClassTagClass.typeConstructor else ErasureTagClass.typeConstructor, List(tp))
+ resolveTag(pos, taggedTp)
+ }
+
+ /** Finds in scope or materializes a TypeTag (if `concrete` is false) or a ConcreteTypeTag (if `concrete` is true).
+ *
+ * @param pos Position for error reporting. Please, provide meaningful value.
+ * @param pre Prefix that represents a universe this type tag will be bound to.
+ * @param tp Type we're looking a TypeTag for, e.g. resolveTypeTag(pos, reflectMirrorPrefix, IntClass.tpe, false) will look for scala.reflect.mirror.TypeTag[Int].
+ * @param concrete If true then the result must not contain unresolved (i.e. not spliced) type parameters and abstract type members.
+ * If false then the function will always succeed (abstract types will be reified as free types).
+ *
+ * @returns Tree that represents a `scala.reflect.TypeTag` for `tp` if everything is okay.
+ * EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
+ */
+ def resolveTypeTag(pos: Position, pre: Type, tp: Type, concrete: Boolean): Tree = {
+ val taggedTp = appliedType(singleType(pre, pre member (if (concrete) ConcreteTypeTagClass else TypeTagClass).name), List(tp))
+ resolveTag(pos, taggedTp)
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index ed263cbbef..a6a8d6009f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -14,7 +14,22 @@ import util.returning
abstract class TreeCheckers extends Analyzer {
import global._
- private def classstr(x: AnyRef) = x.getClass.getName split """\\.|\\$""" last;
+ private val everything = ListBuffer[(Phase, Map[Tree, (Symbol, Type)])]()
+ private val currentTrees = mutable.Map[Tree, (Symbol, Type)]()
+ private val tpeOfTree = mutable.HashMap[Tree, Type]()
+
+ if (settings.debug.value) {
+ sys addShutdownHook {
+ for ((ph, map) <- everything.toList) {
+ println("\n>>>> " + ph + "\n")
+ for ((tree, (sym, tpe)) <- map.toList.sortBy(_._1.summaryString)) {
+ println("%20s %20s %s".format(sym, tpe, ("" + tree) take 50))
+ }
+ }
+ }
+ }
+
+ private def classstr(x: AnyRef) = (x.getClass.getName split """\\.|\\$""").last
private def typestr(x: Type) = " (tpe = " + x + ")"
private def treestr(t: Tree) = t + " [" + classstr(t) + "]" + typestr(t.tpe)
private def ownerstr(s: Symbol) = "'" + s + "'" + s.locationString
@@ -35,13 +50,14 @@ abstract class TreeCheckers extends Analyzer {
object SymbolTracker extends Traverser {
type PhaseMap = mutable.HashMap[Symbol, List[Tree]]
+ val defSyms = mutable.HashMap[Symbol, List[DefTree]]() withDefaultValue Nil
+ val newSyms = mutable.HashSet[Symbol]()
val maps = ListBuffer[(Phase, PhaseMap)]()
+ val movedMsgs = ListBuffer[String]()
+
def prev = maps.init.last._2
def latest = maps.last._2
- val defSyms = mutable.HashMap[Symbol, List[DefTree]]()
- val newSyms = mutable.HashSet[Symbol]()
- val movedMsgs = new ListBuffer[String]
- def sortedNewSyms = newSyms.toList.distinct sortBy (_.name.toString)
+ def sortedNewSyms = newSyms.toList.distinct sortBy (_.name)
def inPrev(sym: Symbol) = {
(maps.size >= 2) && (prev contains sym)
@@ -92,18 +108,21 @@ abstract class TreeCheckers extends Analyzer {
if (maps.isEmpty || maps.last._1 != ph)
maps += ((ph, new PhaseMap))
+ currentTrees.clear()
traverse(unit.body)
+ everything += ((ph, currentTrees.toMap))
+
reportChanges()
}
override def traverse(tree: Tree): Unit = {
val sym = tree.symbol
+ currentTrees(tree) = ((sym, tree.tpe))
+
if (sym != null && sym != NoSymbol) {
record(sym, tree)
tree match {
- case x: DefTree =>
- if (defSyms contains sym) defSyms(sym) = defSyms(sym) :+ x
- else defSyms(sym) = List(x)
- case _ => ()
+ case x: DefTree => defSyms(sym) :+= x
+ case _ => ()
}
}
@@ -111,8 +130,6 @@ abstract class TreeCheckers extends Analyzer {
}
}
- lazy val tpeOfTree = mutable.HashMap[Tree, Type]()
-
def posstr(p: Position) =
try p.source.path + ":" + p.line
catch { case _: UnsupportedOperationException => p.toString }
@@ -128,9 +145,7 @@ abstract class TreeCheckers extends Analyzer {
if (!cond) errorFn(msg)
def checkTrees() {
- if (settings.verbose.value)
- Console.println("[consistency check at the beginning of phase " + phase + "]")
-
+ informFn("[consistency check at the beginning of phase " + phase + "]")
currentRun.units foreach check
}
@@ -153,7 +168,7 @@ abstract class TreeCheckers extends Analyzer {
informProgress("checking "+unit)
val context = rootContext(unit)
context.checking = true
- tpeOfTree.clear
+ tpeOfTree.clear()
SymbolTracker.check(phase, unit)
val checker = new TreeChecker(context)
runWithUnit(unit) {
@@ -263,8 +278,8 @@ abstract class TreeCheckers extends Analyzer {
tree match {
case x: PackageDef =>
- if (sym.ownerChain contains currentOwner) ()
- else fail(sym + " owner chain does not contain currentOwner " + currentOwner)
+ if ((sym.ownerChain contains currentOwner) || currentOwner == definitions.EmptyPackageClass) ()
+ else fail(sym + " owner chain does not contain currentOwner " + currentOwner + sym.ownerChain)
case _ =>
def cond(s: Symbol) = !s.isTerm || s.isMethod || s == sym.owner
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index e17a271dd0..38c2c5f719 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -252,12 +252,17 @@ trait TypeDiagnostics {
}
"" // no elaborable variance situation found
}
- def foundReqMsg(found: Type, req: Type): String = (
- withDisambiguation(Nil, found, req)(
+ // TODO - figure out how to avoid doing any work at all
+ // when the message will never be seen. I though context.reportErrors
+ // being false would do that, but if I return "<suppressed>" under
+ // that condition, I see it.
+ def foundReqMsg(found: Type, req: Type): String = {
+ def baseMessage = (
";\n found : " + found.toLongString + existentialContext(found) + explainAlias(found) +
"\n required: " + req + existentialContext(req) + explainAlias(req)
- ) + explainVariance(found, req)
- )
+ )
+ withDisambiguation(Nil, found, req)(baseMessage) + explainVariance(found, req)
+ }
case class TypeDiag(tp: Type, sym: Symbol) extends Ordered[TypeDiag] {
// save the name because it will be mutated until it has been
@@ -265,8 +270,7 @@ trait TypeDiagnostics {
private val savedName = sym.name
def restoreName() = sym.name = savedName
def isAltered = sym.name != savedName
- def modifyName(f: String => String) =
- sym.name = newTypeName(f(sym.name.toString))
+ def modifyName(f: String => String) = sym setName newTypeName(f(sym.name.toString))
/** Prepend java.lang, scala., or Predef. if this type originated
* in one of those.
@@ -307,16 +311,37 @@ trait TypeDiagnostics {
)
}
}
- private def typeDiags(locals: List[Symbol], types: Type*): List[TypeDiag] = {
- object SymExtractor {
- def unapply(x: Any) = x match {
- case t @ ConstantType(_) => Some(t -> t.underlying.typeSymbol)
- case t @ TypeRef(_, sym, _) => if (locals contains sym) None else Some(t -> sym)
- case _ => None
+ /** This is tricky stuff - we need to traverse types deeply to
+ * explain name ambiguities, which may occur anywhere. However
+ * when lub explosions come through it knocks us into an n^2
+ * disaster, see SI-5580. This is trying to perform the initial
+ * filtering of possibly ambiguous types in a sufficiently
+ * aggressive way that the state space won't explode.
+ */
+ private def typeDiags(locals: List[Symbol], types0: Type*): List[TypeDiag] = {
+ val types = types0.toList
+ // If two different type diag instances are seen for a given
+ // key (either the string representation of a type, or the simple
+ // name of a symbol) then keep them for disambiguation.
+ val strings = mutable.Map[String, Set[TypeDiag]]() withDefaultValue Set()
+ val names = mutable.Map[Name, Set[TypeDiag]]() withDefaultValue Set()
+
+ def record(t: Type, sym: Symbol) = {
+ val diag = TypeDiag(t, sym)
+
+ strings("" + t) += diag
+ names(sym.name) += diag
+ }
+ for (tpe <- types ; t <- tpe) {
+ t match {
+ case ConstantType(_) => record(t, t.underlying.typeSymbol)
+ case TypeRef(_, sym, _) => record(t, sym)
+ case _ => ()
}
}
- for (tp <- types.toList; SymExtractor(t, sym) <- tp) yield TypeDiag(t, sym)
+ val collisions = strings.values ++ names.values filter (_.size > 1)
+ collisions.flatten.toList
}
/** The distinct pairs from an ordered list. */
@@ -431,14 +456,20 @@ trait TypeDiagnostics {
ex match {
case CyclicReference(sym, info: TypeCompleter) =>
- val pos = info.tree match {
- case Import(expr, _) => expr.pos
- case _ => ex.pos
+ if (context0.owner.isTermMacro) {
+ // see comments to TypeSigError for an explanation of this special case
+ // [Eugene] is there a better way?
+ throw ex
+ } else {
+ val pos = info.tree match {
+ case Import(expr, _) => expr.pos
+ case _ => ex.pos
+ }
+ contextError(context0, pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
+
+ if (sym == ObjectClass)
+ throw new FatalError("cannot redefine root "+sym)
}
- contextError(context0, pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
-
- if (sym == ObjectClass)
- throw new FatalError("cannot redefine root "+sym)
case _ =>
contextError(context0, ex.pos, ex)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index c3a7453df0..1392f39c48 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -26,7 +26,7 @@ import util.Statistics._
* @author Martin Odersky
* @version 1.0
*/
-trait Typers extends Modes with Adaptations with PatMatVirtualiser {
+trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser {
self: Analyzer =>
import global._
@@ -51,6 +51,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
transformed.clear()
}
+ // [Eugene] shouldn't this be converted to resetAllAttrs?
object UnTyper extends Traverser {
override def traverse(tree: Tree) = {
if (tree != EmptyTree) tree.tpe = null
@@ -82,7 +83,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
private def isPastTyper = phase.id > currentRun.typerPhase.id
- abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with TyperContextErrors {
+ // don't translate matches in presentation compiler: it loses vital symbols that are needed to do hyperlinking
+ @inline private def doMatchTranslation = !forInteractive && opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id)
+
+ abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tagging with TyperContextErrors {
import context0.unit
import typeDebug.{ ptTree, ptBlock, ptLine }
import TyperErrorGen._
@@ -181,12 +185,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case _ =>
def wrapImplicit(from: Type): Tree = {
val result = inferImplicit(tree, functionType(List(from), to), reportAmbiguous, true, context, saveErrors)
- if (result.subst != EmptyTreeTypeSubstituter) result.subst traverse tree
+ if (result.subst != EmptyTreeTypeSubstituter) {
+ result.subst traverse tree
+ notifyUndetparamsInferred(result.subst.from, result.subst.to)
+ }
result.tree
}
val result = wrapImplicit(from)
if (result != EmptyTree) result
- else wrapImplicit(appliedType(ByNameParamClass.typeConstructor, List(from)))
+ else wrapImplicit(byNameType(from))
}
}
@@ -235,32 +242,41 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
result
}
}
+ def isNonRefinementClassType(tpe: Type) = tpe match {
+ case SingleType(_, sym) => sym.isModuleClass
+ case TypeRef(_, sym, _) => sym.isClass && !sym.isRefinementClass
+ case ErrorType => true
+ case _ => false
+ }
+ private def errorNotClass(tpt: Tree, found: Type) = { ClassTypeRequiredError(tpt, found); false }
+ private def errorNotStable(tpt: Tree, found: Type) = { TypeNotAStablePrefixError(tpt, found); false }
/** Check that `tpt` refers to a non-refinement class type */
- def checkClassType(tpt: Tree, existentialOK: Boolean, stablePrefix: Boolean): Boolean = {
- def errorNotClass(found: AnyRef) = { ClassTypeRequiredError(tpt, found); false }
- def check(tpe: Type): Boolean = tpe.normalize match {
- case TypeRef(pre, sym, _) if sym.isClass && !sym.isRefinementClass =>
- if (stablePrefix && !isPastTyper)
- if (!pre.isStable) {
- TypeNotAStablePrefixError(tpt, pre)
- false
- } else
- // A type projection like X#Y can get by the stable check if the
- // prefix is singleton-bounded, so peek at the tree too.
- tpt match {
- case SelectFromTypeTree(qual, _) if !isSingleType(qual.tpe) => errorNotClass(tpt)
- case _ => true
- }
- else
- true
- case ErrorType => true
- case PolyType(_, restpe) => check(restpe)
- case ExistentialType(_, restpe) if existentialOK => check(restpe)
- case AnnotatedType(_, underlying, _) => check(underlying)
- case t => errorNotClass(t)
+ def checkClassType(tpt: Tree): Boolean = {
+ val tpe = unwrapToClass(tpt.tpe)
+ isNonRefinementClassType(tpe) || errorNotClass(tpt, tpe)
+ }
+
+ /** Check that `tpt` refers to a class type with a stable prefix. */
+ def checkStablePrefixClassType(tpt: Tree): Boolean = {
+ val tpe = unwrapToStableClass(tpt.tpe)
+ def prefixIsStable = {
+ def checkPre = tpe match {
+ case TypeRef(pre, _, _) => pre.isStable || errorNotStable(tpt, pre)
+ case _ => false
+ }
+ // A type projection like X#Y can get by the stable check if the
+ // prefix is singleton-bounded, so peek at the tree too.
+ def checkTree = tpt match {
+ case SelectFromTypeTree(qual, _) => isSingleType(qual.tpe) || errorNotClass(tpt, tpe)
+ case _ => true
+ }
+ checkPre && checkTree
}
- check(tpt.tpe)
+
+ ( (isNonRefinementClassType(tpe) || errorNotClass(tpt, tpe))
+ && (isPastTyper || prefixIsStable)
+ )
}
/** Check that type <code>tp</code> is not a subtype of itself.
@@ -499,7 +515,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
res
}
-
/** The typer for a label definition. If this is part of a template we
* first have to enter the label definition.
*/
@@ -643,13 +658,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
- private def isNarrowable(tpe: Type): Boolean = tpe match {
+ private def isNarrowable(tpe: Type): Boolean = unwrapWrapperTypes(tpe) match {
case TypeRef(_, _, _) | RefinedType(_, _) => true
- case ExistentialType(_, tpe1) => isNarrowable(tpe1)
- case AnnotatedType(_, tpe1, _) => isNarrowable(tpe1)
- case PolyType(_, tpe1) => isNarrowable(tpe1)
- case NullaryMethodType(tpe1) => isNarrowable(tpe1)
- case _ => !phase.erasedTypes
+ case _ => !phase.erasedTypes
}
/**
@@ -666,7 +677,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
if (tree.tpe.isInstanceOf[MethodType] && pre.isStable && sym.tpe.params.isEmpty &&
(isStableContext(tree, mode, pt) || sym.isModule))
- tree.setType(MethodType(List(), singleType(pre, sym)))
+ tree.setType(MethodType(List(), singleType(pre, sym))) // TODO: should this be a NullaryMethodType?
else tree
}
@@ -725,6 +736,58 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
+ /** Check whether feature given by `featureTrait` is enabled.
+ * If it is not, issue an error or a warning depending on whether the feature is required.
+ * @param construct A string expression that is substituted for "#" in the feature description string
+ * @param immediate When set, feature check is run immediately, otherwise it is run
+ * at the end of the typechecking run for the enclosing unit. This
+ * is done to avoid potential cyclic reference errors by implicits
+ * that are forced too early.
+ * @return if feature check is run immediately: true if feature is enabled, false otherwise
+ * if feature check is delayed or suppressed because we are past typer: true
+ */
+ def checkFeature(pos: Position, featureTrait: Symbol, construct: => String = "", immediate: Boolean = false): Boolean =
+ if (isPastTyper) true
+ else {
+ val nestedOwners =
+ featureTrait.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse
+ val featureName = (nestedOwners map (_.name + ".")).mkString + featureTrait.name
+ def action(): Boolean = {
+ def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context) != SearchFailure
+ def hasOption = settings.language.value contains featureName
+ val OK = hasImport || hasOption
+ if (!OK) {
+ val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) =
+ featureTrait getAnnotation LanguageFeatureAnnot
+ val req = if (required) "needs to" else "should"
+ var raw = featureDesc + " " + req + " be enabled\n" +
+ "by making the implicit value language." + featureName + " visible."
+ if (!(currentRun.reportedFeature contains featureTrait))
+ raw += "\nThis can be achieved by adding the import clause 'import language." + featureName + "'\n" +
+ "or by setting the compiler option -language:" + featureName + ".\n" +
+ "See the Scala docs for value scala.language." + featureName + " for a discussion\n" +
+ "why the feature " + req + " be explicitly enabled."
+ currentRun.reportedFeature += featureTrait
+ val msg = raw replace ("#", construct)
+ if (required) unit.error(pos, msg)
+ else currentRun.featureWarnings.warn(pos, msg)
+ }
+ OK
+ }
+ if (immediate) {
+ action()
+ } else {
+ unit.toCheck += action
+ true
+ }
+ }
+
+ def checkExistentialsFeature(pos: Position, tpe: Type, prefix: String) = tpe match {
+ case extp: ExistentialType if !extp.isRepresentableWithWildcards =>
+ checkFeature(pos, ExistentialsFeature, prefix+" "+tpe)
+ case _ =>
+ }
+
/** Perform the following adaptations of expression, pattern or type `tree` wrt to
* given mode `mode` and given prototype `pt`:
* (-1) For expressions with annotated types, let AnnotationCheckers decide what to do
@@ -764,17 +827,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
protected def adapt(tree: Tree, mode: Int, pt: Type, original: Tree = EmptyTree): Tree = {
def adaptToImplicitMethod(mt: MethodType): Tree = {
- if (context.undetparams nonEmpty) { // (9) -- should revisit dropped condition `(mode & POLYmode) == 0`
+ if (context.undetparams.nonEmpty) { // (9) -- should revisit dropped condition `(mode & POLYmode) == 0`
// dropped so that type args of implicit method are inferred even if polymorphic expressions are allowed
// needed for implicits in 2.8 collection library -- maybe once #3346 is fixed, we can reinstate the condition?
context.undetparams = inferExprInstance(tree, context.extractUndetparams(), pt,
// approximate types that depend on arguments since dependency on implicit argument is like dependency on type parameter
mt.approximate,
- // if we are looking for a manifest, instantiate type to Nothing anyway,
- // as we would get ambiguity errors otherwise. Example
- // Looking for a manifest of Nil: This has many potential types,
- // so we need to instantiate to minimal type List[Nothing].
- keepNothings = false, // retract Nothing's that indicate failure, ambiguities in manifests are dealt with in manifestOfType
+ keepNothings = false,
useWeaklyCompatible = true) // #3808
}
@@ -808,7 +867,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case Block(_, tree1) => tree1.symbol
case _ => tree.symbol
}
- if (!meth.isConstructor && !meth.isMacro && isFunctionType(pt)) { // (4.2)
+ if (!meth.isConstructor && !meth.isTermMacro && isFunctionType(pt)) { // (4.2)
debuglog("eta-expanding " + tree + ":" + tree.tpe + " to " + pt)
checkParamsConvertible(tree, tree.tpe)
val tree0 = etaExpand(context.unit, tree)
@@ -1003,12 +1062,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
else TypeApply(tree, tparams1 map (tparam =>
TypeTree(tparam.tpeHK) setPos tree.pos.focus)) setPos tree.pos //@M/tcpolyinfer: changed tparam.tpe to tparam.tpeHK
context.undetparams ++= tparams1
+ notifyUndetparamsAdded(tparams1)
adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt, original)
case mt: MethodType if mt.isImplicit && ((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) => // (4.1)
adaptToImplicitMethod(mt)
case mt: MethodType if (((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) &&
- (context.undetparams.isEmpty || inPolyMode(mode))) =>
+ (context.undetparams.isEmpty || inPolyMode(mode))) && !(tree.symbol != null && tree.symbol.isTermMacro) =>
instantiateToMethodType(mt)
case _ =>
@@ -1021,13 +1081,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
if (tree.isType)
adaptType()
- else if (inExprModeButNot(mode, FUNmode) && tree.symbol != null && tree.symbol.isMacro && !tree.isDef && !(tree exists (_.isErroneous)))
- macroExpand(tree, this) match {
- case Some(expanded: Tree) =>
- typed(expanded, mode, pt)
- case None =>
- setError(tree) // error already reported
- }
+ else if (
+ inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application
+ tree.symbol != null && tree.symbol.isTermMacro) // of a macro
+ macroExpand(this, tree, mode, pt)
else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode))
adaptConstrPattern()
else if (inAllModes(mode, EXPRmode | FUNmode) &&
@@ -1158,12 +1215,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val qtpe = qual.tpe.widen
( !isPastTyper
&& qual.isTerm
+ && !qual.isInstanceOf[Super]
&& ((qual.symbol eq null) || !qual.symbol.isTerm || qual.symbol.isValue)
&& !qtpe.isError
&& !qtpe.typeSymbol.isBottomClass
&& qtpe != WildcardType
&& !qual.isInstanceOf[ApplyImplicitView] // don't chain views
- && context.implicitsEnabled
+ && (context.implicitsEnabled || context.enrichmentEnabled)
// Elaborating `context.implicitsEnabled`:
// don't try to adapt a top-level type that's the subject of an implicit search
// this happens because, if isView, typedImplicit tries to apply the "current" implicit value to
@@ -1173,12 +1231,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
)
}
- def adaptToMember(qual: Tree, searchTemplate: Type): Tree =
- adaptToMember(qual, searchTemplate, true, true)
- def adaptToMember(qual: Tree, searchTemplate: Type, reportAmbiguous: Boolean): Tree =
- adaptToMember(qual, searchTemplate, reportAmbiguous, true)
-
- def adaptToMember(qual: Tree, searchTemplate: Type, reportAmbiguous: Boolean, saveErrors: Boolean): Tree = {
+ def adaptToMember(qual: Tree, searchTemplate: Type, reportAmbiguous: Boolean = true, saveErrors: Boolean = true): Tree = {
if (isAdaptableWithView(qual)) {
qual.tpe.widen.normalize match {
case et: ExistentialType =>
@@ -1284,8 +1337,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
unit.error(clazz.pos, "value class may not be a "+
(if (clazz.owner.isTerm) "local class" else "member of another class"))
val constr = clazz.primaryConstructor
- if ((constr hasFlag (PRIVATE | PROTECTED)) || constr.privateWithin != NoSymbol)
- unit.error(constr.pos, "value class must have public primary constructor")
clazz.info.decls.toList.filter(acc => acc.isMethod && (acc hasFlag PARAMACCESSOR)) match {
case List(acc) =>
def isUnderlyingAcc(sym: Symbol) =
@@ -1444,7 +1495,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def validateParentClass(parent: Tree, superclazz: Symbol) {
if (!parent.isErrorTyped) {
val psym = parent.tpe.typeSymbol.initialize
- checkClassType(parent, false, true)
+ checkStablePrefixClassType(parent)
if (psym != superclazz) {
if (psym.isTrait) {
val ps = psym.info.parents
@@ -1654,7 +1705,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val body =
if (isPastTyper || reporter.hasErrors) templ.body
- else templ.body flatMap rewrappingWrapperTrees(namer.finishGetterSetter(Typer.this, _))
+ else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _))
val body1 = typedStats(body, templ.symbol)
@@ -1907,8 +1958,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
meth.owner.isAnonOrRefinementClass))
InvalidConstructorDefError(ddef)
typed(ddef.rhs)
- } else if (meth.isMacro) {
- EmptyTree
+ } else if (meth.isTermMacro) {
+ // typechecking macro bodies is sort of unconventional
+ // that's why we employ our custom typing scheme orchestrated outside of the typer
+ transformedOr(ddef.rhs, typedMacroBody(this, ddef))
} else {
transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe)
}
@@ -1923,7 +1976,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
rhs1 = checkDead(rhs1)
if (!isPastTyper && meth.owner.isClass &&
- meth.paramss.exists(ps => ps.exists(_.hasDefaultFlag) && isRepeatedParamType(ps.last.tpe)))
+ meth.paramss.exists(ps => ps.exists(_.hasDefault) && isRepeatedParamType(ps.last.tpe)))
StarWithDefaultError(meth)
if (!isPastTyper) {
@@ -1938,6 +1991,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (meth.isStructuralRefinementMember)
checkMethodStructuralCompatible(meth)
+ if (meth.isImplicit && !meth.isSynthetic) meth.info.paramss match {
+ case List(param) :: _ if !param.isImplicit =>
+ checkFeature(ddef.pos, ImplicitConversionsFeature, meth.toString)
+ case _ =>
+ }
+
treeCopy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType
}
@@ -1969,6 +2028,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case TypeBounds(lo1, hi1) if (!(lo1 <:< hi1)) => LowerBoundError(tdef, lo1, hi1)
case _ => ()
}
+
+ if (tdef.symbol.isDeferred && tdef.symbol.info.isHigherKinded)
+ checkFeature(tdef.pos, HigherKindsFeature)
+
treeCopy.TypeDef(tdef, typedMods, tdef.name, tparams1, rhs1) setType NoType
}
@@ -2090,7 +2153,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
for (Apply(_, xs) <- cdef.pat ; x <- xs dropRight 1 ; if treeInfo isStar x)
StarPositionInPatternError(x)
- val pat1 = typedPattern(cdef.pat, pattpe)
+ // withoutAnnotations - see continuations-run/z1673.scala
+ // This adjustment is awfully specific to continuations, but AFAICS the
+ // whole AnnotationChecker framework is.
+ val pat1 = typedPattern(cdef.pat, pattpe.withoutAnnotations)
// When case classes have more than two parameter lists, the pattern ends
// up typed as a method. We only pattern match on the first parameter
// list, so substitute the final result type of the method, i.e. the type
@@ -2109,7 +2175,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
var body1: Tree = typed(cdef.body, pt)
val contextWithTypeBounds = context.nextEnclosing(_.tree.isInstanceOf[CaseDef])
- if (contextWithTypeBounds.savedTypeBounds nonEmpty) {
+ if (contextWithTypeBounds.savedTypeBounds.nonEmpty) {
body1.tpe = contextWithTypeBounds restoreTypeBounds body1.tpe
// insert a cast if something typechecked under the GADT constraints,
@@ -2140,142 +2206,184 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def typedCases(cases: List[CaseDef], pattp: Type, pt: Type): List[CaseDef] =
cases mapConserve { cdef =>
- val caseTyped = newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt)
- if (opt.virtPatmat) {
- val tpPacked = packedType(caseTyped, context.owner)
- caseTyped setType tpPacked
- } else caseTyped
+ newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt)
}
def adaptCase(cdef: CaseDef, mode: Int, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe))
- def translateMatch(selector: Tree, cases: List[CaseDef], mode: Int, resTp: Type, scrutTp: Type = NoType, matchFailGen: Option[Tree => Tree] = None) = {
- val selector1 = if(scrutTp eq NoType) checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType)) else selector
- val selectorTp = if(scrutTp eq NoType) packCaptured(selector1.tpe.widen) else scrutTp
- val casesTyped = typedCases(cases, selectorTp, resTp)
- val (ownType, needAdapt) = if (isFullyDefined(resTp)) (resTp, false) else weakLub(casesTyped map (_.tpe.deconst))
- val casesAdapted = if (!needAdapt) casesTyped else casesTyped map (adaptCase(_, mode, ownType))
- // val (owntype0, needAdapt) = ptOrLub(casesTyped map (x => repackExistential(x.tpe)))
- // val owntype = elimAnonymousClass(owntype0)
-
- def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match {
- case TypeRef(_, RepeatedParamClass, args) => appliedType(SeqClass.typeConstructor, args)
- case _ => tp
+ // takes untyped sub-trees of a match and type checks them
+ def typedMatch(selector0: Tree, cases: List[CaseDef], mode: Int, resTp: Type) = {
+ val (selector, doTranslation) = selector0 match {
+ case Annotated(Ident(nme.synthSwitch), selector) => (selector, false)
+ case s => (s, true)
}
+ val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType))
+ val selectorTp = packCaptured(selector1.tpe.widen.withoutAnnotations)
- def isSynthSelector(selector: Tree): Boolean = selector match {
- case Ident(_) if selector.symbol.hasFlag(SYNTHETIC | CASE) => true
- case Select(sel, nme.toInt) => isSynthSelector(sel) // switch may need to convert to int first
- case _ => false
+ val casesTyped = typedCases(cases, selectorTp, resTp)
+ val caseTypes = casesTyped map (c => packedType(c, context.owner).deconst)
+ val (ownType, needAdapt) = if (isFullyDefined(resTp)) (resTp, false) else weakLub(caseTypes)
+
+ val casesAdapted = if (!needAdapt) casesTyped else casesTyped map (adaptCase(_, mode, ownType))
+
+ (selector1, selectorTp, casesAdapted, ownType, doTranslation)
+ }
+
+ // match has been typed, now translate it
+ def translatedMatch(selector1: Tree, selectorTp: Type, casesAdapted: List[CaseDef], ownType: Type, doTranslation: Boolean, matchFailGen: Option[Tree => Tree] = None) = {
+ def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match {
+ case TypeRef(_, RepeatedParamClass, arg :: Nil) => seqType(arg)
+ case _ => tp
}
- if (isSynthSelector(selector1)) { // a switch
- (Match(selector1, casesAdapted) setType ownType, ownType) // setType of the Match to avoid recursing endlessly
+ if (!doTranslation) { // a switch
+ Match(selector1, casesAdapted) setType ownType // setType of the Match to avoid recursing endlessly
} else {
val scrutType = repeatedToSeq(elimAnonymousClass(selectorTp))
- (MatchTranslator(this).translateMatch(selector1, casesAdapted, repeatedToSeq(ownType), scrutType, matchFailGen), ownType)
+ // we've packed the type for each case in typedMatch so that if all cases have the same existential case, we get a clean lub
+ // here, we should open up the existential again
+ // relevant test cases: pos/existentials-harmful.scala, pos/gadt-gilles.scala, pos/t2683.scala, pos/virtpatmat_exist4.scala
+ // TODO: fix skolemizeExistential (it should preserve annotations, right?)
+ val ownTypeSkolemized = ownType.skolemizeExistential(context.owner, context.tree) withAnnotations ownType.annotations
+ MatchTranslator(this).translateMatch(selector1, casesAdapted, repeatedToSeq(ownTypeSkolemized), scrutType, matchFailGen)
}
}
- // TODO: use this to synthesize (partial)function implementation for matches from the get-go,
- // instead of the dirty post-factum hacks in uncurry -- typedMatchAnonFun is currently not used due to mindboggling failures (see virtpatmat_anonfun_for.scala)
- def typedMatchAnonFun(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type, selOverride: Option[(List[Symbol], Tree)] = None) = {
- val pt = deskolemizeGADTSkolems(pt0)
- val targs = pt.normalize.typeArgs
- val arity = if (isFunctionType(pt)) targs.length - 1 else 1
- val scrutTp0 = if (arity == 1) targs.head else /* arity > 1 */ tupleType(targs.init)
- val scrutTp = packCaptured(scrutTp0)
- val ptRes = targs.last // may not be fully defined
- val isPartial = pt.typeSymbol == PartialFunctionClass
- val cname = tpnme.ANON_FUN_NAME
- val funThis = This(cname)
- // used to create a new context for pattern matching translation so that
- // we can easily rejig the owner structure when we have the actual symbols for these methods
- // (after type checking them, but type checking requires translation -- this seems like the easiest way to end this vicious cycle)
- val applySentinel = NoSymbol.newMethod(nme.apply)
- val idaSentinel = NoSymbol.newMethod(nme._isDefinedAt)
-
- def mkParams = {
- val params =
- for (i <- List.range(0, arity)) yield atPos(tree.pos.focusStart) {
- ValDef(Modifiers(SYNTHETIC | PARAM), unit.freshTermName("x" + i + "$"), TypeTree(), EmptyTree)
- }
- val ids = params map (p => Ident(p.name))
-
- val paramsRef = selOverride match {
- case None => atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) }
- case Some((_, sel)) => sel.duplicate // we'll replace the symbols that refer to the function's original syms by the ones introduced by the DefDef once the method's been type checked (until then, we don't know them)
+ def typedMatchAnonFun(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type, selOverride: Option[(List[ValDef], Tree)] = None) = {
+ val pt = deskolemizeGADTSkolems(pt0)
+ val targs = pt.normalize.typeArgs
+ val arity = if (isFunctionType(pt)) targs.length - 1 else 1 // TODO pt should always be a (Partial)Function, right?
+ val ptRes = if (targs.isEmpty) WildcardType else targs.last // may not be fully defined
+
+ val isPartial = pt.typeSymbol == PartialFunctionClass
+ val anonClass = context.owner.newAnonymousFunctionClass(tree.pos)
+ val funThis = This(anonClass)
+ val serialVersionUIDAnnotation = AnnotationInfo(SerialVersionUIDAttr.tpe, List(Literal(Constant(0))), List())
+
+ anonClass addAnnotation serialVersionUIDAnnotation
+
+ def deriveFormals =
+ selOverride match {
+ case None if targs.isEmpty => Nil
+ case None => targs.init // is there anything we can do if targs.isEmpty??
+ case Some((vparams, _)) =>
+ vparams map {p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe}
}
- (params, paramsRef) // paramsRef can't be typed until after match has been translated, thus supply explicit scrutTp to translate below
+ def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = {
+ selOverride match {
+ case None if targs.isEmpty => MissingParameterTypeAnonMatchError(tree, pt); (Nil, EmptyTree)
+ case None =>
+ val ps = methodSym newSyntheticValueParams formals // is there anything we can do if targs.isEmpty??
+ val ids = ps map (p => Ident(p.name))
+ val sel = atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) }
+ (ps, sel)
+ case Some((vparams, sel)) =>
+ val newParamSyms = (vparams, formals).zipped map {(p, tp) =>
+ methodSym.newValueParameter(p.name, p.pos.focus, SYNTHETIC) setInfo tp
+ }
+
+ (newParamSyms, sel.duplicate)
+ }
}
import CODE._
// need to duplicate the cases before typing them to generate the apply method, or the symbols will be all messed up
- val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => TRUE).duplicate) else Nil
+ val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => TRUE_typed).duplicate) else Nil
+ // println("casesTrue "+ casesTrue)
+ def parentsPartial(targs: List[Type]) = List(appliedType(AbstractPartialFunctionClass.typeConstructor, targs), SerializableClass.tpe)
+
+ def applyMethod = {
+ // rig the show so we can get started typing the method body -- later we'll correct the infos...
+ anonClass setInfo ClassInfoType(List(ObjectClass.tpe, pt, SerializableClass.tpe), newScope, anonClass)
+ val methodSym = anonClass.newMethod(nme.apply, tree.pos, if(isPartial) (FINAL | OVERRIDE) else FINAL)
+ val (paramSyms, selector) = mkParams(methodSym)
+
+ if (selector eq EmptyTree) EmptyTree
+ else {
+ methodSym setInfoAndEnter MethodType(paramSyms, AnyClass.tpe)
+
+ val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
+ paramSyms foreach (methodBodyTyper.context.scope enter _)
+
+ val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, cases, mode, ptRes)
- val (applyMethod, parents) = {
- val (params, paramsRef) = mkParams
- val (body, resTp) = newTyper(context.make(context.tree, applySentinel)).translateMatch(paramsRef, cases, mode, ptRes, scrutTp, if (isPartial) Some(scrut => (funThis DOT nme.missingCase) (scrut)) else None)
+ val methFormals = paramSyms map (_.tpe)
+ val parents =
+ if (isPartial) parentsPartial(List(methFormals.head, resTp))
+ else List(abstractFunctionType(methFormals, resTp), SerializableClass.tpe)
- def abstractFunctionType = {
- val sym = AbstractFunctionClass(arity)
- typeRef(sym.typeConstructor.prefix, sym, targs.init :+ resTp)
+ anonClass setInfo ClassInfoType(parents, newScope, anonClass)
+ methodSym setInfoAndEnter MethodType(paramSyms, resTp)
+
+ DefDef(methodSym, methodBodyTyper.translatedMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation))
}
+ }
+
+ // def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 =
+ def applyOrElseMethodDef = {
+ // rig the show so we can get started typing the method body -- later we'll correct the infos...
+ // targs were type arguments for PartialFunction, so we know they will work for AbstractPartialFunction as well
+ anonClass setInfo ClassInfoType(parentsPartial(targs), newScope, anonClass)
+ val methodSym = anonClass.newMethod(nme.applyOrElse, tree.pos, FINAL | OVERRIDE)
+
+ // create the parameter that corresponds to the function's parameter
+ val List(argTp) = deriveFormals
+ val A1 = methodSym newTypeParameter(newTypeName("A1")) setInfo TypeBounds.upper(argTp)
+ val (List(x), selector) = mkParams(methodSym, List(A1.tpe))
+
+ if (selector eq EmptyTree) EmptyTree
+ else {
+ // applyOrElse's default parameter:
+ val B1 = methodSym newTypeParameter(newTypeName("B1")) setInfo TypeBounds.empty //lower(resTp)
+ val default = methodSym newValueParameter(newTermName("default"), tree.pos.focus, SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe)
+
+ val paramSyms = List(x, default)
+ methodSym setInfoAndEnter polyType(List(A1, B1), MethodType(paramSyms, B1.tpe))
+
+ val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
+ paramSyms foreach (methodBodyTyper.context.scope enter _)
+
+ val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, cases, mode, ptRes)
+
+ anonClass setInfo ClassInfoType(parentsPartial(List(argTp, resTp)), newScope, anonClass)
+ B1 setInfo TypeBounds.lower(resTp)
+ anonClass.info.decls enter methodSym // methodSym's info need not change (B1's bound has been updated instead)
- val parents =
- if (isFunctionType(pt)) List(abstractFunctionType, SerializableClass.tpe)
- else if (isPartial) List(appliedType(AbstractPartialFunctionClass.typeConstructor, List(scrutTp, resTp)), SerializableClass.tpe)
- else List(ObjectClass.tpe, pt, SerializableClass.tpe)
+ // use applyOrElse's first parameter since the scrut's type has been widened
+ def doDefault(scrut_ignored: Tree) = REF(default) APPLY (REF(x))
- (atPos(tree.pos.focus)(DefDef(Modifiers(FINAL), nme.apply, Nil, List(params), TypeTree() setType resTp, body)), parents)
+ val body = methodBodyTyper.translatedMatch(selector1, selectorTp, casesAdapted, B1.tpe, doTranslation, Some(doDefault))
+
+ DefDef(methodSym, body)
+ }
}
def isDefinedAtMethod = {
- val (params, paramsRef) = mkParams
- val (body, _) = newTyper(context.make(context.tree, idaSentinel)).translateMatch(paramsRef, casesTrue, mode, BooleanClass.tpe, scrutTp, Some(scrutinee => FALSE))
- atPos(tree.pos.focus)(
- DefDef(Modifiers(FINAL), nme._isDefinedAt, Nil, List(params), TypeTree() setType BooleanClass.tpe, body)
- )
- }
+ val methodSym = anonClass.newMethod(nme.isDefinedAt, tree.pos, FINAL)
+ val (paramSyms, selector) = mkParams(methodSym)
+ if (selector eq EmptyTree) EmptyTree
+ else {
+ val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
+ paramSyms foreach (methodBodyTyper.context.scope enter _)
+ methodSym setInfoAndEnter MethodType(paramSyms, BooleanClass.tpe)
- val members = if (!isPartial) List(applyMethod) else List(applyMethod, isDefinedAtMethod)
+ val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, casesTrue, mode, BooleanClass.tpe)
+ val body = methodBodyTyper.translatedMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation, Some(scrutinee => FALSE_typed))
- val cmods = Modifiers(FINAL | SYNTHETIC /*TODO: when do we need INCONSTRUCTOR ?*/) withAnnotations (
- List(NEW(SerialVersionUIDAttr, LIT(0))))
- val cdef =
- ClassDef(cmods, cname, Nil,
- Template(parents map (TypeTree() setType _), emptyValDef, Modifiers(0), Nil, List(Nil), members, tree.pos)
- )
- val funInst = (Block(List(cdef), Apply(Select(New(Ident(cname)), nme.CONSTRUCTOR), Nil)))
-
- val res = typed(funInst, mode, pt)
-
- // now that we have the symbols corresponding to the apply/isDefinedAt methods,
- // we can fix up the result of fixerUpper... URGH
- // fixerUpper nests the top-level definitions generated in the match under context.owner, but they should be owner by the apply/isDefinedAt method
- res foreach {
- case d: DefDef if (d.symbol.name == nme.apply) =>
- d.rhs.changeOwner(applySentinel -> d.symbol)
- case d: DefDef if (d.symbol.name == nme._isDefinedAt) =>
- d.rhs.changeOwner(idaSentinel -> d.symbol)
- case _ =>
+ DefDef(methodSym, body)
+ }
}
- selOverride match {
- case None => res
- case Some((paramSyms, sel)) =>
- object substParamSyms extends Transformer {
- override def transform(t: Tree): Tree = t match {
- case d: DefDef if (d.symbol.name == nme.apply) || (d.symbol.name == nme._isDefinedAt) && (d.symbol.owner == res.tpe.typeSymbol) =>
- deriveDefDef(d)(rhs => rhs.substTreeSyms(paramSyms, d.vparamss.head.map(_.symbol)))
- case _ =>
- super.transform(t)
- }
- }
- substParamSyms.transform(res)
- }
+ val members = if (isPartial) {
+ // TODO: don't check for MarkerCPSTypes -- check whether all targs are subtype of any (which they are not under CPS)
+ if ((MarkerCPSTypes ne NoSymbol) && (targs exists (_ hasAnnotation MarkerCPSTypes))) List(applyMethod, isDefinedAtMethod)
+ else List(applyOrElseMethodDef, isDefinedAtMethod)
+ } else List(applyMethod)
+
+ if (members.head eq EmptyTree) setError(tree)
+ else typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt)
}
/**
@@ -2302,7 +2410,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (argpts.lengthCompare(numVparams) != 0)
WrongNumberOfParametersError(fun, argpts)
else {
- val vparamSyms = map2(fun.vparams, argpts) { (vparam, argpt) =>
+ foreach2(fun.vparams, argpts) { (vparam, argpt) =>
if (vparam.tpt.isEmpty) {
vparam.tpt.tpe =
if (isFullyDefined(argpt)) argpt
@@ -2326,30 +2434,28 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
if (!vparam.tpt.pos.isDefined) vparam.tpt setPos vparam.pos.focus
}
- enterSym(context, vparam)
- if (context.retyping) context.scope enter vparam.symbol
- vparam.symbol
}
- val vparams = fun.vparams mapConserve (typedValDef)
-// for (vparam <- vparams) {
-// checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()
-// }
-
- def recompose(from: Type, to: Type) =
- if(clazz == PartialFunctionClass) appliedType(PartialFunctionClass.typeConstructor, List(from, to))
- else functionType(List(from), to)
-
fun.body match {
- case Match(sel, cases) if opt.virtPatmat =>
- val typedSel = typed(sel, EXPRmode | BYVALmode, WildcardType)
+ // later phase indicates scaladoc is calling (where shit is messed up, I tell you)
+ // -- so fall back to old patmat, which is more forgiving
+ case Match(sel, cases) if doMatchTranslation =>
// go to outer context -- must discard the context that was created for the Function since we're discarding the function
// thus, its symbol, which serves as the current context.owner, is not the right owner
// you won't know you're using the wrong owner until lambda lift crashes (unless you know better than to use the wrong owner)
- newTyper(context.outer).typedMatchAnonFun(fun, cases, mode, recompose(typedSel.tpe, respt), Some((vparamSyms, typedSel)))
+ newTyper(context.outer).typedMatchAnonFun(fun, cases, mode, pt, Some((fun.vparams, sel)))
case _ =>
- val body1 = typed(fun.body, respt)
+ val vparamSyms = fun.vparams map { vparam =>
+ enterSym(context, vparam)
+ if (context.retyping) context.scope enter vparam.symbol
+ vparam.symbol
+ }
+ val vparams = fun.vparams mapConserve (typedValDef)
+ // for (vparam <- vparams) {
+ // checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()
+ // }
val formals = vparamSyms map (_.tpe)
+ val body1 = typed(fun.body, respt)
val restpe = packedType(body1, fun.symbol).deconst.resultType
val funtpe = typeRef(clazz.tpe.prefix, clazz, formals :+ restpe)
// body = checkNoEscaping.locals(context.scope, restpe, body)
@@ -2445,54 +2551,53 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
|| (looker.hasAccessorFlag && !accessed.hasAccessorFlag && accessed.isPrivate)
)
- def checkNoDoubleDefsAndAddSynthetics(stats: List[Tree]): List[Tree] = {
+ def checkNoDoubleDefs(stats: List[Tree]): Unit = {
val scope = if (inBlock) context.scope else context.owner.info.decls
- var newStats = new ListBuffer[Tree]
- var needsCheck = true
- var moreToAdd = true
- while (moreToAdd) {
- val initSize = scope.size
- var e = scope.elems
- while ((e ne null) && e.owner == scope) {
-
- // check no double def
- if (needsCheck) {
- var e1 = scope.lookupNextEntry(e)
- while ((e1 ne null) && e1.owner == scope) {
- if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) &&
- (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe) || e.sym.isMacro && e1.sym.isMacro))
- // default getters are defined twice when multiple overloads have defaults. an
- // error for this is issued in RefChecks.checkDefaultsInOverloaded
- if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefaultFlag &&
- !e.sym.hasAnnotation(BridgeClass) && !e1.sym.hasAnnotation(BridgeClass)) {
- log("Double definition detected:\n " +
- ((e.sym.getClass, e.sym.info, e.sym.ownerChain)) + "\n " +
- ((e1.sym.getClass, e1.sym.info, e1.sym.ownerChain)))
-
- DefDefinedTwiceError(e.sym, e1.sym)
- scope.unlink(e1) // need to unlink to avoid later problems with lub; see #2779
- }
- e1 = scope.lookupNextEntry(e1)
+ var e = scope.elems
+ while ((e ne null) && e.owner == scope) {
+ var e1 = scope.lookupNextEntry(e)
+ while ((e1 ne null) && e1.owner == scope) {
+ if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) &&
+ (e.sym.isType || inBlock || (e.sym.tpe matches e1.sym.tpe)))
+ // default getters are defined twice when multiple overloads have defaults. an
+ // error for this is issued in RefChecks.checkDefaultsInOverloaded
+ if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefaultFlag &&
+ !e.sym.hasAnnotation(BridgeClass) && !e1.sym.hasAnnotation(BridgeClass)) {
+ log("Double definition detected:\n " +
+ ((e.sym.getClass, e.sym.info, e.sym.ownerChain)) + "\n " +
+ ((e1.sym.getClass, e1.sym.info, e1.sym.ownerChain)))
+
+ DefDefinedTwiceError(e.sym, e1.sym)
+ scope.unlink(e1) // need to unlink to avoid later problems with lub; see #2779
}
- }
-
- // add synthetics
- context.unit.synthetics get e.sym foreach { tree =>
- newStats += typedStat(tree) // might add even more synthetics to the scope
- context.unit.synthetics -= e.sym
+ e1 = scope.lookupNextEntry(e1)
}
-
e = e.next
}
- needsCheck = false
- // the type completer of a synthetic might add more synthetics. example: if the
- // factory method of a case class (i.e. the constructor) has a default.
- moreToAdd = initSize != scope.size
+ }
+
+ def addSynthetics(stats: List[Tree]): List[Tree] = {
+ val scope = if (inBlock) context.scope else context.owner.info.decls
+ var newStats = new ListBuffer[Tree]
+ var moreToAdd = true
+ while (moreToAdd) {
+ val initElems = scope.elems
+ for (sym <- scope)
+ for (tree <- context.unit.synthetics get sym) {
+ newStats += typedStat(tree) // might add even more synthetics to the scope
+ context.unit.synthetics -= sym
+ }
+ // the type completer of a synthetic might add more synthetics. example: if the
+ // factory method of a case class (i.e. the constructor) has a default.
+ moreToAdd = scope.elems ne initElems
}
if (newStats.isEmpty) stats
else {
// put default getters next to the method they belong to,
// same for companion objects. fixes #2489 and #4036.
+ // [Martin] This is pretty ugly. I think we could avoid
+ // this code by associating defaults and companion objects
+ // with the original tree instead of the new symbol.
def matches(stat: Tree, synt: Tree) = (stat, synt) match {
case (DefDef(_, statName, _, _, _, _), DefDef(mods, syntName, _, _, _, _)) =>
mods.hasDefaultFlag && syntName.toString.startsWith(statName.toString)
@@ -2522,7 +2627,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
context.updateBuffer(statsErrors)
if (phase.erasedTypes) stats1
- else checkNoDoubleDefsAndAddSynthetics(stats1)
+ else {
+ checkNoDoubleDefs(stats1)
+ addSynthetics(stats1)
+ }
}
def typedArg(arg: Tree, mode: Int, newmode: Int, pt: Type): Tree = {
@@ -2546,7 +2654,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
else if (isByNameParamType(formals.head)) 0
else BYVALmode
)
- val tree = typedArg(args.head, mode, typedMode, adapted.head)
+ var tree = typedArg(args.head, mode, typedMode, adapted.head)
+ if (hasPendingMacroExpansions) tree = macroExpandAll(this, tree)
// formals may be empty, so don't call tail
tree :: loop(args.tail, formals drop 1, adapted.tail)
}
@@ -2708,6 +2817,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def tryNamesDefaults: Tree = {
val lencmp = compareLengths(args, formals)
+ def checkNotMacro() = {
+ if (fun.symbol != null && fun.symbol.filter(sym => sym != null && sym.isTermMacro && !sym.isErroneous) != NoSymbol)
+ duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun))
+ }
+
if (mt.isErroneous) duplErrTree
else if (inPatternMode(mode)) {
// #2064
@@ -2726,8 +2840,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
else if (isIdentity(argPos) && !isNamedApplyBlock(fun)) {
// if there's no re-ordering, and fun is not transformed, no need to transform
// more than an optimization, e.g. important in "synchronized { x = update-x }"
+ checkNotMacro()
doTypedApply(tree, fun, namelessArgs, mode, pt)
} else {
+ checkNotMacro()
transformNamedApplication(Typer.this, mode, pt)(
treeCopy.Apply(tree, fun, namelessArgs), argPos)
}
@@ -2735,6 +2851,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// defaults are needed. they are added to the argument list in named style as
// calls to the default getters. Example:
// foo[Int](a)() ==> foo[Int](a)(b = foo$qual.foo$default$2[Int](a))
+ checkNotMacro()
val fun1 = transformNamedApplication(Typer.this, mode, pt)(fun, x => x)
if (fun1.isErroneous) duplErrTree
else {
@@ -2773,7 +2890,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
(args exists isNamed) || // uses a named argument
isNamedApplyBlock(fun)) { // fun was transformed to a named apply block =>
// integrate this application into the block
- tryNamesDefaults
+ if (dyna.isApplyDynamicNamed(fun)) dyna.typedNamedApply(tree, fun, args, mode, pt)
+ else tryNamesDefaults
} else {
val tparams = context.extractUndetparams()
if (tparams.isEmpty) { // all type params are defined
@@ -2986,7 +3104,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (annInfo.atp.isErroneous) { hasError = true; None }
else Some(NestedAnnotArg(annInfo))
- // use of Array.apply[T: ClassManifest](xs: T*): Array[T]
+ // use of Array.apply[T: ArrayTag](xs: T*): Array[T]
// and Array.apply(x: Int, xs: Int*): Array[Int] (and similar)
case Apply(fun, args) =>
val typedFun = typed(fun, forFunMode(mode), WildcardType)
@@ -3077,12 +3195,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
for (sym <- names) {
// make sure the flags are up to date before erroring (jvm/t3415 fails otherwise)
sym.initialize
- if (!sym.hasAnnotation(AnnotationDefaultAttr) && !sym.hasDefaultFlag)
+ if (!sym.hasAnnotation(AnnotationDefaultAttr) && !sym.hasDefault)
reportAnnotationError(AnnotationMissingArgError(ann, annType, sym))
}
if (hasError) annotationError
- else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}).setOriginal(ann).setPos(ann.pos)
+ else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}).setOriginal(Apply(typedFun, args)).setPos(ann.pos)
}
} else if (requireJava) {
reportAnnotationError(NestedAnnotationError(ann, annType))
@@ -3122,7 +3240,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def annInfo(t: Tree): AnnotationInfo = t match {
case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
- AnnotationInfo(annType, args, List()).setOriginal(ann).setPos(t.pos)
+ AnnotationInfo(annType, args, List()).setOriginal(typedAnn).setPos(t.pos)
case Block(stats, expr) =>
context.warning(t.pos, "Usage of named or default arguments transformed this annotation\n"+
@@ -3174,14 +3292,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case tp => tp
}
- (hidden map { s =>
- // Hanging onto lower bound in case anything interesting
- // happens with it.
- (s, s.existentialBound match {
- case TypeBounds(lo, hi) => TypeBounds(lo, hiBound(s))
- case _ => hiBound(s)
- })
- }).toMap
+ // Hanging onto lower bound in case anything interesting
+ // happens with it.
+ mapFrom(hidden)(s => s.existentialBound match {
+ case TypeBounds(lo, hi) => TypeBounds(lo, hiBound(s))
+ case _ => hiBound(s)
+ })
}
/** Given a set `rawSyms` of term- and type-symbols, and a type
@@ -3205,7 +3321,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val typeParams: List[Symbol] = rawSyms map { sym =>
val name = sym.name match {
case x: TypeName => x
- case x => nme.singletonName(x)
+ case x => tpnme.singletonName(x)
}
val bound = allBounds(sym)
val sowner = if (isRawParameter(sym)) context.owner else sym.owner
@@ -3332,7 +3448,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def typedClassOf(tree: Tree, tpt: Tree, noGen: Boolean = false) =
- if (!checkClassType(tpt, true, false) && noGen) tpt
+ if (!checkClassType(tpt) && noGen) tpt
else atPos(tree.pos)(gen.mkClassOf(tpt.tpe))
protected def typedExistentialTypeTree(tree: ExistentialTypeTree, mode: Int): Tree = {
@@ -3394,7 +3510,108 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case ErrorType =>
setError(treeCopy.TypeApply(tree, fun, args))
case _ =>
- TypedApplyDoesNotTakeTpeParametersError(tree, fun)
+ fun match {
+ // drop the application for an applyDynamic or selectDynamic call since it has been pushed down
+ case treeInfo.DynamicApplication(_, _) => fun
+ case _ => TypedApplyDoesNotTakeTpeParametersError(tree, fun)
+ }
+ }
+
+ object dyna {
+ import treeInfo.{isApplyDynamicName, DynamicUpdate, DynamicApplicationNamed}
+
+ def acceptsApplyDynamic(tp: Type) = tp.typeSymbol isNonBottomSubClass DynamicClass
+
+ /** Returns `Some(t)` if `name` can be selected dynamically on `qual`, `None` if not.
+ * `t` specifies the type to be passed to the applyDynamic/selectDynamic call (unless it is NoType)
+ * NOTE: currently either returns None or Some(NoType) (scala-virtualized extends this to Some(t) for selections on staged Structs)
+ */
+ def acceptsApplyDynamicWithType(qual: Tree, name: Name): Option[Type] =
+ // don't selectDynamic selectDynamic, do select dynamic at unknown type,
+ // in scala-virtualized, we may return a Some(tp) where tp ne NoType
+ if (!isApplyDynamicName(name) && acceptsApplyDynamic(qual.tpe.widen)) Some(NoType)
+ else None
+
+ def isDynamicallyUpdatable(tree: Tree) = tree match {
+ case DynamicUpdate(qual, name) =>
+ // if the qualifier is a Dynamic, that's all we need to know
+ acceptsApplyDynamic(qual.tpe)
+ case _ => false
+ }
+
+ def isApplyDynamicNamed(fun: Tree): Boolean = fun match {
+ case DynamicApplicationNamed(qual, _) if acceptsApplyDynamic(qual.tpe.widen) => true
+ case _ => false
+ // look deeper?
+ // val methPart = treeInfo.methPart(fun)
+ // println("methPart of "+ fun +" is "+ methPart)
+ // if (methPart ne fun) isApplyDynamicNamed(methPart)
+ // else false
+ }
+
+ def typedNamedApply(orig: Tree, fun: Tree, args: List[Tree], mode: Int, pt: Type): Tree = {
+ def argToBinding(arg: Tree): Tree = arg match {
+ case AssignOrNamedArg(Ident(name), rhs) => gen.mkTuple(List(CODE.LIT(name.toString), rhs))
+ case _ => gen.mkTuple(List(CODE.LIT(""), arg))
+ }
+ typed(treeCopy.Apply(orig, fun, args map argToBinding), mode, pt)
+ }
+
+ /** Translate selection that does not typecheck according to the normal rules into a selectDynamic/applyDynamic.
+ *
+ * foo.method("blah") ~~> foo.applyDynamic("method")("blah")
+ * foo.method(x = "blah") ~~> foo.applyDynamicNamed("method")(("x", "blah"))
+ * foo.varia = 10 ~~> foo.updateDynamic("varia")(10)
+ * foo.field ~~> foo.selectDynamic("field")
+ * foo.arr(10) = 13 ~~> foo.selectDynamic("arr").update(10, 13)
+ *
+ * what if we want foo.field == foo.selectDynamic("field") == 1, but `foo.field = 10` == `foo.selectDynamic("field").update(10)` == ()
+ * what would the signature for selectDynamic be? (hint: it needs to depend on whether an update call is coming or not)
+ *
+ * need to distinguish selectDynamic and applyDynamic somehow: the former must return the selected value, the latter must accept an apply or an update
+ * - could have only selectDynamic and pass it a boolean whether more is to come,
+ * so that it can either return the bare value or something that can handle the apply/update
+ * HOWEVER that makes it hard to return unrelated values for the two cases
+ * --> selectDynamic's return type is now dependent on the boolean flag whether more is to come
+ * - simplest solution: have two method calls
+ *
+ */
+ def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] =
+ acceptsApplyDynamicWithType(qual, name) map { tp =>
+ // tp eq NoType => can call xxxDynamic, but not passing any type args (unless specified explicitly by the user)
+ // in scala-virtualized, when not NoType, tp is passed as type argument (for selection on a staged Struct)
+
+ // strip off type application -- we're not doing much with outer, so don't bother preserving cxTree's attributes etc
+ val (outer, explicitTargs) = cxTree match {
+ case TypeApply(fun, targs) => (fun, targs)
+ case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
+ case t => (t, Nil)
+ }
+
+ @inline def hasNamedArg(as: List[Tree]) = as collectFirst {case AssignOrNamedArg(lhs, rhs) =>} nonEmpty
+
+ // note: context.tree includes at most one Apply node
+ // thus, we can't use it to detect we're going to receive named args in expressions such as:
+ // qual.sel(a)(a2, arg2 = "a2")
+ val oper = outer match {
+ case Apply(`tree`, as) =>
+ val oper =
+ if (hasNamedArg(as)) nme.applyDynamicNamed
+ else nme.applyDynamic
+ // not supported: foo.bar(a1,..., an: _*)
+ if (treeInfo.isWildcardStarArgList(as)) {
+ DynamicVarArgUnsupported(tree, oper)
+ return Some(setError(tree))
+ } else oper
+ case Assign(`tree`, _) => nme.updateDynamic
+ case _ => nme.selectDynamic
+ }
+
+ val dynSel = Select(qual, oper)
+ val tappSel = if (explicitTargs nonEmpty) TypeApply(dynSel, explicitTargs) else dynSel
+
+ atPos(qual.pos)(Apply(tappSel, List(Literal(Constant(name.decode)))))
+ }
}
@inline final def deindentTyping() = context.typingIndentLevel -= 2
@@ -3408,7 +3625,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
println(s)
}
- protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = {
+ def typed1(tree: Tree, mode: Int, pt: Type): Tree = {
def isPatternMode = inPatternMode(mode)
//Console.println("typed1("+tree.getClass()+","+Integer.toHexString(mode)+","+pt+")")
@@ -3422,10 +3639,26 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def typedAnnotated(ann: Tree, arg1: Tree): Tree = {
- def mkTypeTree(tpe: Type) = TypeTree(tpe) setOriginal tree setPos tree.pos.focus
/** mode for typing the annotation itself */
val annotMode = mode & ~TYPEmode | EXPRmode
+ def resultingTypeTree(tpe: Type) = {
+ // we need symbol-ful originals for reification
+ // hence we go the extra mile to hand-craft tis guy
+ val original =
+ if (arg1.isType)
+ (tree, arg1) match {
+ case (Annotated(annot, arg), tt @ TypeTree()) => Annotated(annot, tt.original)
+ // this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)"
+ case (Annotated(annot, arg), _) => Annotated(annot, arg1)
+ case _ => throw new Error("unexpected trees in typedAnnotated: tree = %s, arg1 = %s".format(showRaw(tree), showRaw(arg1)))
+ }
+ else
+ tree
+ original setType ann.tpe
+ TypeTree(tpe) setOriginal original setPos tree.pos.focus
+ }
+
if (arg1.isType) {
// make sure the annotation is only typechecked once
if (ann.tpe == null) {
@@ -3468,11 +3701,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
arg1 // simply drop erroneous annotations
else {
ann.tpe = atype
- mkTypeTree(atype)
+ resultingTypeTree(atype)
}
} else {
// the annotation was typechecked before
- mkTypeTree(ann.tpe)
+ resultingTypeTree(ann.tpe)
}
}
else {
@@ -3481,7 +3714,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
ann.tpe = arg1.tpe.withAnnotation(annotInfo)
}
val atype = ann.tpe
- Typed(arg1, mkTypeTree(atype)) setPos tree.pos setType atype
+ Typed(arg1, resultingTypeTree(atype)) setPos tree.pos setType atype
}
}
@@ -3526,7 +3759,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
treeCopy.ArrayValue(tree, elemtpt1, elems1)
.setType(
(if (isFullyDefined(pt) && !phase.erasedTypes) pt
- else appliedType(ArrayClass.typeConstructor, List(elemtpt1.tpe))).notNull)
+ else arrayType(elemtpt1.tpe)).notNull)
}
def typedAssign(lhs: Tree, rhs: Tree): Tree = {
@@ -3551,10 +3784,17 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case _ =>
}
}
+// if (varsym.isVariable ||
+// // setter-rewrite has been done above, so rule out methods here, but, wait a minute, why are we assigning to non-variables after erasure?!
+// (phase.erasedTypes && varsym.isValue && !varsym.isMethod)) {
if (varsym.isVariable || varsym.isValue && phase.erasedTypes) {
val rhs1 = typed(rhs, EXPRmode | BYVALmode, lhs1.tpe)
treeCopy.Assign(tree, lhs1, checkDead(rhs1)) setType UnitClass.tpe
}
+ else if(dyna.isDynamicallyUpdatable(lhs1)) {
+ val rhs1 = typed(rhs, EXPRmode | BYVALmode, WildcardType)
+ typed1(Apply(lhs1, List(rhs1)), mode, pt)
+ }
else fail()
}
@@ -3569,9 +3809,16 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
lazy val thenTp = packedType(thenp1, context.owner)
lazy val elseTp = packedType(elsep1, context.owner)
+ // println("typedIf: "+(thenp1.tpe, elsep1.tpe, ptOrLub(List(thenp1.tpe, elsep1.tpe)),"\n", thenTp, elseTp, thenTp =:= elseTp))
val (owntype, needAdapt) =
- // virtpatmat needs more aggressive unification of skolemized types, but lub is not robust enough --> middle ground
- if (opt.virtPatmat && !isPastTyper && thenTp =:= elseTp) (thenTp, true) // this breaks src/library/scala/collection/immutable/TrieIterator.scala
+ // in principle we should pack the types of each branch before lubbing, but lub doesn't really work for existentials anyway
+ // in the special (though common) case where the types are equal, it pays to pack before comparing
+ // especially virtpatmat needs more aggressive unification of skolemized types
+ // this breaks src/library/scala/collection/immutable/TrieIterator.scala
+ if ( opt.virtPatmat && !isPastTyper
+ && thenp1.tpe.annotations.isEmpty && elsep1.tpe.annotations.isEmpty // annotated types need to be lubbed regardless (at least, continations break if you by pass them like this)
+ && thenTp =:= elseTp
+ ) (thenp1.tpe, false) // use unpacked type
// TODO: skolemize (lub of packed types) when that no longer crashes on files/pos/t4070b.scala
else ptOrLub(List(thenp1.tpe, elsep1.tpe))
@@ -3583,11 +3830,14 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
- def typedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = {
- if (opt.virtPatmat && !isPastTyper) {
- if (selector ne EmptyTree) typed(translateMatch(selector, cases, mode, pt)._1, mode, pt)
- else typedMatchAnonFun(tree, cases, mode, pt)
+ def typedTranslatedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = {
+ if (doMatchTranslation) {
+ if (selector ne EmptyTree) {
+ val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt)
+ typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt)
+ } else typedMatchAnonFun(tree, cases, mode, pt)
} else if (selector == EmptyTree) {
+ if (opt.virtPatmat) debugwarn("virtpatmat should not encounter empty-selector matches "+ tree)
val arity = if (isFunctionType(pt)) pt.normalize.typeArgs.length - 1 else 1
val params = for (i <- List.range(0, arity)) yield
atPos(tree.pos.focusStart) {
@@ -3639,9 +3889,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def typedNew(tpt: Tree) = {
val tpt1 = {
val tpt0 = typedTypeConstructor(tpt)
- if (checkClassType(tpt0, false, true))
+ if (checkStablePrefixClassType(tpt0))
if (tpt0.hasSymbol && !tpt0.symbol.typeParams.isEmpty) {
context.undetparams = cloneSymbols(tpt0.symbol.typeParams)
+ notifyUndetparamsAdded(context.undetparams)
TypeTree().setOriginal(tpt0)
.setType(appliedType(tpt0.tpe, context.undetparams map (_.tpeHK))) // @PP: tpeHK! #3343, #4018, #4347.
} else tpt0
@@ -3996,7 +4247,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
} else {
member(qual, name)
}
- if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & EXPRmode) != 0) {
+
+ // symbol not found? --> try to convert implicitly to a type that does have the required member
+ // added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an xml member to StringContext, which in turn has an unapply[Seq] method)
+ if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & (EXPRmode | PATTERNmode)) != 0) {
val qual1 =
if (member(qual, name) != NoSymbol) qual
else adaptToMemberWithArgs(tree, qual, name, mode, true, true)
@@ -4004,6 +4258,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (qual1 ne qual)
return typed(treeCopy.Select(tree, qual1, name), mode, pt)
}
+
if (!reallyExists(sym)) {
if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) {
val tree1 = atPos(tree.pos) { gen.convertToSelectFromType(qual, name) }
@@ -4011,16 +4266,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
// try to expand according to Dynamic rules.
-
- if (settings.Xexperimental.value && (qual.tpe.widen.typeSymbol isNonBottomSubClass DynamicClass)) {
- var dynInvoke = Apply(Select(qual, nme.applyDynamic), List(Literal(Constant(name.decode))))
- context.tree match {
- case Apply(tree1, args) if tree1 eq tree =>
- ;
- case _ =>
- dynInvoke = Apply(dynInvoke, List())
- }
- return typed1(util.trace("dynatype: ")(dynInvoke), mode, pt)
+ dyna.mkInvoke(context.tree, tree, qual, name) match {
+ case Some(invocation) =>
+ return typed1(invocation, mode, pt)
+ case _ =>
}
if (settings.debug.value) {
@@ -4079,7 +4328,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
result match {
// could checkAccessible (called by makeAccessible) potentially have skipped checking a type application in qual?
- case SelectFromTypeTree(qual@TypeTree(), name) if qual.tpe.typeArgs nonEmpty => // TODO: somehow the new qual is not checked in refchecks
+ case SelectFromTypeTree(qual@TypeTree(), name) if qual.tpe.typeArgs.nonEmpty => // TODO: somehow the new qual is not checked in refchecks
treeCopy.SelectFromTypeTree(
result,
(TypeTreeWithDeferredRefCheck(){ () => val tp = qual.tpe; val sym = tp.typeSymbolDirect
@@ -4157,7 +4406,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
var defEntry: ScopeEntry = null // the scope entry of defSym, if defined in a local scope
var cx = startingIdentContext
- while (defSym == NoSymbol && cx != NoContext) {
+ while (defSym == NoSymbol && cx != NoContext && (cx.scope ne null)) { // cx.scope eq null arises during FixInvalidSyms in Duplicators
// !!! Shouldn't the argument to compileSourceFor be cx, not context?
// I can't tell because those methods do nothing in the standard compiler,
// presumably they are overridden in the IDE.
@@ -4472,7 +4721,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
typedIf(cond, thenp, elsep)
case tree @ Match(selector, cases) =>
- typedMatch(tree, selector, cases)
+ typedTranslatedMatch(tree, selector, cases)
case Return(expr) =>
typedReturn(expr)
@@ -4488,9 +4737,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
catches1 = catches1 map (adaptCase(_, mode, owntype))
}
- if(!isPastTyper && opt.virtPatmat) {
+ if (doMatchTranslation)
catches1 = (MatchTranslator(this)).translateTry(catches1, owntype, tree.pos)
- }
treeCopy.Try(tree, block1, catches1, finalizer1) setType owntype
@@ -4502,7 +4750,18 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
typedNew(tpt)
case Typed(expr, Function(List(), EmptyTree)) =>
- typedEta(checkDead(typed1(expr, mode, pt)))
+ // find out whether the programmer is trying to eta-expand a macro def
+ // to do that we need to typecheck the tree first (we need a symbol of the eta-expandee)
+ // that typecheck must not trigger macro expansions, so we explicitly prohibit them
+ // Q: "but, " - you may ask - ", `typed1` doesn't call adapt, which does macro expansion, so why explicit check?"
+ // A: solely for robustness reasons. this mechanism might change in the future, which might break unprotected code
+ val expr1 = context.withMacrosDisabled(typed1(expr, mode, pt))
+ expr1 match {
+ case macroDef if macroDef.symbol != null && macroDef.symbol.isTermMacro && !macroDef.symbol.isErroneous =>
+ MacroEtaError(expr1)
+ case _ =>
+ typedEta(checkDead(expr1))
+ }
case Typed(expr0, tpt @ Ident(tpnme.WILDCARD_STAR)) =>
val expr = typed(expr0, onlyStickyModes(mode), WildcardType)
@@ -4576,18 +4835,17 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
tpt.tpe.typeSymbol == ArrayClass &&
args.length == 1 &&
erasure.GenericArray.unapply(tpt.tpe).isDefined) => // !!! todo simplify by using extractor
- // convert new Array[T](len) to evidence[ClassManifest[T]].newArray(len)
- // convert new Array^N[T](len) for N > 1 to evidence[ClassManifest[T]].newArrayN(len)
- val Some((level, manifType)) = erasure.GenericArray.unapply(tpt.tpe)
- if (level > MaxArrayDims)
- MultiDimensionalArrayError(tree)
- else {
- val newArrayApp = atPos(tree.pos) {
- val manif = getManifestTree(tree, manifType, false)
- new ApplyToImplicitArgs(Select(manif, if (level == 1) "newArray" else "newArray"+level), args)
- }
- typed(newArrayApp, mode, pt)
+ // convert new Array[T](len) to evidence[ClassTag[T]].newArray(len)
+ // convert new Array^N[T](len) for N > 1 to evidence[ClassTag[Array[...Array[T]...]]].newArray(len), where Array HK gets applied (N-1) times
+ // [Eugene] no more MaxArrayDims. ClassTags are flexible enough to allow creation of arrays of arbitrary dimensionality (w.r.t JVM restrictions)
+ val Some((level, componentType)) = erasure.GenericArray.unapply(tpt.tpe)
+ val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.asType, List(tpe))).last
+ val newArrayApp = atPos(tree.pos) {
+ val tag = resolveArrayTag(tree.pos, tagType)
+ if (tag.isEmpty) MissingClassTagError(tree, tagType)
+ else new ApplyToImplicitArgs(Select(tag, nme.newArray), args)
}
+ typed(newArrayApp, mode, pt)
case tree1 =>
tree1
}
@@ -4634,6 +4892,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
else
typedSelect(qual1, name)
+ if (tree.isInstanceOf[PostfixSelect])
+ checkFeature(tree.pos, PostfixOpsFeature, name.decode)
+ if (tree1.symbol != null && tree1.symbol.isOnlyRefinementMember)
+ checkFeature(tree1.pos, ReflectiveCallsFeature, tree1.symbol.toString)
+
if (qual1.symbol == RootPackage) treeCopy.Ident(tree1, name)
else tree1
@@ -4647,7 +4910,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case ReferenceToBoxed(idt @ Ident(_)) =>
val id1 = typed1(idt, mode, pt) match { case id: Ident => id }
- treeCopy.ReferenceToBoxed(tree, id1) setType AnyRefClass.tpe
+ // [Eugene] am I doing it right?
+ val erasedTypes = phaseId(currentPeriod) >= currentRun.erasurePhase.id
+ val tpe = capturedVariableType(idt.symbol, erasedTypes = erasedTypes)
+ treeCopy.ReferenceToBoxed(tree, id1) setType tpe
case Literal(value) =>
tree setType (
@@ -4676,9 +4942,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
treeCopy.TypeBoundsTree(tree, lo1, hi1) setType TypeBounds(lo1.tpe, hi1.tpe)
case etpt @ ExistentialTypeTree(_, _) =>
- typerWithLocalContext(context.makeNewScope(tree, context.owner)){
+ val tree1 = typerWithLocalContext(context.makeNewScope(tree, context.owner)){
_.typedExistentialTypeTree(etpt, mode)
}
+ checkExistentialsFeature(tree1.pos, tree1.tpe, "the existential type")
+ tree1
case dc@TypeTreeWithDeferredRefCheck() => dc // TODO: should we re-type the wrapped tree? then we need to change TypeTreeWithDeferredRefCheck's representation to include the wrapped tree explicitly (instead of in its closure)
case tpt @ TypeTree() =>
@@ -4728,6 +4996,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
ptLine("typing %s: pt = %s".format(ptTree(tree), pt),
"undetparams" -> context.undetparams,
"implicitsEnabled" -> context.implicitsEnabled,
+ "enrichmentEnabled" -> context.enrichmentEnabled,
+ "mode" -> modeString(mode),
"silent" -> context.bufferErrors,
"context.owner" -> context.owner
)
@@ -4831,7 +5101,22 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// We disable implicits because otherwise some constructs will
// type check which should not. The pattern matcher does not
// perform implicit conversions in an attempt to consummate a match.
- context.withImplicitsDisabled(typed(tree, PATTERNmode, pt))
+
+ // on the one hand,
+ // "abc" match { case Seq('a', 'b', 'c') => true }
+ // should be ruled out statically, otherwise this is a runtime
+ // error both because there is an implicit from String to Seq
+ // (even though such implicits are not used by the matcher) and
+ // because the typer is fine with concluding that "abc" might
+ // be of type "String with Seq[T]" and thus eligible for a call
+ // to unapplySeq.
+
+ // on the other hand, we want to be able to use implicits to add members retro-actively (e.g., add xml to StringContext)
+
+ // as a compromise, context.enrichmentEnabled tells adaptToMember to go ahead and enrich,
+ // but arbitrary conversions (in adapt) are disabled
+ // TODO: can we achieve the pattern matching bit of the string interpolation SIP without this?
+ context.withImplicitsDisabledAllowEnrichment(typed(tree, PATTERNmode, pt))
}
/** Types a (fully parameterized) type tree */
@@ -4884,31 +5169,47 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def typedTypeConstructor(tree: Tree): Tree = typedTypeConstructor(tree, NOmode)
def computeType(tree: Tree, pt: Type): Type = {
+ // macros employ different logic of `computeType`
+ assert(!context.owner.isTermMacro, context.owner)
val tree1 = typed(tree, pt)
transformed(tree) = tree1
- packedType(tree1, context.owner)
+ val tpe = packedType(tree1, context.owner)
+ checkExistentialsFeature(tree.pos, tpe, "inferred existential type")
+ tpe
}
- def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match {
- case Some(tree1) => transformed -= tree; tree1
- case None => typed(tree, mode, pt)
+ def computeMacroDefType(tree: Tree, pt: Type): Type = {
+ assert(context.owner.isTermMacro, context.owner)
+ assert(tree.symbol.isTermMacro, tree.symbol)
+ assert(tree.isInstanceOf[DefDef], tree.getClass)
+ val ddef = tree.asInstanceOf[DefDef]
+
+ val tree1 =
+ if (transformed contains ddef.rhs) {
+ // macro defs are typechecked in `methodSig` (by calling this method) in order to establish their link to macro implementation asap
+ // if a macro def doesn't have explicitly specified return type, this method will be called again by `assignTypeToTree`
+ // here we guard against this case
+ transformed(ddef.rhs)
+ } else {
+ val tree1 = typedMacroBody(this, ddef)
+ transformed(ddef.rhs) = tree1
+ tree1
+ }
+
+ val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous))
+ if (isMacroBodyOkay) computeMacroDefTypeFromMacroImpl(ddef, tree.symbol, tree1.symbol) else AnyClass.tpe
}
- def findManifest(tp: Type, full: Boolean) = beforeTyper {
- inferImplicit(
- EmptyTree,
- appliedType((if (full) FullManifestClass else PartialManifestClass).typeConstructor, List(tp)),
- true, false, context)
+ def transformedOr(tree: Tree, op: => Tree): Tree = transformed.get(tree) match {
+ case Some(tree1) => transformed -= tree; tree1
+ case None => op
}
- def getManifestTree(tree: Tree, tp: Type, full: Boolean): Tree = {
- val manifestOpt = findManifest(tp, full)
- if (manifestOpt.tree.isEmpty) {
- MissingManifestError(tree, full, tp)
- } else {
- manifestOpt.tree
- }
+ def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match {
+ case Some(tree1) => transformed -= tree; tree1
+ case None => typed(tree, mode, pt)
}
+
/*
def convertToTypeTree(tree: Tree): Tree = tree match {
case TypeTree() => tree
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 4f5b6868ae..1ebcea4a07 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -112,8 +112,8 @@ trait Unapplies extends ast.TreeDSL
private def toIdent(x: DefTree) = Ident(x.name) setPos x.pos.focus
- private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = {
- val tycon = REF(cdef.symbol)
+ private def classType(cdef: ClassDef, tparams: List[TypeDef], symbolic: Boolean = true): Tree = {
+ val tycon = if (symbolic) REF(cdef.symbol) else Ident(cdef.name)
if (tparams.isEmpty) tycon else AppliedTypeTree(tycon, tparams map toIdent)
}
@@ -166,15 +166,20 @@ trait Unapplies extends ast.TreeDSL
/** The apply method corresponding to a case class
*/
- def caseModuleApplyMeth(cdef: ClassDef): DefDef = {
+ def factoryMeth(mods: Modifiers, name: TermName, cdef: ClassDef, symbolic: Boolean): DefDef = {
val tparams = cdef.tparams map copyUntypedInvariant
val cparamss = constrParamss(cdef)
+ def classtpe = classType(cdef, tparams, symbolic)
atPos(cdef.pos.focus)(
- DefDef(caseMods, nme.apply, tparams, cparamss, classType(cdef, tparams),
- New(classType(cdef, tparams), mmap(cparamss)(gen.paramToArg)))
+ DefDef(mods, name, tparams, cparamss, classtpe,
+ New(classtpe, mmap(cparamss)(gen.paramToArg)))
)
}
+ /** The apply method corresponding to a case class
+ */
+ def caseModuleApplyMeth(cdef: ClassDef): DefDef = factoryMeth(caseMods, nme.apply, cdef, symbolic = true)
+
/** The unapply method corresponding to a case class
*/
def caseModuleUnapplyMeth(cdef: ClassDef): DefDef = {
@@ -195,7 +200,7 @@ trait Unapplies extends ast.TreeDSL
def caseClassCopyMeth(cdef: ClassDef): Option[DefDef] = {
def isDisallowed(vd: ValDef) = isRepeatedParamType(vd.tpt) || isByNameParamType(vd.tpt)
val cparamss = constrParamss(cdef)
- val flat = cparamss flatten
+ val flat = cparamss.flatten
if (cdef.symbol.hasAbstractFlag || (flat exists isDisallowed)) None
else {
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index ce10ee34a2..48ec941b50 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -26,12 +26,12 @@ object ClassPath {
def scalaLibrary = locate[Option[_]]
def scalaCompiler = locate[Global]
- def infoFor[T](value: T) = info(value.getClass)
- def info[T](clazz: Class[T]) = new ClassAndJarInfo()(ClassManifest fromClass clazz)
- def info[T: ClassManifest] = new ClassAndJarInfo[T]
- def locate[T: ClassManifest] = info[T] rootClasspath
- def locateJar[T: ClassManifest] = info[T].rootPossibles find (x => isJarOrZip(x)) map (x => File(x))
- def locateDir[T: ClassManifest] = info[T].rootPossibles find (_.isDirectory) map (_.toDirectory)
+ def infoFor[T](value: T) = info(value.getClass)
+ def info[T](clazz: Class[T]) = new ClassAndJarInfo()(ClassTag[T](clazz))
+ def info[T: ClassTag] = new ClassAndJarInfo[T]
+ def locate[T: ClassTag] = info[T].rootClasspath
+ def locateJar[T: ClassTag] = info[T].rootPossibles find (x => isJarOrZip(x)) map (x => File(x))
+ def locateDir[T: ClassTag] = info[T].rootPossibles find (_.isDirectory) map (_.toDirectory)
/** Expand single path entry */
private def expandS(pattern: String): List[String] = {
@@ -373,7 +373,7 @@ extends ClassPath[T] {
this(entries.toIndexedSeq, context)
def name = entries.head.name
- def asURLs = entries flatMap (_.asURLs) toList
+ def asURLs = (entries flatMap (_.asURLs)).toList
lazy val sourcepaths: IndexedSeq[AbstractFile] = entries flatMap (_.sourcepaths)
override def origin = Some(entries map (x => x.origin getOrElse x.name) mkString ("Merged(", ", ", ")"))
diff --git a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala b/src/compiler/scala/tools/nsc/util/CommandLineParser.scala
index 00fe49d36a..78bfd5e908 100644
--- a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala
+++ b/src/compiler/scala/tools/nsc/util/CommandLineParser.scala
@@ -20,11 +20,10 @@ import scala.collection.mutable.ListBuffer
*/
trait ParserUtil extends Parsers {
- class ParserPlus[+T](underlying: Parser[T]) {
+ protected implicit class ParserPlus[+T](underlying: Parser[T]) {
def !~>[U](p: => Parser[U]): Parser[U] = (underlying ~! p) ^^ { case a~b => b }
def <~![U](p: => Parser[U]): Parser[T] = (underlying ~! p) ^^ { case a~b => a }
}
- protected implicit def parser2parserPlus[T](p: Parser[T]): ParserPlus[T] = new ParserPlus(p)
}
case class CommandLine(
diff --git a/src/compiler/scala/tools/nsc/util/Exceptional.scala b/src/compiler/scala/tools/nsc/util/Exceptional.scala
index 667b7d15a6..7452aa1b67 100644
--- a/src/compiler/scala/tools/nsc/util/Exceptional.scala
+++ b/src/compiler/scala/tools/nsc/util/Exceptional.scala
@@ -5,6 +5,7 @@ import java.util.concurrent.ExecutionException
import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException }
import io.{ Sources, Fileish }
import scala.tools.util.StringOps._
+import language.implicitConversions
/** A simple throwable wrapper so it looks more like a parade of
* glittering frame-shaped beauties than the other thing.
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index 53c767be20..208cd5703a 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -33,51 +33,32 @@ object Position {
}
}
-/** The Position class and its subclasses represent positions of ASTs and symbols.
- * Except for NoPosition and FakePos, every position refers to a SourceFile
- * and to an offset in the sourcefile (its `point`). For batch compilation,
- * that's all. For interactive IDE's there are also RangePositions
- * and TransparentPositions. A RangePosition indicates a start and an end
- * in addition to its point. TransparentPositions are a subclass of RangePositions.
- * Range positions that are not transparent are called opaque.
- * Trees with RangePositions need to satisfy the following invariants.
- *
- * INV1: A tree with an offset position never contains a child
- * with a range position
- * INV2: If the child of a tree with a range position also has a range position,
- * then the child's range is contained in the parent's range.
- * INV3: Opaque range positions of children of the same node are non-overlapping
- * (this means their overlap is at most a single point).
- *
- * The following tests are useful on positions:
- *
- * pos.isDefined true if position is not a NoPosition nor a FakePosition
- * pos.isRange true if position is a range
- * pos.isOpaqueRange true if position is an opaque range
- *
- * The following accessor methods are provided:
- *
- * pos.source The source file of the position, which must be defined
- * pos.point The offset of the position's point, which must be defined
- * pos.start The start of the position, which must be a range
- * pos.end The end of the position, which must be a range
- *
- * There are also convenience methods, such as
- *
- * pos.startOrPoint
- * pos.endOrPoint
- * pos.pointOrElse(default)
- *
- * These are less strict about the kind of position on which they can be applied.
- *
- * The following conversion methods are often used:
- *
- * pos.focus converts a range position to an offset position, keeping its point;
- * returns all other positions unchanged.
- * pos.makeTransparent converts an opaque range position into a transparent one.
- * returns all other positions unchanged.
- */
-trait Position {
+trait Position extends scala.reflect.api.Position with scala.reflect.api.Attachment {
+ /** Exposes itself as payload of Attachment */
+ // necessary for conformance with Attachment
+ def pos: Position = this
+
+ /** A bit weird method that is necessary to safely update positions without destroying custom attachments */
+ // necessary for conformance with Attachment
+ def withPos(newPos: scala.reflect.api.Position): scala.reflect.api.Attachment = newPos
+
+ /** Exposes itself as payload of Attachment */
+ // necessary for conformance with Attachment
+ def payload: Position = this
+
+ /** A bit weird method that is necessary to safely update positions without destroying custom attachments */
+ // necessary for conformance with Attachment
+ def withPayload(newPos: Any): scala.reflect.api.Attachment = newPos.asInstanceOf[Position]
+
+ /** Java file corresponding to the source file of this position.
+ */
+ // necessary for conformance with scala.reflect.api.Position
+ def fileInfo: java.io.File = source.file.file
+
+ /** Contents of the source file that contains this position.
+ */
+ // necessary for conformance with scala.reflect.api.Position
+ def fileContent: Array[Char] = source.content
/** An optional value containing the source file referred to by this position, or
* None if not defined.
@@ -123,74 +104,74 @@ trait Position {
def offset: Option[Int] = if (isDefined) Some(point) else None
/** The same position with a different start value (if a range) */
- def withStart(off: Int) = this
+ def withStart(off: Int): Position = this
/** The same position with a different end value (if a range) */
- def withEnd(off: Int) = this
+ def withEnd(off: Int): Position = this
/** The same position with a different point value (if a range or offset) */
- def withPoint(off: Int) = this
+ def withPoint(off: Int): Position = this
/** The same position with a different source value, and its values shifted by given offset */
- def withSource(source: SourceFile, shift: Int) = this
+ def withSource(source: SourceFile, shift: Int): Position = this
/** If this is a range, the union with the other range, with the point of this position.
* Otherwise, this position
*/
- def union(pos: Position) = this
+ def union(pos: scala.reflect.api.Position): Position = this
/** If this is a range position, the offset position of its start.
* Otherwise the position itself
*/
- def focusStart = this
+ def focusStart: Position = this
/** If this is a range position, the offset position of its point.
* Otherwise the position itself
*/
- def focus = this
+ def focus: Position = this
/** If this is a range position, the offset position of its end.
* Otherwise the position itself
*/
- def focusEnd = this
+ def focusEnd: Position = this
/** Does this position include the given position `pos`.
* This holds if `this` is a range position and its range [start..end]
* is the same or covers the range of the given position, which may or may not be a range position.
*/
- def includes(pos: Position) = false
+ def includes(pos: scala.reflect.api.Position): Boolean = false
/** Does this position properly include the given position `pos` ("properly" meaning their
* ranges are not the same)?
*/
- def properlyIncludes(pos: Position) =
+ def properlyIncludes(pos: scala.reflect.api.Position): Boolean =
includes(pos) && (start < pos.startOrPoint || pos.endOrPoint < end)
/** Does this position precede that position?
* This holds if both positions are defined and the end point of this position
* is not larger than the start point of the given position.
*/
- def precedes(pos: Position) =
+ def precedes(pos: scala.reflect.api.Position): Boolean =
isDefined && pos.isDefined && endOrPoint <= pos.startOrPoint
/** Does this position properly precede the given position `pos` ("properly" meaning their ranges
* do not share a common point).
*/
- def properlyPrecedes(pos: Position) =
+ def properlyPrecedes(pos: scala.reflect.api.Position): Boolean =
isDefined && pos.isDefined && endOrPoint < pos.startOrPoint
/** Does this position overlap with that position?
* This holds if both positions are ranges and there is an interval of
* non-zero length that is shared by both position ranges.
*/
- def overlaps(pos: Position) =
+ def overlaps(pos: scala.reflect.api.Position): Boolean =
isRange && pos.isRange &&
((pos.start < end && start < pos.end) || (start < pos.end && pos.start < end))
/** Does this position cover the same range as that position?
* Holds only if both position are ranges
*/
- def sameRange(pos: Position) =
+ def sameRange(pos: scala.reflect.api.Position): Boolean =
isRange && pos.isRange && start == pos.start && end == pos.end
def line: Int = throw new UnsupportedOperationException("Position.line")
@@ -208,11 +189,11 @@ trait Position {
* file. If the SourceFile is a normal SourceFile, simply
* return this.
*/
- def inUltimateSource(source : SourceFile) =
+ def inUltimateSource(source : SourceFile): Position =
if (source == null) this else source.positionInUltimateSource(this)
- def dbgString = toString
- def safeLine = try line catch { case _: UnsupportedOperationException => -1 }
+ def dbgString: String = toString
+ def safeLine: Int = try line catch { case _: UnsupportedOperationException => -1 }
def show: String = "["+toString+"]"
}
@@ -243,8 +224,10 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e
col + 1
}
- override def union(pos: Position) =
- if (pos.isRange) pos else this
+ override def union(pos: scala.reflect.api.Position) =
+ // [Eugene] how do I get rid of this cast?
+ // I could introduce a "type PositionType <: scala.reflect.api.Position", but that's also ugly
+ if (pos.isRange) pos.asInstanceOf[Position] else this
override def equals(that : Any) = that match {
case that : OffsetPosition => point == that.point && source.file == that.source.file
@@ -254,7 +237,7 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e
override def toString = {
val pointmsg = if (point > source.length) "out-of-bounds-" else "offset="
- "source-%s,line-%s,%s%s".format(source.path, line, pointmsg, point)
+ "source-%s,line-%s,%s%s".format(source.file.canonicalPath, line, pointmsg, point)
}
override def show = "["+point+"]"
}
@@ -278,8 +261,8 @@ extends OffsetPosition(source, point) {
}
override def focusEnd = new OffsetPosition(source, end)
override def makeTransparent = new TransparentPosition(source, start, point, end)
- override def includes(pos: Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end
- override def union(pos: Position) =
+ override def includes(pos: scala.reflect.api.Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end
+ override def union(pos: scala.reflect.api.Position): Position =
if (pos.isRange) new RangePosition(source, start min pos.start, point, end max pos.end) else this
override def toSingleLine: Position = source match {
@@ -290,7 +273,7 @@ extends OffsetPosition(source, point) {
case _ => this
}
- override def toString = "RangePosition("+source+", "+start+", "+point+", "+end+")"
+ override def toString = "RangePosition("+source.file.canonicalPath+", "+start+", "+point+", "+end+")"
override def show = "["+start+":"+end+"]"
private var focusCache: Position = NoPosition
}
@@ -300,10 +283,4 @@ class TransparentPosition(source: SourceFile, start: Int, point: Int, end: Int)
override def isTransparent = true
override def makeTransparent = this
override def show = "<"+start+":"+end+">"
-}
-
-
-
-
-
-
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
index fda713c5c6..120cceb238 100644
--- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
+++ b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
@@ -14,6 +14,8 @@ import java.net.URL
import scala.reflect.ReflectionUtils.unwrapHandler
import ScalaClassLoader._
import scala.util.control.Exception.{ catching }
+import language.implicitConversions
+
// import Exceptional.unwrap
trait HasClassPath {
@@ -65,8 +67,8 @@ trait ScalaClassLoader extends JClassLoader {
result
}
- def constructorsOf[T <: AnyRef : Manifest]: List[Constructor[T]] =
- manifest[T].erasure.getConstructors.toList map (_.asInstanceOf[Constructor[T]])
+ def constructorsOf[T <: AnyRef : ClassTag]: List[Constructor[T]] =
+ classTag[T].erasure.getConstructors.toList map (_.asInstanceOf[Constructor[T]])
/** The actual bytes for a class file, or an empty array if it can't be found. */
def classBytes(className: String): Array[Byte] = classAsStream(className) match {
@@ -123,9 +125,9 @@ object ScalaClassLoader {
def bootLoader = apply(null)
def contextChain = loaderChain(contextLoader)
- def pathToErasure[T: ClassManifest] = pathToClass(classManifest[T].erasure)
- def pathToClass(clazz: Class[_]) = clazz.getName.replace('.', JFile.separatorChar) + ".class"
- def locate[T: ClassManifest] = contextLoader getResource pathToErasure[T]
+ def pathToErasure[T: ClassTag] = pathToClass(classTag[T].erasure)
+ def pathToClass(clazz: Class[_]) = clazz.getName.replace('.', JFile.separatorChar) + ".class"
+ def locate[T: ClassTag] = contextLoader getResource pathToErasure[T]
/** Tries to guess the classpath by type matching the context classloader
* and its parents, looking for any classloaders which will reveal their
diff --git a/src/compiler/scala/tools/nsc/util/Statistics.scala b/src/compiler/scala/tools/nsc/util/Statistics.scala
index d1cdd30dd8..61c7695911 100644
--- a/src/compiler/scala/tools/nsc/util/Statistics.scala
+++ b/src/compiler/scala/tools/nsc/util/Statistics.scala
@@ -57,6 +57,9 @@ class Statistics extends scala.reflect.internal.util.Statistics {
val counter2: SubCounter = new SubCounter(subtypeCount)
val timer1: Timer = new Timer
val timer2: Timer = new Timer
+
+ val macroExpandCount = new Counter
+ val macroExpandNanos = new Timer
}
object Statistics extends Statistics
@@ -125,34 +128,36 @@ abstract class StatisticsInfo {
inform("ms type-flow-analysis: " + analysis.timer.millis)
if (phase.name == "typer") {
- inform("time spent typechecking : "+showRelTyper(typerNanos))
- inform("time classfilereading : "+showRelTyper(classReadNanos))
- inform("time spent in implicits : "+showRelTyper(implicitNanos))
- inform(" successful in scope : "+showRelTyper(inscopeSucceedNanos))
- inform(" failed in scope : "+showRelTyper(inscopeFailNanos))
- inform(" successful of type : "+showRelTyper(oftypeSucceedNanos))
- inform(" failed of type : "+showRelTyper(oftypeFailNanos))
- inform(" assembling parts : "+showRelTyper(subtypeETNanos))
- inform(" matchesPT : "+showRelTyper(matchesPtNanos))
- inform("implicit cache hits : "+showRelative(implicitCacheHits.value + implicitCacheMisses.value)(implicitCacheHits.value))
- inform("time spent in failed : "+showRelTyper(failedSilentNanos))
- inform(" failed apply : "+showRelTyper(failedApplyNanos))
- inform(" failed op= : "+showRelTyper(failedOpEqNanos))
- inform("time spent ref scanning : "+showRelTyper(isReferencedNanos))
- inform("micros by tree node : "+showCounts(microsByType))
- inform("#visits by tree node : "+showCounts(visitsByType))
+ inform("time spent typechecking : " + showRelTyper(typerNanos))
+ inform("time classfilereading : " + showRelTyper(classReadNanos))
+ inform("time spent in implicits : " + showRelTyper(implicitNanos))
+ inform(" successful in scope : " + showRelTyper(inscopeSucceedNanos))
+ inform(" failed in scope : " + showRelTyper(inscopeFailNanos))
+ inform(" successful of type : " + showRelTyper(oftypeSucceedNanos))
+ inform(" failed of type : " + showRelTyper(oftypeFailNanos))
+ inform(" assembling parts : " + showRelTyper(subtypeETNanos))
+ inform(" matchesPT : " + showRelTyper(matchesPtNanos))
+ inform("implicit cache hits : " + showRelative(implicitCacheHits.value + implicitCacheMisses.value)(implicitCacheHits.value))
+ inform("time spent in failed : " + showRelTyper(failedSilentNanos))
+ inform(" failed apply : " + showRelTyper(failedApplyNanos))
+ inform(" failed op= : " + showRelTyper(failedOpEqNanos))
+ inform("time spent ref scanning : " + showRelTyper(isReferencedNanos))
+ inform("micros by tree node : " + showCounts(microsByType))
+ inform("#visits by tree node : " + showCounts(visitsByType))
val average = new ClassCounts
for (c <- microsByType.keysIterator) average(c) = microsByType(c)/visitsByType(c)
- inform("avg micros by tree node : "+showCounts(average))
- inform("time spent in <:< : "+showRelTyper(subtypeNanos))
- inform("time spent in findmember : "+showRelTyper(findMemberNanos))
- inform("time spent in asSeenFrom : "+showRelTyper(asSeenFromNanos))
- inform("#implicit searches : " + implicitSearchCount)
+ inform("avg micros by tree node : " + showCounts(average))
+ inform("time spent in <:< : " + showRelTyper(subtypeNanos))
+ inform("time spent in findmember : " + showRelTyper(findMemberNanos))
+ inform("time spent in asSeenFrom : " + showRelTyper(asSeenFromNanos))
+ inform("#implicit searches : " + implicitSearchCount)
inform("#tried, plausible, matching, typed, found implicits: "+triedImplicits+", "+plausiblyCompatibleImplicits+", "+matchingImplicits+", "+typedImplicits+", "+foundImplicits)
- inform("#implicit improves tests : " + improvesCount)
- inform("#implicit improves cached: " + improvesCachedCount)
- inform("#implicit inscope hits : " + inscopeImplicitHits)
- inform("#implicit oftype hits : " + oftypeImplicitHits)
+ inform("#implicit improves tests : " + improvesCount)
+ inform("#implicit improves cached : " + improvesCachedCount)
+ inform("#implicit inscope hits : " + inscopeImplicitHits)
+ inform("#implicit oftype hits : " + oftypeImplicitHits)
+ inform("#macro expansions : " + macroExpandCount)
+ inform("#time spent in macroExpand : " + showRelTyper(macroExpandNanos))
}
if (ctr1 != null) inform("#ctr1 : " + ctr1)
diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala
index 88e6c51e9f..1336cca3c5 100644
--- a/src/compiler/scala/tools/nsc/util/package.scala
+++ b/src/compiler/scala/tools/nsc/util/package.scala
@@ -9,6 +9,8 @@ import java.io.{ OutputStream, PrintStream, ByteArrayOutputStream, PrintWriter,
package object util {
+ implicit def postfixOps = language.postfixOps // make all postfix ops in this package compile without warning
+
// forwarder for old code that builds against 2.9 and 2.10
val Chars = scala.reflect.internal.Chars
diff --git a/src/compiler/scala/tools/reflect/Invoked.scala b/src/compiler/scala/tools/reflect/Invoked.scala
index 30c6201a0d..516c6b9bf6 100644
--- a/src/compiler/scala/tools/reflect/Invoked.scala
+++ b/src/compiler/scala/tools/reflect/Invoked.scala
@@ -16,7 +16,7 @@ class Invoked private (val proxy: AnyRef, val m: Method, val args: List[AnyRef])
def name = m.getName
def arity = m.getParameterTypes.size
def returnType = m.getReturnType
- def returns[T: Manifest] = returnType == manifest[T].erasure
+ def returns[T: ClassTag] = returnType == classTag[T].erasure
def invokeOn(target: AnyRef) = m.invoke(target, args: _*)
def isObjectMethod = Set("toString", "equals", "hashCode") contains name
diff --git a/src/compiler/scala/tools/reflect/UniversalFn.scala b/src/compiler/scala/tools/reflect/UniversalFn.scala
index 9ccd580560..b0c2a19021 100644
--- a/src/compiler/scala/tools/reflect/UniversalFn.scala
+++ b/src/compiler/scala/tools/reflect/UniversalFn.scala
@@ -26,8 +26,8 @@ class UniversalFn private (val closure: AnyRef, val method: Method) extends (Seq
* them to this universal function. Will throw an exception in the
* face of any bad data.
*/
- def as[T: Manifest] : T = {
- val clazz = manifest[T].erasure
+ def as[T: ClassTag] : T = {
+ val clazz = classTag[T].erasure
require(clazz.isInterface, "Type argument must be an interface.")
val interfaceMethods = clazz.getDeclaredMethods.toSet
diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala
index 8f5e099fbf..0b0c0905cb 100644
--- a/src/compiler/scala/tools/reflect/package.scala
+++ b/src/compiler/scala/tools/reflect/package.scala
@@ -27,17 +27,17 @@ package object reflect {
}
}
- def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest.classType(clazz))
- def zeroOf[T](implicit m: Manifest[T]): AnyRef = {
- if (m == manifest[Boolean] || m == manifest[jl.Boolean]) false: jl.Boolean
- else if (m == manifest[Unit] || m == manifest[jl.Void] || m == manifest[scala.runtime.BoxedUnit]) scala.runtime.BoxedUnit.UNIT
- else if (m == manifest[Char] || m == manifest[jl.Character]) 0.toChar: jl.Character
- else if (m == manifest[Byte] || m == manifest[jl.Byte]) 0.toByte: jl.Byte
- else if (m == manifest[Short] || m == manifest[jl.Short]) 0.toShort: jl.Short
- else if (m == manifest[Int] || m == manifest[jl.Integer]) 0: jl.Integer
- else if (m == manifest[Long] || m == manifest[jl.Long]) 0l: jl.Long
- else if (m == manifest[Float] || m == manifest[jl.Float]) 0f: jl.Float
- else if (m == manifest[Double] || m == manifest[jl.Double]) 0d: jl.Double
+ def zeroOfClass(clazz: Class[_]) = zeroOf(ClassTag(clazz))
+ def zeroOf[T](implicit t: ClassTag[T]): AnyRef = {
+ if (t == classTag[Boolean] || t == classTag[jl.Boolean]) false: jl.Boolean
+ else if (t == classTag[Unit] || t == classTag[jl.Void] || t == classTag[scala.runtime.BoxedUnit]) scala.runtime.BoxedUnit.UNIT
+ else if (t == classTag[Char] || t == classTag[jl.Character]) 0.toChar: jl.Character
+ else if (t == classTag[Byte] || t == classTag[jl.Byte]) 0.toByte: jl.Byte
+ else if (t == classTag[Short] || t == classTag[jl.Short]) 0.toShort: jl.Short
+ else if (t == classTag[Int] || t == classTag[jl.Integer]) 0: jl.Integer
+ else if (t == classTag[Long] || t == classTag[jl.Long]) 0l: jl.Long
+ else if (t == classTag[Float] || t == classTag[jl.Float]) 0f: jl.Float
+ else if (t == classTag[Double] || t == classTag[jl.Double]) 0d: jl.Double
else null
}
}
diff --git a/src/compiler/scala/tools/util/StringOps.scala b/src/compiler/scala/tools/util/StringOps.scala
index 02eb364abe..725e0afb79 100644
--- a/src/compiler/scala/tools/util/StringOps.scala
+++ b/src/compiler/scala/tools/util/StringOps.scala
@@ -25,6 +25,16 @@ trait StringOps {
val ys = oempty(xs: _*)
if (ys.isEmpty) orElse else ys mkString sep
}
+ def trimTrailingSpace(s: String) = {
+ if (s.length == 0 || !s.charAt(s.length - 1).isWhitespace) s
+ else {
+ var idx = s.length - 1
+ while (idx >= 0 && s.charAt(idx).isWhitespace)
+ idx -= 1
+
+ s.substring(0, idx + 1)
+ }
+ }
def decompose(str: String, sep: Char): List[String] = {
def ws(start: Int): List[String] =
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
index af0d768607..bed8e93d1b 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
@@ -94,8 +94,7 @@ abstract class CPSAnnotationChecker extends CPSUtils {
if (!cpsEnabled) return bounds
val anyAtCPS = newCpsParamsMarker(NothingClass.tpe, AnyClass.tpe)
-
- if (isFunctionType(tparams.head.owner.tpe) || tparams.head.owner == PartialFunctionClass) {
+ if (isFunctionType(tparams.head.owner.tpe) || isPartialFunctionType(tparams.head.owner.tpe)) {
vprintln("function bound: " + tparams.head.owner.tpe + "/"+bounds+"/"+targs)
if (hasCpsParamTypes(targs.last))
bounds.reverse match {
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
index 075009ce5e..6f5284f75f 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
@@ -9,7 +9,7 @@ trait CPSUtils {
import global._
import definitions._
- var cpsEnabled = true
+ var cpsEnabled = false
val verbose: Boolean = System.getProperty("cpsVerbose", "false") == "true"
def vprintln(x: =>Any): Unit = if (verbose) println(x)
@@ -24,6 +24,7 @@ trait CPSUtils {
val shift = newTermName("shift")
val shiftR = newTermName("shiftR")
val shiftSuffix = newTermName("$shift")
+ val shiftUnit0 = newTermName("shiftUnit0")
val shiftUnit = newTermName("shiftUnit")
val shiftUnitR = newTermName("shiftUnitR")
}
@@ -38,6 +39,7 @@ trait CPSUtils {
lazy val ModCPS = definitions.getRequiredModule("scala.util.continuations")
lazy val MethShiftUnit = definitions.getMember(ModCPS, cpsNames.shiftUnit)
+ lazy val MethShiftUnit0 = definitions.getMember(ModCPS, cpsNames.shiftUnit0)
lazy val MethShiftUnitR = definitions.getMember(ModCPS, cpsNames.shiftUnitR)
lazy val MethShift = definitions.getMember(ModCPS, cpsNames.shift)
lazy val MethShiftR = definitions.getMember(ModCPS, cpsNames.shiftR)
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index 1189cc2e38..e1d699debc 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -71,24 +71,46 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
// { x => x match { case A => ... }} to
// { x => shiftUnit(x match { case A => ... })}
// which Uncurry cannot handle (see function6.scala)
+ // thus, we push down the shiftUnit to each of the case bodies
val ext = getExternalAnswerTypeAnn(body.tpe)
+ val pureBody = getAnswerTypeAnn(body.tpe).isEmpty
+
+ def transformPureMatch(tree: Tree, selector: Tree, cases: List[CaseDef]) = {
+ val caseVals = cases map { case cd @ CaseDef(pat, guard, body) =>
+ // if (!hasPlusMarker(body.tpe)) body.tpe = body.tpe withAnnotation newPlusMarker() // TODO: to avoid warning
+ val bodyVal = transExpr(body, None, ext) // ??? triggers "cps-transformed unexpectedly" warning in transTailValue
+ treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal)
+ }
+ treeCopy.Match(tree, transform(selector), caseVals)
+ }
+
+ def transformPureVirtMatch(body: Block, selDef: ValDef, cases: List[Tree], matchEnd: Tree) = {
+ val stats = transform(selDef) :: (cases map (transExpr(_, None, ext)))
+ treeCopy.Block(body, stats, transExpr(matchEnd, None, ext))
+ }
val body1 = body match {
- case Match(selector, cases) if (ext.isDefined && getAnswerTypeAnn(body.tpe).isEmpty) =>
- val cases1 = for {
- cd @ CaseDef(pat, guard, caseBody) <- cases
- caseBody1 = transExpr(body, None, ext)
- } yield {
- treeCopy.CaseDef(cd, transform(pat), transform(guard), caseBody1)
- }
- treeCopy.Match(tree, transform(selector), cases1)
+ case Match(selector, cases) if ext.isDefined && pureBody =>
+ transformPureMatch(body, selector, cases)
+
+ // virtpatmat switch
+ case Block(List(selDef: ValDef), mat@Match(selector, cases)) if ext.isDefined && pureBody =>
+ treeCopy.Block(body, List(transform(selDef)), transformPureMatch(mat, selector, cases))
+
+ // virtpatmat
+ case b@Block(matchStats@((selDef: ValDef) :: cases), matchEnd) if ext.isDefined && pureBody && (matchStats forall gen.hasSynthCaseSymbol) =>
+ transformPureVirtMatch(b, selDef, cases, matchEnd)
+
+ // virtpatmat that stores the scrut separately -- TODO: can we eliminate this case??
+ case Block(List(selDef0: ValDef), mat@Block(matchStats@((selDef: ValDef) :: cases), matchEnd)) if ext.isDefined && pureBody && (matchStats forall gen.hasSynthCaseSymbol)=>
+ treeCopy.Block(body, List(transform(selDef0)), transformPureVirtMatch(mat, selDef, cases, matchEnd))
case _ =>
transExpr(body, None, ext)
}
- debuglog("result "+body1)
+ debuglog("anf result "+body1)
debuglog("result is of type "+body1.tpe)
treeCopy.Function(ff, transformValDefs(vparams), body1)
@@ -170,63 +192,72 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
tree match {
case Block(stms, expr) =>
val (cpsA2, cpsR2) = (cpsA, linearize(cpsA, getAnswerTypeAnn(tree.tpe))) // tbd
-// val (cpsA2, cpsR2) = (None, getAnswerTypeAnn(tree.tpe))
- val (a, b) = transBlock(stms, expr, cpsA2, cpsR2)
+ // val (cpsA2, cpsR2) = (None, getAnswerTypeAnn(tree.tpe))
- val tree1 = (treeCopy.Block(tree, a, b)) // no updateSynthFlag here!!!
+ val (a, b) = transBlock(stms, expr, cpsA2, cpsR2)
+ val tree1 = (treeCopy.Block(tree, a, b)) // no updateSynthFlag here!!!
(Nil, tree1, cpsA)
- case If(cond, thenp, elsep) =>
- /* possible situations:
- cps before (cpsA)
- cps in condition (spc) <-- synth flag set if *only* here!
- cps in (one or both) branches */
- val (condStats, condVal, spc) = transInlineValue(cond, cpsA)
- val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe))
- (spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else
- (None, getAnswerTypeAnn(tree.tpe)) // if no cps in condition, branches must conform to tree.tpe directly
- val thenVal = transExpr(thenp, cpsA2, cpsR2)
- val elseVal = transExpr(elsep, cpsA2, cpsR2)
-
- // check that then and else parts agree (not necessary any more, but left as sanity check)
- if (cpsR.isDefined) {
- if (elsep == EmptyTree)
- unit.error(tree.pos, "always need else part in cps code")
- }
- if (hasAnswerTypeAnn(thenVal.tpe) != hasAnswerTypeAnn(elseVal.tpe)) {
- unit.error(tree.pos, "then and else parts must both be cps code or neither of them")
- }
-
- (condStats, updateSynthFlag(treeCopy.If(tree, condVal, thenVal, elseVal)), spc)
+ case If(cond, thenp, elsep) =>
+ /* possible situations:
+ cps before (cpsA)
+ cps in condition (spc) <-- synth flag set if *only* here!
+ cps in (one or both) branches */
+ val (condStats, condVal, spc) = transInlineValue(cond, cpsA)
+ val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe))
+ (spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else
+ (None, getAnswerTypeAnn(tree.tpe)) // if no cps in condition, branches must conform to tree.tpe directly
+ val thenVal = transExpr(thenp, cpsA2, cpsR2)
+ val elseVal = transExpr(elsep, cpsA2, cpsR2)
+
+ // check that then and else parts agree (not necessary any more, but left as sanity check)
+ if (cpsR.isDefined) {
+ if (elsep == EmptyTree)
+ unit.error(tree.pos, "always need else part in cps code")
+ }
+ if (hasAnswerTypeAnn(thenVal.tpe) != hasAnswerTypeAnn(elseVal.tpe)) {
+ unit.error(tree.pos, "then and else parts must both be cps code or neither of them")
+ }
- case Match(selector, cases) =>
+ (condStats, updateSynthFlag(treeCopy.If(tree, condVal, thenVal, elseVal)), spc)
- val (selStats, selVal, spc) = transInlineValue(selector, cpsA)
- val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe))
- (spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else
- (None, getAnswerTypeAnn(tree.tpe))
+ case Match(selector, cases) =>
+ val (selStats, selVal, spc) = transInlineValue(selector, cpsA)
+ val (cpsA2, cpsR2) =
+ if (hasSynthMarker(tree.tpe)) (spc, linearize(spc, getAnswerTypeAnn(tree.tpe)))
+ else (None, getAnswerTypeAnn(tree.tpe))
- val caseVals = for {
- cd @ CaseDef(pat, guard, body) <- cases
- bodyVal = transExpr(body, cpsA2, cpsR2)
- } yield {
- treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal)
- }
+ val caseVals = cases map { case cd @ CaseDef(pat, guard, body) =>
+ val bodyVal = transExpr(body, cpsA2, cpsR2)
+ treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal)
+ }
- (selStats, updateSynthFlag(treeCopy.Match(tree, selVal, caseVals)), spc)
+ (selStats, updateSynthFlag(treeCopy.Match(tree, selVal, caseVals)), spc)
+ // this is utterly broken: LabelDefs need to be considered together when transforming them to DefDefs:
+ // suppose a Block {L1; ... ; LN}
+ // this should become {D1def ; ... ; DNdef ; D1()}
+ // where D$idef = def L$i(..) = {L$i.body; L${i+1}(..)}
case ldef @ LabelDef(name, params, rhs) =>
if (hasAnswerTypeAnn(tree.tpe)) {
- val sym = currentOwner.newMethod(name, tree.pos, Flags.SYNTHETIC) setInfo ldef.symbol.info
- val rhs1 = new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs)
+ // currentOwner.newMethod(name, tree.pos, Flags.SYNTHETIC) setInfo ldef.symbol.info
+ val sym = ldef.symbol resetFlag Flags.LABEL
+ val rhs1 = rhs //new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs)
val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe)) changeOwner (currentOwner -> sym)
val stm1 = localTyper.typed(DefDef(sym, rhsVal))
- val expr = localTyper.typed(Apply(Ident(sym), List()))
-
- (List(stm1), expr, cpsA)
+ // since virtpatmat does not rely on fall-through, don't call the labels it emits
+ // transBlock will take care of calling the first label
+ // calling each labeldef is wrong, since some labels may be jumped over
+ // we can get away with this for now since the only other labels we emit are for tailcalls/while loops,
+ // which do not have consecutive labeldefs (and thus fall-through is irrelevant)
+ if (gen.hasSynthCaseSymbol(ldef)) (List(stm1), localTyper.typed{Literal(Constant(()))}, cpsA)
+ else {
+ assert(params.isEmpty, "problem in ANF transforming label with non-empty params "+ ldef)
+ (List(stm1), localTyper.typed{Apply(Ident(sym), List())}, cpsA)
+ }
} else {
val rhsVal = transExpr(rhs, None, None)
(Nil, updateSynthFlag(treeCopy.LabelDef(tree, name, params, rhsVal)), cpsA)
@@ -310,15 +341,23 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
try {
val Some((a, b)) = cpsR
-
- val res = localTyper.typed(atPos(tree.pos) {
- Apply(TypeApply(gen.mkAttributedRef(MethShiftUnit),
- List(TypeTree(plainTpe), TypeTree(a), TypeTree(b))),
- List(expr))
- })
- return (stms, res)
-
- } catch {
+ /** Since shiftUnit is bounded [A,B,C>:B] this may not typecheck
+ * if C is overly specific. So if !(B <:< C), call shiftUnit0
+ * instead, which takes only two type arguments.
+ */
+ val conforms = a <:< b
+ val call = localTyper.typedPos(tree.pos)(
+ Apply(
+ TypeApply(
+ gen.mkAttributedRef( if (conforms) MethShiftUnit else MethShiftUnit0 ),
+ List(TypeTree(plainTpe), TypeTree(a)) ++ ( if (conforms) List(TypeTree(b)) else Nil )
+ ),
+ List(expr)
+ )
+ )
+ return ((stms, call))
+ }
+ catch {
case ex:TypeError =>
unit.error(ex.pos, "cannot cps-transform expression " + tree + ": " + ex.msg)
}
@@ -404,18 +443,31 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
def transBlock(stms: List[Tree], expr: Tree, cpsA: CPSInfo, cpsR: CPSInfo): (List[Tree], Tree) = {
- stms match {
- case Nil =>
- transTailValue(expr, cpsA, cpsR)
-
- case stm::rest =>
- var (rest2, expr2) = (rest, expr)
- val (headStms, headSpc) = transInlineStm(stm, cpsA)
- val (restStms, restExpr) = transBlock(rest2, expr2, headSpc, cpsR)
- (headStms:::restStms, restExpr)
- }
+ def rec(currStats: List[Tree], currAns: CPSInfo, accum: List[Tree]): (List[Tree], Tree) =
+ currStats match {
+ case Nil =>
+ val (anfStats, anfExpr) = transTailValue(expr, currAns, cpsR)
+ (accum ++ anfStats, anfExpr)
+
+ case stat :: rest =>
+ val (stats, nextAns) = transInlineStm(stat, currAns)
+ rec(rest, nextAns, accum ++ stats)
+ }
+
+ val (anfStats, anfExpr) = rec(stms, cpsA, List())
+ // println("\nanf-block:\n"+ ((stms :+ expr) mkString ("{", "\n", "}")) +"\nBECAME\n"+ ((anfStats :+ anfExpr) mkString ("{", "\n", "}")))
+
+ // SUPER UGLY HACK: handle virtpatmat-style matches, whose labels have already been turned into DefDefs
+ if (anfStats.nonEmpty && (anfStats forall (t => !t.isDef || gen.hasSynthCaseSymbol(t)))) {
+ val (prologue, rest) = (anfStats :+ anfExpr) span (s => !s.isInstanceOf[DefDef]) // find first case
+ // val (defs, calls) = rest partition (_.isInstanceOf[DefDef])
+ if (rest nonEmpty){
+ // the filter drops the ()'s emitted when transValue encountered a LabelDef
+ val stats = prologue ++ (rest filter (_.isInstanceOf[DefDef])).reverse // ++ calls
+ // println("REVERSED "+ (stats mkString ("{", "\n", "}")))
+ (stats, localTyper.typed{Apply(Ident(rest.head.symbol), List())}) // call first label to kick-start the match
+ } else (anfStats, anfExpr)
+ } else (anfStats, anfExpr)
}
-
-
}
}
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala
index eb18f03748..8a500d6c4d 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala
@@ -26,6 +26,7 @@ class SelectiveCPSPlugin(val global: Global) extends Plugin {
override val runsBefore = List("uncurry")
}
+
val components = List[PluginComponent](anfPhase, cpsPhase)
val checker = new CPSAnnotationChecker {
@@ -42,17 +43,19 @@ class SelectiveCPSPlugin(val global: Global) extends Plugin {
}
// TODO: require -enabled command-line flag
+
override def processOptions(options: List[String], error: String => Unit) = {
- var enabled = true
- options foreach {
- case "enable" => enabled = true
- case "disable" => enabled = false
- case option => error("Option not understood: "+option)
+ var enabled = false
+ for (option <- options) {
+ if (option == "enable") {
+ enabled = true
+ } else {
+ error("Option not understood: "+option)
+ }
}
setEnabled(enabled)
}
- override val optionsHelp: Option[String] = {
- Some(" -P:continuations:disable Disable continuations plugin")
- }
+ override val optionsHelp: Option[String] =
+ Some(" -P:continuations:enable Enable continuations")
}
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
index 6453671eac..a78de8e6c8 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
@@ -15,7 +15,7 @@ import scala.tools.nsc.ast._
* In methods marked @cps, CPS-transform assignments introduced by ANF-transform phase.
*/
abstract class SelectiveCPSTransform extends PluginComponent with
- InfoTransform with TypingTransformers with CPSUtils {
+ InfoTransform with TypingTransformers with CPSUtils with TreeDSL {
// inherits abstract value `global` and class `Phase` from Transform
import global._ // the global environment
@@ -190,28 +190,29 @@ abstract class SelectiveCPSTransform extends PluginComponent with
val targettp = transformCPSType(tree.tpe)
-// val expr2 = if (catches.nonEmpty) {
- val pos = catches.head.pos
- val argSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe)
- val rhs = Match(Ident(argSym), catches1)
- val fun = Function(List(ValDef(argSym)), rhs)
- val funSym = currentOwner.newValueParameter(cpsNames.catches, pos).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp)))
- val funDef = localTyper.typed(atPos(pos) { ValDef(funSym, fun) })
- val expr2 = localTyper.typed(atPos(pos) { Apply(Select(expr1, expr1.tpe.member(cpsNames.flatMapCatch)), List(Ident(funSym))) })
-
- argSym.owner = fun.symbol
- rhs.changeOwner(currentOwner -> fun.symbol)
-
- val exSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe)
- val catch2 = { localTyper.typedCases(List(
- CaseDef(Bind(exSym, Typed(Ident("_"), TypeTree(ThrowableClass.tpe))),
- Apply(Select(Ident(funSym), nme.isDefinedAt), List(Ident(exSym))),
- Apply(Ident(funSym), List(Ident(exSym))))
- ), ThrowableClass.tpe, targettp) }
-
- //typedCases(tree, catches, ThrowableClass.tpe, pt)
-
- localTyper.typed(Block(List(funDef), treeCopy.Try(tree, treeCopy.Block(block1, stms, expr2), catch2, finalizer1)))
+ val pos = catches.head.pos
+ val funSym = currentOwner.newValueParameter(cpsNames.catches, pos).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp)))
+ val funDef = localTyper.typed(atPos(pos) {
+ ValDef(funSym, Match(EmptyTree, catches1))
+ })
+ val expr2 = localTyper.typed(atPos(pos) {
+ Apply(Select(expr1, expr1.tpe.member(cpsNames.flatMapCatch)), List(Ident(funSym)))
+ })
+
+ val exSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe)
+
+ import CODE._
+ // generate a case that is supported directly by the back-end
+ val catchIfDefined = CaseDef(
+ Bind(exSym, Ident(nme.WILDCARD)),
+ EmptyTree,
+ IF ((REF(funSym) DOT nme.isDefinedAt)(REF(exSym))) THEN (REF(funSym) APPLY (REF(exSym))) ELSE Throw(REF(exSym))
+ )
+
+ val catch2 = localTyper.typedCases(List(catchIfDefined), ThrowableClass.tpe, targettp)
+ //typedCases(tree, catches, ThrowableClass.tpe, pt)
+
+ localTyper.typed(Block(List(funDef), treeCopy.Try(tree, treeCopy.Block(block1, stms, expr2), catch2, finalizer1)))
/*
diff --git a/src/dbc/scala/dbc/DataType.scala b/src/dbc/scala/dbc/DataType.scala
deleted file mode 100644
index 677621e0c0..0000000000
--- a/src/dbc/scala/dbc/DataType.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc;
-
-
-/** An ISO-9075:2003 (SQL) data type. Mappings between SQL types and
- * database specific types should be provided by the database driver.
- */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class DataType {
-
- /** Tests whether this datatype is equivalent to another. Usually, two
- * types are defined as equivalent if they are equal. Two types can be
- * equivalent without being equal if values of those types will be
- * encoded in the same native Scala type.
- */
- def isEquivalent(datatype: DataType): Boolean;
-
- /** Tests whether this datatype is equivalent or a subtype of another
- * datatype. Type <code>A</code> is said to be subtype of type
- * <code>B</code> if any value of type <code>A</code> can be
- * represented as a value of type <code>B</code>.
- */
- def isSubtypeOf(datatype: DataType): Boolean;
-
- /** The native Scala type in which values of this SQL type will be
- * encoded.
- */
- type NativeType <: Any;
-
- /** The native Scala type in which values of this SQL type will be
- * encoded. This must point to the same type as <code>NativeType</code>.
- */
- def nativeTypeId: DataType.Id;
-
- /** Whether the value can take the null value, None when this property is
- * unknown.
- */
- def nullable: Option[Boolean] = None;
-
- /** The SQL name of the type */
- def sqlString: String = "UNDEFINED DATA TYPE"
-
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object DataType {
-
- type Id = Int;
-
- val OBJECT : Id = 10;
- val BOOLEAN : Id = 20;
- val BYTE : Id = 30;
- val SHORT : Id = 31;
- val INT : Id = 32;
- val LONG : Id = 33;
- val BIG_INTEGER: Id = 34;
- val BIG_DECIMAL: Id = 35;
- val FLOAT : Id = 40;
- val DOUBLE : Id = 41;
- val STRING : Id = 50;
-
-}
diff --git a/src/dbc/scala/dbc/Database.scala b/src/dbc/scala/dbc/Database.scala
deleted file mode 100644
index 60e16367e8..0000000000
--- a/src/dbc/scala/dbc/Database.scala
+++ /dev/null
@@ -1,187 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-
-
-import java.sql._
-
-/** A link to a database. The <code>Database</code> abstract class must
- * be specialised for every different DBMS.
- *
- * @author Gilles Dubochet
- */
-@deprecated(DbcIsDeprecated, "2.9.0") case class Database(dbms: Vendor) {
-
- class Closed extends Exception {}
-
- /** A lock used for operations that need to be atomic for this database
- * instance. */
- private val lock: scala.concurrent.Lock = new scala.concurrent.Lock()
-
- /** The vendor of the DBMS that contains this database. */
- private val vendor: Vendor = dbms
-
- /** The Database connections available to use. */
- private var availableConnections: List[Connection] = Nil
-
- /** The connections that are currently in use. */
- private var usedConnections: List[Connection] = Nil
-
- /** Whether the database no longer accepts new connections. */
- private var closing: Boolean = false;
-
- /** Retrieves a connection from the available connection pool or creates
- * a new one.
- *
- * @return A connection that can be used to access the database.
- */
- private def getConnection: Connection = {
- if (closing) {
- throw new Closed;
- } else {
- availableConnections match {
- case Nil => {
- lock.acquire;
- val connection = vendor.getConnection;
- usedConnections = connection :: usedConnections;
- lock.release;
- connection
- }
- case connection :: cs => {
- lock.acquire;
- availableConnections = cs;
- usedConnections = connection :: usedConnections;
- lock.release;
- connection;
- }
- }
- }
- }
-
- /** Closes a connection to this database. A closed connection might
- * also return to the available connection pool if the latter is depleted.
- *
- * @param connection The connection that should be closed.
- */
- private def closeConnection(connection: Connection): Unit = {
- if (closing) {
- connection.close()
- } else {
- lock.acquire
- usedConnections = usedConnections.filterNot(e => (e.equals(connection)));
- if (availableConnections.length < vendor.retainedConnections)
- availableConnections = connection :: availableConnections
- else
- connection.close()
- lock.release
- }
- }
-
- /** ..
- */
- def close() {
- closing = true
- for (conn <- availableConnections) conn.close()
- }
-
- /** Executes a statement that returns a relation on this database.
- *
- * @param relationStatement The statement to execute.
- * @return The relation returned by the database for this statement.
- */
- def executeStatement(relationStatement: statement.Relation): result.Relation =
- executeStatement(relationStatement, false);
-
- /** Executes a statement that returns a relation on this database.
- *
- * @param relationStatement The statement to execute.
- * @param debug Whether debugging information should be printed on the console.
- * @return The relation returned by the database for this statement.
- */
- def executeStatement(relationStatement: statement.Relation,
- debug: Boolean): result.Relation =
- new scala.dbc.result.Relation {
- val statement = relationStatement
- if (debug) Console.println("## " + statement.sqlString)
- private val connection = getConnection
- val sqlResult = connection.createStatement().executeQuery(statement.sqlString)
- closeConnection(connection)
- statement.typeCheck(this)
- }
-
- /** Executes a statement that updates the state of the database.
- * @param statusStatement The statement to execute.
- * @return The status of the database after the statement has been executed. */
- def executeStatement(statusStatement: statement.Status): result.Status[Unit] =
- executeStatement(statusStatement, false);
-
- /** Executes a statement that updates the state of the database.
- *
- * @param statusStatement The statement to execute.
- * @param debug Whether debugging information should be printed on the console.
- * @return The status of the database after the statement has been executed.
- */
- def executeStatement(statusStatement: statement.Status,
- debug: Boolean): result.Status[Unit] =
- new scala.dbc.result.Status[Unit] {
- val statement = statusStatement;
- if (debug) Console.println("## " + statement.sqlString);
- def result = ()
- private val connection = getConnection;
- val jdbcStatement: java.sql.Statement = connection.createStatement();
- jdbcStatement.execute(statement.sqlString);
- val touchedCount = Some(jdbcStatement.getUpdateCount());
- closeConnection(connection);
- }
-
- /** Executes a list of statements or other operations inside a transaction.
- * Only statements are protected in a transaction, other Scala code is not.
- *
- * @param transactionStatement The transaction to execute as a closure.
- * @return The status of the database after the transaction has been executed.
- */
- def executeStatement[ResultType](transactionStatement: statement.Transaction[ResultType]): result.Status[ResultType] =
- executeStatement(transactionStatement, false);
-
- /** Executes a list of statements or other operations inside a transaction.
- * Only statements are protected in a transaction, other Scala code is not.
- *
- * @param transactionStatement The transaction to execute as a closure.
- * @param debug Whether debugging information should be printed on the console.
- * @return The status of the database after the transaction has been executed.
- */
- def executeStatement[ResultType](transactionStatement: statement.Transaction[ResultType], debug: Boolean): result.Status[ResultType] = {
- new scala.dbc.result.Status[ResultType] {
- val touchedCount = None
- val statement = transactionStatement
- private val connection = getConnection
- connection.setAutoCommit(false)
- val jdbcStatement: java.sql.Statement = connection.createStatement();
- if (debug) Console.println("## " + transactionStatement.sqlStartString);
- jdbcStatement.execute(transactionStatement.sqlStartString);
- val result: ResultType = try {
- val buffer = transactionStatement.transactionBody(Database.this);
- if (debug) Console.println("## " + transactionStatement.sqlCommitString);
- jdbcStatement.execute(transactionStatement.sqlCommitString);
- buffer
- } catch {
- case e: Throwable => {
- if (debug) Console.println("## " + transactionStatement.sqlAbortString);
- jdbcStatement.execute(transactionStatement.sqlAbortString);
- throw e
- }
- }
- connection.setAutoCommit(true)
- closeConnection(connection)
- }
- }
-
-}
diff --git a/src/dbc/scala/dbc/Syntax.scala b/src/dbc/scala/dbc/Syntax.scala
deleted file mode 100644
index 85cd1c1a1d..0000000000
--- a/src/dbc/scala/dbc/Syntax.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc;
-
-
-import java.math.{BigDecimal, BigInteger};
-
-
-/** This class ..
- *
- */
-@deprecated(DbcIsDeprecated, "2.9.0") object Syntax {
-
- import syntax.DataTypeUtil;
-
- /* Data types */
- def boolean = DataTypeUtil.boolean;
- def tinyint = DataTypeUtil.tinyint;
- def smallint = DataTypeUtil.smallint;
- def integer = DataTypeUtil.integer;
- def bigint = DataTypeUtil.bigint;
- def real = DataTypeUtil.real;
-
- def numeric(precision: Int) = DataTypeUtil.numeric(precision);
- def numeric(precision: Int, scale: Int) = DataTypeUtil.numeric(precision, scale);
-
- def doublePrecision = DataTypeUtil.doublePrecision;
- def character(length: Int) = DataTypeUtil.character(length);
- def characterVarying(length: Int) = DataTypeUtil.characterVarying(length);
- def characterLargeObject = DataTypeUtil.characterLargeObject;
-
- /* Statements */
- //def select
-
- /* Other stuff */
- def database (server: String, username: String, password: String): dbc.Database =
- syntax.Database.database(server, username, password);
-
-}
diff --git a/src/dbc/scala/dbc/Utilities.scala b/src/dbc/scala/dbc/Utilities.scala
deleted file mode 100644
index c37b1bb98d..0000000000
--- a/src/dbc/scala/dbc/Utilities.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc;
-
-
-/** An object offering transformation methods (views) on various values.
- * This object's members must be visible in an expression to use value
- * auto-conversion.
- */
-@deprecated(DbcIsDeprecated, "2.9.0") object Utilities {
-
- implicit def constantToValue (obj: statement.expression.Constant): Value =
- obj.constantValue;
-
- implicit def valueToConstant (obj: Value): statement.expression.Constant =
- new statement.expression.Constant {
- val constantValue = obj;
- }
-
-}
diff --git a/src/dbc/scala/dbc/Value.scala b/src/dbc/scala/dbc/Value.scala
deleted file mode 100644
index a502f51cb5..0000000000
--- a/src/dbc/scala/dbc/Value.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc;
-
-
-/** A SQL-99 value of any type. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Value {
-
- /** The SQL-99 type of the value. */
- val dataType: DataType;
-
- type NativeType = dataType.type#NativeType;
-
- val nativeValue: NativeType;
-
- /** A SQL-99 compliant string representation of the value. */
- def sqlString: String;
-
-}
diff --git a/src/dbc/scala/dbc/Vendor.scala b/src/dbc/scala/dbc/Vendor.scala
deleted file mode 100644
index 68f6102526..0000000000
--- a/src/dbc/scala/dbc/Vendor.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc;
-
-
-import java.sql.{Connection, Driver};
-
-
-/** This class ..
- */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Vendor {
-
- def nativeDriverClass: Class[_];
- def uri: java.net.URI;
- def user: String;
- def pass: String;
- def nativeProperties: java.util.Properties = {
- val properties = new java.util.Properties();
- properties.setProperty("user", user);
- properties.setProperty("password", pass);
- properties
- }
-
- def retainedConnections: Int;
-
- def getConnection: Connection = {
- val driver = nativeDriverClass.newInstance().asInstanceOf[Driver];
- driver.connect(uri.toString(),nativeProperties)
- }
-
- def urlProtocolString: String;
-
-}
diff --git a/src/dbc/scala/dbc/datatype/ApproximateNumeric.scala b/src/dbc/scala/dbc/datatype/ApproximateNumeric.scala
deleted file mode 100644
index 31752e18c7..0000000000
--- a/src/dbc/scala/dbc/datatype/ApproximateNumeric.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** A type category for all SQL types that store varying-precision
- * numbers.
- */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class ApproximateNumeric[Type] (
- override val nativeTypeId: DataType.Id
-) extends datatype.Numeric[Type](nativeTypeId) {
-
- def isEquivalent(datatype: DataType) = datatype match {
- case dt: ApproximateNumeric[_] =>
- (nativeTypeId == dt.nativeTypeId &&
- precisionRadix == dt.precisionRadix &&
- precision == dt.precision &&
- signed == dt.signed)
- case _ =>
- false
- }
-
- def isSubtypeOf (datatype:DataType) = datatype match {
- case dt:ApproximateNumeric[_] =>
- (nativeTypeId == dt.nativeTypeId &&
- precisionRadix == dt.precisionRadix &&
- precision <= dt.precision &&
- signed == dt.signed)
- case _ =>
- false
- }
-
- /** A SQL-99 compliant string representation of the type.
- * <h3>Compatibility notice</h3> This method assumes that a real
- * uses 32 bits and a double 64. This is not defined in the
- * standard but is usually the case.
- */
- override def sqlString: java.lang.String = Tuple2(precisionRadix,precision) match {
- case Tuple2(2,64) => "REAL"
- case Tuple2(2,128) => "DOUBLE PRECISION"
- case Tuple2(2,p) =>
- throw exception.UnsupportedFeature("SQL-99 does not support an approximate numeric type with a binary defined precision other than 16, 32 and 64 bits");
- case Tuple2(10,p) => "FLOAT (" + p.toString() + ")"
- case Tuple2(pr,_) =>
- throw exception.UnsupportedFeature("SQL-99 does not support the precision of an approximate numeric type to be defined in a radix other than 2 or 10");
- }
-
-}
diff --git a/src/dbc/scala/dbc/datatype/Boolean.scala b/src/dbc/scala/dbc/datatype/Boolean.scala
deleted file mode 100644
index 4a32ce98f1..0000000000
--- a/src/dbc/scala/dbc/datatype/Boolean.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** The SQL type for a truth value. */
-@deprecated(DbcIsDeprecated, "2.9.0") class Boolean extends DataType {
-
- def isEquivalent (datatype:DataType) = datatype match {
- case dt:Boolean => true
- case _ => false
- }
-
- def isSubtypeOf (datatype:DataType) = isEquivalent(datatype);
-
- type NativeType = scala.Boolean;
- val nativeTypeId = DataType.BOOLEAN;
-
- /** A SQL-99 compliant string representation of the type. */
- override def sqlString: java.lang.String = "BOOLEAN";
-
-}
diff --git a/src/dbc/scala/dbc/datatype/Character.scala b/src/dbc/scala/dbc/datatype/Character.scala
deleted file mode 100644
index 02dec06281..0000000000
--- a/src/dbc/scala/dbc/datatype/Character.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** A SQL type for a string of characters of arbitrary length with
- * arbitrary character set.
- */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Character extends CharacterString {
-
- def isEquivalent(datatype: DataType) = datatype match {
- case dt: Character =>
- length == dt.length && encoding == dt.encoding
- case _ =>
- false
- }
-
- def isSubtypeOf(datatype: DataType) = datatype match {
- case dt: Character =>
- length >= dt.length && encoding == dt.encoding
- case _ =>
- false
- }
-
- /** The length of the string defined in characters. */
- def length: Int;
-
- /** A SQL-99 compliant string representation of the type. */
- override def sqlString: java.lang.String = "CHARACTER (" + length.toString() + ")";
-
-}
diff --git a/src/dbc/scala/dbc/datatype/CharacterLargeObject.scala b/src/dbc/scala/dbc/datatype/CharacterLargeObject.scala
deleted file mode 100644
index 2c7ef64d66..0000000000
--- a/src/dbc/scala/dbc/datatype/CharacterLargeObject.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** A SQL type for an unbounded length string of characters with arbitrary
- * character set. */
-@deprecated(DbcIsDeprecated, "2.9.0") class CharacterLargeObject extends CharacterString {
-
- def isEquivalent (datatype:DataType) = datatype match {
- case dt:CharacterLargeObject => {
- encoding == dt.encoding
- }
- case _ => false
- }
-
- def isSubtypeOf (datatype:DataType) = isEquivalent(datatype);
-
- /** A SQL-99 compliant string representation of the type. */
- override def sqlString: java.lang.String = "CHARACTER LARGE OBJECT";
-
-}
diff --git a/src/dbc/scala/dbc/datatype/CharacterString.scala b/src/dbc/scala/dbc/datatype/CharacterString.scala
deleted file mode 100644
index 54d6e0111f..0000000000
--- a/src/dbc/scala/dbc/datatype/CharacterString.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** A type category for all SQL types that store strings of characters. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class CharacterString extends String {
-
- type NativeType = java.lang.String;
- val nativeTypeId = DataType.STRING;
-
- /** The name of the character set in which the string is encoded. */
- def encoding: Option[java.lang.String] = None;
-
-}
diff --git a/src/dbc/scala/dbc/datatype/CharacterVarying.scala b/src/dbc/scala/dbc/datatype/CharacterVarying.scala
deleted file mode 100644
index 9df487579f..0000000000
--- a/src/dbc/scala/dbc/datatype/CharacterVarying.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** A SQL type for a varying length string of characters with arbitrary
- * maximal length and arbitrary character set.
- */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class CharacterVarying extends CharacterString {
-
- def isEquivalent(datatype: DataType) = datatype match {
- case dt: CharacterVarying =>
- length == dt.length && encoding == dt.encoding
- case _ =>
- false
- }
-
- def isSubtypeOf(datatype: DataType) = datatype match {
- case dt: CharacterVarying =>
- length >= dt.length && encoding == dt.encoding
- case _ =>
- false
- }
-
- /** The maximal length of the string defined in characters. */
- def length: Int;
-
- /** A SQL-99 compliant string representation of the type. */
- override def sqlString: java.lang.String =
- "CHARACTER VARYING (" + length.toString() + ")";
-
-}
diff --git a/src/dbc/scala/dbc/datatype/ExactNumeric.scala b/src/dbc/scala/dbc/datatype/ExactNumeric.scala
deleted file mode 100644
index a578846977..0000000000
--- a/src/dbc/scala/dbc/datatype/ExactNumeric.scala
+++ /dev/null
@@ -1,65 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** A type category for all SQL types that store constant-precision
- * numbers.
- */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class ExactNumeric[Type](
- override val nativeTypeId: DataType.Id
-) extends datatype.Numeric[Type](nativeTypeId) {
-
- def isEquivalent(datatype: DataType) = datatype match {
- case dt: ExactNumeric[_] =>
- (nativeTypeId == dt.nativeTypeId &&
- precisionRadix == dt.precisionRadix &&
- precision == dt.precision &&
- scale == dt.scale &&
- signed == dt.signed)
- case _ =>
- false
- }
-
- def isSubtypeOf(datatype: DataType) = datatype match {
- case dt: ExactNumeric[_] =>
- (nativeTypeId == dt.nativeTypeId &&
- precisionRadix == dt.precisionRadix &&
- precision <= dt.precision &&
- scale <= dt.scale &&
- signed == dt.signed)
- case _ =>
- false
- }
-
- /** The number of digits used after the decimal point. */
- def scale: Int;
-
- /** A SQL-99 compliant string representation of the type.
- * <h3>Compatibility notice</h3> This method assumes that an integer
- * uses 32 bits, a small 16 and a big 64. This is not defined in the
- * standard but is usually the case.
- */
- override def sqlString: java.lang.String = Tuple3(precisionRadix,precision,scale) match {
- case Tuple3(2,16,0) => "SMALLINT"
- case Tuple3(2,32,0) => "INTEGER"
- case Tuple3(2,64,0) => "BIGINT"
- case Tuple3(2,java.lang.Integer.MAX_VALUE,0) => "BIGINT"
- case Tuple3(2,p,s) =>
- throw exception.UnsupportedFeature("SQL-99 does not support an exact numeric type with a binary defined precision other than 16, 32 and 64 bits");
- case Tuple3(10,p,0) => "NUMERIC (" + p.toString() + ")"
- case Tuple3(10,p,s) => "NUMERIC (" + p.toString() + ", " + s.toString() + ")"
- case Tuple3(pr,_,_) =>
- throw exception.UnsupportedFeature("SQL-99 does not support the precision of an exact numeric type to be defined in a radix other than 2 or 10");
- }
-
-}
diff --git a/src/dbc/scala/dbc/datatype/Factory.scala b/src/dbc/scala/dbc/datatype/Factory.scala
deleted file mode 100644
index bb9b3f5b61..0000000000
--- a/src/dbc/scala/dbc/datatype/Factory.scala
+++ /dev/null
@@ -1,250 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-import java.sql.Types._;
-import java.math.BigInteger;
-import java.math.BigDecimal;
-
-@deprecated(DbcIsDeprecated, "2.9.0") object Factory {
-
- final val java_lang_Integer_SIZE = 32;
- final val java_lang_Long_SIZE = 64;
-
- /** Returns a nullable property formatted as a boolean option */
- def isNullable (metadata:java.sql.ResultSetMetaData, index:Int): Option[scala.Boolean] =
- metadata.isNullable(index) match {
- case java.sql.ResultSetMetaData.columnNoNulls => Some(false);
- case java.sql.ResultSetMetaData.columnNullable => Some(true);
- case java.sql.ResultSetMetaData.columnNullableUnknown => None;
- }
-
- /** Returns the binary precision for an integer field. This should only be
- * used to find precision for integer numbers. It assumes that
- * bytes cannot be used partially (result % 8 = 0). */
- def bytePrecision (precision:Int, signed:scala.Boolean, safe:scala.Boolean): Int = {
- val decimalPrecision = precision + (if (safe) 1 else 0);
- Pair(signed,decimalPrecision) match {
- case Pair(_,0) => java.lang.Integer.MAX_VALUE // That's a bit of a hack.
- case Pair(_,dp) if (dp <= 3) => 8
- case Pair(_,dp) if (dp <= 5) => 16
- case Pair(true,dp) if (dp <= 7) => 24
- case Pair(false,dp) if (dp <= 8) => 24
- case Pair(_,dp) if (dp <= 10) => 32
- case Pair(true,dp) if (dp <= 12) => 40
- case Pair(false,dp) if (dp <= 13) => 40
- case Pair(_,dp) if (dp <= 15) => 48
- case Pair(_,dp) if (dp <= 17) => 56
- case Pair(true,dp) if (dp <= 19) => 64
- case Pair(false,dp) if (dp <= 20) => 64
- case Pair(_,dp) if (dp <= 22) => 72
- case Pair(true,dp) if (dp <= 24) => 80
- case Pair(false,dp) if (dp <= 25) => 80
- case Pair(_,dp) if (dp <= 27) => 88
- case Pair(_,dp) if (dp <= 29) => 96
- case Pair(_,dp) if (dp <= 32) => 104
- case Pair(_,dp) if (dp <= 34) => 112
- case Pair(true,dp) if (dp <= 36) => 120
- case Pair(false,dp) if (dp <= 37) => 120
- case Pair(_,dp) if (dp <= 39) => 128
- case _ => java.lang.Integer.MAX_VALUE
- }
- }
-
- def create (metadata:java.sql.ResultSetMetaData, index:Int): DataType = {
- metadata.getColumnType(index) match {
- /* Boolean data types. */
- case BOOLEAN => new datatype.Boolean {
- override val nullable = isNullable(metadata,index);
- }
- case BIT => new datatype.Boolean {
- override val nullable = isNullable(metadata,index);
- }
- /* Fixed precision numeric data types. */
- case DECIMAL => {
- Pair(bytePrecision(metadata.getPrecision(index),metadata.isSigned(index),true),metadata.getScale(index) == 0) match {
- case Pair(bp,true) if (bp <= java_lang_Integer_SIZE) =>
- new datatype.ExactNumeric[Int](DataType.INT) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 10;
- val precision = metadata.getPrecision(index);
- val signed = metadata.isSigned(index);
- val scale = metadata.getScale(index);
- }
- case Pair(bp,true) if (bp <= java_lang_Long_SIZE) =>
- new datatype.ExactNumeric[Long](DataType.LONG) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 10;
- val precision = metadata.getPrecision(index);
- val signed = metadata.isSigned(index);
- val scale = metadata.getScale(index);
- }
- case Pair(_,true) =>
- new datatype.ExactNumeric[BigInteger](DataType.BIG_INTEGER) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 10;
- val precision = metadata.getPrecision(index);
- val signed = metadata.isSigned(index);
- val scale = metadata.getScale(index);
- }
- case Pair(_,false) =>
- new datatype.ExactNumeric[BigDecimal](DataType.BIG_DECIMAL) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 10;
- val precision = metadata.getPrecision(index);
- val signed = metadata.isSigned(index);
- val scale = metadata.getScale(index);
- }
- }
- }
- case NUMERIC => {
- Pair(bytePrecision(metadata.getPrecision(index),metadata.isSigned(index),true),metadata.getScale(index) == 0) match {
- case Pair(bp,true) if (bp <= java_lang_Integer_SIZE) =>
- new datatype.ExactNumeric[Int](DataType.INT) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 10;
- val precision = metadata.getPrecision(index);
- val signed = metadata.isSigned(index);
- val scale = metadata.getScale(index);
- }
- case Pair(bp,true) if (bp <= java_lang_Long_SIZE) =>
- new datatype.ExactNumeric[Long](DataType.LONG) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 10;
- val precision = metadata.getPrecision(index);
- val signed = metadata.isSigned(index);
- val scale = metadata.getScale(index);
- }
- case Pair(_,true) =>
- new datatype.ExactNumeric[BigInteger](DataType.BIG_INTEGER) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 10;
- val precision = metadata.getPrecision(index);
- val signed = metadata.isSigned(index);
- val scale = metadata.getScale(index);
- }
- case Pair(_,false) =>
- new datatype.ExactNumeric[BigDecimal](DataType.BIG_DECIMAL) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 10;
- val precision = metadata.getPrecision(index);
- val signed = metadata.isSigned(index);
- val scale = metadata.getScale(index);
- }
- }
- }
- /* Fixed precision integer data types. */
- case BIGINT =>
- new datatype.ExactNumeric[Long](DataType.LONG) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 2;
- val precision = 64;
- val signed = metadata.isSigned(index);
- val scale = 0;
- }
- case INTEGER =>
- new datatype.ExactNumeric[Int](DataType.INT) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 2;
- val precision = 32;
- val signed = metadata.isSigned(index);
- val scale = 0;
- }
- case SMALLINT =>
- new datatype.ExactNumeric[Short](DataType.SHORT) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 2;
- val precision = 16;
- val signed = metadata.isSigned(index);
- val scale = 0;
- }
- case TINYINT =>
- new datatype.ExactNumeric[Byte](DataType.BYTE) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 2;
- val precision = 8;
- val signed = metadata.isSigned(index);
- val scale = 0;
- }
- /* Floating point numeric data types. */
- case REAL =>
- new datatype.ApproximateNumeric[Float](DataType.FLOAT) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 2;
- val precision = 64;
- val signed = metadata.isSigned(index);
- }
- case DOUBLE =>
- new datatype.ApproximateNumeric[Double](DataType.DOUBLE) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 2;
- val precision = 128;
- val signed = metadata.isSigned(index);
- }
- case FLOAT =>
- new datatype.ApproximateNumeric[Double](DataType.DOUBLE) {
- override val nullable = isNullable(metadata,index);
- val precisionRadix = 2;
- val precision = 128;
- val signed = metadata.isSigned(index);
- }
- /* Character string data types. */
- case CHAR => new datatype.Character {
- override val nullable = isNullable(metadata,index);
- val length = metadata.getColumnDisplaySize(index);
- }
- case CLOB => new datatype.CharacterLargeObject {
- override val nullable = isNullable(metadata,index);
- }
- case LONGVARCHAR => {
- if (metadata.getColumnDisplaySize(index) >= 0)
- new datatype.CharacterVarying {
- override val nullable = isNullable(metadata,index);
- def length = metadata.getColumnDisplaySize(index);
- }
- else // A PostgreSQL Hack
- new datatype.CharacterLargeObject {
- override val nullable = isNullable(metadata,index);
- }
- }
- case VARCHAR => {
- if (metadata.getColumnDisplaySize(index) >= 0)
- new datatype.CharacterVarying {
- override val nullable = isNullable(metadata,index);
- def length = metadata.getColumnDisplaySize(index);
- }
- else // A PostgreSQL Hack
- new datatype.CharacterLargeObject {
- override val nullable = isNullable(metadata,index);
- }
- }
- /* Undefined cases. */
- case OTHER => new datatype.Unknown {
- override val nullable = isNullable(metadata, index);
- }
- /* Unsupported data types. */
- case REF | ARRAY | STRUCT =>
- sys.error ("I don't support composite data types yet.");
- case DATALINK | DISTINCT | JAVA_OBJECT | NULL =>
- sys.error ("I won't support strange data types.");
- /* Unsupported binary string data types. */
- case BINARY | BLOB | LONGVARBINARY | VARBINARY =>
- sys.error ("I don't support binary string data types yet.");
- /* Unsupported date and time data types. */
- case DATE | TIME | TIMESTAMP =>
- sys.error ("I don't support date and time data types yet.");
- /* Default case */
- case x => sys.error ("I don't know about this ("+metadata.getColumnTypeName(index)+") JDBC type.")
- }
- }
-}
diff --git a/src/dbc/scala/dbc/datatype/Numeric.scala b/src/dbc/scala/dbc/datatype/Numeric.scala
deleted file mode 100644
index c13f454dde..0000000000
--- a/src/dbc/scala/dbc/datatype/Numeric.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** A type category for all SQL types that store numbers. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Numeric[Type](_nativeTypeId: DataType.Id) extends DataType {
-
- type NativeType = Type;
- val nativeTypeId = _nativeTypeId;
-
- /** The radix in which the precision (and scale when appliable) is defined.
- * ISO-9075 only allows 2 and 10 for this value.
- */
- def precisionRadix: Int;
-
- /** The number of significant digits for that number. */
- def precision: Int;
-
- /** Whether the number is signed or not. */
- def signed: scala.Boolean;
-
-}
diff --git a/src/dbc/scala/dbc/datatype/String.scala b/src/dbc/scala/dbc/datatype/String.scala
deleted file mode 100644
index 291504f777..0000000000
--- a/src/dbc/scala/dbc/datatype/String.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** A type category for all SQL types that store strings of elements.
- */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class String extends DataType {
-
- /** The maximal possible length of the string defined in characters.
- * This is an implementation-specific value.
- */
- def maxLength: Option[Int] = None;
-
-}
diff --git a/src/dbc/scala/dbc/datatype/Unknown.scala b/src/dbc/scala/dbc/datatype/Unknown.scala
deleted file mode 100644
index 14a33c6be9..0000000000
--- a/src/dbc/scala/dbc/datatype/Unknown.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package datatype;
-
-
-/** The SQL type for a truth value. */
-@deprecated(DbcIsDeprecated, "2.9.0") class Unknown extends DataType {
-
- def isEquivalent(datatype: DataType) = datatype match {
- case dt: Unknown =>
- nativeTypeId == dt.nativeTypeId
- case _ =>
- false
- }
-
- def isSubtypeOf(datatype: DataType) = true;
-
- type NativeType = AnyRef;
- val nativeTypeId = DataType.OBJECT;
-
- /** A SQL-99 compliant string representation of the type. */
- override def sqlString: java.lang.String =
- sys.error("The 'UNKNOWN' data type cannot be represented.");
-
-}
diff --git a/src/dbc/scala/dbc/exception/IncompatibleSchema.scala b/src/dbc/scala/dbc/exception/IncompatibleSchema.scala
deleted file mode 100644
index c8d53bbf1a..0000000000
--- a/src/dbc/scala/dbc/exception/IncompatibleSchema.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package exception
-
-
-/** A type category for all SQL types that store constant-precision numbers. */
-@deprecated(DbcIsDeprecated, "2.9.0") case class IncompatibleSchema (
- expectedSchema: List[DataType],
- foundSchema: List[DataType]
-) extends Exception;
diff --git a/src/dbc/scala/dbc/package.scala b/src/dbc/scala/dbc/package.scala
deleted file mode 100644
index b1552e11d3..0000000000
--- a/src/dbc/scala/dbc/package.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package scala
-
-package object dbc {
- final val DbcIsDeprecated =
- "scala.dbc will be removed after version 2.9. Use an active sql library such as scalaquery instead."
-} \ No newline at end of file
diff --git a/src/dbc/scala/dbc/result/Field.scala b/src/dbc/scala/dbc/result/Field.scala
deleted file mode 100644
index cd3309bb14..0000000000
--- a/src/dbc/scala/dbc/result/Field.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package result
-
-
-import scala.dbc.datatype._
-import scala.dbc.value._
-
-/** An ISO-9075:2003 (SQL) table field. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Field {
-
- /** The content (value) of the field. The type of this value is undefined,
- * transformation into a useful type will be done by an automatic view
- * function defined in the field object.
- */
- def content: Value
-
- final def value[Type <: Value]: Type =
- content.asInstanceOf[Type]
-
- final def exactNumericValue[NativeType] =
- content.asInstanceOf[dbc.value.ExactNumeric[NativeType]]
-
- final def approximateNumericValue[NativeType] =
- content.asInstanceOf[dbc.value.ApproximateNumeric[NativeType]]
-
- final def booleanValue =
- content.asInstanceOf[dbc.value.Boolean]
-
- final def characterValue =
- content.asInstanceOf[dbc.value.Character]
-
- final def characterLargeObjectValue =
- content.asInstanceOf[dbc.value.CharacterLargeObject]
-
- final def characterVaryingValue =
- content.asInstanceOf[dbc.value.CharacterVarying]
-
- final def unknownValue =
- content.asInstanceOf[dbc.value.Unknown]
-
- /** The tuple that contains this field. */
- def originatingTuple: Tuple
-
- /** The field metadata attached to this field. */
- def metadata: FieldMetadata
-
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object Field {
-
- implicit def fieldToValue (field: Field): Value = field.content
-
-}
diff --git a/src/dbc/scala/dbc/result/FieldMetadata.scala b/src/dbc/scala/dbc/result/FieldMetadata.scala
deleted file mode 100644
index 3c2de297d0..0000000000
--- a/src/dbc/scala/dbc/result/FieldMetadata.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package result
-
-
-/** The class <code>FieldMetadata</cocde> provides informations attached to
- * a field about its content and its relationship to the originating database.
- */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class FieldMetadata {
-
- /** The name of the field. */
- def name: String
-
- /** The index of the field in the tuple. */
- def index: Int
-
- /** The expected type of the field. This information is used for automatic
- * transformation of the field value into a usable type.
- */
- def datatype: DataType
-
- /** The name of the catalog in the database from which the field originates */
- def catalog: String
-
- /** The name of the schema in the database from which the field originates */
- def schema: String
-
- /** The name of the table in the database from which the field originates */
- def table: String
-
-}
diff --git a/src/dbc/scala/dbc/result/Relation.scala b/src/dbc/scala/dbc/result/Relation.scala
deleted file mode 100644
index 98d653d61e..0000000000
--- a/src/dbc/scala/dbc/result/Relation.scala
+++ /dev/null
@@ -1,84 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package result
-
-
-/** An ISO-9075:2003 (SQL) table. This is equivalent to a relation in the
- * relational model. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Relation
-extends collection.AbstractIterable[Tuple]
- with Iterable[Tuple] {
-
- /** The statement that generated this relation. */
- def statement: scala.dbc.statement.Relation
-
- /** A JDBC result containing this relation. */
- protected def sqlResult: java.sql.ResultSet
-
- /** A JDBC metadata object attached to the relation. */
- protected def sqlMetadata: java.sql.ResultSetMetaData = sqlResult.getMetaData()
-
- /** Metadata about all fields in a tuple of the relation. */
- def metadata: List[FieldMetadata] =
- for (count <- List.range(1, sqlMetadata.getColumnCount()+1)) yield
- new FieldMetadata {
- val name: String = sqlMetadata.getColumnName(count)
- val index: Int = count
- val datatype: DataType = dbc.datatype.Factory.create(sqlMetadata,count)
- val catalog: String = sqlMetadata.getCatalogName(count)
- val schema: String = sqlMetadata.getSchemaName(count)
- val table: String = sqlMetadata.getTableName(count)
- }
-
- /** Metadata about the field at the given index. If there is no such
- * field <code>None</code> is returned instead. */
- def metadataFor (index:Int): Option[FieldMetadata] = {
- val meta = metadata
- if (meta.length > index)
- Some(meta(index))
- else
- None
- }
-
- /** Metadata about the field with the given column name. If there is no
- * such field, <code>None</code> is returned instead. */
- def metadataFor (name:String): Option[FieldMetadata] =
- metadata.find(f=>(f.name==name));
-
- /** An iterator on the tuples of the relation.
- * <h3>Caution</h3> A Relation only has one single iterator, due to limitations
- * in DBMS. This means that if this method is called multiple times, all returned
- * iterators will share the same state. */
- def iterator: Iterator[Tuple] = new collection.AbstractIterator[Tuple] {
- protected val result: java.sql.ResultSet = Relation.this.sqlResult
- def hasNext: Boolean = resultNext
- private var resultNext = result.next()
- def next: Tuple = {
- if (resultNext) {
- val newTuple = new Tuple {
- val me = this
- val originatingRelation = Relation.this
- val fields: List[Field] = for (fieldMetadata <- metadata) yield
- new Field {
- val metadata = fieldMetadata
- val content = dbc.value.Factory.create(result,metadata.index,metadata.datatype)
- val originatingTuple = me
- }
- }
- resultNext = result.next()
- newTuple
- }
- else sys.error("next on empty iterator")
- }
- }
-
-}
diff --git a/src/dbc/scala/dbc/result/Status.scala b/src/dbc/scala/dbc/result/Status.scala
deleted file mode 100644
index d3152a58ab..0000000000
--- a/src/dbc/scala/dbc/result/Status.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package result;
-
-
-import scala.dbc.datatype._;
-
-/** An object containing the status of a query */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Status[ResultType] {
-
- /** The statement that generated this status result. */
- def statement: scala.dbc.statement.Statement;
-
- /** The number of elements modified or added by this statement. */
- def touchedCount: Option[Int];
-
- def result: ResultType;
-
-}
diff --git a/src/dbc/scala/dbc/result/Tuple.scala b/src/dbc/scala/dbc/result/Tuple.scala
deleted file mode 100644
index 80ab5c22aa..0000000000
--- a/src/dbc/scala/dbc/result/Tuple.scala
+++ /dev/null
@@ -1,42 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package result;
-
-
-/** An ISO-9075:2003 (SQL) table row. This is equivalent to a tuple in the relational model. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Tuple {
-
- /** All the fields contained in the tuple. */
- def fields: List[Field];
-
- /** The relation that contains the tuple. */
- def originatingRelation: Relation;
-
- /** The field at the given index. If there is no such field (that is the index is out of bounds), <code>None</code> is returned instead. */
- def apply (index:Int): Field =
- try {
- fields(index)
- } catch {
- case e =>
- throw new java.lang.IndexOutOfBoundsException("Field at index "+index+" does not exist in relation");
- }
-
- /** The field with the given column name. If there is no such field, <code>None</code> is returned instead. */
- def apply (name:String): Field = {
- def findField (fields: List[Field], name:String): Field = fields match {
- case Nil => throw new java.lang.IndexOutOfBoundsException("Field '"+name+"' does not exist in relation")
- case field :: _ if (field.metadata.name == name) => field
- case field :: fields => findField (fields, name)
- }
- findField (fields, name);
- }
-}
diff --git a/src/dbc/scala/dbc/statement/DerivedColumn.scala b/src/dbc/scala/dbc/statement/DerivedColumn.scala
deleted file mode 100644
index ae05df986a..0000000000
--- a/src/dbc/scala/dbc/statement/DerivedColumn.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class DerivedColumn {
-
- /** The value for the column. This value can be of any type but must be
- * calculated from fields that appear in a relation that takes part
- * in the query.
- */
- def valueExpression: Expression
-
- /** A new name for this field. This name must be unique for the query in
- * which the column takes part.
- */
- def asClause: Option[String]
-
- /** A SQL-99 compliant string representation of the derived column
- * sub-statement. This only has a meaning inside a select statement.
- */
- def sqlString: String =
- valueExpression.sqlInnerString +
- (asClause match {
- case None => ""
- case Some(ac) => " AS " + ac
- })
-
-}
diff --git a/src/dbc/scala/dbc/statement/Expression.scala b/src/dbc/scala/dbc/statement/Expression.scala
deleted file mode 100644
index c2da91e9ef..0000000000
--- a/src/dbc/scala/dbc/statement/Expression.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-/** An expression that calculates some value from fields. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Expression extends Relation {
-
- def fieldTypes: List[DataType] = Nil
-
- /** A SQL-99 compliant string representation of the expression. */
- def sqlString: String = "SELECT " + sqlInnerString
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement.
- */
- def sqlInnerString: String
-
-}
diff --git a/src/dbc/scala/dbc/statement/Insert.scala b/src/dbc/scala/dbc/statement/Insert.scala
deleted file mode 100644
index 189ccec54f..0000000000
--- a/src/dbc/scala/dbc/statement/Insert.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-import scala.dbc.statement.expression._
-
-/** An insertion of values into a table. */
-@deprecated(DbcIsDeprecated, "2.9.0") case class Insert(insertionTarget: String, insertionData: InsertionData)
- extends Status {
-
- /** A SQL-99 compliant string representation of the select statement. */
- def sqlString: String =
- "INSERT INTO " + insertionTarget + " " + insertionData.sqlString
-
- /** The name of the table where the data should be added. */
- //def insertionTarget: String
-
- /** The data that will be added tot he table. */
- //def insertionData: InsertionData
-
-}
diff --git a/src/dbc/scala/dbc/statement/InsertionData.scala b/src/dbc/scala/dbc/statement/InsertionData.scala
deleted file mode 100644
index e91ad7efe6..0000000000
--- a/src/dbc/scala/dbc/statement/InsertionData.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-import scala.dbc.statement.expression._
-
-/** Data to be inserted into a table in an <code>Insert</code>. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class InsertionData {
- def sqlString: String
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object InsertionData {
- /** Insertion of data resulting from a query on the database. */
- @deprecated(DbcIsDeprecated, "2.9.0") case class Subquery(query: Relation) extends InsertionData {
- def sqlString = query.sqlString
- }
- /** Insertion of data as explicitly defined values. */
- @deprecated(DbcIsDeprecated, "2.9.0") case class Constructor(
- columnNames: Option[List[String]],
- columnValues: List[Expression]
- ) extends InsertionData {
- def sqlString =
- (columnNames match {
- case None => ""
- case Some(cn) => cn.mkString(" (",", ",")")
- }) +
- " VALUES" +
- columnValues.map(e => e.sqlInnerString).mkString(" (",", ",")")
- }
-}
diff --git a/src/dbc/scala/dbc/statement/IsolationLevel.scala b/src/dbc/scala/dbc/statement/IsolationLevel.scala
deleted file mode 100644
index b31614c3dd..0000000000
--- a/src/dbc/scala/dbc/statement/IsolationLevel.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class IsolationLevel {
- def sqlString: String
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object IsolationLevel {
- case object ReadUncommitted extends IsolationLevel {
- def sqlString = "ISOLATION LEVEL READ UNCOMMITTED"
- }
- case object ReadCommitted extends IsolationLevel {
- def sqlString = "ISOLATION LEVEL READ COMMITTED"
- }
- case object RepeatableRead extends IsolationLevel {
- def sqlString = "ISOLATION LEVEL REPEATABLE READ"
- }
- case object Serializable extends IsolationLevel {
- def sqlString = "ISOLATION LEVEL SERIALIZABLE"
- }
-}
diff --git a/src/dbc/scala/dbc/statement/JoinType.scala b/src/dbc/scala/dbc/statement/JoinType.scala
deleted file mode 100644
index 698612b10d..0000000000
--- a/src/dbc/scala/dbc/statement/JoinType.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-/** A join behaviour in a <code>Jointure</code>. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class JoinType {
- /** A SQL-99 string representation of the join behaviour. */
- def sqlString: String
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object JoinType {
-
- /** A join behaviour where a joined tuple is created only when a
- * corresponding tuple exists in both original relations.
- */
- case object Inner extends JoinType {
- val sqlString = "INNER JOIN"
- }
-
- /** A join behaviour family where a joined tuple is created even when a
- * tuple has no corresponding tuple in the other relation. The fields
- * populated by values of the other tuple will receive the NULL value.
- */
- abstract class Outer extends JoinType
-
- object Outer {
- /** An outer join behaviour where there will be at least on tuple for
- * every tuple in the left relation.
- */
- case object Left extends Outer {
- val sqlString = "LEFT OUTER JOIN"
- }
- /** An outer join behaviour where there will be at least on tuple for
- * every tuple in the right relation.
- */
- case object Right extends Outer {
- val sqlString = "RIGHT OUTER JOIN"
- }
- /** An outer join behaviour where there will be at least on tuple for
- * every tuple in both right and left relations.
- */
- case object Full extends Outer {
- val sqlString = "FULL OUTER JOIN"
- }
- }
-}
diff --git a/src/dbc/scala/dbc/statement/Jointure.scala b/src/dbc/scala/dbc/statement/Jointure.scala
deleted file mode 100644
index 74c871cc3e..0000000000
--- a/src/dbc/scala/dbc/statement/Jointure.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-/** A jointure between two relations. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Jointure extends Relation {
-
- /** The relation on the left part of the join. */
- def leftRelation: Relation
-
- /** The relation on the right part of the join. */
- def rightRelation: Relation
-
- /** The type of the jointure. */
- def joinType: JoinType
-
- /** The condition on which the jointure needs be done. */
- def joinCondition: Option[Expression]
-
- /** A SQL-99 compliant string representation of the relation statement. */
- def sqlString: String = "SELECT * FROM " + sqlInnerString
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside a query.
- */
- def sqlInnerString: String =
- leftRelation.sqlInnerString + " " +
- joinType.sqlString + " " +
- rightRelation.sqlInnerString +
- (joinCondition match {
- case Some(jc) => jc.sqlString
- case None => ""
- })
-
-}
diff --git a/src/dbc/scala/dbc/statement/Relation.scala b/src/dbc/scala/dbc/statement/Relation.scala
deleted file mode 100644
index 787707ee82..0000000000
--- a/src/dbc/scala/dbc/statement/Relation.scala
+++ /dev/null
@@ -1,55 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement;
-
-
-/** A statement that returns a relation. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Relation extends Statement {
-
- def isCompatibleType: (DataType,DataType)=>Boolean =
- ((dt,wdt)=>dt.isSubtypeOf(wdt));
-
- def typeCheck (relation: result.Relation): Unit = {
- val sameType: Boolean = (
- relation.metadata.length == fieldTypes.length &&
- (relation.metadata.zip(fieldTypes).forall({case Pair(field,expectedType) =>
- isCompatibleType(field.datatype, expectedType)}))
- );
- if (!sameType)
- throw new exception.IncompatibleSchema(fieldTypes,relation.metadata.map(field=>field.datatype));
- }
-
- def fieldTypes: List[DataType];
-
- def sqlTypeString: String =
- if (fieldTypes.isEmpty)
- "UNTYPED"
- else
- fieldTypes.map(dt=>dt.sqlString).mkString("RELATION (",", ",")");
-
- /** A SQL-99 compliant string representation of the statement. */
- def sqlString: String;
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String;
-
- /** Executes the statement on the given database. */
- def execute (database: scala.dbc.Database): scala.dbc.result.Relation = {
- database.executeStatement(this);
- }
-
- def execute (database:scala.dbc.Database, debug:Boolean): scala.dbc.result.Relation = {
- database.executeStatement(this,debug);
- }
-
-}
diff --git a/src/dbc/scala/dbc/statement/Select.scala b/src/dbc/scala/dbc/statement/Select.scala
deleted file mode 100644
index a9ca0212ed..0000000000
--- a/src/dbc/scala/dbc/statement/Select.scala
+++ /dev/null
@@ -1,99 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-/** A statement that when executed on a database will return a relation.
- * The returned relation will be a subset of a table in the database or
- * a jointure between such subsets. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Select extends Relation {
-
- /** Defines if duplicated tuples should be removed from the returned
- * relation. <h3>Compatibility notice</h3> Some DBMS (PostgreSQL) allow
- * uniqueness constrains on an arbitrary field instead of the entire
- * tuple. */
- def setQuantifier: Option[SetQuantifier]
-
- /** Defines the output fields that a tuple in the returned relation will
- * contain, and their content with respect to the tables in the
- * database. If the fields are not specified (that is the list is
- * empty), all possible input fields will be returned. <h3>Compatibility
- * notice</h3> SQL's qualified asterisk select sublist is not
- * available. */
- def selectList: List[DerivedColumn]
-
- /** Defines the relations from which the query will obtain its data.*/
- def fromClause: List[Relation]
-
- /** Defines condition that must be true in the returned relation's tuples.
- * This value expression must return a boolean or boolean-compatible
- * value. This condition is applied before any GROUP BY clause.
- */
- def whereClause: Option[Expression]
-
- /** Defines the grouping of the returned relation's tuples. One tuple is
- * returned for every group. The value of <code>selectList</code> must
- * use aggregate functions for calculation.
- */
- def groupByClause: Option[List[Expression]]
-
- /** Defines conditions that must be true in the returned relation's tuples.
- * The value expression must return a boolean can only refer to fields
- * that are grouped or to any field from inside an aggregate function.
- */
- def havingClause: Option[Expression]
-
- /* def windowClause: Option[_]; */
-
- /** A SQL-99 compliant string representation of the select statement. */
- def sqlString: String = (
- "SELECT" +
- (setQuantifier match {
- case None => ""
- case Some(sq) => " " + sq.sqlString
- }) +
- (selectList match {
- case Nil => " *"
- case _ => (" " + selectList.tail.foldLeft(selectList.head.sqlString)
- ((name:String, dc:DerivedColumn) => name + ", " + dc.sqlString))
- }) +
- (fromClause match {
- case Nil => sys.error("Empty from clause is not allowed")
- case _ => (" FROM " + fromClause.tail.foldLeft(fromClause.head.sqlInnerString)
- ((name:String, rel:Relation) => name + ", " + rel.sqlInnerString))
- }) +
- (whereClause match {
- case None => ""
- case Some(expr) => " WHERE " + expr.sqlInnerString
- }) +
- (groupByClause match {
- case None => ""
- case Some(gbl) => gbl match {
- case Nil => sys.error("Empty group by clause is not allowed")
- case _ =>
- (" GROUP BY " +
- gbl.tail.foldLeft(gbl.head.sqlInnerString)
- ((name:String, gb) => name + ", " + gb.sqlInnerString))
- }
- }) +
- (havingClause match {
- case None => ""
- case Some(expr) => " HAVING " + expr.sqlString
- })
- );
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside a query.
- */
- def sqlInnerString: String = "("+sqlString+")"
-
-}
diff --git a/src/dbc/scala/dbc/statement/SetQuantifier.scala b/src/dbc/scala/dbc/statement/SetQuantifier.scala
deleted file mode 100644
index 77a4b79b8d..0000000000
--- a/src/dbc/scala/dbc/statement/SetQuantifier.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-/** A set quantifier that defines the collection type of a relation. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class SetQuantifier {
- /** A SQL-99 compliant string representation of the set quantifier. */
- def sqlString: String
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object SetQuantifier {
-
- /** A set quantifier that defines a relation as being a bag. That means
- * that duplicates are allowed.
- */
- case object AllTuples extends SetQuantifier {
- /** A SQL-99 compliant string representation of the set quantifier. */
- def sqlString: String = "ALL"
- }
-
- /** A set quantifier that defines a relation as being a set. That means
- * that duplicates are not allowed and will be pruned.
- */
- case object DistinctTuples extends SetQuantifier {
- /** A SQL-99 compliant string representation of the set quantifier. */
- def sqlString: String = "DISTINCT"
- }
-}
diff --git a/src/dbc/scala/dbc/statement/Status.scala b/src/dbc/scala/dbc/statement/Status.scala
deleted file mode 100644
index 0ce64b978d..0000000000
--- a/src/dbc/scala/dbc/statement/Status.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-import scala.dbc.Database
-import scala.dbc.result
-
-/** A statement that changes the status of the database. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Status extends Statement {
-
- /** A SQL-99 compliant string representation of the statement. */
- def sqlString: String
-
- /** Executes the statement on the given database. */
- def execute(database: Database): result.Status[Unit] = {
- database.executeStatement(this)
- }
-
- def execute(database: Database, debug: Boolean): result.Status[Unit] = {
- database.executeStatement(this, debug)
- }
-
-}
diff --git a/src/dbc/scala/dbc/statement/Table.scala b/src/dbc/scala/dbc/statement/Table.scala
deleted file mode 100644
index e729f801a3..0000000000
--- a/src/dbc/scala/dbc/statement/Table.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-
-
-/** A reference to a table in the database.
- * @author Gilles Dubochet
- * @version 1.0 */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Table extends Relation {
-
- /** The name of the table in the database. */
- def tableName: String
-
- /** The name that the table will be called in the enclosing statement. */
- def tableRename: Option[String]
-
- /** A SQL-99 compliant string representation of the relation statement. */
- def sqlString: String = "SELECT * FROM " + tableName
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside a query. */
- def sqlInnerString: String =
- tableName +
- (tableRename match {
- case None => ""
- case Some(rename) => " AS " + rename
- })
-
-}
diff --git a/src/dbc/scala/dbc/statement/Transaction.scala b/src/dbc/scala/dbc/statement/Transaction.scala
deleted file mode 100644
index 1740dae3f9..0000000000
--- a/src/dbc/scala/dbc/statement/Transaction.scala
+++ /dev/null
@@ -1,55 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement;
-
-
-/** A statement that changes the status of the database. */
-@deprecated(DbcIsDeprecated, "2.9.0") case class Transaction [ResultType] (
- transactionBody: (scala.dbc.Database=>ResultType),
- accessMode: Option[AccessMode],
- isolationLevel: Option[IsolationLevel]
-) extends Statement {
-
- /** A SQL-99 compliant string representation of the statement. */
- def sqlStartString: String = (
- "START TRANSACTION" +
- (Pair(accessMode,isolationLevel) match {
- case Pair(None,None) => ""
- case Pair(Some(am),None) => " " + am.sqlString
- case Pair(None,Some(il)) => " " + il.sqlString
- case Pair(Some(am),Some(il)) => " " + am.sqlString + ", " + il.sqlString
- })
- );
-
- def sqlCommitString: String = {
- "COMMIT"
- }
-
- def sqlAbortString: String = {
- "ROLLBACK"
- }
-
- //def transactionBody: (()=>Unit);
-
- //def accessMode: Option[AccessMode];
-
- //def isolationLevel: Option[IsolationLevel];
-
- def execute (database: scala.dbc.Database): scala.dbc.result.Status[ResultType] = {
- database.executeStatement(this);
- }
-
- def execute (database: scala.dbc.Database, debug: Boolean): scala.dbc.result.Status[ResultType] = {
- database.executeStatement(this,debug);
- }
-
-}
diff --git a/src/dbc/scala/dbc/statement/Update.scala b/src/dbc/scala/dbc/statement/Update.scala
deleted file mode 100644
index 836549a4be..0000000000
--- a/src/dbc/scala/dbc/statement/Update.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement;
-
-
-import scala.dbc.statement.expression._;
-
-/** An update of the state of a table. */
-@deprecated(DbcIsDeprecated, "2.9.0") case class Update (
- updateTarget: String,
- setClauses: List[SetClause],
- whereClause: Option[Expression]
-) extends Status {
-
-
- /** A SQL-99 compliant string representation of the select statement. */
- def sqlString: String = (
- "UPDATE " +
- updateTarget +
- " SET " + setClauses.map(sc=>sc.sqlString).mkString("",", ","") +
- (whereClause match {
- case None => ""
- case Some(expr) => " WHERE " + expr.sqlString
- })
- );
-
- /** The name of the table that should be updated. */
- //def updateTarget: String;
-
- /** The data that will be added tot he table. */
- //def setClauses: List[SetClause];
-
- /** Defines condition that must be true in the tuples that will be updated.
- * This value expression must return a boolean or boolean-compatible
- * value. */
- //def whereClause: Option[scala.dbc.statement.expression.Expression];
-
-}
diff --git a/src/dbc/scala/dbc/statement/expression/Aggregate.scala b/src/dbc/scala/dbc/statement/expression/Aggregate.scala
deleted file mode 100644
index c42bffe20e..0000000000
--- a/src/dbc/scala/dbc/statement/expression/Aggregate.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Aggregate extends Expression {
-
- def aggregateName: String;
-
- def setFunction: SetFunction;
-
- def filterClause: Option[Expression];
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = (
- aggregateName +
- "(" + setFunction.sqlString + ")" +
- (filterClause match {
- case None => ""
- case Some(fc) => " FILTER (WHERE " + fc.sqlString + ")"
- })
- )
-
-}
diff --git a/src/dbc/scala/dbc/statement/expression/BinaryOperator.scala b/src/dbc/scala/dbc/statement/expression/BinaryOperator.scala
deleted file mode 100644
index 32f016dbf6..0000000000
--- a/src/dbc/scala/dbc/statement/expression/BinaryOperator.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class BinaryOperator extends Expression {
-
- /** The name of the operator. */
- def operator: String;
-
- /** The expression applied on the left of the operator. */
- def leftOperand: Expression;
-
- /** The expression applied on the right of the operator. */
- def rightOperand: Expression;
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = {
- leftOperand.sqlInnerString + " " + operator + " " + rightOperand.sqlInnerString
- }
-
-}
diff --git a/src/dbc/scala/dbc/statement/expression/Constant.scala b/src/dbc/scala/dbc/statement/expression/Constant.scala
deleted file mode 100644
index 70ec7819dc..0000000000
--- a/src/dbc/scala/dbc/statement/expression/Constant.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Constant extends Expression {
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = constantValue.sqlString;
-
- /** The value of the constant. */
- def constantValue: Value;
-}
diff --git a/src/dbc/scala/dbc/statement/expression/Default.scala b/src/dbc/scala/dbc/statement/expression/Default.scala
deleted file mode 100644
index 78204d0172..0000000000
--- a/src/dbc/scala/dbc/statement/expression/Default.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-case object Default extends Expression {
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = "DEFAULT";
-
-}
diff --git a/src/dbc/scala/dbc/statement/expression/Field.scala b/src/dbc/scala/dbc/statement/expression/Field.scala
deleted file mode 100644
index 9a90903a99..0000000000
--- a/src/dbc/scala/dbc/statement/expression/Field.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Field extends Expression {
-
- /** The name of the schema in the database where the field is located. */
- def schemaName: Option[String] = None;
-
- /** The name of the table in the database where the field is located. */
- def tableName: Option[String];
-
- /** The name of the field in the database. */
- def fieldName: String;
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = (
- (schemaName match {
- case None => ""
- case Some(sn) => sn + "."
- }) +
- (tableName match {
- case None => ""
- case Some(tn) => tn + "."
- }) + fieldName
- )
-
-}
diff --git a/src/dbc/scala/dbc/statement/expression/FunctionCall.scala b/src/dbc/scala/dbc/statement/expression/FunctionCall.scala
deleted file mode 100644
index 962cf209b9..0000000000
--- a/src/dbc/scala/dbc/statement/expression/FunctionCall.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") case class FunctionCall (
- functionName: String,
- arguments: List[Expression]
-) extends Expression {
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = {
- functionName + "(" + arguments.mkString("",", ","") + ")"
- }
-
- /** The name of the function to call. */
- //def functionName: String;
-
- /** A list of all argument expressions to pass to the function, in order. */
- //def arguments: List[Expression];
-
-}
diff --git a/src/dbc/scala/dbc/statement/expression/Select.scala b/src/dbc/scala/dbc/statement/expression/Select.scala
deleted file mode 100644
index 7a6a4a21c4..0000000000
--- a/src/dbc/scala/dbc/statement/expression/Select.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Select extends Expression {
-
- /** The actual select statement */
- def selectStatement: statement.Select;
-
- /** A SQL-99 compliant string representation of the expression. */
- override def sqlString: String = selectStatement.sqlString;
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = "("+selectStatement.sqlString+")";
-
-}
diff --git a/src/dbc/scala/dbc/statement/expression/SetFunction.scala b/src/dbc/scala/dbc/statement/expression/SetFunction.scala
deleted file mode 100644
index 060b2236f2..0000000000
--- a/src/dbc/scala/dbc/statement/expression/SetFunction.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class SetFunction {
- /** A SQL-99 compliant string representation of the set quantifier. */
- def sqlString: String;
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object SetFunction {
- abstract class Asterisk extends SetFunction {
- def sqlString = "(*)";
- }
- abstract class General extends SetFunction {
- def setQuantifier: Option[SetQuantifier];
- def valueExpression: Expression;
- def sqlString = (
- "(" +
- (setQuantifier match {
- case None => ""
- case Some(sq) => sq.sqlString + " "
- }) +
- valueExpression.sqlString + ")"
- );
- }
- abstract class Binary extends SetFunction {
- def sqlString = sys.error("Binary set function is not supported yet.");
- }
-}
diff --git a/src/dbc/scala/dbc/statement/expression/TypeCast.scala b/src/dbc/scala/dbc/statement/expression/TypeCast.scala
deleted file mode 100644
index dbb8dc1b4d..0000000000
--- a/src/dbc/scala/dbc/statement/expression/TypeCast.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") case class TypeCast (
- expression: Expression,
- castType: DataType
-) extends Expression {
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = {
- "CAST (" + expression.sqlInnerString + " AS " + castType.sqlString + ")";
- }
-
- /** The expression that will be casted. */
- //def expression: Expression;
-
- /** The type to which to cast. */
- //def castType: scala.dbc.datatype.DataType;
-}
diff --git a/src/dbc/scala/dbc/statement/expression/UnaryOperator.scala b/src/dbc/scala/dbc/statement/expression/UnaryOperator.scala
deleted file mode 100644
index 4172c451fb..0000000000
--- a/src/dbc/scala/dbc/statement/expression/UnaryOperator.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package statement
-package expression;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class UnaryOperator extends Expression {
-
- /** The name of the operator */
- def operator: String;
-
- /** Whether the operator comes before the operand or not. */
- def operatorIsLeft: Boolean;
-
- /** The operand applied to the operator. */
- def operand: Expression;
-
- /** A SQL-99 compliant string representation of the relation sub-
- * statement. This only has a meaning inside another statement. */
- def sqlInnerString: String = operatorIsLeft match {
- case true => operator + " " + operand.sqlInnerString;
- case false => operand.sqlInnerString + " " + operator;
- }
-}
diff --git a/src/dbc/scala/dbc/syntax/DataTypeUtil.scala b/src/dbc/scala/dbc/syntax/DataTypeUtil.scala
deleted file mode 100644
index a0ebd1713e..0000000000
--- a/src/dbc/scala/dbc/syntax/DataTypeUtil.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package syntax;
-
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-@deprecated(DbcIsDeprecated, "2.9.0") object DataTypeUtil {
-
- final val java_lang_Integer_SIZE = 32;
- final val java_lang_Long_SIZE = 64;
-
- def boolean = new datatype.Boolean;
- def tinyint = new datatype.ExactNumeric[Byte](dbc.DataType.BYTE) {
- val precisionRadix = 2;
- val precision = 8;
- val signed = true;
- val scale = 0;
- }
- def smallint = new datatype.ExactNumeric[Short](dbc.DataType.SHORT) {
- val precisionRadix = 2;
- val precision = 16;
- val signed = true;
- val scale = 0;
- }
- def integer = new datatype.ExactNumeric[Int](dbc.DataType.INT) {
- val precisionRadix = 2;
- val precision = 32;
- val signed = true;
- val scale = 0;
- }
- def bigint = new datatype.ExactNumeric[Long](dbc.DataType.LONG) {
- val precisionRadix = 2;
- val precision = 64;
- val signed = true;
- val scale = 0;
- }
- def numeric (_precision:Int): DataType = numeric(_precision,0);
- def numeric (_precision:Int, _scale:Int): DataType =
- Pair(datatype.Factory.bytePrecision(_precision,true,true),_scale == 0) match {
- case Pair(bp,true) if (bp <= java_lang_Integer_SIZE) =>
- new datatype.ExactNumeric[Int](DataType.INT) {
- val precisionRadix = 10;
- val precision = _precision;
- val signed = true;
- val scale = 0;
- }
- case Pair(bp,true) if (bp <= java_lang_Long_SIZE) =>
- new datatype.ExactNumeric[Long](DataType.LONG) {
- val precisionRadix = 10;
- val precision = _precision;
- val signed = true;
- val scale = 0;
- }
- case Pair(_,true) =>
- new datatype.ExactNumeric[BigInteger](DataType.BIG_INTEGER) {
- val precisionRadix = 10;
- val precision = _precision;
- val signed = true;
- val scale = 0;
- }
- case Pair(_,false) =>
- new datatype.ExactNumeric[BigDecimal](DataType.BIG_DECIMAL) {
- val precisionRadix = 10;
- val precision = _precision;
- val signed = true;
- val scale = _scale;
- }
- }
- def real = new datatype.ApproximateNumeric[Float](DataType.FLOAT) {
- val precisionRadix = 2;
- val precision = 64;
- val signed = true;
- }
- def doublePrecision = new datatype.ApproximateNumeric[Double](DataType.DOUBLE) {
- val precisionRadix = 2;
- val precision = 128;
- val signed = true;
- }
- def character (_length: Int) = new datatype.Character {
- val length = _length;
- }
- def characterVarying (_length: Int) = new datatype.CharacterVarying {
- def length = _length;
- }
- def characterLargeObject = new datatype.CharacterLargeObject;
-
-}
diff --git a/src/dbc/scala/dbc/syntax/Database.scala b/src/dbc/scala/dbc/syntax/Database.scala
deleted file mode 100644
index 4357fb7d4c..0000000000
--- a/src/dbc/scala/dbc/syntax/Database.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package syntax;
-
-
-import java.net.URI;
-
-@deprecated(DbcIsDeprecated, "2.9.0") object Database {
-
- def database (server:String, username:String, password:String): dbc.Database = {
- val uri = new URI(server);
- // Java 1.5 if (uri.toString().contains("postgres")) {
- if (uri.toString().indexOf("postgres") != -1) {
- new dbc.Database(new vendor.PostgreSQL {
- val uri = new URI(server);
- val user = username;
- val pass = password;
- })
- } else {
- throw new Exception("No DBMS vendor support could be found for the given URI");
- }
- }
-
-}
diff --git a/src/dbc/scala/dbc/syntax/Statement.scala b/src/dbc/scala/dbc/syntax/Statement.scala
deleted file mode 100644
index baccbfaa64..0000000000
--- a/src/dbc/scala/dbc/syntax/Statement.scala
+++ /dev/null
@@ -1,274 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package syntax;
-
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import StatementExpression._;
-
-/*
-
-ASSUMPTIONS:
-
-IMPROVABLE:
-For type safety, all types must be defined. If one is missing, none is taken into account.
-It is possible to redefine many types or renamings for a field, in that case,
- only the last one is taken into account ("a" as "b" as "c" of boolean as "e" of integer
- is equivalent to "a" as "e" of integer).
-
-FIXED:
-
-*/
-
-@deprecated(DbcIsDeprecated, "2.9.0") object Statement {
-
- // SELECT ZYGOTE ...
-
- def select: SelectZygote = new SelectZygote {
- val setQuantifier = None;
- }
- def selectBag: SelectZygote = new SelectZygote {
- val setQuantifier = Some(statement.SetQuantifier.AllTuples);
- }
- def selectSet: SelectZygote = new SelectZygote {
- val setQuantifier = Some(statement.SetQuantifier.DistinctTuples);
- }
-
- abstract class SelectZygote {
- def setQuantifier: Option[statement.SetQuantifier];
- def fields (sdc:SelectDerivedColumns): SelectOf = new SelectOf {
- val setQuantifier = SelectZygote.this.setQuantifier;
- val selectList = sdc.selectList;
- val selectTypes = sdc.selectTypes;
- }
- }
-
- abstract class SelectDerivedField {
- def fieldValue: StatementField;
- def fieldRename: Option[String] = {val x = None; x}
- def fieldType: Option[dbc.DataType] = {val x = None; x}
- def as (rename:String): SelectDerivedField = new SelectDerivedField {
- val fieldValue = SelectDerivedField.this.fieldValue;
- override val fieldRename = Some(rename);
- override val fieldType = SelectDerivedField.this.fieldType;
- }
- def of (datatype:dbc.DataType): SelectDerivedField = new SelectDerivedField {
- val fieldValue = SelectDerivedField.this.fieldValue;
- override val fieldRename = SelectDerivedField.this.fieldRename;
- override val fieldType = Some(datatype);
- }
- }
-
- implicit def statementFieldToSelectDerivedField (fv:StatementField): SelectDerivedField = new SelectDerivedField {
- val fieldValue = fv;
- }
-
- implicit def stringToSelectDerivedField (fv:String): SelectDerivedField = new SelectDerivedField {
- val fieldValue: StatementField = StatementExpression.stringToStatementField(fv);
- }
-
- abstract class SelectDerivedColumns {
- def selectList: List[statement.DerivedColumn];
- def selectTypes: List[DataType];
- def and (sdc:SelectDerivedColumns): SelectDerivedColumns = new SelectDerivedColumns {
- val selectList = SelectDerivedColumns.this.selectList ::: sdc.selectList;
- val selectTypes =
- if (SelectDerivedColumns.this.selectTypes.isEmpty | sdc.selectTypes.isEmpty)
- Nil
- else
- SelectDerivedColumns.this.selectTypes ::: sdc.selectTypes;
- }
- }
-
- implicit def selectDerivedFieldToSelectDerivedColumns (sdf:SelectDerivedField): SelectDerivedColumns = new SelectDerivedColumns {
- val selectList = List(new statement.DerivedColumn {
- val valueExpression = sdf.fieldValue.toStatement;
- val asClause = sdf.fieldRename;
- });
- val selectTypes = if (sdf.fieldType.isEmpty) Nil else List(sdf.fieldType.get);
- }
-
- implicit def stringToSelectDerivedColumns (sdfs:String): SelectDerivedColumns = {
- val sdf: SelectDerivedField = sdfs;
- selectDerivedFieldToSelectDerivedColumns(sdf);
- }
-
- // SELECT OF ...
-
- abstract class SelectOf {
- def setQuantifier: Option[statement.SetQuantifier];
- def selectList: List[statement.DerivedColumn];
- def selectTypes: List[DataType];
- def from (sst:SelectSourceTables): SelectBeyond = new SelectBeyond {
- val setQuantifier = SelectOf.this.setQuantifier;
- val selectList = SelectOf.this.selectList;
- val selectTypes = SelectOf.this.selectTypes;
- val fromClause = sst.fromClause;
- val whereClause = None;
- val groupByClause = None;
- val havingClause = None;
- }
- }
-
- abstract class SelectSourceTable {
- def fromRelation: statement.Relation;
- def innerJoin (sst: SelectSourceTable): SelectSourceTable = new SelectSourceTable {
- val fromRelation = new statement.Jointure {
- val leftRelation = SelectSourceTable.this.fromRelation;
- val rightRelation = sst.fromRelation;
- val joinType = statement.JoinType.Inner;
- val joinCondition = None;
- val fieldTypes = leftRelation.fieldTypes ::: rightRelation.fieldTypes;
- }
- }
- def leftOuterJoin (sst: SelectSourceTable): SelectSourceTable = new SelectSourceTable {
- val fromRelation = new statement.Jointure {
- val leftRelation = SelectSourceTable.this.fromRelation;
- val rightRelation = sst.fromRelation;
- val joinType = statement.JoinType.Outer.Left;
- val joinCondition = None;
- val fieldTypes = leftRelation.fieldTypes ::: rightRelation.fieldTypes;
- }
- }
- def rightOuterJoin (sst: SelectSourceTable): SelectSourceTable = new SelectSourceTable {
- val fromRelation = new statement.Jointure {
- val leftRelation = SelectSourceTable.this.fromRelation;
- val rightRelation = sst.fromRelation;
- val joinType = statement.JoinType.Outer.Right;
- val joinCondition = None;
- val fieldTypes = leftRelation.fieldTypes ::: rightRelation.fieldTypes;
- }
- }
- def fullOuterJoin (sst: SelectSourceTable): SelectSourceTable = new SelectSourceTable {
- val fromRelation = new statement.Jointure {
- val leftRelation = SelectSourceTable.this.fromRelation;
- val rightRelation = sst.fromRelation;
- val joinType = statement.JoinType.Outer.Full;
- val joinCondition = None;
- val fieldTypes = leftRelation.fieldTypes ::: rightRelation.fieldTypes;
- }
- }
- }
-
- implicit def stringToSelectSourceTable (sct:String): SelectSourceTable = new SelectSourceTable {
- val fromRelation = new statement.Table {
- val tableName = sct;
- val tableRename = None;
- val fieldTypes = Nil;
- }
- }
-
- implicit def selectToSelectSourceTable (sct:statement.Select): SelectSourceTable = new SelectSourceTable {
- val fromRelation = sct;
- }
-
- abstract class SelectSourceTables {
- def fromClause: List[statement.Relation];
- def join (sct:SelectSourceTable): SelectSourceTables = new SelectSourceTables {
- val fromClause = SelectSourceTables.this.fromClause ::: List(sct.fromRelation);
- }
- }
-
- implicit def stringToSelectSourceTables (sct:String): SelectSourceTables = new SelectSourceTables {
- val fromClause = List(new statement.Table {
- val tableName = sct;
- val tableRename = None;
- val fieldTypes = Nil;
- });
- }
-
- implicit def selectToSelectSourceTables (sct:statement.Select): SelectSourceTables = new SelectSourceTables {
- val fromClause = List(sct);
- }
-
- implicit def selectSourceTableToSelectSourceTables (sct:SelectSourceTable): SelectSourceTables = new SelectSourceTables {
- val fromClause = List(sct.fromRelation);
- }
-
- // SELECT BEYOND ...
-
- abstract class SelectBeyond {
- def setQuantifier: Option[statement.SetQuantifier];
- def selectList: List[statement.DerivedColumn];
- def selectTypes: List[DataType];
- def fromClause: List[statement.Relation];
- def whereClause: Option[statement.Expression];
- def groupByClause: Option[List[statement.Expression]];
- def havingClause: Option[statement.Expression];
- def where (se:StatementExpression): SelectBeyond = new SelectBeyond {
- val setQuantifier = SelectBeyond.this.setQuantifier;
- val selectList = SelectBeyond.this.selectList;
- val selectTypes = SelectBeyond.this.selectTypes;
- val fromClause = SelectBeyond.this.fromClause;
- val whereClause = Some(se.toStatement);
- val groupByClause = SelectBeyond.this.groupByClause;
- val havingClause = SelectBeyond.this.havingClause;
- }
- def groupBy (sgb:SelectGroupBy): SelectBeyond = new SelectBeyond {
- val setQuantifier = SelectBeyond.this.setQuantifier;
- val selectList = SelectBeyond.this.selectList;
- val selectTypes = SelectBeyond.this.selectTypes;
- val fromClause = SelectBeyond.this.fromClause;
- val whereClause = SelectBeyond.this.whereClause;
- val groupByClause = Some(sgb.groupByClause);
- val havingClause = SelectBeyond.this.havingClause;
- }
- def having (se:StatementExpression): SelectBeyond = new SelectBeyond {
- val setQuantifier = SelectBeyond.this.setQuantifier;
- val selectList = SelectBeyond.this.selectList;
- val selectTypes = SelectBeyond.this.selectTypes;
- val fromClause = SelectBeyond.this.fromClause;
- val whereClause = SelectBeyond.this.whereClause;
- val groupByClause = SelectBeyond.this.groupByClause;
- val havingClause = Some(se.toStatement);
- }
- }
-
- implicit def selectBeyondToStatementSelect (sb:SelectBeyond): statement.Select = new statement.Select {
- val setQuantifier = sb.setQuantifier;
- val selectList = sb.selectList;
- val fromClause = sb.fromClause;
- val whereClause = sb.whereClause;
- val groupByClause = sb.groupByClause;
- val havingClause = sb.havingClause;
- val fieldTypes = sb.selectTypes;
- }
-
- abstract class SelectGroupBy {
- def groupByClause: List[statement.Expression];
- def then (se:StatementExpression): SelectGroupBy = new SelectGroupBy {
- val groupByClause =
- SelectGroupBy.this.groupByClause ::: List(se.toStatement);
- }
- def then (se:String): SelectGroupBy = new SelectGroupBy {
- val groupByClause =
- SelectGroupBy.this.groupByClause ::: List(new statement.expression.Field {
- val tableName = None;
- val fieldName = se;
- });
- }
- }
-
- implicit def statementExpressionToSelectGroupBy (se:StatementExpression): SelectGroupBy = new SelectGroupBy {
- val groupByClause = List(se.toStatement);
- }
-
- implicit def stringToSelectGroupBy (se:String): SelectGroupBy = new SelectGroupBy {
- val groupByClause = List(new statement.expression.Field {
- val tableName = None;
- val fieldName = se;
- });
- }
-
-}
diff --git a/src/dbc/scala/dbc/syntax/StatementExpression.scala b/src/dbc/scala/dbc/syntax/StatementExpression.scala
deleted file mode 100644
index 65bb0947f7..0000000000
--- a/src/dbc/scala/dbc/syntax/StatementExpression.scala
+++ /dev/null
@@ -1,221 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package syntax;
-
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class StatementExpression {
-
- def toStatement: statement.Expression;
-
- def and (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "AND";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def or (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "OR";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def == (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "=";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def < (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "<";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def > (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = ">";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def <= (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "<=";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def >= (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = ">=";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def <> (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "<>";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def isNull: StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.UnaryOperator {
- val operator = "IS NULL";
- val operatorIsLeft = false;
- val operand = StatementExpression.this.toStatement;
- }
- }
- def isNotNull: StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.UnaryOperator {
- val operator = "IS NOT NULL";
- val operatorIsLeft = false;
- val operand = StatementExpression.this.toStatement;
- }
- }
- def + (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "+";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def - (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "-";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def * (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "*";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def / (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "/";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def % (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "%";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def ^ (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "^";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def not : StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.UnaryOperator {
- val operator = "!";
- val operatorIsLeft = false;
- val operand = StatementExpression.this.toStatement;
- }
- }
- def || (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "||";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def like (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "LIKE";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def similar (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "SIMILAR";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = se.toStatement;
- }
- }
- def in (se:statement.Select): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.BinaryOperator {
- val operator = "IN";
- val leftOperand = StatementExpression.this.toStatement;
- val rightOperand = new statement.expression.Select {
- val selectStatement = se;
- };
- }
- }
-
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object StatementExpression {
-
- def not (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.UnaryOperator {
- val operator = "NOT";
- val operatorIsLeft = true;
- val operand = se.toStatement;
- }
- }
- def abs (se:StatementExpression): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.UnaryOperator {
- val operator = "@";
- val operatorIsLeft = true;
- val operand = se.toStatement;
- }
- }
- def exists (se:statement.Select): StatementExpression = new StatementExpression {
- val toStatement = new statement.expression.UnaryOperator {
- val operator = "EXISTS";
- val operatorIsLeft = true;
- val operand = new statement.expression.Select {
- val selectStatement = se;
- };
- }
- }
-
- abstract class StatementField extends StatementExpression {
- def fieldName: String;
- def tableName: Option[String] = None;
- def in (tn:String): StatementField = new StatementField {
- val fieldName = StatementField.this.fieldName;
- override val tableName = Some(tn);
- }
- def toStatement: statement.expression.Field = new statement.expression.Field {
- override val schemaName = None;
- val tableName = StatementField.this.tableName;
- val fieldName = StatementField.this.fieldName;
- }
- }
-
- implicit def stringToStatementField (ef:String): StatementField = new StatementField {
- val fieldName = ef;
- }
-
-
-
-
-}
diff --git a/src/dbc/scala/dbc/value/ApproximateNumeric.scala b/src/dbc/scala/dbc/value/ApproximateNumeric.scala
deleted file mode 100644
index fa47d8815b..0000000000
--- a/src/dbc/scala/dbc/value/ApproximateNumeric.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class ApproximateNumeric [Type] extends Value {
-
- val dataType: datatype.ApproximateNumeric[Type];
-
- def sqlString = nativeValue.toString();
-
- }
-
-@deprecated(DbcIsDeprecated, "2.9.0") object ApproximateNumeric {
-
- implicit def approximateNumericToFloar (obj:value.ApproximateNumeric[Float]): Float = obj.nativeValue;
- implicit def approximateNumericToDouble (obj:value.ApproximateNumeric[Double]): Double = obj.nativeValue;
-
-}
diff --git a/src/dbc/scala/dbc/value/Boolean.scala b/src/dbc/scala/dbc/value/Boolean.scala
deleted file mode 100644
index 5221ce2328..0000000000
--- a/src/dbc/scala/dbc/value/Boolean.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Boolean extends Value {
-
- val dataType: datatype.Boolean;
-
- def sqlString = if (nativeValue) "TRUE" else "FALSE";
-
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object Boolean {
-
- implicit def booleanToBoolean (obj:value.Boolean): scala.Boolean = obj.nativeValue;
-
-}
diff --git a/src/dbc/scala/dbc/value/Character.scala b/src/dbc/scala/dbc/value/Character.scala
deleted file mode 100644
index 4ff983c591..0000000000
--- a/src/dbc/scala/dbc/value/Character.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-
-/** A SQL-99 value of type character string. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Character extends Value {
-
- override val dataType: datatype.Character;
-
- /** An SQL-99 compliant string representation of the value. */
- def sqlString: String = {
- "'" + nativeValue + "'"
- }
-
-}
-
-/** An object offering transformation methods (views) on the value.
- * This object must be visible in an expression to use value auto-
- * conversion. */
-@deprecated(DbcIsDeprecated, "2.9.0") object Character {
-
- /** A character string value as a native string. */
- implicit def characterToString (obj:value.Character): String = obj.nativeValue;
-
-}
diff --git a/src/dbc/scala/dbc/value/CharacterLargeObject.scala b/src/dbc/scala/dbc/value/CharacterLargeObject.scala
deleted file mode 100644
index b9e81eb3af..0000000000
--- a/src/dbc/scala/dbc/value/CharacterLargeObject.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-
-/** A SQL-99 value of type character large object. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class CharacterLargeObject extends Value {
-
- override val dataType: datatype.CharacterLargeObject;
-
- /** An SQL-99 compliant string representation of the value. */
- def sqlString: String = {
- "'" + nativeValue + "'"
- }
-
-}
-
-/** An object offering transformation methods (views) on the value.
- * This object must be visible in an expression to use value auto-
- * conversion. */
-@deprecated(DbcIsDeprecated, "2.9.0") object CharacterLargeObject {
-
- /** A character large object value as a native string. */
- implicit def characterLargeObjectToString (obj:value.CharacterLargeObject): String = obj.nativeValue;
-
-}
diff --git a/src/dbc/scala/dbc/value/CharacterVarying.scala b/src/dbc/scala/dbc/value/CharacterVarying.scala
deleted file mode 100644
index 72e7d06362..0000000000
--- a/src/dbc/scala/dbc/value/CharacterVarying.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-
-/** A SQL-99 value of type character varying string. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class CharacterVarying extends Value {
-
- override val dataType: datatype.CharacterVarying;
-
- /** An SQL-99 compliant string representation of the value. */
- def sqlString: String = {
- "'" + nativeValue + "'"
- }
-
-}
-
-/** An object offering transformation methods (views) on the value.
- * This object must be visible in an expression to use value auto-
- * conversion. */
-@deprecated(DbcIsDeprecated, "2.9.0") object CharacterVarying {
-
- /** A character varying string value as a native string. */
- implicit def characterVaryingToString (obj:value.CharacterVarying): String = obj.nativeValue;
-
-}
diff --git a/src/dbc/scala/dbc/value/Conversion.scala b/src/dbc/scala/dbc/value/Conversion.scala
deleted file mode 100644
index c9297e37db..0000000000
--- a/src/dbc/scala/dbc/value/Conversion.scala
+++ /dev/null
@@ -1,156 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-import java.math._;
-
-@deprecated(DbcIsDeprecated, "2.9.0") object Conversion {
-
- class Illegal (msg:String) extends Exception(msg);
-
- implicit def view1 (value:Value): Byte = {
- if (value.dataType.nativeTypeId == DataType.BYTE) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to byte: "+value)
- }
- }
-
- implicit def view2 (value:Value): Short = {
- if (value.dataType.nativeTypeId == DataType.BYTE) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]];
- v.nativeValue.toShort
- } else if (value.dataType.nativeTypeId == DataType.SHORT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to short: "+value)
- }
- }
-
- implicit def view3 (value:Value): Int = {
- if (value.dataType.nativeTypeId == DataType.BYTE) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]];
- v.nativeValue.toInt
- } else if (value.dataType.nativeTypeId == DataType.SHORT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]];
- v.nativeValue.toInt
- } else if (value.dataType.nativeTypeId == DataType.INT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Int]];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to int: "+value)
- }
- }
-
- implicit def view4 (value:Value): Long = {
- if (value.dataType.nativeTypeId == DataType.BYTE) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]];
- v.nativeValue.toLong
- } else if (value.dataType.nativeTypeId == DataType.SHORT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]];
- v.nativeValue.toLong
- } else if (value.dataType.nativeTypeId == DataType.INT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Int]];
- v.nativeValue.toLong
- } else if (value.dataType.nativeTypeId == DataType.LONG) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Long]];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to long: "+value)
- }
- }
-
- implicit def view5 (value:Value): BigInteger = {
- if (value.dataType.nativeTypeId == DataType.BYTE) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]];
- new BigInteger(v.nativeValue.toString(),10)
- } else if (value.dataType.nativeTypeId == DataType.SHORT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]];
- new BigInteger(v.nativeValue.toString(),10)
- } else if (value.dataType.nativeTypeId == DataType.INT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Int]];
- new BigInteger(v.nativeValue.toString(),10)
- } else if (value.dataType.nativeTypeId == DataType.LONG) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Long]];
- new BigInteger(v.nativeValue.toString(),10)
- } else if (value.dataType.nativeTypeId == DataType.BIG_INTEGER) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[BigInteger]];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to big integer: "+value)
- }
- }
-
- implicit def view6 (value:Value): BigDecimal = {
- if (value.dataType.nativeTypeId == DataType.BYTE) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Byte]];
- new BigDecimal(v.nativeValue.toString())
- } else if (value.dataType.nativeTypeId == DataType.SHORT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Short]];
- new BigDecimal(v.nativeValue.toString())
- } else if (value.dataType.nativeTypeId == DataType.INT) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Int]];
- new BigDecimal(v.nativeValue.toString())
- } else if (value.dataType.nativeTypeId == DataType.LONG) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[Long]];
- new BigDecimal(v.nativeValue.toString())
- } else if (value.dataType.nativeTypeId == DataType.BIG_INTEGER) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[BigInteger]];
- new BigDecimal(v.nativeValue)
- } else if (value.dataType.nativeTypeId == DataType.BIG_DECIMAL) {
- val v = value.asInstanceOf[dbc.value.ExactNumeric[BigDecimal]];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to big decimal: "+value)
- }
- }
-
- implicit def view7 (value:Value): Float = {
- if (value.dataType.nativeTypeId == DataType.FLOAT) {
- val v = value.asInstanceOf[dbc.value.ApproximateNumeric[Float]];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to float: "+value)
- }
- }
-
- implicit def view8 (value:Value): Double = {
- if (value.dataType.nativeTypeId == DataType.FLOAT) {
- val v = value.asInstanceOf[dbc.value.ApproximateNumeric[Float]];
- v.nativeValue.toFloat
- } else if (value.dataType.nativeTypeId == DataType.DOUBLE) {
- val v = value.asInstanceOf[dbc.value.ApproximateNumeric[Double]];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to double: "+value)
- }
- }
-
- implicit def view9 (value:Value): scala.Boolean = {
- if (value.dataType.nativeTypeId == DataType.BOOLEAN) {
- val v = value.asInstanceOf[dbc.value.Boolean];
- v.nativeValue
- } else {
- throw new Illegal("Cannot convert value to boolean: "+value)
- }
- }
-
- implicit def view10 (value:Value): String = value match {
- case v:dbc.value.Character => v.nativeValue;
- case v:dbc.value.CharacterLargeObject => v.nativeValue;
- case v:dbc.value.CharacterVarying => v.nativeValue;
- case _ => throw new Illegal("Cannot convert value to string")
- }
-
-}
diff --git a/src/dbc/scala/dbc/value/ExactNumeric.scala b/src/dbc/scala/dbc/value/ExactNumeric.scala
deleted file mode 100644
index 7cd8b89a8c..0000000000
--- a/src/dbc/scala/dbc/value/ExactNumeric.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-
-import java.math.BigInteger;
-import java.math.BigDecimal;
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class ExactNumeric [Type] extends Value {
-
- val dataType: datatype.ExactNumeric[Type];
-
- def sqlString = nativeValue.toString();
-
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object ExactNumeric {
-
- implicit def exactNumericToByte (obj:value.ExactNumeric[Byte]): Byte = obj.nativeValue;
- implicit def exactNumericToShort (obj:value.ExactNumeric[Short]): Short = obj.nativeValue;
- implicit def exactNumericToInt (obj:value.ExactNumeric[Int]): Int = obj.nativeValue;
- implicit def exactNumericToLong (obj:value.ExactNumeric[Long]): Long = obj.nativeValue;
- implicit def exactNumericToBigInteger (obj:value.ExactNumeric[BigInteger]): BigInteger = obj.nativeValue;
- implicit def exactNumericToBigDecimal (obj:value.ExactNumeric[BigDecimal]): BigDecimal = obj.nativeValue;
-
-}
diff --git a/src/dbc/scala/dbc/value/Factory.scala b/src/dbc/scala/dbc/value/Factory.scala
deleted file mode 100644
index 2d6101f6de..0000000000
--- a/src/dbc/scala/dbc/value/Factory.scala
+++ /dev/null
@@ -1,95 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-
-import java.math.BigInteger;
-import java.math.BigDecimal;
-
-@deprecated(DbcIsDeprecated, "2.9.0") object Factory {
-
- def create (result: java.sql.ResultSet, index: Int, expectedDataType: DataType): Value = {
- expectedDataType.nativeTypeId match {
- case DataType.OBJECT =>
- new value.Unknown {
- val dataType = expectedDataType.asInstanceOf[datatype.Unknown];
- val nativeValue: AnyRef = result.getObject(index);
- }
- case DataType.STRING => {
- expectedDataType match {
- case t:datatype.Character =>
- new value.Character {
- val dataType = t;
- val nativeValue: String = result.getString(index);
- }
- case t:datatype.CharacterVarying =>
- new value.CharacterVarying {
- val dataType = t;
- val nativeValue: String = result.getString(index);
- }
- case t:datatype.CharacterLargeObject =>
- new value.CharacterLargeObject {
- val dataType = t;
- val nativeValue: String = result.getString(index);
- }
- }
- }
- case DataType.BOOLEAN =>
- new value.Boolean {
- val dataType = expectedDataType.asInstanceOf[datatype.Boolean];
- val nativeValue: scala.Boolean = result.getBoolean(index);
- }
- case DataType.FLOAT =>
- new value.ApproximateNumeric[Float] {
- val dataType = expectedDataType.asInstanceOf[datatype.ApproximateNumeric[Float]];
- val nativeValue: Float = result.getFloat(index);
- }
- case DataType.DOUBLE =>
- new value.ApproximateNumeric[Double] {
- val dataType = expectedDataType.asInstanceOf[datatype.ApproximateNumeric[Double]];
- val nativeValue: Double = result.getDouble(index);
- }
- case DataType.BYTE =>
- new value.ExactNumeric[Byte] {
- val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[Byte]];
- val nativeValue: Byte = result.getByte(index);
- }
- case DataType.SHORT =>
- new value.ExactNumeric[Short] {
- val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[Short]];
- val nativeValue: Short = result.getShort(index);
- }
- case DataType.INT =>
- new value.ExactNumeric[Int] {
- val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[Int]];
- val nativeValue: Int = result.getInt(index);
- }
- case DataType.LONG =>
- new value.ExactNumeric[Long] {
- val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[Long]];
- val nativeValue:Long = result.getLong(index);
- }
- case DataType.BIG_INTEGER =>
- new value.ExactNumeric[BigInteger] {
- val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[BigInteger]];
- val nativeValue: BigInteger = result.getBigDecimal(index).unscaledValue();
- }
- case DataType.BIG_DECIMAL =>
- new value.ExactNumeric[BigDecimal] {
- val dataType = expectedDataType.asInstanceOf[datatype.ExactNumeric[BigDecimal]];
- val nativeValue: BigDecimal = result.getBigDecimal(index);
- }
-
- }
- }
-
-}
diff --git a/src/dbc/scala/dbc/value/Unknown.scala b/src/dbc/scala/dbc/value/Unknown.scala
deleted file mode 100644
index 89764a5831..0000000000
--- a/src/dbc/scala/dbc/value/Unknown.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package value;
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Unknown extends Value {
-
- val dataType: datatype.Unknown;
-
- def sqlString = sys.error("An 'ANY' value cannot be represented.");
-
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object UnknownType {
-
- def view (obj:value.Unknown): AnyRef = obj.nativeValue;
-
-}
diff --git a/src/dbc/scala/dbc/vendor/PostgreSQL.scala b/src/dbc/scala/dbc/vendor/PostgreSQL.scala
deleted file mode 100644
index ac528d5f82..0000000000
--- a/src/dbc/scala/dbc/vendor/PostgreSQL.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.dbc
-package vendor;
-
-
-import compat.Platform
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class PostgreSQL extends Vendor {
-
- def uri:java.net.URI;
- def user:String;
- def pass:String;
-
- val retainedConnections = 5;
-
- val nativeDriverClass = Platform.getClassForName("org.postgresql.Driver");
-
- val urlProtocolString = "jdbc:postgresql:"
-
-}
diff --git a/src/detach/library/scala/remoting/Channel.scala b/src/detach/library/scala/remoting/Channel.scala
index 541e45a477..54b8fb100e 100644
--- a/src/detach/library/scala/remoting/Channel.scala
+++ b/src/detach/library/scala/remoting/Channel.scala
@@ -116,20 +116,20 @@ class Channel protected (socket: Socket) {
* the expected type.
*/
@throws(classOf[ChannelException])
- def receive[T](implicit expected: reflect.Manifest[T]): T = {
- val found = in.readObject().asInstanceOf[reflect.Manifest[_]]
+ def receive[T](implicit expected: reflect.ClassTag[T]): T = {
+ val found = in.readObject().asInstanceOf[reflect.ClassTag[_]]
info("receive: found="+found+", expected="+expected)
- import scala.reflect.Manifest
+ import scala.reflect.ClassTag
val x = found match {
- case Manifest.Unit => ()
- case Manifest.Boolean => in.readBoolean()
- case Manifest.Byte => in.readByte()
- case Manifest.Char => in.readChar()
- case Manifest.Short => in.readShort()
- case Manifest.Int => in.readInt()
- case Manifest.Long => in.readLong()
- case Manifest.Float => in.readFloat()
- case Manifest.Double => in.readDouble()
+ case ClassTag.Unit => ()
+ case ClassTag.Boolean => in.readBoolean()
+ case ClassTag.Byte => in.readByte()
+ case ClassTag.Char => in.readChar()
+ case ClassTag.Short => in.readShort()
+ case ClassTag.Int => in.readInt()
+ case ClassTag.Long => in.readLong()
+ case ClassTag.Float => in.readFloat()
+ case ClassTag.Double => in.readDouble()
case _ => in.readObject()
}
val res = if (found <:< expected)
@@ -144,12 +144,12 @@ class Channel protected (socket: Socket) {
/** <code>?</code> method may throw either an
* <code>ClassNotFoundException</code> or an <code>IOException</code>.
*/
- def ?[T](implicit m: reflect.Manifest[T]): T = receive[T](m)
+ def ?[T](implicit t: reflect.ClassTag[T]): T = receive[T](t)
/** <code>send</code> method may throw an <code>IOException</code>.
*/
- def send[T](x: T)(implicit m: reflect.Manifest[T]) {
- out writeObject m
+ def send[T](x: T)(implicit t: reflect.ClassTag[T]) {
+ out writeObject t
x match {
case x: Unit => // nop
case x: Boolean => out writeBoolean x
@@ -168,7 +168,7 @@ class Channel protected (socket: Socket) {
/** <code>!</code> method may throw an <code>IOException</code>.
*/
- def ![T](x: T)(implicit m: reflect.Manifest[T]) { send(x)(m) }
+ def ![T](x: T)(implicit m: reflect.ClassTag[T]) { send(x)(m) }
def close() {
try { socket.close() }
diff --git a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java
index e9389e9acb..4b5b3382f5 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinPool.java
@@ -1,5 +1,4 @@
/*
-
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
@@ -12,22 +11,18 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;
-//import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
-//import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.RunnableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
-interface RunnableFuture<T> extends Runnable {
- //TR placeholder for java.util.concurrent.RunnableFuture
-}
-
/**
* An {@link ExecutorService} for running {@link ForkJoinTask}s.
* A {@code ForkJoinPool} provides the entry point for submissions
@@ -127,7 +122,7 @@ interface RunnableFuture<T> extends Runnable {
* @since 1.7
* @author Doug Lea
*/
-public class ForkJoinPool /*extends AbstractExecutorService*/ {
+public class ForkJoinPool extends AbstractExecutorService {
/*
* Implementation Overview
@@ -634,7 +629,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
final ForkJoinPool pool; // the containing pool (may be null)
final ForkJoinWorkerThread owner; // owning thread or null if shared
volatile Thread parker; // == owner during call to park; else null
- ForkJoinTask<?> currentJoin; // task being joined in awaitJoin
+ volatile ForkJoinTask<?> currentJoin; // task being joined in awaitJoin
ForkJoinTask<?> currentSteal; // current non-local task being executed
// Heuristic padding to ameliorate unfortunate memory placements
Object p00, p01, p02, p03, p04, p05, p06, p07;
@@ -726,12 +721,11 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
* version of this method because it is never needed.)
*/
final ForkJoinTask<?> pop() {
- ForkJoinTask<?> t; int m;
- ForkJoinTask<?>[] a = array;
- if (a != null && (m = a.length - 1) >= 0) {
+ ForkJoinTask<?>[] a; ForkJoinTask<?> t; int m;
+ if ((a = array) != null && (m = a.length - 1) >= 0) {
for (int s; (s = top - 1) - base >= 0;) {
- int j = ((m & s) << ASHIFT) + ABASE;
- if ((t = (ForkJoinTask<?>)U.getObjectVolatile(a, j)) == null)
+ long j = ((m & s) << ASHIFT) + ABASE;
+ if ((t = (ForkJoinTask<?>)U.getObject(a, j)) == null)
break;
if (U.compareAndSwapObject(a, j, t, null)) {
top = s;
@@ -835,54 +829,6 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
}
/**
- * If present, removes from queue and executes the given task, or
- * any other cancelled task. Returns (true) immediately on any CAS
- * or consistency check failure so caller can retry.
- *
- * @return false if no progress can be made
- */
- final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
- boolean removed = false, empty = true, progress = true;
- ForkJoinTask<?>[] a; int m, s, b, n;
- if ((a = array) != null && (m = a.length - 1) >= 0 &&
- (n = (s = top) - (b = base)) > 0) {
- for (ForkJoinTask<?> t;;) { // traverse from s to b
- int j = ((--s & m) << ASHIFT) + ABASE;
- t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
- if (t == null) // inconsistent length
- break;
- else if (t == task) {
- if (s + 1 == top) { // pop
- if (!U.compareAndSwapObject(a, j, task, null))
- break;
- top = s;
- removed = true;
- }
- else if (base == b) // replace with proxy
- removed = U.compareAndSwapObject(a, j, task,
- new EmptyTask());
- break;
- }
- else if (t.status >= 0)
- empty = false;
- else if (s + 1 == top) { // pop and throw away
- if (U.compareAndSwapObject(a, j, t, null))
- top = s;
- break;
- }
- if (--n == 0) {
- if (!empty && base == b)
- progress = false;
- break;
- }
- }
- }
- if (removed)
- task.doExec();
- return progress;
- }
-
- /**
* Initializes or doubles the capacity of array. Call either
* by owner or with lock held -- it is OK for base, but not
* top, to move while resizings are in progress.
@@ -944,69 +890,98 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
// Execution methods
/**
- * Removes and runs tasks until empty, using local mode
- * ordering. Normally called only after checking for apparent
- * non-emptiness.
+ * Pops and runs tasks until empty.
*/
- final void runLocalTasks() {
- // hoist checks from repeated pop/poll
- ForkJoinTask<?>[] a; int m;
- if ((a = array) != null && (m = a.length - 1) >= 0) {
- if (mode == 0) {
- for (int s; (s = top - 1) - base >= 0;) {
- int j = ((m & s) << ASHIFT) + ABASE;
- ForkJoinTask<?> t =
- (ForkJoinTask<?>)U.getObjectVolatile(a, j);
- if (t != null) {
- if (U.compareAndSwapObject(a, j, t, null)) {
- top = s;
- t.doExec();
- }
- }
- else
- break;
- }
+ private void popAndExecAll() {
+ // A bit faster than repeated pop calls
+ ForkJoinTask<?>[] a; int m, s; long j; ForkJoinTask<?> t;
+ while ((a = array) != null && (m = a.length - 1) >= 0 &&
+ (s = top - 1) - base >= 0 &&
+ (t = ((ForkJoinTask<?>)
+ U.getObject(a, j = ((m & s) << ASHIFT) + ABASE)))
+ != null) {
+ if (U.compareAndSwapObject(a, j, t, null)) {
+ top = s;
+ t.doExec();
}
- else {
- for (int b; (b = base) - top < 0;) {
- int j = ((m & b) << ASHIFT) + ABASE;
- ForkJoinTask<?> t =
- (ForkJoinTask<?>)U.getObjectVolatile(a, j);
- if (t != null) {
- if (base == b &&
- U.compareAndSwapObject(a, j, t, null)) {
- base = b + 1;
- t.doExec();
- }
- } else if (base == b) {
- if (b + 1 == top)
+ }
+ }
+
+ /**
+ * Polls and runs tasks until empty.
+ */
+ private void pollAndExecAll() {
+ for (ForkJoinTask<?> t; (t = poll()) != null;)
+ t.doExec();
+ }
+
+ /**
+ * If present, removes from queue and executes the given task, or
+ * any other cancelled task. Returns (true) immediately on any CAS
+ * or consistency check failure so caller can retry.
+ *
+ * @return 0 if no progress can be made, else positive
+ * (this unusual convention simplifies use with tryHelpStealer.)
+ */
+ final int tryRemoveAndExec(ForkJoinTask<?> task) {
+ int stat = 1;
+ boolean removed = false, empty = true;
+ ForkJoinTask<?>[] a; int m, s, b, n;
+ if ((a = array) != null && (m = a.length - 1) >= 0 &&
+ (n = (s = top) - (b = base)) > 0) {
+ for (ForkJoinTask<?> t;;) { // traverse from s to b
+ int j = ((--s & m) << ASHIFT) + ABASE;
+ t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
+ if (t == null) // inconsistent length
+ break;
+ else if (t == task) {
+ if (s + 1 == top) { // pop
+ if (!U.compareAndSwapObject(a, j, task, null))
break;
- Thread.yield(); // wait for lagging update
+ top = s;
+ removed = true;
}
+ else if (base == b) // replace with proxy
+ removed = U.compareAndSwapObject(a, j, task,
+ new EmptyTask());
+ break;
+ }
+ else if (t.status >= 0)
+ empty = false;
+ else if (s + 1 == top) { // pop and throw away
+ if (U.compareAndSwapObject(a, j, t, null))
+ top = s;
+ break;
+ }
+ if (--n == 0) {
+ if (!empty && base == b)
+ stat = 0;
+ break;
}
}
}
+ if (removed)
+ task.doExec();
+ return stat;
}
/**
* Executes a top-level task and any local tasks remaining
* after execution.
- *
- * @return true unless terminating
*/
- final boolean runTask(ForkJoinTask<?> t) {
- boolean alive = true;
+ final void runTask(ForkJoinTask<?> t) {
if (t != null) {
currentSteal = t;
t.doExec();
- if (top != base) // conservative guard
- runLocalTasks();
+ if (top != base) { // process remaining local tasks
+ if (mode == 0)
+ popAndExecAll();
+ else
+ pollAndExecAll();
+ }
++nsteals;
currentSteal = null;
}
- else if (runState < 0) // terminating
- alive = false;
- return alive;
}
/**
@@ -1072,7 +1047,6 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
}
}
-
/**
* Per-thread records for threads that submit to pools. Currently
* holds only pseudo-random seed / index that is used to choose
@@ -1165,7 +1139,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
* traversal parameters at the expense of sometimes blocking when
* we could be helping.
*/
- private static final int MAX_HELP = 32;
+ private static final int MAX_HELP = 64;
/**
* Secondary time-based bound (in nanosecs) for helping attempts
@@ -1175,7 +1149,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
* value should roughly approximate the time required to create
* and/or activate a worker thread.
*/
- private static final long COMPENSATION_DELAY = 100L * 1000L; // 0.1 millisec
+ private static final long COMPENSATION_DELAY = 1L << 18; // ~0.25 millisec
/**
* Increment for seed generators. See class ThreadLocal for
@@ -1326,22 +1300,28 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
*
* @param w the worker's queue
*/
+
final void registerWorker(WorkQueue w) {
Mutex lock = this.lock;
lock.lock();
try {
WorkQueue[] ws = workQueues;
if (w != null && ws != null) { // skip on shutdown/failure
- int rs, n;
- while ((n = ws.length) < // ensure can hold total
- (parallelism + (short)(ctl >>> TC_SHIFT) << 1))
- workQueues = ws = Arrays.copyOf(ws, n << 1);
- int m = n - 1;
+ int rs, n = ws.length, m = n - 1;
int s = nextSeed += SEED_INCREMENT; // rarely-colliding sequence
w.seed = (s == 0) ? 1 : s; // ensure non-zero seed
int r = (s << 1) | 1; // use odd-numbered indices
- while (ws[r &= m] != null) // step by approx half size
- r += ((n >>> 1) & SQMASK) + 2;
+ if (ws[r &= m] != null) { // collision
+ int probes = 0; // step by approx half size
+ int step = (n <= 4) ? 2 : ((n >>> 1) & SQMASK) + 2;
+ while (ws[r = (r + step) & m] != null) {
+ if (++probes >= n) {
+ workQueues = ws = Arrays.copyOf(ws, n <<= 1);
+ m = n - 1;
+ probes = 0;
+ }
+ }
+ }
w.eventCount = w.poolIndex = r; // establish before recording
ws[r] = w; // also update seq
runState = ((rs = runState) & SHUTDOWN) | ((rs + 2) & ~SHUTDOWN);
@@ -1488,7 +1468,6 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
}
}
-
// Scanning for tasks
/**
@@ -1496,7 +1475,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
*/
final void runWorker(WorkQueue w) {
w.growArray(false); // initialize queue array in this thread
- do {} while (w.runTask(scan(w)));
+ do { w.runTask(scan(w)); } while (w.runState >= 0);
}
/**
@@ -1559,8 +1538,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
q.base = b + 1; // specialization of pollAt
return t;
}
- else if ((t != null || b + 1 != q.top) &&
- (ec < 0 || j <= m)) {
+ else if (ec < 0 || j <= m) {
rs = 0; // mark scan as imcomplete
break; // caller can retry after release
}
@@ -1568,6 +1546,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
if (--j < 0)
break;
}
+
long c = ctl; int e = (int)c, a = (int)(c >> AC_SHIFT), nr, ns;
if (e < 0) // decode ctl on empty scan
w.runState = -1; // pool is terminating
@@ -1635,7 +1614,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
*/
private void idleAwaitWork(WorkQueue w, long currentCtl, long prevCtl) {
if (w.eventCount < 0 && !tryTerminate(false, false) &&
- (int)prevCtl != 0 && ctl == currentCtl) {
+ (int)prevCtl != 0 && !hasQueuedSubmissions() && ctl == currentCtl) {
Thread wt = Thread.currentThread();
Thread.yield(); // yield before block
while (ctl == currentCtl) {
@@ -1670,70 +1649,79 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
* leaves hints in workers to speed up subsequent calls. The
* implementation is very branchy to cope with potential
* inconsistencies or loops encountering chains that are stale,
- * unknown, or so long that they are likely cyclic. All of these
- * cases are dealt with by just retrying by caller.
+ * unknown, or so long that they are likely cyclic.
*
* @param joiner the joining worker
* @param task the task to join
- * @return true if found or ran a task (and so is immediately retryable)
- */
- private boolean tryHelpStealer(WorkQueue joiner, ForkJoinTask<?> task) {
- WorkQueue[] ws;
- int m, depth = MAX_HELP; // remaining chain depth
- boolean progress = false;
- if ((ws = workQueues) != null && (m = ws.length - 1) > 0 &&
- task.status >= 0) {
- ForkJoinTask<?> subtask = task; // current target
- outer: for (WorkQueue j = joiner;;) {
- WorkQueue stealer = null; // find stealer of subtask
- WorkQueue v = ws[j.stealHint & m]; // try hint
- if (v != null && v.currentSteal == subtask)
- stealer = v;
- else { // scan
- for (int i = 1; i <= m; i += 2) {
- if ((v = ws[i]) != null && v.currentSteal == subtask &&
- v != joiner) {
- stealer = v;
- j.stealHint = i; // save hint
- break;
- }
+ * @return 0 if no progress can be made, negative if task
+ * known complete, else positive
+ */
+ private int tryHelpStealer(WorkQueue joiner, ForkJoinTask<?> task) {
+ int stat = 0, steps = 0; // bound to avoid cycles
+ if (joiner != null && task != null) { // hoist null checks
+ restart: for (;;) {
+ ForkJoinTask<?> subtask = task; // current target
+ for (WorkQueue j = joiner, v;;) { // v is stealer of subtask
+ WorkQueue[] ws; int m, s, h;
+ if ((s = task.status) < 0) {
+ stat = s;
+ break restart;
}
- if (stealer == null)
- break;
- }
-
- for (WorkQueue q = stealer;;) { // try to help stealer
- ForkJoinTask[] a; ForkJoinTask<?> t; int b;
- if (task.status < 0)
- break outer;
- if ((b = q.base) - q.top < 0 && (a = q.array) != null) {
- progress = true;
- int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
- t = (ForkJoinTask<?>)U.getObjectVolatile(a, i);
- if (subtask.status < 0) // must recheck before taking
- break outer;
- if (t != null &&
- q.base == b &&
- U.compareAndSwapObject(a, i, t, null)) {
- q.base = b + 1;
- joiner.runSubtask(t);
+ if ((ws = workQueues) == null || (m = ws.length - 1) <= 0)
+ break restart; // shutting down
+ if ((v = ws[h = (j.stealHint | 1) & m]) == null ||
+ v.currentSteal != subtask) {
+ for (int origin = h;;) { // find stealer
+ if (((h = (h + 2) & m) & 15) == 1 &&
+ (subtask.status < 0 || j.currentJoin != subtask))
+ continue restart; // occasional staleness check
+ if ((v = ws[h]) != null &&
+ v.currentSteal == subtask) {
+ j.stealHint = h; // save hint
+ break;
+ }
+ if (h == origin)
+ break restart; // cannot find stealer
}
- else if (q.base == b)
- break outer; // possibly stalled
}
- else { // descend
- ForkJoinTask<?> next = stealer.currentJoin;
- if (--depth <= 0 || subtask.status < 0 ||
- next == null || next == subtask)
- break outer; // stale, dead-end, or cyclic
- subtask = next;
- j = stealer;
- break;
+ for (;;) { // help stealer or descend to its stealer
+ ForkJoinTask[] a; int b;
+ if (subtask.status < 0) // surround probes with
+ continue restart; // consistency checks
+ if ((b = v.base) - v.top < 0 && (a = v.array) != null) {
+ int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
+ ForkJoinTask<?> t =
+ (ForkJoinTask<?>)U.getObjectVolatile(a, i);
+ if (subtask.status < 0 || j.currentJoin != subtask ||
+ v.currentSteal != subtask)
+ continue restart; // stale
+ stat = 1; // apparent progress
+ if (t != null && v.base == b &&
+ U.compareAndSwapObject(a, i, t, null)) {
+ v.base = b + 1; // help stealer
+ joiner.runSubtask(t);
+ }
+ else if (v.base == b && ++steps == MAX_HELP)
+ break restart; // v apparently stalled
+ }
+ else { // empty -- try to descend
+ ForkJoinTask<?> next = v.currentJoin;
+ if (subtask.status < 0 || j.currentJoin != subtask ||
+ v.currentSteal != subtask)
+ continue restart; // stale
+ else if (next == null || ++steps == MAX_HELP)
+ break restart; // dead-end or maybe cyclic
+ else {
+ subtask = next;
+ j = v;
+ break;
+ }
+ }
}
}
}
}
- return progress;
+ return stat;
}
/**
@@ -1833,44 +1821,50 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
* @return task status on exit
*/
final int awaitJoin(WorkQueue joiner, ForkJoinTask<?> task) {
- ForkJoinTask<?> prevJoin = joiner.currentJoin;
- joiner.currentJoin = task;
- long startTime = 0L;
- for (int k = 0, s; ; ++k) {
- if ((joiner.isEmpty() ? // try to help
- !tryHelpStealer(joiner, task) :
- !joiner.tryRemoveAndExec(task))) {
- if (k == 0) {
- startTime = System.nanoTime();
- tryPollForAndExec(joiner, task); // check uncommon case
- }
- else if ((k & (MAX_HELP - 1)) == 0 &&
- System.nanoTime() - startTime >= COMPENSATION_DELAY &&
- tryCompensate(task, null)) {
- if (task.trySetSignal() && task.status >= 0) {
- synchronized (task) {
- if (task.status >= 0) {
- try { // see ForkJoinTask
- task.wait(); // for explanation
- } catch (InterruptedException ie) {
+ int s;
+ if ((s = task.status) >= 0) {
+ ForkJoinTask<?> prevJoin = joiner.currentJoin;
+ joiner.currentJoin = task;
+ long startTime = 0L;
+ for (int k = 0;;) {
+ if ((s = (joiner.isEmpty() ? // try to help
+ tryHelpStealer(joiner, task) :
+ joiner.tryRemoveAndExec(task))) == 0 &&
+ (s = task.status) >= 0) {
+ if (k == 0) {
+ startTime = System.nanoTime();
+ tryPollForAndExec(joiner, task); // check uncommon case
+ }
+ else if ((k & (MAX_HELP - 1)) == 0 &&
+ System.nanoTime() - startTime >=
+ COMPENSATION_DELAY &&
+ tryCompensate(task, null)) {
+ if (task.trySetSignal()) {
+ synchronized (task) {
+ if (task.status >= 0) {
+ try { // see ForkJoinTask
+ task.wait(); // for explanation
+ } catch (InterruptedException ie) {
+ }
}
+ else
+ task.notifyAll();
}
- else
- task.notifyAll();
}
+ long c; // re-activate
+ do {} while (!U.compareAndSwapLong
+ (this, CTL, c = ctl, c + AC_UNIT));
}
- long c; // re-activate
- do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c + AC_UNIT));
}
+ if (s < 0 || (s = task.status) < 0) {
+ joiner.currentJoin = prevJoin;
+ break;
+ }
+ else if ((k++ & (MAX_HELP - 1)) == MAX_HELP >>> 1)
+ Thread.yield(); // for politeness
}
- if ((s = task.status) < 0) {
- joiner.currentJoin = prevJoin;
- return s;
- }
- else if ((k & (MAX_HELP - 1)) == MAX_HELP >>> 1)
- Thread.yield(); // for politeness
}
+ return s;
}
/**
@@ -1887,7 +1881,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
while ((s = task.status) >= 0 &&
(joiner.isEmpty() ?
tryHelpStealer(joiner, task) :
- joiner.tryRemoveAndExec(task)))
+ joiner.tryRemoveAndExec(task)) != 0)
;
return s;
}
@@ -1919,6 +1913,7 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
}
}
+
/**
* Runs tasks until {@code isQuiescent()}. We piggyback on
* active count ctl maintenance, but rather than blocking
@@ -1927,8 +1922,9 @@ public class ForkJoinPool /*extends AbstractExecutorService*/ {
*/
final void helpQuiescePool(WorkQueue w) {
for (boolean active = true;;) {
- if (w.base - w.top < 0)
- w.runLocalTasks(); // exhaust local queue
+ ForkJoinTask<?> localTask; // exhaust local queue
+ while ((localTask = w.nextLocalTask()) != null)
+ localTask.doExec();
WorkQueue q = findNonEmptyStealQueue(w);
if (q != null) {
ForkJoinTask<?> t; int b;
diff --git a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java
index 344f6887a6..2ba146c4da 100644
--- a/src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java
+++ b/src/forkjoin/scala/concurrent/forkjoin/ForkJoinTask.java
@@ -16,7 +16,7 @@ import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
-//import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.RunnableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantLock;
@@ -115,18 +115,19 @@ import java.lang.reflect.Constructor;
* <p>The ForkJoinTask class is not usually directly subclassed.
* Instead, you subclass one of the abstract classes that support a
* particular style of fork/join processing, typically {@link
- * RecursiveAction} for computations that do not return results, or
- * {@link RecursiveTask} for those that do. Normally, a concrete
- * ForkJoinTask subclass declares fields comprising its parameters,
- * established in a constructor, and then defines a {@code compute}
- * method that somehow uses the control methods supplied by this base
- * class. While these methods have {@code public} access (to allow
- * instances of different task subclasses to call each other's
- * methods), some of them may only be called from within other
- * ForkJoinTasks (as may be determined using method {@link
- * #inForkJoinPool}). Attempts to invoke them in other contexts
- * result in exceptions or errors, possibly including
- * {@code ClassCastException}.
+ * RecursiveAction} for most computations that do not return results,
+ * {@link RecursiveTask} for those that do, and {@link
+ * CountedCompleter} for those in which completed actions trigger
+ * other actions. Normally, a concrete ForkJoinTask subclass declares
+ * fields comprising its parameters, established in a constructor, and
+ * then defines a {@code compute} method that somehow uses the control
+ * methods supplied by this base class. While these methods have
+ * {@code public} access (to allow instances of different task
+ * subclasses to call each other's methods), some of them may only be
+ * called from within other ForkJoinTasks (as may be determined using
+ * method {@link #inForkJoinPool}). Attempts to invoke them in other
+ * contexts result in exceptions or errors, possibly including {@code
+ * ClassCastException}.
*
* <p>Method {@link #join} and its variants are appropriate for use
* only when completion dependencies are acyclic; that is, the
@@ -137,17 +138,17 @@ import java.lang.reflect.Constructor;
* {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that
* may be of use in constructing custom subclasses for problems that
* are not statically structured as DAGs. To support such usages a
- * ForkJoinTask may be atomically <em>marked</em> using {@link
- * #markForkJoinTask} and checked for marking using {@link
- * #isMarkedForkJoinTask}. The ForkJoinTask implementation does not
- * use these {@code protected} methods or marks for any purpose, but
+ * ForkJoinTask may be atomically <em>tagged</em> with a {@code
+ * short} value using {@link #setForkJoinTaskTag} or {@link
+ * #compareAndSetForkJoinTaskTag} and checked using {@link
+ * #getForkJoinTaskTag}. The ForkJoinTask implementation does not
+ * use these {@code protected} methods or tags for any purpose, but
* they may be of use in the construction of specialized subclasses.
* For example, parallel graph traversals can use the supplied methods
* to avoid revisiting nodes/tasks that have already been processed.
- * Also, completion based designs can use them to record that one
- * subtask has completed. (Method names for marking are bulky in part
- * to encourage definition of methods that reflect their usage
- * patterns.)
+ * Also, completion based designs can use them to record that subtasks
+ * have completed. (Method names for tagging are bulky in part to
+ * encourage definition of methods that reflect their usage patterns.)
*
* <p>Most base support methods are {@code final}, to prevent
* overriding of implementations that are intrinsically tied to the
@@ -213,6 +214,10 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
* thin-lock techniques, so use some odd coding idioms that tend
* to avoid them, mainly by arranging that every synchronized
* block performs a wait, notifyAll or both.
+ *
+ * These control bits occupy only (some of) the upper half (16
+ * bits) of status field. The lower bits are used for user-defined
+ * tags.
*/
/** The run status of this task */
@@ -221,13 +226,12 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
static final int NORMAL = 0xf0000000; // must be negative
static final int CANCELLED = 0xc0000000; // must be < NORMAL
static final int EXCEPTIONAL = 0x80000000; // must be < CANCELLED
- static final int SIGNAL = 0x00000001;
- static final int MARKED = 0x00000002;
+ static final int SIGNAL = 0x00010000; // must be >= 1 << 16
+ static final int SMASK = 0x0000ffff; // short bits for tags
/**
* Marks completion and wakes up threads waiting to join this
- * task. A specialization for NORMAL completion is in method
- * doExec.
+ * task.
*
* @param completion one of NORMAL, CANCELLED, EXCEPTIONAL
* @return completion status on exit
@@ -237,7 +241,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
if ((s = status) < 0)
return s;
if (U.compareAndSwapInt(this, STATUS, s, s | completion)) {
- if ((s & SIGNAL) != 0)
+ if ((s >>> 16) != 0)
synchronized (this) { notifyAll(); }
return completion;
}
@@ -259,26 +263,22 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
} catch (Throwable rex) {
return setExceptionalCompletion(rex);
}
- while ((s = status) >= 0 && completed) {
- if (U.compareAndSwapInt(this, STATUS, s, s | NORMAL)) {
- if ((s & SIGNAL) != 0)
- synchronized (this) { notifyAll(); }
- return NORMAL;
- }
- }
+ if (completed)
+ s = setCompletion(NORMAL);
}
return s;
}
/**
- * Tries to set SIGNAL status. Used by ForkJoinPool. Other
- * variants are directly incorporated into externalAwaitDone etc.
+ * Tries to set SIGNAL status unless already completed. Used by
+ * ForkJoinPool. Other variants are directly incorporated into
+ * externalAwaitDone etc.
*
* @return true if successful
*/
final boolean trySetSignal() {
- int s;
- return U.compareAndSwapInt(this, STATUS, s = status, s | SIGNAL);
+ int s = status;
+ return s >= 0 && U.compareAndSwapInt(this, STATUS, s, s | SIGNAL);
}
/**
@@ -328,7 +328,6 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
return s;
}
-
/**
* Implementation for join, get, quietlyJoin. Directly handles
* only cases of already-completed, external wait, and
@@ -417,25 +416,39 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
* @return status on exit
*/
private int setExceptionalCompletion(Throwable ex) {
- int h = System.identityHashCode(this);
- final ReentrantLock lock = exceptionTableLock;
- lock.lock();
- try {
- expungeStaleExceptions();
- ExceptionNode[] t = exceptionTable;
- int i = h & (t.length - 1);
- for (ExceptionNode e = t[i]; ; e = e.next) {
- if (e == null) {
- t[i] = new ExceptionNode(this, ex, t[i]);
- break;
+ int s;
+ if ((s = status) >= 0) {
+ int h = System.identityHashCode(this);
+ final ReentrantLock lock = exceptionTableLock;
+ lock.lock();
+ try {
+ expungeStaleExceptions();
+ ExceptionNode[] t = exceptionTable;
+ int i = h & (t.length - 1);
+ for (ExceptionNode e = t[i]; ; e = e.next) {
+ if (e == null) {
+ t[i] = new ExceptionNode(this, ex, t[i]);
+ break;
+ }
+ if (e.get() == this) // already present
+ break;
}
- if (e.get() == this) // already present
- break;
+ } finally {
+ lock.unlock();
}
- } finally {
- lock.unlock();
+ s = setCompletion(EXCEPTIONAL);
}
- return setCompletion(EXCEPTIONAL);
+ ForkJoinTask<?> p = internalGetCompleter(); // propagate
+ if (p != null && p.status >= 0)
+ p.setExceptionalCompletion(ex);
+ return s;
+ }
+
+ /**
+ * Exception propagation support for tasks with completers.
+ */
+ ForkJoinTask<?> internalGetCompleter() {
+ return null;
}
/**
@@ -517,7 +530,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
Throwable ex;
if (e == null || (ex = e.ex) == null)
return null;
- if (e.thrower != Thread.currentThread().getId()) {
+ if (false && e.thrower != Thread.currentThread().getId()) {
Class<? extends Throwable> ec = ex.getClass();
try {
Constructor<?> noArgCtor = null;
@@ -907,6 +920,18 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
}
/**
+ * Completes this task normally without setting a value. The most
+ * recent value established by {@link #setRawResult} (or {@code
+ * null} by default) will be returned as the result of subsequent
+ * invocations of {@code join} and related operations.
+ *
+ * @since 1.8
+ */
+ public final void quietlyComplete() {
+ setCompletion(NORMAL);
+ }
+
+ /**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*
@@ -1225,15 +1250,18 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
protected abstract void setRawResult(V value);
/**
- * Immediately performs the base action of this task. This method
- * is designed to support extensions, and should not in general be
- * called otherwise. The return value controls whether this task
- * is considered to be done normally. It may return false in
+ * Immediately performs the base action of this task and returns
+ * true if, upon return from this method, this task is guaranteed
+ * to have completed normally. This method may return false
+ * otherwise, to indicate that this task is not necessarily
+ * complete (or is not known to be complete), for example in
* asynchronous actions that require explicit invocations of
- * {@link #complete} to become joinable. It may also throw an
- * (unchecked) exception to indicate abnormal exit.
+ * completion methods. This method may also throw an (unchecked)
+ * exception to indicate abnormal exit. This method is designed to
+ * support extensions, and should not in general be called
+ * otherwise.
*
- * @return {@code true} if completed normally
+ * @return {@code true} if this task is known to have completed normally
*/
protected abstract boolean exec();
@@ -1302,44 +1330,53 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
return wt.pool.nextTaskFor(wt.workQueue);
}
- // Mark-bit operations
+ // tag operations
/**
- * Returns true if this task is marked.
+ * Returns the tag for this task.
*
- * @return true if this task is marked
+ * @return the tag for this task
* @since 1.8
*/
- public final boolean isMarkedForkJoinTask() {
- return (status & MARKED) != 0;
+ public final short getForkJoinTaskTag() {
+ return (short)status;
}
/**
- * Atomically sets the mark on this task.
+ * Atomically sets the tag value for this task.
*
- * @return true if this task was previously unmarked
+ * @param tag the tag value
+ * @return the previous value of the tag
* @since 1.8
*/
- public final boolean markForkJoinTask() {
+ public final short setForkJoinTaskTag(short tag) {
for (int s;;) {
- if (((s = status) & MARKED) != 0)
- return false;
- if (U.compareAndSwapInt(this, STATUS, s, s | MARKED))
- return true;
+ if (U.compareAndSwapInt(this, STATUS, s = status,
+ (s & ~SMASK) | (tag & SMASK)))
+ return (short)s;
}
}
/**
- * Atomically clears the mark on this task.
+ * Atomically conditionally sets the tag value for this task.
+ * Among other applications, tags can be used as visit markers
+ * in tasks operating on graphs, as in methods that check: {@code
+ * if (task.compareAndSetForkJoinTaskTag((short)0, (short)1))}
+ * before processing, otherwise exiting because the node has
+ * already been visited.
*
- * @return true if this task was previously marked
+ * @param e the expected tag value
+ * @param tag the new tag value
+ * @return true if successful; i.e., the current value was
+ * equal to e and is now tag.
* @since 1.8
*/
- public final boolean unmarkForkJoinTask() {
+ public final boolean compareAndSetForkJoinTaskTag(short e, short tag) {
for (int s;;) {
- if (((s = status) & MARKED) == 0)
+ if ((short)(s = status) != e)
return false;
- if (U.compareAndSwapInt(this, STATUS, s, s & ~MARKED))
+ if (U.compareAndSwapInt(this, STATUS, s,
+ (s & ~SMASK) | (tag & SMASK)))
return true;
}
}
diff --git a/src/intellij/dbc.iml.SAMPLE b/src/intellij/dbc.iml.SAMPLE
index 5a6df4cfaa..d2647cfb26 100644
--- a/src/intellij/dbc.iml.SAMPLE
+++ b/src/intellij/dbc.iml.SAMPLE
@@ -12,9 +12,6 @@
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
- <content url="file://$MODULE_DIR$/../dbc">
- <sourceFolder url="file://$MODULE_DIR$/../dbc" isTestSource="false" />
- </content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="library" />
diff --git a/src/intellij/scala-lang.ipr.SAMPLE b/src/intellij/scala-lang.ipr.SAMPLE
index 93b6285cfb..94a9329dd6 100644
--- a/src/intellij/scala-lang.ipr.SAMPLE
+++ b/src/intellij/scala-lang.ipr.SAMPLE
@@ -197,7 +197,6 @@
<modules>
<module fileurl="file://$PROJECT_DIR$/actors.iml" filepath="$PROJECT_DIR$/actors.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler.iml" filepath="$PROJECT_DIR$/compiler.iml" />
- <module fileurl="file://$PROJECT_DIR$/dbc.iml" filepath="$PROJECT_DIR$/dbc.iml" />
<module fileurl="file://$PROJECT_DIR$/library.iml" filepath="$PROJECT_DIR$/library.iml" />
<module fileurl="file://$PROJECT_DIR$/manual.iml" filepath="$PROJECT_DIR$/manual.iml" />
<module fileurl="file://$PROJECT_DIR$/partest.iml" filepath="$PROJECT_DIR$/partest.iml" />
diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala
index 99c54ce58c..fd61cfd0a1 100644
--- a/src/library/scala/Array.scala
+++ b/src/library/scala/Array.scala
@@ -12,17 +12,17 @@ import scala.collection.generic._
import scala.collection.{ mutable, immutable }
import mutable.{ ArrayBuilder, ArraySeq }
import compat.Platform.arraycopy
-import scala.reflect.ClassManifest
+import scala.reflect.ArrayTag
import scala.runtime.ScalaRunTime.{ array_apply, array_update }
/** Contains a fallback builder for arrays when the element type
- * does not have a class manifest. In that case a generic array is built.
+ * does not have a class tag. In that case a generic array is built.
*/
class FallbackArrayBuilding {
/** A builder factory that generates a generic array.
* Called instead of `Array.newBuilder` if the element type of an array
- * does not have a class manifest. Note that fallbackBuilder factory
+ * does not have a class tag. Note that fallbackBuilder factory
* needs an implicit parameter (otherwise it would not be dominated in
* implicit search by `Array.canBuildFrom`). We make sure that
* implicit search is always successful.
@@ -48,16 +48,16 @@ class FallbackArrayBuilding {
* @version 1.0
*/
object Array extends FallbackArrayBuilding {
- implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Array[_], T, Array[T]] =
+ implicit def canBuildFrom[T](implicit t: ArrayTag[T]): CanBuildFrom[Array[_], T, Array[T]] =
new CanBuildFrom[Array[_], T, Array[T]] {
- def apply(from: Array[_]) = ArrayBuilder.make[T]()(m)
- def apply() = ArrayBuilder.make[T]()(m)
+ def apply(from: Array[_]) = ArrayBuilder.make[T]()(t)
+ def apply() = ArrayBuilder.make[T]()(t)
}
/**
* Returns a new [[scala.collection.mutable.ArrayBuilder]].
*/
- def newBuilder[T](implicit m: ClassManifest[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(m)
+ def newBuilder[T](implicit t: ArrayTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(t)
private def slowcopy(src : AnyRef,
srcPos : Int,
@@ -98,14 +98,14 @@ object Array extends FallbackArrayBuilding {
}
/** Returns an array of length 0 */
- def empty[T: ClassManifest]: Array[T] = new Array[T](0)
+ def empty[T: ArrayTag]: Array[T] = new Array[T](0)
/** Creates an array with given elements.
*
* @param xs the elements to put in the array
* @return an array containing all elements from xs.
*/
- def apply[T: ClassManifest](xs: T*): Array[T] = {
+ def apply[T: ArrayTag](xs: T*): Array[T] = {
val array = new Array[T](xs.length)
var i = 0
for (x <- xs.iterator) { array(i) = x; i += 1 }
@@ -194,23 +194,23 @@ object Array extends FallbackArrayBuilding {
}
/** Creates array with given dimensions */
- def ofDim[T: ClassManifest](n1: Int): Array[T] =
+ def ofDim[T: ArrayTag](n1: Int): Array[T] =
new Array[T](n1)
/** Creates a 2-dimensional array */
- def ofDim[T: ClassManifest](n1: Int, n2: Int): Array[Array[T]] = {
+ def ofDim[T: ArrayTag](n1: Int, n2: Int): Array[Array[T]] = {
val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]])
for (i <- 0 until n1) arr(i) = new Array[T](n2)
arr
// tabulate(n1)(_ => ofDim[T](n2))
}
/** Creates a 3-dimensional array */
- def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] =
+ def ofDim[T: ArrayTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] =
tabulate(n1)(_ => ofDim[T](n2, n3))
/** Creates a 4-dimensional array */
- def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] =
+ def ofDim[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] =
tabulate(n1)(_ => ofDim[T](n2, n3, n4))
/** Creates a 5-dimensional array */
- def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] =
+ def ofDim[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] =
tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5))
/** Concatenates all arrays into a single array.
@@ -218,7 +218,7 @@ object Array extends FallbackArrayBuilding {
* @param xss the given arrays
* @return the array created from concatenating `xss`
*/
- def concat[T: ClassManifest](xss: Array[T]*): Array[T] = {
+ def concat[T: ArrayTag](xss: Array[T]*): Array[T] = {
val b = newBuilder[T]
b.sizeHint(xss.map(_.size).sum)
for (xs <- xss) b ++= xs
@@ -239,7 +239,7 @@ object Array extends FallbackArrayBuilding {
* @return an Array of size n, where each element contains the result of computing
* `elem`.
*/
- def fill[T: ClassManifest](n: Int)(elem: => T): Array[T] = {
+ def fill[T: ArrayTag](n: Int)(elem: => T): Array[T] = {
val b = newBuilder[T]
b.sizeHint(n)
var i = 0
@@ -257,7 +257,7 @@ object Array extends FallbackArrayBuilding {
* @param n2 the number of elements in the 2nd dimension
* @param elem the element computation
*/
- def fill[T: ClassManifest](n1: Int, n2: Int)(elem: => T): Array[Array[T]] =
+ def fill[T: ArrayTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] =
tabulate(n1)(_ => fill(n2)(elem))
/** Returns a three-dimensional array that contains the results of some element
@@ -268,7 +268,7 @@ object Array extends FallbackArrayBuilding {
* @param n3 the number of elements in the 3nd dimension
* @param elem the element computation
*/
- def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] =
+ def fill[T: ArrayTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] =
tabulate(n1)(_ => fill(n2, n3)(elem))
/** Returns a four-dimensional array that contains the results of some element
@@ -280,7 +280,7 @@ object Array extends FallbackArrayBuilding {
* @param n4 the number of elements in the 4th dimension
* @param elem the element computation
*/
- def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] =
+ def fill[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] =
tabulate(n1)(_ => fill(n2, n3, n4)(elem))
/** Returns a five-dimensional array that contains the results of some element
@@ -293,7 +293,7 @@ object Array extends FallbackArrayBuilding {
* @param n5 the number of elements in the 5th dimension
* @param elem the element computation
*/
- def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] =
+ def fill[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] =
tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem))
/** Returns an array containing values of a given function over a range of integer
@@ -303,7 +303,7 @@ object Array extends FallbackArrayBuilding {
* @param f The function computing element values
* @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)`
*/
- def tabulate[T: ClassManifest](n: Int)(f: Int => T): Array[T] = {
+ def tabulate[T: ArrayTag](n: Int)(f: Int => T): Array[T] = {
val b = newBuilder[T]
b.sizeHint(n)
var i = 0
@@ -321,7 +321,7 @@ object Array extends FallbackArrayBuilding {
* @param n2 the number of elements in the 2nd dimension
* @param f The function computing element values
*/
- def tabulate[T: ClassManifest](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] =
+ def tabulate[T: ArrayTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] =
tabulate(n1)(i1 => tabulate(n2)(f(i1, _)))
/** Returns a three-dimensional array containing values of a given function
@@ -332,7 +332,7 @@ object Array extends FallbackArrayBuilding {
* @param n3 the number of elements in the 3rd dimension
* @param f The function computing element values
*/
- def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] =
+ def tabulate[T: ArrayTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] =
tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _)))
/** Returns a four-dimensional array containing values of a given function
@@ -344,7 +344,7 @@ object Array extends FallbackArrayBuilding {
* @param n4 the number of elements in the 4th dimension
* @param f The function computing element values
*/
- def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] =
+ def tabulate[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] =
tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _)))
/** Returns a five-dimensional array containing values of a given function
@@ -357,7 +357,7 @@ object Array extends FallbackArrayBuilding {
* @param n5 the number of elements in the 5th dimension
* @param f The function computing element values
*/
- def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] =
+ def tabulate[T: ArrayTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] =
tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _)))
/** Returns an array containing a sequence of increasing integers in a range.
@@ -396,7 +396,7 @@ object Array extends FallbackArrayBuilding {
* @param f the function that is repeatedly applied
* @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...`
*/
- def iterate[T: ClassManifest](start: T, len: Int)(f: T => T): Array[T] = {
+ def iterate[T: ArrayTag](start: T, len: Int)(f: T => T): Array[T] = {
val b = newBuilder[T]
if (len > 0) {
@@ -467,6 +467,19 @@ object Array extends FallbackArrayBuilding {
* @version 1.0
* @see [[http://www.scala-lang.org/docu/files/collections-api/collections_38.html#anchor "The Scala 2.8 Collections' API"]]
* section on `Array` by Martin Odersky for more information.
+ * @define coll array
+ * @define Coll Array
+ * @define orderDependent
+ * @define orderDependentFold
+ * @define mayNotTerminateInf
+ * @define willNotTerminateInf
+ * @define collectExample
+ * @define undefinedorder
+ * @define thatinfo the class of the returned collection. In the standard library configuration,
+ * `That` is either `Array[B]` if an ArrayTag is available for B or `ArraySeq[B]` otherwise.
+ * @define zipthatinfo $thatinfo
+ * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current
+ * representation type `Repr` and the new element type `B`.
*/
final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable {
diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala
index 5078e59d28..edb82b33fe 100644
--- a/src/library/scala/Boolean.scala
+++ b/src/library/scala/Boolean.scala
@@ -17,7 +17,7 @@ package scala
* There is an implicit conversion from [[scala.Boolean]] => [[scala.runtime.RichBoolean]]
* which provides useful non-primitive operations.
*/
-final class Boolean extends AnyVal {
+final class Boolean private extends AnyVal {
/**
* Negates a Boolean expression.
*
@@ -110,7 +110,7 @@ final class Boolean extends AnyVal {
override def getClass(): Class[Boolean] = sys.error("stub")
}
-object Boolean extends AnyValCompanion {
+object Boolean extends AnyValCompanion {
/** Transform a value type into a boxed reference type.
*
diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala
index f9c5f6003e..b5b3d88e3f 100644
--- a/src/library/scala/Byte.scala
+++ b/src/library/scala/Byte.scala
@@ -17,7 +17,7 @@ package scala
* There is an implicit conversion from [[scala.Byte]] => [[scala.runtime.RichByte]]
* which provides useful non-primitive operations.
*/
-final class Byte extends AnyVal {
+final class Byte private extends AnyVal {
def toByte: Byte = sys.error("stub")
def toShort: Short = sys.error("stub")
def toChar: Char = sys.error("stub")
@@ -27,7 +27,7 @@ final class Byte extends AnyVal {
def toDouble: Double = sys.error("stub")
/**
- * @return the bitwise negation of this value
+ * Returns the bitwise negation of this value.
* @example {{{
* ~5 == -6
* // in binary: ~00000101 ==
@@ -36,30 +36,30 @@ final class Byte extends AnyVal {
*/
def unary_~ : Int = sys.error("stub")
/**
- * @return this value, unmodified
+ * Returns this value, unmodified.
*/
def unary_+ : Int = sys.error("stub")
/**
- * @return the negation of this value
+ * Returns the negation of this value.
*/
def unary_- : Int = sys.error("stub")
def +(x: String): String = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Long): Int = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -70,7 +70,7 @@ final class Byte extends AnyVal {
*/
def >>>(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -81,7 +81,7 @@ final class Byte extends AnyVal {
*/
def >>>(x: Long): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -92,7 +92,7 @@ final class Byte extends AnyVal {
*/
def >>(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -104,181 +104,181 @@ final class Byte extends AnyVal {
def >>(x: Long): Int = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Double): Boolean = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -289,7 +289,7 @@ final class Byte extends AnyVal {
*/
def |(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -300,7 +300,7 @@ final class Byte extends AnyVal {
*/
def |(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -311,7 +311,7 @@ final class Byte extends AnyVal {
*/
def |(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -322,7 +322,7 @@ final class Byte extends AnyVal {
*/
def |(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -334,7 +334,7 @@ final class Byte extends AnyVal {
def |(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -345,7 +345,7 @@ final class Byte extends AnyVal {
*/
def &(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -356,7 +356,7 @@ final class Byte extends AnyVal {
*/
def &(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -367,7 +367,7 @@ final class Byte extends AnyVal {
*/
def &(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -378,7 +378,7 @@ final class Byte extends AnyVal {
*/
def &(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -390,7 +390,7 @@ final class Byte extends AnyVal {
def &(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -401,7 +401,7 @@ final class Byte extends AnyVal {
*/
def ^(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -412,7 +412,7 @@ final class Byte extends AnyVal {
*/
def ^(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -423,7 +423,7 @@ final class Byte extends AnyVal {
*/
def ^(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -434,7 +434,7 @@ final class Byte extends AnyVal {
*/
def ^(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -446,154 +446,154 @@ final class Byte extends AnyVal {
def ^(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Byte): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Short): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Char): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Int): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Float): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Double): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Byte): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Short): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Char): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Int): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Long): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Float): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Double): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Byte): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Short): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Char): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Int): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Long): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Float): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Double): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Byte): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Short): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Char): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Int): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Long): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Float): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Double): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Byte): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Short): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Char): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Int): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Long): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Float): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Double): Double = sys.error("stub")
override def getClass(): Class[Byte] = sys.error("stub")
}
-object Byte extends AnyValCompanion {
+object Byte extends AnyValCompanion {
/** The smallest value representable as a Byte.
*/
final val MinValue = java.lang.Byte.MIN_VALUE
@@ -622,5 +622,10 @@ object Byte extends AnyValCompanion {
/** The String representation of the scala.Byte companion object.
*/
override def toString = "object scala.Byte"
+ implicit def byte2short(x: Byte): Short = x.toShort
+ implicit def byte2int(x: Byte): Int = x.toInt
+ implicit def byte2long(x: Byte): Long = x.toLong
+ implicit def byte2float(x: Byte): Float = x.toFloat
+ implicit def byte2double(x: Byte): Double = x.toDouble
}
diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala
index 3d459782cd..e0ac9a2550 100644
--- a/src/library/scala/Char.scala
+++ b/src/library/scala/Char.scala
@@ -17,7 +17,7 @@ package scala
* There is an implicit conversion from [[scala.Char]] => [[scala.runtime.RichChar]]
* which provides useful non-primitive operations.
*/
-final class Char extends AnyVal {
+final class Char private extends AnyVal {
def toByte: Byte = sys.error("stub")
def toShort: Short = sys.error("stub")
def toChar: Char = sys.error("stub")
@@ -27,7 +27,7 @@ final class Char extends AnyVal {
def toDouble: Double = sys.error("stub")
/**
- * @return the bitwise negation of this value
+ * Returns the bitwise negation of this value.
* @example {{{
* ~5 == -6
* // in binary: ~00000101 ==
@@ -36,30 +36,30 @@ final class Char extends AnyVal {
*/
def unary_~ : Int = sys.error("stub")
/**
- * @return this value, unmodified
+ * Returns this value, unmodified.
*/
def unary_+ : Int = sys.error("stub")
/**
- * @return the negation of this value
+ * Returns the negation of this value.
*/
def unary_- : Int = sys.error("stub")
def +(x: String): String = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Long): Int = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -70,7 +70,7 @@ final class Char extends AnyVal {
*/
def >>>(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -81,7 +81,7 @@ final class Char extends AnyVal {
*/
def >>>(x: Long): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -92,7 +92,7 @@ final class Char extends AnyVal {
*/
def >>(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -104,181 +104,181 @@ final class Char extends AnyVal {
def >>(x: Long): Int = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Double): Boolean = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -289,7 +289,7 @@ final class Char extends AnyVal {
*/
def |(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -300,7 +300,7 @@ final class Char extends AnyVal {
*/
def |(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -311,7 +311,7 @@ final class Char extends AnyVal {
*/
def |(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -322,7 +322,7 @@ final class Char extends AnyVal {
*/
def |(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -334,7 +334,7 @@ final class Char extends AnyVal {
def |(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -345,7 +345,7 @@ final class Char extends AnyVal {
*/
def &(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -356,7 +356,7 @@ final class Char extends AnyVal {
*/
def &(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -367,7 +367,7 @@ final class Char extends AnyVal {
*/
def &(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -378,7 +378,7 @@ final class Char extends AnyVal {
*/
def &(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -390,7 +390,7 @@ final class Char extends AnyVal {
def &(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -401,7 +401,7 @@ final class Char extends AnyVal {
*/
def ^(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -412,7 +412,7 @@ final class Char extends AnyVal {
*/
def ^(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -423,7 +423,7 @@ final class Char extends AnyVal {
*/
def ^(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -434,7 +434,7 @@ final class Char extends AnyVal {
*/
def ^(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -446,154 +446,154 @@ final class Char extends AnyVal {
def ^(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Byte): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Short): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Char): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Int): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Float): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Double): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Byte): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Short): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Char): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Int): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Long): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Float): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Double): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Byte): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Short): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Char): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Int): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Long): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Float): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Double): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Byte): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Short): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Char): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Int): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Long): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Float): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Double): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Byte): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Short): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Char): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Int): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Long): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Float): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Double): Double = sys.error("stub")
override def getClass(): Class[Char] = sys.error("stub")
}
-object Char extends AnyValCompanion {
+object Char extends AnyValCompanion {
/** The smallest value representable as a Char.
*/
final val MinValue = java.lang.Character.MIN_VALUE
@@ -622,5 +622,9 @@ object Char extends AnyValCompanion {
/** The String representation of the scala.Char companion object.
*/
override def toString = "object scala.Char"
+ implicit def char2int(x: Char): Int = x.toInt
+ implicit def char2long(x: Char): Long = x.toLong
+ implicit def char2float(x: Char): Float = x.toFloat
+ implicit def char2double(x: Char): Double = x.toDouble
}
diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala
index 01414265c4..bb659b963a 100644
--- a/src/library/scala/Double.scala
+++ b/src/library/scala/Double.scala
@@ -17,7 +17,7 @@ package scala
* There is an implicit conversion from [[scala.Double]] => [[scala.runtime.RichDouble]]
* which provides useful non-primitive operations.
*/
-final class Double extends AnyVal {
+final class Double private extends AnyVal {
def toByte: Byte = sys.error("stub")
def toShort: Short = sys.error("stub")
def toChar: Char = sys.error("stub")
@@ -27,339 +27,339 @@ final class Double extends AnyVal {
def toDouble: Double = sys.error("stub")
/**
- * @return this value, unmodified
+ * Returns this value, unmodified.
*/
def unary_+ : Double = sys.error("stub")
/**
- * @return the negation of this value
+ * Returns the negation of this value.
*/
def unary_- : Double = sys.error("stub")
def +(x: String): String = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Double): Boolean = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Byte): Double = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Short): Double = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Char): Double = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Int): Double = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Long): Double = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Float): Double = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Double): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Byte): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Short): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Char): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Int): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Long): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Float): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Double): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Byte): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Short): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Char): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Int): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Long): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Float): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Double): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Byte): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Short): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Char): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Int): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Long): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Float): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Double): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Byte): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Short): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Char): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Int): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Long): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Float): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Double): Double = sys.error("stub")
override def getClass(): Class[Double] = sys.error("stub")
}
-object Double extends AnyValCompanion {
+object Double extends AnyValCompanion {
/** The smallest positive value greater than 0.0d which is
* representable as a Double.
*/
diff --git a/src/library/scala/Dynamic.scala b/src/library/scala/Dynamic.scala
index 32b57ee88f..dcf7599742 100644
--- a/src/library/scala/Dynamic.scala
+++ b/src/library/scala/Dynamic.scala
@@ -11,7 +11,7 @@ package scala
/** A marker trait that enables dynamic invocations. Instances `x` of this
* trait allow calls `x.meth(args)` for arbitrary method names `meth` and
* argument lists `args`. If a call is not natively supported by `x`, it
- * is rewritten to `x.applyDynamic("meth", args)`.
+ * is rewritten to `x.applyDynamic("meth")(args)`.
*
* As of scala 2.9, `scalac` must receive the `-Xexperimental` option for
* `Dynamic` to receive this treatment.
diff --git a/src/library/scala/Either.scala b/src/library/scala/Either.scala
index e454cdf5ec..20451600a9 100644
--- a/src/library/scala/Either.scala
+++ b/src/library/scala/Either.scala
@@ -10,6 +10,8 @@
package scala
+import language.implicitConversions
+
/** Represents a value of one of two possible types (a disjoint union.)
* Instances of Either are either an instance of [[scala.Left]] or [[scala.Right]].
*
@@ -201,12 +203,6 @@ final case class Right[+A, +B](b: B) extends Either[A, B] {
}
object Either {
- class MergeableEither[A](x: Either[A, A]) {
- def merge: A = x match {
- case Left(a) => a
- case Right(a) => a
- }
- }
/**
* Allows use of a ``merge`` method to extract values from Either instances
@@ -219,7 +215,14 @@ object Either {
* r.merge: Seq[Int] // Vector(1)
* }}}
*/
- implicit def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x)
+ implicit class MergeableEither[A](x: Either[A, A]) {
+ def merge: A = x match {
+ case Left(a) => a
+ case Right(a) => a
+ }
+ }
+ @deprecated("use MergeableEither instead", "2.10")
+ def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x)
/**
* Projects an `Either` into a `Left`.
@@ -258,7 +261,7 @@ object Either {
* case ex => Left(ex)
* }
*
- * // this will only be executed if interactWithDB returns a Some
+ * // this will only be executed if interactWithDB returns a Right
* val report =
* for (r <- interactWithDB(someQuery).right) yield generateReport(r)
* if (report.isRight)
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala
index 80571943e5..ea0d20957d 100644
--- a/src/library/scala/Enumeration.scala
+++ b/src/library/scala/Enumeration.scala
@@ -70,10 +70,9 @@ abstract class Enumeration (initial: Int) extends Serializable {
/** The name of this enumeration.
*/
- override def toString = (
- (getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.' last)
- split Pattern.quote(NAME_JOIN_STRING) last
- )
+ override def toString =
+ ((getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.').last split
+ Pattern.quote(NAME_JOIN_STRING)).last
/** The mapping from the integer used to identify values to the actual
* values. */
@@ -81,7 +80,7 @@ abstract class Enumeration (initial: Int) extends Serializable {
/** The cache listing all values of this enumeration. */
@transient private var vset: ValueSet = null
- @transient private var vsetDefined = false
+ @transient @volatile private var vsetDefined = false
/** The mapping from the integer used to identify values to their
* names. */
diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala
index ff5b3cb112..bb03581062 100644
--- a/src/library/scala/Float.scala
+++ b/src/library/scala/Float.scala
@@ -17,7 +17,7 @@ package scala
* There is an implicit conversion from [[scala.Float]] => [[scala.runtime.RichFloat]]
* which provides useful non-primitive operations.
*/
-final class Float extends AnyVal {
+final class Float private extends AnyVal {
def toByte: Byte = sys.error("stub")
def toShort: Short = sys.error("stub")
def toChar: Char = sys.error("stub")
@@ -27,339 +27,339 @@ final class Float extends AnyVal {
def toDouble: Double = sys.error("stub")
/**
- * @return this value, unmodified
+ * Returns this value, unmodified.
*/
def unary_+ : Float = sys.error("stub")
/**
- * @return the negation of this value
+ * Returns the negation of this value.
*/
def unary_- : Float = sys.error("stub")
def +(x: String): String = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Double): Boolean = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Byte): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Short): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Char): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Int): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Long): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Float): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Double): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Byte): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Short): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Char): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Int): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Long): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Float): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Double): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Byte): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Short): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Char): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Int): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Long): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Float): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Double): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Byte): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Short): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Char): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Int): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Long): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Float): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Double): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Byte): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Short): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Char): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Int): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Long): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Float): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Double): Double = sys.error("stub")
override def getClass(): Class[Float] = sys.error("stub")
}
-object Float extends AnyValCompanion {
+object Float extends AnyValCompanion {
/** The smallest positive value greater than 0.0f which is
* representable as a Float.
*/
@@ -401,5 +401,6 @@ object Float extends AnyValCompanion {
/** The String representation of the scala.Float companion object.
*/
override def toString = "object scala.Float"
+ implicit def float2double(x: Float): Double = x.toDouble
}
diff --git a/src/library/scala/Function.scala b/src/library/scala/Function.scala
index 4a10b65735..9fa56a332f 100644
--- a/src/library/scala/Function.scala
+++ b/src/library/scala/Function.scala
@@ -29,6 +29,7 @@ object Function {
/** Turns a function `A => Option[B]` into a `PartialFunction[A, B]`.
*
+ * TODO: check if the paragraph below is still correct
* '''Important note''': this transformation implies the original function
* will be called 2 or more times on each logical invocation, because the
* only way to supply an implementation of `isDefinedAt` is to call the
@@ -39,11 +40,7 @@ object Function {
* f returns `Some(_)` and undefined where `f` returns `None`.
* @see [[scala.PartialFunction#lift]]
*/
- def unlift[T, R](f: T => Option[R]): PartialFunction[T, R] = new runtime.AbstractPartialFunction[T, R] {
- def apply(x: T): R = f(x).get
- def _isDefinedAt(x: T): Boolean = f(x).isDefined
- override def lift: T => Option[R] = f
- }
+ def unlift[T, R](f: T => Option[R]): PartialFunction[T, R] = PartialFunction.unlifted(f)
/** Uncurrying for functions of arity 2. This transforms a unary function
* returning another unary function into a function of arity 2.
diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala
index dceed26439..cc17f8797a 100644
--- a/src/library/scala/Function0.scala
+++ b/src/library/scala/Function0.scala
@@ -6,7 +6,7 @@
** |/ **
\* */
// GENERATED CODE: DO NOT EDIT.
-// genprod generated these sources at: Tue Feb 14 16:49:03 PST 2012
+// genprod generated these sources at: Tue Apr 24 16:32:13 PDT 2012
package scala
diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala
index 8995ef912b..a4391c1509 100644
--- a/src/library/scala/Function1.scala
+++ b/src/library/scala/Function1.scala
@@ -38,21 +38,5 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, s
*/
def apply(v1: T1): R
- /** Composes two instances of Function1 in a new Function1, with this function applied last.
- *
- * @tparam A the type to which function `g` can be applied
- * @param g a function A => T1
- * @return a new function `f` such that `f(x) == apply(g(x))`
- */
- def compose[A](g: A => T1): A => R = { x => apply(g(x)) }
-
- /** Composes two instances of Function1 in a new Function1, with this function applied first.
- *
- * @tparam A the result type of function `g`
- * @param g a function R => A
- * @return a new function `f` such that `f(x) == g(apply(x))`
- */
- def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) }
-
override def toString() = "<function1>"
}
diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala
index cacb96ef5d..5ea2b411bb 100644
--- a/src/library/scala/Function2.scala
+++ b/src/library/scala/Function2.scala
@@ -37,20 +37,6 @@ trait Function2[@specialized(scala.Int, scala.Long, scala.Double) -T1, @speciali
* @return the result of function application.
*/
def apply(v1: T1, v2: T2): R
- /** Creates a curried version of this function.
- *
- * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)`
- */ def curried: T1 => T2 => R = {
- (x1: T1) => (x2: T2) => apply(x1, x2)
- }
- /** Creates a tupled version of this function: instead of 2 arguments,
- * it accepts a single [[scala.Tuple2]] argument.
- *
- * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)`
- */
- def tupled: Tuple2[T1, T2] => R = {
- case Tuple2(x1, x2) => apply(x1, x2)
- }
override def toString() = "<function2>"
}
diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala
index 316bbced2d..d5d7ef011d 100644
--- a/src/library/scala/Int.scala
+++ b/src/library/scala/Int.scala
@@ -17,7 +17,7 @@ package scala
* There is an implicit conversion from [[scala.Int]] => [[scala.runtime.RichInt]]
* which provides useful non-primitive operations.
*/
-final class Int extends AnyVal {
+final class Int private extends AnyVal {
def toByte: Byte = sys.error("stub")
def toShort: Short = sys.error("stub")
def toChar: Char = sys.error("stub")
@@ -27,7 +27,7 @@ final class Int extends AnyVal {
def toDouble: Double = sys.error("stub")
/**
- * @return the bitwise negation of this value
+ * Returns the bitwise negation of this value.
* @example {{{
* ~5 == -6
* // in binary: ~00000101 ==
@@ -36,30 +36,30 @@ final class Int extends AnyVal {
*/
def unary_~ : Int = sys.error("stub")
/**
- * @return this value, unmodified
+ * Returns this value, unmodified.
*/
def unary_+ : Int = sys.error("stub")
/**
- * @return the negation of this value
+ * Returns the negation of this value.
*/
def unary_- : Int = sys.error("stub")
def +(x: String): String = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Long): Int = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -70,7 +70,7 @@ final class Int extends AnyVal {
*/
def >>>(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -81,7 +81,7 @@ final class Int extends AnyVal {
*/
def >>>(x: Long): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -92,7 +92,7 @@ final class Int extends AnyVal {
*/
def >>(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -104,181 +104,181 @@ final class Int extends AnyVal {
def >>(x: Long): Int = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Double): Boolean = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -289,7 +289,7 @@ final class Int extends AnyVal {
*/
def |(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -300,7 +300,7 @@ final class Int extends AnyVal {
*/
def |(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -311,7 +311,7 @@ final class Int extends AnyVal {
*/
def |(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -322,7 +322,7 @@ final class Int extends AnyVal {
*/
def |(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -334,7 +334,7 @@ final class Int extends AnyVal {
def |(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -345,7 +345,7 @@ final class Int extends AnyVal {
*/
def &(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -356,7 +356,7 @@ final class Int extends AnyVal {
*/
def &(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -367,7 +367,7 @@ final class Int extends AnyVal {
*/
def &(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -378,7 +378,7 @@ final class Int extends AnyVal {
*/
def &(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -390,7 +390,7 @@ final class Int extends AnyVal {
def &(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -401,7 +401,7 @@ final class Int extends AnyVal {
*/
def ^(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -412,7 +412,7 @@ final class Int extends AnyVal {
*/
def ^(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -423,7 +423,7 @@ final class Int extends AnyVal {
*/
def ^(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -434,7 +434,7 @@ final class Int extends AnyVal {
*/
def ^(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -446,154 +446,154 @@ final class Int extends AnyVal {
def ^(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Byte): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Short): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Char): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Int): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Float): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Double): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Byte): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Short): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Char): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Int): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Long): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Float): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Double): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Byte): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Short): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Char): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Int): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Long): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Float): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Double): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Byte): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Short): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Char): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Int): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Long): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Float): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Double): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Byte): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Short): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Char): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Int): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Long): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Float): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Double): Double = sys.error("stub")
override def getClass(): Class[Int] = sys.error("stub")
}
-object Int extends AnyValCompanion {
+object Int extends AnyValCompanion {
/** The smallest value representable as a Int.
*/
final val MinValue = java.lang.Integer.MIN_VALUE
@@ -622,5 +622,8 @@ object Int extends AnyValCompanion {
/** The String representation of the scala.Int companion object.
*/
override def toString = "object scala.Int"
+ implicit def int2long(x: Int): Long = x.toLong
+ implicit def int2float(x: Int): Float = x.toFloat
+ implicit def int2double(x: Int): Double = x.toDouble
}
diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala
index ce8618c22a..85131b4f54 100644
--- a/src/library/scala/Long.scala
+++ b/src/library/scala/Long.scala
@@ -17,7 +17,7 @@ package scala
* There is an implicit conversion from [[scala.Long]] => [[scala.runtime.RichLong]]
* which provides useful non-primitive operations.
*/
-final class Long extends AnyVal {
+final class Long private extends AnyVal {
def toByte: Byte = sys.error("stub")
def toShort: Short = sys.error("stub")
def toChar: Char = sys.error("stub")
@@ -27,7 +27,7 @@ final class Long extends AnyVal {
def toDouble: Double = sys.error("stub")
/**
- * @return the bitwise negation of this value
+ * Returns the bitwise negation of this value.
* @example {{{
* ~5 == -6
* // in binary: ~00000101 ==
@@ -36,30 +36,30 @@ final class Long extends AnyVal {
*/
def unary_~ : Long = sys.error("stub")
/**
- * @return this value, unmodified
+ * Returns this value, unmodified.
*/
def unary_+ : Long = sys.error("stub")
/**
- * @return the negation of this value
+ * Returns the negation of this value.
*/
def unary_- : Long = sys.error("stub")
def +(x: String): String = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Int): Long = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Long): Long = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -70,7 +70,7 @@ final class Long extends AnyVal {
*/
def >>>(x: Int): Long = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -81,7 +81,7 @@ final class Long extends AnyVal {
*/
def >>>(x: Long): Long = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -92,7 +92,7 @@ final class Long extends AnyVal {
*/
def >>(x: Int): Long = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -104,181 +104,181 @@ final class Long extends AnyVal {
def >>(x: Long): Long = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Double): Boolean = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -289,7 +289,7 @@ final class Long extends AnyVal {
*/
def |(x: Byte): Long = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -300,7 +300,7 @@ final class Long extends AnyVal {
*/
def |(x: Short): Long = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -311,7 +311,7 @@ final class Long extends AnyVal {
*/
def |(x: Char): Long = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -322,7 +322,7 @@ final class Long extends AnyVal {
*/
def |(x: Int): Long = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -334,7 +334,7 @@ final class Long extends AnyVal {
def |(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -345,7 +345,7 @@ final class Long extends AnyVal {
*/
def &(x: Byte): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -356,7 +356,7 @@ final class Long extends AnyVal {
*/
def &(x: Short): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -367,7 +367,7 @@ final class Long extends AnyVal {
*/
def &(x: Char): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -378,7 +378,7 @@ final class Long extends AnyVal {
*/
def &(x: Int): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -390,7 +390,7 @@ final class Long extends AnyVal {
def &(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -401,7 +401,7 @@ final class Long extends AnyVal {
*/
def ^(x: Byte): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -412,7 +412,7 @@ final class Long extends AnyVal {
*/
def ^(x: Short): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -423,7 +423,7 @@ final class Long extends AnyVal {
*/
def ^(x: Char): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -434,7 +434,7 @@ final class Long extends AnyVal {
*/
def ^(x: Int): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -446,154 +446,154 @@ final class Long extends AnyVal {
def ^(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Byte): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Short): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Char): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Int): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Float): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Double): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Byte): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Short): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Char): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Int): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Long): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Float): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Double): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Byte): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Short): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Char): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Int): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Long): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Float): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Double): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Byte): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Short): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Char): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Int): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Long): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Float): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Double): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Byte): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Short): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Char): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Int): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Long): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Float): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Double): Double = sys.error("stub")
override def getClass(): Class[Long] = sys.error("stub")
}
-object Long extends AnyValCompanion {
+object Long extends AnyValCompanion {
/** The smallest value representable as a Long.
*/
final val MinValue = java.lang.Long.MIN_VALUE
@@ -622,5 +622,7 @@ object Long extends AnyValCompanion {
/** The String representation of the scala.Long companion object.
*/
override def toString = "object scala.Long"
+ implicit def long2float(x: Long): Float = x.toFloat
+ implicit def long2double(x: Long): Double = x.toDouble
}
diff --git a/src/library/scala/LowPriorityImplicits.scala b/src/library/scala/LowPriorityImplicits.scala
index 447a3c3819..491cd417a3 100644
--- a/src/library/scala/LowPriorityImplicits.scala
+++ b/src/library/scala/LowPriorityImplicits.scala
@@ -12,6 +12,7 @@ import scala.collection.{ mutable, immutable, generic }
import mutable.WrappedArray
import immutable.WrappedString
import generic.CanBuildFrom
+import language.implicitConversions
/** The `LowPriorityImplicits` class provides implicit values that
* are valid in all Scala compilation units without explicit qualification,
diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala
index 6db4904b93..a58297d7d4 100644
--- a/src/library/scala/Option.scala
+++ b/src/library/scala/Option.scala
@@ -9,6 +9,9 @@
package scala
object Option {
+
+ import language.implicitConversions
+
/** An implicit conversion that converts an option to an iterable value
*/
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList
@@ -79,6 +82,17 @@ object Option {
* @define option [[scala.Option]]
* @define p `p`
* @define f `f`
+ * @define coll option
+ * @define Coll Option
+ * @define orderDependent
+ * @define orderDependentFold
+ * @define mayNotTerminateInf
+ * @define willNotTerminateInf
+ * @define collectExample
+ * @define undefinedorder
+ * @define thatinfo the class of the returned collection. In the standard library configuration, `That` is `Iterable[B]`
+ * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current
+ * representation type `Repr` and the new element type `B`.
*/
sealed abstract class Option[+A] extends Product with Serializable {
self =>
@@ -130,6 +144,18 @@ sealed abstract class Option[+A] extends Product with Serializable {
@inline final def map[B](f: A => B): Option[B] =
if (isEmpty) None else Some(f(this.get))
+ /** Returns the result of applying $f to this $option's
+ * value if the $option is nonempty. Otherwise, evaluates
+ * expression $ifEmpty.
+ *
+ * @note This is equivalent to `$option map f getOrElse ifEmpty`.
+ *
+ * @param ifEmpty the expression to evaluate if empty.
+ * @param f the function to apply if nonempty.
+ */
+ @inline final def fold[B](ifEmpty: => B)(f: A => B): B =
+ if (isEmpty) ifEmpty else f(this.get)
+
/** Returns the result of applying $f to this $option's value if
* this $option is nonempty.
* Returns $none if this $option is empty.
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index 3c5d6d0d23..fafaef9c2f 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -8,6 +8,7 @@
package scala
+
/** A partial function of type `PartialFunction[A, B]` is a unary function
* where the domain does not necessarily include all values of type `A`.
* The function `isDefinedAt` allows to test dynamically if a value is in
@@ -43,10 +44,11 @@ package scala
* }}}
*
*
- * @author Martin Odersky
+ * @author Martin Odersky, Pavel Pavlov, Adriaan Moors
* @version 1.0, 16/07/2003
*/
-trait PartialFunction[-A, +B] extends (A => B) {
+trait PartialFunction[-A, +B] extends (A => B) { self =>
+ import PartialFunction._
/** Checks if a value is contained in the function's domain.
*
@@ -55,10 +57,6 @@ trait PartialFunction[-A, +B] extends (A => B) {
*/
def isDefinedAt(x: A): Boolean
- //protected def missingCase[A1 <: A, B1 >: B]: PartialFunction[A1, B1] = PartialFunction.empty
-
- protected def missingCase(x: A): B = throw new MatchError(x)
-
/** Composes this partial function with a fallback partial function which
* gets applied where this partial function is not defined.
*
@@ -70,16 +68,8 @@ trait PartialFunction[-A, +B] extends (A => B) {
* takes `x` to `this(x)` where `this` is defined, and to `that(x)` where it is not.
*/
def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] =
- new runtime.AbstractPartialFunction[A1, B1] {
- def _isDefinedAt(x: A1): Boolean =
- PartialFunction.this.isDefinedAt(x) || that.isDefinedAt(x)
- def apply(x: A1): B1 =
- if (PartialFunction.this.isDefinedAt(x)) PartialFunction.this.apply(x)
- else that.apply(x)
- }
-
- def orElseFast[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] =
- orElse(that)
+ new OrElse[A1, B1] (this, that)
+ //TODO: why not overload it with orElse(that: F1): F1?
/** Composes this partial function with a transformation function that
* gets applied to results of this partial function.
@@ -88,9 +78,9 @@ trait PartialFunction[-A, +B] extends (A => B) {
* @return a partial function with the same domain as this partial function, which maps
* arguments `x` to `k(this(x))`.
*/
- override def andThen[C](k: B => C) : PartialFunction[A, C] = new runtime.AbstractPartialFunction[A, C] {
- def _isDefinedAt(x: A): Boolean = PartialFunction.this.isDefinedAt(x)
- def apply(x: A): C = k(PartialFunction.this.apply(x))
+ def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] {
+ def isDefinedAt(x: A): Boolean = self isDefinedAt x
+ def apply(x: A): C = k(self(x))
}
/** Turns this partial function into an plain function returning an `Option` result.
@@ -98,9 +88,30 @@ trait PartialFunction[-A, +B] extends (A => B) {
* @return a function that takes an argument `x` to `Some(this(x))` if `this`
* is defined for `x`, and to `None` otherwise.
*/
- def lift: A => Option[B] = new (A => Option[B]) {
- def apply(x: A): Option[B] = if (isDefinedAt(x)) Some(PartialFunction.this.apply(x)) else None
- }
+ def lift: A => Option[B] = new Lifted(this)
+
+ /**
+ * TODO: comment
+ * @since 2.10
+ */
+ def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 =
+ if (isDefinedAt(x)) apply(x) else default(x)
+
+ /**
+ * TODO: comment
+ * @since 2.10
+ */
+ def run[U](x: A)(action: B => U): Boolean =
+ applyOrElse(x, fallbackToken) match {
+ case FallbackToken => false
+ case z => action(z); true
+ }
+
+ /**
+ * TODO: comment
+ * @since 2.10
+ */
+ def runWith[U](action: B => U): A => Boolean = { x => run(x)(action) }
}
/** A few handy operations which leverage the extra bit of information
@@ -119,14 +130,73 @@ trait PartialFunction[-A, +B] extends (A => B) {
* @since 2.8
*/
object PartialFunction {
- private[this] final val empty_pf: PartialFunction[Any, Nothing] = new runtime.AbstractPartialFunction[Any, Nothing] {
- def _isDefinedAt(x: Any) = false
- override def isDefinedAt(x: Any) = false
- def apply(x: Any): Nothing = throw new MatchError(x)
- override def orElse[A1, B1](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = that
- override def orElseFast[A1, B1](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = that
- override def lift = (x: Any) => None
+ /** Composite function produced by `PartialFunction#orElse` method
+ */
+ private final class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B]) extends PartialFunction[A, B] {
+ def isDefinedAt(x: A) = f1.isDefinedAt(x) || f2.isDefinedAt(x)
+
+ def apply(x: A): B = f1.applyOrElse(x, f2)
+
+ override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 =
+ f1.applyOrElse(x, fallbackToken) match {
+ case FallbackToken => f2.applyOrElse(x, default)
+ case z => z
+ }
+
+ override def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) =
+ new OrElse[A1, B1] (f1, f2 orElse that)
+
+ override def andThen[C](k: B => C) =
+ new OrElse[A, C] (f1 andThen k, f2 andThen k)
}
+
+ private[scala] lazy val FallbackToken: PartialFunction[Any, PartialFunction[Any, Nothing]] = { case _ => FallbackToken.asInstanceOf[PartialFunction[Any, Nothing]] }
+ private[scala] final def fallbackToken[B] = FallbackToken.asInstanceOf[PartialFunction[Any, B]]
+ //TODO: check generated code for PF literal here
+
+ private[scala] final class Lifted[-A, +B] (val pf: PartialFunction[A, B])
+ extends runtime.AbstractFunction1[A, Option[B]] {
+
+ def apply(x: A): Option[B] = pf.applyOrElse(x, fallbackToken) match {
+ case FallbackToken => None
+ case z => Some(z)
+ }
+ }
+
+ private final class Unlifted[A, B] (f: A => Option[B]) extends runtime.AbstractPartialFunction[A, B] {
+ def isDefinedAt(x: A): Boolean = f(x).isDefined
+ override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 =
+ f(x) getOrElse default(x) //TODO: check generated code and inline getOrElse if needed
+ override def lift = f
+ }
+
+ private[scala] def unlifted[A, B](f: A => Option[B]): PartialFunction[A, B] = f match {
+ case lf: Lifted[A, B] => lf.pf
+ case ff => new Unlifted(ff)
+ }
+
+ /** Converts ordinary function to partial one
+ * @since 2.10
+ */
+ //TODO: check generated code for PF literal here
+ def apply[A, B](f: A => B): PartialFunction[A, B] = { case x => f(x) }
+
+ private[this] final val constFalse: Any => Boolean = { _ => false}
+
+ private[this] final val empty_pf: PartialFunction[Any, Nothing] = new PartialFunction[Any, Nothing] {
+ def isDefinedAt(x: Any) = false
+ def apply(x: Any) = throw new MatchError(x)
+ override def orElse[A1, B1](that: PartialFunction[A1, B1]) = that
+ override def andThen[C](k: Nothing => C) = this
+ override val lift = (x: Any) => None
+ override def run[U](x: Any)(action: Nothing => U) = false
+ override def runWith[U](action: Nothing => U) = constFalse
+ }
+
+ /**
+ * TODO: comment
+ * @since 2.10
+ */
def empty[A, B] : PartialFunction[A, B] = empty_pf
/** Creates a Boolean test based on a value and a partial function.
@@ -137,8 +207,7 @@ object PartialFunction {
* @param pf the partial function
* @return true, iff `x` is in the domain of `pf` and `pf(x) == true`.
*/
- def cond[T](x: T)(pf: PartialFunction[T, Boolean]): Boolean =
- (pf isDefinedAt x) && pf(x)
+ def cond[T](x: T)(pf: PartialFunction[T, Boolean]): Boolean = pf.applyOrElse(x, constFalse)
/** Transforms a PartialFunction[T, U] `pf` into Function1[T, Option[U]] `f`
* whose result is `Some(x)` if the argument is in `pf`'s domain and `None`
@@ -150,6 +219,5 @@ object PartialFunction {
* @param pf the PartialFunction[T, U]
* @return `Some(pf(x))` if `pf isDefinedAt x`, `None` otherwise.
*/
- def condOpt[T,U](x: T)(pf: PartialFunction[T, U]): Option[U] =
- if (pf isDefinedAt x) Some(pf(x)) else None
+ def condOpt[T,U](x: T)(pf: PartialFunction[T, U]): Option[U] = pf.lift(x)
}
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index b5006e7948..96b8b6d8d5 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -14,6 +14,7 @@ import mutable.ArrayOps
import generic.CanBuildFrom
import annotation.{ elidable, implicitNotFound }
import annotation.elidable.ASSERTION
+import language.{implicitConversions, existentials}
/** The `Predef` object provides definitions that are accessible in all Scala
* compilation units without explicit qualification.
@@ -100,8 +101,8 @@ object Predef extends LowPriorityImplicits {
// Manifest types, companions, and incantations for summoning
type ClassManifest[T] = scala.reflect.ClassManifest[T]
- type Manifest[T] = scala.reflect.Manifest[T]
type OptManifest[T] = scala.reflect.OptManifest[T]
+ type Manifest[T] = scala.reflect.Manifest[T]
val ClassManifest = scala.reflect.ClassManifest
val Manifest = scala.reflect.Manifest
val NoManifest = scala.reflect.NoManifest
@@ -110,6 +111,26 @@ object Predef extends LowPriorityImplicits {
def classManifest[T](implicit m: ClassManifest[T]) = m
def optManifest[T](implicit m: OptManifest[T]) = m
+ // Tag types and companions, and incantations for summoning
+ type ArrayTag[T] = scala.reflect.ArrayTag[T]
+ type ErasureTag[T] = scala.reflect.ErasureTag[T]
+ type ClassTag[T] = scala.reflect.ClassTag[T]
+ type TypeTag[T] = scala.reflect.TypeTag[T]
+ type ConcreteTypeTag[T] = scala.reflect.ConcreteTypeTag[T]
+ val ClassTag = scala.reflect.ClassTag // doesn't need to be lazy, because it's not a path-dependent type
+ // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies.
+ lazy val TypeTag = scala.reflect.TypeTag // needs to be lazy, because requires scala.reflect.mirror instance
+ lazy val ConcreteTypeTag = scala.reflect.ConcreteTypeTag
+
+ // [Eugene to Martin] it's really tedious to type "implicitly[...]" all the time, so I'm reintroducing these shortcuts
+ def arrayTag[T](implicit atag: ArrayTag[T]) = atag
+ def erasureTag[T](implicit etag: ErasureTag[T]) = etag
+ def classTag[T](implicit ctag: ClassTag[T]) = ctag
+ def tag[T](implicit ttag: TypeTag[T]) = ttag
+ def typeTag[T](implicit ttag: TypeTag[T]) = ttag
+ def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag
+ def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag
+
// Minor variations on identity functions
def identity[A](x: A): A = x // @see `conforms` for the implicit version
@inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero`
@@ -287,11 +308,11 @@ object Predef extends LowPriorityImplicits {
// views --------------------------------------------------------------
implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc)
+ implicit def function1ToRichFunction1[T, R](f: T => R): runtime.RichFunction1[T, R] = new runtime.RichFunction1(f)
+ implicit def function2ToRichFunction2[T1, T2, R](f: (T1, T2) => R): runtime.RichFunction2[T1, T2, R] =
+ new runtime.RichFunction2(f)
- implicit def zipped2ToTraversable[El1, El2](zz: Tuple2[_, _]#Zipped[_, El1, _, El2]): Traversable[(El1, El2)] =
- new collection.AbstractTraversable[(El1, El2)] {
- def foreach[U](f: ((El1, El2)) => U): Unit = zz foreach Function.untupled(f)
- }
+ implicit def tuple2ToZipped[T1, T2](zz: (T1, T2)) = new runtime.Tuple2ZippedOps(zz)
implicit def zipped3ToTraversable[El1, El2, El3](zz: Tuple3[_, _, _]#Zipped[_, El1, _, El2, _, El3]): Traversable[(El1, El2, El3)] =
new collection.AbstractTraversable[(El1, El2, El3)] {
@@ -325,30 +346,30 @@ object Predef extends LowPriorityImplicits {
// Primitive Widenings --------------------------------------------------------------
- implicit def byte2short(x: Byte): Short = x.toShort
- implicit def byte2int(x: Byte): Int = x.toInt
- implicit def byte2long(x: Byte): Long = x.toLong
- implicit def byte2float(x: Byte): Float = x.toFloat
- implicit def byte2double(x: Byte): Double = x.toDouble
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2short(x: Byte): Short = x.toShort
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2int(x: Byte): Int = x.toInt
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2long(x: Byte): Long = x.toLong
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2float(x: Byte): Float = x.toFloat
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2double(x: Byte): Double = x.toDouble
- implicit def short2int(x: Short): Int = x.toInt
- implicit def short2long(x: Short): Long = x.toLong
- implicit def short2float(x: Short): Float = x.toFloat
- implicit def short2double(x: Short): Double = x.toDouble
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2int(x: Short): Int = x.toInt
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2long(x: Short): Long = x.toLong
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2float(x: Short): Float = x.toFloat
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2double(x: Short): Double = x.toDouble
- implicit def char2int(x: Char): Int = x.toInt
- implicit def char2long(x: Char): Long = x.toLong
- implicit def char2float(x: Char): Float = x.toFloat
- implicit def char2double(x: Char): Double = x.toDouble
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2int(x: Char): Int = x.toInt
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2long(x: Char): Long = x.toLong
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2float(x: Char): Float = x.toFloat
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2double(x: Char): Double = x.toDouble
- implicit def int2long(x: Int): Long = x.toLong
- implicit def int2float(x: Int): Float = x.toFloat
- implicit def int2double(x: Int): Double = x.toDouble
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2long(x: Int): Long = x.toLong
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2float(x: Int): Float = x.toFloat
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2double(x: Int): Double = x.toDouble
- implicit def long2float(x: Long): Float = x.toFloat
- implicit def long2double(x: Long): Double = x.toDouble
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def long2float(x: Long): Float = x.toFloat
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def long2double(x: Long): Double = x.toDouble
- implicit def float2double(x: Float): Double = x.toDouble
+ @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def float2double(x: Float): Double = x.toDouble
// "Autoboxing" and "Autounboxing" ---------------------------------------------------
diff --git a/src/library/scala/Product1.scala b/src/library/scala/Product1.scala
index d268b35f60..edd095c5c6 100644
--- a/src/library/scala/Product1.scala
+++ b/src/library/scala/Product1.scala
@@ -28,7 +28,7 @@ trait Product1[@specialized(Int, Long, Double) +T1] extends Any with Product {
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product10.scala b/src/library/scala/Product10.scala
index cae9e5a664..8daefde699 100644
--- a/src/library/scala/Product10.scala
+++ b/src/library/scala/Product10.scala
@@ -28,7 +28,7 @@ trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Any w
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product11.scala b/src/library/scala/Product11.scala
index 0647b28414..90b4e8013e 100644
--- a/src/library/scala/Product11.scala
+++ b/src/library/scala/Product11.scala
@@ -28,7 +28,7 @@ trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product12.scala b/src/library/scala/Product12.scala
index a080aafa7a..d5997ea05a 100644
--- a/src/library/scala/Product12.scala
+++ b/src/library/scala/Product12.scala
@@ -28,7 +28,7 @@ trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] e
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product13.scala b/src/library/scala/Product13.scala
index 425aebf3e7..db8e0f3722 100644
--- a/src/library/scala/Product13.scala
+++ b/src/library/scala/Product13.scala
@@ -28,7 +28,7 @@ trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product14.scala b/src/library/scala/Product14.scala
index 3d7e4896ef..113c07e8c4 100644
--- a/src/library/scala/Product14.scala
+++ b/src/library/scala/Product14.scala
@@ -28,7 +28,7 @@ trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product15.scala b/src/library/scala/Product15.scala
index 7bca7a2a1b..a6ad9c7594 100644
--- a/src/library/scala/Product15.scala
+++ b/src/library/scala/Product15.scala
@@ -28,7 +28,7 @@ trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product16.scala b/src/library/scala/Product16.scala
index c5042cbc90..cbf47ece94 100644
--- a/src/library/scala/Product16.scala
+++ b/src/library/scala/Product16.scala
@@ -28,7 +28,7 @@ trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product17.scala b/src/library/scala/Product17.scala
index b5651ec712..f56836bfd8 100644
--- a/src/library/scala/Product17.scala
+++ b/src/library/scala/Product17.scala
@@ -28,7 +28,7 @@ trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product18.scala b/src/library/scala/Product18.scala
index 088a48ae32..5b86bcff65 100644
--- a/src/library/scala/Product18.scala
+++ b/src/library/scala/Product18.scala
@@ -28,7 +28,7 @@ trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product19.scala b/src/library/scala/Product19.scala
index 4f4a98c6a0..ed4bf36c93 100644
--- a/src/library/scala/Product19.scala
+++ b/src/library/scala/Product19.scala
@@ -28,7 +28,7 @@ trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product2.scala b/src/library/scala/Product2.scala
index eb67e5d46e..e27e54eff9 100644
--- a/src/library/scala/Product2.scala
+++ b/src/library/scala/Product2.scala
@@ -28,7 +28,7 @@ trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Doub
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product20.scala b/src/library/scala/Product20.scala
index 80f63f1bb4..47437a20af 100644
--- a/src/library/scala/Product20.scala
+++ b/src/library/scala/Product20.scala
@@ -28,7 +28,7 @@ trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product21.scala b/src/library/scala/Product21.scala
index 7056844271..319d2725c0 100644
--- a/src/library/scala/Product21.scala
+++ b/src/library/scala/Product21.scala
@@ -28,7 +28,7 @@ trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product22.scala b/src/library/scala/Product22.scala
index 05e95f92dd..6ab3737acd 100644
--- a/src/library/scala/Product22.scala
+++ b/src/library/scala/Product22.scala
@@ -28,7 +28,7 @@ trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product3.scala b/src/library/scala/Product3.scala
index 91556bb962..1cfbd7956b 100644
--- a/src/library/scala/Product3.scala
+++ b/src/library/scala/Product3.scala
@@ -28,7 +28,7 @@ trait Product3[+T1, +T2, +T3] extends Any with Product {
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product4.scala b/src/library/scala/Product4.scala
index 1f9070c155..843571fd60 100644
--- a/src/library/scala/Product4.scala
+++ b/src/library/scala/Product4.scala
@@ -28,7 +28,7 @@ trait Product4[+T1, +T2, +T3, +T4] extends Any with Product {
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product5.scala b/src/library/scala/Product5.scala
index 52dd284f55..df73bba3dd 100644
--- a/src/library/scala/Product5.scala
+++ b/src/library/scala/Product5.scala
@@ -28,7 +28,7 @@ trait Product5[+T1, +T2, +T3, +T4, +T5] extends Any with Product {
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product6.scala b/src/library/scala/Product6.scala
index 9624bdbe3e..36906ca54e 100644
--- a/src/library/scala/Product6.scala
+++ b/src/library/scala/Product6.scala
@@ -28,7 +28,7 @@ trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Any with Product {
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product7.scala b/src/library/scala/Product7.scala
index 36d4b149db..e7b2c13ad1 100644
--- a/src/library/scala/Product7.scala
+++ b/src/library/scala/Product7.scala
@@ -28,7 +28,7 @@ trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Any with Product {
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product8.scala b/src/library/scala/Product8.scala
index 28c78f9c89..916e57ec39 100644
--- a/src/library/scala/Product8.scala
+++ b/src/library/scala/Product8.scala
@@ -28,7 +28,7 @@ trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Any with Product
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/library/scala/Product9.scala b/src/library/scala/Product9.scala
index d69c550abe..d5e72edc0b 100644
--- a/src/library/scala/Product9.scala
+++ b/src/library/scala/Product9.scala
@@ -28,7 +28,7 @@ trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Any with Pro
* otherwise throws an `IndexOutOfBoundsException`.
*
* @param n number of the projection to be returned
- * @return same as `._(n+1)`, for example `productElement(1)` is the same as `._1`.
+ * @return same as `._(n+1)`, for example `productElement(0)` is the same as `._1`.
* @throws IndexOutOfBoundsException
*/
diff --git a/src/dbc/scala/dbc/statement/Statement.scala b/src/library/scala/ScalaObject.scala
index fc5374262d..7cd64becbe 100644
--- a/src/dbc/scala/dbc/statement/Statement.scala
+++ b/src/library/scala/ScalaObject.scala
@@ -6,11 +6,11 @@
** |/ **
\* */
+package scala
-
-package scala.dbc
-package statement
-
-
-/** An ISO-9075:2003 (SQL) statement. */
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class Statement
+/** Until scala 2.10.0 this marker trait was added to
+ * scala-compiled classes. Now it only exists for backward
+ * compatibility.
+ */
+@deprecated("ScalaObject will be removed", "2.10.0")
+trait ScalaObject
diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala
index 5664c3b44c..1060a9db16 100644
--- a/src/library/scala/Short.scala
+++ b/src/library/scala/Short.scala
@@ -17,7 +17,7 @@ package scala
* There is an implicit conversion from [[scala.Short]] => [[scala.runtime.RichShort]]
* which provides useful non-primitive operations.
*/
-final class Short extends AnyVal {
+final class Short private extends AnyVal {
def toByte: Byte = sys.error("stub")
def toShort: Short = sys.error("stub")
def toChar: Char = sys.error("stub")
@@ -27,7 +27,7 @@ final class Short extends AnyVal {
def toDouble: Double = sys.error("stub")
/**
- * @return the bitwise negation of this value
+ * Returns the bitwise negation of this value.
* @example {{{
* ~5 == -6
* // in binary: ~00000101 ==
@@ -36,30 +36,30 @@ final class Short extends AnyVal {
*/
def unary_~ : Int = sys.error("stub")
/**
- * @return this value, unmodified
+ * Returns this value, unmodified.
*/
def unary_+ : Int = sys.error("stub")
/**
- * @return the negation of this value
+ * Returns the negation of this value.
*/
def unary_- : Int = sys.error("stub")
def +(x: String): String = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the new right bits with zeroes.
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}}
*/
def <<(x: Long): Int = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -70,7 +70,7 @@ final class Short extends AnyVal {
*/
def >>>(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted right by the specified number of bits,
+ * Returns this value bit-shifted right by the specified number of bits,
* filling the new left bits with zeroes.
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}}
* @example {{{
@@ -81,7 +81,7 @@ final class Short extends AnyVal {
*/
def >>>(x: Long): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -92,7 +92,7 @@ final class Short extends AnyVal {
*/
def >>(x: Int): Int = sys.error("stub")
/**
- * @return this value bit-shifted left by the specified number of bits,
+ * Returns this value bit-shifted left by the specified number of bits,
* filling in the right bits with the same value as the left-most bit of this.
* The effect of this is to retain the sign of the value.
* @example {{{
@@ -104,181 +104,181 @@ final class Short extends AnyVal {
def >>(x: Long): Int = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is equal x, `false` otherwise
+ * Returns `true` if this value is equal to x, `false` otherwise.
*/
def ==(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is not equal to x, `false` otherwise
+ * Returns `true` if this value is not equal to x, `false` otherwise.
*/
def !=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than x, `false` otherwise
+ * Returns `true` if this value is less than x, `false` otherwise.
*/
def <(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is less than or equal to x, `false` otherwise
+ * Returns `true` if this value is less than or equal to x, `false` otherwise.
*/
def <=(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than x, `false` otherwise
+ * Returns `true` if this value is greater than x, `false` otherwise.
*/
def >(x: Double): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Byte): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Short): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Char): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Int): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Long): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Float): Boolean = sys.error("stub")
/**
- * @return `true` if this value is greater than or equal to x, `false` otherwise
+ * Returns `true` if this value is greater than or equal to x, `false` otherwise.
*/
def >=(x: Double): Boolean = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -289,7 +289,7 @@ final class Short extends AnyVal {
*/
def |(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -300,7 +300,7 @@ final class Short extends AnyVal {
*/
def |(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -311,7 +311,7 @@ final class Short extends AnyVal {
*/
def |(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -322,7 +322,7 @@ final class Short extends AnyVal {
*/
def |(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise OR of this value and x
+ * Returns the bitwise OR of this value and `x`.
* @example {{{
* (0xf0 | 0xaa) == 0xfa
* // in binary: 11110000
@@ -334,7 +334,7 @@ final class Short extends AnyVal {
def |(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -345,7 +345,7 @@ final class Short extends AnyVal {
*/
def &(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -356,7 +356,7 @@ final class Short extends AnyVal {
*/
def &(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -367,7 +367,7 @@ final class Short extends AnyVal {
*/
def &(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -378,7 +378,7 @@ final class Short extends AnyVal {
*/
def &(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise AND of this value and x
+ * Returns the bitwise AND of this value and `x`.
* @example {{{
* (0xf0 & 0xaa) == 0xa0
* // in binary: 11110000
@@ -390,7 +390,7 @@ final class Short extends AnyVal {
def &(x: Long): Long = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -401,7 +401,7 @@ final class Short extends AnyVal {
*/
def ^(x: Byte): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -412,7 +412,7 @@ final class Short extends AnyVal {
*/
def ^(x: Short): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -423,7 +423,7 @@ final class Short extends AnyVal {
*/
def ^(x: Char): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -434,7 +434,7 @@ final class Short extends AnyVal {
*/
def ^(x: Int): Int = sys.error("stub")
/**
- * @return the bitwise XOR of this value and x
+ * Returns the bitwise XOR of this value and `x`.
* @example {{{
* (0xf0 ^ 0xaa) == 0x5a
* // in binary: 11110000
@@ -446,154 +446,154 @@ final class Short extends AnyVal {
def ^(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Byte): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Short): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Char): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Int): Int = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Long): Long = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Float): Float = sys.error("stub")
/**
- * @return the sum of this value and x
+ * Returns the sum of this value and `x`.
*/
def +(x: Double): Double = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Byte): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Short): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Char): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Int): Int = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Long): Long = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Float): Float = sys.error("stub")
/**
- * @return the difference of this value and x
+ * Returns the difference of this value and `x`.
*/
def -(x: Double): Double = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Byte): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Short): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Char): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Int): Int = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Long): Long = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Float): Float = sys.error("stub")
/**
- * @return the product of this value and x
+ * Returns the product of this value and `x`.
*/
def *(x: Double): Double = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Byte): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Short): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Char): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Int): Int = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Long): Long = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Float): Float = sys.error("stub")
/**
- * @return the quotient of this value and x
+ * Returns the quotient of this value and `x`.
*/
def /(x: Double): Double = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Byte): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Short): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Char): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Int): Int = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Long): Long = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Float): Float = sys.error("stub")
/**
- * @return the remainder of the division of this value by x
+ * Returns the remainder of the division of this value by `x`.
*/
def %(x: Double): Double = sys.error("stub")
override def getClass(): Class[Short] = sys.error("stub")
}
-object Short extends AnyValCompanion {
+object Short extends AnyValCompanion {
/** The smallest value representable as a Short.
*/
final val MinValue = java.lang.Short.MIN_VALUE
@@ -622,5 +622,9 @@ object Short extends AnyValCompanion {
/** The String representation of the scala.Short companion object.
*/
override def toString = "object scala.Short"
+ implicit def short2int(x: Short): Int = x.toInt
+ implicit def short2long(x: Short): Long = x.toLong
+ implicit def short2float(x: Short): Float = x.toFloat
+ implicit def short2double(x: Short): Double = x.toDouble
}
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index 1b01355108..be9e0c290a 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -79,15 +79,13 @@ case class StringContext(parts: String*) {
* start a format specifier), then the string format specifier `%s` is inserted.
*
* 2. Any `%` characters not in formatting positions are left in the resulting
- * string literally. This is achieved by replacing each such occurrence by a string
- * format specifier `%s` and adding a corresponding argument string `"%"`.
+ * string literally. This is achieved by replacing each such occurrence by the
+ * format specifier `%%`.
*/
def f(args: Any*) = {
checkLengths(args: _*)
val pi = parts.iterator
- val ai = args.iterator
val bldr = new java.lang.StringBuilder
- val args1 = new ArrayBuffer[Any]
def copyString(first: Boolean): Unit = {
val str = treatEscapes(pi.next())
val strIsEmpty = str.length == 0
@@ -98,23 +96,23 @@ case class StringContext(parts: String*) {
bldr append "%s"
idx = 1
}
- val len = str.length
- while (idx < len) {
- if (str(idx) == '%') {
- bldr append (str substring (start, idx)) append "%s"
- args1 += "%"
- start = idx + 1
+ if (!strIsEmpty) {
+ val len = str.length
+ while (idx < len) {
+ if (str(idx) == '%') {
+ bldr append (str substring (start, idx)) append "%%"
+ start = idx + 1
+ }
+ idx += 1
}
- idx += 1
+ bldr append (str substring (start, idx))
}
- if (!strIsEmpty) bldr append (str substring (start, idx))
}
copyString(first = true)
while (pi.hasNext) {
- args1 += ai.next()
copyString(first = false)
}
- bldr.toString format (args1: _*)
+ bldr.toString format (args: _*)
}
}
@@ -144,7 +142,7 @@ object StringContext {
var cur = 0
var idx = 0
def output(ch: Char) = {
- bldr append str substring (start, cur)
+ bldr append str.substring (start, cur)
bldr append ch
start = idx
}
diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala
index b1befca4fa..924b2b6fe3 100644
--- a/src/library/scala/Tuple2.scala
+++ b/src/library/scala/Tuple2.scala
@@ -9,9 +9,6 @@
package scala
-import scala.collection.{ TraversableLike => TLike, IterableLike => ILike }
-import scala.collection.generic.{ CanBuildFrom => CBF }
-
/** A tuple of 2 elements; the canonical representation of a [[scala.Product2]].
*
@@ -23,112 +20,11 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s
extends Product2[T1, T2]
{
override def toString() = "(" + _1 + "," + _2 + ")"
-
+
/** Swaps the elements of this `Tuple`.
* @return a new Tuple where the first element is the second element of this Tuple and the
* second element is the first element of this Tuple.
*/
def swap: Tuple2[T2,T1] = Tuple2(_2, _1)
- @deprecated("Use `zipped` instead.", "2.9.0")
- def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1],
- w2: T2 => Iterable[El2],
- cbf1: CBF[Repr1, (El1, El2), To]): To = {
- zipped map ((x, y) => ((x, y)))
- }
-
- /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc.
- * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]]
- * or [[scala.collection.IterableLike]].
- * {{{
- * scala> val tuple = (List(1,2,3),List('a','b','c'))
- * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c))
- *
- * scala> tuple.zipped map { (x,y) => x + ":" + y }
- * res6: List[java.lang.String] = List(1:a, 2:b, 3:c)
- * }}}
- *
- * @see Zipped
- * Note: will not terminate for infinite-sized collections.
- */
- def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2]
- = new Zipped[Repr1, El1, Repr2, El2](_1, _2)
-
- class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { // coll2: ILike for filter
- def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = {
- val b = cbf(coll1.repr)
- b.sizeHint(coll1)
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext)
- b += f(el1, elems2.next)
- else
- return b.result
- }
-
- b.result
- }
-
- def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = {
- val b = cbf(coll1.repr)
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext)
- b ++= f(el1, elems2.next)
- else
- return b.result
- }
-
- b.result
- }
-
- def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = {
- val b1 = cbf1(coll1.repr)
- val b2 = cbf2(coll2.repr)
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext) {
- val el2 = elems2.next
- if (f(el1, el2)) {
- b1 += el1
- b2 += el2
- }
- }
- else return (b1.result, b2.result)
- }
-
- (b1.result, b2.result)
- }
-
- def exists(f: (El1, El2) => Boolean): Boolean = {
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext) {
- if (f(el1, elems2.next))
- return true
- }
- else return false
- }
- false
- }
-
- def forall(f: (El1, El2) => Boolean): Boolean =
- !exists((x, y) => !f(x, y))
-
- def foreach[U](f: (El1, El2) => U): Unit = {
- val elems2 = coll2.iterator
-
- for (el1 <- coll1) {
- if (elems2.hasNext)
- f(el1, elems2.next)
- else
- return
- }
- }
- }
-
}
diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala
index 0d5399308b..dfa0c962a2 100644
--- a/src/library/scala/Tuple3.scala
+++ b/src/library/scala/Tuple3.scala
@@ -24,7 +24,7 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3)
extends Product3[T1, T2, T3]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")"
-
+
@deprecated("Use `zipped` instead.", "2.9.0")
def zip[Repr1, El1, El2, El3, To](implicit w1: T1 => TLike[El1, Repr1],
diff --git a/src/library/scala/Unit.scala b/src/library/scala/Unit.scala
index f6ed0121ab..3da5c083d4 100644
--- a/src/library/scala/Unit.scala
+++ b/src/library/scala/Unit.scala
@@ -16,11 +16,11 @@ package scala
* runtime system. A method with return type `Unit` is analogous to a Java
* method which is declared `void`.
*/
-final class Unit extends AnyVal {
+final class Unit private extends AnyVal {
override def getClass(): Class[Unit] = sys.error("stub")
}
-object Unit extends AnyValCompanion {
+object Unit extends AnyValCompanion {
/** Transform a value type into a boxed reference type.
*
diff --git a/src/library/scala/annotation/ClassfileAnnotation.scala b/src/library/scala/annotation/ClassfileAnnotation.scala
index 582e51996a..2fde5aae80 100644
--- a/src/library/scala/annotation/ClassfileAnnotation.scala
+++ b/src/library/scala/annotation/ClassfileAnnotation.scala
@@ -9,7 +9,7 @@
package scala.annotation
/** A base class for classfile annotations. These are stored as
- * [[http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html#_top Java annotations]]]
+ * [[http://docs.oracle.com/javase/7/docs/technotes/guides/language/annotations.html#_top Java annotations]]]
* in classfiles.
*
* @author Martin Odersky
diff --git a/src/dbc/scala/dbc/statement/SetClause.scala b/src/library/scala/annotation/meta/companionClass.scala
index 3af509c026..8e53f6caf9 100644
--- a/src/dbc/scala/dbc/statement/SetClause.scala
+++ b/src/library/scala/annotation/meta/companionClass.scala
@@ -1,21 +1,17 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
+package scala.annotation.meta
-
-
-package scala.dbc
-package statement
-
-
-import scala.dbc.statement.expression._
-
-/** Data to be inserted into a table in an <code>Insert</code>. */
-@deprecated(DbcIsDeprecated, "2.9.0") case class SetClause(name: String, expr: Expression) {
- val value: Pair[String,Expression] = (name, expr)
- def sqlString: String = value._1 + " = " + value._2.sqlInnerString
-}
+/**
+ * When defining an implicit class, the Scala compiler creates an implicit
+ * conversion method for it. Annotations `@companionClass` and `@companionMethod`
+ * control where an annotation on the implicit class will go. By default, annotations
+ * on an implicit class end up only on the class.
+ *
+ */
+final class companionClass extends annotation.StaticAnnotation
diff --git a/src/library/scala/annotation/meta/companionMethod.scala b/src/library/scala/annotation/meta/companionMethod.scala
new file mode 100644
index 0000000000..379c4f3385
--- /dev/null
+++ b/src/library/scala/annotation/meta/companionMethod.scala
@@ -0,0 +1,17 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+package scala.annotation.meta
+
+/**
+ * When defining an implicit class, the Scala compiler creates an implicit
+ * conversion method for it. Annotations `@companionClass` and `@companionMethod`
+ * control where an annotation on the implicit class will go. By default, annotations
+ * on an implicit class end up only on the class.
+ *
+ */
+final class companionMethod extends annotation.StaticAnnotation
diff --git a/src/dbc/scala/dbc/statement/AccessMode.scala b/src/library/scala/annotation/meta/companionObject.scala
index 885e0012f2..d329df5c42 100644
--- a/src/dbc/scala/dbc/statement/AccessMode.scala
+++ b/src/library/scala/annotation/meta/companionObject.scala
@@ -1,26 +1,14 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
+package scala.annotation.meta
-
-
-package scala.dbc
-package statement
-
-
-@deprecated(DbcIsDeprecated, "2.9.0") abstract class AccessMode {
- def sqlString: String
-}
-
-@deprecated(DbcIsDeprecated, "2.9.0") object AccessMode {
- case object ReadOnly extends AccessMode {
- def sqlString = "READ ONLY"
- }
- case object ReadWrite extends AccessMode {
- def sqlString = "READ WRITE"
- }
-}
+/**
+ * Currently unused; intended as an annotation target for classes such as case classes
+ * that automatically generate a companion object
+ */
+final class companionObject extends annotation.StaticAnnotation
diff --git a/src/dbc/scala/dbc/exception/UnsupportedFeature.scala b/src/library/scala/annotation/meta/languageFeature.scala
index dd6f904077..23acc01b51 100644
--- a/src/dbc/scala/dbc/exception/UnsupportedFeature.scala
+++ b/src/library/scala/annotation/meta/languageFeature.scala
@@ -1,16 +1,13 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
+package scala.annotation.meta
-
-
-package scala.dbc
-package exception
-
-
-/** A type category for all SQL types that store constant-precision numbers. */
-@deprecated(DbcIsDeprecated, "2.9.0") case class UnsupportedFeature (msg: String) extends Exception;
+/**
+ * An annotation giving particulars for a language feature in object `scala.language`.
+ */
+final class languageFeature(feature: String, enableRequired: Boolean) extends annotation.StaticAnnotation
diff --git a/src/library/scala/annotation/switch.scala b/src/library/scala/annotation/switch.scala
index 3734686b27..ee068f50d4 100644
--- a/src/library/scala/annotation/switch.scala
+++ b/src/library/scala/annotation/switch.scala
@@ -9,8 +9,8 @@ package scala.annotation
/** An annotation to be applied to a match expression. If present,
* the compiler will verify that the match has been compiled to a
- * [[http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc14.html tableswitch]]
- * or [[http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc8.html#lookupswitch lookupswitch]]
+ * [[http://docs.oracle.com/javase/specs/jvms/se5.0/html/Instructions2.doc14.html tableswitch]]
+ * or [[http://docs.oracle.com/javase/specs/jvms/se5.0/html/Instructions2.doc8.html#lookupswitch lookupswitch]]
* and issue an error if it instead compiles into a series of conditional expressions.
* Example usage:
{{{
diff --git a/src/library/scala/collection/DefaultMap.scala b/src/library/scala/collection/DefaultMap.scala
index 3af535bdaa..d00414751a 100644
--- a/src/library/scala/collection/DefaultMap.scala
+++ b/src/library/scala/collection/DefaultMap.scala
@@ -41,7 +41,7 @@ trait DefaultMap[A, +B] extends Map[A, B] { self =>
*/
override def - (key: A): Map[A, B] = {
val b = newBuilder
- b ++= this filter (key !=)
+ b ++= this filter (key != _)
b.result
}
}
diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala
index 755abcd2bf..71316cefc9 100644
--- a/src/library/scala/collection/GenSeqLike.scala
+++ b/src/library/scala/collection/GenSeqLike.scala
@@ -142,7 +142,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal
* $mayNotTerminateInf
*
*/
- def indexOf[B >: A](elem: B, from: Int): Int = indexWhere(elem ==, from)
+ def indexOf[B >: A](elem: B, from: Int): Int = indexWhere(elem == _, from)
/** Finds index of last occurrence of some value in this $coll.
*
@@ -157,7 +157,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal
* $willNotTerminateInf
*
*/
- def lastIndexOf[B >: A](elem: B): Int = lastIndexWhere(elem ==)
+ def lastIndexOf[B >: A](elem: B): Int = lastIndexWhere(elem == _)
/** Finds index of last occurrence of some value in this $coll before or at a given end index.
*
@@ -170,7 +170,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal
* @usecase def lastIndexOf(elem: A, end: Int): Int
* @inheritdoc
*/
- def lastIndexOf[B >: A](elem: B, end: Int): Int = lastIndexWhere(elem ==, end)
+ def lastIndexOf[B >: A](elem: B, end: Int): Int = lastIndexWhere(elem == _, end)
/** Finds index of last element satisfying some predicate.
*
diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala
index fd03e0f446..4500a849b1 100644
--- a/src/library/scala/collection/GenTraversableLike.scala
+++ b/src/library/scala/collection/GenTraversableLike.scala
@@ -91,7 +91,7 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with
*/
def scan[B >: A, That](z: B)(op: (B, B) => B)(implicit cbf: CanBuildFrom[Repr, B, That]): That
- /** Produces a collection containing cummulative results of applying the
+ /** Produces a collection containing cumulative results of applying the
* operator going left to right.
*
* $willNotTerminateInf
@@ -106,8 +106,8 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with
*/
def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
- /** Produces a collection containing cummulative results of applying the operator going right to left.
- * The head of the collection is the last cummulative result.
+ /** Produces a collection containing cumulative results of applying the operator going right to left.
+ * The head of the collection is the last cumulative result.
* $willNotTerminateInf
* $orderDependent
*
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index 019d3d0785..fd8595ccb8 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -156,7 +156,7 @@ trait GenTraversableOnce[+A] extends Any {
* @return the result of inserting `op` between consecutive elements of this $coll,
* going left to right with the start value `z` on the left:
* {{{
- * op(...op(op(z, x1), x2), ..., xn)
+ * op(...op(op(z, x_1), x_2), ..., x_n)
* }}}
* where `x,,1,,, ..., x,,n,,` are the elements of this $coll.
*/
@@ -191,7 +191,7 @@ trait GenTraversableOnce[+A] extends Any {
* @return the result of inserting `op` between consecutive elements of this $coll,
* going right to left with the start value `z` on the right:
* {{{
- * op(x1, op(x2, ... op(xn, z)...))
+ * op(x_1, op(x_2, ... op(x_n, z)...))
* }}}
* where `x,,1,,, ..., x,,n,,` are the elements of this $coll.
*/
@@ -209,7 +209,7 @@ trait GenTraversableOnce[+A] extends Any {
* @return the result of inserting `op` between consecutive elements of this $coll,
* going left to right with the start value `z` on the left:
* {{{
- * op(...op(z, x1), x2, ..., xn)
+ * op(...op(z, x_1), x_2, ..., x_n)
* }}}
* where `x,,1,,, ..., x,,n,,` are the elements of this $coll.
*/
@@ -226,7 +226,7 @@ trait GenTraversableOnce[+A] extends Any {
* @return the result of inserting `op` between consecutive elements of this $coll,
* going right to left with the start value `z` on the right:
* {{{
- * op(x1, op(x2, ... op(xn, z)...))
+ * op(x_1, op(x_2, ... op(x_n, z)...))
* }}}
* where `x,,1,,, ..., x,,n,,` are the elements of this $coll.
*/
@@ -271,7 +271,7 @@ trait GenTraversableOnce[+A] extends Any {
* @return the result of inserting `op` between consecutive elements of this $coll,
* going right to left:
* {{{
- * op(x,,1,,, op(x,,2,,, ..., op(x,,n-1,,, x,,n,,)...))
+ * op(x_1, op(x_2, ..., op(x_{n-1}, x_n)...))
* }}}
* where `x,,1,,, ..., x,,n,,` are the elements of this $coll.
* @throws `UnsupportedOperationException` if this $coll is empty.
@@ -459,7 +459,7 @@ trait GenTraversableOnce[+A] extends Any {
/** Converts this $coll to an array.
*
- * @tparam B the type of the elements of the array. A `ClassManifest` for
+ * @tparam B the type of the elements of the array. An `ArrayTag` for
* this type must be available.
* @return an array containing all elements of this $coll.
*
@@ -469,9 +469,9 @@ trait GenTraversableOnce[+A] extends Any {
* $willNotTerminateInf
*
* @return an array containing all elements of this $coll.
- * A `ClassManifest` must be available for the element type of this $coll.
+ * An `ArrayTag` must be available for the element type of this $coll.
*/
- def toArray[A1 >: A: ClassManifest]: Array[A1]
+ def toArray[A1 >: A: ArrayTag]: Array[A1]
/** Converts this $coll to a list.
* $willNotTerminateInf
diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala
index fb6d154952..3c4ad0612a 100644
--- a/src/library/scala/collection/IterableLike.scala
+++ b/src/library/scala/collection/IterableLike.scala
@@ -134,7 +134,7 @@ self =>
it.next
i += 1
}
- b ++= it result
+ (b ++= it).result
}
override /*TraversableLike*/ def takeWhile(p: A => Boolean): Repr = {
diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala
index ce2daf08d4..c842475590 100644
--- a/src/library/scala/collection/IterableViewLike.scala
+++ b/src/library/scala/collection/IterableViewLike.scala
@@ -11,6 +11,7 @@ package scala.collection
import generic._
import TraversableView.NoBuilder
import immutable.Stream
+import language.implicitConversions
/** A template trait for non-strict views of iterable collections.
* $iterableViewInfo
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 7b57a91c41..65de60c8fe 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -329,14 +329,16 @@ trait Iterator[+A] extends TraversableOnce[A] {
def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new AbstractIterator[B] {
// optimize a little bit to prevent n log n behavior.
private var cur : Iterator[B] = self
+ private var selfExhausted : Boolean = false
// since that is by-name, make sure it's only referenced once -
// if "val it = that" is inside the block, then hasNext on an empty
// iterator will continually reevaluate it. (ticket #3269)
lazy val it = that.toIterator
// the eq check is to avoid an infinite loop on "x ++ x"
- def hasNext = cur.hasNext || ((cur eq self) && {
+ def hasNext = cur.hasNext || (!selfExhausted && {
it.hasNext && {
cur = it
+ selfExhausted = true
true
}
})
diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala
index 50919e506a..a978a9a783 100644
--- a/src/library/scala/collection/JavaConversions.scala
+++ b/src/library/scala/collection/JavaConversions.scala
@@ -8,6 +8,9 @@
package scala.collection
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+import convert._
+
/** A collection of implicit conversions supporting interoperability between
* Scala and Java collections.
*
@@ -46,877 +49,83 @@ package scala.collection
* @author Martin Odersky
* @since 2.8
*/
-object JavaConversions {
+object JavaConversions extends WrapAsScala with WrapAsJava {
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type ConcurrentMapWrapper[A, B] = Wrappers.ConcurrentMapWrapper[A, B]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type DictionaryWrapper[A, B] = Wrappers.DictionaryWrapper[A, B]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type IterableWrapper[A] = Wrappers.IterableWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type IteratorWrapper[A] = Wrappers.IteratorWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JCollectionWrapper[A] = Wrappers.JCollectionWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JConcurrentMapWrapper[A, B] = Wrappers.JConcurrentMapWrapper[A, B]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JDictionaryWrapper[A, B] = Wrappers.JDictionaryWrapper[A, B]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JEnumerationWrapper[A] = Wrappers.JEnumerationWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JIterableWrapper[A] = Wrappers.JIterableWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JIteratorWrapper[A] = Wrappers.JIteratorWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JListWrapper[A] = Wrappers.JListWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JMapWrapper[A, B] = Wrappers.JMapWrapper[A, B]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JPropertiesWrapper = Wrappers.JPropertiesWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JSetWrapper[A] = Wrappers.JSetWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MapWrapper[A, B] = Wrappers.MapWrapper[A, B]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableBufferWrapper[A] = Wrappers.MutableBufferWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableMapWrapper[A, B] = Wrappers.MutableMapWrapper[A, B]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableSeqWrapper[A] = Wrappers.MutableSeqWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableSetWrapper[A] = Wrappers.MutableSetWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type SeqWrapper[A] = Wrappers.SeqWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type SetWrapper[A] = Wrappers.SetWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type ToIteratorWrapper[A] = Wrappers.ToIteratorWrapper[A]
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val DictionaryWrapper = Wrappers.DictionaryWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val IterableWrapper = Wrappers.IterableWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val IteratorWrapper = Wrappers.IteratorWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JCollectionWrapper = Wrappers.JCollectionWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JConcurrentMapWrapper = Wrappers.JConcurrentMapWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JDictionaryWrapper = Wrappers.JDictionaryWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JEnumerationWrapper = Wrappers.JEnumerationWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JIterableWrapper = Wrappers.JIterableWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JIteratorWrapper = Wrappers.JIteratorWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JListWrapper = Wrappers.JListWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JMapWrapper = Wrappers.JMapWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JPropertiesWrapper = Wrappers.JPropertiesWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JSetWrapper = Wrappers.JSetWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val MutableBufferWrapper = Wrappers.MutableBufferWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val MutableMapWrapper = Wrappers.MutableMapWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val MutableSeqWrapper = Wrappers.MutableSeqWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val MutableSetWrapper = Wrappers.MutableSetWrapper
+ @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val SeqWrapper = Wrappers.SeqWrapper
+
// Note to implementors: the cavalcade of deprecated methods herein should
// serve as a warning to any who follow: don't overload implicit methods.
- import java.{ lang => jl, util => ju }
- import java.util.{ concurrent => juc }
-
- // Scala => Java
-
- /**
- * Implicitly converts a Scala Iterator to a Java Iterator.
- * The returned Java Iterator is backed by the provided Scala
- * Iterator and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Iterator was previously obtained from an implicit or
- * explicit call of `asIterator(java.util.Iterator)` then the original
- * Java Iterator will be returned.
- *
- * @param i The Iterator to be converted.
- * @return A Java Iterator view of the argument.
- */
- implicit def asJavaIterator[A](it: Iterator[A]): ju.Iterator[A] = it match {
- case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]]
- case _ => IteratorWrapper(it)
- }
-
- /**
- * Implicitly converts a Scala Iterator to a Java Enumeration.
- * The returned Java Enumeration is backed by the provided Scala
- * Iterator and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Iterator was previously obtained from an implicit or
- * explicit call of `asIterator(java.util.Enumeration)` then the
- * original Java Enumeration will be returned.
- *
- * @param i The Iterator to be converted.
- * @return A Java Enumeration view of the argument.
- */
- implicit def asJavaEnumeration[A](it: Iterator[A]): ju.Enumeration[A] = it match {
- case JEnumerationWrapper(wrapped) => wrapped.asInstanceOf[ju.Enumeration[A]]
- case _ => IteratorWrapper(it)
- }
-
- /**
- * Implicitly converts a Scala Iterable to a Java Iterable.
- * The returned Java Iterable is backed by the provided Scala
- * Iterable and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Iterable was previously obtained from an implicit or
- * explicit call of `asIterable(java.lang.Iterable)` then the original
- * Java Iterable will be returned.
- *
- * @param i The Iterable to be converted.
- * @return A Java Iterable view of the argument.
- */
- implicit def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = i match {
- case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]]
- case _ => IterableWrapper(i)
- }
-
- /**
- * Implicitly converts a Scala Iterable to an immutable Java
- * Collection.
- *
- * If the Scala Iterable was previously obtained from an implicit or
- * explicit call of `asSizedIterable(java.util.Collection)` then the original
- * Java Collection will be returned.
- *
- * @param i The SizedIterable to be converted.
- * @return A Java Collection view of the argument.
- */
- implicit def asJavaCollection[A](it: Iterable[A]): ju.Collection[A] = it match {
- case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]]
- case _ => new IterableWrapper(it)
- }
-
- /**
- * Implicitly converts a Scala mutable Buffer to a Java List.
- * The returned Java List is backed by the provided Scala
- * Buffer and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Buffer was previously obtained from an implicit or
- * explicit call of `asBuffer(java.util.List)` then the original
- * Java List will be returned.
- *
- * @param b The Buffer to be converted.
- * @return A Java List view of the argument.
- */
- implicit def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = b match {
- case JListWrapper(wrapped) => wrapped
- case _ => new MutableBufferWrapper(b)
- }
@deprecated("use bufferAsJavaList instead", "2.9.0")
def asJavaList[A](b : mutable.Buffer[A]): ju.List[A] = bufferAsJavaList[A](b)
- /**
- * Implicitly converts a Scala mutable Seq to a Java List.
- * The returned Java List is backed by the provided Scala
- * Seq and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Seq was previously obtained from an implicit or
- * explicit call of `asSeq(java.util.List)` then the original
- * Java List will be returned.
- *
- * @param b The Seq to be converted.
- * @return A Java List view of the argument.
- */
- implicit def mutableSeqAsJavaList[A](seq: mutable.Seq[A]): ju.List[A] = seq match {
- case JListWrapper(wrapped) => wrapped
- case _ => new MutableSeqWrapper(seq)
- }
@deprecated("use mutableSeqAsJavaList instead", "2.9.0")
def asJavaList[A](b : mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList[A](b)
- /**
- * Implicitly converts a Scala Seq to a Java List.
- * The returned Java List is backed by the provided Scala
- * Seq and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Seq was previously obtained from an implicit or
- * explicit call of `asSeq(java.util.List)` then the original
- * Java List will be returned.
- *
- * @param b The Seq to be converted.
- * @return A Java List view of the argument.
- */
- implicit def seqAsJavaList[A](seq: Seq[A]): ju.List[A] = seq match {
- case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]]
- case _ => new SeqWrapper(seq)
- }
-
@deprecated("use seqAsJavaList instead", "2.9.0")
def asJavaList[A](b : Seq[A]): ju.List[A] = seqAsJavaList[A](b)
- /**
- * Implicitly converts a Scala mutable Set to a Java Set.
- * The returned Java Set is backed by the provided Scala
- * Set and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Set was previously obtained from an implicit or
- * explicit call of `asSet(java.util.Set)` then the original
- * Java Set will be returned.
- *
- * @param s The Set to be converted.
- * @return A Java Set view of the argument.
- */
- implicit def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = s match {
- case JSetWrapper(wrapped) => wrapped
- case _ => new MutableSetWrapper(s)
- }
-
@deprecated("use mutableSetAsJavaSet instead", "2.9.0")
def asJavaSet[A](s : mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet[A](s)
- /**
- * Implicitly converts a Scala Set to a Java Set.
- * The returned Java Set is backed by the provided Scala
- * Set and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Set was previously obtained from an implicit or
- * explicit call of asSet(java.util.Set) then the original
- * Java Set will be returned.
- *
- * @param s The Set to be converted.
- * @return A Java Set view of the argument.
- */
- implicit def setAsJavaSet[A](s: Set[A]): ju.Set[A] = s match {
- case JSetWrapper(wrapped) => wrapped
- case _ => new SetWrapper(s)
- }
-
@deprecated("use setAsJavaSet instead", "2.9.0")
def asJavaSet[A](s: Set[A]): ju.Set[A] = setAsJavaSet[A](s)
- /**
- * Implicitly converts a Scala mutable Map to a Java Map.
- * The returned Java Map is backed by the provided Scala
- * Map and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala Map was previously obtained from an implicit or
- * explicit call of `asMap(java.util.Map)` then the original
- * Java Map will be returned.
- *
- * @param m The Map to be converted.
- * @return A Java Map view of the argument.
- */
- implicit def mutableMapAsJavaMap[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = m match {
- //case JConcurrentMapWrapper(wrapped) => wrapped
- case JMapWrapper(wrapped) => wrapped
- case _ => new MutableMapWrapper(m)
- }
-
@deprecated("use mutableMapAsJavaMap instead", "2.9.0")
def asJavaMap[A, B](m : mutable.Map[A, B]): ju.Map[A, B] = mutableMapAsJavaMap[A, B](m)
- /**
- * Implicitly converts a Scala mutable `Map` to a Java `Dictionary`.
- *
- * The returned Java `Dictionary` is backed by the provided Scala
- * `Dictionary` and any side-effects of using it via the Java interface
- * will be visible via the Scala interface and vice versa.
- *
- * If the Scala `Dictionary` was previously obtained from an implicit or
- * explicit call of `asMap(java.util.Dictionary)` then the original
- * Java Dictionary will be returned.
- *
- * @param m The `Map` to be converted.
- * @return A Java `Dictionary` view of the argument.
- */
- implicit def asJavaDictionary[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = m match {
- //case JConcurrentMapWrapper(wrapped) => wrapped
- case JDictionaryWrapper(wrapped) => wrapped
- case _ => new DictionaryWrapper(m)
- }
-
- /**
- * Implicitly converts a Scala `Map` to a Java `Map`.
- *
- * The returned Java `Map` is backed by the provided Scala `Map` and
- * any side-effects of using it via the Java interface will be visible
- * via the Scala interface and vice versa.
- *
- * If the Scala `Map` was previously obtained from an implicit or
- * explicit call of `asMap(java.util.Map)` then the original
- * Java `Map` will be returned.
- *
- * @param m The `Map` to be converted.
- * @return A Java `Map` view of the argument.
- */
- implicit def mapAsJavaMap[A, B](m: Map[A, B]): ju.Map[A, B] = m match {
- //case JConcurrentMapWrapper(wrapped) => wrapped
- case JMapWrapper(wrapped) => wrapped.asInstanceOf[ju.Map[A, B]]
- case _ => new MapWrapper(m)
- }
-
@deprecated("use mapAsJavaMap instead", "2.9.0")
def asJavaMap[A, B](m : Map[A, B]): ju.Map[A, B] = mapAsJavaMap[A, B](m)
- /**
- * Implicitly converts a Scala mutable `ConcurrentMap` to a Java
- * `ConcurrentMap`.
- *
- * The returned Java `ConcurrentMap` is backed by the provided Scala
- * `ConcurrentMap` and any side-effects of using it via the Java interface
- * will be visible via the Scala interface and vice versa.
- *
- * If the Scala `ConcurrentMap` was previously obtained from an implicit or
- * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)`
- * then the original Java ConcurrentMap will be returned.
- *
- * @param m The `ConcurrentMap` to be converted.
- * @return A Java `ConcurrentMap` view of the argument.
- */
- implicit def asJavaConcurrentMap[A, B](m: mutable.ConcurrentMap[A, B]): juc.ConcurrentMap[A, B] = m match {
- case JConcurrentMapWrapper(wrapped) => wrapped
- case _ => new ConcurrentMapWrapper(m)
- }
-
- // Java => Scala
-
- /**
- * Implicitly converts a Java `Iterator` to a Scala `Iterator`.
- *
- * The returned Scala `Iterator` is backed by the provided Java `Iterator`
- * and any side-effects of using it via the Scala interface will be visible
- * via the Java interface and vice versa.
- *
- * If the Java `Iterator` was previously obtained from an implicit or
- * explicit call of `asIterator(scala.collection.Iterator)` then the
- * original Scala `Iterator` will be returned.
- *
- * @param i The `Iterator` to be converted.
- * @return A Scala `Iterator` view of the argument.
- */
- implicit def asScalaIterator[A](it: ju.Iterator[A]): Iterator[A] = it match {
- case IteratorWrapper(wrapped) => wrapped
- case _ => JIteratorWrapper(it)
- }
-
- /**
- * Implicitly converts a Java Enumeration to a Scala Iterator.
- * The returned Scala Iterator is backed by the provided Java
- * Enumeration and any side-effects of using it via the Scala interface will
- * be visible via the Java interface and vice versa.
- *
- * If the Java Enumeration was previously obtained from an implicit or
- * explicit call of `enumerationAsScalaIterator(scala.collection.Iterator)`
- * then the original Scala Iterator will be returned.
- *
- * @param i The Enumeration to be converted.
- * @return A Scala Iterator view of the argument.
- */
- implicit def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = i match {
- case IteratorWrapper(wrapped) => wrapped
- case _ => JEnumerationWrapper(i)
- }
-
- /**
- * Implicitly converts a Java `Iterable` to a Scala `Iterable`.
- *
- * The returned Scala `Iterable` is backed by the provided Java `Iterable`
- * and any side-effects of using it via the Scala interface will be visible
- * via the Java interface and vice versa.
- *
- * If the Java `Iterable` was previously obtained from an implicit or
- * explicit call of `iterableAsScalaIterable(scala.collection.Iterable)`
- * then the original Scala Iterable will be returned.
- *
- * @param i The Iterable to be converted.
- * @return A Scala Iterable view of the argument.
- */
- implicit def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = i match {
- case IterableWrapper(wrapped) => wrapped
- case _ => JIterableWrapper(i)
- }
-
@deprecated("use iterableAsScalaIterable instead", "2.9.0")
def asScalaIterable[A](i : jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable[A](i)
- /**
- * Implicitly converts a Java `Collection` to an Scala `Iterable`.
- *
- * If the Java `Collection` was previously obtained from an implicit or
- * explicit call of `collectionAsScalaIterable(scala.collection.SizedIterable)`
- * then the original Scala `Iterable` will be returned.
- *
- * @param i The Collection to be converted.
- * @return A Scala Iterable view of the argument.
- */
- implicit def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = i match {
- case IterableWrapper(wrapped) => wrapped
- case _ => JCollectionWrapper(i)
- }
@deprecated("use collectionAsScalaIterable instead", "2.9.0")
def asScalaIterable[A](i : ju.Collection[A]): Iterable[A] = collectionAsScalaIterable[A](i)
- /**
- * Implicitly converts a Java `List` to a Scala mutable `Buffer`.
- *
- * The returned Scala `Buffer` is backed by the provided Java `List`
- * and any side-effects of using it via the Scala interface will
- * be visible via the Java interface and vice versa.
- *
- * If the Java `List` was previously obtained from an implicit or
- * explicit call of `asScalaBuffer(scala.collection.mutable.Buffer)`
- * then the original Scala `Buffer` will be returned.
- *
- * @param l The `List` to be converted.
- * @return A Scala mutable `Buffer` view of the argument.
- */
- implicit def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = l match {
- case MutableBufferWrapper(wrapped) => wrapped
- case _ =>new JListWrapper(l)
- }
-
- /**
- * Implicitly converts a Java Set to a Scala mutable Set.
- * The returned Scala Set is backed by the provided Java
- * Set and any side-effects of using it via the Scala interface will
- * be visible via the Java interface and vice versa.
- *
- * If the Java Set was previously obtained from an implicit or
- * explicit call of `asScalaSet(scala.collection.mutable.Set)` then
- * the original Scala Set will be returned.
- *
- * @param s The Set to be converted.
- * @return A Scala mutable Set view of the argument.
- */
- implicit def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = s match {
- case MutableSetWrapper(wrapped) => wrapped
- case _ =>new JSetWrapper(s)
- }
-
- /**
- * Implicitly converts a Java `Map` to a Scala mutable `Map`.
- *
- * The returned Scala `Map` is backed by the provided Java `Map` and any
- * side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * If the Java `Map` was previously obtained from an implicit or
- * explicit call of `mapAsScalaMap(scala.collection.mutable.Map)` then
- * the original Scala Map will be returned.
- *
- * @param m The Map to be converted.
- * @return A Scala mutable Map view of the argument.
- */
- implicit def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = m match {
- //case ConcurrentMapWrapper(wrapped) => wrapped
- case MutableMapWrapper(wrapped) => wrapped
- case _ => new JMapWrapper(m)
- }
-
@deprecated("use mapAsScalaMap instead", "2.9.0")
def asScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap[A, B](m)
- /**
- * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap.
- * The returned Scala ConcurrentMap is backed by the provided Java
- * ConcurrentMap and any side-effects of using it via the Scala interface will
- * be visible via the Java interface and vice versa.
- *
- * If the Java ConcurrentMap was previously obtained from an implicit or
- * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)`
- * then the original Scala ConcurrentMap will be returned.
- *
- * @param m The ConcurrentMap to be converted.
- * @return A Scala mutable ConcurrentMap view of the argument.
- */
- implicit def asScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = m match {
- case cmw: ConcurrentMapWrapper[a, b] => cmw.underlying
- case _ => new JConcurrentMapWrapper(m)
- }
-
- /**
- * Implicitly converts a Java `Dictionary` to a Scala mutable
- * `Map[String, String]`.
- *
- * The returned Scala `Map[String, String]` is backed by the provided Java
- * `Dictionary` and any side-effects of using it via the Scala interface
- * will be visible via the Java interface and vice versa.
- *
- * @param m The Dictionary to be converted.
- * @return A Scala mutable Map[String, String] view of the argument.
- */
- implicit def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = p match {
- case DictionaryWrapper(wrapped) => wrapped
- case _ => new JDictionaryWrapper(p)
- }
-
- /**
- * Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`.
- *
- * The returned Scala `Map[String, String]` is backed by the provided Java
- * `Properties` and any side-effects of using it via the Scala interface
- * will be visible via the Java interface and vice versa.
- *
- * @param m The Properties to be converted.
- * @return A Scala mutable Map[String, String] view of the argument.
- */
- implicit def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = p match {
- case _ => new JPropertiesWrapper(p)
- }
-
@deprecated("use propertiesAsScalaMap instead", "2.9.0")
def asScalaMap(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
+}
- // Private implementations (shared by JavaConverters) ...
-
- trait IterableWrapperTrait[A] extends ju.AbstractCollection[A] {
- val underlying: Iterable[A]
- def size = underlying.size
- override def iterator = IteratorWrapper(underlying.iterator)
- override def isEmpty = underlying.isEmpty
- }
-
- case class IteratorWrapper[A](underlying: Iterator[A])
- extends ju.Iterator[A] with ju.Enumeration[A] {
- def hasNext = underlying.hasNext
- def next() = underlying.next
- def hasMoreElements = underlying.hasNext
- def nextElement() = underlying.next
- def remove() = throw new UnsupportedOperationException
- }
-
- class ToIteratorWrapper[A](underlying : Iterator[A]) {
- def asJava = new IteratorWrapper(underlying)
- }
-
- case class JIteratorWrapper[A](underlying: ju.Iterator[A]) extends AbstractIterator[A] with Iterator[A] {
- def hasNext = underlying.hasNext
- def next() = underlying.next
- }
-
- case class JEnumerationWrapper[A](underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Iterator[A] {
- def hasNext = underlying.hasMoreElements
- def next() = underlying.nextElement
- }
-
- case class IterableWrapper[A](underlying: Iterable[A])
- extends ju.AbstractCollection[A]
- with IterableWrapperTrait[A] { }
-
- case class JIterableWrapper[A](underlying: jl.Iterable[A]) extends AbstractIterable[A] with Iterable[A] {
- def iterator = underlying.iterator
- def newBuilder[B] = new mutable.ArrayBuffer[B]
- }
-
- case class JCollectionWrapper[A](underlying: ju.Collection[A]) extends AbstractIterable[A] with Iterable[A] {
- def iterator = underlying.iterator
- override def size = underlying.size
- override def isEmpty = underlying.isEmpty
- def newBuilder[B] = new mutable.ArrayBuffer[B]
- }
-
- case class SeqWrapper[A](underlying: Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] {
- def get(i: Int) = underlying(i)
- }
-
- case class MutableSeqWrapper[A](underlying: mutable.Seq[A])
- extends ju.AbstractList[A] with IterableWrapperTrait[A] {
- def get(i: Int) = underlying(i)
- override def set(i: Int, elem: A) = {
- val p = underlying(i)
- underlying(i) = elem
- p
- }
- }
-
- case class MutableBufferWrapper[A](underlying: mutable.Buffer[A])
- extends ju.AbstractList[A] with IterableWrapperTrait[A] {
- def get(i: Int) = underlying(i)
- override def set(i: Int, elem: A) = { val p = underlying(i); underlying(i) = elem; p }
- override def add(elem: A) = { underlying append elem; true }
- override def remove(i: Int) = underlying remove i
- }
-
- case class JListWrapper[A](val underlying: ju.List[A]) extends mutable.AbstractBuffer[A] with mutable.Buffer[A] {
- def length = underlying.size
- override def isEmpty = underlying.isEmpty
- override def iterator: Iterator[A] = underlying.iterator
- def apply(i: Int) = underlying.get(i)
- def update(i: Int, elem: A) = underlying.set(i, elem)
- def +=:(elem: A) = { underlying.subList(0, 0) add elem; this }
- def +=(elem: A): this.type = { underlying add elem; this }
- def insertAll(i: Int, elems: Traversable[A]) = {
- val ins = underlying.subList(0, i)
- elems.seq.foreach(ins.add(_))
- }
- def remove(i: Int) = underlying.remove(i)
- def clear() = underlying.clear()
- def result = this
- }
-
- class SetWrapper[A](underlying: Set[A]) extends ju.AbstractSet[A] {
- self =>
- def size = underlying.size
- def iterator = new ju.Iterator[A] {
- val ui = underlying.iterator
- var prev: Option[A] = None
- def hasNext = ui.hasNext
- def next = { val e = ui.next; prev = Some(e); e }
- def remove = prev match {
- case Some(e) =>
- underlying match {
- case ms: mutable.Set[a] =>
- ms remove e
- prev = None
- case _ =>
- throw new UnsupportedOperationException("remove")
- }
- case _ =>
- throw new IllegalStateException("next must be called at least once before remove")
- }
- }
- }
-
- case class MutableSetWrapper[A](underlying: mutable.Set[A]) extends SetWrapper[A](underlying) {
- override def add(elem: A) = {
- val sz = underlying.size
- underlying += elem
- sz < underlying.size
- }
- override def remove(elem: AnyRef) =
- try underlying remove elem.asInstanceOf[A]
- catch { case ex: ClassCastException => false }
- override def clear() = underlying.clear()
- }
-
- case class JSetWrapper[A](underlying: ju.Set[A])
- extends mutable.AbstractSet[A]
- with mutable.Set[A]
- with mutable.SetLike[A, JSetWrapper[A]] {
-
- override def size = underlying.size
-
- def iterator = underlying.iterator
-
- def contains(elem: A): Boolean = underlying.contains(elem)
-
- def +=(elem: A): this.type = { underlying add elem; this }
- def -=(elem: A): this.type = { underlying remove elem; this }
-
- override def add(elem: A): Boolean = underlying add elem
- override def remove(elem: A): Boolean = underlying remove elem
- override def clear() = underlying.clear()
-
- override def empty = JSetWrapper(new ju.HashSet[A])
- }
-
- class MapWrapper[A, B](underlying: Map[A, B]) extends ju.AbstractMap[A, B] { self =>
- override def size = underlying.size
-
- override def get(key: AnyRef): B = try {
- underlying get key.asInstanceOf[A] match {
- case None => null.asInstanceOf[B]
- case Some(v) => v
- }
- } catch {
- case ex: ClassCastException => null.asInstanceOf[B]
- }
-
- override def entrySet: ju.Set[ju.Map.Entry[A, B]] = new ju.AbstractSet[ju.Map.Entry[A, B]] {
- def size = self.size
-
- def iterator = new ju.Iterator[ju.Map.Entry[A, B]] {
- val ui = underlying.iterator
- var prev : Option[A] = None
-
- def hasNext = ui.hasNext
-
- def next() = {
- val (k, v) = ui.next
- prev = Some(k)
- new ju.Map.Entry[A, B] {
- def getKey = k
- def getValue = v
- def setValue(v1 : B) = self.put(k, v1)
- override def hashCode = k.hashCode + v.hashCode
- override def equals(other: Any) = other match {
- case e: ju.Map.Entry[_, _] => k == e.getKey && v == e.getValue
- case _ => false
- }
- }
- }
-
- def remove() {
- prev match {
- case Some(k) =>
- underlying match {
- case mm: mutable.Map[a, _] =>
- mm remove k
- prev = None
- case _ =>
- throw new UnsupportedOperationException("remove")
- }
- case _ =>
- throw new IllegalStateException("next must be called at least once before remove")
- }
- }
- }
- }
- }
-
- case class MutableMapWrapper[A, B](underlying: mutable.Map[A, B])
- extends MapWrapper[A, B](underlying) {
- override def put(k: A, v: B) = underlying.put(k, v) match {
- case Some(v1) => v1
- case None => null.asInstanceOf[B]
- }
-
- override def remove(k: AnyRef): B = try {
- underlying remove k.asInstanceOf[A] match {
- case None => null.asInstanceOf[B]
- case Some(v) => v
- }
- } catch {
- case ex: ClassCastException => null.asInstanceOf[B]
- }
-
- override def clear() = underlying.clear()
- }
-
- trait JMapWrapperLike[A, B, +Repr <: mutable.MapLike[A, B, Repr] with mutable.Map[A, B]]
- extends mutable.Map[A, B] with mutable.MapLike[A, B, Repr] {
- def underlying: ju.Map[A, B]
-
- override def size = underlying.size
-
- def get(k: A) = {
- val v = underlying get k
- if (v != null)
- Some(v)
- else if (underlying containsKey k)
- Some(null.asInstanceOf[B])
- else
- None
- }
-
- def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this }
- def -=(key: A): this.type = { underlying remove key; this }
-
- override def put(k: A, v: B): Option[B] = {
- val r = underlying.put(k, v)
- if (r != null) Some(r) else None
- }
-
- override def update(k: A, v: B) { underlying.put(k, v) }
-
- override def remove(k: A): Option[B] = {
- val r = underlying remove k
- if (r != null) Some(r) else None
- }
-
- def iterator: Iterator[(A, B)] = new AbstractIterator[(A, B)] {
- val ui = underlying.entrySet.iterator
- def hasNext = ui.hasNext
- def next() = { val e = ui.next(); (e.getKey, e.getValue) }
- }
-
- override def clear() = underlying.clear()
-
- override def empty: Repr = null.asInstanceOf[Repr]
- }
-
- case class JMapWrapper[A, B](val underlying : ju.Map[A, B])
- extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JMapWrapper[A, B]] {
- override def empty = JMapWrapper(new ju.HashMap[A, B])
- }
-
- class ConcurrentMapWrapper[A, B](override val underlying: mutable.ConcurrentMap[A, B])
- extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] {
-
- def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match {
- case Some(v) => v
- case None => null.asInstanceOf[B]
- }
-
- def remove(k: AnyRef, v: AnyRef) = try {
- underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B])
- } catch {
- case ex: ClassCastException =>
- false
- }
-
- def replace(k: A, v: B): B = underlying.replace(k, v) match {
- case Some(v) => v
- case None => null.asInstanceOf[B]
- }
-
- def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
- }
-
- case class JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B])
- extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with mutable.ConcurrentMap[A, B] {
- override def get(k: A) = {
- val v = underlying get k
- if (v != null) Some(v)
- else None
- }
-
- override def empty = new JConcurrentMapWrapper(new juc.ConcurrentHashMap[A, B])
-
- def putIfAbsent(k: A, v: B): Option[B] = {
- val r = underlying.putIfAbsent(k, v)
- if (r != null) Some(r) else None
- }
-
- def remove(k: A, v: B): Boolean = underlying.remove(k, v)
-
- def replace(k: A, v: B): Option[B] = {
- val prev = underlying.replace(k, v)
- if (prev != null) Some(prev) else None
- }
-
- def replace(k: A, oldvalue: B, newvalue: B): Boolean =
- underlying.replace(k, oldvalue, newvalue)
- }
-
- case class DictionaryWrapper[A, B](underlying: mutable.Map[A, B])
- extends ju.Dictionary[A, B] {
- def size: Int = underlying.size
- def isEmpty: Boolean = underlying.isEmpty
- def keys: ju.Enumeration[A] = asJavaEnumeration(underlying.keysIterator)
- def elements: ju.Enumeration[B] = asJavaEnumeration(underlying.valuesIterator)
- def get(key: AnyRef) = try {
- underlying get key.asInstanceOf[A] match {
- case None => null.asInstanceOf[B]
- case Some(v) => v
- }
- } catch {
- case ex: ClassCastException => null.asInstanceOf[B]
- }
- def put(key: A, value: B): B = underlying.put(key, value) match {
- case Some(v) => v
- case None => null.asInstanceOf[B]
- }
- override def remove(key: AnyRef) = try {
- underlying remove key.asInstanceOf[A] match {
- case None => null.asInstanceOf[B]
- case Some(v) => v
- }
- } catch {
- case ex: ClassCastException => null.asInstanceOf[B]
- }
- }
-
- case class JDictionaryWrapper[A, B](underlying: ju.Dictionary[A, B])
- extends mutable.AbstractMap[A, B] with mutable.Map[A, B] {
- override def size: Int = underlying.size
-
- def get(k: A) = {
- val v = underlying get k
- if (v != null) Some(v) else None
- }
-
- def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this }
- def -=(key: A): this.type = { underlying remove key; this }
-
- override def put(k: A, v: B): Option[B] = {
- val r = underlying.put(k, v)
- if (r != null) Some(r) else None
- }
-
- override def update(k: A, v: B) { underlying.put(k, v) }
-
- override def remove(k: A): Option[B] = {
- val r = underlying remove k
- if (r != null) Some(r) else None
- }
-
- def iterator = enumerationAsScalaIterator(underlying.keys) map (k => (k, underlying get k))
-
- override def clear() = underlying.clear()
- }
-
- case class JPropertiesWrapper(underlying: ju.Properties)
- extends mutable.AbstractMap[String, String]
- with mutable.Map[String, String]
- with mutable.MapLike[String, String, JPropertiesWrapper] {
-
- override def size = underlying.size
-
- def get(k: String) = {
- val v = underlying get k
- if (v != null) Some(v.asInstanceOf[String]) else None
- }
-
- def +=(kv: (String, String)): this.type = { underlying.put(kv._1, kv._2); this }
- def -=(key: String): this.type = { underlying remove key; this }
-
- override def put(k: String, v: String): Option[String] = {
- val r = underlying.put(k, v)
- if (r != null) Some(r.asInstanceOf[String]) else None
- }
-
- override def update(k: String, v: String) { underlying.put(k, v) }
-
- override def remove(k: String): Option[String] = {
- val r = underlying remove k
- if (r != null) Some(r.asInstanceOf[String]) else None
- }
-
- def iterator: Iterator[(String, String)] = new AbstractIterator[(String, String)] {
- val ui = underlying.entrySet.iterator
- def hasNext = ui.hasNext
- def next() = {
- val e = ui.next()
- (e.getKey.asInstanceOf[String], e.getValue.asInstanceOf[String])
- }
- }
-
- override def clear() = underlying.clear()
-
- override def empty = JPropertiesWrapper(new ju.Properties)
-
- def getProperty(key: String) = underlying.getProperty(key)
-
- def getProperty(key: String, defaultValue: String) =
- underlying.getProperty(key, defaultValue)
- def setProperty(key: String, value: String) =
- underlying.setProperty(key, value)
- }
-}
diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala
index d213e60112..f8a9466caf 100755
--- a/src/library/scala/collection/JavaConverters.scala
+++ b/src/library/scala/collection/JavaConverters.scala
@@ -8,7 +8,15 @@
package scala.collection
-/** A collection of decorators that allow to convert between
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+import convert._
+
+// TODO: I cleaned all this documentation up in JavaConversions, but the
+// documentation in here is basically the pre-cleaned-up version with minor
+// additions. Would be nice to have in one place.
+
+
+/** A collection of decorators that allow converting between
* Scala and Java collections using `asScala` and `asJava` methods.
*
* The following conversions are supported via `asJava`, `asScala`
@@ -48,494 +56,48 @@ package scala.collection
* @author Martin Odersky
* @since 2.8.1
*/
-
-trait JavaConverters {
- import java.{ lang => jl, util => ju }
- import java.util.{ concurrent => juc }
- import JavaConversions._
-
- // TODO: I cleaned all this documentation up in JavaConversions, but the
- // documentation in here is basically the pre-cleaned-up version with minor
- // additions. Would be nice to have in one place.
-
- // Conversion decorator classes
-
- /** Generic class containing the `asJava` converter method */
- class AsJava[C](op: => C) {
- /** Converts a Scala collection to the corresponding Java collection */
- def asJava: C = op
- }
-
- /** Generic class containing the `asScala` converter method */
- class AsScala[C](op: => C) {
- /** Converts a Java collection to the corresponding Scala collection */
- def asScala: C = op
- }
-
- /** Generic class containing the `asJavaCollection` converter method */
- class AsJavaCollection[A](i: Iterable[A]) {
- /** Converts a Scala `Iterable` to a Java `Collection` */
- def asJavaCollection: ju.Collection[A] = JavaConversions.asJavaCollection(i)
- }
-
- /** Generic class containing the `asJavaEnumeration` converter method */
- class AsJavaEnumeration[A](i: Iterator[A]) {
- /** Converts a Scala `Iterator` to a Java `Enumeration` */
- def asJavaEnumeration: ju.Enumeration[A] = JavaConversions.asJavaEnumeration(i)
- }
-
- /** Generic class containing the `asJavaDictionary` converter method */
- class AsJavaDictionary[A, B](m : mutable.Map[A, B]) {
- /** Converts a Scala `Map` to a Java `Dictionary` */
- def asJavaDictionary: ju.Dictionary[A, B] = JavaConversions.asJavaDictionary(m)
- }
-
- // Scala => Java
-
- /**
- * Adds an `asJava` method that implicitly converts a Scala `Iterator` to a
- * Java `Iterator`. The returned Java `Iterator` is backed by the provided Scala
- * `Iterator` and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala `Iterator` was previously obtained from an implicit or explicit
- * call of `asIterator(java.util.Iterator)` then the original Java `Iterator`
- * will be returned by the `asJava` method.
- *
- * @param i The `Iterator` to be converted.
- * @return An object with an `asJava` method that returns a Java `Iterator` view of the argument.
- */
- implicit def asJavaIteratorConverter[A](i : Iterator[A]): AsJava[ju.Iterator[A]] =
- new AsJava(asJavaIterator(i))
-
- /**
- * Adds an `asJavaEnumeration` method that implicitly converts a Scala
- * `Iterator` to a Java `Enumeration`. The returned Java `Enumeration` is
- * backed by the provided Scala `Iterator` and any side-effects of using
- * it via the Java interface will be visible via the Scala interface and
- * vice versa.
- *
- * If the Scala `Iterator` was previously obtained from an implicit or
- * explicit call of `asIterator(java.util.Enumeration)` then the
- * original Java `Enumeration` will be returned.
- *
- * @param i The `Iterator` to be converted.
- * @return An object with an `asJavaEnumeration` method that returns a Java
- * `Enumeration` view of the argument.
- */
- implicit def asJavaEnumerationConverter[A](i : Iterator[A]): AsJavaEnumeration[A] =
- new AsJavaEnumeration(i)
-
- /**
- * Adds an `asJava` method that implicitly converts a Scala `Iterable` to
- * a Java `Iterable`.
- *
- * The returned Java `Iterable` is backed by the provided Scala `Iterable`
- * and any side-effects of using it via the Java interface will be visible
- * via the Scala interface and vice versa.
- *
- * If the Scala `Iterable` was previously obtained from an implicit or
- * explicit call of `asIterable(java.lang.Iterable)` then the original
- * Java `Iterable` will be returned.
- *
- * @param i The `Iterable` to be converted.
- * @return An object with an `asJavaCollection` method that returns a Java
- * `Iterable` view of the argument.
- */
- implicit def asJavaIterableConverter[A](i : Iterable[A]): AsJava[jl.Iterable[A]] =
- new AsJava(asJavaIterable(i))
-
- /**
- * Adds an `asJavaCollection` method that implicitly converts a Scala
- * `Iterable` to an immutable Java `Collection`.
- *
- * If the Scala `Iterable` was previously obtained from an implicit or
- * explicit call of `asSizedIterable(java.util.Collection)` then the
- * original Java `Collection` will be returned.
- *
- * @param i The `SizedIterable` to be converted.
- * @return An object with an `asJava` method that returns a Java
- * `Collection` view of the argument.
- */
- implicit def asJavaCollectionConverter[A](i : Iterable[A]): AsJavaCollection[A] =
- new AsJavaCollection(i)
-
- /**
- * Adds an `asJava` method that implicitly converts a Scala mutable `Buffer`
- * to a Java `List`.
- *
- * The returned Java `List` is backed by the provided Scala `Buffer` and any
- * side-effects of using it via the Java interface will be visible via the
- * Scala interface and vice versa.
- *
- * If the Scala `Buffer` was previously obtained from an implicit or explicit
- * call of `asBuffer(java.util.List)` then the original Java `List` will be
- * returned.
- *
- * @param b The `Buffer` to be converted.
- * @return An object with an `asJava` method that returns a Java `List` view
- * of the argument.
- */
- implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] =
- new AsJava(bufferAsJavaList(b))
-
- /**
- * Adds an `asJava` method that implicitly converts a Scala mutable `Seq`
- * to a Java `List`.
- *
- * The returned Java `List` is backed by the provided Scala `Seq` and any
- * side-effects of using it via the Java interface will be visible via the
- * Scala interface and vice versa.
- *
- * If the Scala `Seq` was previously obtained from an implicit or explicit
- * call of `asSeq(java.util.List)` then the original Java `List` will be
- * returned.
- *
- * @param b The `Seq` to be converted.
- * @return An object with an `asJava` method that returns a Java `List`
- * view of the argument.
- */
- implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] =
- new AsJava(mutableSeqAsJavaList(b))
-
- /**
- * Adds an `asJava` method that implicitly converts a Scala `Seq` to a
- * Java `List`.
- *
- * The returned Java `List` is backed by the provided Scala `Seq` and any
- * side-effects of using it via the Java interface will be visible via the
- * Scala interface and vice versa.
- *
- * If the Scala `Seq` was previously obtained from an implicit or explicit
- * call of `asSeq(java.util.List)` then the original Java `List` will be
- * returned.
- *
- * @param b The `Seq` to be converted.
- * @return An object with an `asJava` method that returns a Java `List`
- * view of the argument.
- */
- implicit def seqAsJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] =
- new AsJava(seqAsJavaList(b))
+object JavaConverters extends DecorateAsJava with DecorateAsScala {
+ @deprecated("Don't access these decorators directly.", "2.10.0")
+ type AsJava[A] = Decorators.AsJava[A]
+ @deprecated("Don't access these decorators directly.", "2.10.0")
+ type AsScala[A] = Decorators.AsScala[A]
+ @deprecated("Don't access these decorators directly.", "2.10.0")
+ type AsJavaCollection[A] = Decorators.AsJavaCollection[A]
+ @deprecated("Don't access these decorators directly.", "2.10.0")
+ type AsJavaEnumeration[A] = Decorators.AsJavaEnumeration[A]
+ @deprecated("Don't access these decorators directly.", "2.10.0")
+ type AsJavaDictionary[A, B] = Decorators.AsJavaDictionary[A, B]
@deprecated("Use bufferAsJavaListConverter instead", "2.9.0")
def asJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] = bufferAsJavaListConverter(b)
+
@deprecated("Use mutableSeqAsJavaListConverter instead", "2.9.0")
def asJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] = mutableSeqAsJavaListConverter(b)
+
@deprecated("Use seqAsJavaListConverter instead", "2.9.0")
def asJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] = seqAsJavaListConverter(b)
- /**
- * Adds an `asJava` method that implicitly converts a Scala mutable `Set`>
- * to a Java `Set`.
- *
- * The returned Java `Set` is backed by the provided Scala `Set` and any
- * side-effects of using it via the Java interface will be visible via
- * the Scala interface and vice versa.
- *
- * If the Scala `Set` was previously obtained from an implicit or explicit
- * call of `asSet(java.util.Set)` then the original Java `Set` will be
- * returned.
- *
- * @param s The `Set` to be converted.
- * @return An object with an `asJava` method that returns a Java `Set` view
- * of the argument.
- */
- implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] =
- new AsJava(mutableSetAsJavaSet(s))
-
@deprecated("Use mutableSetAsJavaSetConverter instead", "2.9.0")
def asJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] = mutableSetAsJavaSetConverter(s)
- /**
- * Adds an `asJava` method that implicitly converts a Scala `Set` to a
- * Java `Set`.
- *
- * The returned Java `Set` is backed by the provided Scala `Set` and any
- * side-effects of using it via the Java interface will be visible via
- * the Scala interface and vice versa.
- *
- * If the Scala `Set` was previously obtained from an implicit or explicit
- * call of `asSet(java.util.Set)` then the original Java `Set` will be
- * returned.
- *
- * @param s The `Set` to be converted.
- * @return An object with an `asJava` method that returns a Java `Set` view
- * of the argument.
- */
- implicit def setAsJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] =
- new AsJava(setAsJavaSet(s))
-
@deprecated("Use setAsJavaSetConverter instead", "2.9.0")
def asJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] = setAsJavaSetConverter(s)
- /**
- * Adds an `asJava` method that implicitly converts a Scala mutable `Map`
- * to a Java `Map`.
- *
- * The returned Java `Map` is backed by the provided Scala `Map` and any
- * side-effects of using it via the Java interface will be visible via the
- * Scala interface and vice versa.
- *
- * If the Scala `Map` was previously obtained from an implicit or explicit
- * call of `asMap(java.util.Map)` then the original Java `Map` will be
- * returned.
- *
- * @param m The `Map` to be converted.
- * @return An object with an `asJava` method that returns a Java `Map` view
- * of the argument.
- */
- implicit def mutableMapAsJavaMapConverter[A, B](m : mutable.Map[A, B]): AsJava[ju.Map[A, B]] =
- new AsJava(mutableMapAsJavaMap(m))
-
@deprecated("use mutableMapAsJavaMapConverter instead", "2.9.0")
def asJavaMapConverter[A, B](m : mutable.Map[A, B]): AsJava[ju.Map[A, B]] = mutableMapAsJavaMapConverter(m)
- /**
- * Adds an `asJavaDictionary` method that implicitly converts a Scala
- * mutable `Map` to a Java `Dictionary`.
- *
- * The returned Java `Dictionary` is backed by the provided Scala
- * `Dictionary` and any side-effects of using it via the Java interface
- * will be visible via the Scala interface and vice versa.
- *
- * If the Scala `Dictionary` was previously obtained from an implicit or
- * explicit call of `asMap(java.util.Dictionary)` then the original
- * Java `Dictionary` will be returned.
- *
- * @param m The `Map` to be converted.
- * @return An object with an `asJavaDictionary` method that returns a
- * Java `Dictionary` view of the argument.
- */
- implicit def asJavaDictionaryConverter[A, B](m : mutable.Map[A, B]): AsJavaDictionary[A, B] =
- new AsJavaDictionary(m)
-
- /**
- * Adds an `asJava` method that implicitly converts a Scala `Map` to
- * a Java `Map`.
- *
- * The returned Java `Map` is backed by the provided Scala `Map` and any
- * side-effects of using it via the Java interface will be visible via
- * the Scala interface and vice versa.
- *
- * If the Scala `Map` was previously obtained from an implicit or explicit
- * call of `asMap(java.util.Map)` then the original Java `Map` will be
- * returned.
- *
- * @param m The `Map` to be converted.
- * @return An object with an `asJava` method that returns a Java `Map` view
- * of the argument.
- */
- implicit def mapAsJavaMapConverter[A, B](m : Map[A, B]): AsJava[ju.Map[A, B]] =
- new AsJava(mapAsJavaMap(m))
-
@deprecated("Use mapAsJavaMapConverter instead", "2.9.0")
def asJavaMapConverter[A, B](m : Map[A, B]): AsJava[ju.Map[A, B]] = mapAsJavaMapConverter(m)
- /**
- * Adds an `asJava` method that implicitly converts a Scala mutable
- * `ConcurrentMap` to a Java `ConcurrentMap`.
- *
- * The returned Java `ConcurrentMap` is backed by the provided Scala
- * `ConcurrentMap` and any side-effects of using it via the Java interface
- * will be visible via the Scala interface and vice versa.
- *
- * If the Scala `ConcurrentMap` was previously obtained from an implicit or
- * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)`
- * then the original Java `ConcurrentMap` will be returned.
- *
- * @param m The `ConcurrentMap` to be converted.
- * @return An object with an `asJava` method that returns a Java
- * `ConcurrentMap` view of the argument.
- */
- implicit def asJavaConcurrentMapConverter[A, B](m: mutable.ConcurrentMap[A, B]): AsJava[juc.ConcurrentMap[A, B]] =
- new AsJava(asJavaConcurrentMap(m))
-
- /**
- * Adds an `asScala` method that implicitly converts a Java `Iterator` to
- * a Scala `Iterator`.
- *
- * The returned Scala `Iterator` is backed by the provided Java `Iterator`
- * and any side-effects of using it via the Scala interface will be visible
- * via the Java interface and vice versa.
- *
- * If the Java `Iterator` was previously obtained from an implicit or
- * explicit call of `asIterator(scala.collection.Iterator)` then the
- * original Scala `Iterator` will be returned.
- *
- * @param i The `Iterator` to be converted.
- * @return An object with an `asScala` method that returns a Scala
- * `Iterator` view of the argument.
- */
- implicit def asScalaIteratorConverter[A](i : ju.Iterator[A]): AsScala[Iterator[A]] =
- new AsScala(asScalaIterator(i))
-
- /**
- * Adds an `asScala` method that implicitly converts a Java `Enumeration`
- * to a Scala `Iterator`.
- *
- * The returned Scala `Iterator` is backed by the provided Java
- * `Enumeration` and any side-effects of using it via the Scala interface
- * will be visible via the Java interface and vice versa.
- *
- * If the Java `Enumeration` was previously obtained from an implicit or
- * explicit call of `asEnumeration(scala.collection.Iterator)` then the
- * original Scala `Iterator` will be returned.
- *
- * @param i The `Enumeration` to be converted.
- * @return An object with an `asScala` method that returns a Scala
- * `Iterator` view of the argument.
- */
- implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A]): AsScala[Iterator[A]] =
- new AsScala(enumerationAsScalaIterator(i))
-
- /**
- * Adds an `asScala` method that implicitly converts a Java `Iterable` to
- * a Scala `Iterable`.
- *
- * The returned Scala `Iterable` is backed by the provided Java `Iterable`
- * and any side-effects of using it via the Scala interface will be visible
- * via the Java interface and vice versa.
- *
- * If the Java `Iterable` was previously obtained from an implicit or
- * explicit call of `asIterable(scala.collection.Iterable)` then the original
- * Scala `Iterable` will be returned.
- *
- * @param i The `Iterable` to be converted.
- * @return An object with an `asScala` method that returns a Scala `Iterable`
- * view of the argument.
- */
- implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] =
- new AsScala(iterableAsScalaIterable(i))
-
@deprecated("Use iterableAsScalaIterableConverter instead", "2.9.0")
def asScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] = iterableAsScalaIterableConverter(i)
- /**
- * Adds an `asScala` method that implicitly converts a Java `Collection` to
- * an Scala `Iterable`.
- *
- * If the Java `Collection` was previously obtained from an implicit or
- * explicit call of `asCollection(scala.collection.SizedIterable)` then
- * the original Scala `SizedIterable` will be returned.
- *
- * @param i The `Collection` to be converted.
- * @return An object with an `asScala` method that returns a Scala
- * `SizedIterable` view of the argument.
- */
- implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] =
- new AsScala(collectionAsScalaIterable(i))
-
@deprecated("Use collectionAsScalaIterableConverter instead", "2.9.0")
def asScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] = collectionAsScalaIterableConverter(i)
- /**
- * Adds an `asScala` method that implicitly converts a Java `List` to a
- * Scala mutable `Buffer`.
- *
- * The returned Scala `Buffer` is backed by the provided Java `List` and
- * any side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * If the Java `List` was previously obtained from an implicit or explicit
- * call of `asList(scala.collection.mutable.Buffer)` then the original
- * Scala `Buffer` will be returned.
- *
- * @param l The `List` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Buffer` view of the argument.
- */
- implicit def asScalaBufferConverter[A](l : ju.List[A]): AsScala[mutable.Buffer[A]] =
- new AsScala(asScalaBuffer(l))
-
- /**
- * Adds an `asScala` method that implicitly converts a Java `Set` to a
- * Scala mutable `Set`.
- *
- * The returned Scala `Set` is backed by the provided Java `Set` and any
- * side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * If the Java `Set` was previously obtained from an implicit or explicit
- * call of `asSet(scala.collection.mutable.Set)` then the original
- * Scala `Set` will be returned.
- *
- * @param s The `Set` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Set` view of the argument.
- */
- implicit def asScalaSetConverter[A](s : ju.Set[A]): AsScala[mutable.Set[A]] =
- new AsScala(asScalaSet(s))
-
- /**
- * Adds an `asScala` method that implicitly converts a Java `Map` to a Scala
- * mutable `Map`. The returned Scala `Map` is backed by the provided Java
- * `Map` and any side-effects of using it via the Scala interface will
- * be visible via the Java interface and vice versa.
- *
- * If the Java `Map` was previously obtained from an implicit or explicit
- * call of `asMap(scala.collection.mutable.Map)` then the original
- * Scala `Map` will be returned.
- *
- * @param m The `Map` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Map` view of the argument.
- */
- implicit def mapAsScalaMapConverter[A, B](m : ju.Map[A, B]): AsScala[mutable.Map[A, B]] =
- new AsScala(mapAsScalaMap(m))
-
@deprecated("Use mapAsScalaMapConverter instead", "2.9.0")
def asScalaMapConverter[A, B](m : ju.Map[A, B]): AsScala[mutable.Map[A, B]] = mapAsScalaMapConverter(m)
- /**
- * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap`
- * to a Scala mutable `ConcurrentMap`. The returned Scala `ConcurrentMap` is
- * backed by the provided Java `ConcurrentMap` and any side-effects of using
- * it via the Scala interface will be visible via the Java interface and
- * vice versa.
- *
- * If the Java `ConcurrentMap` was previously obtained from an implicit or
- * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)`
- * then the original Scala `ConcurrentMap` will be returned.
- *
- * @param m The `ConcurrentMap` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `ConcurrentMap` view of the argument.
- */
- implicit def asScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[mutable.ConcurrentMap[A, B]] =
- new AsScala(asScalaConcurrentMap(m))
-
- /**
- * Adds an `asScala` method that implicitly converts a Java `Dictionary`
- * to a Scala mutable `Map[String, String]`. The returned Scala
- * `Map[String, String]` is backed by the provided Java `Dictionary` and
- * any side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * @param m The `Dictionary` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Map[String, String]` view of the argument.
- */
- implicit def dictionaryAsScalaMapConverter[A, B](p: ju.Dictionary[A, B]): AsScala[mutable.Map[A, B]] =
- new AsScala(dictionaryAsScalaMap(p))
-
- /**
- * Adds an `asScala` method that implicitly converts a Java `Properties`
- * to a Scala mutable `Map[String, String]`. The returned Scala
- * `Map[String, String]` is backed by the provided Java `Properties` and
- * any side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * @param m The `Properties` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Map[String, String]` view of the argument.
- */
- implicit def propertiesAsScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] =
- new AsScala(propertiesAsScalaMap(p))
-
@deprecated("Use propertiesAsScalaMapConverter instead", "2.9.0")
- def asScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] =
- propertiesAsScalaMapConverter(p)
-
+ def asScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] = propertiesAsScalaMapConverter(p)
}
-
-object JavaConverters extends JavaConverters \ No newline at end of file
diff --git a/src/library/scala/collection/SeqExtractors.scala b/src/library/scala/collection/SeqExtractors.scala
index cb3cb27f18..de9ff93521 100644
--- a/src/library/scala/collection/SeqExtractors.scala
+++ b/src/library/scala/collection/SeqExtractors.scala
@@ -11,11 +11,13 @@ object +: {
/** An extractor used to init/last deconstruct sequences. */
object :+ {
/** Splits a sequence into init :+ tail.
- * @returns Some(init, tail) if sequence is non-empty.
- * None otherwise.
+ * @return Some(init, tail) if sequence is non-empty. None otherwise.
*/
def unapply[T,Coll <: SeqLike[T, Coll]](
t: Coll with SeqLike[T, Coll]): Option[(Coll, T)] =
if(t.isEmpty) None
else Some(t.init -> t.last)
}
+
+// Dummy to fool ant
+private abstract class SeqExtractors \ No newline at end of file
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index fd1d42d7e9..ced99e897f 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -185,7 +185,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[
private[this] def init() = {
val m = mutable.HashMap[A, Int]()
- val (es, is) = thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2) unzip
+ val (es, is) = (thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2)).unzip
(es.toBuffer, is.toArray)
}
@@ -240,7 +240,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[
val m = mutable.HashMap[A, Int]()
// e => (e, weight(e))
- val (es, is) = thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2) unzip
+ val (es, is) = (thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2)).unzip
val cs = new Array[Int](m.size)
is foreach (i => cs(i) += 1)
val ns = new Array[Int](cs.length)
diff --git a/src/library/scala/collection/SeqProxyLike.scala b/src/library/scala/collection/SeqProxyLike.scala
index ce32ba97c2..3783ef771f 100644
--- a/src/library/scala/collection/SeqProxyLike.scala
+++ b/src/library/scala/collection/SeqProxyLike.scala
@@ -36,7 +36,7 @@ trait SeqProxyLike[+A, +Repr <: SeqLike[A, Repr] with Seq[A]] extends SeqLike[A,
override def indexOf[B >: A](elem: B): Int = self.indexOf(elem)
override def indexOf[B >: A](elem: B, from: Int): Int = self.indexOf(elem, from)
override def lastIndexOf[B >: A](elem: B): Int = self.lastIndexOf(elem)
- override def lastIndexOf[B >: A](elem: B, end: Int): Int = self.lastIndexWhere(elem ==, end)
+ override def lastIndexOf[B >: A](elem: B, end: Int): Int = self.lastIndexWhere(elem == _, end)
override def lastIndexWhere(p: A => Boolean): Int = self.lastIndexWhere(p, length - 1)
override def lastIndexWhere(p: A => Boolean, end: Int): Int = self.lastIndexWhere(p)
override def reverse: Repr = self.reverse
diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala
index 3fba3dfa79..a65be3ffcc 100644
--- a/src/library/scala/collection/Traversable.scala
+++ b/src/library/scala/collection/Traversable.scala
@@ -75,7 +75,7 @@ trait Traversable[+A] extends TraversableLike[A, Traversable[A]]
override def copyToBuffer[B >: A](dest: Buffer[B])
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int)
override def copyToArray[B >: A](xs: Array[B], start: Int)
- override def toArray[B >: A : ClassManifest]: Array[B]
+ override def toArray[B >: A : ArrayTag]: Array[B]
override def toList: List[A]
override def toIterable: Iterable[A]
override def toSeq: Seq[A]
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index 1f5beb5109..a4f36d20c7 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -487,7 +487,7 @@ trait TraversableLike[+A, +Repr] extends Any
if (n <= 0) {
val b = newBuilder
b.sizeHint(this)
- b ++= thisCollection result
+ (b ++= thisCollection).result
}
else sliceWithKnownDelta(n, Int.MaxValue, -n)
@@ -775,6 +775,6 @@ trait TraversableLike[+A, +Repr] extends Any
// A helper for tails and inits.
private def iterateUntilEmpty(f: Traversable[A @uV] => Traversable[A @uV]): Iterator[Repr] = {
val it = Iterator.iterate(thisCollection)(f) takeWhile (x => !x.isEmpty)
- it ++ Iterator(Nil) map (newBuilder ++= _ result)
+ it ++ Iterator(Nil) map (x => (newBuilder ++= x).result)
}
}
diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala
index 62ea692b90..5b5cee7f1b 100644
--- a/src/library/scala/collection/TraversableOnce.scala
+++ b/src/library/scala/collection/TraversableOnce.scala
@@ -10,6 +10,7 @@ package scala.collection
import mutable.{ Buffer, ListBuffer, ArrayBuffer }
import annotation.unchecked.{ uncheckedVariance => uV }
+import language.{implicitConversions, higherKinds}
/** A template trait for collections which can be traversed either once only
* or one or more times.
@@ -228,7 +229,7 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] {
def copyToArray[B >: A](xs: Array[B]): Unit =
copyToArray(xs, 0, xs.length)
- def toArray[B >: A : ClassManifest]: Array[B] = {
+ def toArray[B >: A : ArrayTag]: Array[B] = {
if (isTraversableAgain) {
val result = new Array[B](size)
copyToArray(result, 0)
@@ -239,7 +240,7 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] {
def toTraversable: Traversable[A]
- def toList: List[A] = new ListBuffer[A] ++= seq toList
+ def toList: List[A] = (new ListBuffer[A] ++= seq).toList
def toIterable: Iterable[A] = toStream
@@ -358,8 +359,11 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] {
object TraversableOnce {
- implicit def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T]
- implicit def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav)
+ @deprecated("use OnceCanBuildFrom instead")
+ def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T]
+ @deprecated("use MonadOps instead")
+ def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav)
+
implicit def alternateImplicit[A](trav: TraversableOnce[A]) = new ForceImplicitAmbiguity
implicit def flattenTraversableOnce[A, CC[_]](travs: TraversableOnce[CC[A]])(implicit ev: CC[A] => TraversableOnce[A]) =
new FlattenOps[A](travs map ev)
@@ -368,7 +372,7 @@ object TraversableOnce {
* operates on Iterators so they can be treated uniformly along with the collections.
* See scala.util.Random.shuffle for an example.
*/
- class OnceCanBuildFrom[A] extends generic.CanBuildFrom[TraversableOnce[A], A, TraversableOnce[A]] {
+ implicit class OnceCanBuildFrom[A] extends generic.CanBuildFrom[TraversableOnce[A], A, TraversableOnce[A]] {
def newIterator = new ArrayBuffer[A] mapResult (_.iterator)
/** Creates a new builder on request of a collection.
@@ -394,7 +398,7 @@ object TraversableOnce {
class ForceImplicitAmbiguity
- class MonadOps[+A](trav: TraversableOnce[A]) {
+ implicit class MonadOps[+A](trav: TraversableOnce[A]) {
def map[B](f: A => B): TraversableOnce[B] = trav.toIterator map f
def flatMap[B](f: A => GenTraversableOnce[B]): TraversableOnce[B] = trav.toIterator flatMap f
def withFilter(p: A => Boolean) = trav.toIterator filter p
diff --git a/src/library/scala/collection/TraversableProxyLike.scala b/src/library/scala/collection/TraversableProxyLike.scala
index e7e797391e..20880e369d 100644
--- a/src/library/scala/collection/TraversableProxyLike.scala
+++ b/src/library/scala/collection/TraversableProxyLike.scala
@@ -73,7 +73,7 @@ trait TraversableProxyLike[+A, +Repr <: TraversableLike[A, Repr] with Traversabl
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) = self.copyToArray(xs, start, len)
override def copyToArray[B >: A](xs: Array[B], start: Int) = self.copyToArray(xs, start)
override def copyToArray[B >: A](xs: Array[B]) = self.copyToArray(xs)
- override def toArray[B >: A: ClassManifest]: Array[B] = self.toArray
+ override def toArray[B >: A: ArrayTag]: Array[B] = self.toArray
override def toList: List[A] = self.toList
override def toIterable: Iterable[A] = self.toIterable
override def toSeq: Seq[A] = self.toSeq
diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala
index fbecad98fe..ad5e3d3240 100644
--- a/src/library/scala/collection/TraversableViewLike.scala
+++ b/src/library/scala/collection/TraversableViewLike.scala
@@ -12,13 +12,14 @@ import generic._
import mutable.{ Builder, ArrayBuffer }
import TraversableView.NoBuilder
import annotation.migration
+import language.implicitConversions
trait ViewMkString[+A] {
self: Traversable[A] =>
// It is necessary to use thisSeq rather than toSeq to avoid cycles in the
// eager evaluation of vals in transformed view subclasses, see #4558.
- protected[this] def thisSeq: Seq[A] = new ArrayBuffer[A] ++= self result
+ protected[this] def thisSeq: Seq[A] = (new ArrayBuffer[A] ++= self).result
// Have to overload all three to work around #4299. The overload
// is because mkString should force a view but toString should not.
diff --git a/src/library/scala/collection/mutable/BasicNode.java b/src/library/scala/collection/concurrent/BasicNode.java
index c05009470a..904ab169a8 100644
--- a/src/library/scala/collection/mutable/BasicNode.java
+++ b/src/library/scala/collection/concurrent/BasicNode.java
@@ -6,7 +6,7 @@
** |/ **
\* */
-package scala.collection.mutable;
+package scala.collection.concurrent;
diff --git a/src/library/scala/collection/mutable/CNodeBase.java b/src/library/scala/collection/concurrent/CNodeBase.java
index 4374943b8d..e343ba95ca 100644
--- a/src/library/scala/collection/mutable/CNodeBase.java
+++ b/src/library/scala/collection/concurrent/CNodeBase.java
@@ -6,7 +6,7 @@
** |/ **
\* */
-package scala.collection.mutable;
+package scala.collection.concurrent;
diff --git a/src/library/scala/collection/mutable/Gen.java b/src/library/scala/collection/concurrent/Gen.java
index 0c9a30d198..4fac4417eb 100644
--- a/src/library/scala/collection/mutable/Gen.java
+++ b/src/library/scala/collection/concurrent/Gen.java
@@ -6,7 +6,7 @@
** |/ **
\* */
-package scala.collection.mutable;
+package scala.collection.concurrent;
diff --git a/src/library/scala/collection/mutable/INodeBase.java b/src/library/scala/collection/concurrent/INodeBase.java
index 487b5cfc28..96bc393b4f 100644
--- a/src/library/scala/collection/mutable/INodeBase.java
+++ b/src/library/scala/collection/concurrent/INodeBase.java
@@ -6,7 +6,7 @@
** |/ **
\* */
-package scala.collection.mutable;
+package scala.collection.concurrent;
diff --git a/src/library/scala/collection/mutable/MainNode.java b/src/library/scala/collection/concurrent/MainNode.java
index 0578de676d..3eea58f3bb 100644
--- a/src/library/scala/collection/mutable/MainNode.java
+++ b/src/library/scala/collection/concurrent/MainNode.java
@@ -6,7 +6,7 @@
** |/ **
\* */
-package scala.collection.mutable;
+package scala.collection.concurrent;
diff --git a/src/library/scala/collection/concurrent/Map.scala b/src/library/scala/collection/concurrent/Map.scala
new file mode 100644
index 0000000000..83445738d9
--- /dev/null
+++ b/src/library/scala/collection/concurrent/Map.scala
@@ -0,0 +1,88 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection.concurrent
+
+/** A template trait for mutable maps that allow concurrent access.
+ *
+ * $concurrentmapinfo
+ *
+ * @since 2.8
+ * @see [[http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html#concurrent_maps "Scala's Collection Library overview"]]
+ * section on `Concurrent Maps` for more information.
+ *
+ * @tparam A the key type of the map
+ * @tparam B the value type of the map
+ *
+ * @define Coll ConcurrentMap
+ * @define coll concurrent map
+ * @define concurrentmapinfo
+ * This is a base trait for all Scala concurrent map implementations. It
+ * provides all of the methods a `Map` does, with the difference that all the
+ * changes are atomic. It also describes methods specific to concurrent maps.
+ *
+ * '''Note''': The concurrent maps do not accept `'''null'''` for keys or values.
+ *
+ * @define atomicop
+ * This is an atomic operation.
+ */
+trait Map[A, B] extends scala.collection.mutable.Map[A, B] {
+
+ /**
+ * Associates the given key with a given value, unless the key was already
+ * associated with some other value.
+ *
+ * $atomicop
+ *
+ * @param k key with which the specified value is to be associated with
+ * @param v value to be associated with the specified key
+ * @return `Some(oldvalue)` if there was a value `oldvalue` previously
+ * associated with the specified key, or `None` if there was no
+ * mapping for the specified key
+ */
+ def putIfAbsent(k: A, v: B): Option[B]
+
+ /**
+ * Removes the entry for the specified key if its currently mapped to the
+ * specified value.
+ *
+ * $atomicop
+ *
+ * @param k key for which the entry should be removed
+ * @param v value expected to be associated with the specified key if
+ * the removal is to take place
+ * @return `true` if the removal took place, `false` otherwise
+ */
+ def remove(k: A, v: B): Boolean
+
+ /**
+ * Replaces the entry for the given key only if it was previously mapped to
+ * a given value.
+ *
+ * $atomicop
+ *
+ * @param k key for which the entry should be replaced
+ * @param oldvalue value expected to be associated with the specified key
+ * if replacing is to happen
+ * @param newvalue value to be associated with the specified key
+ * @return `true` if the entry was replaced, `false` otherwise
+ */
+ def replace(k: A, oldvalue: B, newvalue: B): Boolean
+
+ /**
+ * Replaces the entry for the given key only if it was previously mapped
+ * to some value.
+ *
+ * $atomicop
+ *
+ * @param k key for which the entry should be replaced
+ * @param v value to be associated with the specified key
+ * @return `Some(v)` if the given key was previously mapped to some value `v`, or `None` otherwise
+ */
+ def replace(k: A, v: B): Option[B]
+}
diff --git a/src/library/scala/collection/mutable/ConcurrentTrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala
index cfe1b1950d..2a908aebb1 100644
--- a/src/library/scala/collection/mutable/ConcurrentTrieMap.scala
+++ b/src/library/scala/collection/concurrent/TrieMap.scala
@@ -7,13 +7,13 @@
\* */
package scala.collection
-package mutable
+package concurrent
import java.util.concurrent.atomic._
import collection.immutable.{ ListMap => ImmutableListMap }
-import collection.parallel.mutable.ParConcurrentTrieMap
+import collection.parallel.mutable.ParTrieMap
import generic._
import annotation.tailrec
import annotation.switch
@@ -31,16 +31,16 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
@inline final def CAS(old: MainNode[K, V], n: MainNode[K, V]) = INodeBase.updater.compareAndSet(this, old, n)
- final def gcasRead(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = GCAS_READ(ct)
+ final def gcasRead(ct: TrieMap[K, V]): MainNode[K, V] = GCAS_READ(ct)
- @inline final def GCAS_READ(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = {
+ @inline final def GCAS_READ(ct: TrieMap[K, V]): MainNode[K, V] = {
val m = /*READ*/mainnode
val prevval = /*READ*/m.prev
if (prevval eq null) m
else GCAS_Complete(m, ct)
}
- @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = if (m eq null) null else {
+ @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: TrieMap[K, V]): MainNode[K, V] = if (m eq null) null else {
// complete the GCAS
val prev = /*READ*/m.prev
val ctr = ct.readRoot(true)
@@ -72,7 +72,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): Boolean = {
+ @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: TrieMap[K, V]): Boolean = {
n.WRITE_PREV(old)
if (CAS(old, n)) {
GCAS_Complete(n, ct)
@@ -86,7 +86,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
nin
}
- final def copyToGen(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = {
+ final def copyToGen(ngen: Gen, ct: TrieMap[K, V]) = {
val nin = new INode[K, V](ngen)
val main = GCAS_READ(ct)
nin.WRITE(main)
@@ -97,7 +97,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
*
* @return true if successful, false otherwise
*/
- @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Boolean = {
+ @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: TrieMap[K, V]): Boolean = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -143,7 +143,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
* @param cond null - don't care if the key was there; KEY_ABSENT - key wasn't there; KEY_PRESENT - key was there; other value `v` - key must be bound to `v`
* @return null if unsuccessful, Option[V] otherwise (indicating previous value bound to the key)
*/
- @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = {
+ @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: TrieMap[K, V]): Option[V] = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -233,7 +233,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
*
* @return null if no value has been found, RESTART if the operation wasn't successful, or any other value otherwise
*/
- @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): AnyRef = {
+ @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: TrieMap[K, V]): AnyRef = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -276,7 +276,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
* @param v if null, will remove the key irregardless of the value; otherwise removes only if binding contains that exact key and value
* @return null if not successful, an Option[V] indicating the previous value otherwise
*/
- final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = {
+ final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: TrieMap[K, V]): Option[V] = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -352,7 +352,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- private def clean(nd: INode[K, V], ct: ConcurrentTrieMap[K, V], lev: Int) {
+ private def clean(nd: INode[K, V], ct: TrieMap[K, V], lev: Int) {
val m = nd.GCAS_READ(ct)
m match {
case cn: CNode[K, V] => nd.GCAS(cn, cn.toCompressed(ct, lev, gen), ct)
@@ -360,9 +360,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- final def isNullInode(ct: ConcurrentTrieMap[K, V]) = GCAS_READ(ct) eq null
+ final def isNullInode(ct: TrieMap[K, V]) = GCAS_READ(ct) eq null
- final def cachedSize(ct: ConcurrentTrieMap[K, V]): Int = {
+ final def cachedSize(ct: TrieMap[K, V]): Int = {
val m = GCAS_READ(ct)
m.cachedSize(ct)
}
@@ -379,7 +379,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
-private[mutable] object INode {
+private[concurrent] object INode {
val KEY_PRESENT = new AnyRef
val KEY_ABSENT = new AnyRef
@@ -391,7 +391,7 @@ private[mutable] object INode {
}
-private[mutable] final class FailedNode[K, V](p: MainNode[K, V]) extends MainNode[K, V] {
+private[concurrent] final class FailedNode[K, V](p: MainNode[K, V]) extends MainNode[K, V] {
WRITE_PREV(p)
def string(lev: Int) = throw new UnsupportedOperationException
@@ -402,7 +402,7 @@ private[mutable] final class FailedNode[K, V](p: MainNode[K, V]) extends MainNod
}
-private[mutable] trait KVNode[K, V] {
+private[concurrent] trait KVNode[K, V] {
def kvPair: (K, V)
}
@@ -438,7 +438,7 @@ extends MainNode[K, V] {
if (updmap.size > 1) new LNode(updmap)
else {
val (k, v) = updmap.iterator.next
- new TNode(k, v, ConcurrentTrieMap.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses
+ new TNode(k, v, TrieMap.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses
}
}
def get(k: K) = listmap.get(k)
@@ -455,7 +455,7 @@ extends CNodeBase[K, V] {
val currsz = READ_SIZE()
if (currsz != -1) currsz
else {
- val sz = computeSize(ct.asInstanceOf[ConcurrentTrieMap[K, V]])
+ val sz = computeSize(ct.asInstanceOf[TrieMap[K, V]])
while (READ_SIZE() == -1) CAS_SIZE(-1, sz)
READ_SIZE()
}
@@ -466,7 +466,7 @@ extends CNodeBase[K, V] {
// => if there are concurrent size computations, they start
// at different positions, so they are more likely to
// to be independent
- private def computeSize(ct: ConcurrentTrieMap[K, V]): Int = {
+ private def computeSize(ct: TrieMap[K, V]): Int = {
var i = 0
var sz = 0
val offset = math.abs(util.Random.nextInt()) % array.length
@@ -511,7 +511,7 @@ extends CNodeBase[K, V] {
/** Returns a copy of this cnode such that all the i-nodes below it are copied
* to the specified generation `ngen`.
*/
- final def renewed(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = {
+ final def renewed(ngen: Gen, ct: TrieMap[K, V]) = {
var i = 0
val arr = array
val len = arr.length
@@ -542,7 +542,7 @@ extends CNodeBase[K, V] {
// returns the version of this node with at least some null-inodes
// removed (those existing when the op began)
// - if there are only null-i-nodes below, returns null
- final def toCompressed(ct: ConcurrentTrieMap[K, V], lev: Int, gen: Gen) = {
+ final def toCompressed(ct: TrieMap[K, V], lev: Int, gen: Gen) = {
var bmp = bitmap
var i = 0
val arr = array
@@ -563,7 +563,7 @@ extends CNodeBase[K, V] {
new CNode[K, V](bmp, tmparray, gen).toContracted(lev)
}
- private[mutable] def string(lev: Int): String = "CNode %x\n%s".format(bitmap, array.map(_.string(lev + 1)).mkString("\n"))
+ private[concurrent] def string(lev: Int): String = "CNode %x\n%s".format(bitmap, array.map(_.string(lev + 1)).mkString("\n"))
/* quiescently consistent - don't call concurrently to anything involving a GCAS!! */
protected def collectElems: Seq[(K, V)] = array flatMap {
@@ -587,14 +587,14 @@ extends CNodeBase[K, V] {
}
-private[mutable] object CNode {
+private[concurrent] object CNode {
def dual[K, V](x: SNode[K, V], xhc: Int, y: SNode[K, V], yhc: Int, lev: Int, gen: Gen): MainNode[K, V] = if (lev < 35) {
val xidx = (xhc >>> lev) & 0x1f
val yidx = (yhc >>> lev) & 0x1f
val bmp = (1 << xidx) | (1 << yidx)
if (xidx == yidx) {
- val subinode = new INode[K, V](gen)//(ConcurrentTrieMap.inodeupdater)
+ val subinode = new INode[K, V](gen)//(TrieMap.inodeupdater)
subinode.mainnode = dual(x, xhc, y, yhc, lev + 5, gen)
new CNode(bmp, Array(subinode), gen)
} else {
@@ -608,12 +608,12 @@ private[mutable] object CNode {
}
-private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmain: MainNode[K, V], nv: INode[K, V]) {
+private[concurrent] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmain: MainNode[K, V], nv: INode[K, V]) {
@volatile var committed = false
}
-/** A concurrent hash-trie or ConcurrentTrieMap is a concurrent thread-safe lock-free
+/** A concurrent hash-trie or TrieMap is a concurrent thread-safe lock-free
* implementation of a hash array mapped trie. It is used to implement the
* concurrent map abstraction. It has particularly scalable concurrent insert
* and remove operations and is memory-efficient. It supports O(1), atomic,
@@ -627,20 +627,20 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai
* @since 2.10
*/
@SerialVersionUID(0L - 6402774413839597105L)
-final class ConcurrentTrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[ConcurrentTrieMap[K, V], AnyRef])
-extends ConcurrentMap[K, V]
- with MapLike[K, V, ConcurrentTrieMap[K, V]]
- with CustomParallelizable[(K, V), ParConcurrentTrieMap[K, V]]
+final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[TrieMap[K, V], AnyRef])
+extends scala.collection.concurrent.Map[K, V]
+ with scala.collection.mutable.MapLike[K, V, TrieMap[K, V]]
+ with CustomParallelizable[(K, V), ParTrieMap[K, V]]
with Serializable
{
- import ConcurrentTrieMap.computeHash
+ import TrieMap.computeHash
private var rootupdater = rtupd
@volatile var root = r
def this() = this(
INode.newRootNode,
- AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root")
+ AtomicReferenceFieldUpdater.newUpdater(classOf[TrieMap[K, V]], classOf[AnyRef], "root")
)
/* internal methods */
@@ -652,22 +652,22 @@ extends ConcurrentMap[K, V]
out.writeObject(k)
out.writeObject(v)
}
- out.writeObject(ConcurrentTrieMapSerializationEnd)
+ out.writeObject(TrieMapSerializationEnd)
}
private def readObject(in: java.io.ObjectInputStream) {
root = INode.newRootNode
- rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root")
+ rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[TrieMap[K, V]], classOf[AnyRef], "root")
var obj: AnyRef = null
do {
obj = in.readObject()
- if (obj != ConcurrentTrieMapSerializationEnd) {
+ if (obj != TrieMapSerializationEnd) {
val k = obj.asInstanceOf[K]
val v = in.readObject().asInstanceOf[V]
update(k, v)
}
- } while (obj != ConcurrentTrieMapSerializationEnd)
+ } while (obj != TrieMapSerializationEnd)
}
@inline final def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.compareAndSet(this, ov, nv)
@@ -760,37 +760,37 @@ extends ConcurrentMap[K, V]
override def seq = this
- override def par = new ParConcurrentTrieMap(this)
+ override def par = new ParTrieMap(this)
- override def empty: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V]
+ override def empty: TrieMap[K, V] = new TrieMap[K, V]
final def isReadOnly = rootupdater eq null
final def nonReadOnly = rootupdater ne null
- /** Returns a snapshot of this ConcurrentTrieMap.
+ /** Returns a snapshot of this TrieMap.
* This operation is lock-free and linearizable.
*
* The snapshot is lazily updated - the first time some branch
- * in the snapshot or this ConcurrentTrieMap are accessed, they are rewritten.
+ * in the snapshot or this TrieMap are accessed, they are rewritten.
* This means that the work of rebuilding both the snapshot and this
- * ConcurrentTrieMap is distributed across all the threads doing updates or accesses
+ * TrieMap is distributed across all the threads doing updates or accesses
* subsequent to the snapshot creation.
*/
- @tailrec final def snapshot(): ConcurrentTrieMap[K, V] = {
+ @tailrec final def snapshot(): TrieMap[K, V] = {
val r = RDCSS_READ_ROOT()
val expmain = r.gcasRead(this)
- if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r.copyToGen(new Gen, this), rootupdater)
+ if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new TrieMap(r.copyToGen(new Gen, this), rootupdater)
else snapshot()
}
- /** Returns a read-only snapshot of this ConcurrentTrieMap.
+ /** Returns a read-only snapshot of this TrieMap.
* This operation is lock-free and linearizable.
*
* The snapshot is lazily updated - the first time some branch
- * of this ConcurrentTrieMap are accessed, it is rewritten. The work of creating
+ * of this TrieMap are accessed, it is rewritten. The work of creating
* the snapshot is thus distributed across subsequent updates
- * and accesses on this ConcurrentTrieMap by all threads.
+ * and accesses on this TrieMap by all threads.
* Note that the snapshot itself is never rewritten unlike when calling
* the `snapshot` method, but the obtained snapshot cannot be modified.
*
@@ -799,7 +799,7 @@ extends ConcurrentMap[K, V]
@tailrec final def readOnlySnapshot(): collection.Map[K, V] = {
val r = RDCSS_READ_ROOT()
val expmain = r.gcasRead(this)
- if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r, null)
+ if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new TrieMap(r, null)
else readOnlySnapshot()
}
@@ -872,7 +872,7 @@ extends ConcurrentMap[K, V]
def iterator: Iterator[(K, V)] =
if (nonReadOnly) readOnlySnapshot().iterator
- else new ConcurrentTrieMapIterator(0, this)
+ else new TrieMapIterator(0, this)
private def cachedSize() = {
val r = RDCSS_READ_ROOT()
@@ -883,17 +883,17 @@ extends ConcurrentMap[K, V]
if (nonReadOnly) readOnlySnapshot().size
else cachedSize()
- override def stringPrefix = "ConcurrentTrieMap"
+ override def stringPrefix = "TrieMap"
}
-object ConcurrentTrieMap extends MutableMapFactory[ConcurrentTrieMap] {
+object TrieMap extends MutableMapFactory[TrieMap] {
val inodeupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[INodeBase[_, _]], classOf[MainNode[_, _]], "mainnode")
- implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), ConcurrentTrieMap[K, V]] = new MapCanBuildFrom[K, V]
+ implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), TrieMap[K, V]] = new MapCanBuildFrom[K, V]
- def empty[K, V]: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V]
+ def empty[K, V]: TrieMap[K, V] = new TrieMap[K, V]
@inline final def computeHash[K](k: K): Int = {
var hcode = k.hashCode
@@ -905,7 +905,7 @@ object ConcurrentTrieMap extends MutableMapFactory[ConcurrentTrieMap] {
}
-private[collection] class ConcurrentTrieMapIterator[K, V](var level: Int, private var ct: ConcurrentTrieMap[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] {
+private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: TrieMap[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] {
var stack = new Array[Array[BasicNode]](7)
var stackpos = new Array[Int](7)
var depth = -1
@@ -971,9 +971,9 @@ private[collection] class ConcurrentTrieMapIterator[K, V](var level: Int, privat
}
} else current = null
- protected def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ConcurrentTrieMapIterator[K, V](_lev, _ct, _mustInit)
+ protected def newIterator(_lev: Int, _ct: TrieMap[K, V], _mustInit: Boolean) = new TrieMapIterator[K, V](_lev, _ct, _mustInit)
- protected def dupTo(it: ConcurrentTrieMapIterator[K, V]) = {
+ protected def dupTo(it: TrieMapIterator[K, V]) = {
it.level = this.level
it.ct = this.ct
it.depth = this.depth
@@ -993,7 +993,7 @@ private[collection] class ConcurrentTrieMapIterator[K, V](var level: Int, privat
}
/** Returns a sequence of iterators over subsets of this iterator.
- * It's used to ease the implementation of splitters for a parallel version of the ConcurrentTrieMap.
+ * It's used to ease the implementation of splitters for a parallel version of the TrieMap.
*/
protected def subdivide(): Seq[Iterator[(K, V)]] = if (subiter ne null) {
// the case where an LNode is being iterated
@@ -1038,15 +1038,15 @@ private[collection] class ConcurrentTrieMapIterator[K, V](var level: Int, privat
}
-private[mutable] object RestartException extends util.control.ControlThrowable
+private[concurrent] object RestartException extends util.control.ControlThrowable
/** Only used for ctrie serialization. */
@SerialVersionUID(0L - 7237891413820527142L)
-private[mutable] case object ConcurrentTrieMapSerializationEnd
+private[concurrent] case object TrieMapSerializationEnd
-private[mutable] object Debug {
+private[concurrent] object Debug {
import collection._
lazy val logbuffer = new java.util.concurrent.ConcurrentLinkedQueue[AnyRef]
diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala
new file mode 100644
index 0000000000..bde13f2830
--- /dev/null
+++ b/src/library/scala/collection/convert/DecorateAsJava.scala
@@ -0,0 +1,318 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+import Decorators._
+import WrapAsJava._
+import language.implicitConversions
+
+
+/** A collection of decorators that allow to convert between
+ * Scala and Java collections using `asScala` and `asJava` methods.
+ *
+ * The following conversions are supported via `asJava`, `asScala`
+ *
+ * - `scala.collection.Iterable` <=> `java.lang.Iterable`
+ * - `scala.collection.Iterator` <=> `java.util.Iterator`
+ * - `scala.collection.mutable.Buffer` <=> `java.util.List`
+ * - `scala.collection.mutable.Set` <=> `java.util.Set`
+ * - `scala.collection.mutable.Map` <=> `java.util.Map`
+ * - `scala.collection.mutable.ConcurrentMap` <=> `java.util.concurrent.ConcurrentMap`
+ *
+ * In all cases, converting from a source type to a target type and back
+ * again will return the original source object, e.g.
+ * {{{
+ * import scala.collection.JavaConverters._
+ *
+ * val sl = new scala.collection.mutable.ListBuffer[Int]
+ * val jl : java.util.List[Int] = sl.asJava
+ * val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala
+ * assert(sl eq sl2)
+ * }}}
+ * The following conversions also are supported, but the
+ * direction Scala to Java is done my a more specifically named method:
+ * `asJavaCollection`, `asJavaEnumeration`, `asJavaDictionary`.
+ *
+ * - `scala.collection.Iterable` <=> `java.util.Collection`
+ * - `scala.collection.Iterator` <=> `java.util.Enumeration`
+ * - `scala.collection.mutable.Map` <=> `java.util.Dictionary`
+ *
+ * In addition, the following one way conversions are provided via `asJava`:
+ *
+ * - `scala.collection.Seq` => `java.util.List`
+ * - `scala.collection.mutable.Seq` => `java.util.List`
+ * - `scala.collection.Set` => `java.util.Set`
+ * - `scala.collection.Map` => `java.util.Map`
+ *
+ * @author Martin Odersky
+ * @since 2.8.1
+ */
+
+trait DecorateAsJava {
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala `Iterator` to a
+ * Java `Iterator`. The returned Java `Iterator` is backed by the provided Scala
+ * `Iterator` and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Iterator` was previously obtained from an implicit or explicit
+ * call of `asIterator(java.util.Iterator)` then the original Java `Iterator`
+ * will be returned by the `asJava` method.
+ *
+ * @param i The `Iterator` to be converted.
+ * @return An object with an `asJava` method that returns a Java `Iterator` view of the argument.
+ */
+ implicit def asJavaIteratorConverter[A](i : Iterator[A]): AsJava[ju.Iterator[A]] =
+ new AsJava(asJavaIterator(i))
+
+ /**
+ * Adds an `asJavaEnumeration` method that implicitly converts a Scala
+ * `Iterator` to a Java `Enumeration`. The returned Java `Enumeration` is
+ * backed by the provided Scala `Iterator` and any side-effects of using
+ * it via the Java interface will be visible via the Scala interface and
+ * vice versa.
+ *
+ * If the Scala `Iterator` was previously obtained from an implicit or
+ * explicit call of `asIterator(java.util.Enumeration)` then the
+ * original Java `Enumeration` will be returned.
+ *
+ * @param i The `Iterator` to be converted.
+ * @return An object with an `asJavaEnumeration` method that returns a Java
+ * `Enumeration` view of the argument.
+ */
+ implicit def asJavaEnumerationConverter[A](i : Iterator[A]): AsJavaEnumeration[A] =
+ new AsJavaEnumeration(i)
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala `Iterable` to
+ * a Java `Iterable`.
+ *
+ * The returned Java `Iterable` is backed by the provided Scala `Iterable`
+ * and any side-effects of using it via the Java interface will be visible
+ * via the Scala interface and vice versa.
+ *
+ * If the Scala `Iterable` was previously obtained from an implicit or
+ * explicit call of `asIterable(java.lang.Iterable)` then the original
+ * Java `Iterable` will be returned.
+ *
+ * @param i The `Iterable` to be converted.
+ * @return An object with an `asJavaCollection` method that returns a Java
+ * `Iterable` view of the argument.
+ */
+ implicit def asJavaIterableConverter[A](i : Iterable[A]): AsJava[jl.Iterable[A]] =
+ new AsJava(asJavaIterable(i))
+
+ /**
+ * Adds an `asJavaCollection` method that implicitly converts a Scala
+ * `Iterable` to an immutable Java `Collection`.
+ *
+ * If the Scala `Iterable` was previously obtained from an implicit or
+ * explicit call of `asSizedIterable(java.util.Collection)` then the
+ * original Java `Collection` will be returned.
+ *
+ * @param i The `SizedIterable` to be converted.
+ * @return An object with an `asJava` method that returns a Java
+ * `Collection` view of the argument.
+ */
+ implicit def asJavaCollectionConverter[A](i : Iterable[A]): AsJavaCollection[A] =
+ new AsJavaCollection(i)
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala mutable `Buffer`
+ * to a Java `List`.
+ *
+ * The returned Java `List` is backed by the provided Scala `Buffer` and any
+ * side-effects of using it via the Java interface will be visible via the
+ * Scala interface and vice versa.
+ *
+ * If the Scala `Buffer` was previously obtained from an implicit or explicit
+ * call of `asBuffer(java.util.List)` then the original Java `List` will be
+ * returned.
+ *
+ * @param b The `Buffer` to be converted.
+ * @return An object with an `asJava` method that returns a Java `List` view
+ * of the argument.
+ */
+ implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] =
+ new AsJava(bufferAsJavaList(b))
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala mutable `Seq`
+ * to a Java `List`.
+ *
+ * The returned Java `List` is backed by the provided Scala `Seq` and any
+ * side-effects of using it via the Java interface will be visible via the
+ * Scala interface and vice versa.
+ *
+ * If the Scala `Seq` was previously obtained from an implicit or explicit
+ * call of `asSeq(java.util.List)` then the original Java `List` will be
+ * returned.
+ *
+ * @param b The `Seq` to be converted.
+ * @return An object with an `asJava` method that returns a Java `List`
+ * view of the argument.
+ */
+ implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] =
+ new AsJava(mutableSeqAsJavaList(b))
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala `Seq` to a
+ * Java `List`.
+ *
+ * The returned Java `List` is backed by the provided Scala `Seq` and any
+ * side-effects of using it via the Java interface will be visible via the
+ * Scala interface and vice versa.
+ *
+ * If the Scala `Seq` was previously obtained from an implicit or explicit
+ * call of `asSeq(java.util.List)` then the original Java `List` will be
+ * returned.
+ *
+ * @param b The `Seq` to be converted.
+ * @return An object with an `asJava` method that returns a Java `List`
+ * view of the argument.
+ */
+ implicit def seqAsJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] =
+ new AsJava(seqAsJavaList(b))
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala mutable `Set`>
+ * to a Java `Set`.
+ *
+ * The returned Java `Set` is backed by the provided Scala `Set` and any
+ * side-effects of using it via the Java interface will be visible via
+ * the Scala interface and vice versa.
+ *
+ * If the Scala `Set` was previously obtained from an implicit or explicit
+ * call of `asSet(java.util.Set)` then the original Java `Set` will be
+ * returned.
+ *
+ * @param s The `Set` to be converted.
+ * @return An object with an `asJava` method that returns a Java `Set` view
+ * of the argument.
+ */
+ implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] =
+ new AsJava(mutableSetAsJavaSet(s))
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala `Set` to a
+ * Java `Set`.
+ *
+ * The returned Java `Set` is backed by the provided Scala `Set` and any
+ * side-effects of using it via the Java interface will be visible via
+ * the Scala interface and vice versa.
+ *
+ * If the Scala `Set` was previously obtained from an implicit or explicit
+ * call of `asSet(java.util.Set)` then the original Java `Set` will be
+ * returned.
+ *
+ * @param s The `Set` to be converted.
+ * @return An object with an `asJava` method that returns a Java `Set` view
+ * of the argument.
+ */
+ implicit def setAsJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] =
+ new AsJava(setAsJavaSet(s))
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala mutable `Map`
+ * to a Java `Map`.
+ *
+ * The returned Java `Map` is backed by the provided Scala `Map` and any
+ * side-effects of using it via the Java interface will be visible via the
+ * Scala interface and vice versa.
+ *
+ * If the Scala `Map` was previously obtained from an implicit or explicit
+ * call of `asMap(java.util.Map)` then the original Java `Map` will be
+ * returned.
+ *
+ * @param m The `Map` to be converted.
+ * @return An object with an `asJava` method that returns a Java `Map` view
+ * of the argument.
+ */
+ implicit def mutableMapAsJavaMapConverter[A, B](m : mutable.Map[A, B]): AsJava[ju.Map[A, B]] =
+ new AsJava(mutableMapAsJavaMap(m))
+
+ /**
+ * Adds an `asJavaDictionary` method that implicitly converts a Scala
+ * mutable `Map` to a Java `Dictionary`.
+ *
+ * The returned Java `Dictionary` is backed by the provided Scala
+ * `Dictionary` and any side-effects of using it via the Java interface
+ * will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Dictionary` was previously obtained from an implicit or
+ * explicit call of `asMap(java.util.Dictionary)` then the original
+ * Java `Dictionary` will be returned.
+ *
+ * @param m The `Map` to be converted.
+ * @return An object with an `asJavaDictionary` method that returns a
+ * Java `Dictionary` view of the argument.
+ */
+ implicit def asJavaDictionaryConverter[A, B](m : mutable.Map[A, B]): AsJavaDictionary[A, B] =
+ new AsJavaDictionary(m)
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala `Map` to
+ * a Java `Map`.
+ *
+ * The returned Java `Map` is backed by the provided Scala `Map` and any
+ * side-effects of using it via the Java interface will be visible via
+ * the Scala interface and vice versa.
+ *
+ * If the Scala `Map` was previously obtained from an implicit or explicit
+ * call of `asMap(java.util.Map)` then the original Java `Map` will be
+ * returned.
+ *
+ * @param m The `Map` to be converted.
+ * @return An object with an `asJava` method that returns a Java `Map` view
+ * of the argument.
+ */
+ implicit def mapAsJavaMapConverter[A, B](m : Map[A, B]): AsJava[ju.Map[A, B]] =
+ new AsJava(mapAsJavaMap(m))
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala mutable
+ * `ConcurrentMap` to a Java `ConcurrentMap`.
+ *
+ * The returned Java `ConcurrentMap` is backed by the provided Scala
+ * `ConcurrentMap` and any side-effects of using it via the Java interface
+ * will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `ConcurrentMap` was previously obtained from an implicit or
+ * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * then the original Java `ConcurrentMap` will be returned.
+ *
+ * @param m The `ConcurrentMap` to be converted.
+ * @return An object with an `asJava` method that returns a Java
+ * `ConcurrentMap` view of the argument.
+ */
+ @deprecated("Use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0")
+ implicit def asJavaConcurrentMapConverter[A, B](m: mutable.ConcurrentMap[A, B]): AsJava[juc.ConcurrentMap[A, B]] =
+ new AsJava(asJavaConcurrentMap(m))
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala mutable
+ * `concurrent.Map` to a Java `ConcurrentMap`.
+ *
+ * The returned Java `ConcurrentMap` is backed by the provided Scala
+ * `concurrent.Map` and any side-effects of using it via the Java interface
+ * will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `concurrent.Map` was previously obtained from an implicit or
+ * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * then the original Java `ConcurrentMap` will be returned.
+ *
+ * @param m The Scala `concurrent.Map` to be converted.
+ * @return An object with an `asJava` method that returns a Java
+ * `ConcurrentMap` view of the argument.
+ */
+ implicit def asJavaConcurrentMapConverter[A, B](m: concurrent.Map[A, B]): AsJava[juc.ConcurrentMap[A, B]] =
+ new AsJava(asJavaConcurrentMap(m))
+}
diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala
new file mode 100644
index 0000000000..b170d8d139
--- /dev/null
+++ b/src/library/scala/collection/convert/DecorateAsScala.scala
@@ -0,0 +1,209 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+import Decorators._
+import WrapAsScala._
+import language.implicitConversions
+
+trait DecorateAsScala {
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `Iterator` to
+ * a Scala `Iterator`.
+ *
+ * The returned Scala `Iterator` is backed by the provided Java `Iterator`
+ * and any side-effects of using it via the Scala interface will be visible
+ * via the Java interface and vice versa.
+ *
+ * If the Java `Iterator` was previously obtained from an implicit or
+ * explicit call of `asIterator(scala.collection.Iterator)` then the
+ * original Scala `Iterator` will be returned.
+ *
+ * @param i The `Iterator` to be converted.
+ * @return An object with an `asScala` method that returns a Scala
+ * `Iterator` view of the argument.
+ */
+ implicit def asScalaIteratorConverter[A](i : ju.Iterator[A]): AsScala[Iterator[A]] =
+ new AsScala(asScalaIterator(i))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `Enumeration`
+ * to a Scala `Iterator`.
+ *
+ * The returned Scala `Iterator` is backed by the provided Java
+ * `Enumeration` and any side-effects of using it via the Scala interface
+ * will be visible via the Java interface and vice versa.
+ *
+ * If the Java `Enumeration` was previously obtained from an implicit or
+ * explicit call of `asEnumeration(scala.collection.Iterator)` then the
+ * original Scala `Iterator` will be returned.
+ *
+ * @param i The `Enumeration` to be converted.
+ * @return An object with an `asScala` method that returns a Scala
+ * `Iterator` view of the argument.
+ */
+ implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A]): AsScala[Iterator[A]] =
+ new AsScala(enumerationAsScalaIterator(i))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `Iterable` to
+ * a Scala `Iterable`.
+ *
+ * The returned Scala `Iterable` is backed by the provided Java `Iterable`
+ * and any side-effects of using it via the Scala interface will be visible
+ * via the Java interface and vice versa.
+ *
+ * If the Java `Iterable` was previously obtained from an implicit or
+ * explicit call of `asIterable(scala.collection.Iterable)` then the original
+ * Scala `Iterable` will be returned.
+ *
+ * @param i The `Iterable` to be converted.
+ * @return An object with an `asScala` method that returns a Scala `Iterable`
+ * view of the argument.
+ */
+ implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] =
+ new AsScala(iterableAsScalaIterable(i))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `Collection` to
+ * an Scala `Iterable`.
+ *
+ * If the Java `Collection` was previously obtained from an implicit or
+ * explicit call of `asCollection(scala.collection.SizedIterable)` then
+ * the original Scala `SizedIterable` will be returned.
+ *
+ * @param i The `Collection` to be converted.
+ * @return An object with an `asScala` method that returns a Scala
+ * `SizedIterable` view of the argument.
+ */
+ implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] =
+ new AsScala(collectionAsScalaIterable(i))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `List` to a
+ * Scala mutable `Buffer`.
+ *
+ * The returned Scala `Buffer` is backed by the provided Java `List` and
+ * any side-effects of using it via the Scala interface will be visible via
+ * the Java interface and vice versa.
+ *
+ * If the Java `List` was previously obtained from an implicit or explicit
+ * call of `asList(scala.collection.mutable.Buffer)` then the original
+ * Scala `Buffer` will be returned.
+ *
+ * @param l The `List` to be converted.
+ * @return An object with an `asScala` method that returns a Scala mutable
+ * `Buffer` view of the argument.
+ */
+ implicit def asScalaBufferConverter[A](l : ju.List[A]): AsScala[mutable.Buffer[A]] =
+ new AsScala(asScalaBuffer(l))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `Set` to a
+ * Scala mutable `Set`.
+ *
+ * The returned Scala `Set` is backed by the provided Java `Set` and any
+ * side-effects of using it via the Scala interface will be visible via
+ * the Java interface and vice versa.
+ *
+ * If the Java `Set` was previously obtained from an implicit or explicit
+ * call of `asSet(scala.collection.mutable.Set)` then the original
+ * Scala `Set` will be returned.
+ *
+ * @param s The `Set` to be converted.
+ * @return An object with an `asScala` method that returns a Scala mutable
+ * `Set` view of the argument.
+ */
+ implicit def asScalaSetConverter[A](s : ju.Set[A]): AsScala[mutable.Set[A]] =
+ new AsScala(asScalaSet(s))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `Map` to a Scala
+ * mutable `Map`. The returned Scala `Map` is backed by the provided Java
+ * `Map` and any side-effects of using it via the Scala interface will
+ * be visible via the Java interface and vice versa.
+ *
+ * If the Java `Map` was previously obtained from an implicit or explicit
+ * call of `asMap(scala.collection.mutable.Map)` then the original
+ * Scala `Map` will be returned.
+ *
+ * @param m The `Map` to be converted.
+ * @return An object with an `asScala` method that returns a Scala mutable
+ * `Map` view of the argument.
+ */
+ implicit def mapAsScalaMapConverter[A, B](m : ju.Map[A, B]): AsScala[mutable.Map[A, B]] =
+ new AsScala(mapAsScalaMap(m))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap`
+ * to a Scala mutable `ConcurrentMap`. The returned Scala `ConcurrentMap` is
+ * backed by the provided Java `ConcurrentMap` and any side-effects of using
+ * it via the Scala interface will be visible via the Java interface and
+ * vice versa.
+ *
+ * If the Java `ConcurrentMap` was previously obtained from an implicit or
+ * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)`
+ * then the original Scala `ConcurrentMap` will be returned.
+ *
+ * @param m The `ConcurrentMap` to be converted.
+ * @return An object with an `asScala` method that returns a Scala mutable
+ * `ConcurrentMap` view of the argument.
+ */
+ @deprecated("Use `mapAsScalaConcurrentMapConverter` instead, and use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0")
+ def asScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[mutable.ConcurrentMap[A, B]] =
+ new AsScala(asScalaConcurrentMap(m))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap`
+ * to a Scala mutable `concurrent.Map`. The returned Scala `concurrent.Map` is
+ * backed by the provided Java `ConcurrentMap` and any side-effects of using
+ * it via the Scala interface will be visible via the Java interface and
+ * vice versa.
+ *
+ * If the Java `ConcurrentMap` was previously obtained from an implicit or
+ * explicit call of `mapAsScalaConcurrentMap(scala.collection.mutable.ConcurrentMap)`
+ * then the original Scala `concurrent.Map` will be returned.
+ *
+ * @param m The `ConcurrentMap` to be converted.
+ * @return An object with an `asScala` method that returns a Scala mutable
+ * `concurrent.Map` view of the argument.
+ */
+ implicit def mapAsScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[concurrent.Map[A, B]] =
+ new AsScala(mapAsScalaConcurrentMap(m))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `Dictionary`
+ * to a Scala mutable `Map[String, String]`. The returned Scala
+ * `Map[String, String]` is backed by the provided Java `Dictionary` and
+ * any side-effects of using it via the Scala interface will be visible via
+ * the Java interface and vice versa.
+ *
+ * @param m The `Dictionary` to be converted.
+ * @return An object with an `asScala` method that returns a Scala mutable
+ * `Map[String, String]` view of the argument.
+ */
+ implicit def dictionaryAsScalaMapConverter[A, B](p: ju.Dictionary[A, B]): AsScala[mutable.Map[A, B]] =
+ new AsScala(dictionaryAsScalaMap(p))
+
+ /**
+ * Adds an `asScala` method that implicitly converts a Java `Properties`
+ * to a Scala mutable `Map[String, String]`. The returned Scala
+ * `Map[String, String]` is backed by the provided Java `Properties` and
+ * any side-effects of using it via the Scala interface will be visible via
+ * the Java interface and vice versa.
+ *
+ * @param m The `Properties` to be converted.
+ * @return An object with an `asScala` method that returns a Scala mutable
+ * `Map[String, String]` view of the argument.
+ */
+ implicit def propertiesAsScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] =
+ new AsScala(propertiesAsScalaMap(p))
+}
diff --git a/src/library/scala/collection/convert/Decorators.scala b/src/library/scala/collection/convert/Decorators.scala
new file mode 100644
index 0000000000..3bdd9a0f1c
--- /dev/null
+++ b/src/library/scala/collection/convert/Decorators.scala
@@ -0,0 +1,46 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+
+private[collection] trait Decorators {
+ /** Generic class containing the `asJava` converter method */
+ class AsJava[A](op: => A) {
+ /** Converts a Scala collection to the corresponding Java collection */
+ def asJava: A = op
+ }
+
+ /** Generic class containing the `asScala` converter method */
+ class AsScala[A](op: => A) {
+ /** Converts a Java collection to the corresponding Scala collection */
+ def asScala: A = op
+ }
+
+ /** Generic class containing the `asJavaCollection` converter method */
+ class AsJavaCollection[A](i: Iterable[A]) {
+ /** Converts a Scala `Iterable` to a Java `Collection` */
+ def asJavaCollection: ju.Collection[A] = JavaConversions.asJavaCollection(i)
+ }
+
+ /** Generic class containing the `asJavaEnumeration` converter method */
+ class AsJavaEnumeration[A](i: Iterator[A]) {
+ /** Converts a Scala `Iterator` to a Java `Enumeration` */
+ def asJavaEnumeration: ju.Enumeration[A] = JavaConversions.asJavaEnumeration(i)
+ }
+
+ /** Generic class containing the `asJavaDictionary` converter method */
+ class AsJavaDictionary[A, B](m : mutable.Map[A, B]) {
+ /** Converts a Scala `Map` to a Java `Dictionary` */
+ def asJavaDictionary: ju.Dictionary[A, B] = JavaConversions.asJavaDictionary(m)
+ }
+}
+
+private[collection] object Decorators extends Decorators
diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala
new file mode 100644
index 0000000000..ecf91deb3a
--- /dev/null
+++ b/src/library/scala/collection/convert/WrapAsJava.scala
@@ -0,0 +1,286 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+import Wrappers._
+import language.implicitConversions
+
+trait WrapAsJava {
+ /**
+ * Implicitly converts a Scala Iterator to a Java Iterator.
+ * The returned Java Iterator is backed by the provided Scala
+ * Iterator and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Iterator was previously obtained from an implicit or
+ * explicit call of `asIterator(java.util.Iterator)` then the original
+ * Java Iterator will be returned.
+ *
+ * @param i The Iterator to be converted.
+ * @return A Java Iterator view of the argument.
+ */
+ implicit def asJavaIterator[A](it: Iterator[A]): ju.Iterator[A] = it match {
+ case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]]
+ case _ => IteratorWrapper(it)
+ }
+
+ /**
+ * Implicitly converts a Scala Iterator to a Java Enumeration.
+ * The returned Java Enumeration is backed by the provided Scala
+ * Iterator and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Iterator was previously obtained from an implicit or
+ * explicit call of `asIterator(java.util.Enumeration)` then the
+ * original Java Enumeration will be returned.
+ *
+ * @param i The Iterator to be converted.
+ * @return A Java Enumeration view of the argument.
+ */
+ implicit def asJavaEnumeration[A](it: Iterator[A]): ju.Enumeration[A] = it match {
+ case JEnumerationWrapper(wrapped) => wrapped.asInstanceOf[ju.Enumeration[A]]
+ case _ => IteratorWrapper(it)
+ }
+
+ /**
+ * Implicitly converts a Scala Iterable to a Java Iterable.
+ * The returned Java Iterable is backed by the provided Scala
+ * Iterable and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Iterable was previously obtained from an implicit or
+ * explicit call of `asIterable(java.lang.Iterable)` then the original
+ * Java Iterable will be returned.
+ *
+ * @param i The Iterable to be converted.
+ * @return A Java Iterable view of the argument.
+ */
+ implicit def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = i match {
+ case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]]
+ case _ => IterableWrapper(i)
+ }
+
+ /**
+ * Implicitly converts a Scala Iterable to an immutable Java
+ * Collection.
+ *
+ * If the Scala Iterable was previously obtained from an implicit or
+ * explicit call of `asSizedIterable(java.util.Collection)` then the original
+ * Java Collection will be returned.
+ *
+ * @param i The SizedIterable to be converted.
+ * @return A Java Collection view of the argument.
+ */
+ implicit def asJavaCollection[A](it: Iterable[A]): ju.Collection[A] = it match {
+ case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]]
+ case _ => new IterableWrapper(it)
+ }
+
+ /**
+ * Implicitly converts a Scala mutable Buffer to a Java List.
+ * The returned Java List is backed by the provided Scala
+ * Buffer and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Buffer was previously obtained from an implicit or
+ * explicit call of `asBuffer(java.util.List)` then the original
+ * Java List will be returned.
+ *
+ * @param b The Buffer to be converted.
+ * @return A Java List view of the argument.
+ */
+ implicit def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = b match {
+ case JListWrapper(wrapped) => wrapped
+ case _ => new MutableBufferWrapper(b)
+ }
+
+ /**
+ * Implicitly converts a Scala mutable Seq to a Java List.
+ * The returned Java List is backed by the provided Scala
+ * Seq and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Seq was previously obtained from an implicit or
+ * explicit call of `asSeq(java.util.List)` then the original
+ * Java List will be returned.
+ *
+ * @param b The Seq to be converted.
+ * @return A Java List view of the argument.
+ */
+ implicit def mutableSeqAsJavaList[A](seq: mutable.Seq[A]): ju.List[A] = seq match {
+ case JListWrapper(wrapped) => wrapped
+ case _ => new MutableSeqWrapper(seq)
+ }
+
+ /**
+ * Implicitly converts a Scala Seq to a Java List.
+ * The returned Java List is backed by the provided Scala
+ * Seq and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Seq was previously obtained from an implicit or
+ * explicit call of `asSeq(java.util.List)` then the original
+ * Java List will be returned.
+ *
+ * @param b The Seq to be converted.
+ * @return A Java List view of the argument.
+ */
+ implicit def seqAsJavaList[A](seq: Seq[A]): ju.List[A] = seq match {
+ case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]]
+ case _ => new SeqWrapper(seq)
+ }
+
+ /**
+ * Implicitly converts a Scala mutable Set to a Java Set.
+ * The returned Java Set is backed by the provided Scala
+ * Set and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Set was previously obtained from an implicit or
+ * explicit call of `asSet(java.util.Set)` then the original
+ * Java Set will be returned.
+ *
+ * @param s The Set to be converted.
+ * @return A Java Set view of the argument.
+ */
+ implicit def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = s match {
+ case JSetWrapper(wrapped) => wrapped
+ case _ => new MutableSetWrapper(s)
+ }
+
+ /**
+ * Implicitly converts a Scala Set to a Java Set.
+ * The returned Java Set is backed by the provided Scala
+ * Set and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Set was previously obtained from an implicit or
+ * explicit call of asSet(java.util.Set) then the original
+ * Java Set will be returned.
+ *
+ * @param s The Set to be converted.
+ * @return A Java Set view of the argument.
+ */
+ implicit def setAsJavaSet[A](s: Set[A]): ju.Set[A] = s match {
+ case JSetWrapper(wrapped) => wrapped
+ case _ => new SetWrapper(s)
+ }
+
+ /**
+ * Implicitly converts a Scala mutable Map to a Java Map.
+ * The returned Java Map is backed by the provided Scala
+ * Map and any side-effects of using it via the Java interface will
+ * be visible via the Scala interface and vice versa.
+ *
+ * If the Scala Map was previously obtained from an implicit or
+ * explicit call of `asMap(java.util.Map)` then the original
+ * Java Map will be returned.
+ *
+ * @param m The Map to be converted.
+ * @return A Java Map view of the argument.
+ */
+ implicit def mutableMapAsJavaMap[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = m match {
+ //case JConcurrentMapWrapper(wrapped) => wrapped
+ case JMapWrapper(wrapped) => wrapped
+ case _ => new MutableMapWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Scala mutable `Map` to a Java `Dictionary`.
+ *
+ * The returned Java `Dictionary` is backed by the provided Scala
+ * `Dictionary` and any side-effects of using it via the Java interface
+ * will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Dictionary` was previously obtained from an implicit or
+ * explicit call of `asMap(java.util.Dictionary)` then the original
+ * Java Dictionary will be returned.
+ *
+ * @param m The `Map` to be converted.
+ * @return A Java `Dictionary` view of the argument.
+ */
+ implicit def asJavaDictionary[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = m match {
+ //case JConcurrentMapWrapper(wrapped) => wrapped
+ case JDictionaryWrapper(wrapped) => wrapped
+ case _ => new DictionaryWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Scala `Map` to a Java `Map`.
+ *
+ * The returned Java `Map` is backed by the provided Scala `Map` and
+ * any side-effects of using it via the Java interface will be visible
+ * via the Scala interface and vice versa.
+ *
+ * If the Scala `Map` was previously obtained from an implicit or
+ * explicit call of `asMap(java.util.Map)` then the original
+ * Java `Map` will be returned.
+ *
+ * @param m The `Map` to be converted.
+ * @return A Java `Map` view of the argument.
+ */
+ implicit def mapAsJavaMap[A, B](m: Map[A, B]): ju.Map[A, B] = m match {
+ //case JConcurrentMapWrapper(wrapped) => wrapped
+ case JMapWrapper(wrapped) => wrapped.asInstanceOf[ju.Map[A, B]]
+ case _ => new MapWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Scala mutable `ConcurrentMap` to a Java
+ * `ConcurrentMap`.
+ *
+ * The returned Java `ConcurrentMap` is backed by the provided Scala
+ * `ConcurrentMap` and any side-effects of using it via the Java interface
+ * will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `ConcurrentMap` was previously obtained from an implicit or
+ * explicit call of `asScalaConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * then the original Java ConcurrentMap will be returned.
+ *
+ * @param m The `ConcurrentMap` to be converted.
+ * @return A Java `ConcurrentMap` view of the argument.
+ */
+ @deprecated("Use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0")
+ implicit def asJavaConcurrentMap[A, B](m: mutable.ConcurrentMap[A, B]): juc.ConcurrentMap[A, B] = m match {
+ case JConcurrentMapDeprecatedWrapper(wrapped) => wrapped
+ case _ => new ConcurrentMapDeprecatedWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Scala mutable `concurrent.Map` to a Java
+ * `ConcurrentMap`.
+ *
+ * The returned Java `ConcurrentMap` is backed by the provided Scala
+ * `concurrent.Map` and any side-effects of using it via the Java interface
+ * will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `concurrent.Map` was previously obtained from an implicit or
+ * explicit call of `mapAsScalaConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * then the original Java ConcurrentMap will be returned.
+ *
+ * @param m The Scala `concurrent.Map` to be converted.
+ * @return A Java `ConcurrentMap` view of the argument.
+ */
+ implicit def asJavaConcurrentMap[A, B](m: concurrent.Map[A, B]): juc.ConcurrentMap[A, B] = m match {
+ case JConcurrentMapWrapper(wrapped) => wrapped
+ case _ => new ConcurrentMapWrapper(m)
+ }
+}
+
+object WrapAsJava extends WrapAsJava { }
+
+
+
+
+
+
+
+
diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala
new file mode 100644
index 0000000000..14c64695ff
--- /dev/null
+++ b/src/library/scala/collection/convert/WrapAsScala.scala
@@ -0,0 +1,213 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+import Wrappers._
+import language.implicitConversions
+
+trait WrapAsScala {
+ /**
+ * Implicitly converts a Java `Iterator` to a Scala `Iterator`.
+ *
+ * The returned Scala `Iterator` is backed by the provided Java `Iterator`
+ * and any side-effects of using it via the Scala interface will be visible
+ * via the Java interface and vice versa.
+ *
+ * If the Java `Iterator` was previously obtained from an implicit or
+ * explicit call of `asIterator(scala.collection.Iterator)` then the
+ * original Scala `Iterator` will be returned.
+ *
+ * @param i The `Iterator` to be converted.
+ * @return A Scala `Iterator` view of the argument.
+ */
+ implicit def asScalaIterator[A](it: ju.Iterator[A]): Iterator[A] = it match {
+ case IteratorWrapper(wrapped) => wrapped
+ case _ => JIteratorWrapper(it)
+ }
+
+ /**
+ * Implicitly converts a Java Enumeration to a Scala Iterator.
+ * The returned Scala Iterator is backed by the provided Java
+ * Enumeration and any side-effects of using it via the Scala interface will
+ * be visible via the Java interface and vice versa.
+ *
+ * If the Java Enumeration was previously obtained from an implicit or
+ * explicit call of `enumerationAsScalaIterator(scala.collection.Iterator)`
+ * then the original Scala Iterator will be returned.
+ *
+ * @param i The Enumeration to be converted.
+ * @return A Scala Iterator view of the argument.
+ */
+ implicit def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = i match {
+ case IteratorWrapper(wrapped) => wrapped
+ case _ => JEnumerationWrapper(i)
+ }
+
+ /**
+ * Implicitly converts a Java `Iterable` to a Scala `Iterable`.
+ *
+ * The returned Scala `Iterable` is backed by the provided Java `Iterable`
+ * and any side-effects of using it via the Scala interface will be visible
+ * via the Java interface and vice versa.
+ *
+ * If the Java `Iterable` was previously obtained from an implicit or
+ * explicit call of `iterableAsScalaIterable(scala.collection.Iterable)`
+ * then the original Scala Iterable will be returned.
+ *
+ * @param i The Iterable to be converted.
+ * @return A Scala Iterable view of the argument.
+ */
+ implicit def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = i match {
+ case IterableWrapper(wrapped) => wrapped
+ case _ => JIterableWrapper(i)
+ }
+
+ /**
+ * Implicitly converts a Java `Collection` to an Scala `Iterable`.
+ *
+ * If the Java `Collection` was previously obtained from an implicit or
+ * explicit call of `collectionAsScalaIterable(scala.collection.SizedIterable)`
+ * then the original Scala `Iterable` will be returned.
+ *
+ * @param i The Collection to be converted.
+ * @return A Scala Iterable view of the argument.
+ */
+ implicit def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = i match {
+ case IterableWrapper(wrapped) => wrapped
+ case _ => JCollectionWrapper(i)
+ }
+
+ /**
+ * Implicitly converts a Java `List` to a Scala mutable `Buffer`.
+ *
+ * The returned Scala `Buffer` is backed by the provided Java `List`
+ * and any side-effects of using it via the Scala interface will
+ * be visible via the Java interface and vice versa.
+ *
+ * If the Java `List` was previously obtained from an implicit or
+ * explicit call of `asScalaBuffer(scala.collection.mutable.Buffer)`
+ * then the original Scala `Buffer` will be returned.
+ *
+ * @param l The `List` to be converted.
+ * @return A Scala mutable `Buffer` view of the argument.
+ */
+ implicit def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = l match {
+ case MutableBufferWrapper(wrapped) => wrapped
+ case _ =>new JListWrapper(l)
+ }
+
+ /**
+ * Implicitly converts a Java Set to a Scala mutable Set.
+ * The returned Scala Set is backed by the provided Java
+ * Set and any side-effects of using it via the Scala interface will
+ * be visible via the Java interface and vice versa.
+ *
+ * If the Java Set was previously obtained from an implicit or
+ * explicit call of `asScalaSet(scala.collection.mutable.Set)` then
+ * the original Scala Set will be returned.
+ *
+ * @param s The Set to be converted.
+ * @return A Scala mutable Set view of the argument.
+ */
+ implicit def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = s match {
+ case MutableSetWrapper(wrapped) => wrapped
+ case _ =>new JSetWrapper(s)
+ }
+
+ /**
+ * Implicitly converts a Java `Map` to a Scala mutable `Map`.
+ *
+ * The returned Scala `Map` is backed by the provided Java `Map` and any
+ * side-effects of using it via the Scala interface will be visible via
+ * the Java interface and vice versa.
+ *
+ * If the Java `Map` was previously obtained from an implicit or
+ * explicit call of `mapAsScalaMap(scala.collection.mutable.Map)` then
+ * the original Scala Map will be returned.
+ *
+ * @param m The Map to be converted.
+ * @return A Scala mutable Map view of the argument.
+ */
+ implicit def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = m match {
+ //case ConcurrentMapWrapper(wrapped) => wrapped
+ case MutableMapWrapper(wrapped) => wrapped
+ case _ => new JMapWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap.
+ * The returned Scala ConcurrentMap is backed by the provided Java
+ * ConcurrentMap and any side-effects of using it via the Scala interface will
+ * be visible via the Java interface and vice versa.
+ *
+ * If the Java ConcurrentMap was previously obtained from an implicit or
+ * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)`
+ * then the original Scala ConcurrentMap will be returned.
+ *
+ * @param m The ConcurrentMap to be converted.
+ * @return A Scala mutable ConcurrentMap view of the argument.
+ */
+ @deprecated("Use `mapAsScalaConcurrentMap` instead, and use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0")
+ def asScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = m match {
+ case cmw: ConcurrentMapDeprecatedWrapper[a, b] => cmw.underlying
+ case _ => new JConcurrentMapDeprecatedWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap.
+ * The returned Scala ConcurrentMap is backed by the provided Java
+ * ConcurrentMap and any side-effects of using it via the Scala interface will
+ * be visible via the Java interface and vice versa.
+ *
+ * If the Java ConcurrentMap was previously obtained from an implicit or
+ * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)`
+ * then the original Scala ConcurrentMap will be returned.
+ *
+ * @param m The ConcurrentMap to be converted.
+ * @return A Scala mutable ConcurrentMap view of the argument.
+ */
+ implicit def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = m match {
+ case cmw: ConcurrentMapWrapper[a, b] => cmw.underlying
+ case _ => new JConcurrentMapWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Java `Dictionary` to a Scala mutable
+ * `Map[String, String]`.
+ *
+ * The returned Scala `Map[String, String]` is backed by the provided Java
+ * `Dictionary` and any side-effects of using it via the Scala interface
+ * will be visible via the Java interface and vice versa.
+ *
+ * @param m The Dictionary to be converted.
+ * @return A Scala mutable Map[String, String] view of the argument.
+ */
+ implicit def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = p match {
+ case DictionaryWrapper(wrapped) => wrapped
+ case _ => new JDictionaryWrapper(p)
+ }
+
+ /**
+ * Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`.
+ *
+ * The returned Scala `Map[String, String]` is backed by the provided Java
+ * `Properties` and any side-effects of using it via the Scala interface
+ * will be visible via the Java interface and vice versa.
+ *
+ * @param m The Properties to be converted.
+ * @return A Scala mutable Map[String, String] view of the argument.
+ */
+ implicit def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = p match {
+ case _ => new JPropertiesWrapper(p)
+ }
+}
+
+object WrapAsScala extends WrapAsScala { }
diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala
new file mode 100644
index 0000000000..b1b48b760f
--- /dev/null
+++ b/src/library/scala/collection/convert/Wrappers.scala
@@ -0,0 +1,469 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+import WrapAsScala._
+import WrapAsJava._
+
+/** Don't put the implementations in the same scope as the implicits
+ * which utilize them, or they will stow away into every scope which
+ * extends one of those implementations. See SI-5580.
+ */
+private[collection] trait Wrappers {
+ trait IterableWrapperTrait[A] extends ju.AbstractCollection[A] {
+ val underlying: Iterable[A]
+ def size = underlying.size
+ override def iterator = IteratorWrapper(underlying.iterator)
+ override def isEmpty = underlying.isEmpty
+ }
+
+ case class IteratorWrapper[A](underlying: Iterator[A]) extends ju.Iterator[A] with ju.Enumeration[A] {
+ def hasNext = underlying.hasNext
+ def next() = underlying.next
+ def hasMoreElements = underlying.hasNext
+ def nextElement() = underlying.next
+ def remove() = throw new UnsupportedOperationException
+ }
+
+ class ToIteratorWrapper[A](underlying : Iterator[A]) {
+ def asJava = new IteratorWrapper(underlying)
+ }
+
+ case class JIteratorWrapper[A](underlying: ju.Iterator[A]) extends AbstractIterator[A] with Iterator[A] {
+ def hasNext = underlying.hasNext
+ def next() = underlying.next
+ }
+
+ case class JEnumerationWrapper[A](underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Iterator[A] {
+ def hasNext = underlying.hasMoreElements
+ def next() = underlying.nextElement
+ }
+
+ case class IterableWrapper[A](underlying: Iterable[A]) extends ju.AbstractCollection[A] with IterableWrapperTrait[A] { }
+
+ case class JIterableWrapper[A](underlying: jl.Iterable[A]) extends AbstractIterable[A] with Iterable[A] {
+ def iterator = underlying.iterator
+ def newBuilder[B] = new mutable.ArrayBuffer[B]
+ }
+
+ case class JCollectionWrapper[A](underlying: ju.Collection[A]) extends AbstractIterable[A] with Iterable[A] {
+ def iterator = underlying.iterator
+ override def size = underlying.size
+ override def isEmpty = underlying.isEmpty
+ def newBuilder[B] = new mutable.ArrayBuffer[B]
+ }
+
+ case class SeqWrapper[A](underlying: Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] {
+ def get(i: Int) = underlying(i)
+ }
+
+ case class MutableSeqWrapper[A](underlying: mutable.Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] {
+ def get(i: Int) = underlying(i)
+ override def set(i: Int, elem: A) = {
+ val p = underlying(i)
+ underlying(i) = elem
+ p
+ }
+ }
+
+ case class MutableBufferWrapper[A](underlying: mutable.Buffer[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] {
+ def get(i: Int) = underlying(i)
+ override def set(i: Int, elem: A) = { val p = underlying(i); underlying(i) = elem; p }
+ override def add(elem: A) = { underlying append elem; true }
+ override def remove(i: Int) = underlying remove i
+ }
+
+ case class JListWrapper[A](val underlying: ju.List[A]) extends mutable.AbstractBuffer[A] with mutable.Buffer[A] {
+ def length = underlying.size
+ override def isEmpty = underlying.isEmpty
+ override def iterator: Iterator[A] = underlying.iterator
+ def apply(i: Int) = underlying.get(i)
+ def update(i: Int, elem: A) = underlying.set(i, elem)
+ def +=:(elem: A) = { underlying.subList(0, 0) add elem; this }
+ def +=(elem: A): this.type = { underlying add elem; this }
+ def insertAll(i: Int, elems: Traversable[A]) = {
+ val ins = underlying.subList(0, i)
+ elems.seq.foreach(ins.add(_))
+ }
+ def remove(i: Int) = underlying.remove(i)
+ def clear() = underlying.clear()
+ def result = this
+ }
+
+ class SetWrapper[A](underlying: Set[A]) extends ju.AbstractSet[A] {
+ self =>
+ def size = underlying.size
+ def iterator = new ju.Iterator[A] {
+ val ui = underlying.iterator
+ var prev: Option[A] = None
+ def hasNext = ui.hasNext
+ def next = { val e = ui.next; prev = Some(e); e }
+ def remove = prev match {
+ case Some(e) =>
+ underlying match {
+ case ms: mutable.Set[a] =>
+ ms remove e
+ prev = None
+ case _ =>
+ throw new UnsupportedOperationException("remove")
+ }
+ case _ =>
+ throw new IllegalStateException("next must be called at least once before remove")
+ }
+ }
+ }
+
+ case class MutableSetWrapper[A](underlying: mutable.Set[A]) extends SetWrapper[A](underlying) {
+ override def add(elem: A) = {
+ val sz = underlying.size
+ underlying += elem
+ sz < underlying.size
+ }
+ override def remove(elem: AnyRef) =
+ try underlying remove elem.asInstanceOf[A]
+ catch { case ex: ClassCastException => false }
+ override def clear() = underlying.clear()
+ }
+
+ case class JSetWrapper[A](underlying: ju.Set[A]) extends mutable.AbstractSet[A] with mutable.Set[A] with mutable.SetLike[A, JSetWrapper[A]] {
+
+ override def size = underlying.size
+
+ def iterator = underlying.iterator
+
+ def contains(elem: A): Boolean = underlying.contains(elem)
+
+ def +=(elem: A): this.type = { underlying add elem; this }
+ def -=(elem: A): this.type = { underlying remove elem; this }
+
+ override def add(elem: A): Boolean = underlying add elem
+ override def remove(elem: A): Boolean = underlying remove elem
+ override def clear() = underlying.clear()
+
+ override def empty = JSetWrapper(new ju.HashSet[A])
+ }
+
+ class MapWrapper[A, B](underlying: Map[A, B]) extends ju.AbstractMap[A, B] { self =>
+ override def size = underlying.size
+
+ override def get(key: AnyRef): B = try {
+ underlying get key.asInstanceOf[A] match {
+ case None => null.asInstanceOf[B]
+ case Some(v) => v
+ }
+ } catch {
+ case ex: ClassCastException => null.asInstanceOf[B]
+ }
+
+ override def entrySet: ju.Set[ju.Map.Entry[A, B]] = new ju.AbstractSet[ju.Map.Entry[A, B]] {
+ def size = self.size
+
+ def iterator = new ju.Iterator[ju.Map.Entry[A, B]] {
+ val ui = underlying.iterator
+ var prev : Option[A] = None
+
+ def hasNext = ui.hasNext
+
+ def next() = {
+ val (k, v) = ui.next
+ prev = Some(k)
+ new ju.Map.Entry[A, B] {
+ def getKey = k
+ def getValue = v
+ def setValue(v1 : B) = self.put(k, v1)
+ override def hashCode = k.hashCode + v.hashCode
+ override def equals(other: Any) = other match {
+ case e: ju.Map.Entry[_, _] => k == e.getKey && v == e.getValue
+ case _ => false
+ }
+ }
+ }
+
+ def remove() {
+ prev match {
+ case Some(k) =>
+ underlying match {
+ case mm: mutable.Map[a, _] =>
+ mm remove k
+ prev = None
+ case _ =>
+ throw new UnsupportedOperationException("remove")
+ }
+ case _ =>
+ throw new IllegalStateException("next must be called at least once before remove")
+ }
+ }
+ }
+ }
+ }
+
+ case class MutableMapWrapper[A, B](underlying: mutable.Map[A, B]) extends MapWrapper[A, B](underlying) {
+ override def put(k: A, v: B) = underlying.put(k, v) match {
+ case Some(v1) => v1
+ case None => null.asInstanceOf[B]
+ }
+
+ override def remove(k: AnyRef): B = try {
+ underlying remove k.asInstanceOf[A] match {
+ case None => null.asInstanceOf[B]
+ case Some(v) => v
+ }
+ } catch {
+ case ex: ClassCastException => null.asInstanceOf[B]
+ }
+
+ override def clear() = underlying.clear()
+ }
+
+ trait JMapWrapperLike[A, B, +Repr <: mutable.MapLike[A, B, Repr] with mutable.Map[A, B]] extends mutable.Map[A, B] with mutable.MapLike[A, B, Repr] {
+ def underlying: ju.Map[A, B]
+
+ override def size = underlying.size
+
+ def get(k: A) = {
+ val v = underlying get k
+ if (v != null)
+ Some(v)
+ else if (underlying containsKey k)
+ Some(null.asInstanceOf[B])
+ else
+ None
+ }
+
+ def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this }
+ def -=(key: A): this.type = { underlying remove key; this }
+
+ override def put(k: A, v: B): Option[B] = {
+ val r = underlying.put(k, v)
+ if (r != null) Some(r) else None
+ }
+
+ override def update(k: A, v: B) { underlying.put(k, v) }
+
+ override def remove(k: A): Option[B] = {
+ val r = underlying remove k
+ if (r != null) Some(r) else None
+ }
+
+ def iterator: Iterator[(A, B)] = new AbstractIterator[(A, B)] {
+ val ui = underlying.entrySet.iterator
+ def hasNext = ui.hasNext
+ def next() = { val e = ui.next(); (e.getKey, e.getValue) }
+ }
+
+ override def clear() = underlying.clear()
+
+ override def empty: Repr = null.asInstanceOf[Repr]
+ }
+
+ case class JMapWrapper[A, B](val underlying : ju.Map[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JMapWrapper[A, B]] {
+ override def empty = JMapWrapper(new ju.HashMap[A, B])
+ }
+
+ class ConcurrentMapDeprecatedWrapper[A, B](override val underlying: mutable.ConcurrentMap[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] {
+
+ def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+
+ def remove(k: AnyRef, v: AnyRef) = try {
+ underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B])
+ } catch {
+ case ex: ClassCastException =>
+ false
+ }
+
+ def replace(k: A, v: B): B = underlying.replace(k, v) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+
+ def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
+ }
+
+ class ConcurrentMapWrapper[A, B](override val underlying: concurrent.Map[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] {
+
+ def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+
+ def remove(k: AnyRef, v: AnyRef) = try {
+ underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B])
+ } catch {
+ case ex: ClassCastException =>
+ false
+ }
+
+ def replace(k: A, v: B): B = underlying.replace(k, v) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+
+ def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
+ }
+
+ case class JConcurrentMapDeprecatedWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapDeprecatedWrapper[A, B]] with mutable.ConcurrentMap[A, B] {
+ override def get(k: A) = {
+ val v = underlying get k
+ if (v != null) Some(v)
+ else None
+ }
+
+ override def empty = new JConcurrentMapDeprecatedWrapper(new juc.ConcurrentHashMap[A, B])
+
+ def putIfAbsent(k: A, v: B): Option[B] = {
+ val r = underlying.putIfAbsent(k, v)
+ if (r != null) Some(r) else None
+ }
+
+ def remove(k: A, v: B): Boolean = underlying.remove(k, v)
+
+ def replace(k: A, v: B): Option[B] = {
+ val prev = underlying.replace(k, v)
+ if (prev != null) Some(prev) else None
+ }
+
+ def replace(k: A, oldvalue: B, newvalue: B): Boolean =
+ underlying.replace(k, oldvalue, newvalue)
+ }
+
+ case class JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with concurrent.Map[A, B] {
+ override def get(k: A) = {
+ val v = underlying get k
+ if (v != null) Some(v)
+ else None
+ }
+
+ override def empty = new JConcurrentMapWrapper(new juc.ConcurrentHashMap[A, B])
+
+ def putIfAbsent(k: A, v: B): Option[B] = {
+ val r = underlying.putIfAbsent(k, v)
+ if (r != null) Some(r) else None
+ }
+
+ def remove(k: A, v: B): Boolean = underlying.remove(k, v)
+
+ def replace(k: A, v: B): Option[B] = {
+ val prev = underlying.replace(k, v)
+ if (prev != null) Some(prev) else None
+ }
+
+ def replace(k: A, oldvalue: B, newvalue: B): Boolean =
+ underlying.replace(k, oldvalue, newvalue)
+ }
+
+ case class DictionaryWrapper[A, B](underlying: mutable.Map[A, B]) extends ju.Dictionary[A, B] {
+ def size: Int = underlying.size
+ def isEmpty: Boolean = underlying.isEmpty
+ def keys: ju.Enumeration[A] = asJavaEnumeration(underlying.keysIterator)
+ def elements: ju.Enumeration[B] = asJavaEnumeration(underlying.valuesIterator)
+ def get(key: AnyRef) = try {
+ underlying get key.asInstanceOf[A] match {
+ case None => null.asInstanceOf[B]
+ case Some(v) => v
+ }
+ } catch {
+ case ex: ClassCastException => null.asInstanceOf[B]
+ }
+ def put(key: A, value: B): B = underlying.put(key, value) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+ override def remove(key: AnyRef) = try {
+ underlying remove key.asInstanceOf[A] match {
+ case None => null.asInstanceOf[B]
+ case Some(v) => v
+ }
+ } catch {
+ case ex: ClassCastException => null.asInstanceOf[B]
+ }
+ }
+
+ case class JDictionaryWrapper[A, B](underlying: ju.Dictionary[A, B]) extends mutable.AbstractMap[A, B] with mutable.Map[A, B] {
+ override def size: Int = underlying.size
+
+ def get(k: A) = {
+ val v = underlying get k
+ if (v != null) Some(v) else None
+ }
+
+ def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this }
+ def -=(key: A): this.type = { underlying remove key; this }
+
+ override def put(k: A, v: B): Option[B] = {
+ val r = underlying.put(k, v)
+ if (r != null) Some(r) else None
+ }
+
+ override def update(k: A, v: B) { underlying.put(k, v) }
+
+ override def remove(k: A): Option[B] = {
+ val r = underlying remove k
+ if (r != null) Some(r) else None
+ }
+
+ def iterator = enumerationAsScalaIterator(underlying.keys) map (k => (k, underlying get k))
+
+ override def clear() = underlying.clear()
+ }
+
+ case class JPropertiesWrapper(underlying: ju.Properties) extends mutable.AbstractMap[String, String]
+ with mutable.Map[String, String]
+ with mutable.MapLike[String, String, JPropertiesWrapper] {
+
+ override def size = underlying.size
+
+ def get(k: String) = {
+ val v = underlying get k
+ if (v != null) Some(v.asInstanceOf[String]) else None
+ }
+
+ def +=(kv: (String, String)): this.type = { underlying.put(kv._1, kv._2); this }
+ def -=(key: String): this.type = { underlying remove key; this }
+
+ override def put(k: String, v: String): Option[String] = {
+ val r = underlying.put(k, v)
+ if (r != null) Some(r.asInstanceOf[String]) else None
+ }
+
+ override def update(k: String, v: String) { underlying.put(k, v) }
+
+ override def remove(k: String): Option[String] = {
+ val r = underlying remove k
+ if (r != null) Some(r.asInstanceOf[String]) else None
+ }
+
+ def iterator: Iterator[(String, String)] = new AbstractIterator[(String, String)] {
+ val ui = underlying.entrySet.iterator
+ def hasNext = ui.hasNext
+ def next() = {
+ val e = ui.next()
+ (e.getKey.asInstanceOf[String], e.getValue.asInstanceOf[String])
+ }
+ }
+
+ override def clear() = underlying.clear()
+
+ override def empty = JPropertiesWrapper(new ju.Properties)
+
+ def getProperty(key: String) = underlying.getProperty(key)
+
+ def getProperty(key: String, defaultValue: String) =
+ underlying.getProperty(key, defaultValue)
+
+ def setProperty(key: String, value: String) =
+ underlying.setProperty(key, value)
+ }
+}
+
+object Wrappers extends Wrappers
diff --git a/src/library/scala/collection/convert/package.scala b/src/library/scala/collection/convert/package.scala
new file mode 100644
index 0000000000..2f8bca1e1f
--- /dev/null
+++ b/src/library/scala/collection/convert/package.scala
@@ -0,0 +1,18 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+
+package object convert {
+ val decorateAsJava = new DecorateAsJava { }
+ val decorateAsScala = new DecorateAsScala { }
+ val decorateAll = new DecorateAsJava with DecorateAsScala { }
+ val wrapAsJava = new WrapAsJava { }
+ val wrapAsScala = new WrapAsScala { }
+ val wrapAll = new WrapAsJava with WrapAsScala { }
+}
diff --git a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala b/src/library/scala/collection/generic/ArrayTagTraversableFactory.scala
index e54ce9cdbf..d9ab17559e 100644
--- a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala
+++ b/src/library/scala/collection/generic/ArrayTagTraversableFactory.scala
@@ -9,7 +9,9 @@
package scala.collection
package generic
-/** A template for companion objects of `ClassManifestTraversable` and
+import language.higherKinds
+
+/** A template for companion objects of `ClassTagTraversable` and
* subclasses thereof.
*
* @define coll collection
@@ -19,11 +21,11 @@ package generic
* @author Aleksandar Prokopec
* @since 2.8
*/
-abstract class ClassManifestTraversableFactory[CC[X] <: Traversable[X] with GenericClassManifestTraversableTemplate[X, CC]]
- extends GenericClassManifestCompanion[CC] {
+abstract class ArrayTagTraversableFactory[CC[X] <: Traversable[X] with GenericArrayTagTraversableTemplate[X, CC]]
+ extends GenericArrayTagCompanion[CC] {
- class GenericCanBuildFrom[A](implicit manif: ClassManifest[A]) extends CanBuildFrom[CC[_], A, CC[A]] {
- def apply(from: CC[_]) = from.genericClassManifestBuilder[A]
+ class GenericCanBuildFrom[A](implicit tag: ArrayTag[A]) extends CanBuildFrom[CC[_], A, CC[A]] {
+ def apply(from: CC[_]) = from.genericArrayTagBuilder[A]
def apply = newBuilder[A]
}
}
diff --git a/src/library/scala/collection/generic/GenMapFactory.scala b/src/library/scala/collection/generic/GenMapFactory.scala
index d6f6978ead..b3faf0497b 100644
--- a/src/library/scala/collection/generic/GenMapFactory.scala
+++ b/src/library/scala/collection/generic/GenMapFactory.scala
@@ -10,6 +10,7 @@ package scala.collection
package generic
import mutable.{Builder, MapBuilder}
+import language.higherKinds
/** A template for companion objects of `Map` and subclasses thereof.
*
diff --git a/src/library/scala/collection/generic/GenSeqFactory.scala b/src/library/scala/collection/generic/GenSeqFactory.scala
index ee6ecae3c2..3bd63c08b8 100644
--- a/src/library/scala/collection/generic/GenSeqFactory.scala
+++ b/src/library/scala/collection/generic/GenSeqFactory.scala
@@ -12,6 +12,7 @@ package scala.collection
package generic
import annotation.bridge
+import language.higherKinds
/** A template for companion objects of Seq and subclasses thereof.
*
diff --git a/src/library/scala/collection/generic/GenSetFactory.scala b/src/library/scala/collection/generic/GenSetFactory.scala
index d83f248aff..caae8afa1c 100644
--- a/src/library/scala/collection/generic/GenSetFactory.scala
+++ b/src/library/scala/collection/generic/GenSetFactory.scala
@@ -12,6 +12,7 @@ package scala.collection
package generic
import mutable.Builder
+import language.higherKinds
/** A template for companion objects of `Set` and subclasses thereof.
*
diff --git a/src/library/scala/collection/generic/GenTraversableFactory.scala b/src/library/scala/collection/generic/GenTraversableFactory.scala
index 34cbe1a7f2..f233a40d35 100644
--- a/src/library/scala/collection/generic/GenTraversableFactory.scala
+++ b/src/library/scala/collection/generic/GenTraversableFactory.scala
@@ -10,6 +10,8 @@
package scala.collection
package generic
+import language.higherKinds
+
/** A template for companion objects of `Traversable` and subclasses thereof.
* This class provides a set of operations to create `$Coll` objects.
* It is typically inherited by companion objects of subclasses of `Traversable`.
@@ -71,7 +73,7 @@ abstract class GenTraversableFactory[CC[X] <: GenTraversable[X] with GenericTrav
val b = newBuilder[A]
// At present we're using IndexedSeq as a proxy for "has a cheap size method".
if (xss forall (_.isInstanceOf[IndexedSeq[_]]))
- b.sizeHint(xss map (_.size) sum)
+ b.sizeHint(xss.map(_.size).sum)
for (xs <- xss.seq) b ++= xs
b.result
diff --git a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala b/src/library/scala/collection/generic/GenericArrayTagCompanion.scala
index 546e82fb4a..959adbce6d 100644
--- a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala
+++ b/src/library/scala/collection/generic/GenericArrayTagCompanion.scala
@@ -10,20 +10,21 @@ package scala.collection
package generic
import mutable.Builder
+import language.higherKinds
-/** This class represents companions of classes which require ClassManifests
+/** This class represents companions of classes which require ArrayTags
* for their element types.
*
* @author Aleksandar Prokopec
*/
-abstract class GenericClassManifestCompanion[+CC[X] <: Traversable[X]] {
+abstract class GenericArrayTagCompanion[+CC[X] <: Traversable[X]] {
type Coll = CC[_]
- def newBuilder[A](implicit ord: ClassManifest[A]): Builder[A, CC[A]]
+ def newBuilder[A](implicit ord: ArrayTag[A]): Builder[A, CC[A]]
- def empty[A: ClassManifest]: CC[A] = newBuilder[A].result
+ def empty[A: ArrayTag]: CC[A] = newBuilder[A].result
- def apply[A](elems: A*)(implicit ord: ClassManifest[A]): CC[A] = {
+ def apply[A](elems: A*)(implicit ord: ArrayTag[A]): CC[A] = {
val b = newBuilder[A]
b ++= elems
b.result
diff --git a/src/library/scala/collection/generic/GenericArrayTagTraversableTemplate.scala b/src/library/scala/collection/generic/GenericArrayTagTraversableTemplate.scala
new file mode 100644
index 0000000000..ac84683c59
--- /dev/null
+++ b/src/library/scala/collection/generic/GenericArrayTagTraversableTemplate.scala
@@ -0,0 +1,30 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package generic
+
+import mutable.Builder
+import annotation.unchecked.uncheckedVariance
+import language.higherKinds
+
+/** This trait represents collections classes which require array
+ * tags for their element types.
+ *
+ * @author Aleksandar Prokopec
+ * @since 2.8
+ */
+trait GenericArrayTagTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance] {
+ implicit protected[this] val tag: ArrayTag[A]
+ def arrayTagCompanion: GenericArrayTagCompanion[CC]
+ def genericArrayTagBuilder[B](implicit tag: ArrayTag[B]): Builder[B, CC[B]] = arrayTagCompanion.newBuilder[B]
+ @deprecated("use arrayTagCompanion instead", "2.10.0")
+ def classManifestCompanion: GenericClassManifestCompanion[CC] = arrayTagCompanion
+ @deprecated("use genericArrayTagBuilder instead", "2.10.0")
+ def genericClassManifestBuilder[B](implicit manifest: ClassManifest[B]): Builder[B, CC[B]] = genericArrayTagBuilder[B](manifest)
+}
diff --git a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala b/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala
deleted file mode 100644
index 12b5a495f0..0000000000
--- a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2010-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.collection
-package generic
-
-import mutable.Builder
-import annotation.unchecked.uncheckedVariance
-
-/** This trait represents collections classes which require class
- * manifests for their element types.
- *
- * @author Aleksandar Prokopec
- * @since 2.8
- */
-trait GenericClassManifestTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance] {
- implicit protected[this] val manifest: ClassManifest[A]
- def classManifestCompanion: GenericClassManifestCompanion[CC]
- def genericClassManifestBuilder[B](implicit man: ClassManifest[B]): Builder[B, CC[B]] = classManifestCompanion.newBuilder[B]
-}
diff --git a/src/library/scala/collection/generic/GenericCompanion.scala b/src/library/scala/collection/generic/GenericCompanion.scala
index b36a1e297f..cf01cf5f08 100644
--- a/src/library/scala/collection/generic/GenericCompanion.scala
+++ b/src/library/scala/collection/generic/GenericCompanion.scala
@@ -10,6 +10,7 @@ package scala.collection
package generic
import mutable.Builder
+import language.higherKinds
/** A template class for companion objects of "regular" collection classes
* represent an unconstrained higher-kinded type. Typically
diff --git a/src/library/scala/collection/generic/GenericOrderedCompanion.scala b/src/library/scala/collection/generic/GenericOrderedCompanion.scala
index c3baa28147..290dc435c8 100644
--- a/src/library/scala/collection/generic/GenericOrderedCompanion.scala
+++ b/src/library/scala/collection/generic/GenericOrderedCompanion.scala
@@ -10,6 +10,7 @@ package scala.collection
package generic
import mutable.Builder
+import language.higherKinds
/** This class represents companions of classes which require the ordered trait
* for their element types.
diff --git a/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala b/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala
index 5cfc4666b3..6e04420315 100644
--- a/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala
+++ b/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala
@@ -13,8 +13,7 @@ package generic
import mutable.Builder
import annotation.unchecked.uncheckedVariance
-
-
+import language.higherKinds
/** This trait represents collections classes which require
* ordered element types.
diff --git a/src/library/scala/collection/generic/GenericParCompanion.scala b/src/library/scala/collection/generic/GenericParCompanion.scala
index 40fcfa31d0..93c166b7ba 100644
--- a/src/library/scala/collection/generic/GenericParCompanion.scala
+++ b/src/library/scala/collection/generic/GenericParCompanion.scala
@@ -11,6 +11,7 @@ package scala.collection.generic
import scala.collection.parallel.Combiner
import scala.collection.parallel.ParIterable
import scala.collection.parallel.ParMap
+import language.higherKinds
/** A template class for companion objects of parallel collection classes.
* They should be mixed in together with `GenericCompanion` type.
diff --git a/src/library/scala/collection/generic/GenericParTemplate.scala b/src/library/scala/collection/generic/GenericParTemplate.scala
index 430dcb9e29..fc1c3f5eaa 100644
--- a/src/library/scala/collection/generic/GenericParTemplate.scala
+++ b/src/library/scala/collection/generic/GenericParTemplate.scala
@@ -14,6 +14,7 @@ import scala.collection.parallel.ParMap
import scala.collection.parallel.TaskSupport
import annotation.unchecked.uncheckedVariance
+import language.higherKinds
/** A template trait for collections having a companion.
*
diff --git a/src/library/scala/collection/generic/GenericSeqCompanion.scala b/src/library/scala/collection/generic/GenericSeqCompanion.scala
index 41e8d6dd39..4c0c34733c 100644
--- a/src/library/scala/collection/generic/GenericSeqCompanion.scala
+++ b/src/library/scala/collection/generic/GenericSeqCompanion.scala
@@ -11,6 +11,7 @@ package scala.collection
package generic
import annotation.bridge
+import language.higherKinds
trait GenericSeqCompanion[CC[X] <: Traversable[X]]
extends GenericCompanion[CC] {
diff --git a/src/library/scala/collection/generic/GenericSetTemplate.scala b/src/library/scala/collection/generic/GenericSetTemplate.scala
index 6af6a36981..221bcfb379 100644
--- a/src/library/scala/collection/generic/GenericSetTemplate.scala
+++ b/src/library/scala/collection/generic/GenericSetTemplate.scala
@@ -8,7 +8,7 @@
package scala.collection
package generic
-
+import language.higherKinds
/**
* @since 2.8
*/
diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
index 6586434924..b26e07393c 100644
--- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala
+++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
@@ -14,6 +14,7 @@ package generic
import mutable.Builder
import annotation.migration
import annotation.unchecked.uncheckedVariance
+import language.higherKinds
/** A template class for companion objects of ``regular`` collection classes
* that represent an unconstrained higher-kinded type.
diff --git a/src/library/scala/collection/generic/ImmutableMapFactory.scala b/src/library/scala/collection/generic/ImmutableMapFactory.scala
index bdb657f320..d893188e92 100644
--- a/src/library/scala/collection/generic/ImmutableMapFactory.scala
+++ b/src/library/scala/collection/generic/ImmutableMapFactory.scala
@@ -10,6 +10,8 @@
package scala.collection
package generic
+import language.higherKinds
+
/** A template for companion objects of `immutable.Map` and subclasses thereof.
* @author Martin Odersky
* @version 2.8
diff --git a/src/library/scala/collection/generic/ImmutableSetFactory.scala b/src/library/scala/collection/generic/ImmutableSetFactory.scala
index e128be70a1..7bd5bf2ef8 100644
--- a/src/library/scala/collection/generic/ImmutableSetFactory.scala
+++ b/src/library/scala/collection/generic/ImmutableSetFactory.scala
@@ -10,6 +10,7 @@ package scala.collection
package generic
import mutable.{ Builder, SetBuilder }
+import language.higherKinds
abstract class ImmutableSetFactory[CC[X] <: immutable.Set[X] with SetLike[X, CC[X]]]
extends SetFactory[CC] {
diff --git a/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala b/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala
index 89e19eed87..93aae0e355 100644
--- a/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala
+++ b/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala
@@ -11,6 +11,8 @@
package scala.collection
package generic
+import language.higherKinds
+
/** A template for companion objects of `SortedMap` and subclasses thereof.
*
* @since 2.8
diff --git a/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala b/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala
index fe807d9fe6..67fb72270c 100644
--- a/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala
+++ b/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala
@@ -11,6 +11,8 @@
package scala.collection
package generic
+import language.higherKinds
+
/** A template for companion objects of `SortedSet` and subclasses thereof.
*
* @since 2.8
@@ -23,4 +25,4 @@ package generic
* @define sortedSetCanBuildFromInfo
* The standard `CanBuildFrom` instance for sorted sets
*/
-abstract class ImmutableSortedSetFactory[CC[A] <: immutable.SortedSet[A] with SortedSetLike[A, CC[A]]] extends SortedSetFactory[CC] \ No newline at end of file
+abstract class ImmutableSortedSetFactory[CC[A] <: immutable.SortedSet[A] with SortedSetLike[A, CC[A]]] extends SortedSetFactory[CC]
diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala
index a60e3032c1..e502c4067e 100644
--- a/src/library/scala/collection/generic/MapFactory.scala
+++ b/src/library/scala/collection/generic/MapFactory.scala
@@ -12,6 +12,7 @@ package generic
import mutable.{Builder, MapBuilder}
import annotation.bridge
+import language.higherKinds
/** A template for companion objects of `Map` and subclasses thereof.
*
diff --git a/src/library/scala/collection/generic/MutableMapFactory.scala b/src/library/scala/collection/generic/MutableMapFactory.scala
index 076e41c9f8..8b38b4ddd5 100644
--- a/src/library/scala/collection/generic/MutableMapFactory.scala
+++ b/src/library/scala/collection/generic/MutableMapFactory.scala
@@ -12,6 +12,7 @@ package scala.collection
package generic
import mutable.Builder
+import language.higherKinds
/** A template for companion objects of `mutable.Map` and subclasses thereof.
* @author Martin Odersky
diff --git a/src/library/scala/collection/generic/MutableSetFactory.scala b/src/library/scala/collection/generic/MutableSetFactory.scala
index 6130ef2042..f130489814 100644
--- a/src/library/scala/collection/generic/MutableSetFactory.scala
+++ b/src/library/scala/collection/generic/MutableSetFactory.scala
@@ -10,6 +10,7 @@ package scala.collection
package generic
import mutable.{ Builder, GrowingBuilder }
+import language.higherKinds
abstract class MutableSetFactory[CC[X] <: mutable.Set[X] with mutable.SetLike[X, CC[X]]]
extends SetFactory[CC] {
diff --git a/src/library/scala/collection/generic/MutableSortedSetFactory.scala b/src/library/scala/collection/generic/MutableSortedSetFactory.scala
index cbbedc0231..b0dd23ee1a 100644
--- a/src/library/scala/collection/generic/MutableSortedSetFactory.scala
+++ b/src/library/scala/collection/generic/MutableSortedSetFactory.scala
@@ -10,6 +10,7 @@ package scala.collection
package generic
import scala.collection.mutable.{ Builder, GrowingBuilder }
+import language.higherKinds
/**
* @define Coll mutable.SortedSet
diff --git a/src/library/scala/collection/generic/OrderedTraversableFactory.scala b/src/library/scala/collection/generic/OrderedTraversableFactory.scala
index 259e4123c4..92f166ae08 100644
--- a/src/library/scala/collection/generic/OrderedTraversableFactory.scala
+++ b/src/library/scala/collection/generic/OrderedTraversableFactory.scala
@@ -10,9 +10,7 @@
package scala.collection
package generic
-
-
-
+import language.higherKinds
abstract class OrderedTraversableFactory[CC[X] <: Traversable[X] with GenericOrderedTraversableTemplate[X, CC]]
extends GenericOrderedCompanion[CC] {
diff --git a/src/library/scala/collection/generic/ParFactory.scala b/src/library/scala/collection/generic/ParFactory.scala
index 558024d45c..0829ba6616 100644
--- a/src/library/scala/collection/generic/ParFactory.scala
+++ b/src/library/scala/collection/generic/ParFactory.scala
@@ -10,6 +10,7 @@ package scala.collection.generic
import scala.collection.parallel.ParIterable
import scala.collection.parallel.Combiner
+import language.higherKinds
/** A template class for companion objects of `ParIterable` and subclasses
* thereof. This class extends `TraversableFactory` and provides a set of
diff --git a/src/library/scala/collection/generic/ParMapFactory.scala b/src/library/scala/collection/generic/ParMapFactory.scala
index 2d89f79c13..c05ab73431 100644
--- a/src/library/scala/collection/generic/ParMapFactory.scala
+++ b/src/library/scala/collection/generic/ParMapFactory.scala
@@ -12,6 +12,7 @@ import scala.collection.parallel.ParMap
import scala.collection.parallel.ParMapLike
import scala.collection.parallel.Combiner
import scala.collection.mutable.Builder
+import language.higherKinds
/** A template class for companion objects of `ParMap` and subclasses thereof.
* This class extends `TraversableFactory` and provides a set of operations
diff --git a/src/library/scala/collection/generic/ParSetFactory.scala b/src/library/scala/collection/generic/ParSetFactory.scala
index c2cf971d73..30a36a734a 100644
--- a/src/library/scala/collection/generic/ParSetFactory.scala
+++ b/src/library/scala/collection/generic/ParSetFactory.scala
@@ -12,6 +12,7 @@ import collection.mutable.Builder
import collection.parallel.Combiner
import collection.parallel.ParSet
import collection.parallel.ParSetLike
+import language.higherKinds
/**
* @author Aleksandar Prokopec
diff --git a/src/library/scala/collection/generic/SeqFactory.scala b/src/library/scala/collection/generic/SeqFactory.scala
index 7bd92173ff..3f61de6ceb 100644
--- a/src/library/scala/collection/generic/SeqFactory.scala
+++ b/src/library/scala/collection/generic/SeqFactory.scala
@@ -10,6 +10,7 @@
package scala.collection
package generic
+import language.higherKinds
/** A template for companion objects of Seq and subclasses thereof.
*
diff --git a/src/library/scala/collection/generic/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala
index 348743a120..fb99f83ebb 100644
--- a/src/library/scala/collection/generic/SetFactory.scala
+++ b/src/library/scala/collection/generic/SetFactory.scala
@@ -13,6 +13,7 @@ package generic
import mutable.Builder
import annotation.bridge
+import language.higherKinds
abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]]
extends GenSetFactory[CC] with GenericSeqCompanion[CC] {
diff --git a/src/library/scala/collection/generic/SortedMapFactory.scala b/src/library/scala/collection/generic/SortedMapFactory.scala
index 962a945037..f038c8b09b 100644
--- a/src/library/scala/collection/generic/SortedMapFactory.scala
+++ b/src/library/scala/collection/generic/SortedMapFactory.scala
@@ -12,6 +12,7 @@ package scala.collection
package generic
import mutable.{Builder, MapBuilder}
+import language.higherKinds
/** A template for companion objects of mutable.Map and subclasses thereof.
*
diff --git a/src/library/scala/collection/generic/SortedSetFactory.scala b/src/library/scala/collection/generic/SortedSetFactory.scala
index 45340cf6c1..bb261803a9 100644
--- a/src/library/scala/collection/generic/SortedSetFactory.scala
+++ b/src/library/scala/collection/generic/SortedSetFactory.scala
@@ -12,6 +12,7 @@ package scala.collection
package generic
import mutable.{Builder, SetBuilder}
+import language.higherKinds
/** A template for companion objects of Set and subclasses thereof.
*
diff --git a/src/library/scala/collection/generic/TraversableFactory.scala b/src/library/scala/collection/generic/TraversableFactory.scala
index e71de1252c..07da1bb5c2 100644
--- a/src/library/scala/collection/generic/TraversableFactory.scala
+++ b/src/library/scala/collection/generic/TraversableFactory.scala
@@ -11,6 +11,7 @@ package scala.collection
package generic
import annotation.bridge
+import language.higherKinds
/** A template for companion objects of `Traversable` and subclasses thereof.
* This class provides a set of operations to create `$Coll` objects.
diff --git a/src/library/scala/collection/generic/TraversableForwarder.scala b/src/library/scala/collection/generic/TraversableForwarder.scala
index 3d723a1feb..3d5bc2704f 100644
--- a/src/library/scala/collection/generic/TraversableForwarder.scala
+++ b/src/library/scala/collection/generic/TraversableForwarder.scala
@@ -57,7 +57,7 @@ trait TraversableForwarder[+A] extends Traversable[A] {
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) = underlying.copyToArray(xs, start, len)
override def copyToArray[B >: A](xs: Array[B], start: Int) = underlying.copyToArray(xs, start)
override def copyToArray[B >: A](xs: Array[B]) = underlying.copyToArray(xs)
- override def toArray[B >: A: ClassManifest]: Array[B] = underlying.toArray
+ override def toArray[B >: A: ArrayTag]: Array[B] = underlying.toArray
override def toList: List[A] = underlying.toList
override def toIterable: Iterable[A] = underlying.toIterable
override def toSeq: Seq[A] = underlying.toSeq
diff --git a/src/library/scala/collection/generic/package.scala b/src/library/scala/collection/generic/package.scala
index 0457fef227..32006b4bf0 100644
--- a/src/library/scala/collection/generic/package.scala
+++ b/src/library/scala/collection/generic/package.scala
@@ -3,4 +3,13 @@ import generic.CanBuildFrom
package object generic {
type CanBuild[-Elem, +To] = CanBuildFrom[Nothing, Elem, To]
+
+ @deprecated("use ArrayTagTraversableFactory instead", "2.10.0")
+ type ClassManifestTraversableFactory[CC[X] <: Traversable[X] with GenericClassManifestTraversableTemplate[X, CC]] = ArrayTagTraversableFactory[CC]
+
+ @deprecated("use GenericArrayTagCompanion instead", "2.10.0")
+ type GenericClassManifestCompanion[+CC[X] <: Traversable[X]] = GenericArrayTagCompanion[CC]
+
+ @deprecated("use GenericArrayTagTraversableTemplate instead", "2.10.0")
+ type GenericClassManifestTraversableTemplate[+A, +CC[X] <: Traversable[X]] = GenericArrayTagTraversableTemplate[A, CC]
} \ No newline at end of file
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index 870c179b2d..1b75c10113 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -58,7 +58,7 @@ import java.io._
* @author Martin Odersky and others
* @version 2.8
* @since 1.0
- * @see [["http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#lists" "Scala's Collection Library overview"]]
+ * @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#lists "Scala's Collection Library overview"]]
* section on `Lists` for more information.
*
* @define coll list
diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala
index 47e3245117..b71071d3c0 100644
--- a/src/library/scala/collection/immutable/ListSet.scala
+++ b/src/library/scala/collection/immutable/ListSet.scala
@@ -33,7 +33,7 @@ object ListSet extends ImmutableSetFactory[ListSet] {
*/
class ListSetBuilder[Elem](initial: ListSet[Elem]) extends Builder[Elem, ListSet[Elem]] {
def this() = this(empty[Elem])
- protected val elems = new mutable.ListBuffer[Elem] ++= initial reverse
+ protected val elems = (new mutable.ListBuffer[Elem] ++= initial).reverse
protected val seen = new mutable.HashSet[Elem] ++= initial
def +=(x: Elem): this.type = {
@@ -100,7 +100,7 @@ class ListSet[A] extends AbstractSet[A]
*/
override def ++(xs: GenTraversableOnce[A]): ListSet[A] =
if (xs.isEmpty) this
- else new ListSet.ListSetBuilder(this) ++= xs.seq result
+ else (new ListSet.ListSetBuilder(this) ++= xs.seq).result
@bridge def ++(xs: TraversableOnce[A]): ListSet[A] = ++(xs: GenTraversableOnce[A]): ListSet[A]
diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala
index 65bd9ab6f2..0966fa035f 100644
--- a/src/library/scala/collection/immutable/NumericRange.scala
+++ b/src/library/scala/collection/immutable/NumericRange.scala
@@ -172,6 +172,13 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable {
try containsTyped(x.asInstanceOf[T])
catch { case _: ClassCastException => false }
+ final override def sum[B >: T](implicit num: Numeric[B]): B = {
+ import num.Ops
+ if (isEmpty) this.num fromInt 0
+ else if (numRangeElements == 1) head
+ else ((this.num fromInt numRangeElements) * (head + last) / (this.num fromInt 2))
+ }
+
override lazy val hashCode = super.hashCode()
override def equals(other: Any) = other match {
case x: NumericRange[_] =>
diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala
index 97c7c789f8..68c75ee586 100644
--- a/src/library/scala/collection/immutable/PagedSeq.scala
+++ b/src/library/scala/collection/immutable/PagedSeq.scala
@@ -25,7 +25,7 @@ object PagedSeq {
final val UndeterminedEnd = Int.MaxValue
/** Constructs a paged sequence from an iterator */
- def fromIterator[T: ClassManifest](source: Iterator[T]): PagedSeq[T] =
+ def fromIterator[T: ArrayTag](source: Iterator[T]): PagedSeq[T] =
new PagedSeq[T]((data: Array[T], start: Int, len: Int) => {
var i = 0
while (i < len && source.hasNext) {
@@ -36,7 +36,7 @@ object PagedSeq {
})
/** Constructs a paged sequence from an iterable */
- def fromIterable[T: ClassManifest](source: Iterable[T]): PagedSeq[T] =
+ def fromIterable[T: ArrayTag](source: Iterable[T]): PagedSeq[T] =
fromIterator(source.iterator)
/** Constructs a paged character sequence from a string iterator */
@@ -115,7 +115,7 @@ import PagedSeq._
* It returns the number of elements produced, or -1 if end of logical input stream was reached
* before reading any element.
*
- * @tparam T the type of the elements contained in this paged sequence, with a `ClassManifest` context bound.
+ * @tparam T the type of the elements contained in this paged sequence, with an `ArrayTag` context bound.
*
* @author Martin Odersky
* @since 2.7
@@ -124,7 +124,7 @@ import PagedSeq._
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-class PagedSeq[T: ClassManifest] protected(
+class PagedSeq[T: ArrayTag] protected(
more: (Array[T], Int, Int) => Int,
first1: Page[T],
start: Int,
@@ -205,7 +205,7 @@ extends scala.collection.AbstractSeq[T]
/** Page containing up to PageSize characters of the input sequence.
*/
-private class Page[T: ClassManifest](val num: Int) {
+private class Page[T: ArrayTag](val num: Int) {
private final val PageSize = 4096
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 2eb2f8eb09..2df4ed70c7 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -13,6 +13,7 @@ import generic._
import mutable.{Builder, StringBuilder, LazyBuilder, ListBuffer}
import scala.annotation.tailrec
import Stream.cons
+import language.implicitConversions
/** The class `Stream` implements lazy lists where elements
* are only evaluated when they are needed. Here is an example:
@@ -821,7 +822,7 @@ self =>
*/
override def distinct: Stream[A] =
if (isEmpty) this
- else cons(head, tail.filter(head !=).distinct)
+ else cons(head, tail.filter(head != _).distinct)
/** Returns a new sequence of given length containing the elements of this
* sequence followed by zero or more occurrences of given elements.
diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala
index f9697565de..52032a1cde 100644
--- a/src/library/scala/collection/immutable/StringLike.scala
+++ b/src/library/scala/collection/immutable/StringLike.scala
@@ -60,7 +60,7 @@ self =>
val end = until min length
if (start >= end) newBuilder.result
- else newBuilder ++= toString.substring(start, end) result
+ else (newBuilder ++= toString.substring(start, end)).result
}
/** Return the current string concatenated `n` times.
@@ -207,9 +207,20 @@ self =>
/** You can follow a string with `.r`, turning it into a `Regex`. E.g.
*
- * """A\w*""".r is the regular expression for identifiers starting with `A`.
+ * `"""A\w*""".r` is the regular expression for identifiers starting with `A`.
*/
- def r: Regex = new Regex(toString)
+ def r: Regex = r()
+
+ /** You can follow a string with `.r(g1, ... , gn)`, turning it into a `Regex`,
+ * with group names g1 through gn.
+ *
+ * `"""(\d\d)-(\d\d)-(\d\d\d\d)""".r("month", "day", "year")` matches dates
+ * and provides its subcomponents through groups named "month", "day" and
+ * "year".
+ *
+ * @param groupNames The names of the groups in the pattern, in the order they appear.
+ */
+ def r(groupNames: String*): Regex = new Regex(toString, groupNames: _*)
def toBoolean: Boolean = parseBoolean(toString)
def toByte: Byte = java.lang.Byte.parseByte(toString)
@@ -228,7 +239,7 @@ self =>
else
throw new IllegalArgumentException("For input string: \"null\"")
- override def toArray[B >: Char : ClassManifest]: Array[B] =
+ override def toArray[B >: Char : ArrayTag]: Array[B] =
toString.toCharArray.asInstanceOf[Array[B]]
private def unwrapArg(arg: Any): AnyRef = arg match {
diff --git a/src/library/scala/collection/immutable/TrieIterator.scala b/src/library/scala/collection/immutable/TrieIterator.scala
index c77334b732..ead1a8c744 100644
--- a/src/library/scala/collection/immutable/TrieIterator.scala
+++ b/src/library/scala/collection/immutable/TrieIterator.scala
@@ -75,7 +75,7 @@ private[collection] abstract class TrieIterator[+T](elems: Array[Iterable[T]]) e
}
private[this] def iteratorWithSize(arr: Array[Iterable[T]]): (Iterator[T], Int) =
- (newIterator(arr), arr map (_.size) sum)
+ (newIterator(arr), arr.map(_.size).sum)
private[this] def arrayToIterators(arr: Array[Iterable[T]]): SplitIterators = {
val (fst, snd) = arr.splitAt(arr.length / 2)
diff --git a/src/library/scala/collection/interfaces/IterableMethods.scala b/src/library/scala/collection/interfaces/IterableMethods.scala
index 2054922e59..8efc3fe6f9 100644
--- a/src/library/scala/collection/interfaces/IterableMethods.scala
+++ b/src/library/scala/collection/interfaces/IterableMethods.scala
@@ -11,7 +11,6 @@ package interfaces
import generic._
import mutable.Buffer
-import scala.reflect.ClassManifest
import annotation.unchecked.uncheckedVariance
/**
diff --git a/src/library/scala/collection/interfaces/SeqMethods.scala b/src/library/scala/collection/interfaces/SeqMethods.scala
index 1f5b08d036..4327073d21 100644
--- a/src/library/scala/collection/interfaces/SeqMethods.scala
+++ b/src/library/scala/collection/interfaces/SeqMethods.scala
@@ -11,7 +11,6 @@ package interfaces
import generic._
import mutable.Buffer
-import scala.reflect.ClassManifest
/**
* @since 2.8
diff --git a/src/library/scala/collection/interfaces/SetMethods.scala b/src/library/scala/collection/interfaces/SetMethods.scala
index ffe141ed82..3b6214f45c 100644
--- a/src/library/scala/collection/interfaces/SetMethods.scala
+++ b/src/library/scala/collection/interfaces/SetMethods.scala
@@ -11,7 +11,6 @@ package interfaces
import generic._
import mutable.Buffer
-import scala.reflect.ClassManifest
import annotation.unchecked.uncheckedVariance
/**
diff --git a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
index 471e977134..543d59d118 100644
--- a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
+++ b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
@@ -46,7 +46,7 @@ trait TraversableOnceMethods[+A] {
def copyToBuffer[B >: A](dest: mutable.Buffer[B]): Unit
// conversions
- def toArray[B >: A : ClassManifest]: Array[B]
+ def toArray[B >: A : ArrayTag]: Array[B]
def toBuffer[B >: A]: mutable.Buffer[B]
def toIndexedSeq: immutable.IndexedSeq[A]
def toIterable: Iterable[A]
diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala
index f0e4c79abf..293e85a97e 100644
--- a/src/library/scala/collection/mutable/ArrayBuilder.scala
+++ b/src/library/scala/collection/mutable/ArrayBuilder.scala
@@ -12,7 +12,8 @@ package scala.collection
package mutable
import generic._
-import scala.reflect.ClassManifest
+import scala.reflect.ArrayTag
+import scala.runtime.ScalaRunTime
/** A builder class for arrays.
*
@@ -30,17 +31,31 @@ object ArrayBuilder {
/** Creates a new arraybuilder of type `T`.
*
- * @tparam T type of the elements for the array builder, with a `ClassManifest` context bound.
+ * @tparam T type of the elements for the array builder, with a `ArrayTag` context bound.
* @return a new empty array builder.
*/
- def make[T: ClassManifest](): ArrayBuilder[T] =
- implicitly[ClassManifest[T]].newArrayBuilder()
+ def make[T: ArrayTag](): ArrayBuilder[T] = {
+ val tag = implicitly[ArrayTag[T]]
+ val erasure = ScalaRunTime.arrayElementClass(tag)
+ erasure match {
+ case java.lang.Byte.TYPE => new ArrayBuilder.ofByte().asInstanceOf[ArrayBuilder[T]]
+ case java.lang.Short.TYPE => new ArrayBuilder.ofShort().asInstanceOf[ArrayBuilder[T]]
+ case java.lang.Character.TYPE => new ArrayBuilder.ofChar().asInstanceOf[ArrayBuilder[T]]
+ case java.lang.Integer.TYPE => new ArrayBuilder.ofInt().asInstanceOf[ArrayBuilder[T]]
+ case java.lang.Long.TYPE => new ArrayBuilder.ofLong().asInstanceOf[ArrayBuilder[T]]
+ case java.lang.Float.TYPE => new ArrayBuilder.ofFloat().asInstanceOf[ArrayBuilder[T]]
+ case java.lang.Double.TYPE => new ArrayBuilder.ofDouble().asInstanceOf[ArrayBuilder[T]]
+ case java.lang.Boolean.TYPE => new ArrayBuilder.ofBoolean().asInstanceOf[ArrayBuilder[T]]
+ case java.lang.Void.TYPE => new ArrayBuilder.ofUnit().asInstanceOf[ArrayBuilder[T]]
+ case _ => new ArrayBuilder.ofRef[T with AnyRef]()(tag.asInstanceOf[ArrayTag[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]]
+ }
+ }
/** A class for array builders for arrays of reference types.
*
- * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassManifest` context bound.
+ * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ArrayTag` context bound.
*/
- class ofRef[T <: AnyRef : ClassManifest] extends ArrayBuilder[T] {
+ class ofRef[T <: AnyRef : ArrayTag] extends ArrayBuilder[T] {
private var elems: Array[T] = _
private var capacity: Int = 0
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 5f7c508181..5f0e1e1071 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -12,7 +12,8 @@ package scala.collection
package mutable
import compat.Platform.arraycopy
-import scala.reflect.ClassManifest
+import scala.reflect.ArrayTag
+import scala.runtime.ScalaRunTime._
import parallel.mutable.ParArray
@@ -37,10 +38,8 @@ import parallel.mutable.ParArray
*/
abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] {
- private def rowBuilder[U]: Builder[U, Array[U]] =
- Array.newBuilder(
- ClassManifest.fromClass(
- repr.getClass.getComponentType.getComponentType.asInstanceOf[Predef.Class[U]]))
+ private def elementClass: Class[_] =
+ arrayElementClass(repr.getClass)
override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) {
var l = math.min(len, repr.length)
@@ -48,11 +47,13 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza
Array.copy(repr, 0, xs, start, l)
}
- override def toArray[U >: T : ClassManifest]: Array[U] =
- if (implicitly[ClassManifest[U]].erasure eq repr.getClass.getComponentType)
+ override def toArray[U >: T : ArrayTag]: Array[U] = {
+ val thatElementClass = arrayElementClass(implicitly[ArrayTag[U]])
+ if (elementClass eq thatElementClass)
repr.asInstanceOf[Array[U]]
else
super.toArray[U]
+ }
override def par = ParArray.handoff(repr)
@@ -63,9 +64,9 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza
* @param asArray A function that converts elements of this array to rows - arrays of type `U`.
* @return An array obtained by concatenating rows of this array.
*/
- def flatten[U, To](implicit asTrav: T => collection.Traversable[U], m: ClassManifest[U]): Array[U] = {
+ def flatten[U, To](implicit asTrav: T => collection.Traversable[U], m: ArrayTag[U]): Array[U] = {
val b = Array.newBuilder[U]
- b.sizeHint(map{case is: collection.IndexedSeq[_] => is.size case _ => 0} sum)
+ b.sizeHint(map{case is: collection.IndexedSeq[_] => is.size case _ => 0}.sum)
for (xs <- this)
b ++= asTrav(xs)
b.result
@@ -78,7 +79,8 @@ abstract class ArrayOps[T] extends 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]] = {
- val bs = asArray(head) map (_ => rowBuilder[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)) {
@@ -86,9 +88,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza
i += 1
}
}
- val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(
- ClassManifest.fromClass(
- repr.getClass.getComponentType.asInstanceOf[Predef.Class[Array[U]]]))
+ val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass))
for (b <- bs) bb += b.result
bb.result
}
@@ -109,8 +109,7 @@ object ArrayOps {
override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr)
override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr)
- override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(
- ClassManifest.classType[T](repr.getClass.getComponentType))
+ override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](arrayElementClass(repr.getClass)))
def length: Int = repr.length
def apply(index: Int): T = repr(index)
diff --git a/src/library/scala/collection/mutable/ArrayStack.scala b/src/library/scala/collection/mutable/ArrayStack.scala
index f5287312b9..b3a0534826 100644
--- a/src/library/scala/collection/mutable/ArrayStack.scala
+++ b/src/library/scala/collection/mutable/ArrayStack.scala
@@ -21,7 +21,7 @@ object ArrayStack extends SeqFactory[ArrayStack] {
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, ArrayStack[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
def newBuilder[A]: Builder[A, ArrayStack[A]] = new ArrayStack[A]
def empty: ArrayStack[Nothing] = new ArrayStack()
- def apply[A: ClassManifest](elems: A*): ArrayStack[A] = {
+ def apply[A: ArrayTag](elems: A*): ArrayStack[A] = {
val els: Array[AnyRef] = elems.reverseMap(_.asInstanceOf[AnyRef])(breakOut)
if (els.length == 0) new ArrayStack()
else new ArrayStack[A](els, els.length)
diff --git a/src/library/scala/collection/mutable/ConcurrentMap.scala b/src/library/scala/collection/mutable/ConcurrentMap.scala
index fbb356ffb3..f2b44d6737 100644
--- a/src/library/scala/collection/mutable/ConcurrentMap.scala
+++ b/src/library/scala/collection/mutable/ConcurrentMap.scala
@@ -32,6 +32,7 @@ package mutable
* @define atomicop
* This is an atomic operation.
*/
+@deprecated("Use `scala.collection.concurrent.Map` instead.", "2.10.0")
trait ConcurrentMap[A, B] extends Map[A, B] {
/**
diff --git a/src/library/scala/collection/mutable/FlatArray.scala b/src/library/scala/collection/mutable/FlatArray.scala
deleted file mode 100644
index a7f994bf74..0000000000
--- a/src/library/scala/collection/mutable/FlatArray.scala
+++ /dev/null
@@ -1,150 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.collection
-package mutable
-
-import scala.reflect.ClassManifest
-import generic.CanBuildFrom
-
-/**
- * A class representing `Array[T]`.
- *
- * @tparam T type of the elements in this wrapped array.
- *
- * @author Martin Odersky, Stephane Micheloud
- * @version 1.0
- * @since 2.8
- * @define Coll WrappedArray
- * @define coll wrapped array
- * @define orderDependent
- * @define orderDependentFold
- * @define mayNotTerminateInf
- * @define willNotTerminateInf
- */
-abstract sealed class FlatArray[T]
-extends AbstractSeq[T]
- with IndexedSeq[T]
- with IndexedSeqOptimized[T, FlatArray[T]]
-{
-
- override protected[this] def thisCollection: FlatArray[T] = this
- override protected[this] def toCollection(repr: FlatArray[T]): FlatArray[T] = repr
-
- /** The length of the array */
- def length: Int
-
- /** The element at given index */
- def apply(index: Int): T
-
- /** Update element at given index */
- def update(index: Int, elem: T): Unit
-
- override def stringPrefix = "FlatArray"
-
- override protected[this] def newBuilder: Builder[T, FlatArray[T]] = ??? // implemented in FlatArray.Impl
-
- /** Clones this object, including the underlying Array. */
- override def clone: FlatArray[T] = ??? // implemented in FlatArray.Impl
-}
-
-
-/** A companion object used to create instances of `WrappedArray`.
- */
-object FlatArray {
-
- def empty[Boxed, Unboxed](elems: Boxed*)
- (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): FlatArray[Boxed] = apply()
-
- def apply[Boxed, Unboxed](elems: Boxed*)
- (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): FlatArray[Boxed] = {
- val b = newBuilder[Boxed, Unboxed]
- b.sizeHint(elems.length)
- b ++= elems
- b.result
- }
-
- def newBuilder[Boxed, Unboxed]
- (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): Builder[Boxed, FlatArray[Boxed]] =
- new Bldr[Boxed, Unboxed](boxings, elemManifest)
-
- implicit def canBuildFrom[Boxed, Unboxed](
- implicit
- boxings: BoxingConversions[Boxed, Unboxed],
- elemManifest: ClassManifest[Unboxed]): CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] =
- new CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] {
- def apply(from: FlatArray[_]): Builder[Boxed, FlatArray[Boxed]] =
- newBuilder[Boxed, Unboxed]
- def apply: Builder[Boxed, FlatArray[Boxed]] =
- newBuilder[Boxed, Unboxed]
- }
-
- private class Bldr[Boxed, Unboxed](boxings: BoxingConversions[Boxed, Unboxed], manifest: ClassManifest[Unboxed]) extends Builder[Boxed, FlatArray[Boxed]] {
-
- private var elems: Array[Unboxed] = _
- private var capacity: Int = 0
- private var size: Int = 0
-
- private def resize(size: Int) {
- val newelems = manifest.newArray(size)
- if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
- elems = newelems
- capacity = size
- }
-
- override def sizeHint(size: Int) {
- if (capacity < size) resize(size)
- }
-
- private def ensureSize(size: Int) {
- if (capacity < size) {
- var newsize = if (capacity == 0) 16 else capacity * 2
- while (newsize < size) newsize *= 2
- resize(newsize)
- }
- }
-
- def +=(elem: Boxed): this.type = {
- ensureSize(size + 1)
- elems(size) = boxings.unbox(elem)
- size += 1
- this
- }
-
- def clear() {
- size = 0
- }
-
- def result(): FlatArray[Boxed] = {
- if (capacity == 0 || capacity != size) resize(size)
- new FlatArray.Impl(elems, boxings, manifest)
- }
- }
-
- private class Impl[Boxed, Unboxed](
- elems: Array[Unboxed],
- boxings: BoxingConversions[Boxed, Unboxed],
- elemManifest: ClassManifest[Unboxed]) extends FlatArray[Boxed] {
-
- def length = elems.length
-
- def apply(idx: Int): Boxed = boxings.box(elems(idx))
-
- def update(idx: Int, elem: Boxed) = elems(idx) = boxings.unbox(elem)
-
- /** Creates new builder for this collection ==> move to subclasses
- */
- override protected[this] def newBuilder: Builder[Boxed, FlatArray[Boxed]] =
- new Bldr[Boxed, Unboxed](boxings, elemManifest)
-
- /** Clones this object, including the underlying Array. */
- override def clone: FlatArray[Boxed] = new Impl[Boxed, Unboxed](elems.clone(), boxings, elemManifest)
- }
-}
diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala
index cc0aed6963..06b7d40bfc 100644
--- a/src/library/scala/collection/mutable/HashTable.scala
+++ b/src/library/scala/collection/mutable/HashTable.scala
@@ -366,7 +366,7 @@ private[collection] object HashTable {
private[collection] final def newThreshold(_loadFactor: Int, size: Int) = ((size.toLong * _loadFactor) / loadFactorDenum).toInt
- private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = thr * loadFactorDenum / _loadFactor
+ private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = ((thr.toLong * loadFactorDenum) / _loadFactor).toInt
private[collection] final def capacity(expectedSize: Int) = if (expectedSize == 0) 1 else powerOfTwo(expectedSize)
diff --git a/src/library/scala/collection/mutable/IndexedSeqView.scala b/src/library/scala/collection/mutable/IndexedSeqView.scala
index 593af92255..a0de2ec8ad 100644
--- a/src/library/scala/collection/mutable/IndexedSeqView.scala
+++ b/src/library/scala/collection/mutable/IndexedSeqView.scala
@@ -14,6 +14,7 @@ package mutable
import generic._
import TraversableView.NoBuilder
+import language.implicitConversions
/** A non-strict view of a mutable `IndexedSeq`.
* $viewInfo
diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala
index f6d4915fef..d2815cf9de 100644
--- a/src/library/scala/collection/mutable/LinkedHashSet.scala
+++ b/src/library/scala/collection/mutable/LinkedHashSet.scala
@@ -82,7 +82,7 @@ class LinkedHashSet[A] extends AbstractSet[A]
private def readObject(in: java.io.ObjectInputStream) {
ordered = new ListBuffer[A]
- init(in, ordered += )
+ init(in, ordered += _)
}
}
diff --git a/src/library/scala/collection/mutable/Stack.scala b/src/library/scala/collection/mutable/Stack.scala
index 8fad131009..b70df05c55 100644
--- a/src/library/scala/collection/mutable/Stack.scala
+++ b/src/library/scala/collection/mutable/Stack.scala
@@ -44,7 +44,7 @@ object Stack extends SeqFactory[Stack] {
* @author Martin Odersky
* @version 2.8
* @since 1
- * @see [[http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html#stacks"Scala's Collection Library overview"]]
+ * @see [[http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html#stacks "Scala's Collection Library overview"]]
* section on `Stacks` for more information.
* @define Coll Stack
* @define coll stack
diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala
index d9ad58f054..08c881dbb8 100644
--- a/src/library/scala/collection/mutable/StringBuilder.scala
+++ b/src/library/scala/collection/mutable/StringBuilder.scala
@@ -404,7 +404,7 @@ final class StringBuilder(private val underlying: JavaStringBuilder)
* @return the reversed StringBuilder
*/
@migration("`reverse` returns a new instance. Use `reverseContents` to update in place and return that StringBuilder itself.", "2.8.0")
- override def reverse: StringBuilder = new StringBuilder(new JavaStringBuilder(underlying) reverse)
+ override def reverse: StringBuilder = new StringBuilder(new JavaStringBuilder(underlying).reverse)
override def clone(): StringBuilder = new StringBuilder(new JavaStringBuilder(underlying))
diff --git a/src/library/scala/collection/mutable/UnrolledBuffer.scala b/src/library/scala/collection/mutable/UnrolledBuffer.scala
index 09e6088782..889768d471 100644
--- a/src/library/scala/collection/mutable/UnrolledBuffer.scala
+++ b/src/library/scala/collection/mutable/UnrolledBuffer.scala
@@ -41,11 +41,11 @@ import annotation.tailrec
*
*/
@SerialVersionUID(1L)
-class UnrolledBuffer[T](implicit val manifest: ClassManifest[T])
+class UnrolledBuffer[T](implicit val tag: ArrayTag[T])
extends collection.mutable.AbstractBuffer[T]
with collection.mutable.Buffer[T]
with collection.mutable.BufferLike[T, UnrolledBuffer[T]]
- with GenericClassManifestTraversableTemplate[T, UnrolledBuffer]
+ with GenericArrayTagTraversableTemplate[T, UnrolledBuffer]
with collection.mutable.Builder[T, UnrolledBuffer[T]]
with Serializable
{
@@ -67,7 +67,7 @@ extends collection.mutable.AbstractBuffer[T]
private[collection] def calcNextLength(sz: Int) = sz
- def classManifestCompanion = UnrolledBuffer
+ def arrayTagCompanion = UnrolledBuffer
/** Concatenates the targer unrolled buffer to this unrolled buffer.
*
@@ -183,11 +183,11 @@ extends collection.mutable.AbstractBuffer[T]
}
-object UnrolledBuffer extends ClassManifestTraversableFactory[UnrolledBuffer] {
+object UnrolledBuffer extends ArrayTagTraversableFactory[UnrolledBuffer] {
/** $genericCanBuildFromInfo */
- implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Coll, T, UnrolledBuffer[T]] =
+ implicit def canBuildFrom[T](implicit t: ArrayTag[T]): CanBuildFrom[Coll, T, UnrolledBuffer[T]] =
new GenericCanBuildFrom[T]
- def newBuilder[T](implicit m: ClassManifest[T]): Builder[T, UnrolledBuffer[T]] = new UnrolledBuffer[T]
+ def newBuilder[T](implicit t: ArrayTag[T]): Builder[T, UnrolledBuffer[T]] = new UnrolledBuffer[T]
val waterline = 50
val waterlineDelim = 100
@@ -195,7 +195,7 @@ object UnrolledBuffer extends ClassManifestTraversableFactory[UnrolledBuffer] {
/** Unrolled buffer node.
*/
- class Unrolled[T: ClassManifest] private[collection] (var size: Int, var array: Array[T], var next: Unrolled[T], val buff: UnrolledBuffer[T] = null) {
+ class Unrolled[T: ArrayTag] private[collection] (var size: Int, var array: Array[T], var next: Unrolled[T], val buff: UnrolledBuffer[T] = null) {
private[collection] def this() = this(0, new Array[T](unrolledlength), null, null)
private[collection] def this(b: UnrolledBuffer[T]) = this(0, new Array[T](unrolledlength), null, b)
diff --git a/src/library/scala/collection/mutable/WeakHashMap.scala b/src/library/scala/collection/mutable/WeakHashMap.scala
index 89d7c7a695..4e09755acf 100644
--- a/src/library/scala/collection/mutable/WeakHashMap.scala
+++ b/src/library/scala/collection/mutable/WeakHashMap.scala
@@ -6,14 +6,11 @@
** |/ **
\* */
-
-
package scala.collection
package mutable
-import JavaConversions._
import generic._
-
+import convert.Wrappers._
/** A hash map with references to entries which are weakly reachable. Entries are
* removed from this map when the key is no longer (strongly) referenced. This class wraps
diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala
index 4287bac249..9d170b2832 100644
--- a/src/library/scala/collection/mutable/WrappedArray.scala
+++ b/src/library/scala/collection/mutable/WrappedArray.scala
@@ -11,7 +11,8 @@
package scala.collection
package mutable
-import scala.reflect.ClassManifest
+import scala.reflect.ArrayTag
+import scala.runtime.ScalaRunTime._
import scala.collection.generic._
import scala.collection.parallel.mutable.ParArray
@@ -40,8 +41,11 @@ extends AbstractSeq[T]
override protected[this] def thisCollection: WrappedArray[T] = this
override protected[this] def toCollection(repr: WrappedArray[T]): WrappedArray[T] = repr
- /** The manifest of the element type */
- def elemManifest: ClassManifest[T]
+ /** The tag of the element type */
+ def elemTag: ArrayTag[T]
+
+ @deprecated("use elemTag instead", "2.10.0")
+ def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](arrayElementClass(elemTag).asInstanceOf[Class[T]])
/** The length of the array */
def length: Int
@@ -57,11 +61,16 @@ extends AbstractSeq[T]
override def par = ParArray.handoff(array)
- override def toArray[U >: T : ClassManifest]: Array[U] =
- if (implicitly[ClassManifest[U]].erasure eq array.getClass.getComponentType)
+ private def elementClass: Class[_] =
+ arrayElementClass(repr.getClass)
+
+ override def toArray[U >: T : ArrayTag]: Array[U] = {
+ val thatElementClass = arrayElementClass(implicitly[ArrayTag[U]])
+ if (elementClass eq thatElementClass)
array.asInstanceOf[Array[U]]
else
super.toArray[U]
+ }
override def stringPrefix = "WrappedArray"
@@ -71,7 +80,7 @@ extends AbstractSeq[T]
/** Creates new builder for this collection ==> move to subclasses
*/
override protected[this] def newBuilder: Builder[T, WrappedArray[T]] =
- new WrappedArrayBuilder[T](elemManifest)
+ new WrappedArrayBuilder[T](elemTag)
}
@@ -101,7 +110,7 @@ object WrappedArray {
case x: Array[Unit] => new ofUnit(x)
}).asInstanceOf[WrappedArray[T]]
- implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[WrappedArray[_], T, WrappedArray[T]] =
+ implicit def canBuildFrom[T](implicit m: ArrayTag[T]): CanBuildFrom[WrappedArray[_], T, WrappedArray[T]] =
new CanBuildFrom[WrappedArray[_], T, WrappedArray[T]] {
def apply(from: WrappedArray[_]): Builder[T, WrappedArray[T]] =
ArrayBuilder.make[T]()(m) mapResult WrappedArray.make[T]
@@ -112,70 +121,70 @@ object WrappedArray {
def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer
final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable {
- lazy val elemManifest = ClassManifest.classType[T](array.getClass.getComponentType)
+ lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass))
def length: Int = array.length
def apply(index: Int): T = array(index).asInstanceOf[T]
def update(index: Int, elem: T) { array(index) = elem }
}
final class ofByte(val array: Array[Byte]) extends WrappedArray[Byte] with Serializable {
- def elemManifest = ClassManifest.Byte
+ def elemTag = ClassTag.Byte
def length: Int = array.length
def apply(index: Int): Byte = array(index)
def update(index: Int, elem: Byte) { array(index) = elem }
}
final class ofShort(val array: Array[Short]) extends WrappedArray[Short] with Serializable {
- def elemManifest = ClassManifest.Short
+ def elemTag = ClassTag.Short
def length: Int = array.length
def apply(index: Int): Short = array(index)
def update(index: Int, elem: Short) { array(index) = elem }
}
final class ofChar(val array: Array[Char]) extends WrappedArray[Char] with Serializable {
- def elemManifest = ClassManifest.Char
+ def elemTag = ClassTag.Char
def length: Int = array.length
def apply(index: Int): Char = array(index)
def update(index: Int, elem: Char) { array(index) = elem }
}
final class ofInt(val array: Array[Int]) extends WrappedArray[Int] with Serializable {
- def elemManifest = ClassManifest.Int
+ def elemTag = ClassTag.Int
def length: Int = array.length
def apply(index: Int): Int = array(index)
def update(index: Int, elem: Int) { array(index) = elem }
}
final class ofLong(val array: Array[Long]) extends WrappedArray[Long] with Serializable {
- def elemManifest = ClassManifest.Long
+ def elemTag = ClassTag.Long
def length: Int = array.length
def apply(index: Int): Long = array(index)
def update(index: Int, elem: Long) { array(index) = elem }
}
final class ofFloat(val array: Array[Float]) extends WrappedArray[Float] with Serializable {
- def elemManifest = ClassManifest.Float
+ def elemTag = ClassTag.Float
def length: Int = array.length
def apply(index: Int): Float = array(index)
def update(index: Int, elem: Float) { array(index) = elem }
}
final class ofDouble(val array: Array[Double]) extends WrappedArray[Double] with Serializable {
- def elemManifest = ClassManifest.Double
+ def elemTag = ClassTag.Double
def length: Int = array.length
def apply(index: Int): Double = array(index)
def update(index: Int, elem: Double) { array(index) = elem }
}
final class ofBoolean(val array: Array[Boolean]) extends WrappedArray[Boolean] with Serializable {
- def elemManifest = ClassManifest.Boolean
+ def elemTag = ClassTag.Boolean
def length: Int = array.length
def apply(index: Int): Boolean = array(index)
def update(index: Int, elem: Boolean) { array(index) = elem }
}
final class ofUnit(val array: Array[Unit]) extends WrappedArray[Unit] with Serializable {
- def elemManifest = ClassManifest.Unit
+ def elemTag = ClassTag.Unit
def length: Int = array.length
def apply(index: Int): Unit = array(index)
def update(index: Int, elem: Unit) { array(index) = elem }
diff --git a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
index 9771a45a28..99a0b0ede3 100644
--- a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
+++ b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
@@ -12,23 +12,39 @@ package scala.collection
package mutable
import generic._
-import scala.reflect.ClassManifest
+import scala.reflect.ArrayTag
+import scala.runtime.ScalaRunTime._
/** A builder class for arrays.
*
- * @tparam A type of elements that can be added to this builder.
- * @param manifest class manifest for objects of type `A`.
+ * @tparam A type of elements that can be added to this builder.
+ * @param tag class tag for objects of type `A`.
*
* @since 2.8
*/
-class WrappedArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, WrappedArray[A]] {
+class WrappedArrayBuilder[A](tag: ArrayTag[A]) extends Builder[A, WrappedArray[A]] {
+
+ @deprecated("use tag instead", "2.10.0")
+ val manifest: ArrayTag[A] = tag
private var elems: WrappedArray[A] = _
private var capacity: Int = 0
private var size: Int = 0
private def mkArray(size: Int): WrappedArray[A] = {
- val newelems = manifest.newWrappedArray(size)
+ val erasure = arrayElementClass(tag)
+ val newelems = erasure match {
+ case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](size)).asInstanceOf[WrappedArray[A]]
+ case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](size)).asInstanceOf[WrappedArray[A]]
+ case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](size)).asInstanceOf[WrappedArray[A]]
+ case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](size)).asInstanceOf[WrappedArray[A]]
+ case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](size)).asInstanceOf[WrappedArray[A]]
+ case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](size)).asInstanceOf[WrappedArray[A]]
+ case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](size)).asInstanceOf[WrappedArray[A]]
+ case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](size)).asInstanceOf[WrappedArray[A]]
+ case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](size)).asInstanceOf[WrappedArray[A]]
+ case _ => new WrappedArray.ofRef[A with AnyRef](tag.newArray(size).asInstanceOf[Array[A with AnyRef]]).asInstanceOf[WrappedArray[A]]
+ }
if (this.size > 0) Array.copy(elems.array, 0, newelems.array, 0, this.size)
newelems
}
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index 5551c04ce2..014b9b1a42 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean
import annotation.unchecked.uncheckedVariance
import annotation.unchecked.uncheckedStable
+import language.implicitConversions
/** A template trait for parallel collections of type `ParIterable[T]`.
@@ -154,15 +155,15 @@ extends GenIterableLike[T, Repr]
with HasNewCombiner[T, Repr]
{
self: ParIterableLike[T, Repr, Sequential] =>
-
+
@transient
@volatile
private var _tasksupport = defaultTaskSupport
-
+
protected def initTaskSupport() {
_tasksupport = defaultTaskSupport
}
-
+
def tasksupport = {
val ts = _tasksupport
if (ts eq null) {
@@ -170,9 +171,9 @@ self: ParIterableLike[T, Repr, Sequential] =>
defaultTaskSupport
} else ts
}
-
+
def tasksupport_=(ts: TaskSupport) = _tasksupport = ts
-
+
def seq: Sequential
def repr: Repr = this.asInstanceOf[Repr]
@@ -239,7 +240,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
trait BuilderOps[Elem, To] {
trait Otherwise[Cmb] {
- def otherwise(notbody: => Unit)(implicit m: ClassManifest[Cmb]): Unit
+ def otherwise(notbody: => Unit)(implicit t: ClassTag[Cmb]): Unit
}
def ifIs[Cmb](isbody: Cmb => Unit): Otherwise[Cmb]
@@ -281,8 +282,8 @@ self: ParIterableLike[T, Repr, Sequential] =>
protected implicit def builder2ops[Elem, To](cb: Builder[Elem, To]) = new BuilderOps[Elem, To] {
def ifIs[Cmb](isbody: Cmb => Unit) = new Otherwise[Cmb] {
- def otherwise(notbody: => Unit)(implicit m: ClassManifest[Cmb]) {
- if (cb.getClass == m.erasure) isbody(cb.asInstanceOf[Cmb]) else notbody
+ def otherwise(notbody: => Unit)(implicit t: ClassTag[Cmb]) {
+ if (cb.getClass == t.erasure) isbody(cb.asInstanceOf[Cmb]) else notbody
}
}
def isCombiner = cb.isInstanceOf[Combiner[_, _]]
@@ -753,7 +754,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
cntx.setIndexFlag(Int.MaxValue)
tasksupport.executeAndWaitResult(
new Span(0, pred, combinerFactory, combinerFactory, splitter assign cntx) mapResult {
- _._2.resultWithTaskSupport
+ _._2.resultWithTaskSupport
}
)
}
@@ -801,7 +802,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
def size = splitter.remaining
}
- override def toArray[U >: T: ClassManifest]: Array[U] = {
+ override def toArray[U >: T: ArrayTag]: Array[U] = {
val arr = new Array[U](size)
copyToArray(arr)
arr
diff --git a/src/library/scala/collection/parallel/ParIterableViewLike.scala b/src/library/scala/collection/parallel/ParIterableViewLike.scala
index 536139c812..91eefc2aa5 100644
--- a/src/library/scala/collection/parallel/ParIterableViewLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableViewLike.scala
@@ -18,6 +18,7 @@ import scala.collection.GenSeq
import scala.collection.generic.{ CanBuildFrom, SliceInterval }
import scala.collection.generic.CanCombineFrom
import scala.collection.parallel.immutable.ParRange
+import language.implicitConversions
diff --git a/src/library/scala/collection/parallel/TaskSupport.scala b/src/library/scala/collection/parallel/TaskSupport.scala
index 59b75f523f..2eaa861429 100644
--- a/src/library/scala/collection/parallel/TaskSupport.scala
+++ b/src/library/scala/collection/parallel/TaskSupport.scala
@@ -48,7 +48,7 @@ extends TaskSupport with AdaptiveWorkStealingThreadPoolTasks
* By default, parallel collections are parametrized with this task support object, so parallel collections
* share the same execution context backend as the rest of the `scala.concurrent` package.
*/
-class ExecutionContextTaskSupport(val environment: ExecutionContext = scala.concurrent.executionContext)
+class ExecutionContextTaskSupport(val environment: ExecutionContext = scala.concurrent.defaultExecutionContext)
extends TaskSupport with ExecutionContextTasks
diff --git a/src/library/scala/collection/parallel/immutable/ParHashMap.scala b/src/library/scala/collection/parallel/immutable/ParHashMap.scala
index 49b00bebdb..e630a9dbed 100644
--- a/src/library/scala/collection/parallel/immutable/ParHashMap.scala
+++ b/src/library/scala/collection/parallel/immutable/ParHashMap.scala
@@ -36,7 +36,9 @@ import collection.parallel.Task
*
* @author Aleksandar Prokopec
* @since 2.9
- *
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#parallel_hash_tries Scala's Parallel Collections Library overview]]
+ * section on Parallel Hash Tries for more information.
+ *
* @define Coll immutable.ParHashMap
* @define coll immutable parallel hash map
*/
diff --git a/src/library/scala/collection/parallel/immutable/ParHashSet.scala b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
index 11d92a27c9..084637c5dc 100644
--- a/src/library/scala/collection/parallel/immutable/ParHashSet.scala
+++ b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
@@ -35,6 +35,8 @@ import collection.parallel.Task
*
* @author Aleksandar Prokopec
* @since 2.9
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#parallel_hash_tries Scala's Parallel Collections Library overview]]
+ * section on Parallel Hash Tries for more information.
*
* @define Coll immutable.ParHashSet
* @define coll immutable parallel hash set
diff --git a/src/library/scala/collection/parallel/immutable/ParRange.scala b/src/library/scala/collection/parallel/immutable/ParRange.scala
index 9cac433460..277fd5fdd3 100644
--- a/src/library/scala/collection/parallel/immutable/ParRange.scala
+++ b/src/library/scala/collection/parallel/immutable/ParRange.scala
@@ -25,6 +25,8 @@ import scala.collection.Iterator
*
* @author Aleksandar Prokopec
* @since 2.9
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#parallel_range Scala's Parallel Collections Library overview]]
+ * section on `ParRange` for more information.
*
* @define Coll immutable.ParRange
* @define coll immutable parallel range
diff --git a/src/library/scala/collection/parallel/immutable/ParVector.scala b/src/library/scala/collection/parallel/immutable/ParVector.scala
index 5d9c431bc1..8baa84b77c 100644
--- a/src/library/scala/collection/parallel/immutable/ParVector.scala
+++ b/src/library/scala/collection/parallel/immutable/ParVector.scala
@@ -34,6 +34,8 @@ import immutable.VectorIterator
*
* @author Aleksandar Prokopec
* @since 2.9
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#parallel_vector Scala's Parallel Collections Library overview]]
+ * section on `ParVector` for more information.
*
* @define Coll immutable.ParVector
* @define coll immutable parallel vector
diff --git a/src/library/scala/collection/parallel/mutable/ParArray.scala b/src/library/scala/collection/parallel/mutable/ParArray.scala
index c33495bd39..92ba701f7c 100644
--- a/src/library/scala/collection/parallel/mutable/ParArray.scala
+++ b/src/library/scala/collection/parallel/mutable/ParArray.scala
@@ -44,10 +44,14 @@ import scala.collection.GenTraversableOnce
*
* @tparam T type of the elements in the array
*
+ * @author Aleksandar Prokopec
+ * @since 2.9
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#parallel_array Scala's Parallel Collections Library overview]]
+ * section on `ParArray` for more information.
+ *
* @define Coll ParArray
* @define coll parallel array
*
- * @author Aleksandar Prokopec
*/
@SerialVersionUID(1L)
class ParArray[T] private[mutable] (val arrayseq: ArraySeq[T])
@@ -672,7 +676,7 @@ self =>
private def readObject(in: java.io.ObjectInputStream) {
in.defaultReadObject
-
+
// get raw array from arrayseq
array = arrayseq.array.asInstanceOf[Array[Any]]
}
@@ -702,7 +706,7 @@ object ParArray extends ParFactory[ParArray] {
case _ => new ParArray[T](new ExposedArraySeq[T](runtime.ScalaRunTime.toObjectArray(arr), sz))
}
- def createFromCopy[T <: AnyRef : ClassManifest](arr: Array[T]): ParArray[T] = {
+ def createFromCopy[T <: AnyRef : ArrayTag](arr: Array[T]): ParArray[T] = {
val newarr = new Array[T](arr.length)
Array.copy(arr, 0, newarr, 0, arr.length)
handoff(newarr)
diff --git a/src/library/scala/collection/parallel/mutable/ParHashMap.scala b/src/library/scala/collection/parallel/mutable/ParHashMap.scala
index 6ce6c45460..23b23d55a1 100644
--- a/src/library/scala/collection/parallel/mutable/ParHashMap.scala
+++ b/src/library/scala/collection/parallel/mutable/ParHashMap.scala
@@ -32,6 +32,8 @@ import collection.parallel.Task
* @define coll parallel hash map
*
* @author Aleksandar Prokopec
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#parallel_hash_tables Scala's Parallel Collections Library overview]]
+ * section on Parallel Hash Tables for more information.
*/
@SerialVersionUID(1L)
class ParHashMap[K, V] private[collection] (contents: HashTable.Contents[K, DefaultEntry[K, V]])
diff --git a/src/library/scala/collection/parallel/mutable/ParHashSet.scala b/src/library/scala/collection/parallel/mutable/ParHashSet.scala
index e0a2ab03df..4e9a38c13f 100644
--- a/src/library/scala/collection/parallel/mutable/ParHashSet.scala
+++ b/src/library/scala/collection/parallel/mutable/ParHashSet.scala
@@ -29,6 +29,8 @@ import collection.parallel.Task
* @define coll parallel hash set
*
* @author Aleksandar Prokopec
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#parallel_hash_tables Scala's Parallel Collections Library overview]]
+ * section on Parallel Hash Tables for more information.
*/
@SerialVersionUID(1L)
class ParHashSet[T] private[collection] (contents: FlatHashTable.Contents[T])
diff --git a/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala b/src/library/scala/collection/parallel/mutable/ParTrieMap.scala
index a6495161ea..359c35f1dd 100644
--- a/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala
+++ b/src/library/scala/collection/parallel/mutable/ParTrieMap.scala
@@ -14,18 +14,18 @@ import scala.collection.generic._
import scala.collection.parallel.Combiner
import scala.collection.parallel.IterableSplitter
import scala.collection.parallel.Task
-import scala.collection.mutable.BasicNode
-import scala.collection.mutable.TNode
-import scala.collection.mutable.LNode
-import scala.collection.mutable.CNode
-import scala.collection.mutable.SNode
-import scala.collection.mutable.INode
-import scala.collection.mutable.ConcurrentTrieMap
-import scala.collection.mutable.ConcurrentTrieMapIterator
+import scala.collection.concurrent.BasicNode
+import scala.collection.concurrent.TNode
+import scala.collection.concurrent.LNode
+import scala.collection.concurrent.CNode
+import scala.collection.concurrent.SNode
+import scala.collection.concurrent.INode
+import scala.collection.concurrent.TrieMap
+import scala.collection.concurrent.TrieMapIterator
-/** Parallel ConcurrentTrieMap collection.
+/** Parallel TrieMap collection.
*
* It has its bulk operations parallelized, but uses the snapshot operation
* to create the splitter. This means that parallel bulk operations can be
@@ -33,25 +33,27 @@ import scala.collection.mutable.ConcurrentTrieMapIterator
*
* @author Aleksandar Prokopec
* @since 2.10
+ * @see [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#parallel_concurrent_tries Scala's Parallel Collections Library overview]]
+ * section on `ParTrieMap` for more information.
*/
-final class ParConcurrentTrieMap[K, V] private[collection] (private val ctrie: ConcurrentTrieMap[K, V])
+final class ParTrieMap[K, V] private[collection] (private val ctrie: TrieMap[K, V])
extends ParMap[K, V]
- with GenericParMapTemplate[K, V, ParConcurrentTrieMap]
- with ParMapLike[K, V, ParConcurrentTrieMap[K, V], ConcurrentTrieMap[K, V]]
- with ParConcurrentTrieMapCombiner[K, V]
+ with GenericParMapTemplate[K, V, ParTrieMap]
+ with ParMapLike[K, V, ParTrieMap[K, V], TrieMap[K, V]]
+ with ParTrieMapCombiner[K, V]
with Serializable
{
- def this() = this(new ConcurrentTrieMap)
+ def this() = this(new TrieMap)
- override def mapCompanion: GenericParMapCompanion[ParConcurrentTrieMap] = ParConcurrentTrieMap
+ override def mapCompanion: GenericParMapCompanion[ParTrieMap] = ParTrieMap
- override def empty: ParConcurrentTrieMap[K, V] = ParConcurrentTrieMap.empty
+ override def empty: ParTrieMap[K, V] = ParTrieMap.empty
- protected[this] override def newCombiner = ParConcurrentTrieMap.newCombiner
+ protected[this] override def newCombiner = ParTrieMap.newCombiner
override def seq = ctrie
- def splitter = new ParConcurrentTrieMapSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[ConcurrentTrieMap[K, V]], true)
+ def splitter = new ParTrieMapSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[TrieMap[K, V]], true)
override def clear() = ctrie.clear()
@@ -87,11 +89,11 @@ extends ParMap[K, V]
}
}
- override def stringPrefix = "ParConcurrentTrieMap"
+ override def stringPrefix = "ParTrieMap"
/* tasks */
- /** Computes ConcurrentTrieMap size in parallel. */
+ /** Computes TrieMap size in parallel. */
class Size(offset: Int, howmany: Int, array: Array[BasicNode]) extends Task[Int, Size] {
var result = -1
def leaf(prev: Option[Int]) = {
@@ -118,15 +120,15 @@ extends ParMap[K, V]
}
-private[collection] class ParConcurrentTrieMapSplitter[K, V](lev: Int, ct: ConcurrentTrieMap[K, V], mustInit: Boolean)
-extends ConcurrentTrieMapIterator[K, V](lev, ct, mustInit)
+private[collection] class ParTrieMapSplitter[K, V](lev: Int, ct: TrieMap[K, V], mustInit: Boolean)
+extends TrieMapIterator[K, V](lev, ct, mustInit)
with IterableSplitter[(K, V)]
{
// only evaluated if `remaining` is invoked (which is not used by most tasks)
lazy val totalsize = ct.par.size
var iterated = 0
- protected override def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ParConcurrentTrieMapSplitter[K, V](_lev, _ct, _mustInit)
+ protected override def newIterator(_lev: Int, _ct: TrieMap[K, V], _mustInit: Boolean) = new ParTrieMapSplitter[K, V](_lev, _ct, _mustInit)
override def shouldSplitFurther[S](coll: collection.parallel.ParIterable[S], parallelismLevel: Int) = {
val maxsplits = 3 + Integer.highestOneBit(parallelismLevel)
@@ -153,15 +155,15 @@ extends ConcurrentTrieMapIterator[K, V](lev, ct, mustInit)
}
-/** Only used within the `ParConcurrentTrieMap`. */
-private[mutable] trait ParConcurrentTrieMapCombiner[K, V] extends Combiner[(K, V), ParConcurrentTrieMap[K, V]] {
+/** Only used within the `ParTrieMap`. */
+private[mutable] trait ParTrieMapCombiner[K, V] extends Combiner[(K, V), ParTrieMap[K, V]] {
- def combine[N <: (K, V), NewTo >: ParConcurrentTrieMap[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else {
+ def combine[N <: (K, V), NewTo >: ParTrieMap[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else {
throw new UnsupportedOperationException("This shouldn't have been called in the first place.")
- val thiz = this.asInstanceOf[ParConcurrentTrieMap[K, V]]
- val that = other.asInstanceOf[ParConcurrentTrieMap[K, V]]
- val result = new ParConcurrentTrieMap[K, V]
+ val thiz = this.asInstanceOf[ParTrieMap[K, V]]
+ val that = other.asInstanceOf[ParTrieMap[K, V]]
+ val result = new ParTrieMap[K, V]
result ++= thiz.iterator
result ++= that.iterator
@@ -174,13 +176,13 @@ private[mutable] trait ParConcurrentTrieMapCombiner[K, V] extends Combiner[(K, V
}
-object ParConcurrentTrieMap extends ParMapFactory[ParConcurrentTrieMap] {
+object ParTrieMap extends ParMapFactory[ParTrieMap] {
- def empty[K, V]: ParConcurrentTrieMap[K, V] = new ParConcurrentTrieMap[K, V]
+ def empty[K, V]: ParTrieMap[K, V] = new ParTrieMap[K, V]
- def newCombiner[K, V]: Combiner[(K, V), ParConcurrentTrieMap[K, V]] = new ParConcurrentTrieMap[K, V]
+ def newCombiner[K, V]: Combiner[(K, V), ParTrieMap[K, V]] = new ParTrieMap[K, V]
- implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParConcurrentTrieMap[K, V]] = new CanCombineFromMap[K, V]
+ implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParTrieMap[K, V]] = new CanCombineFromMap[K, V]
}
diff --git a/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala b/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala
index 410b542a68..43d40776bf 100644
--- a/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala
+++ b/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala
@@ -26,7 +26,7 @@ import scala.collection.parallel.Task
-private[mutable] class DoublingUnrolledBuffer[T](implicit m: ClassManifest[T]) extends UnrolledBuffer[T]()(m) {
+private[mutable] class DoublingUnrolledBuffer[T](implicit t: ArrayTag[T]) extends UnrolledBuffer[T]()(t) {
override def calcNextLength(sz: Int) = if (sz < 10000) sz * 2 else sz
protected override def newUnrolled = new Unrolled[T](0, new Array[T](4), null, this)
}
diff --git a/src/library/scala/collection/parallel/package.scala b/src/library/scala/collection/parallel/package.scala
index 943e0208c7..e3124af12e 100644
--- a/src/library/scala/collection/parallel/package.scala
+++ b/src/library/scala/collection/parallel/package.scala
@@ -13,6 +13,7 @@ import scala.collection.generic.CanCombineFrom
import scala.collection.parallel.mutable.ParArray
import scala.collection.mutable.UnrolledBuffer
import annotation.unchecked.uncheckedVariance
+import language.implicitConversions
/** Package object for parallel collections.
*/
diff --git a/src/library/scala/concurrent/Awaitable.scala b/src/library/scala/concurrent/Awaitable.scala
index 6c9995eb05..99bdfbc5a9 100644
--- a/src/library/scala/concurrent/Awaitable.scala
+++ b/src/library/scala/concurrent/Awaitable.scala
@@ -10,14 +10,24 @@ package scala.concurrent
-import scala.annotation.implicitNotFound
import scala.concurrent.util.Duration
trait Awaitable[+T] {
- @implicitNotFound(msg = "Waiting must be done by calling `blocking(timeout) b`, where `b` is the `Awaitable` object or a potentially blocking piece of code.")
- def await(atMost: Duration)(implicit canawait: CanAwait): T
+ /**
+ * Should throw [[scala.concurrent.TimeoutException]] if it times out
+ * This method should not be called directly.
+ */
+ @throws(classOf[TimeoutException])
+ def ready(atMost: Duration)(implicit permit: CanAwait): this.type
+
+ /**
+ * Throws exceptions if it cannot produce a T within the specified time.
+ * This method should not be called directly.
+ */
+ @throws(classOf[Exception])
+ def result(atMost: Duration)(implicit permit: CanAwait): T
}
diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala
index 3471095051..fafd7fd238 100644
--- a/src/library/scala/concurrent/ConcurrentPackageObject.scala
+++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala
@@ -8,14 +8,11 @@
package scala.concurrent
-
-
-import java.util.concurrent.{ Executors, ExecutorService }
-import scala.concurrent.forkjoin.ForkJoinPool
-import scala.util.{ Try, Success, Failure }
+import java.util.concurrent.{ Executors, ExecutorService, ThreadFactory }
+import scala.concurrent.forkjoin.{ ForkJoinPool, ForkJoinWorkerThread }
import scala.concurrent.util.Duration
import ConcurrentPackageObject._
-
+import language.implicitConversions
/** This package object contains primitives for concurrent and parallel programming.
@@ -23,15 +20,9 @@ import ConcurrentPackageObject._
abstract class ConcurrentPackageObject {
/** A global execution environment for executing lightweight tasks.
*/
- lazy val executionContext =
- new impl.ExecutionContextImpl(getExecutorService)
+ lazy val defaultExecutionContext = new impl.ExecutionContextImpl(null)
- private[concurrent] def getExecutorService: AnyRef =
- if (scala.util.Properties.isJavaAtLeast("1.6")) {
- val vendor = scala.util.Properties.javaVmVendor
- if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple")) new ForkJoinPool
- else Executors.newCachedThreadPool()
- } else Executors.newCachedThreadPool()
+ private val currentExecutionContext = new ThreadLocal[ExecutionContext]
val handledFutureException: PartialFunction[Throwable, Throwable] = {
case t: Throwable if isFutureThrowable(t) => t
@@ -45,29 +36,41 @@ abstract class ConcurrentPackageObject {
case _ => true
}
- private[concurrent] def resolve[T](source: Try[T]): Try[T] = source match {
- case Failure(t: scala.runtime.NonLocalReturnControl[_]) => Success(t.value.asInstanceOf[T])
- case Failure(t: scala.util.control.ControlThrowable) => Failure(new ExecutionException("Boxed ControlThrowable", t))
- case Failure(t: InterruptedException) => Failure(new ExecutionException("Boxed InterruptedException", t))
- case Failure(e: Error) => Failure(new ExecutionException("Boxed Error", e))
- case _ => source
+ private[concurrent] def resolveEither[T](source: Either[Throwable, T]): Either[Throwable, T] = source match {
+ case Left(t) => resolver(t)
+ case _ => source
}
- private[concurrent] def resolver[T] =
- resolverFunction.asInstanceOf[PartialFunction[Throwable, Try[T]]]
-
+ private[concurrent] def resolver[T](throwable: Throwable): Either[Throwable, T] = throwable match {
+ case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value.asInstanceOf[T])
+ case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t))
+ case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t))
+ case e: Error => Left(new ExecutionException("Boxed Error", e))
+ case t => Left(t)
+ }
+
/* concurrency constructs */
- def future[T](body: =>T)(implicit execCtx: ExecutionContext = executionContext): Future[T] =
- execCtx future body
-
- def promise[T]()(implicit execCtx: ExecutionContext = executionContext): Promise[T] =
- execCtx promise
-
- /** Wraps a block of code into an awaitable object. */
- def body2awaitable[T](body: =>T) = new Awaitable[T] {
- def await(atMost: Duration)(implicit cb: CanAwait) = body
- }
+ /** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
+ *
+ * The result becomes available once the asynchronous computation is completed.
+ *
+ * @tparam T the type of the result
+ * @param body the asychronous computation
+ * @param execctx the execution context on which the future is run
+ * @return the `Future` holding the result of the computation
+ */
+ def future[T](body: =>T)(implicit execctx: ExecutionContext = defaultExecutionContext): Future[T] =
+ Future[T](body)
+
+ /** Creates a promise object which can be completed with a value.
+ *
+ * @tparam T the type of the value in the promise
+ * @param execctx the execution context on which the promise is created on
+ * @return the newly created `Promise` object
+ */
+ def promise[T]()(implicit execctx: ExecutionContext = defaultExecutionContext): Promise[T] =
+ Promise[T]()
/** Used to block on a piece of code which potentially blocks.
*
@@ -78,8 +81,8 @@ abstract class ConcurrentPackageObject {
* - InterruptedException - in the case that a wait within the blockable object was interrupted
* - TimeoutException - in the case that the blockable object timed out
*/
- def blocking[T](atMost: Duration)(body: =>T)(implicit execCtx: ExecutionContext): T =
- executionContext.blocking(atMost)(body)
+ def blocking[T](body: =>T): T =
+ blocking(impl.Future.body2awaitable(body), Duration.fromNanos(0))
/** Blocks on an awaitable object.
*
@@ -90,8 +93,11 @@ abstract class ConcurrentPackageObject {
* - InterruptedException - in the case that a wait within the blockable object was interrupted
* - TimeoutException - in the case that the blockable object timed out
*/
- def blocking[T](awaitable: Awaitable[T], atMost: Duration)(implicit execCtx: ExecutionContext = executionContext): T =
- executionContext.blocking(awaitable, atMost)
+ def blocking[T](awaitable: Awaitable[T], atMost: Duration): T =
+ currentExecutionContext.get match {
+ case null => Await.result(awaitable, atMost)
+ case ec => ec.internalBlockingCall(awaitable, atMost)
+ }
@inline implicit final def int2durationops(x: Int): DurationOps = new DurationOps(x)
}
@@ -102,11 +108,11 @@ private[concurrent] object ConcurrentPackageObject {
// compiling a subset of sources; it seems that the wildcard is not
// properly handled, and you get messages like "type _$1 defined twice".
// This is consistent with other package object breakdowns.
- private val resolverFunction: PartialFunction[Throwable, Try[_]] = {
- case t: scala.runtime.NonLocalReturnControl[_] => Success(t.value)
- case t: scala.util.control.ControlThrowable => Failure(new ExecutionException("Boxed ControlThrowable", t))
- case t: InterruptedException => Failure(new ExecutionException("Boxed InterruptedException", t))
- case e: Error => Failure(new ExecutionException("Boxed Error", e))
- case t => Failure(t)
- }
+ // private val resolverFunction: PartialFunction[Throwable, Either[Throwable, _]] = {
+ // case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value)
+ // case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t))
+ // case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t))
+ // case e: Error => Left(new ExecutionException("Boxed Error", e))
+ // case t => Left(t)
+ // }
}
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index c4a45f9fb5..3f62f58bf8 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -11,9 +11,8 @@ package scala.concurrent
import java.util.concurrent.atomic.{ AtomicInteger }
-import java.util.concurrent.{ Executors, Future => JFuture, Callable }
+import java.util.concurrent.{ Executors, Future => JFuture, Callable, ExecutorService, Executor }
import scala.concurrent.util.Duration
-import scala.util.{ Try, Success, Failure }
import scala.concurrent.forkjoin.{ ForkJoinPool, RecursiveTask => FJTask, RecursiveAction, ForkJoinWorkerThread }
import scala.collection.generic.CanBuildFrom
import collection._
@@ -21,112 +20,39 @@ import collection._
trait ExecutionContext {
-
- protected implicit object CanAwaitEvidence extends CanAwait
-
+
+ /** Runs a block of code on this execution context.
+ */
def execute(runnable: Runnable): Unit
-
- def execute[U](body: () => U): Unit
-
- def promise[T]: Promise[T]
-
- def future[T](body: Callable[T]): Future[T] = future(body.call())
-
- def future[T](body: => T): Future[T]
-
- def blocking[T](atMost: Duration)(body: =>T): T
-
- def blocking[T](awaitable: Awaitable[T], atMost: Duration): T
-
- def reportFailure(t: Throwable): Unit
-
- /* implementations follow */
-
- private implicit val executionContext = this
-
- def keptPromise[T](result: T): Promise[T] = {
- val p = promise[T]
- p success result
- }
-
- def brokenPromise[T](t: Throwable): Promise[T] = {
- val p = promise[T]
- p failure t
- }
-
- /** TODO some docs
- *
+
+ /** Used internally by the framework - blocks execution for at most `atMost` time while waiting
+ * for an `awaitable` object to become ready.
+ *
+ * Clients should use `scala.concurrent.blocking` instead.
*/
- def all[T, Coll[X] <: Traversable[X]](futures: Coll[Future[T]])(implicit cbf: CanBuildFrom[Coll[_], T, Coll[T]]): Future[Coll[T]] = {
- import nondeterministic._
- val buffer = new mutable.ArrayBuffer[T]
- val counter = new AtomicInteger(1) // how else could we do this?
- val p: Promise[Coll[T]] = promise[Coll[T]] // we need an implicit execctx in the signature
- var idx = 0
-
- def tryFinish() = if (counter.decrementAndGet() == 0) {
- val builder = cbf(futures)
- builder ++= buffer
- p success builder.result
- }
-
- for (f <- futures) {
- val currentIndex = idx
- buffer += null.asInstanceOf[T]
- counter.incrementAndGet()
- f onComplete {
- case Failure(t) =>
- p tryFailure t
- case Success(v) =>
- buffer(currentIndex) = v
- tryFinish()
- }
- idx += 1
- }
-
- tryFinish()
-
- p.future
- }
-
- /** TODO some docs
- *
+ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T
+
+ /** Reports that an asynchronous computation failed.
*/
- def any[T](futures: Traversable[Future[T]]): Future[T] = {
- val p = promise[T]
- val completeFirst: Try[T] => Unit = elem => p tryComplete elem
-
- futures foreach (_ onComplete completeFirst)
+ def reportFailure(t: Throwable): Unit
+
+}
- p.future
- }
- /** TODO some docs
- *
+/** Contains factory methods for creating execution contexts.
+ */
+object ExecutionContext {
+
+ implicit def defaultExecutionContext: ExecutionContext = scala.concurrent.defaultExecutionContext
+
+ /** Creates an `ExecutionContext` from the given `ExecutorService`.
*/
- def find[T](futures: Traversable[Future[T]])(predicate: T => Boolean): Future[Option[T]] = {
- if (futures.isEmpty) Promise.kept[Option[T]](None).future
- else {
- val result = promise[Option[T]]
- val count = new AtomicInteger(futures.size)
- val search: Try[T] => Unit = {
- v => v match {
- case Success(r) => if (predicate(r)) result trySuccess Some(r)
- case _ =>
- }
- if (count.decrementAndGet() == 0) result trySuccess None
- }
-
- futures.foreach(_ onComplete search)
-
- result.future
- }
- }
-
+ def fromExecutorService(e: ExecutorService): ExecutionContext with Executor = new impl.ExecutionContextImpl(e)
+
+ /** Creates an `ExecutionContext` from the given `Executor`.
+ */
+ def fromExecutor(e: Executor): ExecutionContext with Executor = new impl.ExecutionContextImpl(e)
+
}
-sealed trait CanAwait
-
-
-
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index 1dc8e38355..def086bc03 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -17,14 +17,15 @@ import java.util.{ LinkedList => JLinkedList }
import java.{ lang => jl }
import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, AtomicBoolean }
-import scala.util.{ Try, Success, Failure }
import scala.concurrent.util.Duration
+import scala.concurrent.impl.NonFatal
import scala.Option
import scala.annotation.tailrec
import scala.collection.mutable.Stack
import scala.collection.mutable.Builder
import scala.collection.generic.CanBuildFrom
+import language.higherKinds
@@ -83,7 +84,6 @@ import scala.collection.generic.CanBuildFrom
* }}}
*/
trait Future[+T] extends Awaitable[T] {
-self =>
/* Callbacks */
@@ -97,8 +97,8 @@ self =>
* $multipleCallbacks
*/
def onSuccess[U](pf: PartialFunction[T, U]): this.type = onComplete {
- case Failure(t) => // do nothing
- case Success(v) => if (pf isDefinedAt v) pf(v) else { /*do nothing*/ }
+ case Left(t) => // do nothing
+ case Right(v) => if (pf isDefinedAt v) pf(v) else { /*do nothing*/ }
}
/** When this future is completed with a failure (i.e. with a throwable),
@@ -114,11 +114,11 @@ self =>
* $multipleCallbacks
*/
def onFailure[U](callback: PartialFunction[Throwable, U]): this.type = onComplete {
- case Failure(t) => if (isFutureThrowable(t) && callback.isDefinedAt(t)) callback(t) else { /*do nothing*/ }
- case Success(v) => // do nothing
+ case Left(t) => if (isFutureThrowable(t) && callback.isDefinedAt(t)) callback(t) else { /*do nothing*/ }
+ case Right(v) => // do nothing
}
- /** When this future is completed, either through an exception, a timeout, or a value,
+ /** When this future is completed, either through an exception, or a value,
* apply the provided function.
*
* If the future has already been completed,
@@ -126,14 +126,32 @@ self =>
*
* $multipleCallbacks
*/
- def onComplete[U](func: Try[T] => U): this.type
+ def onComplete[U](func: Either[Throwable, T] => U): this.type
/* Miscellaneous */
/** Creates a new promise.
*/
- def newPromise[S]: Promise[S]
+ protected def newPromise[S]: Promise[S]
+
+ /** Returns whether the future has already been completed with
+ * a value or an exception.
+ *
+ * $nonDeterministic
+ *
+ * @return `true` if the future is already completed, `false` otherwise
+ */
+ def isCompleted: Boolean
+
+ /** The value of this `Future`.
+ *
+ * If the future is not completed the returned value will be `None`.
+ * If the future is completed the value will be `Some(Success(t))`
+ * if it contains a valid result, or `Some(Failure(error))` if it contains
+ * an exception.
+ */
+ def value: Option[Either[Throwable, T]]
/* Projections */
@@ -151,14 +169,11 @@ self =>
* and throws a corresponding exception if the original future fails.
*/
def failed: Future[Throwable] = {
- def noSuchElem(v: T) =
- new NoSuchElementException("Future.failed not completed with a throwable. Instead completed with: " + v)
-
val p = newPromise[Throwable]
onComplete {
- case Failure(t) => p success t
- case Success(v) => p failure noSuchElem(v)
+ case Left(t) => p success t
+ case Right(v) => p failure (new NoSuchElementException("Future.failed not completed with a throwable. Instead completed with: " + v))
}
p.future
@@ -172,8 +187,8 @@ self =>
* Will not be called if the future fails.
*/
def foreach[U](f: T => U): Unit = onComplete {
- case Success(r) => f(r)
- case Failure(_) => // do nothing
+ case Right(r) => f(r)
+ case Left(_) => // do nothing
}
/** Creates a new future by applying a function to the successful result of
@@ -186,11 +201,11 @@ self =>
val p = newPromise[S]
onComplete {
- case Failure(t) => p failure t
- case Success(v) =>
+ case Left(t) => p failure t
+ case Right(v) =>
try p success f(v)
catch {
- case t => p complete resolver(t)
+ case NonFatal(t) => p complete resolver(t)
}
}
@@ -208,15 +223,15 @@ self =>
val p = newPromise[S]
onComplete {
- case Failure(t) => p failure t
- case Success(v) =>
+ case Left(t) => p failure t
+ case Right(v) =>
try {
f(v) onComplete {
- case Failure(t) => p failure t
- case Success(v) => p success v
+ case Left(t) => p failure t
+ case Right(v) => p success v
}
} catch {
- case t: Throwable => p complete resolver(t)
+ case NonFatal(t) => p complete resolver(t)
}
}
@@ -228,40 +243,52 @@ self =>
* If the current future contains a value which satisfies the predicate, the new future will also hold that value.
* Otherwise, the resulting future will fail with a `NoSuchElementException`.
*
- * If the current future fails or times out, the resulting future also fails or times out, respectively.
+ * If the current future fails, then the resulting future also fails.
*
* Example:
* {{{
* val f = future { 5 }
* val g = f filter { _ % 2 == 1 }
* val h = f filter { _ % 2 == 0 }
- * await(0) g // evaluates to 5
- * await(0) h // throw a NoSuchElementException
+ * await(g, 0) // evaluates to 5
+ * await(h, 0) // throw a NoSuchElementException
* }}}
*/
def filter(pred: T => Boolean): Future[T] = {
val p = newPromise[T]
onComplete {
- case Failure(t) => p failure t
- case Success(v) =>
+ case Left(t) => p failure t
+ case Right(v) =>
try {
if (pred(v)) p success v
else p failure new NoSuchElementException("Future.filter predicate is not satisfied by: " + v)
} catch {
- case t: Throwable => p complete resolver(t)
+ case NonFatal(t) => p complete resolver(t)
}
}
p.future
}
- /** Creates a new future by mapping the value of the current future if the given partial function is defined at that value.
+ /** Used by for-comprehensions.
+ */
+ final def withFilter(p: T => Boolean): Future[T] = filter(p)
+ // final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p)
+
+ // final class FutureWithFilter[+S](self: Future[S], p: S => Boolean) {
+ // def foreach(f: S => Unit): Unit = self filter p foreach f
+ // def map[R](f: S => R) = self filter p map f
+ // def flatMap[R](f: S => Future[R]) = self filter p flatMap f
+ // def withFilter(q: S => Boolean): FutureWithFilter[S] = new FutureWithFilter[S](self, x => p(x) && q(x))
+ // }
+
+ /** Creates a new future by mapping the value of the current future, if the given partial function is defined at that value.
*
* If the current future contains a value for which the partial function is defined, the new future will also hold that value.
* Otherwise, the resulting future will fail with a `NoSuchElementException`.
*
- * If the current future fails or times out, the resulting future also fails or times out, respectively.
+ * If the current future fails, then the resulting future also fails.
*
* Example:
* {{{
@@ -272,21 +299,21 @@ self =>
* val h = f collect {
* case x if x > 0 => x * 2
* }
- * await(0) g // evaluates to 5
- * await(0) h // throw a NoSuchElementException
+ * await(g, 0) // evaluates to 5
+ * await(h, 0) // throw a NoSuchElementException
* }}}
*/
def collect[S](pf: PartialFunction[T, S]): Future[S] = {
val p = newPromise[S]
onComplete {
- case Failure(t) => p failure t
- case Success(v) =>
+ case Left(t) => p failure t
+ case Right(v) =>
try {
if (pf.isDefinedAt(v)) p success pf(v)
else p failure new NoSuchElementException("Future.collect partial function is not defined at: " + v)
} catch {
- case t: Throwable => p complete resolver(t)
+ case NonFatal(t) => p complete resolver(t)
}
}
@@ -309,9 +336,9 @@ self =>
val p = newPromise[U]
onComplete {
- case Failure(t) if pf isDefinedAt t =>
+ case Left(t) if pf isDefinedAt t =>
try { p success pf(t) }
- catch { case t: Throwable => p complete resolver(t) }
+ catch { case NonFatal(t) => p complete resolver(t) }
case otherwise => p complete otherwise
}
@@ -335,11 +362,11 @@ self =>
val p = newPromise[U]
onComplete {
- case Failure(t) if pf isDefinedAt t =>
+ case Left(t) if pf isDefinedAt t =>
try {
p completeWith pf(t)
} catch {
- case t: Throwable => p complete resolver(t)
+ case NonFatal(t) => p complete resolver(t)
}
case otherwise => p complete otherwise
}
@@ -359,8 +386,8 @@ self =>
val p = newPromise[(T, U)]
this onComplete {
- case Failure(t) => p failure t
- case Success(r) => that onSuccess {
+ case Left(t) => p failure t
+ case Right(r) => that onSuccess {
case r2 => p success ((r, r2))
}
}
@@ -382,19 +409,50 @@ self =>
* {{{
* val f = future { sys.error("failed") }
* val g = future { 5 }
- * val h = f orElse g
- * await(0) h // evaluates to 5
+ * val h = f fallbackTo g
+ * await(h, 0) // evaluates to 5
* }}}
*/
def fallbackTo[U >: T](that: Future[U]): Future[U] = {
val p = newPromise[U]
+ onComplete {
+ case r @ Right(_) ⇒ p complete r
+ case _ ⇒ p completeWith that
+ }
+ p.future
+ }
+
+ /** Creates a new `Future[S]` which is completed with this `Future`'s result if
+ * that conforms to `S`'s erased type or a `ClassCastException` otherwise.
+ */
+ def mapTo[S](implicit tag: ClassTag[S]): Future[S] = {
+ import java.{ lang => jl }
+ val toBoxed = Map[Class[_], Class[_]](
+ classOf[Boolean] -> classOf[jl.Boolean],
+ classOf[Byte] -> classOf[jl.Byte],
+ classOf[Char] -> classOf[jl.Character],
+ classOf[Short] -> classOf[jl.Short],
+ classOf[Int] -> classOf[jl.Integer],
+ classOf[Long] -> classOf[jl.Long],
+ classOf[Float] -> classOf[jl.Float],
+ classOf[Double] -> classOf[jl.Double],
+ classOf[Unit] -> classOf[scala.runtime.BoxedUnit]
+ )
+
+ def boxedType(c: Class[_]): Class[_] = {
+ if (c.isPrimitive) toBoxed(c) else c
+ }
+
+ val p = newPromise[S]
onComplete {
- case Failure(t) => that onComplete {
- case Failure(_) => p failure t
- case Success(v) => p success v
- }
- case Success(v) => p success v
+ case l: Left[Throwable, _] => p complete l.asInstanceOf[Either[Throwable, S]]
+ case Right(t) =>
+ p complete (try {
+ Right(boxedType(tag.erasure).cast(t).asInstanceOf[S])
+ } catch {
+ case e: ClassCastException => Left(e)
+ })
}
p.future
@@ -423,7 +481,7 @@ self =>
* }
* }}}
*/
- def andThen[U](pf: PartialFunction[Try[T], U]): Future[T] = {
+ def andThen[U](pf: PartialFunction[Either[Throwable, T], U]): Future[T] = {
val p = newPromise[T]
onComplete {
@@ -445,18 +503,18 @@ self =>
* val f = future { sys.error("failed") }
* val g = future { 5 }
* val h = f either g
- * await(0) h // evaluates to either 5 or throws a runtime exception
+ * await(h, 0) // evaluates to either 5 or throws a runtime exception
* }}}
*/
def either[U >: T](that: Future[U]): Future[U] = {
- val p = self.newPromise[U]
+ val p = newPromise[U]
- val completePromise: PartialFunction[Try[U], _] = {
- case Failure(t) => p tryFailure t
- case Success(v) => p trySuccess v
+ val completePromise: PartialFunction[Either[Throwable, U], _] = {
+ case Left(t) => p tryFailure t
+ case Right(v) => p trySuccess v
}
- self onComplete completePromise
+ this onComplete completePromise
that onComplete completePromise
p.future
@@ -466,28 +524,111 @@ self =>
-/** TODO some docs
+/** Future companion object.
*
* @define nonDeterministic
* Note: using this method yields nondeterministic dataflow programs.
*/
object Future {
+ /** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
+ *
+ * The result becomes available once the asynchronous computation is completed.
+ *
+ * @tparam T the type of the result
+ * @param body the asychronous computation
+ * @param execctx the execution context on which the future is run
+ * @return the `Future` holding the result of the computation
+ */
+ def apply[T](body: =>T)(implicit execctx: ExecutionContext): Future[T] = impl.Future(body)
+
+ import scala.collection.mutable.Builder
+ import scala.collection.generic.CanBuildFrom
+
+ /** Simple version of `Futures.traverse`. Transforms a `Traversable[Future[A]]` into a `Future[Traversable[A]]`.
+ * Useful for reducing many `Future`s into a single `Future`.
+ */
+ def sequence[A, M[_] <: Traversable[_]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]] = {
+ in.foldLeft(Promise.successful(cbf(in)).future) {
+ (fr, fa) => for (r <- fr; a <- fa.asInstanceOf[Future[A]]) yield (r += a)
+ } map (_.result)
+ }
- // TODO make more modular by encoding all other helper methods within the execution context
- /** TODO some docs
+ /** Returns a `Future` to the result of the first future in the list that is completed.
*/
- def all[T, Coll[X] <: Traversable[X]](futures: Coll[Future[T]])(implicit cbf: CanBuildFrom[Coll[_], T, Coll[T]], ec: ExecutionContext): Future[Coll[T]] =
- ec.all[T, Coll](futures)
+ def firstCompletedOf[T](futures: Traversable[Future[T]])(implicit executor: ExecutionContext): Future[T] = {
+ val p = Promise[T]()
- // move this to future companion object
- @inline def apply[T](body: =>T)(implicit executor: ExecutionContext): Future[T] = executor.future(body)
+ val completeFirst: Either[Throwable, T] => Unit = p tryComplete _
+ futures.foreach(_ onComplete completeFirst)
- def any[T](futures: Traversable[Future[T]])(implicit ec: ExecutionContext): Future[T] = ec.any(futures)
+ p.future
+ }
- def find[T](futures: Traversable[Future[T]])(predicate: T => Boolean)(implicit ec: ExecutionContext): Future[Option[T]] = ec.find(futures)(predicate)
+ /** Returns a `Future` that will hold the optional result of the first `Future` with a result that matches the predicate.
+ */
+ def find[T](futures: Traversable[Future[T]])(predicate: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = {
+ if (futures.isEmpty) Promise.successful[Option[T]](None).future
+ else {
+ val result = Promise[Option[T]]()
+ val ref = new AtomicInteger(futures.size)
+ val search: Either[Throwable, T] => Unit = v => try {
+ v match {
+ case Right(r) => if (predicate(r)) result tryComplete Right(Some(r))
+ case _ =>
+ }
+ } finally {
+ if (ref.decrementAndGet == 0)
+ result tryComplete Right(None)
+ }
-}
+ futures.foreach(_ onComplete search)
+
+ result.future
+ }
+ }
+
+ /** A non-blocking fold over the specified futures, with the start value of the given zero.
+ * The fold is performed on the thread where the last future is completed,
+ * the result will be the first failure of any of the futures, or any failure in the actual fold,
+ * or the result of the fold.
+ *
+ * Example:
+ * {{{
+ * val result = Await.result(Future.fold(futures)(0)(_ + _), 5 seconds)
+ * }}}
+ */
+ def fold[T, R](futures: Traversable[Future[T]])(zero: R)(foldFun: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
+ if (futures.isEmpty) Promise.successful(zero).future
+ else sequence(futures).map(_.foldLeft(zero)(foldFun))
+ }
+ /** Initiates a fold over the supplied futures where the fold-zero is the result value of the `Future` that's completed first.
+ *
+ * Example:
+ * {{{
+ * val result = Await.result(Futures.reduce(futures)(_ + _), 5 seconds)
+ * }}}
+ */
+ def reduce[T, R >: T](futures: Traversable[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
+ if (futures.isEmpty) Promise[R].failure(new NoSuchElementException("reduce attempted on empty collection")).future
+ else sequence(futures).map(_ reduceLeft op)
+ }
+
+ /** Transforms a `Traversable[A]` into a `Future[Traversable[B]]` using the provided function `A => Future[B]`.
+ * This is useful for performing a parallel map. For example, to apply a function to all items of a list
+ * in parallel:
+ *
+ * {{{
+ * val myFutureList = Future.traverse(myList)(x => Future(myFunc(x)))
+ * }}}
+ */
+ def traverse[A, B, M[_] <: Traversable[_]](in: M[A])(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] =
+ in.foldLeft(Promise.successful(cbf(in)).future) { (fr, a) =>
+ val fb = fn(a.asInstanceOf[A])
+ for (r <- fr; b <- fb) yield (r += b)
+ }.map(_.result)
+
+}
diff --git a/src/library/scala/concurrent/FutureTaskRunner.scala b/src/library/scala/concurrent/FutureTaskRunner.scala
index 75e6299ad9..9d6f8a7a88 100644
--- a/src/library/scala/concurrent/FutureTaskRunner.scala
+++ b/src/library/scala/concurrent/FutureTaskRunner.scala
@@ -8,6 +8,8 @@
package scala.concurrent
+import language.{implicitConversions, higherKinds}
+
/** The `FutureTaskRunner</code> trait is a base trait of task runners
* that provide some sort of future abstraction.
*
diff --git a/src/library/scala/concurrent/JavaConversions.scala b/src/library/scala/concurrent/JavaConversions.scala
index 127a0e0055..9b5e741549 100644
--- a/src/library/scala/concurrent/JavaConversions.scala
+++ b/src/library/scala/concurrent/JavaConversions.scala
@@ -9,6 +9,7 @@
package scala.concurrent
import java.util.concurrent.{ExecutorService, Executor}
+import language.implicitConversions
/** The `JavaConversions` object provides implicit converstions supporting
* interoperability between Scala and Java concurrency classes.
diff --git a/src/library/scala/concurrent/ManagedBlocker.scala b/src/library/scala/concurrent/ManagedBlocker.scala
index 0b6d82e76f..9c6f4d51d6 100644
--- a/src/library/scala/concurrent/ManagedBlocker.scala
+++ b/src/library/scala/concurrent/ManagedBlocker.scala
@@ -12,7 +12,6 @@ package scala.concurrent
*
* @author Philipp Haller
*/
-@deprecated("Not used.", "2.10.0")
trait ManagedBlocker {
/**
diff --git a/src/library/scala/concurrent/Promise.scala b/src/library/scala/concurrent/Promise.scala
index 4404e90971..cd22a55ce7 100644
--- a/src/library/scala/concurrent/Promise.scala
+++ b/src/library/scala/concurrent/Promise.scala
@@ -8,11 +8,6 @@
package scala.concurrent
-import scala.util.{ Try, Success, Failure }
-
-
-
-
/** Promise is an object which can be completed with a value or failed
* with an exception.
*
@@ -30,8 +25,6 @@ import scala.util.{ Try, Success, Failure }
*/
trait Promise[T] {
- import nondeterministic._
-
/** Future containing the value of this promise.
*/
def future: Future[T]
@@ -42,7 +35,7 @@ trait Promise[T] {
*
* $promiseCompletion
*/
- def complete(result:Try[T]): this.type = if (tryComplete(result)) this else throwCompleted
+ def complete(result: Either[Throwable, T]): this.type = if (tryComplete(result)) this else throwCompleted
/** Tries to complete the promise with either a value or the exception.
*
@@ -50,7 +43,7 @@ trait Promise[T] {
*
* @return If the promise has already been completed returns `false`, or `true` otherwise.
*/
- def tryComplete(result: Try[T]): Boolean
+ def tryComplete(result: Either[Throwable, T]): Boolean
/** Completes this promise with the specified future, once that future is completed.
*
@@ -77,7 +70,7 @@ trait Promise[T] {
*
* @return If the promise has already been completed returns `false`, or `true` otherwise.
*/
- def trySuccess(value: T): Boolean = tryComplete(Success(value))
+ def trySuccess(value: T): Boolean = tryComplete(Right(value))
/** Completes the promise with an exception.
*
@@ -95,7 +88,7 @@ trait Promise[T] {
*
* @return If the promise has already been completed returns `false`, or `true` otherwise.
*/
- def tryFailure(t: Throwable): Boolean = tryComplete(Failure(t))
+ def tryFailure(t: Throwable): Boolean = tryComplete(Left(t))
/** Wraps a `Throwable` in an `ExecutionException` if necessary. TODO replace with `resolver` from scala.concurrent
*
@@ -114,12 +107,30 @@ trait Promise[T] {
object Promise {
- def kept[T](result: T)(implicit execctx: ExecutionContext): Promise[T] =
- execctx keptPromise result
+ /** Creates a promise object which can be completed with a value.
+ *
+ * @tparam T the type of the value in the promise
+ * @param execctx the execution context on which the promise is created on
+ * @return the newly created `Promise` object
+ */
+ def apply[T]()(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.DefaultPromise[T]()
- def broken[T](t: Throwable)(implicit execctx: ExecutionContext): Promise[T] =
- execctx brokenPromise t
+ /** Creates an already completed Promise with the specified exception.
+ *
+ * @tparam T the type of the value in the promise
+ * @param execctx the execution context on which the promise is created on
+ * @return the newly created `Promise` object
+ */
+ def failed[T](exception: Throwable)(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.KeptPromise[T](Left(exception))
+ /** Creates an already completed Promise with the specified result.
+ *
+ * @tparam T the type of the value in the promise
+ * @param execctx the execution context on which the promise is created on
+ * @return the newly created `Promise` object
+ */
+ def successful[T](result: T)(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.KeptPromise[T](Right(result))
+
}
diff --git a/src/library/scala/concurrent/TaskRunner.scala b/src/library/scala/concurrent/TaskRunner.scala
index 500d79e07f..3180e9ce8a 100644
--- a/src/library/scala/concurrent/TaskRunner.scala
+++ b/src/library/scala/concurrent/TaskRunner.scala
@@ -8,6 +8,8 @@
package scala.concurrent
+import language.{higherKinds, implicitConversions}
+
/** The `TaskRunner` trait...
*
* @author Philipp Haller
diff --git a/src/library/scala/concurrent/ThreadPoolRunner.scala b/src/library/scala/concurrent/ThreadPoolRunner.scala
index a3e0253634..fd6882348a 100644
--- a/src/library/scala/concurrent/ThreadPoolRunner.scala
+++ b/src/library/scala/concurrent/ThreadPoolRunner.scala
@@ -9,6 +9,7 @@
package scala.concurrent
import java.util.concurrent.{ExecutorService, Callable, TimeUnit}
+import language.implicitConversions
/** The `ThreadPoolRunner` trait uses a `java.util.concurrent.ExecutorService`
* to run submitted tasks.
diff --git a/src/library/scala/concurrent/ThreadRunner.scala b/src/library/scala/concurrent/ThreadRunner.scala
index 28fcf57df8..76be94aa6b 100644
--- a/src/library/scala/concurrent/ThreadRunner.scala
+++ b/src/library/scala/concurrent/ThreadRunner.scala
@@ -9,6 +9,7 @@
package scala.concurrent
import java.lang.Thread
+import language.implicitConversions
/** The `ThreadRunner` trait...
*
diff --git a/src/library/scala/concurrent/impl/AbstractPromise.java b/src/library/scala/concurrent/impl/AbstractPromise.java
index 5280d67854..8aac5de042 100644
--- a/src/library/scala/concurrent/impl/AbstractPromise.java
+++ b/src/library/scala/concurrent/impl/AbstractPromise.java
@@ -15,7 +15,7 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
abstract class AbstractPromise {
- private volatile Object _ref = null;
+ private volatile Object _ref;
protected final static AtomicReferenceFieldUpdater<AbstractPromise, Object> updater =
- AtomicReferenceFieldUpdater.newUpdater(AbstractPromise.class, Object.class, "_ref");
-}
+ AtomicReferenceFieldUpdater.newUpdater(AbstractPromise.class, Object.class, "_ref");
+} \ No newline at end of file
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index dd1de2025e..ad98331241 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -10,128 +10,101 @@ package scala.concurrent.impl
-import java.util.concurrent.{Callable, ExecutorService}
+import java.util.concurrent.{Callable, Executor, ExecutorService, Executors, ThreadFactory}
import scala.concurrent.forkjoin._
-import scala.concurrent.{ExecutionContext, resolver, Awaitable, body2awaitable}
-import scala.util.{ Try, Success, Failure }
+import scala.concurrent.{ExecutionContext, resolver, Awaitable}
import scala.concurrent.util.{ Duration }
-import scala.collection.mutable.Stack
-class ExecutionContextImpl(val executorService: AnyRef) extends ExecutionContext {
+private[scala] class ExecutionContextImpl(es: AnyRef) extends ExecutionContext with Executor {
import ExecutionContextImpl._
-
- def execute(runnable: Runnable): Unit = executorService match {
- case fj: ForkJoinPool =>
- if (Thread.currentThread.isInstanceOf[ForkJoinWorkerThread]) {
- val fjtask = ForkJoinTask.adapt(runnable)
- fjtask.fork
- } else {
- fj.execute(runnable)
+
+ val executorService: AnyRef = if (es eq null) getExecutorService else es
+
+ // to ensure that the current execution context thread local is properly set
+ def executorsThreadFactory = new ThreadFactory {
+ def newThread(r: Runnable) = new Thread(new Runnable {
+ override def run() {
+ currentExecutionContext.set(ExecutionContextImpl.this)
+ r.run()
}
- case executorService: ExecutorService =>
- executorService execute runnable
+ })
}
-
- def execute[U](body: () => U): Unit = execute(new Runnable {
- def run() = body()
- })
-
- def promise[T]: Promise[T] = new Promise.DefaultPromise[T]()(this)
-
- def future[T](body: =>T): Future[T] = {
- val p = promise[T]
-
- dispatchFuture {
- () =>
- p complete {
- try {
- Success(body)
- } catch {
- case e => resolver(e)
- }
+
+ // to ensure that the current execution context thread local is properly set
+ def forkJoinPoolThreadFactory = new ForkJoinPool.ForkJoinWorkerThreadFactory {
+ def newThread(fjp: ForkJoinPool) = new ForkJoinWorkerThread(fjp) {
+ override def onStart() {
+ currentExecutionContext.set(ExecutionContextImpl.this)
}
}
-
- p.future
}
+
+ def getExecutorService: AnyRef =
+ if (scala.util.Properties.isJavaAtLeast("1.6")) {
+ val vendor = scala.util.Properties.javaVmVendor
+ if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple"))
+ new ForkJoinPool(
+ Runtime.getRuntime.availableProcessors(),
+ forkJoinPoolThreadFactory,
+ null,
+ false)
+ else
+ Executors.newCachedThreadPool(executorsThreadFactory)
+ } else Executors.newCachedThreadPool(executorsThreadFactory)
- def blocking[T](atMost: Duration)(body: =>T): T = blocking(body2awaitable(body), atMost)
+ def execute(runnable: Runnable): Unit = executorService match {
+ case fj: ForkJoinPool =>
+ Thread.currentThread match {
+ case fjw: ForkJoinWorkerThread if fjw.getPool eq fj =>
+ val fjtask = runnable match {
+ case fjt: ForkJoinTask[_] => fjt
+ case _ => ForkJoinTask.adapt(runnable)
+ }
+ fjtask.fork
+ case _ =>
+ fj.execute(runnable)
+ }
+ case executor: Executor =>
+ executor execute runnable
+ }
- def blocking[T](awaitable: Awaitable[T], atMost: Duration): T = {
- currentExecutionContext.get match {
- case null => awaitable.await(atMost)(null) // outside - TODO - fix timeout case
- case x => x.blockingCall(awaitable) // inside an execution context thread
+ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T = {
+ Future.releaseStack(this)
+
+ executorService match {
+ case fj: ForkJoinPool =>
+ var result: T = null.asInstanceOf[T]
+ val managedBlocker = new ForkJoinPool.ManagedBlocker {
+ @volatile var isdone = false
+ def block() = {
+ result = awaitable.result(atMost)(scala.concurrent.Await.canAwaitEvidence)
+ isdone = true
+ true
+ }
+ def isReleasable = isdone
+ }
+ ForkJoinPool.managedBlock(managedBlocker)
+ result
+ case _ =>
+ awaitable.result(atMost)(scala.concurrent.Await.canAwaitEvidence)
}
}
def reportFailure(t: Throwable) = t match {
- case e: Error => throw e // rethrow serious errors
+ // `Error`s are currently wrapped by `resolver`.
+ // Also, re-throwing `Error`s here causes an exception handling test to fail.
+ //case e: Error => throw e
case t => t.printStackTrace()
}
- /** Only callable from the tasks running on the same execution context. */
- private def blockingCall[T](body: Awaitable[T]): T = {
- releaseStack()
-
- // TODO see what to do with timeout
- body.await(Duration.fromNanos(0))(CanAwaitEvidence)
- }
-
- // an optimization for batching futures
- // TODO we should replace this with a public queue,
- // so that it can be stolen from
- // OR: a push to the local task queue should be so cheap that this is
- // not even needed, but stealing is still possible
- private val _taskStack = new ThreadLocal[Stack[() => Unit]]()
-
- private def releaseStack(): Unit =
- _taskStack.get match {
- case stack if (stack ne null) && stack.nonEmpty =>
- val tasks = stack.elems
- stack.clear()
- _taskStack.remove()
- dispatchFuture(() => _taskStack.get.elems = tasks, true)
- case null =>
- // do nothing - there is no local batching stack anymore
- case _ =>
- _taskStack.remove()
- }
-
- private[impl] def dispatchFuture(task: () => Unit, force: Boolean = false): Unit =
- _taskStack.get match {
- case stack if (stack ne null) && !force => stack push task
- case _ => this.execute(
- new Runnable {
- def run() {
- try {
- val taskStack = Stack[() => Unit](task)
- _taskStack set taskStack
- while (taskStack.nonEmpty) {
- val next = taskStack.pop()
- try {
- next.apply()
- } catch {
- case e =>
- // TODO catching all and continue isn't good for OOME
- reportFailure(e)
- }
- }
- } finally {
- _taskStack.remove()
- }
- }
- }
- )
- }
-
}
-object ExecutionContextImpl {
+private[concurrent] object ExecutionContextImpl {
- private[concurrent] def currentExecutionContext: ThreadLocal[ExecutionContextImpl] = new ThreadLocal[ExecutionContextImpl] {
+ private[concurrent] def currentExecutionContext: ThreadLocal[ExecutionContext] = new ThreadLocal[ExecutionContext] {
override protected def initialValue = null
}
diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala
index 9466761d4d..548524c9fe 100644
--- a/src/library/scala/concurrent/impl/Future.scala
+++ b/src/library/scala/concurrent/impl/Future.scala
@@ -8,13 +8,16 @@
package scala.concurrent.impl
-import scala.concurrent.{Awaitable, ExecutionContext}
-import scala.util.{ Try, Success, Failure }
-//import scala.util.continuations._
-trait Future[+T] extends scala.concurrent.Future[T] with Awaitable[T] {
- implicit def executor: ExecutionContextImpl
+import scala.concurrent.util.Duration
+import scala.concurrent.{Awaitable, ExecutionContext, CanAwait}
+import scala.collection.mutable.Stack
+
+
+private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awaitable[T] {
+
+ implicit def executor: ExecutionContext
/** For use only within a Future.flow block or another compatible Delimited Continuations reset block.
*
@@ -25,65 +28,87 @@ trait Future[+T] extends scala.concurrent.Future[T] with Awaitable[T] {
/** Tests whether this Future has been completed.
*/
- final def isCompleted: Boolean = value.isDefined
+ def isCompleted: Boolean
/** The contained value of this Future. Before this Future is completed
* the value will be None. After completion the value will be Some(Right(t))
* if it contains a valid result, or Some(Left(error)) if it contains
* an exception.
*/
- def value: Option[Try[T]]
+ def value: Option[Either[Throwable, T]]
- def onComplete[U](func: Try[T] => U): this.type
+ def onComplete[U](func: Either[Throwable, T] => U): this.type
- /** Creates a new Future[A] which is completed with this Future's result if
- * that conforms to A's erased type or a ClassCastException otherwise.
- */
- final def mapTo[T](implicit m: Manifest[T]) = {
- val p = executor.promise[T]
-
- onComplete {
- case f @ Failure(t) => p complete f.asInstanceOf[Try[T]]
- case Success(v) =>
- p complete (try {
- Success(Future.boxedType(m.erasure).cast(v).asInstanceOf[T])
- } catch {
- case e: ClassCastException ⇒ Failure(e)
- })
- }
+}
- p.future
+object Future {
+ /** Wraps a block of code into an awaitable object. */
+ private[concurrent] def body2awaitable[T](body: =>T) = new Awaitable[T] {
+ def ready(atMost: Duration)(implicit permit: CanAwait) = {
+ body
+ this
+ }
+ def result(atMost: Duration)(implicit permit: CanAwait) = body
}
-
- /** Used by for-comprehensions.
- */
- final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p)
-
- final class FutureWithFilter[+A](self: Future[A], p: A => Boolean) {
- def foreach(f: A => Unit): Unit = self filter p foreach f
- def map[B](f: A => B) = self filter p map f
- def flatMap[B](f: A => Future[B]) = self filter p flatMap f
- def withFilter(q: A => Boolean): FutureWithFilter[A] = new FutureWithFilter[A](self, x ⇒ p(x) && q(x))
+
+ def apply[T](body: =>T)(implicit executor: ExecutionContext): Future[T] = {
+ val promise = new Promise.DefaultPromise[T]()
+
+ //TODO: use `dispatchFuture`?
+ executor.execute(new Runnable {
+ def run = {
+ promise complete {
+ try {
+ Right(body)
+ } catch {
+ case NonFatal(e) =>
+ // Commenting out reporting for now, since it produces too much output in the tests
+ //executor.reportFailure(e)
+ scala.concurrent.resolver(e)
+ }
+ }
+ }
+ })
+ promise.future
}
-}
+ // an optimization for batching futures
+ // TODO we should replace this with a public queue,
+ // so that it can be stolen from
+ // OR: a push to the local task queue should be so cheap that this is
+ // not even needed, but stealing is still possible
+ private val _taskStack = new ThreadLocal[Stack[() => Unit]]()
+
+ private[impl] def releaseStack(executor: ExecutionContext): Unit =
+ _taskStack.get match {
+ case stack if (stack ne null) && stack.nonEmpty =>
+ val tasks = stack.elems
+ stack.clear()
+ _taskStack.remove()
+ dispatchFuture(executor, () => _taskStack.get.elems = tasks, true)
+ case null =>
+ // do nothing - there is no local batching stack anymore
+ case _ =>
+ _taskStack.remove()
+ }
-object Future {
- import java.{ lang => jl }
-
- private val toBoxed = Map[Class[_], Class[_]](
- classOf[Boolean] -> classOf[jl.Boolean],
- classOf[Byte] -> classOf[jl.Byte],
- classOf[Char] -> classOf[jl.Character],
- classOf[Short] -> classOf[jl.Short],
- classOf[Int] -> classOf[jl.Integer],
- classOf[Long] -> classOf[jl.Long],
- classOf[Float] -> classOf[jl.Float],
- classOf[Double] -> classOf[jl.Double],
- classOf[Unit] -> classOf[scala.runtime.BoxedUnit]
- )
-
- def boxedType(c: Class[_]): Class[_] = {
- if (c.isPrimitive) toBoxed(c) else c
- }
+ private[impl] def dispatchFuture(executor: ExecutionContext, task: () => Unit, force: Boolean = false): Unit =
+ _taskStack.get match {
+ case stack if (stack ne null) && !force => stack push task // FIXME we can't mix tasks aimed for different ExecutionContexts see: https://github.com/akka/akka/blob/v2.0.1/akka-actor/src/main/scala/akka/dispatch/Future.scala#L373
+ case _ => executor.execute(new Runnable {
+ def run() {
+ try {
+ val taskStack = Stack[() => Unit](task)
+ _taskStack set taskStack
+ while (taskStack.nonEmpty) {
+ val next = taskStack.pop()
+ try next() catch { case NonFatal(e) => executor reportFailure e }
+ }
+ } finally {
+ _taskStack.remove()
+ }
+ }
+ })
+ }
+
}
diff --git a/src/library/scala/concurrent/impl/NonFatal.scala b/src/library/scala/concurrent/impl/NonFatal.scala
new file mode 100644
index 0000000000..bc509e664c
--- /dev/null
+++ b/src/library/scala/concurrent/impl/NonFatal.scala
@@ -0,0 +1,37 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.concurrent
+package impl
+
+/**
+ * Extractor of non-fatal Throwables. Will not match fatal errors
+ * like VirtualMachineError (OutOfMemoryError)
+ * ThreadDeath, LinkageError and InterruptedException.
+ * StackOverflowError is matched, i.e. considered non-fatal.
+ *
+ * Usage to catch all harmless throwables:
+ * {{{
+ * try {
+ * // dangerous stuff
+ * } catch {
+ * case NonFatal(e) => log.error(e, "Something not that bad")
+ * }
+ * }}}
+ */
+private[concurrent] object NonFatal {
+
+ def unapply(t: Throwable): Option[Throwable] = t match {
+ case e: StackOverflowError ⇒ Some(e) // StackOverflowError ok even though it is a VirtualMachineError
+ // VirtualMachineError includes OutOfMemoryError and other fatal errors
+ case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError ⇒ None
+ case e ⇒ Some(e)
+ }
+
+}
+
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index 3d40ae6930..ee1841aaff 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -12,21 +12,20 @@ package scala.concurrent.impl
import java.util.concurrent.TimeUnit.{ NANOSECONDS, MILLISECONDS }
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
-import scala.concurrent.{Awaitable, ExecutionContext, resolve, resolver, blocking, CanAwait, TimeoutException}
+import scala.concurrent.{Awaitable, ExecutionContext, resolveEither, resolver, blocking, CanAwait, TimeoutException}
//import scala.util.continuations._
import scala.concurrent.util.Duration
-import scala.util.Try
import scala.util
import scala.annotation.tailrec
//import scala.concurrent.NonDeterministic
-trait Promise[T] extends scala.concurrent.Promise[T] with Future[T] {
+private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with Future[T] {
def future = this
- def newPromise[S]: Promise[S] = executor promise
+ def newPromise[S]: scala.concurrent.Promise[S] = new Promise.DefaultPromise()
// TODO refine answer and return types here from Any to type parameters
// then move this up in the hierarchy
@@ -75,36 +74,10 @@ trait Promise[T] extends scala.concurrent.Promise[T] with Future[T] {
object Promise {
- def dur2long(dur: Duration): Long = if (dur.isFinite) dur.toNanos else Long.MaxValue
-
- def EmptyPending[T](): FState[T] = emptyPendingValue.asInstanceOf[FState[T]]
-
- /** Represents the internal state.
- *
- * [adriaan] it's unsound to make FState covariant (tryComplete won't type check)
- */
- sealed trait FState[T] { def value: Option[Try[T]] }
-
- case class Pending[T](listeners: List[Try[T] => Any] = Nil) extends FState[T] {
- def value: Option[Try[T]] = None
- }
-
- case class Success[T](value: Option[util.Success[T]] = None) extends FState[T] {
- def result: T = value.get.get
- }
-
- case class Failure[T](value: Option[util.Failure[T]] = None) extends FState[T] {
- def exception: Throwable = value.get.exception
- }
-
- private val emptyPendingValue = Pending[Nothing](Nil)
-
/** Default promise implementation.
*/
- class DefaultPromise[T](implicit val executor: ExecutionContextImpl) extends AbstractPromise with Promise[T] {
- self =>
-
- updater.set(this, Promise.EmptyPending())
+ class DefaultPromise[T](implicit val executor: ExecutionContext) extends AbstractPromise with Promise[T] { self =>
+ updater.set(this, Nil) // Start at "No callbacks" //FIXME switch to Unsafe instead of ARFU
protected final def tryAwait(atMost: Duration): Boolean = {
@tailrec
@@ -115,7 +88,7 @@ object Promise {
val start = System.nanoTime()
try {
synchronized {
- while (value.isEmpty) wait(ms, ns)
+ while (!isCompleted) wait(ms, ns)
}
} catch {
case e: InterruptedException =>
@@ -123,93 +96,91 @@ object Promise {
awaitUnsafe(waitTimeNanos - (System.nanoTime() - start))
} else
- value.isDefined
+ isCompleted
}
-
- executor.blocking(concurrent.body2awaitable(awaitUnsafe(dur2long(atMost))), Duration.fromNanos(0))
+ //FIXME do not do this if there'll be no waiting
+ blocking(Future.body2awaitable(awaitUnsafe(if (atMost.isFinite) atMost.toNanos else Long.MaxValue)), atMost)
}
- private def ready(atMost: Duration)(implicit permit: CanAwait): this.type =
- if (value.isDefined || tryAwait(atMost)) this
+ @throws(classOf[TimeoutException])
+ def ready(atMost: Duration)(implicit permit: CanAwait): this.type =
+ if (isCompleted || tryAwait(atMost)) this
else throw new TimeoutException("Futures timed out after [" + atMost.toMillis + "] milliseconds")
- def await(atMost: Duration)(implicit permit: CanAwait): T =
+ @throws(classOf[Exception])
+ def result(atMost: Duration)(implicit permit: CanAwait): T =
ready(atMost).value.get match {
- case util.Failure(e) => throw e
- case util.Success(r) => r
+ case Left(e) => throw e
+ case Right(r) => r
}
- def value: Option[Try[T]] = getState.value
+ def value: Option[Either[Throwable, T]] = getState match {
+ case c: Either[_, _] => Some(c.asInstanceOf[Either[Throwable, T]])
+ case _ => None
+ }
+
+ override def isCompleted(): Boolean = getState match { // Cheaper than boxing result into Option due to "def value"
+ case _: Either[_, _] => true
+ case _ => false
+ }
@inline
- private[this] final def updater = AbstractPromise.updater.asInstanceOf[AtomicReferenceFieldUpdater[AbstractPromise, FState[T]]]
+ private[this] final def updater = AbstractPromise.updater.asInstanceOf[AtomicReferenceFieldUpdater[AbstractPromise, AnyRef]]
@inline
- protected final def updateState(oldState: FState[T], newState: FState[T]): Boolean = updater.compareAndSet(this, oldState, newState)
+ protected final def updateState(oldState: AnyRef, newState: AnyRef): Boolean = updater.compareAndSet(this, oldState, newState)
@inline
- protected final def getState: FState[T] = updater.get(this)
+ protected final def getState: AnyRef = updater.get(this)
- def tryComplete(value: Try[T]): Boolean = {
- val callbacks: List[Try[T] => Any] = {
+ def tryComplete(value: Either[Throwable, T]): Boolean = {
+ val callbacks: List[Either[Throwable, T] => Unit] = {
try {
@tailrec
- def tryComplete(v: Try[T]): List[Try[T] => Any] = {
+ def tryComplete(v: Either[Throwable, T]): List[Either[Throwable, T] => Unit] = {
getState match {
- case cur @ Pending(listeners) =>
- val newState =
- if (v.isFailure) Failure(Some(v.asInstanceOf[util.Failure[T]]))
- else Success(Some(v.asInstanceOf[util.Success[T]]))
-
- if (updateState(cur, newState)) listeners
- else tryComplete(v)
+ case raw: List[_] =>
+ val cur = raw.asInstanceOf[List[Either[Throwable, T] => Unit]]
+ if (updateState(cur, v)) cur else tryComplete(v)
case _ => null
}
}
- tryComplete(resolve(value))
+ tryComplete(resolveEither(value))
} finally {
- synchronized { notifyAll() } // notify any blockers from `tryAwait`
+ synchronized { notifyAll() } //Notify any evil blockers
}
}
callbacks match {
case null => false
case cs if cs.isEmpty => true
- case cs =>
- executor dispatchFuture {
- () => cs.foreach(f => notifyCompleted(f, value))
- }
- true
+ case cs => Future.dispatchFuture(executor, () => cs.foreach(f => notifyCompleted(f, value))); true
}
}
- def onComplete[U](func: Try[T] => U): this.type = {
- @tailrec // Returns whether the future has already been completed or not
- def tryAddCallback(): Boolean = {
+ def onComplete[U](func: Either[Throwable, T] => U): this.type = {
+ @tailrec //Returns the future's results if it has already been completed, or null otherwise.
+ def tryAddCallback(): Either[Throwable, T] = {
val cur = getState
cur match {
- case _: Success[_] | _: Failure[_] => true
- case p: Pending[_] =>
- val pt = p.asInstanceOf[Pending[T]]
- if (updateState(pt, pt.copy(listeners = func :: pt.listeners))) false else tryAddCallback()
+ case r: Either[_, _] => r.asInstanceOf[Either[Throwable, T]]
+ case listeners: List[_] => if (updateState(listeners, func :: listeners)) null else tryAddCallback()
}
}
- if (tryAddCallback()) {
- val result = value.get
- executor dispatchFuture {
- () => notifyCompleted(func, result)
- }
+ tryAddCallback() match {
+ case null => this
+ case completed =>
+ Future.dispatchFuture(executor, () => notifyCompleted(func, completed))
+ this
}
-
- this
}
- private final def notifyCompleted(func: Try[T] => Any, result: Try[T]) {
+ private final def notifyCompleted(func: Either[Throwable, T] => Any, result: Either[Throwable, T]) {
try {
func(result)
} catch {
- case e => executor.reportFailure(e)
+ case NonFatal(e) => executor reportFailure e
}
}
}
@@ -218,41 +189,26 @@ object Promise {
*
* Useful in Future-composition when a value to contribute is already available.
*/
- final class KeptPromise[T](suppliedValue: Try[T])(implicit val executor: ExecutionContextImpl) extends Promise[T] {
- val value = Some(resolve(suppliedValue))
+ final class KeptPromise[T](suppliedValue: Either[Throwable, T])(implicit val executor: ExecutionContext) extends Promise[T] {
+
+ val value = Some(resolveEither(suppliedValue))
+
+ override def isCompleted(): Boolean = true
- def tryComplete(value: Try[T]): Boolean = false
+ def tryComplete(value: Either[Throwable, T]): Boolean = false
- def onComplete[U](func: Try[T] => U): this.type = {
+ def onComplete[U](func: Either[Throwable, T] => U): this.type = {
val completedAs = value.get
- executor dispatchFuture {
- () => func(completedAs)
- }
+ Future.dispatchFuture(executor, () => func(completedAs))
this
}
- private def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this
+ def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this
- def await(atMost: Duration)(implicit permit: CanAwait): T = value.get match {
- case util.Failure(e) => throw e
- case util.Success(r) => r
+ def result(atMost: Duration)(implicit permit: CanAwait): T = value.get match {
+ case Left(e) => throw e
+ case Right(r) => r
}
}
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/library/scala/concurrent/impl/Unsafe.java b/src/library/scala/concurrent/impl/Unsafe.java
new file mode 100644
index 0000000000..21f7e638e5
--- /dev/null
+++ b/src/library/scala/concurrent/impl/Unsafe.java
@@ -0,0 +1,32 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+package scala.concurrent;
+
+import java.lang.reflect.Field;
+
+final class Unsafe {
+ public final static sun.misc.Unsafe instance;
+ static {
+ try {
+ sun.misc.Unsafe found = null;
+ for(Field field : sun.misc.Unsafe.class.getDeclaredFields()) {
+ if (field.getType() == sun.misc.Unsafe.class) {
+ field.setAccessible(true);
+ found = (sun.misc.Unsafe) field.get(null);
+ break;
+ }
+ }
+ if (found == null) throw new IllegalStateException("Can't find instance of sun.misc.Unsafe");
+ else instance = found;
+ } catch(Throwable t) {
+ throw new ExceptionInInitializerError(t);
+ }
+ }
+}
diff --git a/src/library/scala/concurrent/package.scala b/src/library/scala/concurrent/package.scala
index 204b3f2673..b06c6f3c63 100644
--- a/src/library/scala/concurrent/package.scala
+++ b/src/library/scala/concurrent/package.scala
@@ -20,35 +20,15 @@ package object concurrent extends scala.concurrent.ConcurrentPackageObject {
}
package concurrent {
- object await {
- def ready[T](atMost: Duration)(awaitable: Awaitable[T])(implicit execCtx: ExecutionContext = executionContext): Awaitable[T] = {
- try blocking(awaitable, atMost)
- catch { case _ => }
- awaitable
- }
-
- def result[T](atMost: Duration)(awaitable: Awaitable[T])(implicit execCtx: ExecutionContext = executionContext): T = {
- blocking(awaitable, atMost)
- }
- }
-
- /** Importing this object allows using some concurrency primitives
- * on futures and promises that can yield nondeterministic programs.
- *
- * While program determinism is broken when using these primitives,
- * some programs cannot be written without them (e.g. multiple client threads
- * cannot send requests to a server thread through regular promises and futures).
- */
- object nondeterministic { }
-
- /** A timeout exception.
- *
- * Futures are failed with a timeout exception when their timeout expires.
- *
- * Each timeout exception contains an origin future which originally timed out.
- */
- class FutureTimeoutException(origin: Future[_], message: String) extends TimeoutException(message) {
- def this(origin: Future[_]) = this(origin, "Future timed out.")
+
+ sealed trait CanAwait
+
+ object Await {
+ private[concurrent] implicit val canAwaitEvidence = new CanAwait {}
+
+ def ready[T](awaitable: Awaitable[T], atMost: Duration): Awaitable[T] = awaitable.ready(atMost)
+
+ def result[T](awaitable: Awaitable[T], atMost: Duration): T = awaitable.result(atMost)
}
final class DurationOps private[concurrent] (x: Int) {
diff --git a/src/library/scala/concurrent/util/Duration.scala b/src/library/scala/concurrent/util/Duration.scala
index 33d034da76..c4e5fa491a 100644
--- a/src/library/scala/concurrent/util/Duration.scala
+++ b/src/library/scala/concurrent/util/Duration.scala
@@ -7,51 +7,7 @@ package scala.concurrent.util
import java.util.concurrent.TimeUnit
import TimeUnit._
import java.lang.{ Double ⇒ JDouble }
-
-object DurationImplicits {
- trait Classifier[C] {
- type R
- def convert(d: FiniteDuration): R
- }
-
- object span
- implicit object spanConvert extends Classifier[span.type] {
- type R = FiniteDuration
- def convert(d: FiniteDuration) = d
- }
-
- object fromNow
- implicit object fromNowConvert extends Classifier[fromNow.type] {
- type R = Deadline
- def convert(d: FiniteDuration) = Deadline.now + d
- }
-
- implicit def intToDurationInt(n: Int) = new DurationInt(n)
- implicit def longToDurationLong(n: Long) = new DurationLong(n)
- implicit def doubleToDurationDouble(d: Double) = new DurationDouble(d)
-
- implicit def pairIntToDuration(p: (Int, TimeUnit)) = Duration(p._1, p._2)
- implicit def pairLongToDuration(p: (Long, TimeUnit)) = Duration(p._1, p._2)
- implicit def durationToPair(d: Duration) = (d.length, d.unit)
-
- /*
- * Avoid reflection based invocation by using non-duck type
- */
- class IntMult(i: Int) {
- def *(d: Duration) = d * i
- }
- implicit def intMult(i: Int) = new IntMult(i)
-
- class LongMult(l: Long) {
- def *(d: Duration) = d * l
- }
- implicit def longMult(l: Long) = new LongMult(l)
-
- class DoubleMult(f: Double) {
- def *(d: Duration) = d * f
- }
- implicit def doubleMult(f: Double) = new DoubleMult(f)
-}
+import language.implicitConversions
case class Deadline private (time: Duration) {
def +(other: Duration): Deadline = copy(time = time + other)
@@ -71,10 +27,7 @@ object Duration {
def apply(length: Long, unit: TimeUnit): FiniteDuration = new FiniteDuration(length, unit)
def apply(length: Double, unit: TimeUnit): FiniteDuration = fromNanos(unit.toNanos(1) * length)
- def apply(length: Long, unit: String): FiniteDuration = {
- val (mult, timeUnit) = Duration.timeUnit(unit)
- new FiniteDuration(length * mult, timeUnit)
- }
+ def apply(length: Long, unit: String): FiniteDuration = new FiniteDuration(length, Duration.timeUnit(unit))
/**
* Construct a Duration by parsing a String. In case of a format error, a
@@ -117,11 +70,11 @@ object Duration {
def unapply(s: String): Option[Duration] = s match {
case RE(length, d, h, m, s, ms, mus, ns) ⇒
if (d ne null)
- Some(Duration(JDouble.parseDouble(length) * 86400, SECONDS))
+ Some(Duration(JDouble.parseDouble(length), DAYS))
else if (h ne null)
- Some(Duration(JDouble.parseDouble(length) * 3600, SECONDS))
+ Some(Duration(JDouble.parseDouble(length), HOURS))
else if (m ne null)
- Some(Duration(JDouble.parseDouble(length) * 60, SECONDS))
+ Some(Duration(JDouble.parseDouble(length), MINUTES))
else if (s ne null)
Some(Duration(JDouble.parseDouble(length), SECONDS))
else if (ms ne null)
@@ -142,11 +95,11 @@ object Duration {
def fromNanos(nanos: Long): FiniteDuration = {
if (nanos % 86400000000000L == 0) {
- Duration(nanos / 1000000000L, SECONDS)
- } else if (nanos % 1000000000L == 0) {
- Duration(nanos / 1000000000L, SECONDS)
- } else if (nanos % 1000000000L == 0) {
- Duration(nanos / 1000000000L, SECONDS)
+ Duration(nanos / 86400000000000L, DAYS)
+ } else if (nanos % 3600000000000L == 0) {
+ Duration(nanos / 3600000000000L, HOURS)
+ } else if (nanos % 60000000000L == 0) {
+ Duration(nanos / 60000000000L, MINUTES)
} else if (nanos % 1000000000L == 0) {
Duration(nanos / 1000000000L, SECONDS)
} else if (nanos % 1000000L == 0) {
@@ -161,14 +114,14 @@ object Duration {
/**
* Parse TimeUnit from string representation.
*/
- protected[util] def timeUnit(unit: String): (Long, TimeUnit) = unit.toLowerCase match {
- case "d" | "day" | "days" ⇒ (86400, SECONDS)
- case "h" | "hour" | "hours" ⇒ (3600, SECONDS)
- case "min" | "minute" | "minutes" ⇒ (60, SECONDS)
- case "s" | "sec" | "second" | "seconds" ⇒ (1, SECONDS)
- case "ms" | "milli" | "millis" | "millisecond" | "milliseconds" ⇒ (1, MILLISECONDS)
- case "µs" | "micro" | "micros" | "microsecond" | "microseconds" ⇒ (1, MICROSECONDS)
- case "ns" | "nano" | "nanos" | "nanosecond" | "nanoseconds" ⇒ (1, NANOSECONDS)
+ protected[util] def timeUnit(unit: String): TimeUnit = unit.toLowerCase match {
+ case "d" | "day" | "days" ⇒ DAYS
+ case "h" | "hour" | "hours" ⇒ HOURS
+ case "min" | "minute" | "minutes" ⇒ MINUTES
+ case "s" | "sec" | "second" | "seconds" ⇒ SECONDS
+ case "ms" | "milli" | "millis" | "millisecond" | "milliseconds" ⇒ MILLISECONDS
+ case "µs" | "micro" | "micros" | "microsecond" | "microseconds" ⇒ MICROSECONDS
+ case "ns" | "nano" | "nanos" | "nanosecond" | "nanoseconds" ⇒ NANOSECONDS
}
val Zero: FiniteDuration = new FiniteDuration(0, NANOSECONDS)
@@ -328,13 +281,9 @@ object FiniteDuration {
def compare(a: FiniteDuration, b: FiniteDuration) = a compare b
}
- def apply(length: Long, unit: TimeUnit) =
- new FiniteDuration(length, unit)
+ def apply(length: Long, unit: TimeUnit) = new FiniteDuration(length, unit)
- def apply(length: Long, unit: String) = {
- val (mult, timeUnit) = Duration.timeUnit(unit)
- new FiniteDuration(length * mult, timeUnit)
- }
+ def apply(length: Long, unit: String) = new FiniteDuration(length, Duration.timeUnit(unit))
}
@@ -348,9 +297,15 @@ class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration {
def toMinutes = unit.toMinutes(length)
def toHours = unit.toHours(length)
def toDays = unit.toDays(length)
- def toUnit(u: TimeUnit) = long2double(toNanos) / NANOSECONDS.convert(1, u)
+ def toUnit(u: TimeUnit) = toNanos.toDouble / NANOSECONDS.convert(1, u)
override def toString = this match {
+ case Duration(1, DAYS) ⇒ "1 day"
+ case Duration(x, DAYS) ⇒ x + " days"
+ case Duration(1, HOURS) ⇒ "1 hour"
+ case Duration(x, HOURS) ⇒ x + " hours"
+ case Duration(1, MINUTES) ⇒ "1 minute"
+ case Duration(x, MINUTES) ⇒ x + " minutes"
case Duration(1, SECONDS) ⇒ "1 second"
case Duration(x, SECONDS) ⇒ x + " seconds"
case Duration(1, MILLISECONDS) ⇒ "1 millisecond"
@@ -386,11 +341,11 @@ class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration {
}
}
- def *(factor: Double) = fromNanos(long2double(toNanos) * factor)
+ def *(factor: Double) = fromNanos(toNanos.toDouble * factor)
- def /(factor: Double) = fromNanos(long2double(toNanos) / factor)
+ def /(factor: Double) = fromNanos(toNanos.toDouble / factor)
- def /(other: Duration) = if (other.finite_?) long2double(toNanos) / other.toNanos else 0
+ def /(other: Duration) = if (other.finite_?) toNanos.toDouble / other.toNanos else 0
def unary_- = Duration(-length, unit)
@@ -404,7 +359,7 @@ class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration {
}
class DurationInt(n: Int) {
- import DurationImplicits.Classifier
+ import duration.Classifier
def nanoseconds = Duration(n, NANOSECONDS)
def nanos = Duration(n, NANOSECONDS)
@@ -424,14 +379,14 @@ class DurationInt(n: Int) {
def seconds = Duration(n, SECONDS)
def second = Duration(n, SECONDS)
- def minutes = Duration(n * 60, SECONDS)
- def minute = Duration(n * 60, SECONDS)
+ def minutes = Duration(n, MINUTES)
+ def minute = Duration(n, MINUTES)
- def hours = Duration(n * 3600, SECONDS)
- def hour = Duration(n * 3600, SECONDS)
+ def hours = Duration(n, HOURS)
+ def hour = Duration(n, HOURS)
- def days = Duration(n * 86400, SECONDS)
- def day = Duration(n * 86400, SECONDS)
+ def days = Duration(n, DAYS)
+ def day = Duration(n, DAYS)
def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
@@ -451,18 +406,18 @@ class DurationInt(n: Int) {
def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS))
def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS))
- def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS))
- def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS))
+ def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES))
+ def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES))
- def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS))
- def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS))
+ def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS))
+ def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS))
- def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS))
- def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS))
+ def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS))
+ def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS))
}
class DurationLong(n: Long) {
- import DurationImplicits.Classifier
+ import duration.Classifier
def nanoseconds = Duration(n, NANOSECONDS)
def nanos = Duration(n, NANOSECONDS)
@@ -482,14 +437,14 @@ class DurationLong(n: Long) {
def seconds = Duration(n, SECONDS)
def second = Duration(n, SECONDS)
- def minutes = Duration(n * 60, SECONDS)
- def minute = Duration(n * 60, SECONDS)
+ def minutes = Duration(n, MINUTES)
+ def minute = Duration(n, MINUTES)
- def hours = Duration(n * 3600, SECONDS)
- def hour = Duration(n * 3600, SECONDS)
+ def hours = Duration(n, HOURS)
+ def hour = Duration(n, HOURS)
- def days = Duration(n * 86400, SECONDS)
- def day = Duration(n * 86400, SECONDS)
+ def days = Duration(n, DAYS)
+ def day = Duration(n, DAYS)
def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS))
@@ -509,18 +464,18 @@ class DurationLong(n: Long) {
def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS))
def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS))
- def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS))
- def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS))
+ def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES))
+ def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES))
- def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS))
- def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS))
+ def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS))
+ def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS))
- def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS))
- def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS))
+ def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS))
+ def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS))
}
class DurationDouble(d: Double) {
- import DurationImplicits.Classifier
+ import duration.Classifier
def nanoseconds = Duration(d, NANOSECONDS)
def nanos = Duration(d, NANOSECONDS)
@@ -540,14 +495,14 @@ class DurationDouble(d: Double) {
def seconds = Duration(d, SECONDS)
def second = Duration(d, SECONDS)
- def minutes = Duration(d * 60, SECONDS)
- def minute = Duration(d * 60, SECONDS)
+ def minutes = Duration(d, MINUTES)
+ def minute = Duration(d, MINUTES)
- def hours = Duration(d * 3600, SECONDS)
- def hour = Duration(d * 3600, SECONDS)
+ def hours = Duration(d, HOURS)
+ def hour = Duration(d, HOURS)
- def days = Duration(d * 86400, SECONDS)
- def day = Duration(d * 86400, SECONDS)
+ def days = Duration(d, DAYS)
+ def day = Duration(d, DAYS)
def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS))
def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS))
@@ -567,12 +522,12 @@ class DurationDouble(d: Double) {
def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, SECONDS))
def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, SECONDS))
- def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 60, SECONDS))
- def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 60, SECONDS))
+ def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MINUTES))
+ def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MINUTES))
- def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 3600, SECONDS))
- def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 3600, SECONDS))
+ def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, HOURS))
+ def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, HOURS))
- def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 86400, SECONDS))
- def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 86400, SECONDS))
+ def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, DAYS))
+ def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, DAYS))
}
diff --git a/src/library/scala/concurrent/util/duration/Classifier.scala b/src/library/scala/concurrent/util/duration/Classifier.scala
new file mode 100644
index 0000000000..10faf0a5ce
--- /dev/null
+++ b/src/library/scala/concurrent/util/duration/Classifier.scala
@@ -0,0 +1,9 @@
+package scala.concurrent.util.duration
+
+import scala.concurrent.util.{ FiniteDuration }
+
+trait Classifier[C] {
+ type R
+ def convert(d: FiniteDuration): R
+}
+
diff --git a/src/library/scala/concurrent/util/duration/IntMult.scala b/src/library/scala/concurrent/util/duration/IntMult.scala
new file mode 100644
index 0000000000..94c58fb8c2
--- /dev/null
+++ b/src/library/scala/concurrent/util/duration/IntMult.scala
@@ -0,0 +1,18 @@
+package scala.concurrent.util.duration
+
+import scala.concurrent.util.{ Duration }
+
+/*
+ * Avoid reflection based invocation by using non-duck type
+ */
+protected[duration] class IntMult(i: Int) {
+ def *(d: Duration) = d * i
+}
+
+protected[duration] class LongMult(i: Long) {
+ def *(d: Duration) = d * i
+}
+
+protected[duration] class DoubleMult(f: Double) {
+ def *(d: Duration) = d * f
+}
diff --git a/src/library/scala/concurrent/util/duration/package.scala b/src/library/scala/concurrent/util/duration/package.scala
new file mode 100644
index 0000000000..e3cf229c61
--- /dev/null
+++ b/src/library/scala/concurrent/util/duration/package.scala
@@ -0,0 +1,31 @@
+package scala.concurrent.util
+
+import java.util.concurrent.TimeUnit
+import language.implicitConversions
+
+package object duration {
+
+ object span
+ implicit object spanConvert extends Classifier[span.type] {
+ type R = FiniteDuration
+ def convert(d: FiniteDuration) = d
+ }
+
+ object fromNow
+ implicit object fromNowConvert extends Classifier[fromNow.type] {
+ type R = Deadline
+ def convert(d: FiniteDuration) = Deadline.now + d
+ }
+
+ implicit def intToDurationInt(n: Int) = new DurationInt(n)
+ implicit def longToDurationLong(n: Long) = new DurationLong(n)
+ implicit def doubleToDurationDouble(d: Double) = new DurationDouble(d)
+
+ implicit def pairIntToDuration(p: (Int, TimeUnit)) = Duration(p._1, p._2)
+ implicit def pairLongToDuration(p: (Long, TimeUnit)) = Duration(p._1, p._2)
+ implicit def durationToPair(d: Duration) = (d.length, d.unit)
+
+ implicit def intMult(i: Int) = new IntMult(i)
+ implicit def longMult(l: Long) = new LongMult(l)
+ implicit def doubleMult(f: Double) = new DoubleMult(f)
+}
diff --git a/src/library/scala/io/BytePickle.scala b/src/library/scala/io/BytePickle.scala
index bec0cfb53f..3bb5ea9c2b 100644
--- a/src/library/scala/io/BytePickle.scala
+++ b/src/library/scala/io/BytePickle.scala
@@ -269,7 +269,7 @@ object BytePickle {
}
def string: SPU[String] = share(wrap(
- (a: Array[Byte]) => Codec fromUTF8 a mkString,
+ (a: Array[Byte]) => (Codec fromUTF8 a).mkString,
(s: String) => Codec toUTF8 s,
bytearray
))
diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala
index d9cef0edb1..84cac88dcc 100644
--- a/src/library/scala/io/Codec.scala
+++ b/src/library/scala/io/Codec.scala
@@ -11,6 +11,7 @@ package scala.io
import java.nio.charset.{ Charset, CharsetDecoder, CharsetEncoder, CharacterCodingException, CodingErrorAction => Action }
import annotation.migration
+import language.implicitConversions
// Some notes about encodings for use in refining this implementation.
//
diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala
index 3cee0ace79..5e09e13680 100644
--- a/src/library/scala/io/Source.scala
+++ b/src/library/scala/io/Source.scala
@@ -188,7 +188,7 @@ abstract class Source extends Iterator[Char] {
var nerrors = 0
var nwarnings = 0
- private def lineNum(line: Int): String = getLines() drop (line - 1) take 1 mkString
+ private def lineNum(line: Int): String = (getLines() drop (line - 1) take 1).mkString
class LineIterator extends AbstractIterator[String] with Iterator[String] {
private[this] val sb = new StringBuilder
diff --git a/src/library/scala/language.scala b/src/library/scala/language.scala
new file mode 100644
index 0000000000..df2eb0b910
--- /dev/null
+++ b/src/library/scala/language.scala
@@ -0,0 +1,124 @@
+package scala
+
+object language {
+
+ import languageFeature._
+
+ /** Where enabled, direct or indirect subclasses of trait scala.Dynamic can
+ * be defined. Unless dynamics is enabled, a definition of a class, trait,
+ * or object that has Dynamic as a base trait is rejected. Dynamic member
+ * selection of existing subclasses of trait Dynamic are unaffected;
+ * they can be used anywhere.
+ *
+ * _Why introduce the feature?_ To enable flexible DSLs and convenient interfacing
+ * with dynamic languages.
+ *
+ * _Why control it?_ Dynamic member selection can undermine static checkability
+ * of programs. Furthermore, dynamic member selection often relies on reflection,
+ * which is not available on all platforms.
+ */
+ implicit lazy val dynamics: dynamics = ???
+
+ /** Only where enabled, postfix operator notation `(expr op)` will be allowed.
+ *
+ * _Why keep the feature?_ Several DSLs written in Scala need the notation.
+ *
+ * _Why control it?_ Postfix operators interact poorly with semicolon inference.
+ * Most programmers avoid them for this reason.
+ */
+ implicit lazy val postfixOps: postfixOps = ???
+
+ /** Only where enabled, accesses to members of structural types that need
+ * reflection are supported. Reminder: A structural type is a type of the form
+ * `Parents { Decls }` where `Decls` contains declarations of new members that do
+ * not override any member in `Parents`. To access one of these members, a
+ * reflective call is needed.
+ *
+ * _Why keep the feature?_ Structural types provide great flexibility because
+ * they avoid the need to define inheritance hierarchies a priori. Besides,
+ * their definition falls out quite naturally from Scala’s concept of type refinement.
+ *
+ * _Why control it?+ Reflection is not available on all platforms. Popular tools
+ * such as ProGuard have problems dealing with it. Even where reflection is available,
+ * reflective dispatch can lead to surprising performance degradations.
+ */
+ implicit lazy val reflectiveCalls: reflectiveCalls = ???
+
+ /** Only where enabled, definitions of implicit conversions are allowed. An
+ * implicit conversion is an implicit value of unary function type `A => B`,
+ * or an implicit method that has in its first parameter section a single,
+ * non-implicit parameter. Examples:
+ *
+ * implicit def stringToInt(s: String): Int = s.length
+ * implicit val conv = (s: String) => s.length
+ * implicit def listToX(xs: List[T])(implicit f: T => X): X = …
+ *
+ * implicit values of other types are not affected, and neither are implicit
+ * classes.
+ *
+ * _Why keep the feature?_ Implicit conversions are central to many aspects
+ * of Scala’s core libraries.
+ *
+ * _Why control it?_ Implicit conversions are known to cause many pitfalls
+ * if over-used. And there is a tendency to over-use them because they look
+ * very powerful and their effects seem to be easy to understand. Also, in
+ * most situations using implicit parameters leads to a better design than
+ * implicit conversions.
+ */
+ implicit lazy val implicitConversions: implicitConversions = ???
+
+ /** Only where this flag is enabled, higher-kinded types can be written.
+ *
+ * _Why keep the feature?_ Higher-kinded types enable the definition of very general
+ * abstractions such as functor, monad, or arrow. A significant set of advanced
+ * libraries relies on them. Higher-kinded types are also at the core of the
+ * scala-virtualized effort to produce high-performance parallel DSLs through staging.
+ *
+ * _Why control it?_ Higher kinded types in Scala lead to a Turing-complete
+ * type system, where compiler termination is no longer guaranteed. They tend
+ * to be useful mostly for type-level computation and for highly generic design
+ * patterns. The level of abstraction implied by these design patterns is often
+ * a barrier to understanding for newcomers to a Scala codebase. Some syntactic
+ * aspects of higher-kinded types are hard to understand for the uninitiated and
+ * type inference is less effective for them than for normal types. Because we are
+ * not completely happy with them yet, it is possible that some aspects of
+ * higher-kinded types will change in future versions of Scala. So an explicit
+ * enabling also serves as a warning that code involving higher-kinded types
+ * might have to be slightly revised in the future.
+ */
+ implicit lazy val higherKinds: higherKinds = ???
+
+ /** Only where enabled, existential types that cannot be expressed as wildcard
+ * types can be written and are allowed in inferred types of values or return
+ * types of methods. Existential types with wildcard type syntax such as `List[_]`,
+ * or `Map[String, _]` are not affected.
+ *
+ * _Why keep the feature?_ Existential types are needed to make sense of Java’s wildcard
+ * types and raw types and the erased types of run-time values.
+ *
+ * Why control it? Having complex existential types in a code base usually makes
+ * application code very brittle, with a tendency to produce type errors with
+ * obscure error messages. Therefore, going overboard with existential types
+ * is generally perceived not to be a good idea. Also, complicated existential types
+ * might be no longer supported in a future simplification of the language.
+ */
+ implicit lazy val existentials: existentials = ???
+
+ object experimental {
+
+ import languageFeature.experimental._
+
+ /** Where enabled, macro definitions are allowed. Macro implementations and
+ * macro applications are unaffected; they can be used anywhere.
+ *
+ * _Why introduce the feature?_ Macros promise to make the language more regular,
+ * replacing ad-hoc language constructs with a general powerful abstraction
+ * capability that can express them. Macros are also a more disciplined and
+ * powerful replacement for compiler plugins.
+ *
+ * _Why control it?_ For their very power, macros can lead to code that is hard
+ * to debug and understand.
+ */
+ implicit lazy val macros: macros = ???
+ }
+}
diff --git a/src/library/scala/languageFeature.scala b/src/library/scala/languageFeature.scala
new file mode 100644
index 0000000000..c990f714c1
--- /dev/null
+++ b/src/library/scala/languageFeature.scala
@@ -0,0 +1,30 @@
+package scala
+
+import annotation.meta
+
+object languageFeature {
+
+ @meta.languageFeature("extension of type scala.Dynamic", true)
+ sealed trait dynamics
+
+ @meta.languageFeature("postfix operator #", false)
+ sealed trait postfixOps
+
+ @meta.languageFeature("reflective access of structural type member #", false)
+ sealed trait reflectiveCalls
+
+ @meta.languageFeature("implicit conversion #", false)
+ sealed trait implicitConversions
+
+ @meta.languageFeature("higher-kinded type", false)
+ sealed trait higherKinds
+
+ @meta.languageFeature("#, which cannot be expressed by wildcards, ", false)
+ sealed trait existentials
+
+ object experimental {
+ @meta.languageFeature("macro definition", true)
+ sealed trait macros
+ }
+}
+
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index c1f45eccfb..74daa510ca 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -12,6 +12,7 @@ package scala.math
import java.{ lang => jl }
import java.math.{ MathContext, BigDecimal => BigDec }
import scala.collection.immutable.NumericRange
+import language.implicitConversions
/**
@@ -183,7 +184,8 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
override def equals (that: Any): Boolean = that match {
case that: BigDecimal => this equals that
case that: BigInt => this.toBigIntExact exists (that equals _)
- case _: Float | _: Double => unifiedPrimitiveEquals(that)
+ case that: Double => isValidDouble && toDouble == that
+ case that: Float => isValidFloat && toFloat == that
case _ => isValidLong && unifiedPrimitiveEquals(that)
}
override def isValidByte = noArithmeticException(toByteExact)
@@ -191,6 +193,18 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
override def isValidChar = isValidInt && toIntExact >= Char.MinValue && toIntExact <= Char.MaxValue
override def isValidInt = noArithmeticException(toIntExact)
def isValidLong = noArithmeticException(toLongExact)
+ /** Returns `true` iff this can be represented exactly by [[scala.Float]]; otherwise returns `false`.
+ */
+ def isValidFloat = {
+ val f = toFloat
+ !f.isInfinity && bigDecimal.compareTo(new java.math.BigDecimal(f)) == 0
+ }
+ /** Returns `true` iff this can be represented exactly by [[scala.Double]]; otherwise returns `false`.
+ */
+ def isValidDouble = {
+ val d = toDouble
+ !d.isInfinity && bigDecimal.compareTo(new java.math.BigDecimal(d)) == 0
+ }
private def noArithmeticException(body: => Unit): Boolean = {
try { body ; true }
@@ -279,7 +293,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
/** Returns the absolute value of this BigDecimal
*/
- def abs: BigDecimal = this.bigDecimal abs
+ def abs: BigDecimal = this.bigDecimal.abs
/** Returns the sign of this BigDecimal, i.e.
* -1 if it is less than 0,
diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala
index 8a53afaa62..ff52ca9bec 100644
--- a/src/library/scala/math/BigInt.scala
+++ b/src/library/scala/math/BigInt.scala
@@ -9,6 +9,7 @@
package scala.math
import java.math.BigInteger
+import language.implicitConversions
/**
* @author Martin Odersky
@@ -20,6 +21,7 @@ object BigInt {
private val minCached = -1024
private val maxCached = 1024
private val cache = new Array[BigInt](maxCached - minCached + 1)
+ private val minusOne = BigInteger.valueOf(-1)
@deprecated("Use Long.MinValue", "2.9.0")
val MinLong = BigInt(Long.MinValue)
@@ -122,6 +124,8 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def equals(that: Any): Boolean = that match {
case that: BigInt => this equals that
case that: BigDecimal => that.toBigIntExact exists (this equals _)
+ case that: Double => isValidDouble && toDouble == that
+ case that: Float => isValidFloat && toFloat == that
case x => isValidLong && unifiedPrimitiveEquals(x)
}
override def isValidByte = this >= Byte.MinValue && this <= Byte.MaxValue
@@ -129,6 +133,41 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def isValidChar = this >= Char.MinValue && this <= Char.MaxValue
override def isValidInt = this >= Int.MinValue && this <= Int.MaxValue
def isValidLong = this >= Long.MinValue && this <= Long.MaxValue
+ /** Returns `true` iff this can be represented exactly by [[scala.Float]]; otherwise returns `false`.
+ */
+ def isValidFloat = {
+ val bitLen = bitLength
+ (bitLen <= 24 ||
+ {
+ val lowest = lowestSetBit
+ bitLen <= java.lang.Float.MAX_EXPONENT + 1 && // exclude this < -2^128 && this >= 2^128
+ lowest >= bitLen - 24 &&
+ lowest < java.lang.Float.MAX_EXPONENT + 1 // exclude this == -2^128
+ }
+ ) && !bitLengthOverflow
+ }
+ /** Returns `true` iff this can be represented exactly by [[scala.Double]]; otherwise returns `false`.
+ */
+ def isValidDouble = {
+ val bitLen = bitLength
+ (bitLen <= 53 ||
+ {
+ val lowest = lowestSetBit
+ bitLen <= java.lang.Double.MAX_EXPONENT + 1 && // exclude this < -2^1024 && this >= 2^1024
+ lowest >= bitLen - 53 &&
+ lowest < java.lang.Double.MAX_EXPONENT + 1 // exclude this == -2^1024
+ }
+ ) && !bitLengthOverflow
+ }
+ /** Some implementations of java.math.BigInteger allow huge values with bit length greater than Int.MaxValue .
+ * The BigInteger.bitLength method returns truncated bit length in this case .
+ * This method tests if result of bitLength is valid.
+ * This method will become unnecessary if BigInt constructors reject huge BigIntegers.
+ */
+ private def bitLengthOverflow = {
+ val shifted = bigInteger.shiftRight(Int.MaxValue)
+ (shifted.signum != 0) && !(shifted equals BigInt.minusOne)
+ }
protected[math] def isWhole = true
def underlying = bigInteger
diff --git a/src/library/scala/math/Fractional.scala b/src/library/scala/math/Fractional.scala
index de09b184e0..0686569c16 100644
--- a/src/library/scala/math/Fractional.scala
+++ b/src/library/scala/math/Fractional.scala
@@ -8,6 +8,8 @@
package scala.math
+import language.implicitConversions
+
/**
* @since 2.8
*/
diff --git a/src/library/scala/math/Integral.scala b/src/library/scala/math/Integral.scala
index bb364a79b4..4b4de28228 100644
--- a/src/library/scala/math/Integral.scala
+++ b/src/library/scala/math/Integral.scala
@@ -10,6 +10,8 @@
package scala.math
+import language.implicitConversions
+
/**
* @since 2.8
*/
diff --git a/src/library/scala/math/Numeric.scala b/src/library/scala/math/Numeric.scala
index ff88e0ff4d..ee62706e49 100644
--- a/src/library/scala/math/Numeric.scala
+++ b/src/library/scala/math/Numeric.scala
@@ -8,6 +8,8 @@
package scala.math
+import language.implicitConversions
+
/**
* @since 2.8
*/
@@ -34,8 +36,8 @@ object Numeric {
def fromInt(x: Int): BigInt = BigInt(x)
def toInt(x: BigInt): Int = x.intValue
def toLong(x: BigInt): Long = x.longValue
- def toFloat(x: BigInt): Float = x.longValue.toFloat
- def toDouble(x: BigInt): Double = x.longValue.toDouble
+ def toFloat(x: BigInt): Float = x.floatValue
+ def toDouble(x: BigInt): Double = x.doubleValue
}
implicit object BigIntIsIntegral extends BigIntIsIntegral with Ordering.BigIntOrdering
diff --git a/src/library/scala/math/Ordered.scala b/src/library/scala/math/Ordered.scala
index b76030718f..80addea7f3 100644
--- a/src/library/scala/math/Ordered.scala
+++ b/src/library/scala/math/Ordered.scala
@@ -8,6 +8,8 @@
package scala.math
+import language.implicitConversions
+
/** A trait for data that have a single, natural ordering. See
* [[scala.math.Ordering]] before using this trait for
* more information about whether to use [[scala.math.Ordering]] instead.
diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala
index 8fc74a9d5d..ab685815a1 100644
--- a/src/library/scala/math/Ordering.scala
+++ b/src/library/scala/math/Ordering.scala
@@ -9,6 +9,7 @@
package scala.math
import java.util.Comparator
+import language.{implicitConversions, higherKinds}
/** Ordering is a trait whose instances each represent a strategy for sorting
* instances of a type.
diff --git a/src/library/scala/parallel/Future.scala b/src/library/scala/parallel/Future.scala
index af06852b32..f61d376093 100644
--- a/src/library/scala/parallel/Future.scala
+++ b/src/library/scala/parallel/Future.scala
@@ -8,11 +8,14 @@
package scala.parallel
+
+
/** A future is a function without parameters that will block the caller if
* the parallel computation associated with the function is not completed.
*
* @since 2.9
*/
+@deprecated("Use `scala.concurrent.Future` instead.", "2.10.0")
trait Future[@specialized +R] extends (() => R) {
/** Returns a result once the parallel computation completes. If the
* computation produced an exception, an exception is forwarded.
diff --git a/src/library/scala/reflect/ArrayTag.scala b/src/library/scala/reflect/ArrayTag.scala
new file mode 100644
index 0000000000..ba0c075723
--- /dev/null
+++ b/src/library/scala/reflect/ArrayTag.scala
@@ -0,0 +1,25 @@
+package scala.reflect
+
+/** An `ArrayTag[T]` is a descriptor that is requested by the compiler every time
+ * when an array is instantiated, but the element type is unknown at compile time.
+ *
+ * Implicit in the contract of `ArrayTag[T]` is the fact that `T`
+ * cannot contain unresolved references to type parameters or abstract types.
+ *
+ * Scala library provides a standard implementation of this trait,
+ * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T
+ * and uses Java reflection to instantiate arrays.
+ *
+ * However other platforms (e.g. a Scala -> JS crosscompiler) may reimplement this trait as they see fit
+ * and then expose the implementation via an implicit macro.
+ *
+ * @see [[scala.reflect.api.TypeTags]]
+ */
+@annotation.implicitNotFound(msg = "No ArrayTag available for ${T}")
+trait ArrayTag[T] {
+ /** Produces an `ArrayTag` that knows how to build `Array[Array[T]]` */
+ def wrap: ArrayTag[Array[T]]
+
+ /** Produces a new array with element type `T` and length `len` */
+ def newArray(len: Int): Array[T]
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala
index 37be067614..43e043fd40 100644
--- a/src/library/scala/reflect/ClassManifest.scala
+++ b/src/library/scala/reflect/ClassManifest.scala
@@ -6,23 +6,6 @@
** |/ **
\* */
-/* [Martin]
- * Todo: ClassManifests currently contain all available type arguments.
- * That's a waste of cycles if all that's needed is the class.
- * We should have instead consider a structure like this:
- *
- * OptManifest
- * / \
- * / \
- * PartialManifest ClassManifest
- * \ /
- * \ /
- * Manifest
- *
- * where PartialManifest means: generate as much as you can, use NoManifest
- * where nothing is known, and
- * ClassManifest means: generate exactly the top-level class, and nothing else.
- */
package scala.reflect
import scala.collection.mutable.{ WrappedArray, ArrayBuilder }
@@ -39,17 +22,12 @@ import java.lang.{ Class => jClass }
* be wrong when variance is involved or when a subtype has a different
* number of type arguments than a supertype.
*/
-trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable {
+@deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0")
+trait ClassManifest[T] extends OptManifest[T] with ClassTag[T] with Equals with Serializable {
/** A class representing the type `U` to which `T` would be erased. Note
* that there is no subtyping relationship between `T` and `U`. */
def erasure: jClass[_]
- /** The Scala type described by this manifest.
- */
- lazy val tpe: mirror.Type = mirror.classToType(erasure)
-
- def symbol: mirror.Symbol = mirror.classToSymbol(erasure)
-
private def subtype(sub: jClass[_], sup: jClass[_]): Boolean = {
def loop(left: Set[jClass[_]], seen: Set[jClass[_]]): Boolean = {
left.nonEmpty && {
@@ -110,7 +88,7 @@ trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable {
def >:>(that: ClassManifest[_]): Boolean =
that <:< this
- def canEqual(other: Any) = other match {
+ override def canEqual(other: Any) = other match {
case _: ClassManifest[_] => true
case _ => false
}
@@ -131,7 +109,7 @@ trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable {
def arrayManifest: ClassManifest[Array[T]] =
ClassManifest.classType[Array[T]](arrayClass[T](erasure), this)
- def newArray(len: Int): Array[T] =
+ override def newArray(len: Int): Array[T] =
java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]]
def newArray2(len: Int): Array[Array[T]] =
@@ -169,6 +147,7 @@ trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable {
/** The object `ClassManifest` defines factory methods for manifests.
* It is intended for use by the compiler and should not be used in client code.
*/
+@deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0")
object ClassManifest {
val Byte = Manifest.Byte
val Short = Manifest.Short
@@ -207,18 +186,18 @@ object ClassManifest {
* pass varargs as arrays into this, we get an infinitely recursive call
* to boxArray. (Besides, having a separate case is more efficient)
*/
- def classType[T](clazz: jClass[_]): ClassManifest[T] =
+ def classType[T <: AnyRef](clazz: jClass[_]): ClassManifest[T] =
new ClassTypeManifest[T](None, clazz, Nil)
/** ClassManifest for the class type `clazz[args]`, where `clazz` is
* a top-level or static class and `args` are its type arguments */
- def classType[T](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] =
+ def classType[T <: AnyRef](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] =
new ClassTypeManifest[T](None, clazz, arg1 :: args.toList)
/** ClassManifest for the class type `clazz[args]`, where `clazz` is
* a class with non-package prefix type `prefix` and type arguments `args`.
*/
- def classType[T](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] =
+ def classType[T <: AnyRef](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] =
new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match {
@@ -250,8 +229,8 @@ object ClassManifest {
}
/** Manifest for the class type `clazz[args]`, where `clazz` is
- * a top-level or static class: todo: we should try to merge this with Manifest's class */
-private class ClassTypeManifest[T](
+ * a top-level or static class */
+private class ClassTypeManifest[T <: AnyRef](
prefix: Option[OptManifest[_]],
val erasure: jClass[_],
override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T]
@@ -260,4 +239,4 @@ private class ClassTypeManifest[T](
(if (prefix.isEmpty) "" else prefix.get.toString+"#") +
(if (erasure.isArray) "Array" else erasure.getName) +
argString
-}
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
new file mode 100644
index 0000000000..e485691747
--- /dev/null
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -0,0 +1,96 @@
+package scala.reflect
+
+import java.lang.{ Class => jClass }
+import scala.reflect.{ mirror => rm }
+import language.{implicitConversions, existentials}
+import scala.runtime.ScalaRunTime.arrayClass
+
+/** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method.
+ *
+ * This is useful in itself, but also enables very important use case.
+ * Having this knowledge ClassTag can instantiate `Arrays`
+ * in those cases where the element type is unknown at compile time.
+ * Hence, ClassTag[T] conforms to the ArrayTag[T] trait.
+ *
+ * If an implicit value of type u.ClassTag[T] is required, the compiler will make one up on demand.
+ * The implicitly created value contains in its erasure field the Java class that is the result of erasing type T.
+ * In that value, any occurrences of type parameters or abstract types U which come themselves with a ClassTag
+ * or a reflect.mirror.ConcreteTypeTag are represented by the type referenced by that tag.
+ * If the type T contains unresolved references to type parameters or abstract types, a static error results.
+ *
+ * A ConcreteTypeTag member of the reflect.mirror object is convertible to a ClassTag via an implicit conversion
+ * (this is not possible to do in all reflection universes because an operation that converts a type to a Java class might not be available).
+ *
+ * @see [[scala.reflect.api.TypeTags]]
+ */
+@annotation.implicitNotFound(msg = "No ClassTag available for ${T}")
+trait ClassTag[T] extends ArrayTag[T] with ErasureTag[T] with Equals with Serializable {
+ // please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder`
+ // class tags, and all tags in general, should be as minimalistic as possible
+
+ /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */
+ def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(erasure))
+
+ /** Produces a new array with element type `T` and length `len` */
+ def newArray(len: Int): Array[T] =
+ erasure match {
+ case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]]
+ case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]]
+ case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]]
+ case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]]
+ case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]]
+ case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]]
+ case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]]
+ case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]]
+ case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]]
+ case _ => java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]]
+ }
+
+ /** case class accessories */
+ override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]]
+ override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.erasure == x.asInstanceOf[ClassTag[_]].erasure
+ override def hashCode = scala.runtime.ScalaRunTime.hash(erasure)
+ override def toString = "ClassTag[" + erasure + "]"
+}
+
+object ClassTag {
+ private val NothingTYPE = classOf[scala.runtime.Nothing$]
+ private val NullTYPE = classOf[scala.runtime.Null$]
+ private val ObjectTYPE = classOf[java.lang.Object]
+ private val StringTYPE = classOf[java.lang.String]
+
+ val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte]{ def erasure = java.lang.Byte.TYPE; private def readResolve() = ClassTag.Byte }
+ val Short : ClassTag[scala.Short] = new ClassTag[scala.Short]{ def erasure = java.lang.Short.TYPE; private def readResolve() = ClassTag.Short }
+ val Char : ClassTag[scala.Char] = new ClassTag[scala.Char]{ def erasure = java.lang.Character.TYPE; private def readResolve() = ClassTag.Char }
+ val Int : ClassTag[scala.Int] = new ClassTag[scala.Int]{ def erasure = java.lang.Integer.TYPE; private def readResolve() = ClassTag.Int }
+ val Long : ClassTag[scala.Long] = new ClassTag[scala.Long]{ def erasure = java.lang.Long.TYPE; private def readResolve() = ClassTag.Long }
+ val Float : ClassTag[scala.Float] = new ClassTag[scala.Float]{ def erasure = java.lang.Float.TYPE; private def readResolve() = ClassTag.Float }
+ val Double : ClassTag[scala.Double] = new ClassTag[scala.Double]{ def erasure = java.lang.Double.TYPE; private def readResolve() = ClassTag.Double }
+ val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean]{ def erasure = java.lang.Boolean.TYPE; private def readResolve() = ClassTag.Boolean }
+ val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit]{ def erasure = java.lang.Void.TYPE; private def readResolve() = ClassTag.Unit }
+ val Any : ClassTag[scala.Any] = new ClassTag[scala.Any]{ def erasure = ObjectTYPE; private def readResolve() = ClassTag.Any }
+ val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object]{ def erasure = ObjectTYPE; private def readResolve() = ClassTag.Object }
+ val AnyVal : ClassTag[scala.AnyVal] = new ClassTag[scala.AnyVal]{ def erasure = ObjectTYPE; private def readResolve() = ClassTag.AnyVal }
+ val AnyRef : ClassTag[scala.AnyRef] = new ClassTag[scala.AnyRef]{ def erasure = ObjectTYPE; private def readResolve() = ClassTag.AnyRef }
+ val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing]{ def erasure = NothingTYPE; private def readResolve() = ClassTag.Nothing }
+ val Null : ClassTag[scala.Null] = new ClassTag[scala.Null]{ def erasure = NullTYPE; private def readResolve() = ClassTag.Null }
+ val String : ClassTag[java.lang.String] = new ClassTag[java.lang.String]{ def erasure = StringTYPE; private def readResolve() = ClassTag.String }
+
+ def apply[T](erasure1: jClass[_]): ClassTag[T] =
+ erasure1 match {
+ case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]]
+ case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]]
+ case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]]
+ case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]]
+ case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]]
+ case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]]
+ case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]]
+ case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]]
+ case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]]
+ case ObjectTYPE => ClassTag.Object.asInstanceOf[ClassTag[T]]
+ case StringTYPE => ClassTag.String.asInstanceOf[ClassTag[T]]
+ case _ => new ClassTag[T]{ def erasure = erasure1 }
+ }
+
+ def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.erasure)
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala
new file mode 100644
index 0000000000..f5b757fdba
--- /dev/null
+++ b/src/library/scala/reflect/DummyMirror.scala
@@ -0,0 +1,784 @@
+package scala.reflect
+
+import scala.reflect.api.AbsTreeGen
+import scala.reflect.api.Attachment
+import scala.reflect.api.Modifier
+import scala.reflect.api.Universe
+
+// todo. make Dummy objects not equal to themselves
+class DummyMirror(cl: ClassLoader) extends api.Mirror {
+ // Members declared in scala.reflect.api.AnnotationInfos
+ implicit def classfileAnnotArgTag: scala.reflect.ClassTag[ClassfileAnnotArg] = notSupported()
+ type AnnotationInfo = DummyAnnotationInfo.type
+ object DummyAnnotationInfo
+ val AnnotationInfo: AnnotationInfoExtractor = DummyAnnotationInfoExtractor
+ object DummyAnnotationInfoExtractor extends AnnotationInfoExtractor {
+ def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo = DummyAnnotationInfo
+ def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] = notSupported()
+ }
+ type ClassfileAnnotArg = AnyRef
+ type LiteralAnnotArg = DummyLiteralAnnotArg.type
+ object DummyLiteralAnnotArg
+ val LiteralAnnotArg: LiteralAnnotArgExtractor = DummyLiteralAnnotArgExtractor
+ type ArrayAnnotArg = DummyArrayAnnotArg.type
+ object DummyArrayAnnotArg
+ val ArrayAnnotArg: ArrayAnnotArgExtractor = DummyArrayAnnotArgExtractor
+ type NestedAnnotArg = DummyNestedAnnotArg.type
+ object DummyNestedAnnotArg
+ val NestedAnnotArg: NestedAnnotArgExtractor = DummyNestedAnnotArgExtractor
+ object DummyLiteralAnnotArgExtractor extends LiteralAnnotArgExtractor {
+ def apply(const: Constant): LiteralAnnotArg = DummyLiteralAnnotArg
+ def unapply(arg: LiteralAnnotArg): Option[Constant] = notSupported()
+ }
+ object DummyArrayAnnotArgExtractor extends ArrayAnnotArgExtractor {
+ def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg = DummyArrayAnnotArg
+ def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]] = notSupported()
+ }
+ object DummyNestedAnnotArgExtractor extends NestedAnnotArgExtractor {
+ def apply(anninfo: AnnotationInfo): NestedAnnotArg = DummyNestedAnnotArg
+ def unapply(arg: NestedAnnotArg): Option[AnnotationInfo] = notSupported()
+ }
+
+ // Members declared in scala.reflect.api.Constants
+ type Constant = DummyConstant.type
+ object DummyConstant extends AbsConstant {
+ val value: Any = notSupported()
+ def tpe: Type = notSupported()
+ def isNaN: Boolean = notSupported()
+ def booleanValue: Boolean = notSupported()
+ def byteValue: Byte = notSupported()
+ def shortValue: Short = notSupported()
+ def charValue: Char = notSupported()
+ def intValue: Int = notSupported()
+ def longValue: Long = notSupported()
+ def floatValue: Float = notSupported()
+ def doubleValue: Double = notSupported()
+ def stringValue: String = notSupported()
+ def typeValue: Type = notSupported()
+ def symbolValue: Symbol = notSupported()
+ def convertTo(pt: Type): Constant = notSupported()
+ }
+ val Constant: ConstantExtractor = DummyConstantExtractor
+ object DummyConstantExtractor extends ConstantExtractor {
+ def apply(const: Any): Constant = DummyConstant
+ def unapply(arg: Constant): Option[Any] = notSupported()
+ }
+
+ // Members declared in scala.reflect.api.FreeVars
+ type FreeTerm = DummyFreeTerm.type
+ val DummyFreeTerm = DummySymbol
+ val FreeTerm: FreeTermExtractor = DummyFreeTermExtractor
+ object DummyFreeTermExtractor extends FreeTermExtractor {
+ def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] = notSupported()
+ }
+ type FreeType = DummyFreeType.type
+ val DummyFreeType = DummySymbol
+ val FreeType: FreeTypeExtractor = DummyFreeTypeExtractor
+ object DummyFreeTypeExtractor extends FreeTypeExtractor {
+ def unapply(freeType: FreeType): Option[(TypeName, Type, String)] = notSupported()
+ }
+ def freeTerms(tree: Tree): List[FreeTerm] = notSupported()
+ def freeTypes(tree: Tree): List[FreeType] = notSupported()
+ def substituteFreeTypes(tpe: Type,subs: Map[FreeType,Type]): Type = notSupported()
+ def substituteFreeTypes(tree: Tree,subs: Map[FreeType,Type]): Tree = notSupported()
+
+ // Members declared in scala.reflect.api.Importers
+ def mkImporter(from0: scala.reflect.api.Universe): Importer{val from: from0.type} = notSupported()
+
+ // Members declared in scala.reflect.api.Mirror
+ def classLoader: ClassLoader = cl
+ def classLoader_=(x$1: ClassLoader): Unit = notSupported()
+ def classToSymbol(clazz: Class[_]): Symbol = notSupported()
+ def classToType(clazz: Class[_]): Type = notSupported()
+ def companionInstance(clazz: Symbol): AnyRef = notSupported()
+ def getValueOfField(receiver: AnyRef,field: Symbol): Any = notSupported()
+ def invoke(receiver: AnyRef,meth: Symbol)(args: Any*): Any = notSupported()
+ def setValueOfField(receiver: AnyRef,field: Symbol,value: Any): Unit = notSupported()
+ def symbolForName(name: String): Symbol = notSupported()
+ def symbolOfInstance(instance: Any): Symbol = notSupported()
+ def symbolToClass(sym: Symbol): Class[_] = notSupported()
+ def typeOfInstance(instance: Any): Type = notSupported()
+ def typeToClass(tpe: Type): Class[_] = notSupported()
+
+ // Members declared in scala.reflect.api.Names
+ type Name = DummyName.type
+ type TypeName = DummyName.type
+ type TermName = DummyName.type
+ object DummyName extends AbsName {
+ def isTermName: Boolean = notSupported()
+ def isTypeName: Boolean = notSupported()
+ def toTermName: TermName = notSupported()
+ def toTypeName: TypeName = notSupported()
+ def decoded: String = notSupported()
+ def encoded: String = notSupported()
+ def decodedName: Name = notSupported()
+ def encodedName: Name = notSupported()
+ }
+ def newTermName(s: String): TermName = notSupported()
+ def newTypeName(s: String): TypeName = notSupported()
+
+ // Members declared in scala.reflect.api.Positions
+ type Position = DummyPosition.type
+ object DummyPosition extends api.Position {
+ def pos: Position = notSupported()
+ def withPos(newPos: scala.reflect.api.Position): Attachment = notSupported()
+ def payload: Any = notSupported()
+ def withPayload(newPayload: Any): Attachment = notSupported()
+ def fileInfo: java.io.File = notSupported()
+ def fileContent: Array[Char] = notSupported()
+ def isDefined: Boolean = notSupported()
+ def isTransparent: Boolean = notSupported()
+ def isRange: Boolean = notSupported()
+ def isOpaqueRange: Boolean = notSupported()
+ def makeTransparent: Position = notSupported()
+ def start: Int = notSupported()
+ def startOrPoint: Int = notSupported()
+ def point: Int = notSupported()
+ def pointOrElse(default: Int): Int = notSupported()
+ def end: Int = notSupported()
+ def endOrPoint: Int = notSupported()
+ def withStart(off: Int): Position = notSupported()
+ def withEnd(off: Int): Position = notSupported()
+ def withPoint(off: Int): Position = notSupported()
+ def union(pos: scala.reflect.api.Position): Position = notSupported()
+ def focusStart: Position = notSupported()
+ def focus: Position = notSupported()
+ def focusEnd: Position = notSupported()
+ def includes(pos: scala.reflect.api.Position): Boolean = notSupported()
+ def properlyIncludes(pos: scala.reflect.api.Position): Boolean = notSupported()
+ def precedes(pos: scala.reflect.api.Position): Boolean = notSupported()
+ def properlyPrecedes(pos: scala.reflect.api.Position): Boolean = notSupported()
+ def overlaps(pos: scala.reflect.api.Position): Boolean = notSupported()
+ def sameRange(pos: scala.reflect.api.Position): Boolean = notSupported()
+ def line: Int = notSupported()
+ def column: Int = notSupported()
+ def toSingleLine: Position = notSupported()
+ def lineContent: String = notSupported()
+ def show: String = notSupported()
+ }
+ val NoPosition: Position = DummyPosition
+ def atPos[T <: Tree](pos: Position)(tree: T): T = tree
+ def ensureNonOverlapping(tree: Tree,others: List[Tree]): Unit = notSupported()
+ def wrappingPos(trees: List[Tree]): Position = notSupported()
+ def wrappingPos(default: Position,trees: List[Tree]): Position = notSupported()
+
+ // Members declared in scala.reflect.api.FrontEnds
+ def mkConsoleFrontEnd(minSeverity: Int): FrontEnd = notSupported()
+
+ // Members declared in scala.reflect.api.Scopes
+ type Scope = DummyScope.type
+ object DummyScope extends Iterable[Symbol] {
+ def iterator: Iterator[Symbol] = notSupported()
+ }
+ def newScope: Scope = DummyScope
+ def newScopeWith(elems: Symbol*): Scope = DummyScope
+ def newNestedScope(outer: Scope): Scope = DummyScope
+
+ // Members declared in scala.reflect.api.StandardDefinitions
+ val AnyRefTpe: Type = DummyType
+ val AnyTpe: Type = DummyType
+ val AnyValTpe: Type = DummyType
+ val BooleanTpe: Type = DummyType
+ val ByteTpe: Type = DummyType
+ val CharTpe: Type = DummyType
+ val DoubleTpe: Type = DummyType
+ val FloatTpe: Type = DummyType
+ val IntTpe: Type = DummyType
+ val LongTpe: Type = DummyType
+ val NothingTpe: Type = DummyType
+ val NullTpe: Type = DummyType
+ val ObjectTpe: Type = DummyType
+ val ShortTpe: Type = DummyType
+ val StringTpe: Type = DummyType
+ val UnitTpe: Type = DummyType
+ val definitions: AbsDefinitions = DummyDefinitions
+ object DummyDefinitions extends AbsDefinitions {
+ def ByNameParamClass = DummySymbol
+ def JavaRepeatedParamClass = DummySymbol
+ def RepeatedParamClass = DummySymbol
+ def AnyClass = DummyClassSymbol
+ def AnyRefClass = DummyTypeSymbol
+ def AnyValClass = DummyClassSymbol
+ def ArrayClass = DummyClassSymbol
+ def ArrayModule = DummySymbol
+ def ArrayModule_overloadedApply = DummySymbol
+ def Array_apply = DummySymbol
+ def Array_clone = DummySymbol
+ def Array_length = DummySymbol
+ def Array_update = DummySymbol
+ def BooleanClass = DummyClassSymbol
+ def ByteClass = DummyClassSymbol
+ def CharClass = DummyClassSymbol
+ def ClassClass = DummyClassSymbol
+ def ClassTagClass = DummyClassSymbol
+ def ClassTagModule = DummySymbol
+ def ConcreteTypeTagClass = DummyClassSymbol
+ def ConcreteTypeTagModule = DummySymbol
+ def ConsClass = DummySymbol
+ def DoubleClass = DummyClassSymbol
+ def EmptyPackage = DummyPackageSymbol
+ def EmptyPackageClass = DummySymbol
+ def FloatClass = DummyClassSymbol
+ def FunctionClass: Array[Symbol] = Array()
+ def IntClass = DummyClassSymbol
+ def IterableClass = DummySymbol
+ def IteratorClass = DummySymbol
+ def IteratorModule = DummySymbol
+ def Iterator_apply = DummySymbol
+ def JavaLangPackage = DummyPackageSymbol
+ def JavaLangPackageClass = DummySymbol
+ def ListClass = DummyClassSymbol
+ def ListModule = DummyModuleSymbol
+ def List_apply = DummySymbol
+ def LongClass = DummyClassSymbol
+ def NilModule = DummySymbol
+ def NoneModule = DummySymbol
+ def NothingClass = DummyClassSymbol
+ def NullClass = DummyClassSymbol
+ def ObjectClass = DummyClassSymbol
+ def OptionClass = DummySymbol
+ def PredefModule = DummyModuleSymbol
+ def ProductClass: Array[Symbol] = Array()
+ def RootClass = DummyClassSymbol
+ def RootPackage = DummyPackageSymbol
+ def ScalaPackage = DummyPackageSymbol
+ def ScalaPackageClass = DummySymbol
+ def ScalaPrimitiveValueClasses = Nil
+ def SeqClass = DummySymbol
+ def SeqModule = DummySymbol
+ def ShortClass = DummyClassSymbol
+ def SomeClass = DummySymbol
+ def SomeModule = DummySymbol
+ def StringBuilderClass = DummySymbol
+ def StringClass = DummyClassSymbol
+ def SymbolClass = DummySymbol
+ def TraversableClass = DummySymbol
+ def TupleClass: Array[Symbol] = Array()
+ def TypeTagClass = DummyClassSymbol
+ def TypeTagModule = DummySymbol
+ def UnitClass = DummyClassSymbol
+ def isNumericValueClass(sym: Symbol): Boolean = notSupported()
+ def isPrimitiveValueClass(sym: Symbol): Boolean = notSupported()
+ def vmClassType(arg: Type): Type = DummyType
+ def vmSignature(sym: Symbol,info: Type): String = notSupported()
+ }
+
+ // Members declared in scala.reflect.api.StandardNames
+ val nme: AbsTermNames = DummyAbsTermNames
+ val tpnme: AbsTypeNames = DummyAbsTypeNames
+ object DummyAbsTermNames extends AbsTermNames {
+ type NameType = TermName
+ val EMPTY: NameType = DummyName
+ val ANON_FUN_NAME: NameType = DummyName
+ val ANON_CLASS_NAME: NameType = DummyName
+ val EMPTY_PACKAGE_NAME: NameType = DummyName
+ val IMPORT: NameType = DummyName
+ val MODULE_VAR_SUFFIX: NameType = DummyName
+ val ROOT: NameType = DummyName
+ val PACKAGE: NameType = DummyName
+ val SPECIALIZED_SUFFIX: NameType = DummyName
+ val ERROR: NameType = DummyName
+ val NO_NAME: NameType = DummyName
+ val WILDCARD: NameType = DummyName
+ def flattenedName(segments: Name*): NameType = notSupported()
+ val EXPAND_SEPARATOR_STRING: String = ""
+ val ANYNAME: TermName = DummyName
+ val CONSTRUCTOR: TermName = DummyName
+ val FAKE_LOCAL_THIS: TermName = DummyName
+ val INITIALIZER: TermName = DummyName
+ val LAZY_LOCAL: TermName = DummyName
+ val LOCAL_SUFFIX_STRING: String = ""
+ val MIRROR_PREFIX: TermName = DummyName
+ val MIRROR_SHORT: TermName = DummyName
+ val MIRROR_FREE_PREFIX: TermName = DummyName
+ val MIRROR_FREE_THIS_SUFFIX: TermName = DummyName
+ val MIRROR_FREE_VALUE_SUFFIX: TermName = DummyName
+ val MIRROR_SYMDEF_PREFIX: TermName = DummyName
+ val MIXIN_CONSTRUCTOR: TermName = DummyName
+ val MODULE_INSTANCE_FIELD: TermName = DummyName
+ val OUTER: TermName = DummyName
+ val OUTER_LOCAL: TermName = DummyName
+ val OUTER_SYNTH: TermName = DummyName
+ val SELECTOR_DUMMY: TermName = DummyName
+ val SELF: TermName = DummyName
+ val SPECIALIZED_INSTANCE: TermName = DummyName
+ val STAR: TermName = DummyName
+ val THIS: TermName = DummyName
+ val BITMAP_NORMAL: TermName = DummyName
+ val BITMAP_TRANSIENT: TermName = DummyName
+ val BITMAP_PRIVATE: TermName = DummyName
+ val BITMAP_CHECKINIT: TermName = DummyName
+ val BITMAP_CHECKINIT_TRANSIENT: TermName = DummyName
+ val INTERPRETER_IMPORT_WRAPPER: String = ""
+ val INTERPRETER_LINE_PREFIX: String = ""
+ val INTERPRETER_VAR_PREFIX: String = ""
+ val INTERPRETER_WRAPPER_SUFFIX: String = ""
+ val ROOTPKG: TermName = DummyName
+ val ADD: TermName = DummyName
+ val AND: TermName = DummyName
+ val ASR: TermName = DummyName
+ val DIV: TermName = DummyName
+ val EQ: TermName = DummyName
+ val EQL: TermName = DummyName
+ val GE: TermName = DummyName
+ val GT: TermName = DummyName
+ val HASHHASH: TermName = DummyName
+ val LE: TermName = DummyName
+ val LSL: TermName = DummyName
+ val LSR: TermName = DummyName
+ val LT: TermName = DummyName
+ val MINUS: TermName = DummyName
+ val MOD: TermName = DummyName
+ val MUL: TermName = DummyName
+ val NE: TermName = DummyName
+ val OR: TermName = DummyName
+ val PLUS : TermName = DummyName
+ val SUB: TermName = DummyName
+ val XOR: TermName = DummyName
+ val ZAND: TermName = DummyName
+ val ZOR: TermName = DummyName
+ val UNARY_~ : TermName = DummyName
+ val UNARY_+ : TermName = DummyName
+ val UNARY_- : TermName = DummyName
+ val UNARY_! : TermName = DummyName
+ val ??? : TermName = DummyName
+ val MODULE_SUFFIX_NAME: TermName = DummyName
+ val NAME_JOIN_NAME: TermName = DummyName
+ val IMPL_CLASS_SUFFIX: String = ""
+ val LOCALDUMMY_PREFIX: String = ""
+ val PROTECTED_PREFIX: String = ""
+ val PROTECTED_SET_PREFIX: String = ""
+ val SINGLETON_SUFFIX: String = ""
+ val SUPER_PREFIX_STRING: String = ""
+ val TRAIT_SETTER_SEPARATOR_STRING: String = ""
+ val SETTER_SUFFIX: TermName = DummyName
+ def isConstructorName(name: Name): Boolean = notSupported()
+ def isExceptionResultName(name: Name): Boolean = notSupported()
+ def isImplClassName(name: Name): Boolean = notSupported()
+ def isLocalDummyName(name: Name): Boolean = notSupported()
+ def isLocalName(name: Name): Boolean = notSupported()
+ def isLoopHeaderLabel(name: Name): Boolean = notSupported()
+ def isProtectedAccessorName(name: Name): Boolean = notSupported()
+ def isSuperAccessorName(name: Name): Boolean = notSupported()
+ def isReplWrapperName(name: Name): Boolean = notSupported()
+ def isSetterName(name: Name): Boolean = notSupported()
+ def isTraitSetterName(name: Name): Boolean = notSupported()
+ def isSingletonName(name: Name): Boolean = notSupported()
+ def isModuleName(name: Name): Boolean = notSupported()
+ def isOpAssignmentName(name: Name): Boolean = notSupported()
+ def segments(name: String, assumeTerm: Boolean): List[Name] = notSupported()
+ def originalName(name: Name): Name = notSupported()
+ def stripModuleSuffix(name: Name): Name = notSupported()
+ def unspecializedName(name: Name): Name = notSupported()
+ def splitSpecializedName(name: Name): (Name, String, String) = notSupported()
+ def dropLocalSuffix(name: Name): Name = notSupported()
+ def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName = notSupported()
+ def expandedSetterName(name: TermName, base: Symbol): TermName = notSupported()
+ def protName(name: Name): TermName = notSupported()
+ def protSetterName(name: Name): TermName = notSupported()
+ def getterName(name: TermName): TermName = notSupported()
+ def getterToLocal(name: TermName): TermName = notSupported()
+ def getterToSetter(name: TermName): TermName = notSupported()
+ def localToGetter(name: TermName): TermName = notSupported()
+ def setterToGetter(name: TermName): TermName = notSupported()
+ def defaultGetterName(name: Name, pos: Int): TermName = notSupported()
+ def defaultGetterToMethod(name: Name): TermName = notSupported()
+ def localDummyName(clazz: Symbol): TermName = notSupported()
+ def superName(name: Name): TermName = notSupported()
+ }
+ object DummyAbsTypeNames extends AbsTypeNames {
+ type NameType = TypeName
+ val EMPTY: NameType = DummyName
+ val ANON_FUN_NAME: NameType = DummyName
+ val ANON_CLASS_NAME: NameType = DummyName
+ val EMPTY_PACKAGE_NAME: NameType = DummyName
+ val IMPORT: NameType = DummyName
+ val MODULE_VAR_SUFFIX: NameType = DummyName
+ val ROOT: NameType = DummyName
+ val PACKAGE: NameType = DummyName
+ val SPECIALIZED_SUFFIX: NameType = DummyName
+ val ERROR: NameType = DummyName
+ val NO_NAME: NameType = DummyName
+ val WILDCARD: NameType = DummyName
+ def flattenedName(segments: Name*): NameType = notSupported()
+ val REFINE_CLASS_NAME: TypeName = DummyName
+ val BYNAME_PARAM_CLASS_NAME: TypeName = DummyName
+ val EQUALS_PATTERN_NAME: TypeName = DummyName
+ val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName = DummyName
+ val LOCAL_CHILD: TypeName = DummyName
+ val REPEATED_PARAM_CLASS_NAME: TypeName = DummyName
+ val WILDCARD_STAR: TypeName = DummyName
+
+ def dropSingletonName(name: Name): TypeName = notSupported()
+ def singletonName(name: Name): TypeName = notSupported()
+ def implClassName(name: Name): TypeName = notSupported()
+ def interfaceName(implname: Name): TypeName = notSupported()
+ }
+
+ // Members declared in scala.reflect.api.Symbols
+ val NoSymbol = DummySymbol
+ type Symbol = DummySymbolApi
+ object DummySymbol extends DummySymbolApi
+ type TypeSymbol = DummyTypeSymbolApi
+ object DummyTypeSymbol extends DummyTypeSymbolApi
+ type TermSymbol = DummyTermSymbolApi
+ object DummyTermSymbol extends DummyTermSymbolApi
+ type MethodSymbol = DummyMethodSymbolApi
+ object DummyMethodSymbol extends DummyMethodSymbolApi
+ type ModuleSymbol = DummyModuleSymbolApi
+ object DummyModuleSymbol extends DummyModuleSymbolApi
+ type PackageSymbol = DummyPackageSymbolApi
+ object DummyPackageSymbol extends DummyPackageSymbolApi
+ type ClassSymbol = DummyClassSymbolApi
+ object DummyClassSymbol extends DummyClassSymbolApi
+ trait DummySymbolApi extends AbsSymbol {
+ this: Symbol =>
+
+ def pos: Position = notSupported()
+ def modifiers: Set[Modifier] = notSupported()
+ def hasModifier(mod: Modifier): Boolean = notSupported()
+ def annotations: List[AnnotationInfo] = notSupported()
+ def hasAnnotation(sym: Symbol): Boolean = notSupported()
+ def owner: Symbol = notSupported()
+ def name: Name = notSupported()
+ def fullName: String = notSupported()
+ def id: Int = notSupported()
+ def orElse[T](alt: => Symbol): Symbol = notSupported()
+ def filter(cond: Symbol => Boolean): Symbol = notSupported()
+ def suchThat(cond: Symbol => Boolean): Symbol = notSupported()
+ def privateWithin: Symbol = notSupported()
+ def companionSymbol: Symbol = notSupported()
+ def moduleClass: Symbol = notSupported()
+ def enclosingTopLevelClass: Symbol = notSupported()
+ def enclosingClass: Symbol = notSupported()
+ def enclosingMethod: Symbol = notSupported()
+ def enclosingPackageClass: Symbol = notSupported()
+ def isTerm : Boolean = notSupported()
+ def isPackage : Boolean = notSupported()
+ def isMethod : Boolean = notSupported()
+ def isOverloaded : Boolean = notSupported()
+ def isFreeTerm : Boolean = notSupported()
+ def isType : Boolean = notSupported()
+ def isClass : Boolean = notSupported()
+ def isPackageClass : Boolean = notSupported()
+ def isPrimitiveValueClass: Boolean = notSupported()
+ def isDerivedValueClass: Boolean = notSupported()
+ def isAliasType : Boolean = notSupported()
+ def isAbstractType : Boolean = notSupported()
+ def isSkolem : Boolean = notSupported()
+ def isExistential : Boolean = notSupported()
+ def isFreeType : Boolean = notSupported()
+ def isContravariant : Boolean = notSupported()
+ def isCovariant : Boolean = notSupported()
+ def isErroneous : Boolean = notSupported()
+ def typeSignature: Type = notSupported()
+ def typeSignatureIn(site: Type): Type = notSupported()
+ def asType: Type = notSupported()
+ def asTypeIn(site: Type): Type = notSupported()
+ def asTypeConstructor: Type = notSupported()
+ def thisPrefix: Type = notSupported()
+ def selfType: Type = notSupported()
+ def alternatives: List[Symbol] = notSupported()
+ def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol = notSupported()
+ def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = notSupported()
+ def setInternalFlags(flags: Long): this.type = notSupported()
+ def setTypeSignature(tpe: Type): this.type = notSupported()
+ def setAnnotations(annots: AnnotationInfo*): this.type = notSupported()
+ def kind: String = notSupported()
+ }
+ trait DummyTypeSymbolApi extends DummySymbolApi with TypeSymbolApi {
+ this: TypeSymbol =>
+ }
+ trait DummyTermSymbolApi extends DummySymbolApi with TermSymbolApi {
+ this: TermSymbol =>
+ }
+ trait DummyMethodSymbolApi extends DummyTermSymbolApi with MethodSymbolApi {
+ this: MethodSymbol =>
+ }
+ trait DummyModuleSymbolApi extends DummyTermSymbolApi with ModuleSymbolApi {
+ this: ModuleSymbol =>
+ }
+ trait DummyPackageSymbolApi extends DummyModuleSymbolApi with PackageSymbolApi {
+ this: PackageSymbol =>
+ }
+ trait DummyClassSymbolApi extends DummyTypeSymbolApi with ClassSymbolApi {
+ this: ClassSymbol =>
+ }
+
+ // Members declared in scala.reflect.api.ToolBoxes
+ def mkToolBox(frontEnd: FrontEnd, options: String): AbsToolBox = notSupported()
+
+ // Members declared in scala.reflect.api.TreeBuildUtil
+ // type TreeGen = DummyTreeGen.type // [Eugene] cannot compile if uncomment this
+ val gen: TreeGen{val global: DummyMirror.this.type} = DummyTreeGen.asInstanceOf[TreeGen{val global: DummyMirror.this.type}]
+ def modifiersFromInternalFlags(flags: Long,privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers
+ def newFreeExistential(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol
+ def newFreeTerm(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol
+ def newFreeType(name: String,info: Type,value: => Any,flags: Long,origin: String) = DummySymbol
+ def selectOverloadedMethod(owner: Symbol,name: String,index: Int) = DummySymbol
+ def selectOverloadedMethodIfDefined(owner: Symbol,name: String,index: Int) = DummySymbol
+ def selectTerm(owner: Symbol,name: String) = DummySymbol
+ def selectTermIfDefined(owner: Symbol,name: String) = DummySymbol
+ def selectType(owner: Symbol,name: String) = DummySymbol
+ def selectTypeIfDefined(owner: Symbol,name: String) = DummySymbol
+ def staticClass(fullName: String) = DummySymbol
+ def staticClassIfDefined(fullName: String) = DummySymbol
+ def staticModule(fullName: String) = DummySymbol
+ def staticModuleIfDefined(fullName: String) = DummySymbol
+ def thisModuleType(fullName: String): Type = DummyType
+ object DummyTreeGen extends AbsTreeGen {
+ val global: Universe = DummyMirror.this
+ type TreeGenTree = global.Tree
+ type TreeGenType = global.Type
+ type TreeGenSymbol = global.Symbol
+ type TreeGenName = global.Name
+ def mkAttributedQualifier(tpe: TreeGenType): TreeGenTree = notSupported()
+ def mkAttributedQualifier(tpe: TreeGenType, termSym: TreeGenSymbol): TreeGenTree = notSupported()
+ def mkAttributedRef(pre: TreeGenType, sym: TreeGenSymbol): TreeGenTree = notSupported()
+ def mkAttributedRef(sym: TreeGenSymbol): TreeGenTree = notSupported()
+ def mkAttributedThis(sym: TreeGenSymbol): TreeGenTree = notSupported()
+ def mkAttributedIdent(sym: TreeGenSymbol): TreeGenTree = notSupported()
+ def mkAttributedSelect(qual: TreeGenTree, sym: TreeGenSymbol): TreeGenTree = notSupported()
+ def mkMethodCall(target: TreeGenTree,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported()
+ def mkMethodCall(receiver: TreeGenTree,method: TreeGenSymbol,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported()
+ def mkMethodCall(receiver: TreeGenSymbol,methodName: TreeGenName,args: List[TreeGenTree]): TreeGenTree = notSupported()
+ def mkMethodCall(target: TreeGenTree,args: List[TreeGenTree]): TreeGenTree = notSupported()
+ def mkMethodCall(method: TreeGenSymbol,args: List[TreeGenTree]): TreeGenTree = notSupported()
+ def mkMethodCall(method: TreeGenSymbol,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported()
+ def mkMethodCall(receiver: TreeGenSymbol,methodName: TreeGenName,targs: List[TreeGenType],args: List[TreeGenTree]): TreeGenTree = notSupported()
+ def mkNullaryCall(method: TreeGenSymbol,targs: List[TreeGenType]): TreeGenTree = notSupported()
+ }
+
+ // Members declared in scala.reflect.api.TreePrinters
+ def newTreePrinter(out: java.io.PrintWriter): TreePrinter = notSupported()
+
+ // Members declared in scala.reflect.api.Trees
+ def Apply(sym: Symbol,args: Tree*): Tree = Apply(EmptyTree, Nil)
+ def Bind(sym: Symbol,body: Tree): Bind = Bind(DummyName, EmptyTree)
+ def Block(stats: Tree*): Block = Block()
+ def CaseDef(pat: Tree,body: Tree): CaseDef = CaseDef(EmptyTree, EmptyTree, EmptyTree)
+ def ClassDef(sym: Symbol,impl: Template): ClassDef = ClassDef(DummyModifiers, DummyName, Nil, Template(Nil, emptyValDef, Nil))
+ def DefDef(sym: Symbol,rhs: List[List[Symbol]] => Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
+ def DefDef(sym: Symbol,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
+ def DefDef(sym: Symbol,mods: Modifiers,rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
+ def DefDef(sym: Symbol,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
+ def DefDef(sym: Symbol,mods: Modifiers,vparamss: List[List[ValDef]],rhs: Tree): DefDef = DefDef(DummyModifiers, DummyName, Nil, Nil, EmptyTree, EmptyTree)
+ def Ident(sym: Symbol): Ident = Ident(DummyName)
+ def Ident(name: String): Ident = Ident(DummyName)
+ def LabelDef(sym: Symbol,params: List[Symbol],rhs: Tree): LabelDef = LabelDef(DummyName, Nil, EmptyTree)
+ type Modifiers = DummyModifiers.type
+ val NoMods: Modifiers = DummyModifiers
+ object DummyModifiers extends AbsModifiers {
+ def modifiers: Set[Modifier] = notSupported()
+ def hasModifier(mod: Modifier): Boolean = notSupported()
+ def privateWithin: Name = notSupported()
+ def annotations: List[Tree] = notSupported()
+ def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = notSupported()
+ }
+ def Modifiers(mods: Set[scala.reflect.api.Modifier],privateWithin: Name,annotations: List[Tree]): Modifiers = DummyModifiers
+ def ModuleDef(sym: Symbol,impl: Template): ModuleDef = ModuleDef(DummyModifiers, DummyName, Template(Nil, emptyValDef, Nil))
+ def New(sym: Symbol,args: Tree*): Tree = New(EmptyTree)
+ def New(tpe: Type,args: Tree*): Tree = New(EmptyTree)
+ def New(tpt: Tree,argss: List[List[Tree]]): Tree = New(EmptyTree)
+ def Select(qualifier: Tree,sym: Symbol): Select = Select(EmptyTree, DummyName)
+ def Select(qualifier: Tree,name: String): Select = Select(EmptyTree, DummyName)
+ def Super(sym: Symbol,mix: TypeName): Tree = Super(EmptyTree, DummyName)
+ def This(sym: Symbol): Tree = This(DummyName)
+ def Throw(tpe: Type,args: Tree*): Throw = Throw(EmptyTree)
+ def Try(body: Tree,cases: (Tree, Tree)*): Try = Try(EmptyTree)
+ def TypeDef(sym: Symbol): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree)
+ def TypeDef(sym: Symbol,rhs: Tree): TypeDef = TypeDef(DummyModifiers, DummyName, Nil, EmptyTree)
+ def ValDef(sym: Symbol): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree)
+ def ValDef(sym: Symbol,rhs: Tree): ValDef = ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree)
+ protected def duplicateTree(tree: Tree): Tree = notSupported()
+ object emptyValDef extends ValDef(DummyModifiers, DummyName, EmptyTree, EmptyTree) { override def isEmpty = true }
+ type TreeCopier = DummyTreeCopier.type
+ def newStrictTreeCopier: TreeCopier = DummyTreeCopier
+ def newLazyTreeCopier: TreeCopier = DummyTreeCopier
+ object DummyTreeCopier extends TreeCopierOps {
+ def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef = notSupported()
+ def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef = notSupported()
+ def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef = notSupported()
+ def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef = notSupported()
+ def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef = notSupported()
+ def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef = notSupported()
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef = notSupported()
+ def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import = notSupported()
+ def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template = notSupported()
+ def Block(tree: Tree, stats: List[Tree], expr: Tree): Block = notSupported()
+ def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef = notSupported()
+ def Alternative(tree: Tree, trees: List[Tree]): Alternative = notSupported()
+ def Star(tree: Tree, elem: Tree): Star = notSupported()
+ def Bind(tree: Tree, name: Name, body: Tree): Bind = notSupported()
+ def UnApply(tree: Tree, fun: Tree, args: List[Tree]): UnApply = notSupported()
+ def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue = notSupported()
+ def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function = notSupported()
+ def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign = notSupported()
+ def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg = notSupported()
+ def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If = notSupported()
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match = notSupported()
+ def Return(tree: Tree, expr: Tree): Return = notSupported()
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try = notSupported()
+ def Throw(tree: Tree, expr: Tree): Throw = notSupported()
+ def New(tree: Tree, tpt: Tree): New = notSupported()
+ def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed = notSupported()
+ def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply = notSupported()
+ def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply = notSupported()
+ def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic = notSupported()
+ def Super(tree: Tree, qual: Tree, mix: TypeName): Super = notSupported()
+ def This(tree: Tree, qual: Name): This = notSupported()
+ def Select(tree: Tree, qualifier: Tree, selector: Name): Select = notSupported()
+ def Ident(tree: Tree, name: Name): Ident = notSupported()
+ def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed = notSupported()
+ def Literal(tree: Tree, value: Constant): Literal = notSupported()
+ def TypeTree(tree: Tree): TypeTree = notSupported()
+ def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated = notSupported()
+ def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree = notSupported()
+ def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree = notSupported()
+ def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree = notSupported()
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree = notSupported()
+ def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree): TypeBoundsTree = notSupported()
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree = notSupported()
+ }
+
+ // Members declared in scala.reflect.api.Types
+ type Type = DummyType.type
+ type SingletonType = DummyType.type
+ type CompoundType = DummyType.type
+ type AnnotatedType = DummyType.type
+ val AnnotatedType: AnnotatedTypeExtractor = DummyAnnotatedTypeExtractor
+ type BoundedWildcardType = DummyType.type
+ val BoundedWildcardType: BoundedWildcardTypeExtractor = DummyBoundedWildcardTypeExtractor
+ type ClassInfoType = DummyType.type
+ val ClassInfoType: ClassInfoTypeExtractor = DummyClassInfoTypeExtractor
+ type ConstantType = DummyType.type
+ val ConstantType: ConstantTypeExtractor = DummyConstantTypeExtractor
+ type ExistentialType = DummyType.type
+ val ExistentialType: ExistentialTypeExtractor = DummyExistentialTypeExtractor
+ type MethodType = DummyType.type
+ val MethodType: MethodTypeExtractor = DummyMethodTypeExtractor
+ val NoPrefix: Type = DummyType
+ val NoType: Type = DummyType
+ type NullaryMethodType = DummyType.type
+ val NullaryMethodType: NullaryMethodTypeExtractor = DummyNullaryMethodTypeExtractor
+ type PolyType = DummyType.type
+ val PolyType: PolyTypeExtractor = DummyPolyTypeExtractor
+ type RefinedType = DummyType.type
+ val RefinedType: RefinedTypeExtractor = DummyRefinedTypeExtractor
+ type SingleType = DummyType.type
+ val SingleType: SingleTypeExtractor = DummySingleTypeExtractor
+ type SuperType = DummyType.type
+ val SuperType: SuperTypeExtractor = DummySuperTypeExtractor
+ type ThisType = DummyType.type
+ val ThisType: ThisTypeExtractor = DummyThisTypeExtractor
+ type TypeBounds = DummyType.type
+ val TypeBounds: TypeBoundsExtractor = DummyTypeBoundsExtractor
+ type TypeRef = DummyType.type
+ val TypeRef: TypeRefExtractor = DummyTypeRefExtractor
+ val WildcardType: Type = DummyType
+ def appliedType(tycon: Type,args: List[Type]): Type = DummyType
+ def existentialAbstraction(tparams: List[Symbol],tpe0: Type): Type = DummyType
+ def glb(ts: List[Type]): Type = DummyType
+ def intersectionType(tps: List[Type],owner: Symbol): Type = DummyType
+ def intersectionType(tps: List[Type]): Type = DummyType
+ def lub(xs: List[Type]): Type = DummyType
+ def polyType(tparams: List[Symbol],tpe: Type): Type = DummyType
+ def refinedType(parents: List[Type],owner: Symbol): Type = DummyType
+ def refinedType(parents: List[Type],owner: Symbol,decls: Scope,pos: Position): Type = DummyType
+ def singleType(pre: Type,sym: Symbol): Type = DummyType
+ def typeRef(pre: Type,sym: Symbol,args: List[Type]): Type = DummyType
+ object DummyType extends AbsType {
+ def =:=(that: Type): Boolean = notSupported()
+ def <:<(that: Type): Boolean = notSupported()
+ def asSeenFrom(pre: Type,clazz: Symbol): Type = notSupported()
+ def baseClasses: List[Symbol] = notSupported()
+ def baseType(clazz: Symbol): Type = notSupported()
+ def contains(sym: Symbol): Boolean = notSupported()
+ def declaration(name: Name): Symbol = notSupported()
+ def declarations: Iterable[Symbol] = notSupported()
+ def erasure: Type = notSupported()
+ def exists(p: Type => Boolean): Boolean = notSupported()
+ def find(p: Type => Boolean): Option[Type] = notSupported()
+ def foreach(f: Type => Unit): Unit = notSupported()
+ def isConcrete: Boolean = notSupported()
+ def isHigherKinded: Boolean = notSupported()
+ def isSpliceable: Boolean = notSupported()
+ def kind: String = notSupported()
+ def map(f: Type => Type): Type = notSupported()
+ def member(name: Name): Symbol = notSupported()
+ def members: Iterable[Symbol] = notSupported()
+ def nonPrivateMember(name: Name): Symbol = notSupported()
+ def nonPrivateMembers: Iterable[Symbol] = notSupported()
+ def normalize: Type = notSupported()
+ def parents: List[Type] = notSupported()
+ def substituteTypes(from: List[Symbol],to: List[Type]): Type = notSupported()
+ def typeArguments: List[Type] = notSupported()
+ def typeConstructor: Type = notSupported()
+ def typeParams: List[Symbol] = notSupported()
+ def typeSymbol: Symbol = notSupported()
+ def underlying: Type = notSupported()
+ def widen: Type = notSupported()
+ }
+ object DummyAnnotatedTypeExtractor extends AnnotatedTypeExtractor {
+ def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType = DummyType
+ def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)] = notSupported()
+ }
+ object DummyBoundedWildcardTypeExtractor extends BoundedWildcardTypeExtractor {
+ def apply(bounds: TypeBounds): BoundedWildcardType = DummyType
+ def unapply(tpe: BoundedWildcardType): Option[TypeBounds] = notSupported()
+ }
+ object DummyClassInfoTypeExtractor extends ClassInfoTypeExtractor {
+ def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType = DummyType
+ def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] = notSupported()
+ }
+ object DummyConstantTypeExtractor extends ConstantTypeExtractor {
+ def apply(value: Constant): ConstantType = DummyType
+ def unapply(tpe: ConstantType): Option[Constant] = notSupported()
+ }
+ object DummyExistentialTypeExtractor extends ExistentialTypeExtractor {
+ def apply(quantified: List[Symbol], underlying: Type): ExistentialType = DummyType
+ def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] = notSupported()
+ }
+ object DummyMethodTypeExtractor extends MethodTypeExtractor {
+ def apply(params: List[Symbol], resultType: Type): MethodType = DummyType
+ def unapply(tpe: MethodType): Option[(List[Symbol], Type)] = notSupported()
+ }
+ object DummyNullaryMethodTypeExtractor extends NullaryMethodTypeExtractor {
+ def apply(resultType: Type): NullaryMethodType = DummyType
+ def unapply(tpe: NullaryMethodType): Option[(Type)] = notSupported()
+ }
+ object DummyPolyTypeExtractor extends PolyTypeExtractor {
+ def apply(typeParams: List[Symbol], resultType: Type): PolyType = DummyType
+ def unapply(tpe: PolyType): Option[(List[Symbol], Type)] = notSupported()
+ }
+ object DummyRefinedTypeExtractor extends RefinedTypeExtractor {
+ def apply(parents: List[Type], decls: Scope): RefinedType = DummyType
+ def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType = DummyType
+ def unapply(tpe: RefinedType): Option[(List[Type], Scope)] = notSupported()
+ }
+ object DummySingleTypeExtractor extends SingleTypeExtractor {
+ def apply(pre: Type, sym: Symbol): Type = DummyType
+ def unapply(tpe: SingleType): Option[(Type, Symbol)] = notSupported()
+ }
+ object DummySuperTypeExtractor extends SuperTypeExtractor {
+ def apply(thistpe: Type, supertpe: Type): Type = DummyType
+ def unapply(tpe: SuperType): Option[(Type, Type)] = notSupported()
+ }
+ object DummyThisTypeExtractor extends ThisTypeExtractor {
+ def apply(sym: Symbol): Type = DummyType
+ def unapply(tpe: ThisType): Option[Symbol] = notSupported()
+ }
+ object DummyTypeBoundsExtractor extends TypeBoundsExtractor {
+ def apply(lo: Type, hi: Type): TypeBounds = DummyType
+ def unapply(tpe: TypeBounds): Option[(Type, Type)] = notSupported()
+ }
+ object DummyTypeRefExtractor extends TypeRefExtractor {
+ def apply(pre: Type, sym: Symbol, args: List[Type]): Type = DummyType
+ def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] = notSupported()
+ }
+
+ // Utils
+ def notSupported() = {
+ throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(cl))
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala
new file mode 100644
index 0000000000..3ed17fea41
--- /dev/null
+++ b/src/library/scala/reflect/DynamicProxy.scala
@@ -0,0 +1,74 @@
+package scala.reflect
+/**
+ * A dynamic proxy which redirects method calls and attribute access to a given
+ * target object at runtime using reflection.
+ *
+ * Usage example:
+ *
+ * object x{ def hello = "hello world" }
+ * val d = new DynamicProxy{ val dynamicProxyTarget = x }
+ * assert( d.hello == "hello world" )
+ *
+ * Not supported (yet):
+ * - implicit conversions and parameters
+ * - multiple arguments lists
+ * - explicit type arguments
+ */
+trait DynamicProxy extends Dynamic{
+ /** Method calls on DynamicProxy are redirected to this object. Needs to be defined in a subclass. */
+ val dynamicProxyTarget : AnyRef
+
+ import scala.reflect.mirror._
+ /**
+ * boxing to preserve information on primitive types for overloading resolution
+ */
+ case class DynamicReflectBoxed( class_ : Class[_], value: Any )
+ object DynamicReflectBoxed{
+ implicit def box[@specialized T]( v:T ) = DynamicReflectBoxed( v.getClass, v )
+ }
+
+ def selectDynamic( method:String ) = {
+ val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName )
+ invoke( dynamicProxyTarget, symbol )()
+ }
+
+ def updateDynamic( method:String )( value : Any ) = {
+ val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method+"_=").encodedName )
+ invoke( dynamicProxyTarget, symbol )( value )
+ }
+
+ def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any
+ = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* )
+
+ def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = {
+ val class_ = dynamicProxyTarget.getClass
+ var i = 0
+ val toolbox = mkToolBox(mkConsoleFrontEnd(),"")
+ val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName )
+ if(args.size == 0){
+ invoke( dynamicProxyTarget, symbol )()
+ } else {
+ val call =
+ Apply(
+ Select(
+ TypeApply(
+ Select(
+ Select(
+ Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this))
+ , newTermName("dynamicProxyTarget")
+ ),
+ newTermName("asInstanceOf") )
+ , List(TypeTree().setType(classToType(class_)))
+ )
+ ,newTermName(method).encodedName
+ )
+ ,args.map{ case(name,box) =>
+ val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value))
+ if( name == "" ) value
+ else AssignOrNamedArg( Ident(name), value )
+ }.toList
+ )
+ toolbox.runExpr( call )
+ }
+ }
+}
diff --git a/src/library/scala/reflect/ErasureTag.scala b/src/library/scala/reflect/ErasureTag.scala
new file mode 100644
index 0000000000..f95451fab2
--- /dev/null
+++ b/src/library/scala/reflect/ErasureTag.scala
@@ -0,0 +1,23 @@
+package scala.reflect
+
+import java.lang.{Class => jClass}
+
+/** An `ErasureTag[T]` is a descriptor that is requested by the compiler every time
+ * when it needs to persist an erasure of a type.
+ *
+ * Scala library provides a standard implementation of this trait,
+ * `TypeTag[T]` that carries the `java.lang.Class` erasure for arbitrary types.
+ *
+ * However other platforms may reimplement this trait as they see fit
+ * and then expose the implementation via an implicit macro.
+ *
+ * If you need to guarantee that the type does not contain
+ * references to type parameters or abstract types, use `ClassTag[T]`.
+ *
+ * @see [[scala.reflect.api.TypeTags]]
+ */
+@annotation.implicitNotFound(msg = "No ErasureTag available for ${T}")
+trait ErasureTag[T] {
+ /** Returns an erasure of type `T` */
+ def erasure: jClass[_]
+}
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index e5df487be9..da029f046d 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -40,6 +40,7 @@ import mirror._
*
*/
@annotation.implicitNotFound(msg = "No Manifest available for ${T}.")
+@deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0")
trait Manifest[T] extends ClassManifest[T] with Equals {
override def typeArguments: List[Manifest[_]] = Nil
@@ -60,6 +61,7 @@ trait Manifest[T] extends ClassManifest[T] with Equals {
override def hashCode = this.erasure.##
}
+@deprecated("Use type tags and manually check the corresponding class or type instead", "2.10.0")
abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals {
override def <:<(that: ClassManifest[_]): Boolean =
(that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal)
@@ -75,9 +77,8 @@ abstract class AnyValManifest[T <: AnyVal](override val toString: String) extend
* It is intended for use by the compiler and should not be used
* in client code.
*/
+@deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0")
object Manifest {
- import mirror.{ definitions => mdefs }
-
def valueManifests: List[AnyValManifest[_]] =
List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit)
@@ -154,40 +155,33 @@ object Manifest {
}
val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any]("Any") {
- override def symbol = mdefs.AnyClass
override def <:<(that: ClassManifest[_]): Boolean = (that eq this)
private def readResolve(): Any = Manifest.Any
}
val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object]("Object") {
- override def symbol = mdefs.ObjectClass
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
private def readResolve(): Any = Manifest.Object
}
val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal]("AnyVal") {
- override def symbol = mdefs.AnyValClass
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
private def readResolve(): Any = Manifest.AnyVal
}
val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null]("Null") {
- override def symbol = mdefs.NullClass
override def <:<(that: ClassManifest[_]): Boolean =
(that ne null) && (that ne Nothing) && !(that <:< AnyVal)
private def readResolve(): Any = Manifest.Null
}
val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing]("Nothing") {
- override def symbol = mdefs.NothingClass
override def <:<(that: ClassManifest[_]): Boolean = (that ne null)
private def readResolve(): Any = Manifest.Nothing
}
private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] {
lazy val erasure = value.getClass
- override lazy val symbol = InstanceRefSymbol(value) // todo: change to freevar
- override lazy val tpe = mirror.SingleType(mirror.NoPrefix, symbol)
override lazy val toString = value.toString + ".type"
}
@@ -216,12 +210,8 @@ object Manifest {
def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
- /** Phantom types have no runtime representation; they all erase to Object,
- * but the Symbol preserves their identity.
- */
private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) {
- override lazy val tpe = namedType(mirror.NoPrefix, symbol, Nil)
- override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
override val hashCode = System.identityHashCode(this)
}
@@ -230,15 +220,6 @@ object Manifest {
private class ClassTypeManifest[T](prefix: Option[Manifest[_]],
val erasure: Predef.Class[_],
override val typeArguments: List[Manifest[_]]) extends Manifest[T] {
-
- override lazy val tpe = {
- val pre = prefix match {
- case Some(pm) => pm.tpe
- case None => symbol.owner.thisPrefix
- }
- namedType(pre, symbol, typeArguments map (_.tpe))
- }
-
override def toString =
(if (prefix.isEmpty) "" else prefix.get.toString+"#") +
(if (erasure.isArray) "Array" else erasure.getName) +
@@ -254,7 +235,6 @@ object Manifest {
def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
new Manifest[T] {
def erasure = upperBound
- override lazy val tpe = namedType(prefix.tpe, prefix.tpe.member(newTypeName(name)), args map (_.tpe) toList)
override val typeArguments = args.toList
override def toString = prefix.toString+"#"+name+argString
}
@@ -264,7 +244,6 @@ object Manifest {
def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] =
new Manifest[T] {
def erasure = upperBound.erasure
- override lazy val tpe = mirror.TypeBounds(lowerBound.tpe, upperBound.tpe)
override def toString =
"_" +
(if (lowerBound eq Nothing) "" else " >: "+lowerBound) +
@@ -275,28 +254,6 @@ object Manifest {
def intersectionType[T](parents: Manifest[_]*): Manifest[T] =
new Manifest[T] {
def erasure = parents.head.erasure
- override lazy val tpe = mirror.RefinedType((parents map (_.tpe)).toList, newScope)
override def toString = parents.mkString(" with ")
}
-
- /** A generic manifest factory from a reflect.Type. Except where
- * mandated by performance considerations, we should replace most
- * other manifest factories by this one. There's just one thing
- * that needs to be done first: A Manifest's type can refer
- * to type variables that are controlled by manifests. In that
- * case the reified type needs to contain the type passed in the manifest
- * instead of the reference to the manifest. Note that splicing manifests
- * into manfifests is completely analogous to splicing code blocks into
- * code blocks. Manifest[T] and Code[T] are really the same thing, only one
- * works for types, the other for trees.
- * Another complication is that once we generate manifests from types, we really
- * should have reflection as a standard component shipped with the standard library,
- * instead of in scala-compiler.jar.
- */
- def apply[T](_tpe: mirror.Type): Manifest[T] = new Manifest[T] {
- override def symbol = _tpe.typeSymbol
- override lazy val tpe = _tpe
- override def erasure = mirror.typeToClass(_tpe.erasedType)
- override def toString = _tpe.toString
- }
-}
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/NoManifest.scala b/src/library/scala/reflect/NoManifest.scala
index 191e46ae39..7b8037272c 100644
--- a/src/library/scala/reflect/NoManifest.scala
+++ b/src/library/scala/reflect/NoManifest.scala
@@ -10,6 +10,7 @@ package scala.reflect
/** One of the branches of an [[scala.reflect.OptManifest]].
*/
+@deprecated("Use `@scala.reflect.TypeTag` instead", "2.10.0")
object NoManifest extends OptManifest[Nothing] with Serializable {
override def toString = "<?>"
-}
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/OptManifest.scala b/src/library/scala/reflect/OptManifest.scala
index 2a955deb2c..46f23c4e22 100644
--- a/src/library/scala/reflect/OptManifest.scala
+++ b/src/library/scala/reflect/OptManifest.scala
@@ -14,4 +14,5 @@ package scala.reflect
*
* @author Martin Odersky
*/
-trait OptManifest[+T] extends Serializable
+@deprecated("Use `@scala.reflect.TypeTag` instead", "2.10.0")
+trait OptManifest[+T] extends Serializable \ No newline at end of file
diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala
index 510f0819c6..6ea69cb80d 100644
--- a/src/library/scala/reflect/ReflectionUtils.scala
+++ b/src/library/scala/reflect/ReflectionUtils.scala
@@ -5,6 +5,7 @@
package scala.reflect
+import java.lang.{Class => jClass}
import java.lang.reflect.{ InvocationTargetException, UndeclaredThrowableException }
/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
@@ -27,7 +28,39 @@ object ReflectionUtils {
case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex))
}
- def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): AnyRef = {
+ private def systemProperties: Iterator[(String, String)] = {
+ import scala.collection.JavaConverters._
+ System.getProperties.asScala.iterator
+ }
+
+ private def searchForBootClasspath = (
+ systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse ""
+ )
+
+ def show(cl: ClassLoader) = {
+ def inferClasspath(cl: ClassLoader) = cl match {
+ case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]"
+ case _ => "<unknown>"
+ }
+ cl match {
+ case cl if cl != null =>
+ "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl))
+ case null =>
+ "primordial classloader with boot classpath [%s]".format(searchForBootClasspath)
+ }
+ }
+
+ def defaultReflectionClassLoader() = {
+ // say no to non-determinism of mirror classloaders
+ // default classloader will be instantiated using current system classloader
+ // if you wish so, you can rebind it by setting ``mirror.classLoader'' to whatever is necessary
+// val cl = Thread.currentThread.getContextClassLoader
+// if (cl == null) getClass.getClassLoader else cl
+// cl
+ getClass.getClassLoader
+ }
+
+ def singletonInstance(cl: ClassLoader, className: String): AnyRef = {
val name = if (className endsWith "$") className else className + "$"
val clazz = java.lang.Class.forName(name, true, cl)
val singleton = clazz getField "MODULE$" get null
@@ -35,7 +68,17 @@ object ReflectionUtils {
}
// Retrieves the MODULE$ field for the given class name.
- def singletonInstanceOpt(className: String, cl: ClassLoader = getClass.getClassLoader): Option[AnyRef] =
- try Some(singletonInstance(className, cl))
+ def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] =
+ try Some(singletonInstance(cl, className))
+ catch { case _: ClassNotFoundException => None }
+
+ def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = {
+ val singleton = singletonInstance(cl, className)
+ val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader])
+ method.invoke(singleton, args: _*)
+ }
+
+ def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] =
+ try Some(invokeFactory(cl, className, methodName, args: _*))
catch { case _: ClassNotFoundException => None }
}
diff --git a/src/library/scala/reflect/TagInterop.scala b/src/library/scala/reflect/TagInterop.scala
new file mode 100644
index 0000000000..6c6bfcc2f2
--- /dev/null
+++ b/src/library/scala/reflect/TagInterop.scala
@@ -0,0 +1,34 @@
+package scala.reflect
+
+import scala.runtime.ScalaRunTime._
+import mirror._
+import definitions._
+
+object TagInterop {
+ def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = {
+ val erasure = arrayElementClass(tag)
+ if (erasure.isArray) {
+ val elementClass = arrayElementClass(erasure)
+ val elementManifest = arrayTagToClassManifest(ClassTag(elementClass))
+ ClassManifest.arrayType(elementManifest).asInstanceOf[ClassManifest[T]]
+ } else {
+ ClassManifest.fromClass(erasure.asInstanceOf[Class[T]])
+ }
+ }
+
+ def concreteTypeTagToManifest[T](tag: ConcreteTypeTag[T]): Manifest[T] = {
+ // todo. reproduce manifest generation code here. toolboxes are too slow.
+ val implicitly = PredefModule.typeSignature.member(newTermName("implicitly"))
+ val taggedTpe = appliedType(staticClass("scala.reflect.Manifest").asTypeConstructor, List(tag.tpe))
+ val materializer = TypeApply(Ident(implicitly), List(TypeTree(taggedTpe)))
+ try mkToolBox().runExpr(materializer).asInstanceOf[Manifest[T]]
+ catch { case ex: Throwable => Manifest.classType(tag.erasure).asInstanceOf[Manifest[T]] }
+ }
+
+ def manifestToConcreteTypeTag[T](tag: Manifest[T]): ConcreteTypeTag[T] = {
+ val tpe =
+ if (tag.typeArguments.isEmpty) classToType(tag.erasure)
+ else appliedType(classToType(tag.erasure).typeConstructor, tag.typeArguments map (manifestToConcreteTypeTag(_)) map (_.tpe))
+ ConcreteTypeTag(tpe, tag.erasure)
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/AnnotationInfos.scala b/src/library/scala/reflect/api/AnnotationInfos.scala
index 96a65606e5..cc1c4d2b6b 100755
--- a/src/library/scala/reflect/api/AnnotationInfos.scala
+++ b/src/library/scala/reflect/api/AnnotationInfos.scala
@@ -12,7 +12,7 @@ trait AnnotationInfos { self: Universe =>
}
type ClassfileAnnotArg <: AnyRef
- implicit def classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] // need a precise manifest to pass to UnPickle's toArray call
+ implicit def classfileAnnotArgTag: ArrayTag[ClassfileAnnotArg] // need a precise tag to pass to UnPickle's toArray call
type LiteralAnnotArg <: ClassfileAnnotArg
val LiteralAnnotArg: LiteralAnnotArgExtractor
diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala
new file mode 100644
index 0000000000..50f55b4aa5
--- /dev/null
+++ b/src/library/scala/reflect/api/Attachment.scala
@@ -0,0 +1,29 @@
+package scala.reflect
+package api
+
+/** Attachment is a generalisation of Position.
+ * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads.
+ *
+ * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree
+ * imposing an unnecessary memory tax because of something that will not be used in most cases.
+ */
+trait Attachment {
+ /** Gets the underlying position */
+ def pos: Position
+
+ /** Creates a copy of this attachment with its position updated */
+ def withPos(newPos: Position): Attachment
+
+ /** Gets the underlying payload */
+ def payload: Any
+
+ /** Creates a copy of this attachment with its payload updated */
+ def withPayload(newPayload: Any): Attachment
+}
+
+// [Eugene] with the introduction of `attach` and `attachment[T]` users don't need to create custom attachments anymore
+// however, we cannot move attachments to scala.reflect.internal, because they are used in Trees, which are implemented completely in scala.reflect.api
+private[scala] case class NontrivialAttachment(pos: api.Position, payload: collection.mutable.ListBuffer[Any]) extends Attachment {
+ def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload)
+ def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload.asInstanceOf[collection.mutable.ListBuffer[Any]])
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/ClassLoaders.scala b/src/library/scala/reflect/api/ClassLoaders.scala
new file mode 100644
index 0000000000..7be402d3df
--- /dev/null
+++ b/src/library/scala/reflect/api/ClassLoaders.scala
@@ -0,0 +1,16 @@
+package scala.reflect
+package api
+
+trait ClassLoaders { self: Universe =>
+
+ /** The symbol corresponding to the globally accessible class with the
+ * given fully qualified name `fullName`.
+ */
+ def staticClass(fullName: String): Symbol
+
+ /** The symbol corresponding to the globally accessible object with the
+ * given fully qualified name `fullName`.
+ */
+ def staticModule(fullName: String): Symbol
+
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/api/Exprs.scala
new file mode 100644
index 0000000000..b8db64422e
--- /dev/null
+++ b/src/library/scala/reflect/api/Exprs.scala
@@ -0,0 +1,19 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package api
+import language.implicitConversions
+
+trait Exprs { self: Universe =>
+
+ /** An expression tree tagged with its type */
+ case class Expr[+T: TypeTag](tree: Tree) {
+ def tpe: Type = implicitly[TypeTag[T]].tpe
+ def eval: T = mkToolBox().runExpr(tree).asInstanceOf[T]
+ lazy val value: T = eval
+ override def toString = "Expr["+tpe+"]("+tree+")"
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/FreeVars.scala b/src/library/scala/reflect/api/FreeVars.scala
new file mode 100644
index 0000000000..0bef099a55
--- /dev/null
+++ b/src/library/scala/reflect/api/FreeVars.scala
@@ -0,0 +1,42 @@
+package scala.reflect
+package api
+
+trait FreeVars {
+ self: Universe =>
+
+ /** Represents a free term captured by reification.
+ */
+ type FreeTerm <: Symbol
+
+ val FreeTerm: FreeTermExtractor
+
+ abstract class FreeTermExtractor {
+ def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)]
+ }
+
+ /** Extracts free terms from a tree that is reified or contains reified subtrees.
+ */
+ def freeTerms(tree: Tree): List[FreeTerm]
+
+ /** Represents a free type captured by reification.
+ */
+ type FreeType <: Symbol
+
+ val FreeType: FreeTypeExtractor
+
+ abstract class FreeTypeExtractor {
+ def unapply(freeType: FreeType): Option[(TypeName, Type, String)]
+ }
+
+ /** Extracts free types from a tree that is reified or contains reified subtrees.
+ */
+ def freeTypes(tree: Tree): List[FreeType]
+
+ /** Substitutes free types in a reified tree.
+ */
+ def substituteFreeTypes(tree: Tree, subs: Map[FreeType, Type]): Tree
+
+ /** Substitutes free types in a reified type.
+ */
+ def substituteFreeTypes(tpe: Type, subs: Map[FreeType, Type]): Type
+}
diff --git a/src/library/scala/reflect/api/FrontEnds.scala b/src/library/scala/reflect/api/FrontEnds.scala
new file mode 100644
index 0000000000..2c1f3feff6
--- /dev/null
+++ b/src/library/scala/reflect/api/FrontEnds.scala
@@ -0,0 +1,68 @@
+package scala.reflect
+package api
+
+trait FrontEnds { self: Universe =>
+
+ trait FrontEnd {
+ object severity extends Enumeration
+ class Severity(val id: Int) extends severity.Value {
+ var count: Int = 0
+ override def toString() = this match {
+ case INFO => "INFO"
+ case WARNING => "WARNING"
+ case ERROR => "ERROR"
+ case _ => "<unknown>"
+ }
+ }
+ val INFO = new Severity(0)
+ val WARNING = new Severity(1)
+ val ERROR = new Severity(2)
+
+ def hasErrors = ERROR.count > 0
+ def hasWarnings = WARNING.count > 0
+
+ case class Info(val pos: Position, val msg: String, val severity: Severity)
+ val infos = new collection.mutable.LinkedHashSet[Info]
+
+ /** Handles incoming info */
+ def log(pos: Position, msg: String, severity: Severity) {
+ infos += new Info(pos, msg, severity)
+ severity.count += 1
+ display(infos.last)
+ }
+
+ /** Displays incoming info */
+ def display(info: Info): Unit
+
+ /** Services a request to drop into interactive mode */
+ def interactive(): Unit
+
+ /** Refreshes the UI */
+ def flush(): Unit = {}
+
+ /** Resets the reporter */
+ def reset(): Unit = {
+ INFO.count = 0
+ WARNING.count = 0
+ ERROR.count = 0
+ infos.clear()
+ }
+ }
+
+ class SilentFrontEnd extends FrontEnd {
+ def display(info: Info) {}
+ def interactive() {}
+ }
+
+ /** Creates a UI-less reporter that simply accumulates all the messages
+ */
+ def mkSilentFrontEnd(): FrontEnd = new SilentFrontEnd()
+
+ /** Creates a reporter that prints messages to the console according to the settings.
+ *
+ * ``minSeverity'' determines minimum severity of the messages to be printed.
+ * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR.
+ */
+ // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here!
+ def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/Importers.scala b/src/library/scala/reflect/api/Importers.scala
new file mode 100644
index 0000000000..1d8890b7db
--- /dev/null
+++ b/src/library/scala/reflect/api/Importers.scala
@@ -0,0 +1,19 @@
+package scala.reflect
+package api
+
+trait Importers { self: Universe =>
+
+ def mkImporter(from0: Universe): Importer { val from: from0.type }
+
+ trait Importer {
+ val from: Universe
+
+ val reverse: from.Importer { val from: self.type }
+
+ def importSymbol(sym: from.Symbol): Symbol
+
+ def importType(tpe: from.Type): Type
+
+ def importTree(tree: from.Tree): Tree
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/Mirror.scala b/src/library/scala/reflect/api/Mirror.scala
index cea9e1a37d..ed8ead7aaf 100644
--- a/src/library/scala/reflect/api/Mirror.scala
+++ b/src/library/scala/reflect/api/Mirror.scala
@@ -5,7 +5,22 @@ package api
* runtime entities such as class names and object instances
* with a reflexive universe.
*/
-trait Mirror extends Universe with RuntimeTypes with TreeBuildUtil {
+trait Mirror extends Universe {
+
+ /** Class loader that is a mastermind behind the reflexive mirror.
+ *
+ * By default it is set to system classloader (more precisely, to the classloader that loads the `scala.reflect.package` class).
+ * However, sometimes it is useful to have a mirror services by a custom classloader.
+ *
+ * There are two ways to customize the `classLoader`:
+ * 1) Create a new mirror using the `scala.reflect.mkMirror(classLoader: ClassLoader)` method
+ * 2) Set `classLoader` to the new value
+ *
+ * The first, immutable, way should be strongly preferred in most situation.
+ * However sometimes it is necessary to migrate the default reflexive mirror (`scala.reflect.mirror`) to a new classloader.
+ * In that and only that case, use the setter, but be very careful not to introduce inconsistencies.
+ */
+ var classLoader: ClassLoader
/** The Scala class symbol that has given fully qualified name
* @param name The fully qualified name of the class to be returned
diff --git a/src/library/scala/reflect/api/Names.scala b/src/library/scala/reflect/api/Names.scala
index c72774dfc7..96651ffa88 100755
--- a/src/library/scala/reflect/api/Names.scala
+++ b/src/library/scala/reflect/api/Names.scala
@@ -33,13 +33,13 @@ trait Names {
/** Returns a type name that represents the same string as this name */
def toTypeName: TypeName
- /** Replaces all occurrences of $op_names in this name by corresponding operator symbols.
- * Example: `foo_+=` becomes `foo_$plus$eq`.
+ /** Replaces all occurrences of \$op_names in this name by corresponding operator symbols.
+ * Example: `foo_\$plus\$eq` becomes `foo_+=`
*/
def decoded: String
- /** Replaces all occurrences of operator symbols in this name by corresponding $op_names.
- * Example: `foo_$plus$eq` becomes `foo_+=`
+ /** Replaces all occurrences of operator symbols in this name by corresponding \$op_names.
+ * Example: `foo_+=` becomes `foo_\$plus\$eq`.
*/
def encoded: String
diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala
index 181e7c1525..8f01e0ced1 100644
--- a/src/library/scala/reflect/api/Positions.scala
+++ b/src/library/scala/reflect/api/Positions.scala
@@ -2,8 +2,201 @@ package scala.reflect
package api
trait Positions {
+ self: Universe =>
- type Position
+ // [Eugene] in quite a lot of situations (mostly related to error reporting) we need positions in the API
+ // however it seems that neither runtime compilation, nor macros need facilities to create positions from scratch
+ // both emit ASTs, which can be automatically transformed into synthetic sources and assigned with synthetic positions
+ // hence I added possibilities to inspect everything we can, but add any position factories
+ // this simplified a lot of things, the biggest of them is that we don't need to expose SourceFile/AbstractFile
+ type Position <: scala.reflect.api.Position
val NoPosition: Position
-} \ No newline at end of file
+ /** A position that wraps a set of trees.
+ * The point of the wrapping position is the point of the default position.
+ * If some of the trees are ranges, returns a range position enclosing all ranges
+ * Otherwise returns default position.
+ */
+ def wrappingPos(default: Position, trees: List[Tree]): Position
+
+ /** A position that wraps the non-empty set of trees.
+ * The point of the wrapping position is the point of the first trees' position.
+ * If all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees
+ * Otherwise returns a synthetic offset position to point.
+ */
+ def wrappingPos(trees: List[Tree]): Position
+
+ /** Ensure that given tree has no positions that overlap with
+ * any of the positions of `others`. This is done by
+ * shortening the range or assigning TransparentPositions
+ * to some of the nodes in `tree`.
+ */
+ def ensureNonOverlapping(tree: Tree, others: List[Tree])
+
+ /** Assigns a given position to all position-less nodes of a given AST.
+ */
+ def atPos[T <: Tree](pos: Position)(tree: T): T
+}
+
+/** The Position class and its subclasses represent positions of ASTs and symbols.
+ * Except for NoPosition and FakePos, every position refers to a SourceFile
+ * and to an offset in the sourcefile (its `point`). For batch compilation,
+ * that's all. For interactive IDE's there are also RangePositions
+ * and TransparentPositions. A RangePosition indicates a start and an end
+ * in addition to its point. TransparentPositions are a subclass of RangePositions.
+ * Range positions that are not transparent are called opaque.
+ * Trees with RangePositions need to satisfy the following invariants.
+ *
+ * INV1: A tree with an offset position never contains a child
+ * with a range position
+ * INV2: If the child of a tree with a range position also has a range position,
+ * then the child's range is contained in the parent's range.
+ * INV3: Opaque range positions of children of the same node are non-overlapping
+ * (this means their overlap is at most a single point).
+ *
+ * The following tests are useful on positions:
+ *
+ * pos.isDefined true if position is not a NoPosition nor a FakePosition
+ * pos.isRange true if position is a range
+ * pos.isOpaqueRange true if position is an opaque range
+ *
+ * The following accessor methods are provided:
+ *
+ * pos.source The source file of the position, which must be defined
+ * pos.point The offset of the position's point, which must be defined
+ * pos.start The start of the position, which must be a range
+ * pos.end The end of the position, which must be a range
+ *
+ * There are also convenience methods, such as
+ *
+ * pos.startOrPoint
+ * pos.endOrPoint
+ * pos.pointOrElse(default)
+ *
+ * These are less strict about the kind of position on which they can be applied.
+ *
+ * The following conversion methods are often used:
+ *
+ * pos.focus converts a range position to an offset position, keeping its point;
+ * returns all other positions unchanged.
+ * pos.makeTransparent converts an opaque range position into a transparent one.
+ * returns all other positions unchanged.
+ */
+trait Position extends Attachment {
+
+ /** Java file corresponding to the source file of this position.
+ */
+ def fileInfo: java.io.File
+
+ /** Content of the source file that contains this position.
+ */
+ def fileContent: Array[Char]
+
+ /** Is this position neither a NoPosition nor a FakePosition?
+ * If isDefined is true, offset and source are both defined.
+ */
+ def isDefined: Boolean
+
+ /** Is this position a transparent position? */
+ def isTransparent: Boolean
+
+ /** Is this position a range position? */
+ def isRange: Boolean
+
+ /** Is this position a non-transparent range position? */
+ def isOpaqueRange: Boolean
+
+ /** if opaque range, make this position transparent */
+ def makeTransparent: Position
+
+ /** The start of the position's range, error if not a range position */
+ def start: Int
+
+ /** The start of the position's range, or point if not a range position */
+ def startOrPoint: Int
+
+ /** The point (where the ^ is) of the position */
+ def point: Int
+
+ /** The point (where the ^ is) of the position, or else `default` if undefined */
+ def pointOrElse(default: Int): Int
+
+ /** The end of the position's range, error if not a range position */
+ def end: Int
+
+ /** The end of the position's range, or point if not a range position */
+ def endOrPoint: Int
+
+ /** The same position with a different start value (if a range) */
+ def withStart(off: Int): Position
+
+ /** The same position with a different end value (if a range) */
+ def withEnd(off: Int): Position
+
+ /** The same position with a different point value (if a range or offset) */
+ def withPoint(off: Int): Position
+
+ /** If this is a range, the union with the other range, with the point of this position.
+ * Otherwise, this position
+ */
+ def union(pos: Position): Position
+
+ /** If this is a range position, the offset position of its start.
+ * Otherwise the position itself
+ */
+ def focusStart: Position
+
+ /** If this is a range position, the offset position of its point.
+ * Otherwise the position itself
+ */
+ def focus: Position
+
+ /** If this is a range position, the offset position of its end.
+ * Otherwise the position itself
+ */
+ def focusEnd: Position
+
+ /** Does this position include the given position `pos`.
+ * This holds if `this` is a range position and its range [start..end]
+ * is the same or covers the range of the given position, which may or may not be a range position.
+ */
+ def includes(pos: Position): Boolean
+
+ /** Does this position properly include the given position `pos` ("properly" meaning their
+ * ranges are not the same)?
+ */
+ def properlyIncludes(pos: Position): Boolean
+
+ /** Does this position precede that position?
+ * This holds if both positions are defined and the end point of this position
+ * is not larger than the start point of the given position.
+ */
+ def precedes(pos: Position): Boolean
+
+ /** Does this position properly precede the given position `pos` ("properly" meaning their ranges
+ * do not share a common point).
+ */
+ def properlyPrecedes(pos: Position): Boolean
+
+ /** Does this position overlap with that position?
+ * This holds if both positions are ranges and there is an interval of
+ * non-zero length that is shared by both position ranges.
+ */
+ def overlaps(pos: Position): Boolean
+
+ /** Does this position cover the same range as that position?
+ * Holds only if both position are ranges
+ */
+ def sameRange(pos: Position): Boolean
+
+ def line: Int
+
+ def column: Int
+
+ /** Convert this to a position around `point` that spans a single source line */
+ def toSingleLine: Position
+
+ def lineContent: String
+
+ def show: String
+}
diff --git a/src/library/scala/reflect/api/RuntimeTypes.scala b/src/library/scala/reflect/api/RuntimeTypes.scala
deleted file mode 100644
index f58b328868..0000000000
--- a/src/library/scala/reflect/api/RuntimeTypes.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-package scala.reflect
-package api
-
-/** A mirror establishes connections of
- * runtime entities such as class names and object instances
- * with a refexive universe.
- */
-private[reflect] trait RuntimeTypes extends Universe {
-
- type InstanceRefSymbol >: Null <: Symbol
-
- val InstanceRefSymbol: InstanceRefSymbolExtractor
-
- private[reflect] def namedType(pre: Type, sym: Symbol, args: List[Type]): Type
-
- abstract class InstanceRefSymbolExtractor {
- def apply(value: AnyRef): InstanceRefSymbol
- def unapply(tpe: InstanceRefSymbol): Option[AnyRef]
- }
-}
diff --git a/src/library/scala/reflect/api/Scopes.scala b/src/library/scala/reflect/api/Scopes.scala
index d4e4e24f29..4a5702eadc 100755
--- a/src/library/scala/reflect/api/Scopes.scala
+++ b/src/library/scala/reflect/api/Scopes.scala
@@ -5,7 +5,12 @@ trait Scopes { self: Universe =>
type Scope <: Iterable[Symbol]
- def newScope(): Scope
-}
+ /** Create a new scope */
+ def newScope: Scope
+ /** Create a new scope nested in another one with which it shares its elements */
+ def newNestedScope(outer: Scope): Scope
+ /** Create a new scope with given initial elements */
+ def newScopeWith(elems: Symbol*): Scope
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala
index c3d989f971..21f7c9283b 100755
--- a/src/library/scala/reflect/api/StandardDefinitions.scala
+++ b/src/library/scala/reflect/api/StandardDefinitions.scala
@@ -6,55 +6,131 @@
package scala.reflect
package api
-trait StandardDefinitions { self: Universe =>
+trait StandardTypes {
+ self: Universe =>
+
+ val ByteTpe: Type
+ val ShortTpe: Type
+ val CharTpe: Type
+ val IntTpe: Type
+ val LongTpe: Type
+ val FloatTpe: Type
+ val DoubleTpe: Type
+ val BooleanTpe: Type
+ val UnitTpe: Type
+
+ val AnyTpe: Type
+ val AnyValTpe: Type
+ val AnyRefTpe: Type
+ val ObjectTpe: Type
+
+ val NothingTpe: Type
+ val NullTpe: Type
+ val StringTpe: Type
+}
+
+trait StandardDefinitions extends StandardTypes {
+ self: Universe =>
val definitions: AbsDefinitions
- abstract class AbsDefinitions {
+ // I intend to pull everything in here out of the public API.
+ trait AbsDefinitionsInternal {
+ def ArrayModule: Symbol
+ def ArrayModule_overloadedApply: Symbol
+ def Array_apply: Symbol
+ def Array_clone: Symbol
+ def Array_length: Symbol
+ def Array_update: Symbol
+ def ByNameParamClass: Symbol
+ def ClassTagModule: Symbol
+ def ConcreteTypeTagModule: Symbol
+ def ConsClass: Symbol
+ def EmptyPackageClass: Symbol
+ def FunctionClass : Array[Symbol]
+ def IterableClass: Symbol
+ def IteratorClass: Symbol
+ def IteratorModule: Symbol
+ def Iterator_apply: Symbol
+ def JavaLangPackageClass: Symbol
+ def JavaRepeatedParamClass: Symbol
+ def ListModule: Symbol
+ def List_apply: Symbol
+ def NilModule: Symbol
+ def NoneModule: Symbol
+ def OptionClass: Symbol
+ def ProductClass : Array[Symbol]
+ def RepeatedParamClass: Symbol
+ def ScalaPackageClass: Symbol
+ def SeqClass: Symbol
+ def SeqModule: Symbol
+ def SomeClass: Symbol
+ def SomeModule: Symbol
+ def StringBuilderClass: Symbol
+ def SymbolClass : Symbol
+ def TraversableClass: Symbol
+ def TupleClass : Array[Symbol]
+ def TypeTagModule: Symbol
+ def ScalaPrimitiveValueClasses: List[ClassSymbol]
+ }
+
+ trait AbsDefinitions extends AbsDefinitionsInternal {
// packages
- def RootPackage: Symbol
- def RootClass: Symbol
- def EmptyPackage: Symbol
- def ScalaPackage: Symbol
+ def RootClass: ClassSymbol
+ def RootPackage: PackageSymbol
+ def EmptyPackage: PackageSymbol
+ def ScalaPackage: PackageSymbol
+ def JavaLangPackage: PackageSymbol
// top types
- def AnyClass : Symbol
- def AnyValClass: Symbol
- def AnyRefClass: Symbol
- def ObjectClass: Symbol
+ def AnyClass : ClassSymbol
+ def AnyValClass: ClassSymbol
+ def ObjectClass: ClassSymbol
+ def AnyRefClass: TypeSymbol
// bottom types
- def NullClass : Symbol
- def NothingClass: Symbol
+ def NullClass : ClassSymbol
+ def NothingClass: ClassSymbol
// the scala value classes
- def UnitClass : Symbol
- def ByteClass : Symbol
- def ShortClass : Symbol
- def CharClass : Symbol
- def IntClass : Symbol
- def LongClass : Symbol
- def FloatClass : Symbol
- def DoubleClass : Symbol
- def BooleanClass: Symbol
-
- // fundamental reference classes
- def SymbolClass : Symbol
- def StringClass : Symbol
- def ClassClass : Symbol
+ def UnitClass : ClassSymbol
+ def ByteClass : ClassSymbol
+ def ShortClass : ClassSymbol
+ def CharClass : ClassSymbol
+ def IntClass : ClassSymbol
+ def LongClass : ClassSymbol
+ def FloatClass : ClassSymbol
+ def DoubleClass : ClassSymbol
+ def BooleanClass: ClassSymbol
- // product, tuple, function
- def TupleClass : Array[Symbol]
- def ProductClass : Array[Symbol]
- def FunctionClass : Array[Symbol]
+ // some special classes
+ def StringClass : ClassSymbol
+ def ClassClass : ClassSymbol
+ def ArrayClass: ClassSymbol
+
+ // collections classes
+ def ListClass: ClassSymbol
+ def ListModule: ModuleSymbol
+
+ // collections modules
+ def PredefModule: ModuleSymbol
- // fundamental modules
- def PredefModule: Symbol
+ // type tags
+ def ClassTagClass: ClassSymbol
+ def TypeTagClass: ClassSymbol
+ def ConcreteTypeTagClass: ClassSymbol
/** Given a type T, returns the type corresponding to the VM's
* representation: ClassClass's type constructor applied to `arg`.
*/
def vmClassType(arg: Type): Type // !!! better name?
+ // [Eugene] we already have arg.erasure, right?
+ //
+ // [Paul] You misunderstand the method (it could be better named).
+ // Given List[String], it returns java.lang.Class[List[String]]
+ // (or the .Net equivalent), not the erasure of List[String].
+ // See def ClassType in definitions - that's what it was called before,
+ // and obviously that name has to go.
/** The string representation used by the given type in the VM.
*/
diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala
index 81517d2a6b..60c64f947a 100644
--- a/src/library/scala/reflect/api/StandardNames.scala
+++ b/src/library/scala/reflect/api/StandardNames.scala
@@ -1,21 +1,164 @@
/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Martin Odersky
- */
+* Copyright 2005-2011 LAMP/EPFL
+* @author Martin Odersky
+*/
package scala.reflect
package api
-trait StandardNames { self: Universe =>
+trait StandardNames {
+ self: Universe =>
val nme: AbsTermNames
+ val tpnme: AbsTypeNames
+
+ trait AbsNames {
+ type NameType <: Name
+
+ val ANON_CLASS_NAME: NameType
+ val ANON_FUN_NAME: NameType
+ val EMPTY: NameType
+ val EMPTY_PACKAGE_NAME: NameType
+ val ERROR: NameType
+ val IMPORT: NameType
+ val MODULE_VAR_SUFFIX: NameType
+ val NO_NAME: NameType
+ val PACKAGE: NameType
+ val ROOT: NameType
+ val SPECIALIZED_SUFFIX: NameType
+ val WILDCARD: NameType
+
+ def flattenedName(segments: Name*): NameType
+ }
+
+ trait AbsTermNames extends AbsNames {
+ val EXPAND_SEPARATOR_STRING: String
+ val IMPL_CLASS_SUFFIX: String
+ val INTERPRETER_IMPORT_WRAPPER: String
+ val INTERPRETER_LINE_PREFIX: String
+ val INTERPRETER_VAR_PREFIX: String
+ val INTERPRETER_WRAPPER_SUFFIX: String
+ val LOCALDUMMY_PREFIX: String
+ val LOCAL_SUFFIX_STRING: String
+ val MODULE_SUFFIX_NAME: TermName
+ val NAME_JOIN_NAME: TermName
+ val PROTECTED_PREFIX: String
+ val PROTECTED_SET_PREFIX: String
+ val SETTER_SUFFIX: TermName
+ val SINGLETON_SUFFIX: String
+ val SUPER_PREFIX_STRING: String
+ val TRAIT_SETTER_SEPARATOR_STRING: String
- abstract class AbsTermNames {
+ val ANYNAME: TermName
val CONSTRUCTOR: TermName
+ val FAKE_LOCAL_THIS: TermName
+ val INITIALIZER: TermName
+ val LAZY_LOCAL: TermName
+ val MIRROR_FREE_PREFIX: TermName
+ val MIRROR_FREE_THIS_SUFFIX: TermName
+ val MIRROR_FREE_VALUE_SUFFIX: TermName
+ val MIRROR_PREFIX: TermName
+ val MIRROR_SHORT: TermName
+ val MIRROR_SYMDEF_PREFIX: TermName
+ val MIXIN_CONSTRUCTOR: TermName
+ val MODULE_INSTANCE_FIELD: TermName
+ val OUTER: TermName
+ val OUTER_LOCAL: TermName
+ val OUTER_SYNTH: TermName
+ val SELECTOR_DUMMY: TermName
+ val SELF: TermName
+ val SPECIALIZED_INSTANCE: TermName
+ val STAR: TermName
+ val THIS: TermName
+
+ val BITMAP_NORMAL: TermName
+ val BITMAP_TRANSIENT: TermName
+ val BITMAP_PRIVATE: TermName
+ val BITMAP_CHECKINIT: TermName
+ val BITMAP_CHECKINIT_TRANSIENT: TermName
+
+ val ROOTPKG: TermName
+
+ val ADD: TermName
+ val AND: TermName
+ val ASR: TermName
+ val DIV: TermName
+ val EQ: TermName
+ val EQL: TermName
+ val GE: TermName
+ val GT: TermName
+ val HASHHASH: TermName
+ val LE: TermName
+ val LSL: TermName
+ val LSR: TermName
+ val LT: TermName
+ val MINUS: TermName
+ val MOD: TermName
+ val MUL: TermName
+ val NE: TermName
+ val OR: TermName
+ val PLUS : TermName
+ val SUB: TermName
+ val XOR: TermName
+ val ZAND: TermName
+ val ZOR: TermName
+
+ val UNARY_~ : TermName
+ val UNARY_+ : TermName
+ val UNARY_- : TermName
+ val UNARY_! : TermName
+
+ val ??? : TermName
+
+ def isConstructorName(name: Name): Boolean
+ def isExceptionResultName(name: Name): Boolean
+ def isImplClassName(name: Name): Boolean
+ def isLocalDummyName(name: Name): Boolean
+ def isLocalName(name: Name): Boolean
+ def isLoopHeaderLabel(name: Name): Boolean
+ def isModuleName(name: Name): Boolean
+ def isOpAssignmentName(name: Name): Boolean
+ def isProtectedAccessorName(name: Name): Boolean
+ def isReplWrapperName(name: Name): Boolean
+ def isSetterName(name: Name): Boolean
+ def isSingletonName(name: Name): Boolean
+ def isSuperAccessorName(name: Name): Boolean
+ def isTraitSetterName(name: Name): Boolean
+
+ def defaultGetterName(name: Name, pos: Int): TermName
+ def defaultGetterToMethod(name: Name): TermName
+ def expandedName(name: TermName, base: Symbol, separator: String): TermName
+ def expandedSetterName(name: TermName, base: Symbol): TermName
+ def getterName(name: TermName): TermName
+ def getterToLocal(name: TermName): TermName
+ def getterToSetter(name: TermName): TermName
+ def localDummyName(clazz: Symbol): TermName
+ def localToGetter(name: TermName): TermName
+ def protName(name: Name): TermName
+ def protSetterName(name: Name): TermName
+ def setterToGetter(name: TermName): TermName
+ def superName(name: Name): TermName
+
+ def dropLocalSuffix(name: Name): Name
+ def originalName(name: Name): Name
+ def stripModuleSuffix(name: Name): Name
+ def unspecializedName(name: Name): Name
+ def segments(name: String, assumeTerm: Boolean): List[Name]
+ def splitSpecializedName(name: Name): (Name, String, String)
}
- val tpnme: AbsTypeNames
+ trait AbsTypeNames extends AbsNames {
+ val BYNAME_PARAM_CLASS_NAME: TypeName
+ val EQUALS_PATTERN_NAME: TypeName
+ val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName
+ val LOCAL_CHILD: TypeName
+ val REFINE_CLASS_NAME: TypeName
+ val REPEATED_PARAM_CLASS_NAME: TypeName
+ val WILDCARD_STAR: TypeName
- abstract class AbsTypeNames {
+ def dropSingletonName(name: Name): TypeName
+ def implClassName(name: Name): TypeName
+ def interfaceName(implname: Name): TypeName
+ def singletonName(name: Name): TypeName
}
}
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index 44dc2ce1c2..dbd264c0ab 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -4,8 +4,105 @@ package api
trait Symbols { self: Universe =>
type Symbol >: Null <: AbsSymbol
+ type TypeSymbol <: Symbol with TypeSymbolApi
+ type TermSymbol <: Symbol with TermSymbolApi
+ type MethodSymbol <: TermSymbol with MethodSymbolApi
+ type ModuleSymbol <: TermSymbol with ModuleSymbolApi
+ type PackageSymbol <: ModuleSymbol with PackageSymbolApi
+ type ClassSymbol <: TypeSymbol with ClassSymbolApi
- abstract class AbsSymbol { this: Symbol =>
+ val NoSymbol: Symbol
+
+ trait TypeSymbolApi {
+ self: TypeSymbol =>
+
+ def name: TypeName
+ }
+ trait TermSymbolApi {
+ self: TermSymbol =>
+
+ def name: TermName
+ }
+ trait MethodSymbolApi extends TermSymbolApi {
+ self: MethodSymbol =>
+ }
+ trait ClassSymbolApi extends TypeSymbolApi {
+ self: ClassSymbol =>
+ }
+ trait ModuleSymbolApi extends TermSymbolApi {
+ self: ModuleSymbol =>
+ }
+ trait PackageSymbolApi extends ModuleSymbolApi {
+ self: PackageSymbol =>
+ }
+
+ // I intend to pull everything in here out of the public API.
+ trait AbsSymbolInternal {
+ this: Symbol =>
+
+ /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
+ * the current symbol as its owner.
+ */
+ def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol
+ // needed by LiftCode !!! not enough reason to have in the api
+
+ /** Low-level operation to set the symbol's flags
+ * @return the symbol itself
+ */
+ def setInternalFlags(flags: Long): this.type
+ // needed by LiftCode !!! not enough reason to have in the api
+
+ /** Set symbol's type signature to given type
+ * @return the symbol itself
+ */
+ def setTypeSignature(tpe: Type): this.type
+ // needed by LiftCode !!! not enough reason to have in the api
+
+ /** Set symbol's annotations to given annotations `annots`.
+ */
+ def setAnnotations(annots: AnnotationInfo*): this.type
+ // needed by LiftCode !!! not enough reason to have in the api
+
+ /** Does this symbol represent the definition of a skolem?
+ * Skolems are used during typechecking to represent type parameters viewed from inside their scopes.
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isSkolem : Boolean
+
+ /** Does this symbol represent a free type captured by reification?
+ */
+ // needed for ones who wish to inspect reified trees
+ def isFreeType : Boolean
+
+ /** The type signature of this symbol.
+ * Note if the symbol is a member of a class, one almost always is interested
+ * in `typeSignatureIn` with a site type instead.
+ */
+ def typeSignature: Type // !!! Since one should almost never use this, let's give it a different name.
+
+ /** A type reference that refers to this type symbol
+ * Note if symbol is a member of a class, one almost always is interested
+ * in `asTypeIn` with a site type instead.
+ *
+ * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
+ * `C`. Then `C.asType` is the type `C[T]`.
+ *
+ * By contrast, `C.typeSignature` would be a type signature of form
+ * `PolyType(ClassInfoType(...))` that describes type parameters, value
+ * parameters, parent types, and members of `C`.
+ */
+ def asType: Type // !!! Same as typeSignature.
+
+ /** The kind of this symbol; used for debugging */
+ def kind: String
+ }
+
+ trait AbsSymbol extends AbsSymbolInternal {
+ this: Symbol =>
+
+ /** The position of this symbol
+ */
+ def pos: Position
/** The modifiers of this symbol
*/
@@ -47,6 +144,18 @@ trait Symbols { self: Universe =>
/** An id number which is unique for all symbols in this universe */
def id: Int
+ /** ...
+ */
+ def orElse[T](alt: => Symbol): Symbol
+
+ /** ...
+ */
+ def filter(cond: Symbol => Boolean): Symbol
+
+ /** ...
+ */
+ def suchThat(cond: Symbol => Boolean): Symbol
+
/**
* Set when symbol has a modifier of the form private[X], NoSymbol otherwise.
*
@@ -112,6 +221,25 @@ trait Symbols { self: Universe =>
*/
def isTerm : Boolean
+ /** Does this symbol represent a package?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isPackage : Boolean
+
+ /** Does this symbol represent the definition of method?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isMethod : Boolean
+
+ /** Is this symbol an overloaded method?
+ */
+ def isOverloaded : Boolean
+
+ /** Does this symbol represent a free term captured by reification?
+ */
+ // needed for ones who wish to inspect reified trees
+ def isFreeTerm : Boolean
+
/** Does this symbol represent the definition of type?
* Note that every symbol is either a term or a type.
* So for every symbol `sym`, either `sym.isTerm` is true
@@ -124,6 +252,22 @@ trait Symbols { self: Universe =>
*/
def isClass : Boolean
+ /** Does this symbol represent a package class?
+ * If yes, `isClass` is also guaranteed to be true.
+ */
+ def isPackageClass : Boolean
+
+ /** Does this symbol represent the definition of a primitive class?
+ * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]],
+ * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]?
+ */
+ def isPrimitiveValueClass: Boolean
+
+ /** Does this symbol represent the definition of a custom value class?
+ * Namely, is AnyVal among its parent classes?
+ */
+ def isDerivedValueClass: Boolean
+
/** Does this symbol represent the definition of a type alias?
* If yes, `isType` is also guaranteed to be true.
*/
@@ -134,28 +278,26 @@ trait Symbols { self: Universe =>
*/
def isAbstractType : Boolean
- /** The type signature of this symbol.
- * Note if the symbol is a member of a class, one almost always is interested
- * in `typeSignatureIn` with a site type instead.
+ /** Does this symbol represent an existentially bound type?
+ * If yes, `isType` is also guaranteed to be true.
*/
- def typeSignature: Type // !!! Since one should almost never use this, let's give it a different name.
+ def isExistential : Boolean
- /** The type signature of this symbol seen as a member of given type `site`.
+ /** Is the type parameter represented by this symbol contravariant?
*/
- def typeSignatureIn(site: Type): Type
+ def isContravariant : Boolean
- /** A type reference that refers to this type symbol
- * Note if symbol is a member of a class, one almost always is interested
- * in `asTypeIn` with a site type instead.
- *
- * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
- * `C`. Then `C.asType` is the type `C[T]`.
- *
- * By contrast, `C.typeSignature` would be a type signature of form
- * `PolyType(ClassInfoType(...))` that describes type parameters, value
- * parameters, parent types, and members of `C`.
+ /** Is the type parameter represented by this symbol contravariant?
+ */
+ def isCovariant : Boolean
+
+ /** Does this symbol or its underlying type represent a typechecking error?
+ */
+ def isErroneous : Boolean
+
+ /** The type signature of this symbol seen as a member of given type `site`.
*/
- def asType: Type // !!! Same as typeSignature.
+ def typeSignatureIn(site: Type): Type
/** A type reference that refers to this type symbol seen
* as a member of given type `site`.
@@ -180,25 +322,9 @@ trait Symbols { self: Universe =>
*/
def selfType: Type
- /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
- * the current symbol as its owner.
- */
- def newNestedSymbol(name: Name, pos: Position, flags: Long): Symbol // needed by LiftCode
+ /** The overloaded alternatives of this symbol */
+ def alternatives: List[Symbol]
- /** Low-level operation to set the symbol's flags
- * @return the symbol itself
- */
- def setInternalFlags(flags: Long): this.type // needed by LiftCode !!! not enough reason to have in the api
-
- /** Set symbol's type signature to given type
- * @return the symbol itself
- */
- def setTypeSignature(tpe: Type): this.type // needed by LiftCode !!! not enough reason to have in the api
-
- /** Set symbol's annotations to given annotations `annots`.
- */
- def setAnnotations(annots: AnnotationInfo*): this.type // needed by LiftCode !!! not enough reason to have in the api
+ def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol
}
-
- val NoSymbol: Symbol
}
diff --git a/src/library/scala/reflect/api/ToolBoxes.scala b/src/library/scala/reflect/api/ToolBoxes.scala
new file mode 100644
index 0000000000..aefd6b511c
--- /dev/null
+++ b/src/library/scala/reflect/api/ToolBoxes.scala
@@ -0,0 +1,90 @@
+package scala.reflect
+package api
+
+trait ToolBoxes { self: Universe =>
+
+ type ToolBox <: AbsToolBox
+
+ def mkToolBox(frontEnd: FrontEnd = mkSilentFrontEnd(), options: String = ""): AbsToolBox
+
+ // [Eugene] what do you think about the interface? namely about the ``freeTypes'' part.
+ trait AbsToolBox {
+
+ /** Front end of the toolbox.
+ *
+ * Accumulates and displays warnings and errors, can drop to interactive mode (if supported).
+ * The latter can be useful to study the typechecker or to debug complex macros.
+ */
+ def frontEnd: FrontEnd
+
+ /** Typechecks a tree using this ToolBox.
+ * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings.
+ *
+ * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols),
+ * then they might, might be partially or might not be specified in the ``freeTypes'' parameter.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Ydebug.
+ *
+ * Typechecking can be steered with the following optional parameters:
+ * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false
+ * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false
+ */
+ def typeCheck(tree: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree
+
+ /** Infers an implicit value of the expected type ``pt'' in the macro callsite context.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
+ * Unlike in ``typeCheck'', ``silent'' is true by default.
+ */
+ def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree
+
+ /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context.
+ *
+ * Otional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported.
+ * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
+ * Unlike in ``typeCheck'', ``silent'' is true by default.
+ */
+ def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree
+
+ /** Recursively resets symbols and types in a given tree.
+ *
+ * Note that this does not revert the tree to its pre-typer shape.
+ * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ */
+ def resetAllAttrs[T <: Tree](tree: T): T
+
+ /** Recursively resets locally defined symbols and types in a given tree.
+ *
+ * Note that this does not revert the tree to its pre-typer shape.
+ * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ */
+ def resetLocalAttrs[T <: Tree](tree: T): T
+
+ /** Compiles and runs a tree using this ToolBox.
+ *
+ * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols),
+ * then they all have to be specified in the ``freeTypes'' parameter or an error occurs.
+ *
+ * This spawns the compiler at the Namer phase, and pipelines the tree through that compiler.
+ * Currently ``runExpr'' does not accept trees that already typechecked, because typechecking isn't idempotent.
+ * For more info, take a look at https://issues.scala-lang.org/browse/SI-5464.
+ */
+ def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any
+
+ /** Represents an error during toolboxing
+ */
+ type ToolBoxError <: Throwable
+ val ToolBoxError: ToolBoxErrorExtractor
+ abstract class ToolBoxErrorExtractor {
+ def unapply(error: ToolBoxError): Option[(ToolBox, String)]
+ }
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala
index f28008bc21..87790b3812 100644
--- a/src/library/scala/reflect/api/TreeBuildUtil.scala
+++ b/src/library/scala/reflect/api/TreeBuildUtil.scala
@@ -1,46 +1,159 @@
-package scala.reflect.api
+package scala.reflect
+package api
-trait TreeBuildUtil extends Universe {
+trait TreeBuildUtil { self: Universe =>
- /** The symbol corresponding to the globally accessible class with the
- * given fully qualified name `fullName`.
+ /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`.
+ * Unlike `staticClassIfDefined`, throws `MissingRequirementError` is requested class cannot be found.
*/
def staticClass(fullName: String): Symbol
- /** The symbol corresponding to the globally accessible object with the
- * given fully qualified name `fullName`.
+ /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`.
+ * Unlike `staticClass`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested class cannot be found.
+ */
+ def staticClassIfDefined(fullName: String): Symbol
+
+ /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`.
+ * Unlike `staticModuleIfDefined`, throws `MissingRequirementError` is requested object cannot be found.
*/
def staticModule(fullName: String): Symbol
+ /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`.
+ * Unlike `staticModule`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested object cannot be found.
+ */
+ def staticModuleIfDefined(fullName: String): Symbol
+
/** The this-ptype of the globally accessible object with the
* given fully qualified name `fullName`.
*/
def thisModuleType(fullName: String): Type
/** Selects type symbol with given simple name `name` from the defined members of `owner`.
+ * Unlike `selectTypeIfDefined`, throws `MissingRequirementError` is requested type symbol cannot be found.
*/
def selectType(owner: Symbol, name: String): Symbol
+ /** Selects type symbol with given simple name `name` from the defined members of `owner`.
+ * Unlike `selectType`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested type symbol cannot be found.
+ */
+ def selectTypeIfDefined(owner: Symbol, name: String): Symbol
+
/** Selects term symbol with given name and type from the defined members of prefix type
- * @pre The prefix type
- * @name The name of the selected member
+ * Unlike `selectTermIfDefined`, throws `MissingRequirementError` is requested term symbol cannot be found.
*/
def selectTerm(owner: Symbol, name: String): Symbol
- def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol
+ /** Selects term symbol with given name and type from the defined members of prefix type
+ * Unlike `selectTerm`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested term symbol cannot be found.
+ */
+ def selectTermIfDefined(owner: Symbol, name: String): Symbol
- def selectParam(owner: Symbol, idx: Int): Symbol
+ /** Selects overloaded method symbol with given name and index
+ * Unlike `selectOverloadedMethodIfDefined`, throws `MissingRequirementError` is requested overloaded method cannot be found.
+ */
+ def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol
- def newScopeWith(decls: Symbol*): Scope
+ /** Selects overloaded method symbol with given name and index
+ * Unlike `selectOverloadedMethod`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested overloaded method cannot be found.
+ */
+ def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol
- /** Create a fresh free variable symbol.
+ /** Create a fresh free term symbol.
* @param name the name of the free variable
- * @param tsig the type signature of the free variable
+ * @param info the type signature of the free variable
* @param value the value of the free variable at runtime
+ * @param flags (optional) flags of the free variable
+ * @param origin debug information that tells where this symbol comes from
+ */
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
+
+ /** Create a fresh free non-existential type symbol.
+ * @param name the name of the free variable
+ * @param info the type signature of the free variable
+ * @param value a type tag that captures the value of the free variable
+ * is completely phantom, since the captured type cannot be propagated to the runtime
+ * if it could be, we wouldn't be creating a free type to begin with
+ * the only usage for it is preserving the captured symbol for compile-time analysis
+ * @param flags (optional) flags of the free variable
+ * @param origin debug information that tells where this symbol comes from
*/
- def newFreeVar(name: String, info: Type, value: Any): Symbol
+ def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
+
+ /** Create a fresh free existential type symbol.
+ * @param name the name of the free variable
+ * @param info the type signature of the free variable
+ * @param value a type tag that captures the value of the free variable
+ * is completely phantom, since the captured type cannot be propagated to the runtime
+ * if it could be, we wouldn't be creating a free type to begin with
+ * the only usage for it is preserving the captured symbol for compile-time analysis
+ * @param flags (optional) flags of the free variable
+ * @param origin (optional) debug information that tells where this symbol comes from
+ */
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
/** Create a Modiiers structure given internal flags, qualifier, annotations */
def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers
-} \ No newline at end of file
+ val gen: TreeGen { val global: TreeBuildUtil.this.type }
+
+ type TreeGen <: AbsTreeGen
+}
+
+// [Eugene to Paul] we need to expose some of the functionality provided by TreeGen
+// I added some stuff that was necessary for typetag materialization macros
+// but we should think it over and pick other generally useful stuff
+// same goes for tree traversers/transformers, type maps, etc
+// and once we expose all that, there's another question: how do we stay in sync?
+trait AbsTreeGen {
+ val global: Universe
+
+ import global._
+ import definitions._
+
+ /** Builds a reference to value whose type is given stable prefix.
+ * The type must be suitable for this. For example, it
+ * must not be a TypeRef pointing to an abstract type variable.
+ */
+ def mkAttributedQualifier(tpe: Type): Tree
+
+ /** Builds a reference to value whose type is given stable prefix.
+ * If the type is unsuitable, e.g. it is a TypeRef for an
+ * abstract type variable, then an Ident will be made using
+ * termSym as the Ident's symbol. In that case, termSym must
+ * not be NoSymbol.
+ */
+ def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree
+
+ /** Builds a typed reference to given symbol with given stable prefix. */
+ def mkAttributedRef(pre: Type, sym: Symbol): Tree
+
+ /** Builds a typed reference to given symbol. */
+ def mkAttributedRef(sym: Symbol): Tree
+
+ /** Builds a typed This reference to given symbol. */
+ def mkAttributedThis(sym: Symbol): Tree
+
+ /** Builds a typed Ident with an underlying symbol. */
+ def mkAttributedIdent(sym: Symbol): Tree
+
+ /** Builds a typed Select with an underlying symbol. */
+ def mkAttributedSelect(qual: Tree, sym: Symbol): Tree
+
+ /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...)
+ * There are a number of variations.
+ *
+ * @param receiver symbol of the method receiver
+ * @param methodName name of the method to call
+ * @param targs type arguments (if Nil, no TypeApply node will be generated)
+ * @param args value arguments
+ * @return the newly created trees.
+ */
+ def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree
+ def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree
+ def mkMethodCall(method: Symbol, args: List[Tree]): Tree
+ def mkMethodCall(target: Tree, args: List[Tree]): Tree
+ def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree
+ def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree
+ def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree
+ def mkNullaryCall(method: Symbol, targs: List[Type]): Tree
+}
diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala
index 43865915d3..3d64ec8e40 100644
--- a/src/library/scala/reflect/api/TreePrinters.scala
+++ b/src/library/scala/reflect/api/TreePrinters.scala
@@ -29,17 +29,21 @@ trait TreePrinters { self: Universe =>
def newTreePrinter(out: PrintWriter): TreePrinter
// emits more or less verbatim representation of the provided tree
- // todo. when LiftCode becomes a macro, throw this code away and use that macro
class RawTreePrinter(out: PrintWriter) extends TreePrinter {
+ val EmptyValDef = self.emptyValDef
def print(args: Any*): Unit = args foreach {
case EmptyTree =>
print("EmptyTree")
+ case EmptyValDef =>
+ print("emptyValDef")
case tree @ TypeTree() =>
print("TypeTree()")
if (tree.tpe != null)
print(".setType(", tree.tpe, ")")
else if (tree.original != null)
print(".setOriginal(", tree.original, ")")
+ case Literal(Constant(s: String)) =>
+ print("Literal(Constant(\"" + s + "\"))")
case tree: Tree =>
print(tree.printingPrefix+"(")
val it = tree.productIterator
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 466c380cef..9f8906a8cd 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -14,6 +14,7 @@ trait Trees { self: Universe =>
private[scala] var nodeCount = 0
type Modifiers >: Null <: AbsModifiers
+ val NoMods: Modifiers
abstract class AbsModifiers {
def modifiers: Set[Modifier]
@@ -74,17 +75,49 @@ trait Trees { self: Universe =>
val id = nodeCount
nodeCount += 1
- private[this] var rawpos: Position = NoPosition
-
/** Prefix under which to print this tree type. Defaults to product
* prefix (e.g. DefTree) but because that is used in reification
* it cannot be altered without breaking reflection.
*/
def printingPrefix = productPrefix
- def pos = rawpos
- def pos_=(pos: Position) = rawpos = pos
- def setPos(pos: Position): this.type = { rawpos = pos; this }
+ def pos: Position = rawatt.pos.asInstanceOf[Position] // [Eugene] how do we get rid of this cast?
+ def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness
+ def setPos(newpos: Position): this.type = { pos = newpos; this }
+
+ // [Eugene] can we make this more type-safe
+ private var rawatt: Attachment = NoPosition
+ def attach(att: Any): Unit =
+ rawatt match {
+ case NontrivialAttachment(pos, payload) =>
+ val index = payload.indexWhere(p => p.getClass == att.getClass)
+ if (index == -1) payload += att
+ else payload(index) = att
+ case _ =>
+ rawatt = NontrivialAttachment(pos, collection.mutable.ListBuffer[Any](att))
+ }
+ def withAttachment(att: Any): this.type = { attach(att); this }
+ def detach(att: Any): Unit =
+ detach(att.getClass)
+ def detach(clazz: java.lang.Class[_]): Unit =
+ rawatt match {
+ case NontrivialAttachment(pos, payload) =>
+ val index = payload.indexWhere(p => p.getClass == clazz)
+ if (index != -1) payload.remove(index)
+ case _ =>
+ // do nothing
+ }
+ def withoutAttachment(att: Any): this.type = { detach(att); this }
+ def attachment[T: ClassTag]: T = attachmentOpt[T] getOrElse { throw new Error("no attachment of type %s".format(classTag[T].erasure)) }
+ def attachmentOpt[T: ClassTag]: Option[T] =
+ rawatt match {
+ case NontrivialAttachment(pos, payload) =>
+ val index = payload.indexWhere(p => p.getClass == classTag[T].erasure)
+ if (index != -1) Some(payload(index).asInstanceOf[T])
+ else None
+ case _ =>
+ None
+ }
private[this] var rawtpe: Type = _
@@ -136,6 +169,7 @@ trait Trees { self: Universe =>
def hasSymbol = false
def isDef = false
def isEmpty = false
+ def orElse(alt: => Tree) = if (!isEmpty) this else alt
def hasSymbolWhich(f: Symbol => Boolean) = hasSymbol && f(symbol)
@@ -172,6 +206,13 @@ trait Trees { self: Universe =>
}
def filter(f: Tree => Boolean): List[Tree] = withFilter(f)
+ /** Apply `pf' to each subtree on which the function is defined */
+ def collect[T](pf: PartialFunction[Tree, T]): List[T] = {
+ val ctt = new CollectTreeTraverser[T](pf)
+ ctt.traverse(this)
+ ctt.results.toList
+ }
+
/** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p`,
* or None if none exists.
*/
@@ -181,9 +222,12 @@ trait Trees { self: Universe =>
ft.result
}
- /** Is there part of this tree which satisfies predicate `p`? */
+ /** Is there exists a part of this tree which satisfies predicate `p`? */
def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty
+ /** Do all parts of this tree satisfy predicate `p`? */
+ def forAll(p: Tree => Boolean): Boolean = find(!p(_)).isEmpty
+
def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _)
def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean =
f(this, that) || ((this.productArity == that.productArity) && {
@@ -223,7 +267,7 @@ trait Trees { self: Universe =>
duplicateTree(this).asInstanceOf[this.type]
private[scala] def copyAttrs(tree: Tree): this.type = {
- pos = tree.pos
+ rawatt = tree.rawatt
tpe = tree.tpe
if (hasSymbol) symbol = tree.symbol
this
@@ -251,18 +295,24 @@ trait Trees { self: Universe =>
override var symbol: Symbol = NoSymbol
}
+ /** A tree with a name - effectively, a DefTree or RefTree.
+ */
+ trait NameTree extends Tree {
+ def name: Name
+ }
+
/** A tree which references a symbol-carrying entity.
* References one, as opposed to defining one; definitions
* are in DefTrees.
*/
- trait RefTree extends SymTree {
+ trait RefTree extends SymTree with NameTree {
def qualifier: Tree // empty for Idents
def name: Name
}
/** A tree which defines a symbol-carrying entity.
*/
- abstract class DefTree extends SymTree {
+ abstract class DefTree extends SymTree with NameTree {
def name: Name
override def isDef = true
}
@@ -291,7 +341,6 @@ trait Trees { self: Universe =>
case ValDef(mods, _, _, _) => if (mods hasModifier Modifier.mutable) "var" else "val"
case _ => ""
}
- // final def hasFlag(mask: Long): Boolean = mods hasFlag mask
}
/** A packaging, such as `package pid { stats }`
@@ -313,12 +362,23 @@ trait Trees { self: Universe =>
case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)
extends ImplDef
+ /** @param sym the class symbol
+ * @return the implementation template
+ */
+ def ClassDef(sym: Symbol, impl: Template): ClassDef
+
/** An object definition, e.g. `object Foo`. Internally, objects are
* quite frequently called modules to reduce ambiguity.
*/
case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
extends ImplDef
+ /**
+ * @param sym the class symbol
+ * @param impl the implementation template
+ */
+ def ModuleDef(sym: Symbol, impl: Template): ModuleDef
+
/** A common base class for ValDefs and DefDefs.
*/
abstract class ValOrDefDef extends MemberDef {
@@ -337,17 +397,37 @@ trait Trees { self: Universe =>
*/
case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef
+ def ValDef(sym: Symbol, rhs: Tree): ValDef
+
+ def ValDef(sym: Symbol): ValDef
+
/** A method or macro definition.
* @param name The name of the method or macro. Can be a type name in case this is a type macro
*/
case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef],
vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef
+ def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef
+
/** An abstract type, a type parameter, or a type alias.
*/
case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree)
extends MemberDef
+ /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */
+ def TypeDef(sym: Symbol, rhs: Tree): TypeDef
+
+ /** A TypeDef node which defines abstract type or type parameter for given `sym` */
+ def TypeDef(sym: Symbol): TypeDef
+
/** A labelled expression. Not expressible in language syntax, but
* generated by the compiler to simulate while/do-while loops, and
* also by the pattern matcher.
@@ -365,6 +445,8 @@ trait Trees { self: Universe =>
case class LabelDef(name: TermName, params: List[Ident], rhs: Tree)
extends DefTree with TermTree
+ def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef
+
/** Import selector
*
* Representation of an imported name its optional rename and their optional positions
@@ -409,12 +491,19 @@ trait Trees { self: Universe =>
case class Block(stats: List[Tree], expr: Tree)
extends TermTree
+ /** Block factory that flattens directly nested blocks.
+ */
+ def Block(stats: Tree*): Block
+
/** Case clause in a pattern match, eliminated during explicitouter
* (except for occurrences in switch statements)
*/
case class CaseDef(pat: Tree, guard: Tree, body: Tree)
extends Tree
+ /** casedef shorthand */
+ def CaseDef(pat: Tree, body: Tree): CaseDef
+
/** Alternatives of patterns, eliminated by explicitouter, except for
* occurrences in encoded Switch stmt (=remaining Match(CaseDef(...))
*/
@@ -433,6 +522,8 @@ trait Trees { self: Universe =>
case class Bind(name: Name, body: Tree)
extends DefTree
+ def Bind(sym: Symbol, body: Tree): Bind
+
case class UnApply(fun: Tree, args: List[Tree])
extends TermTree
@@ -483,10 +574,14 @@ trait Trees { self: Universe =>
case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)
extends TermTree
+ def Try(body: Tree, cases: (Tree, Tree)*): Try
+
/** Throw expression */
case class Throw(expr: Tree)
extends TermTree
+ def Throw(tpe: Type, args: Tree*): Throw
+
/** Object instantiation
* One should always use factory method below to build a user level new.
*
@@ -497,14 +592,13 @@ trait Trees { self: Universe =>
/** Factory method for object creation `new tpt(args_1)...(args_n)`
* A `New(t, as)` is expanded to: `(new t).<init>(as)`
*/
- def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match {
- case Nil => new ApplyConstructor(tpt, Nil)
- case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply)
- }
+ def New(tpt: Tree, argss: List[List[Tree]]): Tree
+
/** 0-1 argument list new, based on a type.
*/
- def New(tpe: Type, args: Tree*): Tree =
- new ApplyConstructor(TypeTree(tpe), args.toList)
+ def New(tpe: Type, args: Tree*): Tree
+
+ def New(sym: Symbol, args: Tree*): Tree
/** Type annotation, eliminated by explicit outer */
case class Typed(expr: Tree, tpt: Tree)
@@ -539,10 +633,19 @@ trait Trees { self: Universe =>
override def symbol_=(sym: Symbol) { fun.symbol = sym }
}
+ def Apply(sym: Symbol, args: Tree*): Tree
+
+ // TODO remove this class, add a tree attachment to Apply to track whether implicits were involved
+ // copying trees will all too easily forget to distinguish subclasses
class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args)
+ // TODO remove this class, add a tree attachment to Apply to track whether implicits were involved
+ // copying trees will all too easily forget to distinguish subclasses
class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args)
+ // TODO: use a factory method, not a class (???)
+ // as a case in point of the comment that should go here by similarity to ApplyToImplicitArgs,
+ // this tree is considered in importers, but not in treecopier
class ApplyConstructor(tpt: Tree, args: List[Tree]) extends Apply(Select(New(tpt), nme.CONSTRUCTOR), args) {
override def printingPrefix = "ApplyConstructor"
}
@@ -557,7 +660,9 @@ trait Trees { self: Universe =>
extends TermTree with SymTree
// The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none.
- /** Super reference, qual = corresponding this reference */
+ /** Super reference, qual = corresponding this reference
+ * A super reference C.super[M] is represented as Super(This(C), M).
+ */
case class Super(qual: Tree, mix: TypeName) extends TermTree {
// The symbol of a Super is the class _from_ which the super reference is made.
// For instance in C.super(...), it would be C.
@@ -565,38 +670,49 @@ trait Trees { self: Universe =>
override def symbol_=(sym: Symbol) { qual.symbol = sym }
}
+ def Super(sym: Symbol, mix: TypeName): Tree
+
/** Self reference */
case class This(qual: TypeName)
extends TermTree with SymTree
// The symbol of a This is the class to which the this refers.
// For instance in C.this, it would be C.
- def This(sym: Symbol): Tree =
- This(sym.name.toTypeName) setSymbol sym
+ def This(sym: Symbol): Tree
/** Designator <qualifier> . <name> */
case class Select(qualifier: Tree, name: Name)
extends RefTree
- def Select(qualifier: Tree, name: String): Select =
- Select(qualifier, newTermName(name))
+ def Select(qualifier: Tree, name: String): Select
- def Select(qualifier: Tree, sym: Symbol): Select =
- Select(qualifier, sym.name) setSymbol sym
+ def Select(qualifier: Tree, sym: Symbol): Select
/** Identifier <name> */
case class Ident(name: Name) extends RefTree {
def qualifier: Tree = EmptyTree
}
- def Ident(name: String): Ident =
- Ident(newTermName(name))
+ def Ident(name: String): Ident
- def Ident(sym: Symbol): Ident =
- Ident(sym.name) setSymbol sym
+ def Ident(sym: Symbol): Ident
+ // TODO remove this class, add a tree attachment to Ident to track whether it was backquoted
+ // copying trees will all too easily forget to distinguish subclasses
class BackQuotedIdent(name: Name) extends Ident(name)
+ /** Marks underlying reference to id as boxed.
+ * @pre: id must refer to a captured variable
+ * A reference such marked will refer to the boxed entity, no dereferencing
+ * with `.elem` is done on it.
+ * This tree node can be emitted by macros such as reify that call referenceCapturedVariable.
+ * It is eliminated in LambdaLift, where the boxing conversion takes place.
+ */
+ case class ReferenceToBoxed(ident: Ident) extends TermTree {
+ override def symbol: Symbol = ident.symbol
+ override def symbol_=(sym: Symbol) { ident.symbol = sym }
+ }
+
/** Literal */
case class Literal(value: Constant)
extends TermTree {
@@ -867,6 +983,8 @@ trait Trees { self: Universe =>
traverse(qualifier)
case Ident(_) =>
;
+ case ReferenceToBoxed(idt) =>
+ traverse(idt)
case Literal(_) =>
;
case TypeTree() =>
@@ -952,6 +1070,7 @@ trait Trees { self: Universe =>
def This(tree: Tree, qual: Name): This
def Select(tree: Tree, qualifier: Tree, selector: Name): Select
def Ident(tree: Tree, name: Name): Ident
+ def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed
def Literal(tree: Tree, value: Constant): Literal
def TypeTree(tree: Tree): TypeTree
def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated
@@ -1019,9 +1138,10 @@ trait Trees { self: Universe =>
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) =
new TypeApply(fun, args).copyAttrs(tree)
def Apply(tree: Tree, fun: Tree, args: List[Tree]) =
- (tree match {
+ (tree match { // TODO: use a tree attachment to track whether this is an apply to implicit args or a view
case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args)
case _: ApplyImplicitView => new ApplyImplicitView(fun, args)
+ // TODO: ApplyConstructor ???
case _ => new Apply(fun, args)
}).copyAttrs(tree)
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
@@ -1033,7 +1153,12 @@ trait Trees { self: Universe =>
def Select(tree: Tree, qualifier: Tree, selector: Name) =
new Select(qualifier, selector).copyAttrs(tree)
def Ident(tree: Tree, name: Name) =
- new Ident(name).copyAttrs(tree)
+ (tree match { // TODO: use a tree attachment to track whether this identifier was backquoted
+ case _ : BackQuotedIdent => new BackQuotedIdent(name)
+ case _ => new Ident(name)
+ }).copyAttrs(tree)
+ def ReferenceToBoxed(tree: Tree, idt: Ident) =
+ new ReferenceToBoxed(idt).copyAttrs(tree)
def Literal(tree: Tree, value: Constant) =
new Literal(value).copyAttrs(tree)
def TypeTree(tree: Tree) =
@@ -1222,6 +1347,11 @@ trait Trees { self: Universe =>
if name0 == name => t
case _ => treeCopy.Ident(tree, name)
}
+ def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match {
+ case t @ ReferenceToBoxed(idt0)
+ if (idt0 == idt) => t
+ case _ => this.treeCopy.ReferenceToBoxed(tree, idt)
+ }
def Literal(tree: Tree, value: Constant) = tree match {
case t @ Literal(value0)
if value0 == value => t
@@ -1366,6 +1496,8 @@ trait Trees { self: Universe =>
treeCopy.Select(tree, transform(qualifier), selector)
case Ident(name) =>
treeCopy.Ident(tree, name)
+ case ReferenceToBoxed(idt) =>
+ treeCopy.ReferenceToBoxed(tree, transform(idt) match { case idt1: Ident => idt1 })
case Literal(value) =>
treeCopy.Literal(tree, value)
case TypeTree() =>
@@ -1407,7 +1539,7 @@ trait Trees { self: Universe =>
def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
stats mapConserve (stat =>
if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(transform(stat))
- else transform(stat)) filter (EmptyTree !=)
+ else transform(stat)) filter (EmptyTree != _)
def transformModifiers(mods: Modifiers): Modifiers =
mods.mapAnnotations(transformTrees)
@@ -1437,6 +1569,14 @@ trait Trees { self: Universe =>
}
}
+ class CollectTreeTraverser[T](pf: PartialFunction[Tree, T]) extends Traverser {
+ val results = new ListBuffer[T]
+ override def traverse(t: Tree) {
+ if (pf.isDefinedAt(t)) results += pf(t)
+ super.traverse(t)
+ }
+ }
+
class FindTreeTraverser(p: Tree => Boolean) extends Traverser {
var result: Option[Tree] = None
override def traverse(t: Tree) {
@@ -1529,7 +1669,7 @@ trait Trees { self: Universe =>
case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup)
// fun(args)
case Super(qual, mix) =>
- // qual.super[mix] if qual and/or mix is empty, ther are tpnme.EMPTY
+ // qual.super[mix] qual is always This(something), if mix is empty, it is tpnme.EMPTY
case This(qual) =>
// qual.this
case Select(qualifier, selector) =>
@@ -1538,6 +1678,10 @@ trait Trees { self: Universe =>
// name
// note: type checker converts idents that refer to enclosing fields or methods
// to selects; name ==> this.name
+ case ReferenceToBoxed(ident) => (created by typer, eliminated by lambdalift)
+ // synthetic node emitted by macros to reference capture vars directly without going through ``elem''
+ // var x = ...; fun { x } will emit Ident(x), which gets transformed to Select(Ident(x), "elem")
+ // if ReferenceToBoxed were used instead of Ident, no transformation would be performed
case Literal(value) =>
// value
case TypeTree() => (introduced by refcheck)
diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala
new file mode 100644
index 0000000000..c58b0fcec2
--- /dev/null
+++ b/src/library/scala/reflect/api/TypeTags.scala
@@ -0,0 +1,254 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package api
+
+import java.lang.{ Class => jClass }
+import language.implicitConversions
+
+/**
+ * Type tags encapsulate a representation of type T.
+ * They are supposed to replace the pre-2.10 concept of a [[scala.reflect.Manifest]].
+ * TypeTags are much better integrated with reflection than manifests are, and are consequently much simpler.
+ *
+ * === Overview ===
+ *
+ * Type tags are organized in a hierarchy of five classes:
+ * [[scala.reflect.ArrayTag]], [[scala.reflect.ErasureTag]], [[scala.reflect.ClassTag]],
+ * [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#ConcreteTypeTag]].
+ *
+ * An [[scala.reflect.ArrayTag]] value carries knowledge about how to build an array of elements of type T.
+ * Typically such operation is performed by storing an erasure and instantiating arrays via Java reflection,
+ * but [[scala.reflect.ArrayTag]] only defines an interface, not an implementation, hence it only contains the factory methods
+ * `newArray` and `wrap` that can be used to build, correspondingly, single-dimensional and multi-dimensional arrays.
+ *
+ * An [[scala.reflect.ErasureTag]] value wraps a Java class, which can be accessed via the `erasure` method.
+ * This notion, previously embodied in a [[scala.reflect.ClassManifest]] together with the notion of array creation,
+ * deserves a concept of itself. Quite often (e.g. for serialization or classloader introspection) it's useful to
+ * know an erasure, and only it, so we've implemented this notion in [[scala.reflect.ErasureTag]].
+ *
+ * A [[scala.reflect.ClassTag]] is a standard implementation of both [[scala.reflect.ArrayTag]] and [[scala.reflect.ErasureTag]].
+ * It guarantees that the source type T did not to contain any references to type parameters or abstract types.
+ * [[scala.reflect.ClassTag]] corresponds to a previous notion of [[scala.reflect.ClassManifest]].
+ *
+ * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field.
+ * A [[scala.reflect.api.Universe#ConcreteTypeTag]] value is a [[scala.reflect.api.Universe#TypeTag]]
+ * that is guaranteed not to contain any references to type parameters or abstract types.
+ * Both flavors of TypeTags also carry an erasure, so [[scala.reflect.api.Universe#TypeTag]] is also an [[scala.reflect.ErasureTag]],
+ * and [[scala.reflect.api.Universe#ConcreteTypeTag]] is additionally an [[scala.reflect.ArrayTag]] and a [[scala.reflect.ClassTag]]
+ *
+ * It is recommended to use the tag supertypes of to precisely express your intent, i.e.:
+ * use ArrayTag when you want to construct arrays,
+ * use ErasureTag when you need an erasure and don't mind it being generated for untagged abstract types,
+ * use ClassTag only when you need an erasure of a type that doesn't refer to untagged abstract types.
+ *
+ * === Splicing ===
+ *
+ * Tags can be spliced, i.e. if compiler generates a tag for a type that contains references to tagged
+ * type parameters or abstract type members, it will retrieve the corresponding tag and embed it into the result.
+ * An example that illustrates the TypeTag embedding, consider the following function:
+ *
+ * import reflect.mirror._
+ * def f[T: TypeTag, U] = {
+ * type L = T => U
+ * implicitly[TypeTag[L]]
+ * }
+ *
+ * Then a call of f[String, Int] will yield a result of the form
+ *
+ * TypeTag(<[ String => U ]>).
+ *
+ * Note that T has been replaced by String, because it comes with a TypeTag in f, whereas U was left as a type parameter.
+ *
+ * === ErasureTag vs ClassTag and TypeTag vs ConcreteTypeTag ===
+ *
+ * Be careful with ErasureTag and TypeTag, because they will reify types even if these types are abstract.
+ * This makes it easy to forget to tag one of the methods in the call chain and discover it much later in the runtime
+ * by getting cryptic errors far away from their source. For example, consider the following snippet:
+ *
+ * def bind[T: TypeTag](name: String, value: T): IR.Result = bind((name, value))
+ * def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
+ * object NamedParam {
+ * implicit def namedValue[T: TypeTag](name: String, x: T): NamedParam = apply(name, x)
+ * def apply[T: TypeTag](name: String, x: T): NamedParam = new Typed[T](name, x)
+ * }
+ *
+ * This fragment of Scala REPL implementation defines a `bind` function that carries a named value along with its type
+ * into the heart of the REPL. Using a [[scala.reflect.api.Universe#TypeTag]] here is reasonable, because it is desirable
+ * to work with all types, even if they are type parameters or abstract type members.
+ *
+ * However if any of the three `TypeTag` context bounds is omitted, the resulting code will be incorrect,
+ * because the missing `TypeTag` will be transparently generated by the compiler, carrying meaningless information.
+ * Most likely, this problem will manifest itself elsewhere, making debugging complicated.
+ * If `TypeTag` context bounds were replaced with `ConcreteTypeTag`, then such errors would be reported statically.
+ * But in that case we wouldn't be able to use `bind` in arbitrary contexts.
+ *
+ * === Backward compatibility ===
+ *
+ * TypeTags correspond loosely to Manifests. More precisely:
+ * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag,
+ * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.ConcreteTypeTag,
+ * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]].
+ *
+ * In Scala 2.10, manifests are deprecated, so it's adviseable to migrate them to tags,
+ * because manifests might be removed in the next major release.
+ *
+ * In most cases it will be enough to replace ClassManifests with ClassTags and Manifests with ConcreteTypeTags,
+ * however there are a few caveats:
+ *
+ * 1) The notion of OptManifest is no longer supported. Tags can reify arbitrary types, so they are always available.
+ * // [Eugene] it might be useful, though, to guard against abstractness of the incoming type.
+ *
+ * 2) There's no equivalent for AnyValManifest. Consider comparing your tag with one of the core tags
+ * (defined in the corresponding companion objects) to find out whether it represents a primitive value class.
+ *
+ * 3) There's no replacement for factory methods defined in `ClassManifest` and `Manifest` companion objects.
+ * Consider assembling corresponding types using reflection API provided by Java (for classes) and Scala (for types).
+ *
+ * 4) Certain manifest functions (such as `<:<`, `>:>` and `typeArguments`) weren't included in the tag API.
+ * Consider using reflection API provided by Java (for classes) and Scala (for types) instead.
+ */
+trait TypeTags { self: Universe =>
+
+ /**
+ * If an implicit value of type u.TypeTag[T] is required, the compiler will make one up on demand.
+ * The implicitly created value contains in its tpe field a value of type u.Type that is a reflective representation of T.
+ * In that value, any occurrences of type parameters or abstract types U
+ * which come themselves with a TypeTag are represented by the type referenced by that TypeTag.
+ *
+ * @see [[scala.reflect.api.TypeTags]]
+ */
+ @annotation.implicitNotFound(msg = "No TypeTag available for ${T}")
+ trait TypeTag[T] extends ErasureTag[T] with Equals with Serializable {
+
+ def tpe: Type
+ def sym: Symbol = tpe.typeSymbol
+
+ def isConcrete: Boolean = tpe.isConcrete
+ def notConcrete: Boolean = !isConcrete
+ def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe, erasure)
+
+ /** case class accessories */
+ override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]]
+ override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.tpe == x.asInstanceOf[TypeTag[_]].tpe
+ override def hashCode = scala.runtime.ScalaRunTime.hash(tpe)
+ override def toString = if (!self.isInstanceOf[DummyMirror]) (if (isConcrete) "*ConcreteTypeTag" else "TypeTag") + "[" + tpe + "]" else "TypeTag[?]"
+ }
+
+ object TypeTag {
+ val Byte : TypeTag[scala.Byte] = ConcreteTypeTag.Byte
+ val Short : TypeTag[scala.Short] = ConcreteTypeTag.Short
+ val Char : TypeTag[scala.Char] = ConcreteTypeTag.Char
+ val Int : TypeTag[scala.Int] = ConcreteTypeTag.Int
+ val Long : TypeTag[scala.Long] = ConcreteTypeTag.Long
+ val Float : TypeTag[scala.Float] = ConcreteTypeTag.Float
+ val Double : TypeTag[scala.Double] = ConcreteTypeTag.Double
+ val Boolean : TypeTag[scala.Boolean] = ConcreteTypeTag.Boolean
+ val Unit : TypeTag[scala.Unit] = ConcreteTypeTag.Unit
+ val Any : TypeTag[scala.Any] = ConcreteTypeTag.Any
+ val Object : TypeTag[java.lang.Object] = ConcreteTypeTag.Object
+ val AnyVal : TypeTag[scala.AnyVal] = ConcreteTypeTag.AnyVal
+ val AnyRef : TypeTag[scala.AnyRef] = ConcreteTypeTag.AnyRef
+ val Nothing : TypeTag[scala.Nothing] = ConcreteTypeTag.Nothing
+ val Null : TypeTag[scala.Null] = ConcreteTypeTag.Null
+ val String : TypeTag[java.lang.String] = ConcreteTypeTag.String
+
+ // todo. uncomment after I redo the starr
+ // def apply[T](tpe1: Type, erasure1: jClass[_]): TypeTag[T] =
+ def apply[T](tpe1: Type, erasure1: jClass[_]): TypeTag[T] =
+ tpe1 match {
+ case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]]
+ case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]]
+ case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]]
+ case IntTpe => TypeTag.Int.asInstanceOf[TypeTag[T]]
+ case LongTpe => TypeTag.Long.asInstanceOf[TypeTag[T]]
+ case FloatTpe => TypeTag.Float.asInstanceOf[TypeTag[T]]
+ case DoubleTpe => TypeTag.Double.asInstanceOf[TypeTag[T]]
+ case BooleanTpe => TypeTag.Boolean.asInstanceOf[TypeTag[T]]
+ case UnitTpe => TypeTag.Unit.asInstanceOf[TypeTag[T]]
+ case AnyTpe => TypeTag.Any.asInstanceOf[TypeTag[T]]
+ case ObjectTpe => TypeTag.Object.asInstanceOf[TypeTag[T]]
+ case AnyValTpe => TypeTag.AnyVal.asInstanceOf[TypeTag[T]]
+ case AnyRefTpe => TypeTag.AnyRef.asInstanceOf[TypeTag[T]]
+ case NothingTpe => TypeTag.Nothing.asInstanceOf[TypeTag[T]]
+ case NullTpe => TypeTag.Null.asInstanceOf[TypeTag[T]]
+ case StringTpe => TypeTag.String.asInstanceOf[TypeTag[T]]
+ case _ => new TypeTag[T]{ def tpe = tpe1; def erasure = erasure1 }
+ }
+
+ def unapply[T](ttag: TypeTag[T]): Option[Type] = Some(ttag.tpe)
+ }
+
+ /**
+ * If an implicit value of type u.ConcreteTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags.
+ * However, if the resulting type still contains references to type parameters or abstract types, a static error results.
+ *
+ * @see [[scala.reflect.api.TypeTags]]
+ */
+ @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}")
+ trait ConcreteTypeTag[T] extends TypeTag[T] with ClassTag[T] with Equals with Serializable {
+ if (!self.isInstanceOf[DummyMirror]) {
+ if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind))
+ }
+
+ /** case class accessories */
+ override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]] // this is done on purpose. TypeTag(tpe) and ConcreteTypeTag(tpe) should be equal if tpe's are equal
+ override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.tpe == x.asInstanceOf[TypeTag[_]].tpe
+ override def hashCode = scala.runtime.ScalaRunTime.hash(tpe)
+ override def toString = if (!self.isInstanceOf[DummyMirror]) "ConcreteTypeTag[" + tpe + "]" else "ConcreteTypeTag[?]"
+ }
+
+ object ConcreteTypeTag {
+ val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte]{ def tpe = ByteTpe; def erasure = ClassTag.Byte.erasure; private def readResolve() = ConcreteTypeTag.Byte }
+ val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short]{ def tpe = ShortTpe; def erasure = ClassTag.Short.erasure; private def readResolve() = ConcreteTypeTag.Short }
+ val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char]{ def tpe = CharTpe; def erasure = ClassTag.Char.erasure; private def readResolve() = ConcreteTypeTag.Char }
+ val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int]{ def tpe = IntTpe; def erasure = ClassTag.Int.erasure; private def readResolve() = ConcreteTypeTag.Int }
+ val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long]{ def tpe = LongTpe; def erasure = ClassTag.Long.erasure; private def readResolve() = ConcreteTypeTag.Long }
+ val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float]{ def tpe = FloatTpe; def erasure = ClassTag.Float.erasure; private def readResolve() = ConcreteTypeTag.Float }
+ val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double]{ def tpe = DoubleTpe; def erasure = ClassTag.Double.erasure; private def readResolve() = ConcreteTypeTag.Double }
+ val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean]{ def tpe = BooleanTpe; def erasure = ClassTag.Boolean.erasure; private def readResolve() = ConcreteTypeTag.Boolean }
+ val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit]{ def tpe = UnitTpe; def erasure = ClassTag.Unit.erasure; private def readResolve() = ConcreteTypeTag.Unit }
+ val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any]{ def tpe = AnyTpe; def erasure = ClassTag.Any.erasure; private def readResolve() = ConcreteTypeTag.Any }
+ val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object]{ def tpe = ObjectTpe; def erasure = ClassTag.Object.erasure; private def readResolve() = ConcreteTypeTag.Object }
+ val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal]{ def tpe = AnyValTpe; def erasure = ClassTag.AnyVal.erasure; private def readResolve() = ConcreteTypeTag.AnyVal }
+ val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef]{ def tpe = AnyRefTpe; def erasure = ClassTag.AnyRef.erasure; private def readResolve() = ConcreteTypeTag.AnyRef }
+ val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing]{ def tpe = NothingTpe; def erasure = ClassTag.Nothing.erasure; private def readResolve() = ConcreteTypeTag.Nothing }
+ val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null]{ def tpe = NullTpe; def erasure = ClassTag.Null.erasure; private def readResolve() = ConcreteTypeTag.Null }
+ val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String]{ def tpe = StringTpe; def erasure = ClassTag.String.erasure; private def readResolve() = ConcreteTypeTag.String }
+
+ // todo. uncomment after I redo the starr
+ // def apply[T](tpe1: Type, erasure1: jClass[_]): ConcreteTypeTag[T] =
+ def apply[T](tpe1: Type, erasure1: jClass[_] = null): ConcreteTypeTag[T] =
+ tpe1 match {
+ case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]]
+ case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]]
+ case CharTpe => ConcreteTypeTag.Char.asInstanceOf[ConcreteTypeTag[T]]
+ case IntTpe => ConcreteTypeTag.Int.asInstanceOf[ConcreteTypeTag[T]]
+ case LongTpe => ConcreteTypeTag.Long.asInstanceOf[ConcreteTypeTag[T]]
+ case FloatTpe => ConcreteTypeTag.Float.asInstanceOf[ConcreteTypeTag[T]]
+ case DoubleTpe => ConcreteTypeTag.Double.asInstanceOf[ConcreteTypeTag[T]]
+ case BooleanTpe => ConcreteTypeTag.Boolean.asInstanceOf[ConcreteTypeTag[T]]
+ case UnitTpe => ConcreteTypeTag.Unit.asInstanceOf[ConcreteTypeTag[T]]
+ case AnyTpe => ConcreteTypeTag.Any.asInstanceOf[ConcreteTypeTag[T]]
+ case ObjectTpe => ConcreteTypeTag.Object.asInstanceOf[ConcreteTypeTag[T]]
+ case AnyValTpe => ConcreteTypeTag.AnyVal.asInstanceOf[ConcreteTypeTag[T]]
+ case AnyRefTpe => ConcreteTypeTag.AnyRef.asInstanceOf[ConcreteTypeTag[T]]
+ case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]]
+ case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]]
+ case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]]
+ case _ => new ConcreteTypeTag[T]{ def tpe = tpe1; def erasure = erasure1 }
+ }
+
+ def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None
+ }
+
+ // incantations for summoning
+ // moved to Context, since rm.tags have their own incantations in Predef, and these guys are only useful in macros
+// def tag[T](implicit ttag: TypeTag[T]) = ttag
+// def typeTag[T](implicit ttag: TypeTag[T]) = ttag
+// def concreteTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag
+// def concreteTypeTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag
+}
diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala
index 0371e2c5df..e06bb37cba 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -53,10 +53,26 @@ trait Types { self: Universe =>
*/
def typeArguments: List[Type]
+ /** For a (potentially wrapped) poly type, its type parameters,
+ * the empty list for all other types */
+ def typeParams: List[Symbol]
+
/** Is this type a type constructor that is missing its type arguments?
*/
def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no?
+ /** Returns the corresponding type constructor (e.g. List for List[T] or List[String])
+ */
+ def typeConstructor: Type
+
+ /** Does this type refer to spliceable types or is a spliceable type?
+ */
+ def isConcrete: Boolean
+
+ /** Is this type an abstract type that needs to be resolved?
+ */
+ def isSpliceable: Boolean
+
/**
* Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
* Functions on types are also implemented as PolyTypes.
@@ -105,7 +121,8 @@ trait Types { self: Universe =>
/** The erased type corresponding to this type after
* all transformations from Scala to Java have been performed.
*/
- def erasedType: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased")
+ def erasure: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased")
+ // why not name it "erasure"?
/** Apply `f` to each part of this type, returning
* a new type. children get mapped before their parents */
@@ -146,6 +163,33 @@ trait Types { self: Universe =>
* <o.x.type>.widen = o.C
*/
def widen: Type
+
+ /** The kind of this type; used for debugging */
+ def kind: String
+ }
+
+ /** An object representing an unknown type, used during type inference.
+ * If you see WildcardType outside of inference it is almost certainly a bug.
+ */
+ val WildcardType: Type
+
+ /** BoundedWildcardTypes, used only during type inference, are created in
+ * two places that I can find:
+ *
+ * 1. If the expected type of an expression is an existential type,
+ * its hidden symbols are replaced with bounded wildcards.
+ * 2. When an implicit conversion is being sought based in part on
+ * the name of a method in the converted type, a HasMethodMatching
+ * type is created: a MethodType with parameters typed as
+ * BoundedWildcardTypes.
+ */
+ type BoundedWildcardType >: Null <: Type
+
+ val BoundedWildcardType: BoundedWildcardTypeExtractor
+
+ abstract class BoundedWildcardTypeExtractor {
+ def apply(bounds: TypeBounds): BoundedWildcardType
+ def unapply(tpe: BoundedWildcardType): Option[TypeBounds]
}
/** The type of Scala types, and also Scala type signatures.
@@ -225,6 +269,7 @@ trait Types { self: Universe =>
* (T # x).type SingleType(T, x)
* p.x.type SingleType(p.type, x)
* x.type SingleType(NoPrefix, x)
+ * }}}
*/
type SingleType <: SingletonType
@@ -424,5 +469,66 @@ trait Types { self: Universe =>
/** The greatest lower bound wrt <:< of a list of types */
def glb(ts: List[Type]): Type
+
+ // Creators ---------------------------------------------------------------
+ // too useful and too non-trivial to be left out of public API
+ // [Eugene to Paul] needs review!
+
+ /** The canonical creator for single-types */
+ def singleType(pre: Type, sym: Symbol): Type
+
+ /** the canonical creator for a refined type with a given scope */
+ def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type
+
+ /** The canonical creator for a refined type with an initially empty scope.
+ *
+ * @param parents ...
+ * @param owner ...
+ * @return ...
+ */
+ def refinedType(parents: List[Type], owner: Symbol): Type
+
+ /** The canonical creator for typerefs
+ */
+ def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type
+
+ /** A creator for intersection type where intersections of a single type are
+ * replaced by the type itself. */
+ def intersectionType(tps: List[Type]): Type
+
+ /** A creator for intersection type where intersections of a single type are
+ * replaced by the type itself, and repeated parent classes are merged.
+ *
+ * !!! Repeated parent classes are not merged - is this a bug in the
+ * comment or in the code?
+ */
+ def intersectionType(tps: List[Type], owner: Symbol): Type
+
+ /** A creator for type applications */
+ def appliedType(tycon: Type, args: List[Type]): Type
+
+ /** A creator for type parameterizations that strips empty type parameter lists.
+ * Use this factory method to indicate the type has kind * (it's a polymorphic value)
+ * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty).
+ */
+ def polyType(tparams: List[Symbol], tpe: Type): Type
+
+ /** A creator for existential types. This generates:
+ *
+ * tpe1 where { tparams }
+ *
+ * where `tpe1` is the result of extrapolating `tpe` wrt to `tparams`.
+ * Extrapolating means that type variables in `tparams` occurring
+ * in covariant positions are replaced by upper bounds, (minus any
+ * SingletonClass markers), type variables in `tparams` occurring in
+ * contravariant positions are replaced by upper bounds, provided the
+ * resulting type is legal wrt to stability, and does not contain any type
+ * variable in `tparams`.
+ *
+ * The abstraction drops all type parameters that are not directly or
+ * indirectly referenced by type `tpe1`. If there are no remaining type
+ * parameters, simply returns result type `tpe`.
+ */
+ def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type
}
diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala
index a3cec3271b..9670780522 100755
--- a/src/library/scala/reflect/api/Universe.scala
+++ b/src/library/scala/reflect/api/Universe.scala
@@ -1,19 +1,71 @@
package scala.reflect
package api
+import language.experimental.macros
+
abstract class Universe extends Symbols
+ with FreeVars
with Types
with Constants
with Scopes
with Names
with Trees
- with Positions
- with TreePrinters
with AnnotationInfos
+ with Positions
+ with Exprs
with StandardDefinitions
- with StandardNames {
- type Position
- val NoPosition: Position
+ with TypeTags
+ with TreePrinters
+ with StandardNames
+ with ClassLoaders
+ with TreeBuildUtil
+ with ToolBoxes
+ with FrontEnds
+ with Importers {
+ /** Given an expression, generate a tree that when compiled and executed produces the original tree.
+ * The produced tree will be bound to the Universe it was called from.
+ *
+ * For instance, given the abstract syntax tree representation of the <[ x + 1 ]> expression:
+ *
+ * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1))))
+ *
+ * The reifier transforms it to the following expression:
+ *
+ * <[
+ * val $mr: scala.reflect.api.Universe = <reference to the Universe that calls the reify>
+ * $mr.Expr[Int]($mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", <Int>, x), "+"), List($mr.Literal($mr.Constant(1))))))
+ * ]>
+ *
+ * Reification performs expression splicing (when processing Expr.eval and Expr.value)
+ * and type splicing (for every type T that has a TypeTag[T] implicit in scope):
+ *
+ * val two = mirror.reify(2) // Literal(Constant(2))
+ * val four = mirror.reify(two.eval + two.eval) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree))
+ *
+ * def macroImpl[T](c: Context) = {
+ * ...
+ * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion
+ * // however, if T were annotated with c.TypeTag (which would declare an implicit parameter for macroImpl)
+ * // then reification would subtitute T with the TypeTree that was used in a TypeApply of this particular macro invocation
+ * val factory = c.reify{ new Queryable[T] }
+ * ...
+ * }
+ *
+ * The transformation looks mostly straightforward, but it has its tricky parts:
+ * * Reifier retains symbols and types defined outside the reified tree, however
+ * locally defined entities get erased and replaced with their original trees
+ * * Free variables are detected and wrapped in symbols of the type FreeVar
+ * * Mutable variables that are accessed from a local function are wrapped in refs
+ * * Since reified trees can be compiled outside of the scope they've been created in,
+ * special measures are taken to ensure that all members accessed in the reifee remain visible
+ */
+ def reify[T](expr: T): Expr[T] = macro Universe.reify[T]
}
+object Universe {
+ def reify[T](cc: scala.reflect.makro.Context{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = {
+ import scala.reflect.makro.internal._
+ cc.Expr(cc.materializeExpr(cc.prefix.tree, expr.tree))
+ }
+}
diff --git a/src/library/scala/reflect/macro/Context.scala b/src/library/scala/reflect/macro/Context.scala
deleted file mode 100644
index 2fd9bb6484..0000000000
--- a/src/library/scala/reflect/macro/Context.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-package scala.reflect
-package macro
-
-trait Context extends api.Universe {
-
- /** Mark a variable as captured; i.e. force boxing in a *Ref type.
- */
- def captureVariable(vble: Symbol): Unit
-
- /** Mark given identifier as a reference to a captured variable itself
- * suppressing dereferencing with the `elem` field.
- */
- def referenceCapturedVariable(id: Ident): Tree
-
- /** Given a tree or type, generate a tree that when executed at runtime produces the original tree or type.
- * For instance, given the abstract syntax tree representation of the `x + 1` expression:
- *
- * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1))))
- *
- * The reifier transforms it to the following tree:
- *
- * $mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", <Int>, x), "+"), List($mr.Literal($mr.Constant(1))))))
- *
- * The transformation looks mostly straightforward, but it has its tricky parts:
- * * Reifier retains symbols and types defined outside the reified tree, however
- * locally defined entities get erased and replaced with their original trees
- * * Free variables are detected and wrapped in symbols of the type FreeVar
- * * Mutable variables that are accessed from a local function are wrapped in refs
- * * Since reified trees can be compiled outside of the scope they've been created in,
- * special measures are taken to ensure that all freeVars remain visible
- *
- * Typical usage of this function is to retain some of the trees received/created by a macro
- * into the form that can be inspected (via pattern matching) or compiled/run (by a reflective ToolBox) during the runtime.
- */
- def reify(tree: Tree): Tree
-}
diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala
new file mode 100644
index 0000000000..38b1065a40
--- /dev/null
+++ b/src/library/scala/reflect/makro/Aliases.scala
@@ -0,0 +1,26 @@
+package scala.reflect.makro
+
+trait Aliases {
+ self: Context =>
+
+ /** Aliases of mirror types */
+ type Symbol = mirror.Symbol
+ type Type = mirror.Type
+ type Name = mirror.Name
+ type Tree = mirror.Tree
+ type Position = mirror.Position
+ type Scope = mirror.Scope
+ type Modifiers = mirror.Modifiers
+ type Expr[+T] = mirror.Expr[T]
+ type TypeTag[T] = mirror.TypeTag[T]
+
+ /** Creator/extractor objects for Expr and TypeTag values */
+ val TypeTag = mirror.TypeTag
+ val Expr = mirror.Expr
+
+ /** incantations for summoning tags */
+ def tag[T](implicit ttag: TypeTag[T]) = ttag
+ def typeTag[T](implicit ttag: TypeTag[T]) = ttag
+ def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag
+ def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag
+}
diff --git a/src/library/scala/reflect/makro/CapturedVariables.scala b/src/library/scala/reflect/makro/CapturedVariables.scala
new file mode 100644
index 0000000000..6ce832b2b3
--- /dev/null
+++ b/src/library/scala/reflect/makro/CapturedVariables.scala
@@ -0,0 +1,20 @@
+package scala.reflect.makro
+
+trait CapturedVariables {
+ self: Context =>
+
+ import mirror._
+
+ /** Mark a variable as captured; i.e. force boxing in a *Ref type.
+ */
+ def captureVariable(vble: Symbol): Unit
+
+ /** Mark given identifier as a reference to a captured variable itself
+ * suppressing dereferencing with the `elem` field.
+ */
+ def referenceCapturedVariable(vble: Symbol): Tree
+
+ /** Convert type of a captured variable to *Ref type.
+ */
+ def capturedVariableType(vble: Symbol): Type
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala
new file mode 100644
index 0000000000..b8fb0dcce5
--- /dev/null
+++ b/src/library/scala/reflect/makro/Context.scala
@@ -0,0 +1,44 @@
+package scala.reflect.makro
+
+import language.experimental.macros
+
+// todo. introduce context hierarchy
+// the most lightweight context should just expose the stuff from the SIP
+// the full context should include all traits from scala.reflect.makro (and probably reside in scala-compiler.jar)
+
+trait Context extends Aliases
+ with CapturedVariables
+ with Enclosures
+ with Infrastructure
+ with Names
+ with Reifiers
+ with FrontEnds
+ with Settings
+ with Symbols
+ with Typers
+ with Util {
+
+ /** The mirror that corresponds to the compile-time universe */
+ val mirror: scala.reflect.api.Universe
+
+ /** The type of the prefix tree from which the macro is selected */
+ type PrefixType
+
+ /** The prefix tree from which the macro is selected */
+ val prefix: Expr[PrefixType]
+
+ /** Alias to the underlying mirror's reify */
+ def reify[T](expr: T): Expr[T] = macro Context.reify[T]
+}
+
+object Context {
+ def reify[T](cc: Context{ type PrefixType = Context })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = {
+ import cc.mirror._
+ import scala.reflect.makro.internal._
+ // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure?
+ val prefix: Tree = Select(cc.prefix.tree, newTermName("mirror"))
+ val prefixTpe = cc.typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe
+ prefix setType prefixTpe
+ cc.Expr(cc.materializeExpr(prefix, expr.tree))
+ }
+}
diff --git a/src/library/scala/reflect/makro/Enclosures.scala b/src/library/scala/reflect/makro/Enclosures.scala
new file mode 100644
index 0000000000..136d39498e
--- /dev/null
+++ b/src/library/scala/reflect/makro/Enclosures.scala
@@ -0,0 +1,53 @@
+package scala.reflect.makro
+
+trait Enclosures {
+ self: Context =>
+
+ /** The tree that undergoes macro expansion.
+ * Can be useful to get an offset or a range position of the entire tree being processed.
+ */
+ val macroApplication: Tree
+
+ /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only.
+ * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion.
+ *
+ * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees.
+ * In that dire case navigate the ``enclosingMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application.
+ * See ``enclosingPosition'' for a default implementation of this logic.
+ *
+ * Unlike `openMacros`, this is a val, which means that it gets initialized when the context is created
+ * and always stays the same regardless of whatever happens during macro expansion.
+ */
+ val enclosingMacros: List[Context]
+
+ /** Types along with corresponding trees for which implicit arguments are currently searched.
+ * Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion.
+ *
+ * Unlike `openImplicits`, this is a val, which means that it gets initialized when the context is created
+ * and always stays the same regardless of whatever happens during macro expansion.
+ */
+ val enclosingImplicits: List[(Type, Tree)]
+
+ /** Tries to guess a position for the enclosing application.
+ * But that is simple, right? Just dereference ``pos'' of ``macroApplication''? Not really.
+ * If we're in a synthetic macro expansion (no positions), we must do our best to infer the position of something that triggerd this expansion.
+ * Surprisingly, quite often we can do this by navigation the ``enclosingMacros'' stack.
+ */
+ val enclosingPosition: Position
+
+ /** Tree that corresponds to the enclosing application, or EmptyTree if not applicable.
+ */
+ val enclosingApplication: Tree
+
+ /** Tree that corresponds to the enclosing method, or EmptyTree if not applicable.
+ */
+ val enclosingMethod: Tree
+
+ /** Tree that corresponds to the enclosing class, or EmptyTree if not applicable.
+ */
+ val enclosingClass: Tree
+
+ /** Compilation unit that contains this macro application.
+ */
+ val enclosingUnit: CompilationUnit
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/FrontEnds.scala b/src/library/scala/reflect/makro/FrontEnds.scala
new file mode 100644
index 0000000000..a1e24dcea3
--- /dev/null
+++ b/src/library/scala/reflect/makro/FrontEnds.scala
@@ -0,0 +1,39 @@
+package scala.reflect.makro
+
+trait FrontEnds {
+ self: Context =>
+
+ import mirror._
+
+ /** Exposes means to control the compiler UI */
+ def frontEnd: FrontEnd
+ def setFrontEnd(frontEnd: FrontEnd): this.type
+ def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T
+
+ /** For sending a message which should not be labeled as a warning/error,
+ * but also shouldn't require -verbose to be visible.
+ * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''.
+ */
+ def echo(pos: Position, msg: String): Unit
+
+ /** Informational messages, suppressed unless -verbose or force=true.
+ * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''.
+ */
+ def info(pos: Position, msg: String, force: Boolean): Unit
+
+ /** Warnings and errors.
+ * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''.
+ */
+ def hasWarnings: Boolean
+ def hasErrors: Boolean
+ def warning(pos: Position, msg: String): Unit
+ def error(pos: Position, msg: String): Unit
+
+ /** Abruptly terminates current macro expansion leaving a note about what happened.
+ * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''.
+ */
+ def abort(pos: Position, msg: String): Nothing
+
+ /** Drops into interactive mode if supported by the compiler UI */
+ def interactive(): Unit
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/Infrastructure.scala b/src/library/scala/reflect/makro/Infrastructure.scala
new file mode 100644
index 0000000000..2bf49dca77
--- /dev/null
+++ b/src/library/scala/reflect/makro/Infrastructure.scala
@@ -0,0 +1,73 @@
+package scala.reflect.makro
+
+trait Infrastructure {
+ self: Context =>
+
+ /** Determines whether the compiler expanding a macro targets JVM.
+ */
+ val forJVM: Boolean
+
+ /** Determines whether the compiler expanding a macro targets CLR.
+ */
+ val forMSIL: Boolean
+
+ /** Determines whether the compiler expanding a macro is a presentation compiler.
+ */
+ val forInteractive: Boolean
+
+ /** Determines whether the compiler expanding a macro is a Scaladoc compiler.
+ */
+ val forScaladoc: Boolean
+
+ /** Exposes current compilation run.
+ */
+ val currentRun: Run
+
+ /** As seen by macro API, compilation run is an opaque type that can be deconstructed into:
+ * 1) Current compilation unit
+ * 2) List of all compilation units that comprise the run
+ */
+ type Run
+
+ val Run: RunExtractor
+
+ abstract class RunExtractor {
+ def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])]
+ }
+
+ /** As seen by macro API, compilation unit is an opaque type that can be deconstructed into:
+ * 1) File that corresponds to the unit (if not applicable, null)
+ * 2) Content of the file (if not applicable, empty array)
+ * 3) Body, i.e. the AST that represents the compilation unit
+ */
+ type CompilationUnit
+
+ val CompilationUnit: CompilationUnitExtractor
+
+ abstract class CompilationUnitExtractor {
+ def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)]
+ }
+
+ /** Returns a macro definition which triggered this macro expansion.
+ */
+ val currentMacro: Symbol
+
+ // todo. redo caches as discussed on Reflecting Meeting 2012/03/29
+ // https://docs.google.com/document/d/1oUZGQpdt2qwioTlJcSt8ZFQwVLTvpxn8xa67P8OGVpU/edit
+
+ /** A cache shared by all invocations of all macros across all compilation runs.
+ *
+ * Needs to be used with extreme care, since memory leaks here will swiftly crash the presentation compiler.
+ * For example, Scala IDE typically launches a compiler run on every edit action so there might be hundreds of runs per minute.
+ */
+ val globalCache: collection.mutable.Map[Any, Any]
+
+ /** A cache shared by all invocations of the same macro within a single compilation run.
+ *
+ * This cache is cleared automatically after a compilation run is completed or abandoned.
+ * It is also specific to a particular macro definition.
+ *
+ * To share data between different macros and/or different compilation runs, use ``globalCache''.
+ */
+ val cache: collection.mutable.Map[Any, Any]
+}
diff --git a/src/library/scala/reflect/makro/Names.scala b/src/library/scala/reflect/makro/Names.scala
new file mode 100644
index 0000000000..8a823d19cb
--- /dev/null
+++ b/src/library/scala/reflect/makro/Names.scala
@@ -0,0 +1,14 @@
+package scala.reflect.makro
+
+trait Names {
+ self: Context =>
+
+ /** Creates a fresh string */
+ def fresh(): String
+
+ /** Creates a fresh string from the provided string */
+ def fresh(name: String): String
+
+ /** Creates a fresh name from the provided name */
+ def fresh(name: Name): Name
+}
diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala
new file mode 100644
index 0000000000..b1de8d9957
--- /dev/null
+++ b/src/library/scala/reflect/makro/Reifiers.scala
@@ -0,0 +1,77 @@
+package scala.reflect.makro
+
+trait Reifiers {
+ self: Context =>
+
+ /** Reification prefix that refers to the standard reflexive mirror, ``scala.reflect.mirror''.
+ * Providing it for the ``prefix'' parameter of ``reifyTree'' or ``reifyType'' will create a tree that can be inspected at runtime.
+ */
+ val reflectMirrorPrefix: Tree
+
+ /** Given a tree, generate a tree that when compiled and executed produces the original tree.
+ * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix'').
+ * For more information and examples see the documentation for ``Universe.reify''.
+ *
+ * This function is deeply connected to ``Universe.reify'', a macro that reifies arbitrary expressions into runtime trees.
+ * They do very similar things (``Universe.reify'' calls ``Context.reifyTree'' to implement itself), but they operate on different metalevels (see below).
+ *
+ * Let's study the differences between ``Context.reifyTree'' and ``Universe.reify'' on an example of using them inside a ``fooMacro'' macro:
+ *
+ * * Since reify itself is a macro, it will be executed when fooMacro is being compiled (metalevel -1)
+ * and will produce a tree that when evaluated during macro expansion of fooMacro (metalevel 0) will recreate the input tree.
+ *
+ * This provides a facility analogous to quasi-quoting. Writing "reify{ expr }" will generate an AST that represents expr.
+ * Afterwards this AST (or its parts) can be used to construct the return value of fooMacro.
+ *
+ * * reifyTree is evaluated during macro expansion (metalevel 0)
+ * and will produce a tree that when evaluated during the runtime of the program (metalevel 1) will recreate the input tree.
+ *
+ * This provides a way to retain certain trees from macro expansion time to be inspected later, in the runtime.
+ * For example, DSL authors may find it useful to capture DSL snippets into ASTs that are then processed at runtime in a domain-specific way.
+ *
+ * Also note the difference between universes of the runtime trees produced by two reifies:
+ *
+ * * The result of compiling and running the result of reify will be bound to the Universe that called reify.
+ * This is possible because it's a macro, so it can generate whatever code it wishes.
+ *
+ * * The result of compiling and running the result of reifyTree will be the ``prefix'' that needs to be passed explicitly.
+ * This happens because the Universe of the evaluated result is from a different metalevel than the Context the called reify.
+ *
+ * Typical usage of this function is to retain some of the trees received/created by a macro
+ * into the form that can be inspected (via pattern matching) or compiled/run (by a reflective ToolBox) during the runtime.
+ */
+ def reifyTree(prefix: Tree, tree: Tree): Tree
+
+ /** Given a type, generate a tree that when compiled and executed produces the original type.
+ * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix'').
+ * For more information and examples see the documentation for ``Context.reifyTree'' and ``Universe.reify''.
+ */
+ def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Tree
+
+ /** Given a type, generate a tree that when compiled and executed produces the erasure of the original type.
+ * If ``concrete'' is true, then this function will bail on types, whose erasure includes abstract types (like `ClassTag` does).
+ */
+ def reifyErasure(tpe: Type, concrete: Boolean = true): Tree
+
+ /** Undoes reification of a tree.
+ *
+ * This reversion doesn't simply restore the original tree (that would lose the context of reification),
+ * but does something more involved that conforms to the following laws:
+ *
+ * 1) unreifyTree(reifyTree(tree)) != tree // unreified tree is tree + saved context
+ * // in current implementation, the result of unreify is opaque
+ * // i.e. there's no possibility to inspect underlying tree/context
+ *
+ * 2) reifyTree(unreifyTree(reifyTree(tree))) == reifyTree(tree) // the result of reifying a tree in its original context equals to
+ * // the result of reifying a tree along with its saved context
+ *
+ * 3) compileAndEval(unreifyTree(reifyTree(tree))) ~ compileAndEval(tree) // at runtime original and unreified trees are behaviorally equivalent
+ */
+ def unreifyTree(tree: Tree): Tree
+}
+
+// made these guys non path-dependent, otherwise exception handling quickly becomes a mess
+
+case class ReificationError(var pos: reflect.api.Position, val msg: String) extends Throwable(msg)
+
+case class UnexpectedReificationError(val pos: reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause) \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/Settings.scala b/src/library/scala/reflect/makro/Settings.scala
new file mode 100644
index 0000000000..c4a8ebd1b5
--- /dev/null
+++ b/src/library/scala/reflect/makro/Settings.scala
@@ -0,0 +1,38 @@
+package scala.reflect.makro
+
+trait Settings {
+ self: Context =>
+
+ /** Exposes macro-specific settings as a list of strings.
+ * These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option.
+ */
+ def settings: List[String]
+
+ /** Exposes current compiler settings as a list of options.
+ * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
+ */
+ // [Eugene] ugly? yes, but I don't really fancy copy/pasting all our settings here and keep it synchronized at all times
+ // why all settings? because macros need to be in full control of the stuff going on
+ // maybe later we can implement a gettable/settable list of important settings, but for now let's leave it like that
+ def compilerSettings: List[String]
+
+ /** Updates current compiler settings with an option string.
+ * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
+ */
+ def setCompilerSettings(options: String): this.type
+
+ /** Updates current compiler settings with a list of options.
+ * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
+ */
+ def setCompilerSettings(options: List[String]): this.type
+
+ /** Temporary sets compiler settings to a given option string and executes a given closure.
+ * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
+ */
+ def withCompilerSettings[T](options: String)(op: => T): T
+
+ /** Temporary sets compiler settings to a given list of options and executes a given closure.
+ * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
+ */
+ def withCompilerSettings[T](options: List[String])(op: => T): T
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/Symbols.scala b/src/library/scala/reflect/makro/Symbols.scala
new file mode 100644
index 0000000000..ca1c17534c
--- /dev/null
+++ b/src/library/scala/reflect/makro/Symbols.scala
@@ -0,0 +1,24 @@
+package scala.reflect.makro
+
+trait Symbols {
+ self: Context =>
+
+ /** Can this symbol be loaded by a reflective mirror?
+ *
+ * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs.
+ * Such annotations (also called "pickles") are applied on top-level classes and include information
+ * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block)
+ * are typically unreachable and information about them gets lost.
+ *
+ * This method is useful for macro writers who wish to save certain ASTs to be used at runtime.
+ * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment.
+ */
+ def isLocatable(sym: Symbol): Boolean
+
+ /** Is this symbol static (i.e. with no outer instance)?
+ * Q: When exactly is a sym marked as STATIC?
+ * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep.
+ * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6
+ */
+ def isStatic(sym: Symbol): Boolean
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/Typers.scala b/src/library/scala/reflect/makro/Typers.scala
new file mode 100644
index 0000000000..c62c5f254c
--- /dev/null
+++ b/src/library/scala/reflect/makro/Typers.scala
@@ -0,0 +1,85 @@
+package scala.reflect.makro
+
+trait Typers {
+ self: Context =>
+
+ import mirror._
+
+ /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only.
+ * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion.
+ *
+ * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees.
+ * In that dire case navigate the ``openMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application.
+ * See ``enclosingPosition'' for a default implementation of this logic.
+ *
+ * Unlike `enclosingMacros`, this is a def, which means that it gets recalculated on every invocation,
+ * so it might change depending on what is going on during macro expansion.
+ */
+ def openMacros: List[Context]
+
+ /** Types along with corresponding trees for which implicit arguments are currently searched.
+ * Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion.
+ *
+ * Unlike `enclosingImplicits`, this is a def, which means that it gets recalculated on every invocation,
+ * so it might change depending on what is going on during macro expansion.
+ */
+ def openImplicits: List[(Type, Tree)]
+
+ /** Typechecks the provided tree against the expected type ``pt'' in the macro callsite context.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Ymacro-debug-verbose.
+ * Unlike in ``inferImplicitValue'' and ``inferImplicitView'', ``silent'' is false by default.
+ *
+ * Typechecking can be steered with the following optional parameters:
+ * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false
+ * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false
+ */
+ def typeCheck(tree: Tree, pt: Type = WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree
+
+ /** Infers an implicit value of the expected type ``pt'' in the macro callsite context.
+ * Optional ``pos'' parameter provides a position that will be associated with the implicit search.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
+ * Unlike in ``typeCheck'', ``silent'' is true by default.
+ */
+ def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree
+
+ /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context.
+ *
+ * Optional ``pos'' parameter provides a position that will be associated with the implicit search.
+ * Another optional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported.
+ * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''.
+ *
+ * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error.
+ * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs.
+ * Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
+ * Unlike in ``typeCheck'', ``silent'' is true by default.
+ */
+ def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree
+
+ /** Recursively resets symbols and types in a given tree.
+ *
+ * Note that this does not revert the tree to its pre-typer shape.
+ * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ */
+ def resetAllAttrs[T <: Tree](tree: T): T
+
+ /** Recursively resets locally defined symbols and types in a given tree.
+ *
+ * Note that this does not revert the tree to its pre-typer shape.
+ * For more info, read up https://issues.scala-lang.org/browse/SI-5464.
+ */
+ def resetLocalAttrs[T <: Tree](tree: T): T
+
+ /** Represents an error during typechecking
+ */
+ type TypeError <: Throwable
+ val TypeError: TypeErrorExtractor
+ abstract class TypeErrorExtractor {
+ def unapply(error: TypeError): Option[(Position, String)]
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/Util.scala b/src/library/scala/reflect/makro/Util.scala
new file mode 100644
index 0000000000..16eb2395a9
--- /dev/null
+++ b/src/library/scala/reflect/makro/Util.scala
@@ -0,0 +1,31 @@
+package scala.reflect.makro
+
+trait Util {
+ self: Context =>
+
+ def literalNull: Expr[Null]
+
+ def literalUnit: Expr[Unit]
+
+ def literalTrue: Expr[Boolean]
+
+ def literalFalse: Expr[Boolean]
+
+ def literal(x: Boolean): Expr[Boolean]
+
+ def literal(x: Byte): Expr[Byte]
+
+ def literal(x: Short): Expr[Short]
+
+ def literal(x: Int): Expr[Int]
+
+ def literal(x: Long): Expr[Long]
+
+ def literal(x: Float): Expr[Float]
+
+ def literal(x: Double): Expr[Double]
+
+ def literal(x: String): Expr[String]
+
+ def literal(x: Char): Expr[Char]
+}
diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala
new file mode 100644
index 0000000000..3af58e1c88
--- /dev/null
+++ b/src/library/scala/reflect/makro/internal/Utils.scala
@@ -0,0 +1,146 @@
+package scala.reflect.makro
+
+import scala.reflect.api.Universe
+import language.implicitConversions
+import language.experimental.macros
+
+/** This package is required by the compiler and <b>should not be used in client code</b>. */
+package object internal {
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeArrayTag[T](u: Universe): ArrayTag[T] = macro materializeArrayTag_impl[T]
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeArrayTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ArrayTag[T]] =
+ c.Expr[Nothing](c.materializeArrayTag(u.tree, implicitly[c.TypeTag[T]].tpe))(c.TypeTag.Nothing)
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeErasureTag[T](u: Universe): ErasureTag[T] = macro materializeErasureTag_impl[T]
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeErasureTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ErasureTag[T]] =
+ c.Expr[Nothing](c.materializeErasureTag(u.tree, implicitly[c.TypeTag[T]].tpe, concrete = false))(c.TypeTag.Nothing)
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeClassTag[T](u: Universe): ClassTag[T] = macro materializeClassTag_impl[T]
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeClassTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ClassTag[T]] =
+ c.Expr[Nothing](c.materializeClassTag(u.tree, implicitly[c.TypeTag[T]].tpe))(c.TypeTag.Nothing)
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeTypeTag[T](u: Universe): u.TypeTag[T] = macro materializeTypeTag_impl[T]
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.TypeTag[T]] =
+ c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, concrete = false))(c.TypeTag.Nothing)
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeConcreteTypeTag[T](u: Universe): u.ConcreteTypeTag[T] = macro materializeConcreteTypeTag_impl[T]
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ def materializeConcreteTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.ConcreteTypeTag[T]] =
+ c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, concrete = true))(c.TypeTag.Nothing)
+
+ /** This method is required by the compiler and <b>should not be used in client code</b>. */
+ private[scala] implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils
+}
+
+package internal {
+ private[scala] abstract class Utils {
+ val c: Context
+
+ import c.mirror._
+ import definitions._
+
+ val coreTags = Map(
+ ByteClass.asType -> newTermName("Byte"),
+ ShortClass.asType -> newTermName("Short"),
+ CharClass.asType -> newTermName("Char"),
+ IntClass.asType -> newTermName("Int"),
+ LongClass.asType -> newTermName("Long"),
+ FloatClass.asType -> newTermName("Float"),
+ DoubleClass.asType -> newTermName("Double"),
+ BooleanClass.asType -> newTermName("Boolean"),
+ UnitClass.asType -> newTermName("Unit"),
+ AnyClass.asType -> newTermName("Any"),
+ ObjectClass.asType -> newTermName("Object"),
+ AnyValClass.asType -> newTermName("AnyVal"),
+ AnyRefClass.asType -> newTermName("AnyRef"),
+ NothingClass.asType -> newTermName("Nothing"),
+ NullClass.asType -> newTermName("Null"),
+ StringClass.asType -> newTermName("String"))
+
+ // todo. the following two methods won't be necessary once we implement implicit macro generators for tags
+
+ def materializeArrayTag(prefix: Tree, tpe: Type): Tree =
+ materializeClassTag(prefix, tpe)
+
+ def materializeErasureTag(prefix: Tree, tpe: Type, concrete: Boolean): Tree =
+ if (concrete) materializeClassTag(prefix, tpe) else materializeTypeTag(prefix, tpe, concrete = false)
+
+ def materializeClassTag(prefix: Tree, tpe: Type): Tree =
+ materializeTag(prefix, tpe, ClassTagModule, {
+ val erasure = c.reifyErasure(tpe, concrete = true)
+ val factory = TypeApply(Select(Ident(ClassTagModule), "apply"), List(TypeTree(tpe)))
+ Apply(factory, List(erasure))
+ })
+
+ def materializeTypeTag(prefix: Tree, tpe: Type, concrete: Boolean): Tree = {
+ val tagModule = if (concrete) ConcreteTypeTagModule else TypeTagModule
+ materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, concrete = concrete))
+ }
+
+ private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = {
+ val result =
+ tpe match {
+ case coreTpe if coreTags contains coreTpe =>
+ val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name)
+ Select(ref, coreTags(coreTpe))
+ case _ =>
+ val manifestInScope = nonSyntheticManifestInScope(tpe)
+ if (manifestInScope.isEmpty) translatingReificationErrors(materializer)
+ else gen.mkMethodCall(staticModule("scala.reflect.package"), newTermName("manifestToConcreteTypeTag"), List(tpe), List(manifestInScope))
+ }
+ try c.typeCheck(result)
+ catch { case terr @ c.TypeError(pos, msg) => failTag(terr) }
+ }
+
+ private def nonSyntheticManifestInScope(tpe: Type) = {
+ val ManifestClass = staticClass("scala.reflect.Manifest")
+ val ManifestModule = staticModule("scala.reflect.Manifest")
+ val manifest = c.inferImplicitValue(appliedType(ManifestClass.asTypeConstructor, List(tpe)))
+ val notOk = manifest.isEmpty || (manifest exists (sub => sub.symbol != null && (sub.symbol == ManifestModule || sub.symbol.owner == ManifestModule)))
+ if (notOk) EmptyTree else manifest
+ }
+
+ def materializeExpr(prefix: Tree, expr: Tree): Tree = {
+ val result = translatingReificationErrors(c.reifyTree(prefix, expr))
+ try c.typeCheck(result)
+ catch { case terr @ c.TypeError(pos, msg) => failExpr(terr) }
+ }
+
+ private def translatingReificationErrors(materializer: => Tree): Tree = {
+ try materializer
+ catch {
+ case ReificationError(pos, msg) =>
+ c.error(pos.asInstanceOf[c.Position], msg) // this cast is a very small price for the sanity of exception handling
+ EmptyTree
+ case UnexpectedReificationError(pos, err, cause) if cause != null =>
+ throw cause
+ }
+ }
+
+ private def failTag(reason: Any): Nothing = {
+ val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication
+ val tpe = tpeTree.tpe
+ val PolyType(_, MethodType(_, tagTpe)) = fun.tpe
+ val tagModule = tagTpe.typeSymbol.companionSymbol
+ if (c.compilerSettings.contains("-Xlog-implicits"))
+ c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason)
+ c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe))
+ }
+
+ private def failExpr(reason: Any): Nothing =
+ c.abort(c.enclosingPosition, "Cannot materialize Expr because:\n" + reason)
+ }
+}
diff --git a/src/library/scala/reflect/makro/internal/macroImpl.scala b/src/library/scala/reflect/makro/internal/macroImpl.scala
new file mode 100644
index 0000000000..86600ba0a1
--- /dev/null
+++ b/src/library/scala/reflect/makro/internal/macroImpl.scala
@@ -0,0 +1,5 @@
+package scala.reflect.makro
+package internal
+
+/** This type is required by the compiler and <b>should not be used in client code</b>. */
+class macroImpl(val referenceToMacroImpl: Any) extends StaticAnnotation
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index 1c3e618520..38a144cd49 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -2,20 +2,41 @@ package scala
package object reflect {
+ import ReflectionUtils._
+ import scala.compat.Platform.EOL
+
// !!! This was a val; we can't throw exceptions that aggressively without breaking
// non-standard environments, e.g. google app engine. I made it a lazy val, but
// I think it would be better yet to throw the exception somewhere else - not during
// initialization, but in response to a doomed attempt to utilize it.
- lazy val mirror: api.Mirror = {
- // we use (Java) reflection here so that we can keep reflect.runtime and reflect.internals in a seperate jar
- ReflectionUtils.singletonInstanceOpt("scala.reflect.runtime.Mirror") collect { case x: api.Mirror => x } getOrElse {
- throw new UnsupportedOperationException("Scala reflection not available on this platform")
+
+ // todo. default mirror (a static object) might become a source for memory leaks (because it holds a strong reference to a classloader)!
+ lazy val mirror: api.Mirror =
+ try mkMirror(defaultReflectionClassLoader)
+ catch {
+ case ex: UnsupportedOperationException =>
+ new DummyMirror(defaultReflectionClassLoader)
}
- }
- type Symbol = mirror.Symbol
- type Type = mirror.Type
- type Tree = mirror.Tree
+ private[scala] def mirrorDiagnostics(cl: ClassLoader): String = """
+ |
+ | This error has happened because `scala.reflect.runtime.package` located in
+ | scala-compiler.jar cannot be loaded. Classloader you are using is:
+ | %s.
+ |
+ | For the instructions for some of the situations that might be relevant
+ | visit our knowledge base at https://gist.github.com/2391081.
+ """.stripMargin('|').format(show(cl))
+
+ def mkMirror(classLoader: ClassLoader): api.Mirror = {
+ val coreClassLoader = getClass.getClassLoader
+ val instance = invokeFactoryOpt(coreClassLoader, "scala.reflect.runtime.package", "mkMirror", classLoader)
+ instance match {
+ case Some(x: api.Mirror) => x
+ case Some(_) => throw new UnsupportedOperationException("Available scala reflection implementation is incompatible with this interface." + mirrorDiagnostics(coreClassLoader))
+ case None => throw new UnsupportedOperationException("Scala reflection not available on this platform." + mirrorDiagnostics(coreClassLoader))
+ }
+ }
@deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0")
type BeanDescription = scala.beans.BeanDescription
@@ -31,4 +52,19 @@ package object reflect {
type BooleanBeanProperty = scala.beans.BooleanBeanProperty
@deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0")
type ScalaBeanInfo = scala.beans.ScalaBeanInfo
+
+ // ArrayTag trait is defined separately from the mirror
+ // ErasureTag trait is defined separately from the mirror
+ // ConcreteErasureTag trait is defined separately from the mirror
+ // ClassTag class is defined separately from the mirror
+ type TypeTag[T] = scala.reflect.mirror.TypeTag[T]
+ type ConcreteTypeTag[T] = scala.reflect.mirror.ConcreteTypeTag[T]
+
+ // ClassTag object is defined separately from the mirror
+ lazy val TypeTag = scala.reflect.mirror.TypeTag
+ lazy val ConcreteTypeTag = scala.reflect.mirror.ConcreteTypeTag
+
+ def arrayTagToClassManifest[T](tag: ArrayTag[T]): ClassManifest[T] = TagInterop.arrayTagToClassManifest[T](tag)
+ def concreteTypeTagToManifest[T](tag: ConcreteTypeTag[T]): Manifest[T] = TagInterop.concreteTypeTagToManifest[T](tag)
+ def manifestToConcreteTypeTag[T](tag: Manifest[T]): ConcreteTypeTag[T] = TagInterop.manifestToConcreteTypeTag[T](tag)
}
diff --git a/src/library/scala/runtime/AbstractPartialFunction.scala b/src/library/scala/runtime/AbstractPartialFunction.scala
index cbe778f09b..2e435d8a7e 100644
--- a/src/library/scala/runtime/AbstractPartialFunction.scala
+++ b/src/library/scala/runtime/AbstractPartialFunction.scala
@@ -8,45 +8,61 @@
package scala.runtime
-import scala.annotation.unchecked.uncheckedVariance
-
-/** This class provides a default implementation of partial functions
- * that is used for all partial function literals.
- * It contains an optimized `orElse` method which supports
- * chained `orElse` in linear time, and with no slow-down
- * if the `orElse` part is not needed.
- * The implementation of `orElse` works by cloning the abstract function object
- * and modifying a private `fallBack` variable that encodes the `getorElse` part.
+/** `AbstractPartialFunction` reformulates all operations of its supertrait `PartialFunction` in terms of `isDefinedAt` and `applyOrElse`.
+ *
+ * This allows more efficient implementations in many cases:
+ * - optimized `orElse` method supports chained `orElse` in linear time,
+ * and with no slow-down if the `orElse` part is not needed.
+ * - optimized `lift` method helps to avoid double evaluation of pattern matchers & guards
+ * of partial function literals.
+ *
+ * This trait is used as a basis for implementation of all partial function literals
+ * with non-exhaustive matchers.
+ *
+ * Use of `AbstractPartialFunction` instead of `PartialFunction` as a base trait for
+ * user-defined partial functions may result in better performance
+ * and more predictable behavior w.r.t. side effects.
+ *
+ * @author Pavel Pavlov
+ * @since 2.10
*/
-abstract class AbstractPartialFunction[-T1, +R]
- extends AbstractFunction1[T1, R]
- with PartialFunction[T1, R]
- with Cloneable {
-
- private var fallBackField: PartialFunction[T1 @uncheckedVariance, R @uncheckedVariance] = _
+abstract class AbstractPartialFunction[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, scala.AnyRef) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double, scala.AnyRef) +R] extends Function1[T1, R] with PartialFunction[T1, R] { self =>
+ // this method must be overridden for better performance,
+ // for backwards compatibility, fall back to the one inherited from PartialFunction
+ // this assumes the old-school partial functions override the apply method, though
+ // override def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = ???
- def fallBack: PartialFunction[T1, R] = synchronized {
- if (fallBackField eq null) fallBackField = PartialFunction.empty
- fallBackField
- }
+ // probably okay to make final since classes compiled before have overridden against the old version of AbstractPartialFunction
+ // let's not make it final so as not to confuse anyone
+ /*final*/ def apply(x: T1): R = applyOrElse(x, PartialFunction.empty)
- override protected def missingCase(x: T1): R = fallBack(x)
-
- // Question: Need to ensure that fallBack is overwritten before any access
- // Is the `synchronized` here the right thing to achieve this?
- // Is there a cheaper way?
- override def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = {
- val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
- result.synchronized {
- result.fallBackField = if (this.fallBackField eq null) that else this.fallBackField orElse that
- result
+ override final def andThen[C](k: R => C) : PartialFunction[T1, C] =
+ new AbstractPartialFunction[T1, C] {
+ def isDefinedAt(x: T1): Boolean = self.isDefinedAt(x)
+ override def applyOrElse[A1 <: T1, C1 >: C](x: A1, default: A1 => C1): C1 =
+ self.applyOrElse(x, PartialFunction.fallbackToken) match {
+ case PartialFunction.FallbackToken => default(x)
+ case z => k(z)
+ }
}
- }
-
- def isDefinedAt(x: T1): scala.Boolean = _isDefinedAt(x) || fallBack.isDefinedAt(x)
- def _isDefinedAt(x: T1): scala.Boolean
+ // TODO: remove
+ protected def missingCase(x: T1): R = throw new MatchError(x)
}
-
+/** `AbstractTotalFunction` is a partial function whose `isDefinedAt` method always returns `true`.
+ *
+ * This class is used as base class for partial function literals with
+ * certainly exhaustive pattern matchers.
+ *
+ * @author Pavel Pavlov
+ * @since 2.10
+ */
+abstract class AbstractTotalFunction[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, scala.AnyRef) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double, scala.AnyRef) +R] extends Function1[T1, R] with PartialFunction[T1, R] {
+ final def isDefinedAt(x: T1): Boolean = true
+ override final def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = apply(x)
+ override final def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = this
+ //TODO: check generated code for PF literal here
+ override final def andThen[C](k: R => C): PartialFunction[T1, C] = { case x => k(apply(x)) }
+}
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index b19c8d086c..258a176671 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -31,14 +31,16 @@ public final class BoxesRunTime
{
private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7;
+ /** We don't need to return BYTE and SHORT, as everything which might
+ * care widens to INT.
+ */
private static int typeCode(Object a) {
if (a instanceof java.lang.Integer) return INT;
- if (a instanceof java.lang.Byte) return BYTE;
- if (a instanceof java.lang.Character) return CHAR;
- if (a instanceof java.lang.Long) return LONG;
if (a instanceof java.lang.Double) return DOUBLE;
- if (a instanceof java.lang.Short) return SHORT;
+ if (a instanceof java.lang.Long) return LONG;
+ if (a instanceof java.lang.Character) return CHAR;
if (a instanceof java.lang.Float) return FLOAT;
+ if ((a instanceof java.lang.Byte) || (a instanceof java.lang.Short)) return INT;
return OTHER;
}
@@ -119,15 +121,6 @@ public final class BoxesRunTime
/* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */
- private static int eqTypeCode(Number a) {
- if ((a instanceof java.lang.Integer) || (a instanceof java.lang.Byte)) return INT;
- if (a instanceof java.lang.Long) return LONG;
- if (a instanceof java.lang.Double) return DOUBLE;
- if (a instanceof java.lang.Short) return INT;
- if (a instanceof java.lang.Float) return FLOAT;
- return OTHER;
- }
-
public static boolean equals(Object x, Object y) {
if (x == y) return true;
return equals2(x, y);
@@ -159,8 +152,8 @@ public final class BoxesRunTime
}
public static boolean equalsNumNum(java.lang.Number xn, java.lang.Number yn) {
- int xcode = eqTypeCode(xn);
- int ycode = eqTypeCode(yn);
+ int xcode = typeCode(xn);
+ int ycode = typeCode(yn);
switch (ycode > xcode ? ycode : xcode) {
case INT:
return xn.intValue() == yn.intValue();
@@ -192,8 +185,11 @@ public final class BoxesRunTime
}
private static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) {
+ if (yc == null)
+ return xn == null;
+
char ch = yc.charValue();
- switch (eqTypeCode(xn)) {
+ switch (typeCode(xn)) {
case INT:
return xn.intValue() == ch;
case LONG:
@@ -203,9 +199,6 @@ public final class BoxesRunTime
case DOUBLE:
return xn.doubleValue() == ch;
default:
- if (xn == null)
- return yc == null;
-
return xn.equals(yc);
}
}
@@ -271,6 +264,31 @@ public final class BoxesRunTime
else return a.hashCode();
}
+ private static int unboxCharOrInt(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).intValue();
+ }
+ private static long unboxCharOrLong(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).longValue();
+ }
+ private static float unboxCharOrFloat(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).floatValue();
+ }
+ private static double unboxCharOrDouble(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).doubleValue();
+ }
+
/* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */
/** arg1 + arg2 */
@@ -279,24 +297,16 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 + val2);
+ return boxToInteger(unboxCharOrInt(arg1, code1) + unboxCharOrInt(arg2, code2));
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 + val2);
+ return boxToLong(unboxCharOrLong(arg1, code1) + unboxCharOrLong(arg2, code2));
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 + val2);
+ return boxToFloat(unboxCharOrFloat(arg1, code1) + unboxCharOrFloat(arg2, code2));
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 + val2);
+ return boxToDouble(unboxCharOrDouble(arg1, code1) + unboxCharOrDouble(arg2, code2));
}
throw new NoSuchMethodException();
}
@@ -307,24 +317,16 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 - val2);
+ return boxToInteger(unboxCharOrInt(arg1, code1) - unboxCharOrInt(arg2, code2));
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 - val2);
+ return boxToLong(unboxCharOrLong(arg1, code1) - unboxCharOrLong(arg2, code2));
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 - val2);
+ return boxToFloat(unboxCharOrFloat(arg1, code1) - unboxCharOrFloat(arg2, code2));
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 - val2);
+ return boxToDouble(unboxCharOrDouble(arg1, code1) - unboxCharOrDouble(arg2, code2));
}
throw new NoSuchMethodException();
}
@@ -335,24 +337,16 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 * val2);
+ return boxToInteger(unboxCharOrInt(arg1, code1) * unboxCharOrInt(arg2, code2));
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 * val2);
+ return boxToLong(unboxCharOrLong(arg1, code1) * unboxCharOrLong(arg2, code2));
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 * val2);
+ return boxToFloat(unboxCharOrFloat(arg1, code1) * unboxCharOrFloat(arg2, code2));
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 * val2);
+ return boxToDouble(unboxCharOrDouble(arg1, code1) * unboxCharOrDouble(arg2, code2));
}
throw new NoSuchMethodException();
}
@@ -362,26 +356,16 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 / val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 / val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 / val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 / val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) / unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) / unboxCharOrLong(arg2, code2));
+ if (maxcode <= FLOAT)
+ return boxToFloat(unboxCharOrFloat(arg1, code1) / unboxCharOrFloat(arg2, code2));
+ if (maxcode <= DOUBLE)
+ return boxToDouble(unboxCharOrDouble(arg1, code1) / unboxCharOrDouble(arg2, code2));
+
throw new NoSuchMethodException();
}
@@ -390,26 +374,16 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 % val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 % val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 % val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 % val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) % unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) % unboxCharOrLong(arg2, code2));
+ if (maxcode <= FLOAT)
+ return boxToFloat(unboxCharOrFloat(arg1, code1) % unboxCharOrFloat(arg2, code2));
+ if (maxcode <= DOUBLE)
+ return boxToDouble(unboxCharOrDouble(arg1, code1) % unboxCharOrDouble(arg2, code2));
+
throw new NoSuchMethodException();
}
@@ -418,24 +392,24 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToInteger(val1 >> val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToInteger(val1 >> val2);
}
}
if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToLong(val1 >> val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToLong(val1 >> val2);
}
}
@@ -447,24 +421,24 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToInteger(val1 << val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToInteger(val1 << val2);
}
}
if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToLong(val1 << val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToLong(val1 << val2);
}
}
@@ -476,24 +450,24 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToInteger(val1 >>> val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToInteger(val1 >>> val2);
}
}
if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToLong(val1 >>> val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToLong(val1 >>> val2);
}
}
@@ -504,19 +478,19 @@ public final class BoxesRunTime
public static Object negate(Object arg) throws NoSuchMethodException {
int code = typeCode(arg);
if (code <= INT) {
- int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue();
+ int val = unboxCharOrInt(arg, code);
return boxToInteger(-val);
}
if (code <= LONG) {
- long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue();
+ long val = unboxCharOrLong(arg, code);
return boxToLong(-val);
}
if (code <= FLOAT) {
- float val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).floatValue();
+ float val = unboxCharOrFloat(arg, code);
return boxToFloat(-val);
}
if (code <= DOUBLE) {
- double val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).doubleValue();
+ double val = unboxCharOrDouble(arg, code);
return boxToDouble(-val);
}
throw new NoSuchMethodException();
@@ -526,20 +500,16 @@ public final class BoxesRunTime
public static Object positive(Object arg) throws NoSuchMethodException {
int code = typeCode(arg);
if (code <= INT) {
- int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue();
- return boxToInteger(+val);
+ return boxToInteger(+unboxCharOrInt(arg, code));
}
if (code <= LONG) {
- long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue();
- return boxToLong(+val);
+ return boxToLong(+unboxCharOrLong(arg, code));
}
if (code <= FLOAT) {
- float val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).floatValue();
- return boxToFloat(+val);
+ return boxToFloat(+unboxCharOrFloat(arg, code));
}
if (code <= DOUBLE) {
- double val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).doubleValue();
- return boxToDouble(+val);
+ return boxToDouble(+unboxCharOrDouble(arg, code));
}
throw new NoSuchMethodException();
}
@@ -547,72 +517,60 @@ public final class BoxesRunTime
/** arg1 & arg2 */
public static Object takeAnd(Object arg1, Object arg2) throws NoSuchMethodException {
if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue());
+ else
throw new NoSuchMethodException();
- }
- return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue());
}
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 & val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 & val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) & unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) & unboxCharOrLong(arg2, code2));
+
throw new NoSuchMethodException();
}
/** arg1 | arg2 */
public static Object takeOr(Object arg1, Object arg2) throws NoSuchMethodException {
if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() | ((java.lang.Boolean) arg2).booleanValue());
+ else
throw new NoSuchMethodException();
- }
- return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() | ((java.lang.Boolean) arg2).booleanValue());
}
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 | val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 | val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) | unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) | unboxCharOrLong(arg2, code2));
+
throw new NoSuchMethodException();
}
/** arg1 ^ arg2 */
public static Object takeXor(Object arg1, Object arg2) throws NoSuchMethodException {
if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() ^ ((java.lang.Boolean) arg2).booleanValue());
+ else
throw new NoSuchMethodException();
- }
- return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() ^ ((java.lang.Boolean) arg2).booleanValue());
}
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 ^ val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 ^ val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) ^ unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) ^ unboxCharOrLong(arg2, code2));
+
throw new NoSuchMethodException();
}
@@ -636,12 +594,10 @@ public final class BoxesRunTime
public static Object complement(Object arg) throws NoSuchMethodException {
int code = typeCode(arg);
if (code <= INT) {
- int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue();
- return boxToInteger(~val);
+ return boxToInteger(~unboxCharOrInt(arg, code));
}
if (code <= LONG) {
- long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue();
- return boxToLong(~val);
+ return boxToLong(~unboxCharOrLong(arg, code));
}
throw new NoSuchMethodException();
}
@@ -667,23 +623,23 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToBoolean(val1 < val2);
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToBoolean(val1 < val2);
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
return boxToBoolean(val1 < val2);
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
return boxToBoolean(val1 < val2);
}
throw new NoSuchMethodException();
@@ -694,23 +650,23 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToBoolean(val1 <= val2);
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToBoolean(val1 <= val2);
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
return boxToBoolean(val1 <= val2);
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
return boxToBoolean(val1 <= val2);
}
throw new NoSuchMethodException();
@@ -721,23 +677,23 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToBoolean(val1 >= val2);
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToBoolean(val1 >= val2);
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
return boxToBoolean(val1 >= val2);
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
return boxToBoolean(val1 >= val2);
}
throw new NoSuchMethodException();
@@ -748,33 +704,30 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToBoolean(val1 > val2);
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToBoolean(val1 > val2);
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
return boxToBoolean(val1 > val2);
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
return boxToBoolean(val1 > val2);
}
throw new NoSuchMethodException();
}
-
+
public static boolean isBoxedNumberOrBoolean(Object arg) {
- if (arg instanceof java.lang.Boolean)
- return true;
- else
- return isBoxedNumber(arg);
+ return (arg instanceof java.lang.Boolean) || isBoxedNumber(arg);
}
public static boolean isBoxedNumber(Object arg) {
return (
diff --git a/src/library/scala/runtime/RichDouble.scala b/src/library/scala/runtime/RichDouble.scala
index 0a9cda40ec..f702b9e3da 100644
--- a/src/library/scala/runtime/RichDouble.scala
+++ b/src/library/scala/runtime/RichDouble.scala
@@ -35,4 +35,16 @@ final class RichDouble(val self: Double) extends FractionalProxy[Double] {
def isInfinity: Boolean = java.lang.Double.isInfinite(self)
def isPosInfinity: Boolean = isInfinity && self > 0.0
def isNegInfinity: Boolean = isInfinity && self < 0.0
+
+ override def isValidByte = self.toByte.toDouble == self
+ override def isValidShort = self.toShort.toDouble == self
+ override def isValidChar = self.toChar.toDouble == self
+ override def isValidInt = self.toInt.toDouble == self
+ // override def isValidLong = { val l = self.toLong; l.toDouble == self && l != Long.MaxValue }
+ // override def isValidFloat = self.toFloat.toDouble == self
+ // override def isValidDouble = !java.lang.Double.isNaN(self)
+ override def isWhole = {
+ val l = self.toLong
+ l.toDouble == self || l == Long.MaxValue && self < Double.PositiveInfinity || l == Long.MinValue && self > Double.NegativeInfinity
+ }
}
diff --git a/src/library/scala/runtime/RichFloat.scala b/src/library/scala/runtime/RichFloat.scala
index c6478ec0c9..6b72a9dd55 100644
--- a/src/library/scala/runtime/RichFloat.scala
+++ b/src/library/scala/runtime/RichFloat.scala
@@ -36,4 +36,16 @@ final class RichFloat(val self: Float) extends FractionalProxy[Float] {
def isInfinity: Boolean = java.lang.Float.isInfinite(self)
def isPosInfinity: Boolean = isInfinity && self > 0.0f
def isNegInfinity: Boolean = isInfinity && self < 0.0f
+
+ override def isValidByte = self.toByte.toFloat == self
+ override def isValidShort = self.toShort.toFloat == self
+ override def isValidChar = self.toChar.toFloat == self
+ override def isValidInt = { val i = self.toInt; i.toFloat == self && i != Int.MaxValue }
+ // override def isValidLong = { val l = self.toLong; l.toFloat == self && l != Long.MaxValue }
+ // override def isValidFloat = !java.lang.Float.isNaN(self)
+ // override def isValidDouble = !java.lang.Float.isNaN(self)
+ override def isWhole = {
+ val l = self.toLong
+ l.toFloat == self || l == Long.MaxValue && self < Float.PositiveInfinity || l == Long.MinValue && self > Float.NegativeInfinity
+ }
}
diff --git a/src/library/scala/runtime/RichFunction1.scala b/src/library/scala/runtime/RichFunction1.scala
new file mode 100644
index 0000000000..26651b8d6a
--- /dev/null
+++ b/src/library/scala/runtime/RichFunction1.scala
@@ -0,0 +1,27 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.runtime
+
+@inline final class RichFunction1[-T1, +R](f: T1 => R) {
+ /** Composes two instances of Function1 in a new Function1, with the function on the left applied last.
+ *
+ * @tparam A the type to which function `g` can be applied
+ * @param g a function A => T1
+ * @return a new function `h` such that `h(x) == f(g(x))`
+ */
+ def compose[A](g: A => T1): A => R = { x => f(g(x)) }
+
+ /** Composes two instances of Function1 in a new Function1, with the function on the left applied first.
+ *
+ * @tparam A the result type of function `g`
+ * @param g a function R => A
+ * @return a new function `h` such that `h(x) == g(f(x))`
+ */
+ def andThen[A](g: R => A): T1 => A = { x => g(f(x)) }
+}
diff --git a/src/library/scala/runtime/RichFunction2.scala b/src/library/scala/runtime/RichFunction2.scala
new file mode 100644
index 0000000000..14e23be31b
--- /dev/null
+++ b/src/library/scala/runtime/RichFunction2.scala
@@ -0,0 +1,26 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.runtime
+
+@inline final class RichFunction2[-T1, -T2, +R](f: (T1, T2) => R) {
+ /** Creates a curried version of this function.
+ *
+ * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)`
+ */
+ def curried: T1 => T2 => R = (x1: T1) => (x2: T2) => f(x1, x2)
+
+ /** Creates a tupled version of this function: instead of 2 arguments,
+ * it accepts a single [[scala.Tuple2]] argument.
+ *
+ * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)`
+ */
+ def tupled: ((T1, T2)) => R = {
+ case Tuple2(x1, x2) => f(x1, x2)
+ }
+}
diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala
index f93d9459d1..5784934ffd 100644
--- a/src/library/scala/runtime/RichLong.scala
+++ b/src/library/scala/runtime/RichLong.scala
@@ -12,4 +12,12 @@ final class RichLong(val self: Long) extends IntegralProxy[Long] {
def toBinaryString: String = java.lang.Long.toBinaryString(self)
def toHexString: String = java.lang.Long.toHexString(self)
def toOctalString: String = java.lang.Long.toOctalString(self)
+
+ override def isValidByte = self.toByte.toLong == self
+ override def isValidShort = self.toShort.toLong == self
+ override def isValidChar = self.toChar.toLong == self
+ override def isValidInt = self.toInt.toLong == self
+ // override def isValidLong = true
+ // override def isValidFloat = self.toFloat.toLong == self && self != Long.MaxValue
+ // override def isValidDouble = self.toDouble.toLong == self && self != Long.MaxValue
}
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 8bc63ae3a0..9d67644d61 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -31,7 +31,7 @@ object ScalaRunTime {
clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1))
def isValueClass(clazz: Class[_]) = clazz.isPrimitive()
- def isTuple(x: Any) = tupleNames(x.getClass.getName)
+ def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName)
def isAnyVal(x: Any) = x match {
case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true
case _ => false
@@ -47,21 +47,29 @@ object ScalaRunTime {
names.toSet
}
+ /** Return the class object representing an array with element class `clazz`.
+ */
+ def arrayClass(clazz: Class[_]): Class[_] = {
+ // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680
+ if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]]
+ else java.lang.reflect.Array.newInstance(clazz, 0).getClass
+ }
+
+ /** Return the class object representing elements in arrays described by a given schematic.
+ */
+ def arrayElementClass(schematic: Any): Class[_] = schematic match {
+ case cls: Class[_] => cls.getComponentType
+ case tag: ClassTag[_] => tag.erasure
+ case tag: ArrayTag[_] => tag.newArray(0).getClass.getComponentType
+ case _ => throw new UnsupportedOperationException("unsupported schematic %s (%s)".format(schematic, if (schematic == null) "null" else schematic.getClass))
+ }
+
/** Return the class object representing an unboxed value type,
* e.g. classOf[int], not classOf[java.lang.Integer]. The compiler
* rewrites expressions like 5.getClass to come here.
*/
- def anyValClass[T <: AnyVal](value: T): Class[T] = (value match {
- case x: Byte => java.lang.Byte.TYPE
- case x: Short => java.lang.Short.TYPE
- case x: Char => java.lang.Character.TYPE
- case x: Int => java.lang.Integer.TYPE
- case x: Long => java.lang.Long.TYPE
- case x: Float => java.lang.Float.TYPE
- case x: Double => java.lang.Double.TYPE
- case x: Boolean => java.lang.Boolean.TYPE
- case x: Unit => java.lang.Void.TYPE
- }).asInstanceOf[Class[T]]
+ def anyValClass[T <: AnyVal : ClassTag](value: T): Class[T] =
+ classTag[T].erasure.asInstanceOf[Class[T]]
/** Retrieve generic array element */
def array_apply(xs: AnyRef, idx: Int): Any = xs match {
@@ -329,14 +337,14 @@ object ScalaRunTime {
case null => "null"
case "" => "\"\""
case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x
- case x if useOwnToString(x) => x toString
+ case x if useOwnToString(x) => x.toString
case x: AnyRef if isArray(x) => arrayToString(x)
case x: collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")")
case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma
case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")")
- case x => x toString
+ case x => x.toString
}
// The try/catch is defense against iterables which aren't actually designed
diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala
new file mode 100644
index 0000000000..2eb2a47e46
--- /dev/null
+++ b/src/library/scala/runtime/Tuple2Zipped.scala
@@ -0,0 +1,109 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.runtime
+
+import scala.collection.{ TraversableLike => TLike, IterableLike => ILike }
+import scala.collection.generic.{ CanBuildFrom => CBF }
+
+ /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc.
+ * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]]
+ * or [[scala.collection.IterableLike]].
+ * {{{
+ * scala> val tuple = (List(1,2,3),List('a','b','c'))
+ * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c))
+ *
+ * scala> tuple.zipped map { (x,y) => x + ":" + y }
+ * res6: List[java.lang.String] = List(1:a, 2:b, 3:c)
+ * }}}
+ *
+ * @see Zipped
+ * Note: will not terminate for infinite-sized collections.
+ */
+@inline private[scala] final class Tuple2Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) {
+ // coll2: ILike for filter
+ def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = {
+ val b = cbf(coll1.repr)
+ b.sizeHint(coll1)
+ val elems2 = coll2.iterator
+
+ for (el1 <- coll1) {
+ if (elems2.hasNext)
+ b += f(el1, elems2.next)
+ else
+ return b.result
+ }
+
+ b.result
+ }
+
+ def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = {
+ val b = cbf(coll1.repr)
+ val elems2 = coll2.iterator
+
+ for (el1 <- coll1) {
+ if (elems2.hasNext)
+ b ++= f(el1, elems2.next)
+ else
+ return b.result
+ }
+
+ b.result
+ }
+
+ def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = {
+ val b1 = cbf1(coll1.repr)
+ val b2 = cbf2(coll2.repr)
+ val elems2 = coll2.iterator
+
+ for (el1 <- coll1) {
+ if (elems2.hasNext) {
+ val el2 = elems2.next
+ if (f(el1, el2)) {
+ b1 += el1
+ b2 += el2
+ }
+ }
+ else return (b1.result, b2.result)
+ }
+
+ (b1.result, b2.result)
+ }
+
+ def exists(f: (El1, El2) => Boolean): Boolean = {
+ val elems2 = coll2.iterator
+
+ for (el1 <- coll1) {
+ if (elems2.hasNext) {
+ if (f(el1, elems2.next))
+ return true
+ }
+ else return false
+ }
+ false
+ }
+
+ def forall(f: (El1, El2) => Boolean): Boolean =
+ !exists((x, y) => !f(x, y))
+
+ def foreach[U](f: (El1, El2) => U): Unit = {
+ val elems2 = coll2.iterator
+
+ for (el1 <- coll1) {
+ if (elems2.hasNext)
+ f(el1, elems2.next)
+ else
+ return
+ }
+ }
+}
+
+@inline private[scala] final class Tuple2ZippedOps[T1, T2](zz: (T1, T2)) {
+ def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]) =
+ new Tuple2Zipped[Repr1, El1, Repr2, El2](w1(zz._1), w2(zz._2))
+}
diff --git a/src/library/scala/sys/BooleanProp.scala b/src/library/scala/sys/BooleanProp.scala
index e940990785..45fc6f5897 100644
--- a/src/library/scala/sys/BooleanProp.scala
+++ b/src/library/scala/sys/BooleanProp.scala
@@ -8,6 +8,8 @@
package scala.sys
+import language.implicitConversions
+
/** A few additional conveniences for Boolean properties.
*/
trait BooleanProp extends Prop[Boolean] {
diff --git a/src/library/scala/sys/SystemProperties.scala b/src/library/scala/sys/SystemProperties.scala
index 52e0ac230b..4853da3495 100644
--- a/src/library/scala/sys/SystemProperties.scala
+++ b/src/library/scala/sys/SystemProperties.scala
@@ -11,6 +11,8 @@ package scala.sys
import scala.collection.{ mutable, Iterator }
import scala.collection.JavaConverters._
import java.security.AccessControlException
+import language.implicitConversions
+
/** A bidirectional map wrapping the java System properties.
* Changes to System properties will be immediately visible in the map,
diff --git a/src/library/scala/sys/process/Process.scala b/src/library/scala/sys/process/Process.scala
index c2a61af936..d56c6f2c9d 100644
--- a/src/library/scala/sys/process/Process.scala
+++ b/src/library/scala/sys/process/Process.scala
@@ -11,6 +11,7 @@ package process
import processInternal._
import ProcessBuilder._
+import language.implicitConversions
/** Represents a process that is running or has finished running.
* It may be a compound process with several underlying native processes (such as `a #&& b`).
diff --git a/src/library/scala/testing/Show.scala b/src/library/scala/testing/Show.scala
index b0d094e466..5ab46b8985 100644
--- a/src/library/scala/testing/Show.scala
+++ b/src/library/scala/testing/Show.scala
@@ -11,7 +11,7 @@
package scala.testing
/** Classes inheriting trait `Show` can test their member methods using the
- * notattion `meth(arg,,1,,, ..., arg,,n,,)`, where `meth` is the name of
+ * notation `meth(arg,,1,,, ..., arg,,n,,)`, where `meth` is the name of
* the method and `arg,,1,,,...,arg,,n,,` are the arguments.
*
* The only difference to a normal method call is the leading quote
@@ -27,17 +27,17 @@ package scala.testing
*/
trait Show {
- /** The result class of wrapper `symApply`.
+ /** An implicit definition that adds an apply method to Symbol which forwards to `test`.
* Prints out diagnostics of method applications.
*/
- class SymApply(f: Symbol) {
+ implicit class SymApply(f: Symbol) {
def apply[A](args: A*) {
println(test(f, args: _*))
}
}
- /** An implicit definition that adds an apply method to Symbol which forwards to `test`. */
- implicit def symApply(sym: Symbol) = new SymApply(sym)
+ @deprecated("use SymApply instead", "2.10")
+ def symApply(sym: Symbol): SymApply = new SymApply(sym)
/** Apply method with name of given symbol `f` to given arguments and return
* a result diagnostics.
diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala
index daeaf4c53b..e2ebe7851c 100644
--- a/src/library/scala/util/Marshal.scala
+++ b/src/library/scala/util/Marshal.scala
@@ -11,19 +11,19 @@
package scala.util
/**
- * Marshalling of Scala objects using Scala manifests.
+ * Marshalling of Scala objects using Scala tags.
*
* @author Stephane Micheloud
* @version 1.0
*/
object Marshal {
import java.io._
- import scala.reflect.ClassManifest
+ import scala.reflect.ClassTag
- def dump[A](o: A)(implicit m: ClassManifest[A]): Array[Byte] = {
+ def dump[A](o: A)(implicit t: ClassTag[A]): Array[Byte] = {
val ba = new ByteArrayOutputStream(512)
val out = new ObjectOutputStream(ba)
- out.writeObject(m)
+ out.writeObject(t)
out.writeObject(o)
out.close()
ba.toByteArray()
@@ -32,19 +32,20 @@ object Marshal {
@throws(classOf[IOException])
@throws(classOf[ClassCastException])
@throws(classOf[ClassNotFoundException])
- def load[A](buffer: Array[Byte])(implicit expected: ClassManifest[A]): A = {
+ def load[A](buffer: Array[Byte])(implicit expected: ClassTag[A]): A = {
val in = new ObjectInputStream(new ByteArrayInputStream(buffer))
- val found = in.readObject.asInstanceOf[ClassManifest[_]]
- if (found <:< expected) {
- val o = in.readObject.asInstanceOf[A]
- in.close()
- o
- } else {
- in.close()
- throw new ClassCastException("type mismatch;"+
- "\n found : "+found+
- "\n required: "+expected)
+ val found = in.readObject.asInstanceOf[ClassTag[_]]
+ try {
+ // [Eugene] needs review
+ // previously was: found <:< expected
+ found.erasure.asSubclass(expected.erasure)
+ in.readObject.asInstanceOf[A]
+ } catch {
+ case _: ClassCastException =>
+ in.close()
+ throw new ClassCastException("type mismatch;"+
+ "\n found : "+found+
+ "\n required: "+expected)
}
}
-
}
diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala
index 791582c9ec..17c356801b 100644
--- a/src/library/scala/util/Random.scala
+++ b/src/library/scala/util/Random.scala
@@ -11,6 +11,7 @@ package scala.util
import collection.mutable.ArrayBuffer
import collection.generic.CanBuildFrom
import scala.collection.immutable.{ List, Stream }
+import language.{implicitConversions, higherKinds}
/**
* @author Stephane Micheloud
@@ -117,18 +118,9 @@ class Random(val self: java.util.Random) {
swap(n - 1, k)
}
- bf(xs) ++= buf result
+ (bf(xs) ++= buf).result
}
-}
-
-/** The object `Random` offers a default implementation
- * of scala.util.Random and random-related convenience methods.
- *
- * @since 2.8
- */
-object Random extends Random {
-
/** Returns a Stream of pseudorandomly chosen alphanumeric characters,
* equally chosen from A-Z, a-z, and 0-9.
*
@@ -141,3 +133,14 @@ object Random extends Random {
}
}
+
+/** The object `Random` offers a default implementation
+ * of scala.util.Random and random-related convenience methods.
+ *
+ * @since 2.8
+ */
+object Random extends Random {
+
+ implicit def javaRandomToRandom(r: java.util.Random): Random = new Random(r)
+
+}
diff --git a/src/library/scala/util/Sorting.scala b/src/library/scala/util/Sorting.scala
index bf460a118f..7d98e57741 100644
--- a/src/library/scala/util/Sorting.scala
+++ b/src/library/scala/util/Sorting.scala
@@ -8,7 +8,7 @@
package scala.util
-import scala.reflect.ClassManifest
+import scala.reflect.ClassTag
import scala.math.Ordering
/** The Sorting object provides functions that can sort various kinds of
@@ -39,14 +39,14 @@ object Sorting {
/** Sort an array of K where K is Ordered, preserving the existing order
* where the values are equal. */
- def stableSort[K: ClassManifest: Ordering](a: Array[K]) {
+ def stableSort[K: ArrayTag: Ordering](a: Array[K]) {
stableSort(a, 0, a.length-1, new Array[K](a.length), Ordering[K].lt _)
}
/** Sorts an array of `K` given an ordering function `f`.
* `f` should return `true` iff its first parameter is strictly less than its second parameter.
*/
- def stableSort[K: ClassManifest](a: Array[K], f: (K, K) => Boolean) {
+ def stableSort[K: ArrayTag](a: Array[K], f: (K, K) => Boolean) {
stableSort(a, 0, a.length-1, new Array[K](a.length), f)
}
@@ -57,14 +57,14 @@ object Sorting {
* @param f the comparison function.
* @return the sorted sequence of items.
*/
- def stableSort[K: ClassManifest](a: Seq[K], f: (K, K) => Boolean): Array[K] = {
+ def stableSort[K: ArrayTag](a: Seq[K], f: (K, K) => Boolean): Array[K] = {
val ret = a.toArray
stableSort(ret, f)
ret
}
/** Sorts an arbitrary sequence of items that are viewable as ordered. */
- def stableSort[K: ClassManifest: Ordering](a: Seq[K]): Array[K] =
+ def stableSort[K: ArrayTag: Ordering](a: Seq[K]): Array[K] =
stableSort(a, Ordering[K].lt _)
/** Stably sorts a sequence of items given an extraction function that will
@@ -74,8 +74,8 @@ object Sorting {
* @param f the comparison function.
* @return the sorted sequence of items.
*/
- def stableSort[K: ClassManifest, M: Ordering](a: Seq[K], f: K => M): Array[K] =
- stableSort(a)(implicitly[ClassManifest[K]], Ordering[M] on f)
+ def stableSort[K: ArrayTag, M: Ordering](a: Seq[K], f: K => M): Array[K] =
+ stableSort(a)(implicitly[ArrayTag[K]], Ordering[M] on f)
private def sort1[K: Ordering](x: Array[K], off: Int, len: Int) {
val ord = Ordering[K]
@@ -498,7 +498,7 @@ object Sorting {
sort2(off, len)
}
- private def stableSort[K : ClassManifest](a: Array[K], lo: Int, hi: Int, scratch: Array[K], f: (K,K) => Boolean) {
+ private def stableSort[K : ArrayTag](a: Array[K], lo: Int, hi: Int, scratch: Array[K], f: (K,K) => Boolean) {
if (lo < hi) {
val mid = (lo+hi) / 2
stableSort(a, lo, mid, scratch, f)
diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala
index c9bde81317..efa2fcabb8 100644
--- a/src/library/scala/util/Try.scala
+++ b/src/library/scala/util/Try.scala
@@ -101,9 +101,9 @@ sealed abstract class Try[+T] {
}
-final case class Failure[+T](val exception: Throwable) extends Try[T] {
- def isFailure = true
- def isSuccess = false
+final class Failure[+T](val exception: Throwable) extends Try[T] {
+ def isFailure: Boolean = true
+ def isSuccess: Boolean = false
def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U] = {
try {
if (rescueException.isDefinedAt(exception)) rescueException(exception) else this
@@ -129,30 +129,49 @@ final case class Failure[+T](val exception: Throwable) extends Try[T] {
}
-final case class Success[+T](r: T) extends Try[T] {
- def isFailure = false
- def isSuccess = true
- def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U] = Success(r)
- def get = r
+final class Success[+T](value: T) extends Try[T] {
+ def isFailure: Boolean = false
+ def isSuccess: Boolean = true
+ def rescue[U >: T](rescueException: PartialFunction[Throwable, Try[U]]): Try[U] = Success(value)
+ def get = value
def flatMap[U](f: T => Try[U]): Try[U] =
- try f(r)
+ try f(value)
catch {
case e => Failure(e)
}
- def flatten[U](implicit ev: T <:< Try[U]): Try[U] = r
- def foreach[U](f: T => U): Unit = f(r)
- def map[U](f: T => U): Try[U] = Try[U](f(r))
+ def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value
+ def foreach[U](f: T => U): Unit = f(value)
+ def map[U](f: T => U): Try[U] = Try[U](f(value))
def collect[U](pf: PartialFunction[T, U]): Try[U] =
- if (pf isDefinedAt r) Success(pf(r))
- else Failure[U](new NoSuchElementException("Partial function not defined at " + r))
+ if (pf isDefinedAt value) Success(pf(value))
+ else Failure[U](new NoSuchElementException("Partial function not defined at " + value))
def filter(p: T => Boolean): Try[T] =
- if (p(r)) this
- else Failure(new NoSuchElementException("Predicate does not hold for " + r))
+ if (p(value)) this
+ else Failure(new NoSuchElementException("Predicate does not hold for " + value))
def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] = this
- def exists(p: T => Boolean): Boolean = p(r)
+ def exists(p: T => Boolean): Boolean = p(value)
def failed: Try[Throwable] = Failure(new UnsupportedOperationException("Success.failed"))
}
+object Failure {
+ def apply[T](e: Throwable): Failure[T] = new Failure(e)
+ def unapply(scrutinizee: Any): Option[Throwable] = scrutinizee match {
+ case Right(_) => None
+ case Left(e) => Some(e.asInstanceOf[Throwable])
+ case s: Success[_] => None
+ case f: Failure[_] => Some(f.exception)
+ }
+}
+
+object Success {
+ def apply[T](value: T): Success[T] = new Success(value)
+ def unapply[T](scrutinizee: Any): Option[T] = scrutinizee match {
+ case Right(v) => Some(v.asInstanceOf[T])
+ case Left(_) => None
+ case s: Success[_] => Some(s.get.asInstanceOf[T])
+ case f: Failure[Throwable] => None
+ }
+}
object Try {
diff --git a/src/library/scala/util/automata/BaseBerrySethi.scala b/src/library/scala/util/automata/BaseBerrySethi.scala
index 18f36f9496..c78b2d0790 100644
--- a/src/library/scala/util/automata/BaseBerrySethi.scala
+++ b/src/library/scala/util/automata/BaseBerrySethi.scala
@@ -78,7 +78,7 @@ abstract class BaseBerrySethi {
* @return ...
*/
protected def compFollow1(fol1: Set[Int], r: RegExp): Set[Int] = r match {
- case x: Alt => Set(x.rs reverseMap (compFollow1(fol1, _)) flatten: _*)
+ case x: Alt => Set((x.rs reverseMap (compFollow1(fol1, _))).flatten: _*)
case x: Meta => compFollow1(fol1, x.r)
case x: Star => compFollow1(fol1 ++ compFirst(x.r), x.r)
case x: Sequ =>
diff --git a/src/library/scala/util/automata/NondetWordAutom.scala b/src/library/scala/util/automata/NondetWordAutom.scala
index fbc05de7fd..b09e82ca11 100644
--- a/src/library/scala/util/automata/NondetWordAutom.scala
+++ b/src/library/scala/util/automata/NondetWordAutom.scala
@@ -50,8 +50,8 @@ abstract class NondetWordAutom[T <: AnyRef] {
override def toString = {
val finalString = Map(finalStates map (j => j -> finals(j)) : _*).toString
- val deltaString = (0 until nstates) .
- map (i => " %d->%s\n _>%s\n".format(i, delta(i), default(i))) mkString
+ val deltaString = (0 until nstates)
+ .map(i => " %d->%s\n _>%s\n".format(i, delta(i), default(i))).mkString
"[NondetWordAutom nstates=%d finals=%s delta=\n%s".format(nstates, finalString, deltaString)
}
diff --git a/src/library/scala/util/automata/SubsetConstruction.scala b/src/library/scala/util/automata/SubsetConstruction.scala
index 8049d10d88..81805fce2f 100644
--- a/src/library/scala/util/automata/SubsetConstruction.scala
+++ b/src/library/scala/util/automata/SubsetConstruction.scala
@@ -14,7 +14,7 @@ class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) {
import nfa.labels
def selectTag(Q: immutable.BitSet, finals: Array[Int]) =
- Q map finals filter (_ > 0) min
+ (Q map finals filter (_ > 0)).min
def determinize: DetWordAutom[T] = {
// for assigning numbers to bitsets
diff --git a/src/library/scala/util/automata/WordBerrySethi.scala b/src/library/scala/util/automata/WordBerrySethi.scala
index 84b78d8dd8..a7ad92e648 100644
--- a/src/library/scala/util/automata/WordBerrySethi.scala
+++ b/src/library/scala/util/automata/WordBerrySethi.scala
@@ -139,7 +139,7 @@ abstract class WordBerrySethi extends BaseBerrySethi {
finals = finals.updated(0, finalTag)
val delta1 = immutable.Map(deltaq.zipWithIndex map (_.swap): _*)
- val finalsArr = 0 until pos map (k => finals.getOrElse(k, 0)) toArray // 0 == not final
+ val finalsArr = (0 until pos map (k => finals.getOrElse(k, 0))).toArray // 0 == not final
val initialsArr = initials.toArray
val deltaArr: Array[mutable.Map[_labelT, immutable.BitSet]] =
@@ -147,7 +147,7 @@ abstract class WordBerrySethi extends BaseBerrySethi {
mutable.HashMap(delta1(x).toSeq map { case (k, v) => k -> immutable.BitSet(v: _*) } : _*)
}).toArray
- val defaultArr = 0 until pos map (k => immutable.BitSet(defaultq(k): _*)) toArray
+ val defaultArr = (0 until pos map (k => immutable.BitSet(defaultq(k): _*))).toArray
new NondetWordAutom[_labelT] {
val nstates = pos
@@ -161,4 +161,4 @@ abstract class WordBerrySethi extends BaseBerrySethi {
automatonFrom(Sequ(z.asInstanceOf[this.lang._regexpT]), finalTag)
}
}
-} \ No newline at end of file
+}
diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala
index 5e3f8b6451..38f4abb20a 100644
--- a/src/library/scala/util/control/Exception.scala
+++ b/src/library/scala/util/control/Exception.scala
@@ -10,6 +10,8 @@ package scala.util.control
import collection.immutable.List
import java.lang.reflect.InvocationTargetException
+import language.implicitConversions
+
/** Classes representing the components of exception handling.
* Each class is independently composable. Some example usages:
@@ -28,9 +30,9 @@ import java.lang.reflect.InvocationTargetException
object Exception {
type Catcher[+T] = PartialFunction[Throwable, T]
- def mkCatcher[Ex <: Throwable: ClassManifest, T](isDef: Ex => Boolean, f: Ex => T) = new Catcher[T] {
+ def mkCatcher[Ex <: Throwable: ClassTag, T](isDef: Ex => Boolean, f: Ex => T) = new Catcher[T] {
private def downcast(x: Throwable): Option[Ex] =
- if (classManifest[Ex].erasure.isAssignableFrom(x.getClass)) Some(x.asInstanceOf[Ex])
+ if (classTag[Ex].erasure.isAssignableFrom(x.getClass)) Some(x.asInstanceOf[Ex])
else None
def isDefinedAt(x: Throwable) = downcast(x) exists isDef
@@ -39,7 +41,7 @@ object Exception {
def mkThrowableCatcher[T](isDef: Throwable => Boolean, f: Throwable => T) = mkCatcher(isDef, f)
- implicit def throwableSubtypeToCatcher[Ex <: Throwable: ClassManifest, T](pf: PartialFunction[Ex, T]) =
+ implicit def throwableSubtypeToCatcher[Ex <: Throwable: ClassTag, T](pf: PartialFunction[Ex, T]) =
mkCatcher(pf.isDefinedAt _, pf.apply _)
/** !!! Not at all sure of every factor which goes into this,
@@ -230,8 +232,5 @@ object Exception {
classes exists (_ isAssignableFrom x.getClass)
private def pfFromExceptions(exceptions: Class[_]*): PartialFunction[Throwable, Nothing] =
- new scala.runtime.AbstractPartialFunction[Throwable, Nothing] {
- def apply(x: Throwable) = throw x
- def _isDefinedAt(x: Throwable) = wouldMatch(x, exceptions)
- }
+ { case x if wouldMatch(x, exceptions) => throw x }
}
diff --git a/src/library/scala/util/control/NoStackTrace.scala b/src/library/scala/util/control/NoStackTrace.scala
index dff29c86b4..c2b5dbca22 100644
--- a/src/library/scala/util/control/NoStackTrace.scala
+++ b/src/library/scala/util/control/NoStackTrace.scala
@@ -23,5 +23,9 @@ trait NoStackTrace extends Throwable {
}
object NoStackTrace {
- final val noSuppression = sys.SystemProperties.noTraceSupression.value
+ final def noSuppression = _noSuppression
+
+ // two-stage init to make checkinit happy, since sys.SystemProperties.noTraceSupression.value calls back into NoStackTrace.noSuppression
+ final private var _noSuppression = false
+ _noSuppression = sys.SystemProperties.noTraceSupression.value
}
diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala
index ca97515e23..a83619cf01 100644
--- a/src/library/scala/util/matching/Regex.scala
+++ b/src/library/scala/util/matching/Regex.scala
@@ -133,6 +133,15 @@ import java.util.regex.{ Pattern, Matcher }
*
* @param regex A string representing a regular expression
* @param groupNames A mapping from names to indices in capture groups
+ *
+ * @define replacementString
+ * In the replacement String, a dollar sign (`$`) followed by a number will be
+ * interpreted as a reference to a group in the matched pattern, with numbers
+ * 1 through 9 corresponding to the first nine groups, and 0 standing for the
+ * whole match. Any other character is an error. The backslash (`\`) character
+ * will be interpreted as an escape character, and can be used to escape the
+ * dollar sign. One can use [[scala.util.matching.Regex]]'s `quoteReplacement`
+ * to automatically escape these characters.
*/
@SerialVersionUID(-2094783597747625537L)
class Regex(regex: String, groupNames: String*) extends Serializable {
@@ -180,7 +189,7 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
None
}
- /** Return all matches of this regexp in given character sequence as a [[scala.util.mathcing.Regex.MatchIterator]],
+ /** Return all matches of this regexp in given character sequence as a [[scala.util.matching.Regex.MatchIterator]],
* which is a special [[scala.collection.Iterator]] that returns the
* matched strings, but can also be converted into a normal iterator
* that returns objects of type [[scala.util.matching.Regex.Match]]
@@ -193,6 +202,25 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
*/
def findAllIn(source: java.lang.CharSequence) = new Regex.MatchIterator(source, this, groupNames)
+
+ /** Return all matches of this regexp in given character sequence as a
+ * [[scala.collection.Iterator]] of [[scala.util.matching.Regex.Match]].
+ *
+ * @param source The text to match against.
+ * @return A [[scala.collection.Iterator]] of [[scala.util.matching.Regex.Match]] for all matches.
+ * @example {{{for (words <- """\w+""".r findAllMatchIn "A simple example.") yield words.start}}}
+ */
+ def findAllMatchIn(source: java.lang.CharSequence): Iterator[Match] = {
+ val matchIterator = findAllIn(source)
+ new Iterator[Match] {
+ def hasNext = matchIterator.hasNext
+ def next: Match = {
+ matchIterator.next;
+ new Match(matchIterator.source, matchIterator.matcher, matchIterator.groupNames).force
+ }
+ }
+ }
+
/** Return optionally first matching string of this regexp in given character sequence,
* or None if it does not exist.
*
@@ -258,6 +286,8 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
/** Replaces all matches by a string.
*
+ * $replacementString
+ *
* @param target The string to match
* @param replacement The string that will replace each match
* @return The resulting string
@@ -280,6 +310,8 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
* val repl = datePattern replaceAllIn (text, m => m.group("month")+"/"+m.group("day"))
* }}}
*
+ * $replacementString
+ *
* @param target The string to match.
* @param replacer The function which maps a match to another string.
* @return The target string after replacements.
@@ -298,13 +330,15 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
* {{{
* import scala.util.matching.Regex._
*
- * val map = Map("x" -> "a var", "y" -> "another var")
+ * val map = Map("x" -> "a var", "y" -> """some $ and \ signs""")
* val text = "A text with variables %x, %y and %z."
* val varPattern = """%(\w+)""".r
- * val mapper = (m: Match) => map get (m group 1)
+ * val mapper = (m: Match) => map get (m group 1) map (quoteReplacement(_))
* val repl = varPattern replaceSomeIn (text, mapper)
* }}}
*
+ * $replacementString
+ *
* @param target The string to match.
* @param replacer The function which optionally maps a match to another string.
* @return The target string after replacements.
@@ -319,6 +353,8 @@ class Regex(regex: String, groupNames: String*) extends Serializable {
/** Replaces the first match by a string.
*
+ * $replacementString
+ *
* @param target The string to match
* @param replacement The string that will replace the match
* @return The resulting string
@@ -505,7 +541,7 @@ object Regex {
class MatchIterator(val source: java.lang.CharSequence, val regex: Regex, val groupNames: Seq[String])
extends AbstractIterator[String] with Iterator[String] with MatchData { self =>
- protected val matcher = regex.pattern.matcher(source)
+ protected[Regex] val matcher = regex.pattern.matcher(source)
private var nextSeen = false
/** Is there another match? */
@@ -569,4 +605,18 @@ object Regex {
def replace(rs: String) = matcher.appendReplacement(sb, rs)
}
+
+ /** Quotes replacement strings to be used in replacement methods.
+ *
+ * Replacement methods give special meaning to backslashes (`\`) and
+ * dollar signs (`$`) in replacement strings, so they are not treated
+ * as literals. This method escapes these characters so the resulting
+ * string can be used as a literal replacement representing the input
+ * string.
+ *
+ * @param text The string one wishes to use as literal replacement.
+ * @return A string that can be used to replace matches with `text`.
+ * @example {{{"CURRENCY".r.replaceAllIn(input, Regex quoteReplacement "US$")}}}
+ */
+ def quoteReplacement(text: String): String = Matcher quoteReplacement text
}
diff --git a/src/library/scala/util/parsing/ast/Binders.scala b/src/library/scala/util/parsing/ast/Binders.scala
index 0646f57064..09ad5ce2ab 100644
--- a/src/library/scala/util/parsing/ast/Binders.scala
+++ b/src/library/scala/util/parsing/ast/Binders.scala
@@ -10,6 +10,7 @@ package scala.util.parsing.ast
import scala.collection.AbstractIterable
import scala.collection.mutable
+import language.implicitConversions
//DISCLAIMER: this code is highly experimental!
diff --git a/src/library/scala/util/parsing/combinator/ImplicitConversions.scala b/src/library/scala/util/parsing/combinator/ImplicitConversions.scala
index e993628e88..270ac680a9 100644
--- a/src/library/scala/util/parsing/combinator/ImplicitConversions.scala
+++ b/src/library/scala/util/parsing/combinator/ImplicitConversions.scala
@@ -9,6 +9,8 @@
package scala.util.parsing.combinator
+import language.implicitConversions
+
/** This object contains implicit conversions that come in handy when using the `^^` combinator.
*
* Refer to [[scala.util.parsing.combinator.Parsers]] to construct an AST from the concrete syntax.
diff --git a/src/library/scala/util/parsing/combinator/PackratParsers.scala b/src/library/scala/util/parsing/combinator/PackratParsers.scala
index ea856efc3a..9516df0093 100644
--- a/src/library/scala/util/parsing/combinator/PackratParsers.scala
+++ b/src/library/scala/util/parsing/combinator/PackratParsers.scala
@@ -11,6 +11,7 @@ package scala.util.parsing.combinator
import scala.util.parsing.combinator._
import scala.util.parsing.input.{ Reader, Position }
import scala.collection.mutable
+import language.implicitConversions
/**
* `PackratParsers` is a component that extends the parser combinators
diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala
index 9aaf0aeb54..e5458f89af 100644
--- a/src/library/scala/util/parsing/combinator/Parsers.scala
+++ b/src/library/scala/util/parsing/combinator/Parsers.scala
@@ -12,6 +12,7 @@ import scala.util.parsing.input._
import scala.collection.mutable.ListBuffer
import scala.annotation.tailrec
import annotation.migration
+import language.implicitConversions
// TODO: better error handling (labelling like parsec's <?>)
diff --git a/src/library/scala/util/parsing/combinator/RegexParsers.scala b/src/library/scala/util/parsing/combinator/RegexParsers.scala
index 86eecd03c4..d685329ef1 100644
--- a/src/library/scala/util/parsing/combinator/RegexParsers.scala
+++ b/src/library/scala/util/parsing/combinator/RegexParsers.scala
@@ -13,6 +13,7 @@ import java.util.regex.Pattern
import scala.util.matching.Regex
import scala.util.parsing.input._
import scala.collection.immutable.PagedSeq
+import language.implicitConversions
/** The ''most important'' differences between `RegexParsers` and
* [[scala.util.parsing.combinator.Parsers]] are:
diff --git a/src/library/scala/util/parsing/combinator/lexical/Lexical.scala b/src/library/scala/util/parsing/combinator/lexical/Lexical.scala
index 9979a420d6..6c3bc52c1a 100644
--- a/src/library/scala/util/parsing/combinator/lexical/Lexical.scala
+++ b/src/library/scala/util/parsing/combinator/lexical/Lexical.scala
@@ -32,7 +32,7 @@ abstract class Lexical extends Scanners with Tokens {
def digit = elem("digit", _.isDigit)
/** A character-parser that matches any character except the ones given in `cs` (and returns it).*/
- def chrExcept(cs: Char*) = elem("", ch => (cs forall (ch !=)))
+ def chrExcept(cs: Char*) = elem("", ch => (cs forall (ch != _)))
/** A character-parser that matches a white-space character (and returns it).*/
def whitespaceChar = elem("space char", ch => ch <= ' ' && ch != EofCh)
diff --git a/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala b/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala
index e494a69cf0..215b8b792f 100644
--- a/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala
+++ b/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala
@@ -13,6 +13,7 @@ package syntactical
import token._
import lexical.StdLexical
+import language.implicitConversions
/** This component provides primitive parsers for the standard tokens defined in `StdTokens`.
*
diff --git a/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala b/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala
index 0901f9bbd0..7aa6178df9 100644
--- a/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala
+++ b/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala
@@ -14,6 +14,7 @@ package syntactical
import token._
import scala.collection.mutable
+import language.implicitConversions
/** This component provides primitive parsers for the standard tokens defined in `StdTokens`.
*
diff --git a/src/library/scala/util/parsing/combinator/testing/RegexTest.scala b/src/library/scala/util/parsing/combinator/testing/RegexTest.scala
index 299736046e..255730e5db 100644
--- a/src/library/scala/util/parsing/combinator/testing/RegexTest.scala
+++ b/src/library/scala/util/parsing/combinator/testing/RegexTest.scala
@@ -3,6 +3,7 @@ package scala.util.parsing.combinator.testing
import scala.util.parsing.combinator._
import scala.util.parsing.input._
+import language.postfixOps
case class Ident(s: String)
case class Number(n: Int)
diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala
index 5b6b9f2bb9..f140fd1e07 100755
--- a/src/library/scala/xml/Elem.scala
+++ b/src/library/scala/xml/Elem.scala
@@ -107,5 +107,5 @@ extends Node with Serializable
/** Returns concatenation of `text(n)` for each child `n`.
*/
- override def text = child map (_.text) mkString
+ override def text = (child map (_.text)).mkString
}
diff --git a/src/library/scala/xml/MetaData.scala b/src/library/scala/xml/MetaData.scala
index c516747bae..b44a817499 100644
--- a/src/library/scala/xml/MetaData.scala
+++ b/src/library/scala/xml/MetaData.scala
@@ -167,7 +167,7 @@ extends AbstractIterable[MetaData]
/** Returns a Map containing the attributes stored as key/value pairs.
*/
def asAttrMap: Map[String, String] =
- iterator map (x => (x.prefixedKey, x.value.text)) toMap
+ (iterator map (x => (x.prefixedKey, x.value.text))).toMap
/** returns Null or the next MetaData item */
def next: MetaData
diff --git a/src/library/scala/xml/NodeSeq.scala b/src/library/scala/xml/NodeSeq.scala
index ff5618645f..f0be338fcf 100644
--- a/src/library/scala/xml/NodeSeq.scala
+++ b/src/library/scala/xml/NodeSeq.scala
@@ -11,6 +11,7 @@ package scala.xml
import collection.{ mutable, immutable, generic, SeqLike, AbstractSeq }
import mutable.{ Builder, ListBuffer }
import generic.{ CanBuildFrom }
+import language.implicitConversions
/** This object ...
*
@@ -152,5 +153,5 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S
override def toString(): String = theSeq.mkString
- def text: String = this map (_.text) mkString
+ def text: String = (this map (_.text)).mkString
}
diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala
index 9f944c0e92..062a62e240 100755
--- a/src/library/scala/xml/Utility.scala
+++ b/src/library/scala/xml/Utility.scala
@@ -10,6 +10,7 @@ package scala.xml
import scala.collection.mutable
import parsing.XhtmlEntities
+import language.implicitConversions
/**
* The `Utility` object provides utility functions for processing instances
@@ -20,6 +21,8 @@ import parsing.XhtmlEntities
object Utility extends AnyRef with parsing.TokenTests {
final val SU = '\u001A'
+ // [Martin] This looks dubious. We don't convert StringBuilders to
+ // Strings anywhere else, why do it here?
implicit def implicitSbToString(sb: StringBuilder) = sb.toString()
// helper for the extremely oft-repeated sequence of creating a
@@ -137,7 +140,7 @@ object Utility extends AnyRef with parsing.TokenTests {
* @return `'''null'''` if `ref` was not a predefined entity.
*/
final def unescape(ref: String, s: StringBuilder): StringBuilder =
- (unescMap get ref) map (s append _) orNull
+ ((unescMap get ref) map (s append _)).orNull
/**
* Returns a set of all namespaces used in a sequence of nodes
diff --git a/src/library/scala/xml/dtd/ContentModel.scala b/src/library/scala/xml/dtd/ContentModel.scala
index 1e9a3a4b58..a5d2a6bd7e 100644
--- a/src/library/scala/xml/dtd/ContentModel.scala
+++ b/src/library/scala/xml/dtd/ContentModel.scala
@@ -36,8 +36,8 @@ object ContentModel extends WordExp {
def traverse(r: RegExp): Set[String] = r match { // !!! check for match translation problem
case Letter(ElemName(name)) => Set(name)
case Star( x @ _ ) => traverse( x ) // bug if x@_*
- case Sequ( xs @ _* ) => Set(xs map traverse flatten: _*)
- case Alt( xs @ _* ) => Set(xs map traverse flatten: _*)
+ case Sequ( xs @ _* ) => Set(xs flatMap traverse: _*)
+ case Alt( xs @ _* ) => Set(xs flatMap traverse: _*)
}
traverse(r)
diff --git a/src/library/scala/xml/factory/LoggedNodeFactory.scala b/src/library/scala/xml/factory/LoggedNodeFactory.scala
index c15a9ebe7b..45ba9530e1 100644
--- a/src/library/scala/xml/factory/LoggedNodeFactory.scala
+++ b/src/library/scala/xml/factory/LoggedNodeFactory.scala
@@ -12,13 +12,13 @@ package factory
/** This class logs what the nodefactory is actually doing.
* If you want to see what happens during loading, use it like this:
{{{
-object testLogged extends Application {
+object testLogged extends App {
val x = new scala.xml.parsing.NoBindingFactoryAdapter
with scala.xml.factory.LoggedNodeFactory[scala.xml.Elem]
with scala.util.logging.ConsoleLogger
Console.println("Start")
- val doc = x.load(new java.net.URL("http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk/build.xml"))
+ val doc = x.load(new java.net.URL("http://example.com/file.xml"))
Console.println("End")
Console.println(doc)
}
diff --git a/src/library/scala/xml/parsing/ConstructingParser.scala b/src/library/scala/xml/parsing/ConstructingParser.scala
index 5571c9844d..471cde056e 100644
--- a/src/library/scala/xml/parsing/ConstructingParser.scala
+++ b/src/library/scala/xml/parsing/ConstructingParser.scala
@@ -16,10 +16,10 @@ import scala.io.Source
object ConstructingParser {
def fromFile(inp: File, preserveWS: Boolean) =
- new ConstructingParser(Source.fromFile(inp), preserveWS) initialize
+ new ConstructingParser(Source.fromFile(inp), preserveWS).initialize
def fromSource(inp: Source, preserveWS: Boolean) =
- new ConstructingParser(inp, preserveWS) initialize
+ new ConstructingParser(inp, preserveWS).initialize
}
/** An xml parser. parses XML and invokes callback methods of a MarkupHandler.
diff --git a/src/manual/scala/man1/fsc.scala b/src/manual/scala/man1/fsc.scala
index 1f82cdf0ce..2aafe7d82c 100644
--- a/src/manual/scala/man1/fsc.scala
+++ b/src/manual/scala/man1/fsc.scala
@@ -141,7 +141,6 @@ object fsc extends Command {
val seeAlso = Section("SEE ALSO",
- Link(Bold("sbaz") & "(1)", "sbaz.html") & ", " &
Link(Bold("scala") & "(1)", "scala.html") & ", " &
Link(Bold("scalac") & "(1)", "scalac.html") & ", " &
Link(Bold("scaladoc") & "(1)", "scaladoc.html") & ", " &
@@ -149,9 +148,9 @@ object fsc extends Command {
def manpage = new Document {
title = command
- date = "January 2007"
+ date = "March 2012"
author = "Lex Spoon"
- version = "0.4"
+ version = "0.5"
sections = List(
name,
synopsis,
diff --git a/src/manual/scala/man1/sbaz.scala b/src/manual/scala/man1/sbaz.scala
deleted file mode 100644
index 2e12330408..0000000000
--- a/src/manual/scala/man1/sbaz.scala
+++ /dev/null
@@ -1,209 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Stephane Micheloud
- */
-
-package scala.man1
-
-/**
- * @author Stephane Micheloud
- * @version 1.0
- */
-object sbaz extends Command {
- import _root_.scala.tools.docutil.ManPage._
-
- protected val cn = new Error().getStackTrace()(0).getClassName()
-
- val name = Section("NAME",
-
- MBold(command) & " " & NDash & " Scala package sharing tool for the " &
- Link("Scala 2", "http://scala-lang.org/") & " language")
-
- val synopsis = Section("SYNOPSIS",
-
- CmdLine(" [ " & Argument("global_options") & " ] " & Argument("command") &
- " [ " & Argument("command_options") & " ]"))
-
- val parameters = Section("PARAMETERS",
-
- DefinitionList(
- Definition(
- Mono(Argument("global_options")),
- "Command line options. See " & Link(Bold("OPTIONS"), "#options") &
- " below."),
- Definition(
- Mono(Argument("command")),
- "Internal " & MBold(command) & " command."),
- Definition(
- Mono(Argument("command_options")),
- MBold(command) & " command options.")))
-
- val description = Section("DESCRIPTION",
-
- "The " & MBold(command) & " tool is a system used by Scala enthusiasts " &
- "to share computer files with each other. In particular, it makes it " &
- "easy to share libraries and applications.")
-
- val options = Section("OPTIONS",
-
- "The " & MBold(command) & " tool has a set of standard options that are " &
- "supported on the current development environment and will be supported " &
- "in future releases.",
-
- Section("Global Options",
- DefinitionList(
- Definition(
- CmdOption("d", Argument("dir")),
- "Operate on dir as the local managed directory."),
- Definition(
- CmdOption("n") & "| " & CmdOptionLong("dryrun"),
- "Do not actually do anything. Only print out what " +
- "tool would normally do with the following arguments."),
- Definition(
- CmdOption("v") & "| " & CmdOptionLong("verbose"),
- "Output messages about what the " & MBold(command) & " tool is doing"),
- Definition(
- CmdOption("version"),
- "Display the version information"),
-
- Definition(
- CmdOptionLong("univ", Argument("name")),
- "Operate on the named remote universe, selected from those " &
- "in the local managed directory's universe. Affects "&
- "the "&MBold("share")&" and "&MBold("retract")&" commands."),
-
- Definition(
- CmdOptionLong("univ-url", Argument("url")),
- "Operate on the universe at the specified URL. Affects "&
- "the "&MBold("share")&" and "&MBold("retract")&" commands."))),
-
- Section("Available Commands",
- DefinitionList(
- Definition(
- MBold("available"),
- "List the available packages for installation; only display the " +
- "three most recent versions of each package."),
- Definition(
- MBold("available") & " " & CmdOption("a"),
- "List the available packages for installation; display all shared " +
- "versions of each package."),
- Definition(
- MBold("compact"),
- "Clear the download cache to save space."),
- Definition(
- MBold("help"),
- "Display a help message."),
- Definition(
- MBold("install"),
- "Install a package."),
- Definition(
- MBold("installed"),
- "List the packages that are installed."),
- Definition(
- MBold("keycreate"),
- "Request that a new key be created."),
- Definition(
- MBold("keyforget"),
- "Forget the specified key."),
- Definition(
- MBold("keyknown"),
- "List all known keys."),
- Definition(
- MBold("keyremember"),
- "Remember the specified key for future use."),
- Definition(
- MBold("keyremoteknown"),
- "List all keys known to the bazaar server."),
- Definition(
- MBold("keyrevoke"),
- "Request that a specified key be revoked."),
- Definition(
- MBold("pack") & " " & Argument("name") & " " & Argument("directory") &
- " [ " & Argument("options") & " ]",
- "Create an sbaz package and, if a link base is specified, "&
- "an advertisement file. The package file is named " &
- Mono("name-version.sbp") & ". The advertisement file is named " &
- Mono("name-version.advert") & ". The URL is the advertisement " &
- "file is the URL base with the package filename appended."),
- Definition(
- MBold("remove"),
- "Remove a package."),
- Definition(
- MBold("retract"),
- "Retract a previously shared package."),
- Definition(
- MBold("setuniverse"),
- "Set the universe for a directory."),
- Definition(
- MBold("setup"),
- "Initialize a directory to be managed."),
- Definition(
- MBold("share") & " " & Argument("filename"),
- "Share a package advertisement on a bazaar."),
- Definition(
- MBold("share") & " " & CmdOption("i", Argument("descriptor")),
- "The package advertisement is usually specified in a file, " &
- "but it may also be specified on the command line with the " &
- CmdOption("i") & " option."),
- Definition(
- MBold("share") & " " & CmdOptionLong("template"),
- "If " & CmdOptionLong("template") & " is specified, then instead " &
- "of uploading a description, the command prints out a template " &
- "of a package advertisement."),
- Definition(
- MBold("show"),
- "Show information about one package."),
- Definition(
- MBold("update"),
- "Update the list of available packages."),
- Definition(
- MBold("upgrade"),
- "Upgrade all possible packages."))))
-
- val examples = Section("EXAMPLES",
-
- DefinitionList(
- Definition(
- "Update the list of available packages.",
- CmdLine(MBold("update"))),
- Definition(
- "Upload package description for " & Mono("scala-devel-2.5.1") &
- " to the universe",
- CmdLine(MBold("share") & " scala-devel-2.5.1.advert"))))
-
- val exitStatus = Section("EXIT STATUS",
-
- MBold(command) & " returns a zero exist status if it succeeds to process " &
- "the specified input files. Non zero is returned in case of failure.")
-
- override val authors = Section("AUTHOR",
-
- "Written by Lex Spoon.")
-
- val seeAlso = Section("SEE ALSO",
-
- Link(Bold("fsc") & "(1)", "fsc.html") & ", " &
- Link(Bold("scala") & "(1)", "scala.html") & ", " &
- Link(Bold("scalac") & "(1)", "scalac.html") & ", " &
- Link(Bold("scaladoc") & "(1)", "scaladoc.html") & ", " &
- Link(Bold("scalap") & "(1)", "scalap.html"))
-
- def manpage = new Document {
- title = command
- date = "August 2006"
- author = "Stephane Micheloud"
- version = "0.3"
- sections = List(
- name,
- synopsis,
- parameters,
- description,
- options,
- examples,
- exitStatus,
- authors,
- bugs,
- copyright,
- seeAlso)
- }
-}
diff --git a/src/manual/scala/man1/scala.scala b/src/manual/scala/man1/scala.scala
index 368453f3a9..8daab84d3e 100644
--- a/src/manual/scala/man1/scala.scala
+++ b/src/manual/scala/man1/scala.scala
@@ -250,7 +250,6 @@ object scala extends Command {
val seeAlso = Section("SEE ALSO",
Link(Bold("fsc") & "(1)", "fsc.html") & ", " &
- Link(Bold("sbaz") & "(1)", "sbaz.html") & ", " &
Link(Bold("scalac") & "(1)", "scalac.html") & ", " &
Link(Bold("scaladoc") & "(1)", "scaladoc.html") & ", " &
Link(Bold("scalap") & "(1)", "scalap.html"))
diff --git a/src/manual/scala/man1/scalac.scala b/src/manual/scala/man1/scalac.scala
index b84510ee16..49324ffa83 100644
--- a/src/manual/scala/man1/scalac.scala
+++ b/src/manual/scala/man1/scalac.scala
@@ -174,6 +174,8 @@ object scalac extends Command {
Definition(
Mono(Bold("@") & Argument("file")),
"A text file containing compiler arguments (options and source files)")
+
+ // TODO - Add macros an dsuch here.
)
),
@@ -424,14 +426,13 @@ object scalac extends Command {
val seeAlso = Section("SEE ALSO",
Link(Bold("fsc") & "(1)", "fsc.html") & ", " &
- Link(Bold("sbaz") & "(1)", "sbaz.html") & ", " &
Link(Bold("scala") & "(1)", "scala.html") & ", " &
Link(Bold("scaladoc") & "(1)", "scaladoc.html") & ", " &
Link(Bold("scalap") & "(1)", "scalap.html"))
def manpage = new Document {
title = command
- date = "September 2011"
+ date = "March 2012"
author = "Stephane Micheloud"
version = "1.0"
sections = List(
diff --git a/src/manual/scala/man1/scaladoc.scala b/src/manual/scala/man1/scaladoc.scala
index a6832be4b0..193c77fc51 100644
--- a/src/manual/scala/man1/scaladoc.scala
+++ b/src/manual/scala/man1/scaladoc.scala
@@ -137,7 +137,6 @@ object scaladoc extends Command {
val seeAlso = Section("SEE ALSO",
Link(Bold("fsc") & "(1)", "fsc.html") & ", " &
- Link(Bold("sbaz") & "(1)", "sbaz.html") & ", " &
Link(Bold("scala") & "(1)", "scala.html") & ", " &
Link(Bold("scalac") & "(1)", "scalac.html") & ", " &
Link(Bold("scalap") & "(1)", "scalap.html"))
diff --git a/src/manual/scala/man1/scalap.scala b/src/manual/scala/man1/scalap.scala
index cc9b312dac..88fc91957f 100644
--- a/src/manual/scala/man1/scalap.scala
+++ b/src/manual/scala/man1/scalap.scala
@@ -86,7 +86,6 @@ object scalap extends Command {
val seeAlso = Section("SEE ALSO",
Link(Bold("fsc") & "(1)", "fsc.html") & ", " &
- Link(Bold("sbaz") & "(1)", "sbaz.html") & ", " &
Link(Bold("scala") & "(1)", "scala.html") & ", " &
Link(Bold("scalac") & "(1)", "scalac.html") & ", " &
Link(Bold("scaladoc") & "(1)", "scaladoc.html"))
diff --git a/src/manual/scala/tools/docutil/resources/index.html b/src/manual/scala/tools/docutil/resources/index.html
index 4e5130aa3d..d1f3bd81f4 100644
--- a/src/manual/scala/tools/docutil/resources/index.html
+++ b/src/manual/scala/tools/docutil/resources/index.html
@@ -44,8 +44,8 @@
<ul class="ContentList">
<li>
- <a href="#basic"><b class="SansSerif">Basic Tools</b></a> (<code>sbaz</code>,
- <code>fsc</code>, <code>scala</code>, <code>scalac</code>, <code>scaladoc</code>,
+ <a href="#basic"><b class="SansSerif">Basic Tools</b></a> (<code>fsc</code>,
+ <code>scala</code>, <code>scalac</code>, <code>scaladoc</code>,
<code>scalap</code>)
</li>
</ul>
@@ -133,17 +133,6 @@
</tr>
<tr>
<td width="13%" valign="top">
- <span class="tool">sbaz</span>
- </td>
- <td width="70%" valign="top">
- The Scala sharing tool.
- </td>
- <td width="17%" valign="top" class="links">
- [<a href="sbaz.html">Solaris, Linux and Windows</a>]
- </td>
- </tr>
- <tr>
- <td width="13%" valign="top">
<span class="tool">scala</span>
</td>
<td width="70%" valign="top">
@@ -191,7 +180,7 @@
<hr/>
<div style="font-size:x-small;">
- Copyright (c) 2002-2011 <a href="http://www.epfl.ch/">EPFL</a>,
+ Copyright (c) 2002-2012 <a href="http://www.epfl.ch/">EPFL</a>,
Lausanne, unless specified otherwise.<br/>
All rights reserved.
</div>
diff --git a/src/partest/scala/tools/partest/CompilerTest.scala b/src/partest/scala/tools/partest/CompilerTest.scala
index 994928c0f6..86678760be 100644
--- a/src/partest/scala/tools/partest/CompilerTest.scala
+++ b/src/partest/scala/tools/partest/CompilerTest.scala
@@ -5,6 +5,7 @@
package scala.tools.partest
+import scala.reflect.{mirror => rm}
import scala.tools.nsc._
/** For testing compiler internals directly.
@@ -29,13 +30,13 @@ abstract class CompilerTest extends DirectTest {
// Override at least one of these...
def code = ""
def sources: List[String] = List(code)
-
+
// Utility functions
-
+
class MkType(sym: Symbol) {
- def apply[M](implicit m1: Manifest[M]): Type =
+ def apply[M](implicit t: rm.TypeTag[M]): Type =
if (sym eq NoSymbol) NoType
- else appliedType(sym.typeConstructor, List(m1) map (x => manifestToType(x)))
+ else appliedType(sym, compilerTypeFromTag(t))
}
implicit def mkMkType(sym: Symbol) = new MkType(sym)
@@ -47,7 +48,7 @@ abstract class CompilerTest extends DirectTest {
}
loop(Set(), List(root))
}
-
+
class SymsInPackage(pkgName: String) {
def pkg = getRequiredModule(pkgName)
def classes = allMembers(pkg) filter (_.isClass)
diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala
new file mode 100644
index 0000000000..142f2baea5
--- /dev/null
+++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala
@@ -0,0 +1,146 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Vlad Ureche
+ */
+
+package scala.tools.partest
+
+import scala.tools.partest._
+import java.io._
+import scala.tools.nsc._
+import scala.tools.nsc.util.CommandLineParser
+import scala.tools.nsc.doc.{Settings, DocFactory, Universe}
+import scala.tools.nsc.doc.model._
+import scala.tools.nsc.reporters.ConsoleReporter
+
+/** A class for testing scaladoc model generation
+ * - you need to specify the code in the `code` method
+ * - you need to override the testModel method to test the model
+ * - you may specify extra parameters to send to scaladoc in `scaladocSettings`
+ * {{{
+ import scala.tools.nsc.doc.model._
+ import scala.tools.partest.ScaladocModelTest
+
+ object Test extends ScaladocModelTest {
+
+ override def code = """ ... """ // or override def resourceFile = "<file>.scala" (from test/scaladoc/resources)
+ def scaladocSettings = " ... "
+ def testModel(rootPackage: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // just need to check the member exists, access methods will throw an error if there's a problem
+ rootPackage._package("scala")._package("test")._class("C")._method("foo")
+ }
+ }
+ * }}}
+ */
+abstract class ScaladocModelTest extends DirectTest {
+
+ /** Override this to give scaladoc command line parameters */
+ def scaladocSettings: String
+
+ /** Override this to test the model */
+ def testModel(root: Package): Unit
+
+ /** Override to feed a file in resources to scaladoc*/
+ def resourceFile: String = null
+
+ /** Override to feed code into scaladoc */
+ override def code =
+ if (resourceFile ne null)
+ io.File(resourcePath + "/" + resourceFile).slurp()
+ else
+ sys.error("Scaladoc Model Test: You need to give a file or some code to feed to scaladoc!")
+
+ def resourcePath = io.Directory(sys.props("partest.cwd") + "/../resources")
+
+ // Implementation follows:
+ override def extraSettings: String = "-usejavacp"
+
+ override def show(): Unit = {
+ // redirect err to out, for logging
+ val prevErr = System.err
+ System.setErr(System.out)
+
+ try {
+ // 1 - compile with scaladoc and get the model out
+ val universe = model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")})
+ // 2 - check the model generated
+ testModel(universe.rootPackage)
+ println("Done.")
+ } catch {
+ case e =>
+ println(e)
+ e.printStackTrace
+ }
+ // set err back to the real err handler
+ System.setErr(prevErr)
+ }
+
+ private[this] var settings: Settings = null
+
+ // create a new scaladoc compiler
+ def newDocFactory: DocFactory = {
+ settings = new Settings(_ => ())
+ settings.reportModel = false // yaay, no more "model contains X documentable templates"!
+ val args = extraSettings + " " + scaladocSettings
+ val command = new ScalaDoc.Command((CommandLineParser tokenize (args)), settings)
+ val docFact = new DocFactory(new ConsoleReporter(settings), settings)
+ docFact
+ }
+
+ // compile with scaladoc and output the result
+ def model: Option[Universe] = newDocFactory.makeUniverse(Right(code))
+
+ // so we don't get the newSettings warning
+ override def isDebug = false
+
+
+ // finally, enable easy navigation inside the entities
+ object access {
+
+ class TemplateAccess(tpl: DocTemplateEntity) {
+ def _class(name: String): DocTemplateEntity = getTheFirst(_classes(name), tpl.qualifiedName + ".class(" + name + ")")
+ def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case c: Class => c})
+
+ def _trait(name: String): DocTemplateEntity = getTheFirst(_traits(name), tpl.qualifiedName + ".trait(" + name + ")")
+ def _traits(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case t: Trait => t})
+
+ def _object(name: String): DocTemplateEntity = getTheFirst(_objects(name), tpl.qualifiedName + ".object(" + name + ")")
+ def _objects(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case o: Object => o})
+
+ def _method(name: String): Def = getTheFirst(_methods(name), tpl.qualifiedName + ".method(" + name + ")")
+ def _methods(name: String): List[Def] = tpl.methods.filter(_.name == name)
+
+ def _value(name: String): Val = getTheFirst(_values(name), tpl.qualifiedName + ".value(" + name + ")")
+ def _values(name: String): List[Val] = tpl.values.filter(_.name == name)
+
+ def _conversion(name: String): ImplicitConversion = getTheFirst(_conversions(name), tpl.qualifiedName + ".conversion(" + name + ")")
+ def _conversions(name: String): List[ImplicitConversion] = tpl.conversions.filter(_.conversionQualifiedName == name)
+ }
+
+ class PackageAccess(pack: Package) extends TemplateAccess(pack) {
+ def _package(name: String): Package = getTheFirst(_packages(name), pack.qualifiedName + ".package(" + name + ")")
+ def _packages(name: String): List[Package] = pack.packages.filter(_.name == name)
+ }
+
+ class MemberAccess(mbrs: WithMembers) {
+ def _member(name: String): MemberEntity = getTheFirst(_members(name), mbrs.toString + ".member(" + name + ")")
+ def _members(name: String): List[MemberEntity] = mbrs.members.filter(_.name == name)
+ }
+
+ type WithMembers = { def members: List[MemberEntity]; def toString: String } /* DocTemplates and ImplicitConversions */
+
+ implicit def templateAccess(tpl: DocTemplateEntity) = new TemplateAccess(tpl)
+ implicit def packageAccess(pack: Package) = new PackageAccess(pack)
+ implicit def membersAccess(mbrs: WithMembers) = new MemberAccess(mbrs)
+
+ def getTheFirst[T](list: List[T], expl: String): T = list.length match {
+ case 1 => list.head
+ case 0 => sys.error("Error getting " + expl + ": No such element.")
+ case _ => sys.error("Error getting " + expl + ": " + list.length + " elements with this name. " +
+ "All elements in list: [" + list.mkString(", ") + "]")
+ }
+ }
+}
diff --git a/src/partest/scala/tools/partest/SigTest.scala b/src/partest/scala/tools/partest/SigTest.scala
index 072ec006f9..999d901d21 100644
--- a/src/partest/scala/tools/partest/SigTest.scala
+++ b/src/partest/scala/tools/partest/SigTest.scala
@@ -20,31 +20,31 @@ trait SigTest {
def isObjectMethodName(name: String) = classOf[Object].getMethods exists (_.getName == name)
- def fields[T: ClassManifest](p: JField => Boolean) = {
- val cl = classManifest[T].erasure
+ def fields[T: ClassTag](p: JField => Boolean) = {
+ val cl = classTag[T].erasure
val fs = (cl.getFields ++ cl.getDeclaredFields).distinct sortBy (_.getName)
fs filter p
}
- def methods[T: ClassManifest](p: JMethod => Boolean) = {
- val cl = classManifest[T].erasure
+ def methods[T: ClassTag](p: JMethod => Boolean) = {
+ val cl = classTag[T].erasure
val ms = (cl.getMethods ++ cl.getDeclaredMethods).distinct sortBy (x => (x.getName, x.isBridge))
ms filter p
}
- def allFields[T: ClassManifest]() = fields[T](_ => true)
- def allMethods[T: ClassManifest]() = methods[T](m => !isObjectMethodName(m.getName))
- def fieldsNamed[T: ClassManifest](name: String) = fields[T](_.getName == name)
- def methodsNamed[T: ClassManifest](name: String) = methods[T](_.getName == name)
+ def allFields[T: ClassTag]() = fields[T](_ => true)
+ def allMethods[T: ClassTag]() = methods[T](m => !isObjectMethodName(m.getName))
+ def fieldsNamed[T: ClassTag](name: String) = fields[T](_.getName == name)
+ def methodsNamed[T: ClassTag](name: String) = methods[T](_.getName == name)
- def allGenericStrings[T: ClassManifest]() =
+ def allGenericStrings[T: ClassTag]() =
(allMethods[T]() map mstr) ++ (allFields[T]() map fstr)
- def genericStrings[T: ClassManifest](name: String) =
+ def genericStrings[T: ClassTag](name: String) =
(methodsNamed[T](name) map mstr) ++ (fieldsNamed[T](name) map fstr)
- def show[T: ClassManifest](name: String = "") = {
- println(classManifest[T].erasure.getName)
+ def show[T: ClassTag](name: String = "") = {
+ println(classTag[T].erasure.getName)
if (name == "") allGenericStrings[T]() foreach println
else genericStrings[T](name) foreach println
}
diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
index fa533eeb10..8d239a84bd 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
@@ -96,6 +96,7 @@ class ConsoleFileManager extends FileManager {
latestActorsFile = dir / "lib/scala-actors.jar"
latestCompFile = dir / "lib/scala-compiler.jar"
latestPartestFile = dir / "lib/scala-partest.jar"
+ latestFjbgFile = testParent / "lib" / "fjbg.jar"
}
else {
def setupQuick() {
diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
index 85060ad633..fb3cab52c4 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
@@ -213,7 +213,12 @@ class ConsoleRunner extends DirectRunner {
* @return (success count, failure count)
*/
def testCheckAll(enabledSets: List[TestSet]): (Int, Int) = {
- def kindOf(f: File) = (srcDir relativize Path(f).toCanonical).segments.head
+ def kindOf(f: File) = {
+ (srcDir relativize Path(f).toCanonical).segments match {
+ case (".." :: "scaladoc" :: xs) => xs.head
+ case xs => xs.head
+ }
+ }
val (valid, invalid) = testFiles partition (x => testSetKinds contains kindOf(x))
invalid foreach (x => NestUI.failure(
diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala
index fc5792e886..1aa0a7baf6 100644
--- a/src/partest/scala/tools/partest/nest/TestFile.scala
+++ b/src/partest/scala/tools/partest/nest/TestFile.scala
@@ -35,7 +35,9 @@ abstract class TestFile(val kind: String) extends TestFileCommon {
if (setOutDir)
settings.outputDirs setSingleOutput setOutDirTo.path
- // adding code.jar to the classpath (to provide Code.lift services for reification tests)
+ // adding codelib.jar to the classpath
+ // codelib provides the possibility to override standard reify
+ // this shields the massive amount of reification tests from changes in the API
settings.classpath prepend PathSettings.srcCodeLib.toString
if (propIsSet("java.class.path")) setProp("java.class.path", PathSettings.srcCodeLib.toString + ";" + propOrElse("java.class.path", ""))
diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala
index cb6f2a0edc..00ee8ba857 100644
--- a/src/partest/scala/tools/partest/nest/Worker.scala
+++ b/src/partest/scala/tools/partest/nest/Worker.scala
@@ -181,7 +181,9 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
//
private def replaceSlashes(dir: File, s: String): String = {
val base = (dir.getAbsolutePath + File.separator).replace('\\', '/')
- s.replace('\\', '/').replaceAll("""\Q%s\E""" format base, "")
+ var regex = """\Q%s\E""" format base
+ if (isWin) regex = "(?i)" + regex
+ s.replace('\\', '/').replaceAll(regex, "")
}
private def currentFileString = {
@@ -521,9 +523,15 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor
runTestCommon(file, expectFailure = false)((logFile, outDir) => {
val dir = file.getParentFile
- // adding code.jar to the classpath (to provide Code.lift services for reification tests)
- execTest(outDir, logFile, PathSettings.srcCodeLib.toString) &&
- diffCheck(compareOutput(dir, logFile))
+ // adding codelib.jar to the classpath
+ // codelib provides the possibility to override standard reify
+ // this shields the massive amount of reification tests from changes in the API
+ execTest(outDir, logFile, PathSettings.srcCodeLib.toString) && {
+ // cannot replace paths here since this also inverts slashes
+ // which affects a bunch of tests
+ //fileManager.mapFile(logFile, replaceSlashes(dir, _))
+ diffCheck(compareOutput(dir, logFile))
+ }
})
// Apache Ant 1.6 or newer
diff --git a/src/scalacheck/org/scalacheck/Arbitrary.scala b/src/scalacheck/org/scalacheck/Arbitrary.scala
index 91d56b0aec..9bb235f917 100644
--- a/src/scalacheck/org/scalacheck/Arbitrary.scala
+++ b/src/scalacheck/org/scalacheck/Arbitrary.scala
@@ -263,7 +263,7 @@ object Arbitrary {
): Arbitrary[C[T]] = Arbitrary(containerOf[C,T](arbitrary[T]))
/** Arbitrary instance of any array. */
- implicit def arbArray[T](implicit a: Arbitrary[T], c: ClassManifest[T]
+ implicit def arbArray[T](implicit a: Arbitrary[T], c: ClassTag[T]
): Arbitrary[Array[T]] = Arbitrary(containerOf[Array,T](arbitrary[T]))
diff --git a/src/scalacheck/org/scalacheck/util/Buildable.scala b/src/scalacheck/org/scalacheck/util/Buildable.scala
index 6378e72d4f..662bc6146b 100644
--- a/src/scalacheck/org/scalacheck/util/Buildable.scala
+++ b/src/scalacheck/org/scalacheck/util/Buildable.scala
@@ -30,7 +30,7 @@ object Buildable {
def builder = (new mutable.ListBuffer[T]).mapResult(_.toStream)
}
- implicit def buildableArray[T](implicit cm: ClassManifest[T]) =
+ implicit def buildableArray[T](implicit t: ClassTag[T]) =
new Buildable[T,Array] {
def builder = mutable.ArrayBuilder.make[T]
}
diff --git a/src/swing/scala/swing/Font.scala.disabled b/src/swing/scala/swing/Font.scala.disabled
index 6eebd667bd..9e21eb859c 100644
--- a/src/swing/scala/swing/Font.scala.disabled
+++ b/src/swing/scala/swing/Font.scala.disabled
@@ -1,36 +1,36 @@
package scala.swing
-/*object Font {
- def apply(fontFormat: Int, fontFile: java.io.File) = java.awt.Font.createFont(fontFormat, fontFile)
- def apply(fontFormat: Int, fontStream: java.io.InputStream) = java.awt.Font.createFont(fontFormat, fontStream)
+/*object Font {
+ def apply(fontFormat: Int, fontFile: java.io.File) = java.awt.Font.createFont(fontFormat, fontFile)
+ def apply(fontFormat: Int, fontStream: java.io.InputStream) = java.awt.Font.createFont(fontFormat, fontStream)
def decode(str: String) = java.awt.Font.decode(str)
-
+
/* TODO: finish implementation
/**
* See [java.awt.Font.getFont].
*/
- def get(attributes: Map[_ <: java.text.AttributedCharacterIterator.Attribute, _]) =
+ def get(attributes: Map[_ <: java.text.AttributedCharacterIterator.Attribute, _]) =
java.awt.Font.getFont(ImmutableMapWrapper(attributes))
-
+
import java.{util => ju}
- private case class ImmutableMapWrapper[A, B](underlying : Map[A, B])(m : ClassManifest[A]) extends ju.AbstractMap[A, B] {
+ private case class ImmutableMapWrapper[A, B](underlying : Map[A, B])(t : ClassTag[A]) extends ju.AbstractMap[A, B] {
self =>
override def size = underlying.size
- override def put(k : A, v : B) =
+ override def put(k : A, v : B) =
throw new UnsupportedOperationException("This is a wrapper that does not support mutation")
- override def remove(k : AnyRef) =
+ override def remove(k : AnyRef) =
throw new UnsupportedOperationException("This is a wrapper that does not support mutation")
-
+
override def entrySet : ju.Set[ju.Map.Entry[A, B]] = new ju.AbstractSet[ju.Map.Entry[A, B]] {
def size = self.size
def iterator = new ju.Iterator[ju.Map.Entry[A, B]] {
val ui = underlying.iterator
var prev : Option[A] = None
-
+
def hasNext = ui.hasNext
-
+
def next = {
val (k, v) = ui.next
prev = Some(k)
@@ -44,7 +44,7 @@ package scala.swing
}
}
}
-
+
def remove = prev match {
case Some(k) => val v = self.remove(k.asInstanceOf[AnyRef]) ; prev = None ; v
case _ => throw new IllegalStateException("next must be called at least once before remove")
@@ -53,7 +53,7 @@ package scala.swing
}
}
*/
-
+
/**
* See [java.awt.Font.getFont].
*/
@@ -62,9 +62,9 @@ package scala.swing
* See [java.awt.Font.getFont].
*/
def get(nm: String, font: Font) = java.awt.Font.getFont(nm, font)
-
+
def Insets(x: Int, y: Int, width: Int, height: Int) = new Insets(x, y, width, height)
def Rectangle(x: Int, y: Int, width: Int, height: Int) = new Insets(x, y, width, height)
def Point(x: Int, y: Int) = new Point(x, y)
- def Dimension(x: Int, y: Int) = new Dimension(x, y)
+ def Dimension(x: Int, y: Int) = new Dimension(x, y)
}*/ \ No newline at end of file
diff --git a/test/benchmarking/ParHashMap.scala b/test/benchmarking/ParHashMap.scala
new file mode 100644
index 0000000000..33a378fb04
--- /dev/null
+++ b/test/benchmarking/ParHashMap.scala
@@ -0,0 +1,33 @@
+
+
+
+import collection.parallel.mutable.ParHashMap
+
+
+
+object Map extends testing.Benchmark {
+ val length = sys.props("length").toInt
+ val par = sys.props("par").toInt
+ val phm = ParHashMap((0 until length) zip (0 until length): _*)
+
+ phm.tasksupport = new collection.parallel.ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(par))
+
+ def run = {
+ phm map {
+ kv => kv
+ }
+ }
+}
+
+
+object MapSeq extends testing.Benchmark {
+ val length = sys.props("length").toInt
+ val hm = collection.mutable.HashMap((0 until length) zip (0 until length): _*)
+
+ def run = {
+ hm map {
+ kv => kv
+ }
+ }
+}
+
diff --git a/test/benchmarking/ParVector-reduce.scala b/test/benchmarking/ParVector-reduce.scala
new file mode 100644
index 0000000000..2b4594e997
--- /dev/null
+++ b/test/benchmarking/ParVector-reduce.scala
@@ -0,0 +1,33 @@
+
+
+
+import collection.parallel.immutable.ParVector
+
+
+
+object Reduce extends testing.Benchmark {
+ val length = sys.props("length").toInt
+ val par = sys.props("par").toInt
+ val parvector = ParVector((0 until length): _*)
+
+ parvector.tasksupport = new collection.parallel.ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(par))
+
+ def run = {
+ parvector reduce {
+ (a, b) => a + b
+ }
+ }
+}
+
+
+object ReduceSeq extends testing.Benchmark {
+ val length = sys.props("length").toInt
+ val vector = collection.immutable.Vector((0 until length): _*)
+
+ def run = {
+ vector reduce {
+ (a, b) => a + b
+ }
+ }
+}
+
diff --git a/test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala b/test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala
index e6feb59fcd..22d2107f62 100644
--- a/test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala
+++ b/test/benchmarks/src/scala/collection/parallel/benchmarks/arrays/Resetting.scala
@@ -4,19 +4,19 @@ package scala.collection.parallel.benchmarks.arrays
import scala.collection.parallel.benchmarks._
-abstract class Resetting[T: Manifest](elemcreate: Int => T, sz: Int, p: Int, what: String)
+abstract class Resetting[T: ClassTag](elemcreate: Int => T, sz: Int, p: Int, what: String)
extends Bench {
val size = sz
val parallelism = p
val runWhat = what
-
+
var anyarray: Array[Any] = null
var castarray: AnyRef = null
var gencastarray: Array[T] = null
var manifarray: Array[T] = null
-
+
reset
-
+
def reset = what match {
case "any" =>
anyarray = new Array[Any](sz)
diff --git a/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala b/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala
index 5f902ff483..6d5b189c3a 100644
--- a/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala
+++ b/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/MatrixMultiplication.scala
@@ -16,54 +16,54 @@ class MatrixMultiplication(sz: Int, p: Int, what: String)
extends Resettable(sz, p, what, new Cont(_), new Array[Any](_), classOf[Cont]) {
def companion = MatrixMultiplication
collection.parallel.tasksupport.environment = forkjoinpool
-
+
val a = Matrix.unit[Int](sz)
val b = Matrix.unit[Int](sz)
var c = new Matrix[Int](sz)
-
+
def runpar = c = a * b //{ c.assignProduct(a, b) } //; println("--------"); c.output }
def runseq = throw new UnsupportedOperationException
def comparisonMap = collection.Map()
-
- class Matrix[T](n: Int)(implicit num: Numeric[T], man: Manifest[T]) {
+
+ class Matrix[T](n: Int)(implicit num: Numeric[T], tag: ClassTag[T]) {
val array = new Array[T](n * n)
-
+
def apply(y: Int, x: Int) = array(y * n + x)
-
+
def update(y: Int, x: Int, elem: T) = array(y * n + x) = elem
-
+
def *(b: Matrix[T]) = {
val m = new Matrix[T](n)
m.assignProduct(this, b)
m
}
-
+
def assignProduct(a: Matrix[T], b: Matrix[T]) = {
val range = ParRange(0, n * n, 1, false)
for (i <- range) this(i / n, i % n) = calcProduct(a, b, i / n, i % n);
}
-
+
private def calcProduct(a: Matrix[T], b: Matrix[T], y: Int, x: Int): T = {
import num._
var sum = zero
for (i <- 0 until n) sum += a(y, i) * b(i, x)
sum
}
-
+
def output = for (y <- 0 until n) {
for (x <- 0 until n) print(this(y, x))
println
}
}
-
+
object Matrix {
- def unit[T](n: Int)(implicit num: Numeric[T], man: Manifest[T]) = {
+ def unit[T](n: Int)(implicit num: Numeric[T], tag: ClassTag[T]) = {
val m = new Matrix[T](n)
for (i <- 0 until n) m(i, i) = num.one
m
}
}
-
+
}
diff --git a/test/files/continuations-neg/infer0.check b/test/disabled/continuations-neg/infer0.check
index 1dd072ef09..1dd072ef09 100644
--- a/test/files/continuations-neg/infer0.check
+++ b/test/disabled/continuations-neg/infer0.check
diff --git a/test/files/continuations-neg/infer0.scala b/test/disabled/continuations-neg/infer0.scala
index 9cf69c5d35..6d97d7504d 100644
--- a/test/files/continuations-neg/infer0.scala
+++ b/test/disabled/continuations-neg/infer0.scala
@@ -4,11 +4,9 @@ import scala.util.continuations._
object Test {
-
def test(x: => Int @cpsParam[String,Int]) = 7
-
- def main(args: Array[String]): Any = {
+
+ def main(args: Array[String]) {
test(8)
}
-
-} \ No newline at end of file
+}
diff --git a/test/files/jvm/concurrent-future.check b/test/disabled/jvm/concurrent-future.check
index c55e824818..715ac90ce7 100644
--- a/test/files/jvm/concurrent-future.check
+++ b/test/disabled/jvm/concurrent-future.check
@@ -12,5 +12,3 @@ test6: hai world
test6: kthxbye
test7: hai world
test7: kthxbye
-test8: hai world
-test8: im in yr loop
diff --git a/test/files/jvm/concurrent-future.scala b/test/disabled/jvm/concurrent-future.scala
index b44d054219..eda05428c8 100644
--- a/test/files/jvm/concurrent-future.scala
+++ b/test/disabled/jvm/concurrent-future.scala
@@ -90,25 +90,25 @@ object Test extends App {
}
}
- def testOnFailureWhenFutureTimeoutException(): Unit = once {
- done =>
- val f = future[Unit] {
- output(8, "hai world")
- throw new FutureTimeoutException(null)
- }
- f onSuccess { case _ =>
- output(8, "onoes")
- done()
- }
- f onFailure {
- case e: FutureTimeoutException =>
- output(8, "im in yr loop")
- done()
- case other =>
- output(8, "onoes: " + other)
- done()
- }
- }
+ // def testOnFailureWhenFutureTimeoutException(): Unit = once {
+ // done =>
+ // val f = future[Unit] {
+ // output(8, "hai world")
+ // throw new FutureTimeoutException(null)
+ // }
+ // f onSuccess { case _ =>
+ // output(8, "onoes")
+ // done()
+ // }
+ // f onFailure {
+ // case e: FutureTimeoutException =>
+ // output(8, "im in yr loop")
+ // done()
+ // case other =>
+ // output(8, "onoes: " + other)
+ // done()
+ // }
+ // }
testOnSuccess()
testOnSuccessWhenCompleted()
@@ -117,6 +117,6 @@ object Test extends App {
testOnFailureWhenSpecialThrowable(5, new Error)
testOnFailureWhenSpecialThrowable(6, new scala.util.control.ControlThrowable { })
testOnFailureWhenSpecialThrowable(7, new InterruptedException)
- testOnFailureWhenFutureTimeoutException()
+ // testOnFailureWhenFutureTimeoutException()
}
diff --git a/test/disabled/presentation/akka.check b/test/disabled/presentation/akka.check
index 9cd20ffb1c..5105d85a00 100644
--- a/test/disabled/presentation/akka.check
+++ b/test/disabled/presentation/akka.check
@@ -153,11 +153,11 @@ retrieved 131 members
`method spawn(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef`
`method spawnLink(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef`
`method spawnLinkRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef`
-`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: Manifest[T])akka.actor.ActorRef`
-`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: Manifest[T])akka.actor.ActorRef`
+`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: ClassTag[T])akka.actor.ActorRef`
+`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: ClassTag[T])akka.actor.ActorRef`
`method spawnRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef`
-`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: Manifest[T])akka.actor.ActorRef`
-`method spawn[T <: akka.actor.Actor](implicit evidence$1: Manifest[T])akka.actor.ActorRef`
+`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: ClassTag[T])akka.actor.ActorRef`
+`method spawn[T <: akka.actor.Actor](implicit evidence$1: ClassTag[T])akka.actor.ActorRef`
`method start()akka.actor.ActorRef`
`method startLink(actorRef: akka.actor.ActorRef)Unit`
`method stop()Unit`
@@ -286,11 +286,11 @@ retrieved 131 members
`method spawn(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef`
`method spawnLink(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef`
`method spawnLinkRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef`
-`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: Manifest[T])akka.actor.ActorRef`
-`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: Manifest[T])akka.actor.ActorRef`
+`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: ClassTag[T])akka.actor.ActorRef`
+`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: ClassTag[T])akka.actor.ActorRef`
`method spawnRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef`
-`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: Manifest[T])akka.actor.ActorRef`
-`method spawn[T <: akka.actor.Actor](implicit evidence$1: Manifest[T])akka.actor.ActorRef`
+`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: ClassTag[T])akka.actor.ActorRef`
+`method spawn[T <: akka.actor.Actor](implicit evidence$1: ClassTag[T])akka.actor.ActorRef`
`method start()akka.actor.ActorRef`
`method startLink(actorRef: akka.actor.ActorRef)Unit`
`method stop()Unit`
@@ -419,11 +419,11 @@ retrieved 131 members
`method spawn(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef`
`method spawnLink(clazz: Class[_ <: akka.actor.Actor])akka.actor.ActorRef`
`method spawnLinkRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef`
-`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: Manifest[T])akka.actor.ActorRef`
-`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: Manifest[T])akka.actor.ActorRef`
+`method spawnLinkRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$4: ClassTag[T])akka.actor.ActorRef`
+`method spawnLink[T <: akka.actor.Actor](implicit evidence$3: ClassTag[T])akka.actor.ActorRef`
`method spawnRemote(clazz: Class[_ <: akka.actor.Actor], hostname: String, port: Int, timeout: Long)akka.actor.ActorRef`
-`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: Manifest[T])akka.actor.ActorRef`
-`method spawn[T <: akka.actor.Actor](implicit evidence$1: Manifest[T])akka.actor.ActorRef`
+`method spawnRemote[T <: akka.actor.Actor](hostname: String, port: Int, timeout: Long)(implicit evidence$2: ClassTag[T])akka.actor.ActorRef`
+`method spawn[T <: akka.actor.Actor](implicit evidence$1: ClassTag[T])akka.actor.ActorRef`
`method start()akka.actor.ActorRef`
`method startLink(actorRef: akka.actor.ActorRef)Unit`
`method stop()Unit`
diff --git a/test/disabled/presentation/akka/src/akka/actor/Actor.scala b/test/disabled/presentation/akka/src/akka/actor/Actor.scala
index b955c4c38b..b9bc51b635 100644
--- a/test/disabled/presentation/akka/src/akka/actor/Actor.scala
+++ b/test/disabled/presentation/akka/src/akka/actor/Actor.scala
@@ -135,7 +135,7 @@ object Actor extends ListenerManagement {
* val actor = actorOf[MyActor].start()
* </pre>
*/
- def actorOf[T <: Actor: Manifest]: ActorRef = actorOf(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]])
+ def actorOf[T <: Actor: ClassTag]: ActorRef = actorOf(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]])
/** Creates an ActorRef out of the Actor of the specified Class.
* <pre>
@@ -481,7 +481,7 @@ private[actor] class AnyOptionAsTypedOption(anyOption: Option[Any]) {
/** Convenience helper to cast the given Option of Any to an Option of the given type. Will swallow a possible
* ClassCastException and return None in that case.
*/
- def asSilently[T: Manifest]: Option[T] = narrowSilently[T](anyOption)
+ def asSilently[T: ClassTag]: Option[T] = narrowSilently[T](anyOption)
}
/** Marker interface for proxyable actors (such as typed actor).
diff --git a/test/disabled/presentation/akka/src/akka/actor/ActorRef.scala b/test/disabled/presentation/akka/src/akka/actor/ActorRef.scala
index ff67c9468e..da0b63006a 100644
--- a/test/disabled/presentation/akka/src/akka/actor/ActorRef.scala
+++ b/test/disabled/presentation/akka/src/akka/actor/ActorRef.scala
@@ -1406,28 +1406,28 @@ trait ScalaActorRef extends ActorRefShared { ref: ActorRef =>
/**
* Atomically create (from actor class) and start an actor.
*/
- def spawn[T <: Actor: Manifest]: ActorRef =
- spawn(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]])
+ def spawn[T <: Actor: ClassTag]: ActorRef =
+ spawn(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]])
/**
* Atomically create (from actor class), start and make an actor remote.
*/
- def spawnRemote[T <: Actor: Manifest](hostname: String, port: Int, timeout: Long): ActorRef = {
+ def spawnRemote[T <: Actor: ClassTag](hostname: String, port: Int, timeout: Long): ActorRef = {
ensureRemotingEnabled
- spawnRemote(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout)
+ spawnRemote(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout)
}
/**
* Atomically create (from actor class), start and link an actor.
*/
- def spawnLink[T <: Actor: Manifest]: ActorRef =
- spawnLink(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]])
+ def spawnLink[T <: Actor: ClassTag]: ActorRef =
+ spawnLink(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]])
/**
* Atomically create (from actor class), start, link and make an actor remote.
*/
- def spawnLinkRemote[T <: Actor: Manifest](hostname: String, port: Int, timeout: Long): ActorRef = {
+ def spawnLinkRemote[T <: Actor: ClassTag](hostname: String, port: Int, timeout: Long): ActorRef = {
ensureRemotingEnabled
- spawnLinkRemote(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout)
+ spawnLinkRemote(classTag[T].erasure.asInstanceOf[Class[_ <: Actor]], hostname, port, timeout)
}
}
diff --git a/test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala b/test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala
index df335dc8b4..5d649fcd36 100644
--- a/test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala
+++ b/test/disabled/presentation/akka/src/akka/actor/ActorRegistry.scala
@@ -5,7 +5,7 @@
package akka.actor
import scala.collection.mutable.{ ListBuffer, Map }
-import scala.reflect.Manifest
+import scala.reflect.ArrayTag
import java.util.concurrent.{ ConcurrentSkipListSet, ConcurrentHashMap }
import java.util.{ Set => JSet }
@@ -74,10 +74,10 @@ final class ActorRegistry private[actor] () extends ListenerManagement {
}
/**
- * Finds all actors that are subtypes of the class passed in as the Manifest argument and supporting passed message.
+ * Finds all actors that are subtypes of the class passed in as the ClassTag argument and supporting passed message.
*/
- def actorsFor[T <: Actor](message: Any)(implicit manifest: Manifest[T]): Array[ActorRef] =
- filter(a => manifest.erasure.isAssignableFrom(a.actor.getClass) && a.isDefinedAt(message))
+ def actorsFor[T <: Actor](message: Any)(implicit classTag: ClassTag[T]): Array[ActorRef] =
+ filter(a => classTag.erasure.isAssignableFrom(a.actor.getClass) && a.isDefinedAt(message))
/**
* Finds all actors that satisfy a predicate.
@@ -93,16 +93,16 @@ final class ActorRegistry private[actor] () extends ListenerManagement {
}
/**
- * Finds all actors that are subtypes of the class passed in as the Manifest argument.
+ * Finds all actors that are subtypes of the class passed in as the ClassTag argument.
*/
- def actorsFor[T <: Actor](implicit manifest: Manifest[T]): Array[ActorRef] =
- actorsFor[T](manifest.erasure.asInstanceOf[Class[T]])
+ def actorsFor[T <: Actor](implicit classTag: ClassTag[T]): Array[ActorRef] =
+ actorsFor[T](classTag.erasure.asInstanceOf[Class[T]])
/**
* Finds any actor that matches T. Very expensive, traverses ALL alive actors.
*/
- def actorFor[T <: Actor](implicit manifest: Manifest[T]): Option[ActorRef] =
- find({ case a: ActorRef if manifest.erasure.isAssignableFrom(a.actor.getClass) => a })
+ def actorFor[T <: Actor](implicit classTag: ClassTag[T]): Option[ActorRef] =
+ find({ case a: ActorRef if classTag.erasure.isAssignableFrom(a.actor.getClass) => a })
/**
* Finds all actors of type or sub-type specified by the class passed in as the Class argument.
@@ -166,21 +166,21 @@ final class ActorRegistry private[actor] () extends ListenerManagement {
}
/**
- * Finds all typed actors that are subtypes of the class passed in as the Manifest argument.
+ * Finds all typed actors that are subtypes of the class passed in as the ClassTag argument.
*/
- def typedActorsFor[T <: AnyRef](implicit manifest: Manifest[T]): Array[AnyRef] = {
+ def typedActorsFor[T <: AnyRef](implicit classTag: ClassTag[T]): Array[AnyRef] = {
TypedActorModule.ensureEnabled
- typedActorsFor[T](manifest.erasure.asInstanceOf[Class[T]])
+ typedActorsFor[T](classTag.erasure.asInstanceOf[Class[T]])
}
/**
* Finds any typed actor that matches T.
*/
- def typedActorFor[T <: AnyRef](implicit manifest: Manifest[T]): Option[AnyRef] = {
+ def typedActorFor[T <: AnyRef](implicit classTag: ClassTag[T]): Option[AnyRef] = {
TypedActorModule.ensureEnabled
def predicate(proxy: AnyRef): Boolean = {
val actorRef = TypedActorModule.typedActorObjectInstance.get.actorFor(proxy)
- actorRef.isDefined && manifest.erasure.isAssignableFrom(actorRef.get.actor.getClass)
+ actorRef.isDefined && classTag.erasure.isAssignableFrom(actorRef.get.actor.getClass)
}
findTypedActor({ case a: Some[AnyRef] if predicate(a.get) => a })
}
@@ -279,7 +279,7 @@ final class ActorRegistry private[actor] () extends ListenerManagement {
*
* @author Viktor Klang
*/
-class Index[K <: AnyRef, V <: AnyRef: Manifest] {
+class Index[K <: AnyRef, V <: AnyRef: ArrayTag] {
private val Naught = Array[V]() //Nil for Arrays
private val container = new ConcurrentHashMap[K, JSet[V]]
private val emptySet = new ConcurrentSkipListSet[V]
diff --git a/test/disabled/presentation/akka/src/akka/event/EventHandler.scala b/test/disabled/presentation/akka/src/akka/event/EventHandler.scala
index f3176b7c21..af2fee6c47 100644
--- a/test/disabled/presentation/akka/src/akka/event/EventHandler.scala
+++ b/test/disabled/presentation/akka/src/akka/event/EventHandler.scala
@@ -115,8 +115,8 @@ object EventHandler extends ListenerManagement {
notifyListeners(event)
}
- def notify[T <: Event: ClassManifest](event: => T) {
- if (level >= levelFor(classManifest[T].erasure.asInstanceOf[Class[_ <: Event]])) notifyListeners(event)
+ def notify[T <: Event: ClassTag](event: => T) {
+ if (level >= levelFor(classTag[T].erasure.asInstanceOf[Class[_ <: Event]])) notifyListeners(event)
}
def error(cause: Throwable, instance: AnyRef, message: => String) {
diff --git a/test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala b/test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala
index 0c5da82294..5219c49dcb 100644
--- a/test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala
+++ b/test/disabled/presentation/akka/src/akka/remoteinterface/RemoteInterface.scala
@@ -206,8 +206,8 @@ abstract class RemoteSupport extends ListenerManagement with RemoteServerModule
* </pre>
*/
@deprecated("Will be removed after 1.1", "1.1")
- def actorOf[T <: Actor: Manifest](host: String, port: Int): ActorRef =
- clientManagedActorOf(() => createActorFromClass(manifest.erasure), host, port)
+ def actorOf[T <: Actor: ClassTag](host: String, port: Int): ActorRef =
+ clientManagedActorOf(() => createActorFromClass(classTag[T].erasure), host, port)
protected def createActorFromClass(clazz: Class[_]): Actor = {
import ReflectiveAccess.{ createInstance, noParams, noArgs }
diff --git a/test/disabled/presentation/akka/src/akka/util/Helpers.scala b/test/disabled/presentation/akka/src/akka/util/Helpers.scala
index 48477426c9..0ff45408d0 100644
--- a/test/disabled/presentation/akka/src/akka/util/Helpers.scala
+++ b/test/disabled/presentation/akka/src/akka/util/Helpers.scala
@@ -37,7 +37,7 @@ object Helpers {
* Convenience helper to cast the given Option of Any to an Option of the given type. Will swallow a possible
* ClassCastException and return None in that case.
*/
- def narrowSilently[T: Manifest](o: Option[Any]): Option[T] =
+ def narrowSilently[T: ClassTag](o: Option[Any]): Option[T] =
try {
narrow(o)
} catch {
diff --git a/test/files/presentation/shutdown-deadlock.check b/test/disabled/presentation/shutdown-deadlock.check
index ddcb4ff59b..ddcb4ff59b 100644
--- a/test/files/presentation/shutdown-deadlock.check
+++ b/test/disabled/presentation/shutdown-deadlock.check
diff --git a/test/files/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala b/test/disabled/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala
index 53af84541a..cef9d2a5ed 100644
--- a/test/files/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala
+++ b/test/disabled/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala
@@ -20,7 +20,7 @@ object Test extends InteractiveTest {
}
for ((j, i) <- jobs1.zipWithIndex) {
- j.get(5000) match {
+ j.get(40000) match {
case None =>
println(i + ": TIMEOUT")
exit(1) // no need to delay the test any longer
diff --git a/test/files/presentation/shutdown-deadlock/src/arrays.scala b/test/disabled/presentation/shutdown-deadlock/src/arrays.scala
index ecebc78a6f..ecebc78a6f 100644
--- a/test/files/presentation/shutdown-deadlock/src/arrays.scala
+++ b/test/disabled/presentation/shutdown-deadlock/src/arrays.scala
diff --git a/test/disabled/presentation/simple-tests.check b/test/disabled/presentation/simple-tests.check
index b90dfce77c..cdb80ed987 100644
--- a/test/disabled/presentation/simple-tests.check
+++ b/test/disabled/presentation/simple-tests.check
@@ -244,7 +244,7 @@ TypeMember(method disable,(s: Tester.this.settings.Setting)scala.collection.muta
TypeMember(value disable,Tester.this.settings.MultiStringSetting,false,true,<none>)
TypeMember(value elidebelow,Tester.this.settings.IntSetting,false,true,<none>)
TypeMember(method embeddedDefaults,(loader: java.lang.ClassLoader)Unit,true,true,<none>)
-TypeMember(method embeddedDefaults,[T](implicit evidence$1: Manifest[T])Unit,true,true,<none>)
+TypeMember(method embeddedDefaults,[T](implicit evidence$1: ClassTag[T])Unit,true,true,<none>)
TypeMember(value encoding,Tester.this.settings.StringSetting,false,true,<none>)
TypeMember(method ensuring,(cond: (scala.tools.nsc.Settings) => Boolean,msg: => Any)scala.tools.nsc.Settings,true,false,method any2Ensuring)
TypeMember(method ensuring,(cond: (scala.tools.nsc.Settings) => Boolean)scala.tools.nsc.Settings,true,false,method any2Ensuring)
diff --git a/test/files/buildmanager/t2559/D.scala b/test/files/buildmanager/t2559/D.scala
index 906b69a3e7..62dc5427f9 100644
--- a/test/files/buildmanager/t2559/D.scala
+++ b/test/files/buildmanager/t2559/D.scala
@@ -1,8 +1,4 @@
object D {
- def x(a: A) =
- a match {
- case _: B => ()
- case _: C => ()
- }
+ def x(a: A) = if (a.isInstanceOf[B] || a.isInstanceOf[C]) ()
}
diff --git a/test/files/buildmanager/t2559/t2559.check b/test/files/buildmanager/t2559/t2559.check
index 752278fbe8..4d43838cf5 100644
--- a/test/files/buildmanager/t2559/t2559.check
+++ b/test/files/buildmanager/t2559/t2559.check
@@ -6,9 +6,4 @@ compiling Set(A.scala)
Changes: Map(class B -> List(), class C -> List(), class E -> List(Changed(Class(A))[class E extends a sealed trait A]), trait A -> List())
invalidate D.scala because it references changed class [Changed(Class(A))[class E extends a sealed trait A]]
compiling Set(D.scala)
-D.scala:3: warning: match is not exhaustive!
-missing combination E
-
- a match {
- ^
Changes: Map(object D -> List())
diff --git a/test/files/buildmanager/t2650_1/t2650_1.check b/test/files/buildmanager/t2650_1/t2650_1.check
index ecddb33620..f1e4b1b8bc 100644
--- a/test/files/buildmanager/t2650_1/t2650_1.check
+++ b/test/files/buildmanager/t2650_1/t2650_1.check
@@ -1,5 +1,6 @@
builder > A.scala B.scala
compiling Set(A.scala, B.scala)
+warning: there were 1 feature warnings; re-run with -feature for details
Changes: Map()
builder > A.scala
compiling Set(A.scala)
diff --git a/test/files/buildmanager/t2657/t2657.check b/test/files/buildmanager/t2657/t2657.check
index 74ba87a21d..cd0357599c 100644
--- a/test/files/buildmanager/t2657/t2657.check
+++ b/test/files/buildmanager/t2657/t2657.check
@@ -1,5 +1,6 @@
builder > A.scala B.scala
compiling Set(A.scala, B.scala)
+warning: there were 1 feature warnings; re-run with -feature for details
Changes: Map()
builder > A.scala
compiling Set(A.scala)
diff --git a/test/files/codelib/code.jar.desired.sha1 b/test/files/codelib/code.jar.desired.sha1
index 8dabf404b9..21c4dccb30 100644
--- a/test/files/codelib/code.jar.desired.sha1
+++ b/test/files/codelib/code.jar.desired.sha1
@@ -1 +1 @@
-e76a8883d275ca4870f745b505fb0a1cb9cbe446 ?code.jar
+3ddb9fded6e19ca591a78b8a294284c9e945da30 ?code.jar
diff --git a/test/files/continuations-run/match2.scala b/test/files/continuations-run/match2.scala
index 8b0fb946df..5092ce3abe 100644
--- a/test/files/continuations-run/match2.scala
+++ b/test/files/continuations-run/match2.scala
@@ -18,7 +18,7 @@ object Test {
}
- def main(args: Array[String]): Any = {
+ def main(args: Array[String]): Unit = {
println(reset(test1()))
println(reset(test2()))
}
diff --git a/test/files/continuations-run/shift-pct.check b/test/files/continuations-run/shift-pct.check
new file mode 100644
index 0000000000..fb190e770a
--- /dev/null
+++ b/test/files/continuations-run/shift-pct.check
@@ -0,0 +1,25 @@
+d = 1, d2 = 1.0, pct = 1.000
+d = 2, d2 = 4.0, pct = 0.500
+d = 3, d2 = 9.0, pct = 0.333
+d = 4, d2 = 16.0, pct = 0.250
+d = 5, d2 = 25.0, pct = 0.200
+d = 6, d2 = 36.0, pct = 0.167
+d = 7, d2 = 49.0, pct = 0.143
+d = 8, d2 = 64.0, pct = 0.125
+d = 9, d2 = 81.0, pct = 0.111
+d = 10, d2 = 100.0, pct = 0.100
+d = 11, d2 = 121.0, pct = 0.091
+d = 12, d2 = 144.0, pct = 0.083
+d = 13, d2 = 169.0, pct = 0.077
+d = 14, d2 = 196.0, pct = 0.071
+d = 15, d2 = 225.0, pct = 0.067
+d = 16, d2 = 256.0, pct = 0.063
+d = 17, d2 = 289.0, pct = 0.059
+d = 18, d2 = 324.0, pct = 0.056
+d = 19, d2 = 361.0, pct = 0.053
+d = 20, d2 = 400.0, pct = 0.050
+d = 21, d2 = 441.0, pct = 0.048
+d = 22, d2 = 484.0, pct = 0.045
+d = 23, d2 = 529.0, pct = 0.043
+d = 24, d2 = 576.0, pct = 0.042
+d = 25, d2 = 625.0, pct = 0.040
diff --git a/test/files/continuations-run/shift-pct.scala b/test/files/continuations-run/shift-pct.scala
new file mode 100644
index 0000000000..7ef9922168
--- /dev/null
+++ b/test/files/continuations-run/shift-pct.scala
@@ -0,0 +1,30 @@
+import scala.util.continuations._
+
+object Test {
+ abstract class IfReturnRepro {
+ def s1: Double @cpsParam[Any, Unit]
+ def s2: Double @cpsParam[Any, Unit]
+
+ def p(i: Int): Double @cpsParam[Unit, Any] = {
+ val px = s1
+ val pct = if (px > 100) px else px / s2
+ println("pct = %.3f".format(pct))
+ pct
+ }
+ }
+
+ def main(args: Array[String]) : Unit = {
+ var d: Double = 0d
+ def d2 = d * d
+
+ val irr = new IfReturnRepro {
+ def s1 = shift(f => f(d))
+ def s2 = shift(f => f(d2))
+ }
+ 1 to 25 foreach { i =>
+ d = i
+ print("d = " + i + ", d2 = " + d2 + ", ")
+ run(irr p i)
+ }
+ }
+}
diff --git a/test/pending/run/reify_classfileann_b.check b/test/files/continuations-run/z1673.check
index e69de29bb2..e69de29bb2 100644
--- a/test/pending/run/reify_classfileann_b.check
+++ b/test/files/continuations-run/z1673.check
diff --git a/test/files/continuations-run/z1673.scala b/test/files/continuations-run/z1673.scala
new file mode 100644
index 0000000000..716b374860
--- /dev/null
+++ b/test/files/continuations-run/z1673.scala
@@ -0,0 +1,31 @@
+import scala.util.continuations._
+
+class MatchRepro {
+ def s: String @cps[Any] = shift { k => k("foo") }
+
+ def p = {
+ val k = s
+ s match { case lit0 => }
+ }
+
+ def q = {
+ val k = s
+ k match { case lit1 => }
+ }
+
+ def r = {
+ s match { case "FOO" => }
+ }
+
+ def t = {
+ val k = s
+ k match { case "FOO" => }
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val m = new MatchRepro
+ ()
+ }
+}
diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check
index 243c9aa3be..dc835bf8b6 100755..100644
--- a/test/files/jvm/interpreter.check
+++ b/test/files/jvm/interpreter.check
@@ -1,372 +1,374 @@
-Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala>
-
-scala> // basics
-
-scala> 3+4
-res0: Int = 7
-
-scala> def gcd(x: Int, y: Int): Int = {
- if (x == 0) y
- else if (y == 0) x
- else gcd(y%x, x)
-}
-gcd: (x: Int, y: Int)Int
-
-scala> val five = gcd(15,35)
-five: Int = 5
-
-scala> var x = 1
-x: Int = 1
-
-scala> x = 2
-x: Int = 2
-
-scala> val three = x+1
-three: Int = 3
-
-scala> type anotherint = Int
-defined type alias anotherint
-
-scala> val four: anotherint = 4
-four: anotherint = 4
-
-scala> val bogus: anotherint = "hello"
-<console>:8: error: type mismatch;
- found : String("hello")
- required: anotherint
- (which expands to) Int
- val bogus: anotherint = "hello"
- ^
-
-scala> trait PointlessTrait
-defined trait PointlessTrait
-
-scala> val (x,y) = (2,3)
-x: Int = 2
-y: Int = 3
-
-scala> println("hello")
-hello
-
-scala>
-
-scala> // ticket #1513
-
-scala> val t1513 = Array(null)
-t1513: Array[Null] = Array(null)
-
-scala> // ambiguous toString problem from #547
-
-scala> val atom = new scala.xml.Atom()
-atom: scala.xml.Atom[Unit] = ()
-
-scala> // overriding toString problem from #1404
-
-scala> class S(override val toString : String)
-defined class S
-
-scala> val fish = new S("fish")
-fish: S = fish
-
-scala> // Test that arrays pretty print nicely.
-
-scala> val arr = Array("What's", "up", "doc?")
-arr: Array[String] = Array(What's, up, doc?)
-
-scala> // Test that arrays pretty print nicely, even when we give them type Any
-
-scala> val arrInt : Any = Array(1,2,3)
-arrInt: Any = Array(1, 2, 3)
-
-scala> // Test that nested arrays are pretty-printed correctly
-
-scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4))
-arrArrInt: Any = Array(Array(1, 2), Array(3, 4))
-
-scala>
-
-scala> // implicit conversions
-
-scala> case class Foo(n: Int)
-defined class Foo
-
-scala> case class Bar(n: Int)
-defined class Bar
-
-scala> implicit def foo2bar(foo: Foo) = Bar(foo.n)
-foo2bar: (foo: Foo)Bar
-
-scala> val bar: Bar = Foo(3)
-bar: Bar = Bar(3)
-
-scala>
-
-scala> // importing from a previous result
-
-scala> import bar._
-import bar._
-
-scala> val m = n
-m: Int = 3
-
-scala>
-
-scala> // stressing the imports mechanism
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala> val one = 1
-one: Int = 1
-
-scala>
-
-scala>
-
-scala> val x1 = 1
-x1: Int = 1
-
-scala> val x2 = 1
-x2: Int = 1
-
-scala> val x3 = 1
-x3: Int = 1
-
-scala> val x4 = 1
-x4: Int = 1
-
-scala> val x5 = 1
-x5: Int = 1
-
-scala> val x6 = 1
-x6: Int = 1
-
-scala> val x7 = 1
-x7: Int = 1
-
-scala> val x8 = 1
-x8: Int = 1
-
-scala> val x9 = 1
-x9: Int = 1
-
-scala> val x10 = 1
-x10: Int = 1
-
-scala> val x11 = 1
-x11: Int = 1
-
-scala> val x12 = 1
-x12: Int = 1
-
-scala> val x13 = 1
-x13: Int = 1
-
-scala> val x14 = 1
-x14: Int = 1
-
-scala> val x15 = 1
-x15: Int = 1
-
-scala> val x16 = 1
-x16: Int = 1
-
-scala> val x17 = 1
-x17: Int = 1
-
-scala> val x18 = 1
-x18: Int = 1
-
-scala> val x19 = 1
-x19: Int = 1
-
-scala> val x20 = 1
-x20: Int = 1
-
-scala>
-
-scala> val two = one + x5
-two: Int = 2
-
-scala>
-
-scala> // handling generic wildcard arrays (#2386)
-
-scala> // It's put here because type feedback is an important part of it.
-
-scala> val xs: Array[_] = Array(1, 2)
-xs: Array[_] = Array(1, 2)
-
-scala> xs.size
-res2: Int = 2
-
-scala> xs.head
-res3: Any = 1
-
-scala> xs filter (_ == 2)
-res4: Array[_] = Array(2)
-
-scala> xs map (_ => "abc")
-res5: Array[String] = Array(abc, abc)
-
-scala> xs map (x => x)
-res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2)
-
-scala> xs map (x => (x, x))
-res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2))
-
-scala>
-
-scala> // interior syntax errors should *not* go into multi-line input mode.
-
-scala> // both of the following should abort immediately:
-
-scala> def x => y => z
-<console>:1: error: '=' expected but '=>' found.
- def x => y => z
- ^
-
-scala> [1,2,3]
-<console>:1: error: illegal start of definition
- [1,2,3]
- ^
-
-scala>
-
-scala>
-
-scala> // multi-line XML
-
-scala> <a>
-<b
- c="c"
- d="dd"
-/></a>
-res8: scala.xml.Elem =
-<a>
-<b c="c" d="dd"/></a>
-
-scala>
-
-scala>
-
-scala> /*
- /*
- multi-line comment
- */
-*/
-
-scala>
-
-scala>
-
-scala> // multi-line string
-
-scala> """
-hello
-there
-"""
-res9: String =
-"
-hello
-there
-"
-
-scala>
-
-scala> (1 + // give up early by typing two blank lines
-
-
-You typed two blank lines. Starting a new command.
-
-scala> // defining and using quoted names should work (ticket #323)
-
-scala> def `match` = 1
-match: Int
-
-scala> val x = `match`
-x: Int = 1
-
-scala>
-
-scala> // multiple classes defined on one line
-
-scala> sealed class Exp; class Fact extends Exp; class Term extends Exp
-defined class Exp
-defined class Fact
-defined class Term
-
-scala> def f(e: Exp) = e match { // non-exhaustive warning here
- case _:Fact => 3
-}
-<console>:18: warning: match is not exhaustive!
-missing combination Exp
-missing combination Term
-
- def f(e: Exp) = e match { // non-exhaustive warning here
- ^
-f: (e: Exp)Int
-
-scala>
-
-scala>
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> // basics
+
+scala> 3+4
+res0: Int = 7
+
+scala> def gcd(x: Int, y: Int): Int = {
+ if (x == 0) y
+ else if (y == 0) x
+ else gcd(y%x, x)
+}
+gcd: (x: Int, y: Int)Int
+
+scala> val five = gcd(15,35)
+five: Int = 5
+
+scala> var x = 1
+x: Int = 1
+
+scala> x = 2
+x: Int = 2
+
+scala> val three = x+1
+three: Int = 3
+
+scala> type anotherint = Int
+defined type alias anotherint
+
+scala> val four: anotherint = 4
+four: anotherint = 4
+
+scala> val bogus: anotherint = "hello"
+<console>:8: error: type mismatch;
+ found : String("hello")
+ required: anotherint
+ (which expands to) Int
+ val bogus: anotherint = "hello"
+ ^
+
+scala> trait PointlessTrait
+defined trait PointlessTrait
+
+scala> val (x,y) = (2,3)
+x: Int = 2
+y: Int = 3
+
+scala> println("hello")
+hello
+
+scala>
+
+scala> // ticket #1513
+
+scala> val t1513 = Array(null)
+t1513: Array[Null] = Array(null)
+
+scala> // ambiguous toString problem from #547
+
+scala> val atom = new scala.xml.Atom()
+atom: scala.xml.Atom[Unit] = ()
+
+scala> // overriding toString problem from #1404
+
+scala> class S(override val toString : String)
+defined class S
+
+scala> val fish = new S("fish")
+fish: S = fish
+
+scala> // Test that arrays pretty print nicely.
+
+scala> val arr = Array("What's", "up", "doc?")
+arr: Array[String] = Array(What's, up, doc?)
+
+scala> // Test that arrays pretty print nicely, even when we give them type Any
+
+scala> val arrInt : Any = Array(1,2,3)
+arrInt: Any = Array(1, 2, 3)
+
+scala> // Test that nested arrays are pretty-printed correctly
+
+scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4))
+arrArrInt: Any = Array(Array(1, 2), Array(3, 4))
+
+scala>
+
+scala> // implicit conversions
+
+scala> case class Foo(n: Int)
+defined class Foo
+
+scala> case class Bar(n: Int)
+defined class Bar
+
+scala> implicit def foo2bar(foo: Foo) = Bar(foo.n)
+warning: there were 1 feature warnings; re-run with -feature for details
+foo2bar: (foo: Foo)Bar
+
+scala> val bar: Bar = Foo(3)
+bar: Bar = Bar(3)
+
+scala>
+
+scala> // importing from a previous result
+
+scala> import bar._
+import bar._
+
+scala> val m = n
+m: Int = 3
+
+scala>
+
+scala> // stressing the imports mechanism
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala> val one = 1
+one: Int = 1
+
+scala>
+
+scala>
+
+scala> val x1 = 1
+x1: Int = 1
+
+scala> val x2 = 1
+x2: Int = 1
+
+scala> val x3 = 1
+x3: Int = 1
+
+scala> val x4 = 1
+x4: Int = 1
+
+scala> val x5 = 1
+x5: Int = 1
+
+scala> val x6 = 1
+x6: Int = 1
+
+scala> val x7 = 1
+x7: Int = 1
+
+scala> val x8 = 1
+x8: Int = 1
+
+scala> val x9 = 1
+x9: Int = 1
+
+scala> val x10 = 1
+x10: Int = 1
+
+scala> val x11 = 1
+x11: Int = 1
+
+scala> val x12 = 1
+x12: Int = 1
+
+scala> val x13 = 1
+x13: Int = 1
+
+scala> val x14 = 1
+x14: Int = 1
+
+scala> val x15 = 1
+x15: Int = 1
+
+scala> val x16 = 1
+x16: Int = 1
+
+scala> val x17 = 1
+x17: Int = 1
+
+scala> val x18 = 1
+x18: Int = 1
+
+scala> val x19 = 1
+x19: Int = 1
+
+scala> val x20 = 1
+x20: Int = 1
+
+scala>
+
+scala> val two = one + x5
+two: Int = 2
+
+scala>
+
+scala> // handling generic wildcard arrays (#2386)
+
+scala> // It's put here because type feedback is an important part of it.
+
+scala> val xs: Array[_] = Array(1, 2)
+xs: Array[_] = Array(1, 2)
+
+scala> xs.size
+res2: Int = 2
+
+scala> xs.head
+res3: Any = 1
+
+scala> xs filter (_ == 2)
+res4: Array[_] = Array(2)
+
+scala> xs map (_ => "abc")
+res5: Array[String] = Array(abc, abc)
+
+scala> xs map (x => x)
+res6: Array[_] = Array(1, 2)
+
+scala> xs map (x => (x, x))
+warning: there were 1 feature warnings; re-run with -feature for details
+warning: there were 1 feature warnings; re-run with -feature for details
+res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2))
+
+scala>
+
+scala> // interior syntax errors should *not* go into multi-line input mode.
+
+scala> // both of the following should abort immediately:
+
+scala> def x => y => z
+<console>:1: error: '=' expected but '=>' found.
+ def x => y => z
+ ^
+
+scala> [1,2,3]
+<console>:1: error: illegal start of definition
+ [1,2,3]
+ ^
+
+scala>
+
+scala>
+
+scala> // multi-line XML
+
+scala> <a>
+<b
+ c="c"
+ d="dd"
+/></a>
+res8: scala.xml.Elem =
+<a>
+<b c="c" d="dd"/></a>
+
+scala>
+
+scala>
+
+scala> /*
+ /*
+ multi-line comment
+ */
+*/
+
+
+You typed two blank lines. Starting a new command.
+
+scala> // multi-line string
+
+scala> """
+hello
+there
+"""
+res12: String =
+"
+hello
+there
+"
+
+scala>
+
+scala> (1 + // give up early by typing two blank lines
+
+
+You typed two blank lines. Starting a new command.
+
+scala> // defining and using quoted names should work (ticket #323)
+
+scala> def `match` = 1
+match: Int
+
+scala> val x = `match`
+x: Int = 1
+
+scala>
+
+scala> // multiple classes defined on one line
+
+scala> sealed class Exp; class Fact extends Exp; class Term extends Exp
+defined class Exp
+defined class Fact
+defined class Term
+
+scala> def f(e: Exp) = e match { // non-exhaustive warning here
+ case _:Fact => 3
+}
+<console>:18: warning: match is not exhaustive!
+missing combination Exp
+missing combination Term
+
+ def f(e: Exp) = e match { // non-exhaustive warning here
+ ^
+f: (e: Exp)Int
+
+scala>
+
+scala>
plusOne: (x: Int)Int
res0: Int = 6
res0: String = after reset
diff --git a/test/files/jvm/interpreter.scala b/test/files/jvm/interpreter.scala
index f0bc8b5818..755b2ac9ae 100644
--- a/test/files/jvm/interpreter.scala
+++ b/test/files/jvm/interpreter.scala
@@ -2,6 +2,7 @@ import scala.tools.nsc._
import scala.tools.partest.ReplTest
object Test extends ReplTest {
+ override def extraSettings = "-deprecation -Xoldpatmat"
def code = <code>
// basics
3+4
@@ -29,7 +30,7 @@ val atom = new scala.xml.Atom()
class S(override val toString : String)
val fish = new S("fish")
// Test that arrays pretty print nicely.
-val arr = Array("What's", "up", "doc?")
+val arr = Array("What's", "up", "doc?")
// Test that arrays pretty print nicely, even when we give them type Any
val arrInt : Any = Array(1,2,3)
// Test that nested arrays are pretty-printed correctly
@@ -132,8 +133,8 @@ there
// defining and using quoted names should work (ticket #323)
-def `match` = 1
-val x = `match`
+def `match` = 1
+val x = `match`
// multiple classes defined on one line
sealed class Exp; class Fact extends Exp; class Term extends Exp
@@ -153,6 +154,6 @@ def f(e: Exp) = e match {{ // non-exhaustive warning here
interp.interpret("\"after reset\"")
interp.interpret("plusOne(5) // should be undefined now")
}
-
+
appendix()
}
diff --git a/test/files/jvm/manifests-new.check b/test/files/jvm/manifests-new.check
new file mode 100644
index 0000000000..9fca856970
--- /dev/null
+++ b/test/files/jvm/manifests-new.check
@@ -0,0 +1,58 @@
+x=(), t=ConcreteTypeTag[Unit], k=TypeRef, s=class Unit
+x=true, t=ConcreteTypeTag[Boolean], k=TypeRef, s=class Boolean
+x=a, t=ConcreteTypeTag[Char], k=TypeRef, s=class Char
+x=1, t=ConcreteTypeTag[Int], k=TypeRef, s=class Int
+x=abc, t=ConcreteTypeTag[String], k=TypeRef, s=class String
+x='abc, t=ConcreteTypeTag[Symbol], k=TypeRef, s=class Symbol
+
+x=List(()), t=ConcreteTypeTag[List[Unit]], k=TypeRef, s=class List
+x=List(true), t=ConcreteTypeTag[List[Boolean]], k=TypeRef, s=class List
+x=List(1), t=ConcreteTypeTag[List[Int]], k=TypeRef, s=class List
+x=List(abc), t=ConcreteTypeTag[List[String]], k=TypeRef, s=class List
+x=List('abc), t=ConcreteTypeTag[List[Symbol]], k=TypeRef, s=class List
+
+x=[Z, t=ConcreteTypeTag[Array[Boolean]], k=TypeRef, s=class Array
+x=[C, t=ConcreteTypeTag[Array[Char]], k=TypeRef, s=class Array
+x=[I, t=ConcreteTypeTag[Array[Int]], k=TypeRef, s=class Array
+x=[Ljava.lang.String;, t=ConcreteTypeTag[Array[String]], k=TypeRef, s=class Array
+x=[Lscala.Symbol;, t=ConcreteTypeTag[Array[Symbol]], k=TypeRef, s=class Array
+
+x=((),()), t=ConcreteTypeTag[(Unit, Unit)], k=TypeRef, s=class Tuple2
+x=(true,false), t=ConcreteTypeTag[(Boolean, Boolean)], k=TypeRef, s=class Tuple2
+x=(1,2), t=ConcreteTypeTag[(Int, Int)], k=TypeRef, s=class Tuple2
+x=(abc,xyz), t=ConcreteTypeTag[(String, String)], k=TypeRef, s=class Tuple2
+x=('abc,'xyz), t=ConcreteTypeTag[(Symbol, Symbol)], k=TypeRef, s=class Tuple2
+
+x=Test$, t=ConcreteTypeTag[Test.type], k=TypeRef, s=object Test
+x=scala.collection.immutable.List$, t=ConcreteTypeTag[scala.collection.immutable.List.type], k=TypeRef, s=object List
+
+x=Foo, t=ConcreteTypeTag[Foo[Int]], k=TypeRef, s=class Foo
+x=Foo, t=ConcreteTypeTag[Foo[List[Int]]], k=TypeRef, s=class Foo
+x=Foo, t=ConcreteTypeTag[Foo[Foo[Int]]], k=TypeRef, s=class Foo
+x=Foo, t=ConcreteTypeTag[Foo[List[Foo[Int]]]], k=TypeRef, s=class Foo
+
+x=Test1$$anon$1, t=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1>
+x=Test1$$anon$2, t=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1>
+
+()=()
+true=true
+a=a
+1=1
+'abc='abc
+
+List(())=List(())
+List(true)=List(true)
+List('abc)=List('abc)
+
+Array()=Array()
+Array(true)=Array(true)
+Array(a)=Array(a)
+Array(1)=Array(1)
+
+((),())=((),())
+(true,false)=(true,false)
+
+List(List(1), List(2))=List(List(1), List(2))
+
+Array(Array(1), Array(2))=Array(Array(1), Array(2))
+
diff --git a/test/files/jvm/manifests-new.scala b/test/files/jvm/manifests-new.scala
new file mode 100644
index 0000000000..d02f6ee608
--- /dev/null
+++ b/test/files/jvm/manifests-new.scala
@@ -0,0 +1,109 @@
+object Test extends App {
+ Test1
+ Test2
+}
+
+class Foo[T](x: T)
+trait Bar[T] { def f: T }
+
+object Test1 extends TestUtil {
+ print(())
+ print(true)
+ print('a')
+ print(1)
+ print("abc")
+ print('abc)
+ println()
+
+ print(List(()))
+ print(List(true))
+ print(List(1))
+ print(List("abc"))
+ print(List('abc))
+ println()
+
+ //print(Array(())) //Illegal class name "[V" in class file Test$
+ print(Array(true))
+ print(Array('a'))
+ print(Array(1))
+ print(Array("abc"))
+ print(Array('abc))
+ println()
+
+ print(((), ()))
+ print((true, false))
+ print((1, 2))
+ print(("abc", "xyz"))
+ print(('abc, 'xyz))
+ println()
+
+ print(Test)
+ print(List)
+ println()
+
+ print(new Foo(2))
+ print(new Foo(List(2)))
+ print(new Foo(new Foo(2)))
+ print(new Foo(List(new Foo(2))))
+ println()
+
+ print(new Bar[String] { def f = "abc" });
+ {print(new Bar[String] { def f = "abc" })}
+ println()
+}
+
+object Test2 {
+ import scala.util.Marshal._
+ println("()="+load[Unit](dump(())))
+ println("true="+load[Boolean](dump(true)))
+ println("a="+load[Char](dump('a')))
+ println("1="+load[Int](dump(1)))
+ println("'abc="+load[Symbol](dump('abc)))
+ println()
+
+ println("List(())="+load[List[Unit]](dump(List(()))))
+ println("List(true)="+load[List[Boolean]](dump(List(true))))
+ println("List('abc)="+load[List[Symbol]](dump(List('abc))))
+ println()
+
+ def loadArray[T](x: Array[Byte])(implicit t: reflect.ClassTag[Array[T]]) =
+ load[Array[T]](x)(t).deep.toString
+ println("Array()="+loadArray[Int](dump(Array(): Array[Int])))
+ println("Array(true)="+loadArray[Boolean](dump(Array(true))))
+ println("Array(a)="+loadArray[Char](dump(Array('a'))))
+ println("Array(1)="+loadArray[Int](dump(Array(1))))
+ println()
+
+ println("((),())="+load[(Unit, Unit)](dump(((), ()))))
+ println("(true,false)="+load[(Boolean, Boolean)](dump((true, false))))
+ println()
+
+ println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2)))))
+ println()
+
+ println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2)))))
+ println()
+}
+
+trait TestUtil {
+ import java.io._
+ def write[A](o: A): Array[Byte] = {
+ val ba = new ByteArrayOutputStream(512)
+ val out = new ObjectOutputStream(ba)
+ out.writeObject(o)
+ out.close()
+ ba.toByteArray()
+ }
+ def read[A](buffer: Array[Byte]): A = {
+ val in = new ObjectInputStream(new ByteArrayInputStream(buffer))
+ in.readObject().asInstanceOf[A]
+ }
+ import scala.reflect._
+ def print[T](x: T)(implicit t: ConcreteTypeTag[T]) {
+ // todo. type tags are not yet serializable
+// val t1: ConcreteTypeTag[T] = read(write(t))
+ val t1: ConcreteTypeTag[T] = t
+ val x1 = x.toString.replaceAll("@[0-9a-z]+$", "")
+ println("x="+x1+", t="+t1+", k="+t1.tpe.kind+", s="+t1.sym.toString)
+ }
+}
diff --git a/test/files/jvm/manifests.check b/test/files/jvm/manifests-old.check
index 54f504b929..54f504b929 100644
--- a/test/files/jvm/manifests.check
+++ b/test/files/jvm/manifests-old.check
diff --git a/test/files/jvm/manifests.scala b/test/files/jvm/manifests-old.scala
index 6bbea4d052..241966fd9d 100644
--- a/test/files/jvm/manifests.scala
+++ b/test/files/jvm/manifests-old.scala
@@ -1,7 +1,6 @@
object Test extends App {
Test1
Test2
- //Test3 // Java 1.5+ only
}
class Foo[T](x: T)
@@ -88,15 +87,6 @@ object Test2 {
println()
}
-object Test3 extends TestUtil {
- import scala.reflect.Manifest._
- val ct1 = classType(classOf[Char])
- val ct2 = classType(classOf[List[_]], ct1)
- print(ct1)
- //print(ct2) // ??? x=scala.List[char], m=scala.reflect.Manifest[scala.runtime.Nothing$]
- println()
-}
-
trait TestUtil {
import java.io._
def write[A](o: A): Array[Byte] = {
diff --git a/test/files/jvm/scala-concurrent-tck.scala b/test/files/jvm/scala-concurrent-tck.scala
index 70221c0de1..fce1a25bb6 100644
--- a/test/files/jvm/scala-concurrent-tck.scala
+++ b/test/files/jvm/scala-concurrent-tck.scala
@@ -1,6 +1,3 @@
-
-
-
import scala.concurrent.{
Future,
Promise,
@@ -67,14 +64,14 @@ trait FutureCallbacks extends TestBase {
}
}
}
-
+
def testOnSuccessWhenFailed(): Unit = once {
done =>
val f = future[Unit] {
done()
throw new Exception
}
- f onSuccess {
+ f onSuccess {
case _ => assert(false)
}
}
@@ -97,7 +94,7 @@ trait FutureCallbacks extends TestBase {
assert(x == 1)
}
}
-
+
def testOnFailureWhenSpecialThrowable(num: Int, cause: Throwable): Unit = once {
done =>
val f = future[Unit] {
@@ -142,7 +139,8 @@ trait FutureCallbacks extends TestBase {
testOnFailure()
testOnFailureWhenSpecialThrowable(5, new Error)
testOnFailureWhenSpecialThrowable(6, new scala.util.control.ControlThrowable { })
- testOnFailureWhenSpecialThrowable(7, new InterruptedException)
+ //TODO: this test is currently problematic, because NonFatal does not match InterruptedException
+ //testOnFailureWhenSpecialThrowable(7, new InterruptedException)
testOnFailureWhenTimeoutException()
}
@@ -150,59 +148,188 @@ trait FutureCallbacks extends TestBase {
trait FutureCombinators extends TestBase {
- // map: stub
def testMapSuccess(): Unit = once {
done =>
- done()
+ val f = future { 5 }
+ val g = f map { x => "result: " + x }
+ g onSuccess {
+ case s =>
+ done()
+ assert(s == "result: 5")
+ }
+ g onFailure {
+ case _ =>
+ done()
+ assert(false)
+ }
}
def testMapFailure(): Unit = once {
done =>
- done()
+ val f = future {
+ throw new Exception("exception message")
+ }
+ val g = f map { x => "result: " + x }
+ g onSuccess {
+ case _ =>
+ done()
+ assert(false)
+ }
+ g onFailure {
+ case t =>
+ done()
+ assert(t.getMessage() == "exception message")
+ }
}
- // flatMap: stub
def testFlatMapSuccess(): Unit = once {
done =>
- done()
+ val f = future { 5 }
+ val g = f flatMap { _ => future { 10 } }
+ g onSuccess {
+ case x =>
+ done()
+ assert(x == 10)
+ }
+ g onFailure {
+ case _ =>
+ done()
+ assert(false)
+ }
}
def testFlatMapFailure(): Unit = once {
done =>
- done()
+ val f = future {
+ throw new Exception("exception message")
+ }
+ val g = f flatMap { _ => future { 10 } }
+ g onSuccess {
+ case _ =>
+ done()
+ assert(false)
+ }
+ g onFailure {
+ case t =>
+ done()
+ assert(t.getMessage() == "exception message")
+ }
}
- // filter: stub
def testFilterSuccess(): Unit = once {
done =>
- done()
+ val f = future { 4 }
+ val g = f filter { _ % 2 == 0 }
+ g onSuccess {
+ case x: Int =>
+ done()
+ assert(x == 4)
+ }
+ g onFailure {
+ case _ =>
+ done()
+ assert(false)
+ }
}
def testFilterFailure(): Unit = once {
done =>
- done()
+ val f = future { 4 }
+ val g = f filter { _ % 2 == 1 }
+ g onSuccess {
+ case x: Int =>
+ done()
+ assert(false)
+ }
+ g onFailure {
+ case e: NoSuchElementException =>
+ done()
+ assert(true)
+ case _ =>
+ done()
+ assert(false)
+ }
}
- // collect: stub
def testCollectSuccess(): Unit = once {
done =>
- done()
+ val f = future { -5 }
+ val g = f collect {
+ case x if x < 0 => -x
+ }
+ g onSuccess {
+ case x: Int =>
+ done()
+ assert(x == 5)
+ }
+ g onFailure {
+ case _ =>
+ done()
+ assert(false)
+ }
}
def testCollectFailure(): Unit = once {
done =>
- done()
+ val f = future { -5 }
+ val g = f collect {
+ case x if x > 0 => x * 2
+ }
+ g onSuccess {
+ case _ =>
+ done()
+ assert(false)
+ }
+ g onFailure {
+ case e: NoSuchElementException =>
+ done()
+ assert(true)
+ case _ =>
+ done()
+ assert(false)
+ }
}
- // foreach: stub
+ /* TODO: Test for NonFatal in collect (more of a regression test at this point).
+ */
+
def testForeachSuccess(): Unit = once {
done =>
- done()
+ val p = promise[Int]()
+ val f = future[Int] { 5 }
+ f foreach { x => p.success(x * 2) }
+ val g = p.future
+
+ g.onSuccess {
+ case res: Int =>
+ done()
+ assert(res == 10)
+ }
+ g.onFailure {
+ case _ =>
+ done()
+ assert(false)
+ }
}
def testForeachFailure(): Unit = once {
done =>
- done()
+ val p = promise[Int]()
+ val f = future[Int] { throw new Exception }
+ f foreach { x => p.success(x * 2) }
+ f onFailure { case _ => p.failure(new Exception) }
+ val g = p.future
+
+ g.onSuccess {
+ case _ =>
+ done()
+ assert(false)
+ }
+ g.onFailure {
+ case _ =>
+ done()
+ assert(true)
+ }
}
def testRecoverSuccess(): Unit = once {
@@ -240,6 +367,132 @@ trait FutureCombinators extends TestBase {
}
}
+ def testRecoverWithSuccess(): Unit = once {
+ done =>
+ val cause = new RuntimeException
+ val f = future {
+ throw cause
+ } recoverWith {
+ case re: RuntimeException =>
+ future { "recovered" }
+ } onSuccess {
+ case x =>
+ done()
+ assert(x == "recovered")
+ } onFailure { case any =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testRecoverWithFailure(): Unit = once {
+ done =>
+ val cause = new RuntimeException
+ val f = future {
+ throw cause
+ } recoverWith {
+ case te: TimeoutException =>
+ future { "timeout" }
+ } onSuccess {
+ case x =>
+ done()
+ assert(false)
+ } onFailure { case any =>
+ done()
+ assert(any == cause)
+ }
+ }
+
+ def testZipSuccess(): Unit = once {
+ done =>
+ val f = future { 5 }
+ val g = future { 6 }
+ val h = f zip g
+ h onSuccess {
+ case (l: Int, r: Int) =>
+ done()
+ assert(l+r == 11)
+ }
+ h onFailure {
+ case _ =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testZipFailureLeft(): Unit = once {
+ done =>
+ val cause = new Exception("exception message")
+ val f = future { throw cause }
+ val g = future { 6 }
+ val h = f zip g
+ h onSuccess {
+ case _ =>
+ done()
+ assert(false)
+ }
+ h onFailure {
+ case e: Exception =>
+ done()
+ assert(e.getMessage == "exception message")
+ }
+ }
+
+ def testZipFailureRight(): Unit = once {
+ done =>
+ val cause = new Exception("exception message")
+ val f = future { 5 }
+ val g = future { throw cause }
+ val h = f zip g
+ h onSuccess {
+ case _ =>
+ done()
+ assert(false)
+ }
+ h onFailure {
+ case e: Exception =>
+ done()
+ assert(e.getMessage == "exception message")
+ }
+ }
+
+ def testFallbackTo(): Unit = once {
+ done =>
+ val f = future { sys.error("failed") }
+ val g = future { 5 }
+ val h = f fallbackTo g
+
+ h onSuccess {
+ case x: Int =>
+ done()
+ assert(x == 5)
+ }
+ h onFailure {
+ case _ =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testFallbackToFailure(): Unit = once {
+ done =>
+ val cause = new Exception
+ val f = future { sys.error("failed") }
+ val g = future { throw cause }
+ val h = f fallbackTo g
+
+ h onSuccess {
+ case _ =>
+ done()
+ assert(false)
+ }
+ h onFailure {
+ case e: Exception =>
+ done()
+ assert(e == cause)
+ }
+ }
+
testMapSuccess()
testMapFailure()
testFlatMapSuccess()
@@ -252,7 +505,13 @@ trait FutureCombinators extends TestBase {
testForeachFailure()
testRecoverSuccess()
testRecoverFailure()
-
+ testRecoverWithSuccess()
+ testRecoverWithFailure()
+ testZipSuccess()
+ testZipFailureLeft()
+ testZipFailureRight()
+ testFallbackTo()
+ testFallbackToFailure()
}
@@ -398,6 +657,80 @@ trait Exceptions extends TestBase {
}
+trait TryEitherExtractor extends TestBase {
+
+ import scala.util.{Try, Success, Failure}
+
+ def testSuccessMatch(): Unit = once {
+ done =>
+ val thisIsASuccess = Success(42)
+ thisIsASuccess match {
+ case Success(v) =>
+ done()
+ assert(v == 42)
+ case Failure(e) =>
+ done()
+ assert(false)
+ case other =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testRightMatch(): Unit = once {
+ done =>
+ val thisIsNotASuccess: Right[Throwable, Int] = Right(43)
+ thisIsNotASuccess match {
+ case Success(v) =>
+ done()
+ assert(v == 43)
+ case Failure(e) =>
+ done()
+ assert(false)
+ case other =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testFailureMatch(): Unit = once {
+ done =>
+ val thisIsAFailure = Failure(new Exception("I'm an exception"))
+ thisIsAFailure match {
+ case Success(v) =>
+ done()
+ assert(false)
+ case Failure(e) =>
+ done()
+ assert(e.getMessage == "I'm an exception")
+ case other =>
+ done()
+ assert(false)
+ }
+ }
+
+ def testLeftMatch(): Unit = once {
+ done =>
+ val thisIsNotAFailure: Left[Throwable, Int] = Left(new Exception("I'm an exception"))
+ thisIsNotAFailure match {
+ case Success(v) =>
+ done()
+ assert(false)
+ case Failure(e) =>
+ done()
+ assert(e.getMessage == "I'm an exception")
+ case other =>
+ done()
+ assert(false)
+ }
+
+ }
+
+ testSuccessMatch()
+ testRightMatch()
+ testFailureMatch()
+ testLeftMatch()
+}
object Test
extends App
@@ -406,8 +739,11 @@ with FutureCombinators
with FutureProjections
with Promises
with Exceptions
+with TryEitherExtractor
{
System.exit(0)
}
+
+
diff --git a/test/files/jvm/serialization-new.check b/test/files/jvm/serialization-new.check
new file mode 100644
index 0000000000..fa51c6a879
--- /dev/null
+++ b/test/files/jvm/serialization-new.check
@@ -0,0 +1,313 @@
+a1 = Array[1,2,3]
+_a1 = Array[1,2,3]
+arrayEquals(a1, _a1): true
+
+e1 = Left(1)
+_e1 = Left(1)
+e1 eq _e1: false, _e1 eq e1: false
+e1 equals _e1: true, _e1 equals e1: true
+
+x7 = RoundingMode
+y7 = RoundingMode
+x7 eq y7: true, y7 eq x7: true
+x7 equals y7: true, y7 equals x7: true
+
+x8 = WeekDay
+y8 = WeekDay
+x8 eq y8: true, y8 eq x8: true
+x8 equals y8: true, y8 equals x8: true
+
+x9 = UP
+y9 = UP
+x9 eq y9: true, y9 eq x9: true
+x9 equals y9: true, y9 equals x9: true
+
+x10 = Monday
+y10 = Monday
+x10 eq y10: true, y10 eq x10: true
+x10 equals y10: true, y10 equals x10: true
+
+x9 eq x10: false, x10 eq x9: false
+x9 equals x10: false, x10 equals x9: false
+x9 eq y10: false, y10 eq x9: false
+x9 equals y10: false, y10 equals x9: false
+
+f1 = <na>
+_f1 = <na>
+f1(2): 4, _f1(2): 4
+
+xs0 = List(1, 2, 3)
+_xs0 = List(1, 2, 3)
+xs0 eq _xs0: false, _xs0 eq xs0: false
+xs0 equals _xs0: true, _xs0 equals xs0: true
+
+xs1 = List()
+_xs1 = List()
+xs1 eq _xs1: true, _xs1 eq xs1: true
+
+o1 = None
+_o1 = None
+o1 eq _o1: true, _o1 eq o1: true
+
+o2 = Some(1)
+_o2 = Some(1)
+o2 eq _o2: false, _o2 eq o2: false
+o2 equals _o2: true, _o2 equals o2: true
+
+s1 = 'hello
+_s1 = 'hello
+s1 eq _s1: true, _s1 eq s1: true
+s1 equals _s1: true, _s1 equals s1: true
+
+t1 = (BannerLimit,12345)
+_t1 = (BannerLimit,12345)
+t1 eq _t1: false, _t1 eq t1: false
+t1 equals _t1: true, _t1 equals t1: true
+
+x = BitSet(1, 2)
+y = BitSet(1, 2)
+x equals y: true, y equals x: true
+
+x = BitSet(2, 3)
+y = BitSet(2, 3)
+x equals y: true, y equals x: true
+
+x = Map(1 -> A, 2 -> B, 3 -> C)
+y = Map(1 -> A, 2 -> B, 3 -> C)
+x equals y: true, y equals x: true
+
+x = Set(1, 2)
+y = Set(1, 2)
+x equals y: true, y equals x: true
+
+x = List((buffers,20), (layers,2), (title,3))
+y = List((buffers,20), (layers,2), (title,3))
+x equals y: true, y equals x: true
+
+x = Map(buffers -> 20, layers -> 2, title -> 3)
+y = Map(buffers -> 20, layers -> 2, title -> 3)
+x equals y: true, y equals x: true
+
+x = ListSet(5, 3)
+y = ListSet(5, 3)
+x equals y: true, y equals x: true
+
+x = Queue(a, b, c)
+y = Queue(a, b, c)
+x equals y: true, y equals x: true
+
+x = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+y = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+x equals y: true, y equals x: true
+
+x = NumericRange(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+y = NumericRange(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+x equals y: true, y equals x: true
+
+x = Map(1 -> A, 2 -> B, 3 -> C)
+y = Map(1 -> A, 2 -> B, 3 -> C)
+x equals y: true, y equals x: true
+
+x = TreeSet(1, 2, 3)
+y = TreeSet(1, 2, 3)
+x equals y: true, y equals x: true
+
+x = Stack(c, b, a)
+y = Stack(c, b, a)
+x equals y: true, y equals x: true
+
+x = Stream(0, ?)
+y = Stream(0, ?)
+x equals y: true, y equals x: true
+
+x = Map(42 -> FortyTwo)
+y = Map(42 -> FortyTwo)
+x equals y: true, y equals x: true
+
+x = TreeSet(0, 2)
+y = TreeSet(0, 2)
+x equals y: true, y equals x: true
+
+x = Vector('a, 'b, 'c)
+y = Vector('a, 'b, 'c)
+x equals y: true, y equals x: true
+
+x = ArrayBuffer(one, two)
+y = ArrayBuffer(one, two)
+x equals y: true, y equals x: true
+
+x = ArrayBuilder.ofLong
+y = ArrayBuilder.ofLong
+x equals y: true, y equals x: true
+
+x = ArrayBuilder.ofFloat
+y = ArrayBuilder.ofFloat
+x equals y: true, y equals x: true
+
+x = ArraySeq(1, 2, 3)
+y = ArraySeq(1, 2, 3)
+x equals y: true, y equals x: true
+
+x = ArrayStack(3, 2, 20)
+y = ArrayStack(3, 2, 20)
+x equals y: true, y equals x: true
+
+x = BitSet(0, 8, 9)
+y = BitSet(0, 8, 9)
+x equals y: true, y equals x: true
+
+x = Map(A -> 1, C -> 3, B -> 2)
+y = Map(A -> 1, C -> 3, B -> 2)
+x equals y: true, y equals x: true
+
+x = Set(buffers, title, layers)
+y = Set(buffers, title, layers)
+x equals y: true, y equals x: true
+
+x = History()
+y = History()
+x equals y: true, y equals x: true
+
+x = ListBuffer(white, black)
+y = ListBuffer(white, black)
+x equals y: true, y equals x: true
+
+x = Queue(20, 2, 3)
+y = Queue(20, 2, 3)
+x equals y: true, y equals x: true
+
+x = Stack(3, 2, 20)
+y = Stack(3, 2, 20)
+x equals y: true, y equals x: true
+
+x = abc
+y = abc
+x equals y: true, y equals x: true
+
+x = WrappedArray(1, 2, 3)
+y = WrappedArray(1, 2, 3)
+x equals y: true, y equals x: true
+
+x = TreeSet(1, 2, 3)
+y = TreeSet(1, 2, 3)
+x equals y: true, y equals x: true
+
+x = TrieMap(1 -> one, 2 -> two, 3 -> three)
+y = TrieMap(1 -> one, 2 -> two, 3 -> three)
+x equals y: true, y equals x: true
+
+x = xml:src="hello"
+y = xml:src="hello"
+x equals y: true, y equals x: true
+
+x = <title></title>
+y = <title></title>
+x equals y: true, y equals x: true
+
+x = <html><title>title</title><body></body></html>
+y = <html><title>title</title><body></body></html>
+x equals y: true, y equals x: true
+
+x = <html>
+ <body>
+ <table cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Last Name</th>
+ <th>First Name</th>
+ </tr>
+ <tr>
+ <td> Tom </td>
+ <td> 20 </td>
+ </tr><tr>
+ <td> Bob </td>
+ <td> 22 </td>
+ </tr><tr>
+ <td> James </td>
+ <td> 19 </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+y = <html>
+ <body>
+ <table cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Last Name</th>
+ <th>First Name</th>
+ </tr>
+ <tr>
+ <td> Tom </td>
+ <td> 20 </td>
+ </tr><tr>
+ <td> Bob </td>
+ <td> 22 </td>
+ </tr><tr>
+ <td> James </td>
+ <td> 19 </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+x equals y: true, y equals x: true
+
+x = Tim
+y = Tim
+x equals y: true, y equals x: true
+
+x = Bob
+y = Bob
+x equals y: true, y equals x: true
+
+x = John
+y = John
+x equals y: true, y equals x: true
+
+x = Bill
+y = Bill
+x equals y: true, y equals x: true
+
+x = Paul
+y = Paul
+x equals y: true, y equals x: true
+
+1
+2
+1
+2
+
+x = UnrolledBuffer(one, two)
+y = UnrolledBuffer(one, two)
+x equals y: true, y equals x: true
+
+x = ParArray(abc, def, etc)
+y = ParArray(abc, def, etc)
+x equals y: true, y equals x: true
+
+x = ParHashMap(2 -> 4, 1 -> 2)
+y = ParHashMap(2 -> 4, 1 -> 2)
+x equals y: true, y equals x: true
+
+x = ParTrieMap(1 -> 2, 2 -> 4)
+y = ParTrieMap(1 -> 2, 2 -> 4)
+x equals y: true, y equals x: true
+
+x = ParHashSet(1, 2, 3)
+y = ParHashSet(1, 2, 3)
+x equals y: true, y equals x: true
+
+x = ParRange(0, 1, 2, 3, 4)
+y = ParRange(0, 1, 2, 3, 4)
+x equals y: true, y equals x: true
+
+x = ParRange(0, 1, 2, 3)
+y = ParRange(0, 1, 2, 3)
+x equals y: true, y equals x: true
+
+x = ParMap(5 -> 1, 10 -> 2)
+y = ParMap(5 -> 1, 10 -> 2)
+x equals y: true, y equals x: true
+
+x = ParSet(two, one)
+y = ParSet(two, one)
+x equals y: true, y equals x: true
+
diff --git a/test/files/jvm/serialization-new.scala b/test/files/jvm/serialization-new.scala
new file mode 100644
index 0000000000..bb971fdf36
--- /dev/null
+++ b/test/files/jvm/serialization-new.scala
@@ -0,0 +1,651 @@
+//############################################################################
+// Serialization
+//############################################################################
+
+object Serialize {
+ @throws(classOf[java.io.IOException])
+ def write[A](o: A): Array[Byte] = {
+ val ba = new java.io.ByteArrayOutputStream(512)
+ val out = new java.io.ObjectOutputStream(ba)
+ out.writeObject(o)
+ out.close()
+ ba.toByteArray()
+ }
+ @throws(classOf[java.io.IOException])
+ @throws(classOf[ClassNotFoundException])
+ def read[A](buffer: Array[Byte]): A = {
+ val in =
+ new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer))
+ in.readObject().asInstanceOf[A]
+ }
+ def check[A, B](x: A, y: B) {
+ println("x = " + x)
+ println("y = " + y)
+ println("x equals y: " + (x equals y) + ", y equals x: " + (y equals x))
+ assert((x equals y) && (y equals x))
+ println()
+ }
+}
+import Serialize._
+
+//############################################################################
+// Test classes in package "scala"
+
+object Test1_scala {
+
+ private def arrayToString[A](arr: Array[A]): String =
+ arr.mkString("Array[",",","]")
+
+ private def arrayEquals[A, B](a1: Array[A], a2: Array[B]): Boolean =
+ (a1.length == a2.length) &&
+ (Iterator.range(0, a1.length) forall { i => a1(i) == a2(i) })
+
+ object WeekDay extends Enumeration {
+ type WeekDay = Value
+ val Monday, Tuesday, Wednesday, Thusday, Friday, Saturday, Sunday = Value
+ }
+ import WeekDay._, BigDecimal._, RoundingMode._
+
+ // in alphabetic order
+ try {
+ // Array
+ val a1 = Array(1, 2, 3)
+ val _a1: Array[Int] = read(write(a1))
+ println("a1 = " + arrayToString(a1))
+ println("_a1 = " + arrayToString(_a1))
+ println("arrayEquals(a1, _a1): " + arrayEquals(a1, _a1))
+ println()
+
+ // Either
+ val e1 = Left(1)
+ val _e1: Either[Int, String] = read(write(e1))
+ println("e1 = " + e1)
+ println("_e1 = " + _e1)
+ println("e1 eq _e1: " + (e1 eq _e1) + ", _e1 eq e1: " + (_e1 eq e1))
+ println("e1 equals _e1: " + (e1 equals _e1) + ", _e1 equals e1: " + (_e1 equals e1))
+ println()
+
+ // Enumeration
+ val x7 = BigDecimal.RoundingMode
+ val y7: RoundingMode.type = read(write(x7))
+ println("x7 = " + x7)
+ println("y7 = " + y7)
+ println("x7 eq y7: " + (x7 eq y7) + ", y7 eq x7: " + (y7 eq x7))
+ println("x7 equals y7: " + (x7 equals y7) + ", y7 equals x7: " + (y7 equals x7))
+ println()
+
+ val x8 = WeekDay
+ val y8: WeekDay.type = read(write(x8))
+ println("x8 = " + x8)
+ println("y8 = " + y8)
+ println("x8 eq y8: " + (x8 eq y8) + ", y8 eq x8: " + (y8 eq x8))
+ println("x8 equals y8: " + (x8 equals y8) + ", y8 equals x8: " + (y8 equals x8))
+ println()
+
+ val x9 = UP
+ val y9: RoundingMode = read(write(x9))
+ println("x9 = " + x9)
+ println("y9 = " + y9)
+ println("x9 eq y9: " + (x9 eq y9) + ", y9 eq x9: " + (y9 eq x9))
+ println("x9 equals y9: " + (x9 equals y9) + ", y9 equals x9: " + (y9 equals x9))
+ println()
+
+ val x10 = Monday
+ val y10: WeekDay = read(write(x10))
+ println("x10 = " + x10)
+ println("y10 = " + y10)
+ println("x10 eq y10: " + (x10 eq y10) + ", y10 eq x10: " + (y10 eq x10))
+ println("x10 equals y10: " + (x10 equals y10) + ", y10 equals x10: " + (y10 equals x10))
+ println()
+
+ println("x9 eq x10: " + (x9 eq x10) + ", x10 eq x9: " + (x10 eq x9))
+ println("x9 equals x10: " + (x9 equals x10) + ", x10 equals x9: " + (x10 equals x9))
+ println("x9 eq y10: " + (x9 eq y10) + ", y10 eq x9: " + (y10 eq x9))
+ println("x9 equals y10: " + (x9 equals y10) + ", y10 equals x9: " + (y10 equals x9))
+ println()
+
+ // Function
+ val f1 = { x: Int => 2 * x }
+ val _f1: Function[Int, Int] = read(write(f1))
+ println("f1 = <na>")
+ println("_f1 = <na>")
+ println("f1(2): " + f1(2) + ", _f1(2): " + _f1(2))
+ println()
+
+ // List
+ val xs0 = List(1, 2, 3)
+ val _xs0: List[Int] = read(write(xs0))
+ println("xs0 = " + xs0)
+ println("_xs0 = " + _xs0)
+ println("xs0 eq _xs0: " + (xs0 eq _xs0) + ", _xs0 eq xs0: " + (_xs0 eq xs0))
+ println("xs0 equals _xs0: " + (xs0 equals _xs0) + ", _xs0 equals xs0: " + (_xs0 equals xs0))
+ println()
+
+ val xs1 = Nil
+ val _xs1: List[Nothing] = read(write(xs1))
+ println("xs1 = " + xs1)
+ println("_xs1 = " + _xs1)
+ println("xs1 eq _xs1: " + (xs1 eq _xs1) + ", _xs1 eq xs1: " + (_xs1 eq xs1))
+ println()
+
+ // Option
+ val o1 = None
+ val _o1: Option[Nothing] = read(write(o1))
+ println("o1 = " + o1)
+ println("_o1 = " + _o1)
+ println("o1 eq _o1: " + (o1 eq _o1) + ", _o1 eq o1: " + (_o1 eq o1))
+ println()
+
+ val o2 = Some(1)
+ val _o2: Option[Int] = read(write(o2))
+ println("o2 = " + o2)
+ println("_o2 = " + _o2)
+ println("o2 eq _o2: " + (o2 eq _o2) + ", _o2 eq o2: " + (_o2 eq o2))
+ println("o2 equals _o2: " + (o2 equals _o2) + ", _o2 equals o2: " + (_o2 equals o2))
+ println()
+/*
+ // Responder
+ val r1 = Responder.constant("xyz")
+ val _r1: Responder[String] = read(write(r1))
+ check(r1, _r1)
+*/
+ // Symbol
+ val s1 = 'hello
+ val _s1: Symbol = read(write(s1))
+ println("s1 = " + s1)
+ println("_s1 = " + _s1)
+ println("s1 eq _s1: " + (s1 eq _s1) + ", _s1 eq s1: " + (_s1 eq s1))
+ println("s1 equals _s1: " + (s1 equals _s1) + ", _s1 equals s1: " + (_s1 equals s1))
+ println()
+
+ // Tuple
+ val t1 = ("BannerLimit", 12345)
+ val _t1: (String, Int) = read(write(t1))
+ println("t1 = " + t1)
+ println("_t1 = " + _t1)
+ println("t1 eq _t1: " + (t1 eq _t1) + ", _t1 eq t1: " + (_t1 eq t1))
+ println("t1 equals _t1: " + (t1 equals _t1) + ", _t1 equals t1: " + (_t1 equals t1))
+ println()
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test1_scala: " + e)
+ throw e
+ }
+}
+
+//############################################################################
+// Test classes in package "scala.collection.immutable"
+
+object Test2_immutable {
+ import scala.collection.immutable.{
+ BitSet, HashMap, HashSet, ListMap, ListSet, Queue, Range, SortedMap,
+ SortedSet, Stack, Stream, TreeMap, TreeSet, Vector}
+
+ // in alphabetic order
+ try {
+ // BitSet
+ val bs1 = BitSet.empty + 1 + 2
+ val _bs1: BitSet = read(write(bs1))
+ check(bs1, _bs1)
+
+ val bs2 = {
+ val bs = new collection.mutable.BitSet()
+ bs += 2; bs += 3
+ bs.toImmutable
+ }
+ val _bs2: BitSet = read(write(bs2))
+ check(bs2, _bs2)
+
+ // HashMap
+ val hm1 = new HashMap[Int, String] + (1 -> "A", 2 -> "B", 3 -> "C")
+ val _hm1: HashMap[Int, String] = read(write(hm1))
+ check(hm1, _hm1)
+
+ // HashSet
+ val hs1 = new HashSet[Int] + 1 + 2
+ val _hs1: HashSet[Int] = read(write(hs1))
+ check(hs1, _hs1)
+
+ // List
+ val xs1 = List(("buffers", 20), ("layers", 2), ("title", 3))
+ val _xs1: List[(String, Int)] = read(write(xs1))
+ check(xs1, _xs1)
+
+ // ListMap
+ val lm1 = new ListMap[String, Int] + ("buffers" -> 20, "layers" -> 2, "title" -> 3)
+ val _lm1: ListMap[String, Int] = read(write(lm1))
+ check(lm1, _lm1)
+
+ // ListSet
+ val ls1 = new ListSet[Int] + 3 + 5
+ val _ls1: ListSet[Int] = read(write(ls1))
+ check(ls1, _ls1)
+
+ // Queue
+ val q1 = Queue("a", "b", "c")
+ val _q1: Queue[String] = read(write(q1))
+ check(q1, _q1)
+
+ // Range
+ val r1 = 0 until 10
+ val _r1: Range = read(write(r1))
+ check(r1, _r1)
+
+ val r2 = Range.Long(0L, 10L, 1)
+ val _r2: r2.type = read(write(r2))
+ check(r2, _r2)
+
+ // SortedMap
+ val sm1 = SortedMap.empty[Int, String] + (2 -> "B", 3 -> "C", 1 -> "A")
+ val _sm1: SortedMap[Int, String] = read(write(sm1))
+ check(sm1, _sm1)
+
+ // SortedSet
+ val ss1 = SortedSet.empty[Int] + 2 + 3 + 1
+ val _ss1: SortedSet[Int] = read(write(ss1))
+ check(ss1, _ss1)
+
+ // Stack
+ val s1 = new Stack().push("a", "b", "c")
+ val _s1: Stack[String] = read(write(s1))
+ check(s1, _s1)
+
+ // Stream
+ val st1 = Stream.range(0, 10)
+ val _st1: Stream[Int] = read(write(st1))
+ check(st1, _st1)
+
+ // TreeMap
+ val tm1 = new TreeMap[Int, String] + (42 -> "FortyTwo")
+ val _tm1: TreeMap[Int, String] = read(write(tm1))
+ check(tm1, _tm1)
+
+ // TreeSet
+ val ts1 = new TreeSet[Int]() + 2 + 0
+ val _ts1: TreeSet[Int] = read(write(ts1))
+ check(ts1, _ts1)
+
+ // Vector
+ val v1 = Vector('a, 'b, 'c)
+ val _v1: Vector[Symbol] = read(write(v1))
+ check(v1, _v1)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test2_immutable: " + e)
+ throw e
+ }
+}
+
+//############################################################################
+// Test classes in package "scala.collection.mutable"
+
+object Test3_mutable {
+ import scala.reflect.ArrayTag
+ import scala.collection.mutable.{
+ ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList,
+ HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue,
+ Stack, StringBuilder, WrappedArray, TreeSet}
+ import scala.collection.concurrent.TrieMap
+
+ // in alphabetic order
+ try {
+ // ArrayBuffer
+ val ab1 = new ArrayBuffer[String]
+ ab1 ++= List("one", "two")
+ val _ab1: ArrayBuffer[String] = read(write(ab1))
+ check(ab1, _ab1)
+
+ // ArrayBuilder
+ val abu1 = ArrayBuilder.make[Long]
+ val _abu1: ArrayBuilder[ArrayTag[Long]] = read(write(abu1))
+ check(abu1, _abu1)
+
+ val abu2 = ArrayBuilder.make[Float]
+ val _abu2: ArrayBuilder[ArrayTag[Float]] = read(write(abu2))
+ check(abu2, _abu2)
+
+ // ArraySeq
+ val aq1 = ArraySeq(1, 2, 3)
+ val _aq1: ArraySeq[Int] = read(write(aq1))
+ check(aq1, _aq1)
+
+ // ArrayStack
+ val as1 = new ArrayStack[Int]
+ as1 ++= List(20, 2, 3).iterator
+ val _as1: ArrayStack[Int] = read(write(as1))
+ check(as1, _as1)
+
+ // BitSet
+ val bs1 = new BitSet()
+ bs1 += 0
+ bs1 += 8
+ bs1 += 9
+ val _bs1: BitSet = read(write(bs1))
+ check(bs1, _bs1)
+/*
+ // DoubleLinkedList
+ val dl1 = new DoubleLinkedList[Int](2, null)
+ dl1.append(new DoubleLinkedList(3, null))
+ val _dl1: DoubleLinkedList[Int] = read(write(dl1))
+ check(dl1, _dl1)
+*/
+ // HashMap
+ val hm1 = new HashMap[String, Int]
+ hm1 ++= List(("A", 1), ("B", 2), ("C", 3)).iterator
+ val _hm1: HashMap[String, Int] = read(write(hm1))
+ check(hm1, _hm1)
+
+ // HashSet
+ val hs1 = new HashSet[String]
+ hs1 ++= List("layers", "buffers", "title").iterator
+ val _hs1: HashSet[String] = read(write(hs1))
+ check(hs1, _hs1)
+
+ val h1 = new History[String, Int]
+ val _h1: History[String, Int] = read(write(h1))
+ check(h1, _h1)
+/*
+ // LinkedList
+ val ll1 = new LinkedList[Int](2, null)
+ ll1.append(new LinkedList(3, null))
+ val _ll1: LinkedList[Int] = read(write(ll1))
+ check(ll1, _ll1)
+*/
+ // ListBuffer
+ val lb1 = new ListBuffer[String]
+ lb1 ++= List("white", "black")
+ val _lb1: ListBuffer[String] = read(write(lb1))
+ check(lb1, _lb1)
+
+ // Queue
+ val q1 = new Queue[Int]
+ q1 ++= List(20, 2, 3).iterator
+ val _q1: Queue[Int] = read(write(q1))
+ check(q1, _q1)
+
+ // Stack
+ val s1 = new Stack[Int]
+ s1 pushAll q1
+ val _s1: Stack[Int] = read(write(s1))
+ check(s1, _s1)
+
+ // StringBuilder
+ val sb1 = new StringBuilder
+ sb1 append "abc"
+ val _sb1: StringBuilder = read(write(sb1))
+ check(sb1, _sb1)
+
+ // WrappedArray
+ val wa1 = WrappedArray.make(Array(1, 2, 3))
+ val _wa1: WrappedArray[Int] = read(write(wa1))
+ check(wa1, _wa1)
+
+ // TreeSet
+ val ts1 = TreeSet[Int]() ++= Array(1, 2, 3)
+ val _ts1: TreeSet[Int] = read(write(ts1))
+ check(ts1, _ts1)
+
+ // concurrent.TrieMap
+ val ct1 = TrieMap[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three")
+ val _ct1: TrieMap[Int, String] = read(write(ct1))
+ check(ct1, _ct1)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test3_mutable: " + e)
+ throw e
+ }
+}
+
+
+//############################################################################
+// Test classes in package "scala.xml"
+
+object Test4_xml {
+ import scala.xml.{Attribute, Document, Elem, Null, PrefixedAttribute, Text}
+
+ case class Person(name: String, age: Int)
+
+ try {
+ // Attribute
+ val a1 = new PrefixedAttribute("xml", "src", Text("hello"), Null)
+ val _a1: Attribute = read(write(a1))
+ check(a1, _a1)
+
+ // Document
+ val d1 = new Document
+ d1.docElem = <title></title>
+ d1.encoding = Some("UTF-8")
+ val _d1: Document = read(write(d1))
+ check(d1, _d1)
+
+ // Elem
+ val e1 = <html><title>title</title><body></body></html>;
+ val _e1: Elem = read(write(e1))
+ check(e1, _e1)
+
+ class AddressBook(a: Person*) {
+ private val people: List[Person] = a.toList
+ def toXHTML =
+ <table cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Last Name</th>
+ <th>First Name</th>
+ </tr>
+ { for (p <- people) yield
+ <tr>
+ <td> { p.name } </td>
+ <td> { p.age.toString() } </td>
+ </tr> }
+ </table>;
+ }
+
+ val people = new AddressBook(
+ Person("Tom", 20),
+ Person("Bob", 22),
+ Person("James", 19))
+
+ val e2 =
+ <html>
+ <body>
+ { people.toXHTML }
+ </body>
+ </html>;
+ val _e2: Elem = read(write(e2))
+ check(e2, _e2)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test4_xml: " + e)
+ throw e
+ }
+}
+
+//############################################################################
+// Test user-defined classes WITHOUT nesting
+
+class Person(_name: String) extends Serializable {
+ private var name = _name
+ override def toString() = name
+ override def equals(that: Any): Boolean =
+ that.isInstanceOf[Person] &&
+ (name == that.asInstanceOf[Person].name)
+}
+
+class Employee(_name: String) extends Serializable {
+ private var name = _name
+ override def toString() = name
+}
+
+object bob extends Employee("Bob")
+
+object Test5 {
+ val x1 = new Person("Tim")
+ val x2 = bob
+
+ try {
+ val y1: Person = read(write(x1))
+ val y2: Employee = read(write(x2))
+
+ check(x1, y1)
+ check(x2, y2)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test5: " + e)
+ }
+}
+
+//############################################################################
+// Test user-defined classes WITH nesting
+
+object Test6 {
+ object bill extends Employee("Bill") {
+ val x = paul
+ }
+ object paul extends Person("Paul") {
+ val x = 4 // bill; => StackOverflowException !!!
+ }
+ val x1 = new Person("John")
+ val x2 = bill
+ val x3 = paul
+
+ try {
+ val y1: Person = read(write(x1))
+ val y2: Employee = read(write(x2))
+ val y3: Person = read(write(x3))
+
+ check(x1, y1)
+ check(x2, y2)
+ check(x3, y3)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test6: " + e)
+ }
+}
+
+//############################################################################
+// Nested objects cannot get readresolve automatically because after deserialization
+// they would be null (they are treated as lazy vals)
+class Outer extends Serializable {
+ object Inner extends Serializable
+}
+
+object Test7 {
+ val x = new Outer
+ x.Inner // initialize
+ val y:Outer = read(write(x))
+ if (y.Inner == null)
+ println("Inner object is null")
+}
+
+// Verify that transient lazy vals don't get serialized
+class WithTransient extends Serializable {
+ @transient lazy val a1 = 1
+ @transient private lazy val a2 = 2
+ @transient object B extends Serializable
+ @transient private object C extends Serializable
+
+ def test = {
+ println(a1)
+ println(a2)
+ if (B == null || C == null)
+ println("Transient nested object failed to serialize properly")
+ }
+}
+
+object Test8 {
+ val x = new WithTransient
+ x.test
+ try {
+ val y:WithTransient = read(write(x))
+ y.test
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test8: " + e)
+ }
+}
+
+//############################################################################
+// Test code
+
+object Test {
+ def main(args: Array[String]) {
+ Test1_scala
+ Test2_immutable
+ Test3_mutable
+ Test4_xml
+ Test5
+ Test6
+ Test7
+ Test8
+ Test9_parallel
+ }
+}
+
+//############################################################################
+
+
+//############################################################################
+// Test classes in package "scala.collection.parallel" and subpackages
+object Test9_parallel {
+ import scala.collection.parallel._
+
+ try {
+ println()
+
+ // UnrolledBuffer
+ val ub = new collection.mutable.UnrolledBuffer[String]
+ ub ++= List("one", "two")
+ val _ub: collection.mutable.UnrolledBuffer[String] = read(write(ub))
+ check(ub, _ub)
+
+ // mutable.ParArray
+ val pa = mutable.ParArray("abc", "def", "etc")
+ val _pa: mutable.ParArray[String] = read(write(pa))
+ check(pa, _pa)
+
+ // mutable.ParHashMap
+ val mpm = mutable.ParHashMap(1 -> 2, 2 -> 4)
+ val _mpm: mutable.ParHashMap[Int, Int] = read(write(mpm))
+ check(mpm, _mpm)
+
+ // mutable.ParTrieMap
+ val mpc = mutable.ParTrieMap(1 -> 2, 2 -> 4)
+ val _mpc: mutable.ParTrieMap[Int, Int] = read(write(mpc))
+ check(mpc, _mpc)
+
+ // mutable.ParHashSet
+ val mps = mutable.ParHashSet(1, 2, 3)
+ val _mps: mutable.ParHashSet[Int] = read(write(mps))
+ check(mps, _mps)
+
+ // immutable.ParRange
+ val pr1 = immutable.ParRange(0, 4, 1, true)
+ val _pr1: immutable.ParRange = read(write(pr1))
+ check(pr1, _pr1)
+
+ val pr2 = immutable.ParRange(0, 4, 1, false)
+ val _pr2: immutable.ParRange = read(write(pr2))
+ check(pr2, _pr2)
+
+ // immutable.ParHashMap
+ val ipm = immutable.ParHashMap(5 -> 1, 10 -> 2)
+ val _ipm: immutable.ParHashMap[Int, Int] = read(write(ipm))
+ check(ipm, _ipm)
+
+ // immutable.ParHashSet
+ val ips = immutable.ParHashSet("one", "two")
+ val _ips: immutable.ParHashSet[String] = read(write(ips))
+ check(ips, _ips)
+
+ } catch {
+ case e: Exception =>
+ println("Error in Test5_parallel: " + e)
+ throw e
+ }
+}
diff --git a/test/files/jvm/serialization.check b/test/files/jvm/serialization.check
index 0b8055a6b9..fa51c6a879 100644
--- a/test/files/jvm/serialization.check
+++ b/test/files/jvm/serialization.check
@@ -192,8 +192,8 @@ x = TreeSet(1, 2, 3)
y = TreeSet(1, 2, 3)
x equals y: true, y equals x: true
-x = ConcurrentTrieMap(1 -> one, 2 -> two, 3 -> three)
-y = ConcurrentTrieMap(1 -> one, 2 -> two, 3 -> three)
+x = TrieMap(1 -> one, 2 -> two, 3 -> three)
+y = TrieMap(1 -> one, 2 -> two, 3 -> three)
x equals y: true, y equals x: true
x = xml:src="hello"
@@ -287,8 +287,8 @@ x = ParHashMap(2 -> 4, 1 -> 2)
y = ParHashMap(2 -> 4, 1 -> 2)
x equals y: true, y equals x: true
-x = ParConcurrentTrieMap(1 -> 2, 2 -> 4)
-y = ParConcurrentTrieMap(1 -> 2, 2 -> 4)
+x = ParTrieMap(1 -> 2, 2 -> 4)
+y = ParTrieMap(1 -> 2, 2 -> 4)
x equals y: true, y equals x: true
x = ParHashSet(1, 2, 3)
diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala
index 1e89036f37..9c2f2acdbf 100644
--- a/test/files/jvm/serialization.scala
+++ b/test/files/jvm/serialization.scala
@@ -286,7 +286,8 @@ object Test3_mutable {
import scala.collection.mutable.{
ArrayBuffer, ArrayBuilder, ArraySeq, ArrayStack, BitSet, DoubleLinkedList,
HashMap, HashSet, History, LinkedList, ListBuffer, Publisher, Queue,
- Stack, StringBuilder, WrappedArray, TreeSet, ConcurrentTrieMap}
+ Stack, StringBuilder, WrappedArray, TreeSet}
+ import scala.collection.concurrent.TrieMap
// in alphabetic order
try {
@@ -386,9 +387,9 @@ object Test3_mutable {
val _ts1: TreeSet[Int] = read(write(ts1))
check(ts1, _ts1)
- // ConcurrentTrieMap
- val ct1 = ConcurrentTrieMap[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three")
- val _ct1: ConcurrentTrieMap[Int, String] = read(write(ct1))
+ // concurrent.TrieMap
+ val ct1 = TrieMap[Int, String]() ++= Array(1 -> "one", 2 -> "two", 3 -> "three")
+ val _ct1: TrieMap[Int, String] = read(write(ct1))
check(ct1, _ct1)
}
catch {
@@ -613,9 +614,9 @@ object Test9_parallel {
val _mpm: mutable.ParHashMap[Int, Int] = read(write(mpm))
check(mpm, _mpm)
- // mutable.ParConcurrentTrieMap
- val mpc = mutable.ParConcurrentTrieMap(1 -> 2, 2 -> 4)
- val _mpc: mutable.ParConcurrentTrieMap[Int, Int] = read(write(mpc))
+ // mutable.ParTrieMap
+ val mpc = mutable.ParTrieMap(1 -> 2, 2 -> 4)
+ val _mpc: mutable.ParTrieMap[Int, Int] = read(write(mpc))
check(mpc, _mpc)
// mutable.ParHashSet
diff --git a/test/files/jvm/si5471.check b/test/files/jvm/si5471.check
new file mode 100644
index 0000000000..bb101b641b
--- /dev/null
+++ b/test/files/jvm/si5471.check
@@ -0,0 +1,2 @@
+true
+true
diff --git a/test/files/jvm/si5471.scala b/test/files/jvm/si5471.scala
new file mode 100644
index 0000000000..2c8c4205c5
--- /dev/null
+++ b/test/files/jvm/si5471.scala
@@ -0,0 +1,17 @@
+
+object Test {
+
+ def main(args: Array[String]) {
+ import scala.math.Numeric
+ import scala.math.Numeric.Implicits._
+
+ val b = BigInt(Long.MaxValue) + 1
+
+ def dbl[N :Numeric](n: N) = n.toDouble
+ def flt[N :Numeric](n: N) = n.toFloat
+
+ println(dbl(b) == b.toDouble)
+ println(flt(b) == b.toFloat)
+ }
+
+}
diff --git a/test/files/macros/Printf.scala b/test/files/macros/Printf.scala
deleted file mode 100644
index 4a88e5b069..0000000000
--- a/test/files/macros/Printf.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-// macros should be built separately from their clients, so simple "scalac Printf.scala Test.scala" won't work
-// 1) first build this file with "scalac -Xmacros Printf.scala"
-// 2) the build the test with "scalac -cp <output directory of compiling Printf.scala> Test.scala"
-
-object Printf extends App {
- def macro printf(format: String, params: Any*) : String = {
- var i = 0
- def gensym(name: String) = { i += 1; newTermName(name + i) }
-
- def createTempValDef(value: Tree, clazz: Class[_]): (Option[Tree], Tree) = {
- val local = gensym("temp")
- val tpe = if (clazz == classOf[Int]) Ident(newTypeName("Int"))
- else if (clazz == classOf[String]) Select(Select(Ident(newTermName("java")), newTermName("lang")), newTypeName("String"))
- else throw new Exception("unknown class " + clazz.toString)
- (Some(ValDef(Modifiers(), local, tpe, value)), Ident(local))
- }
-
- def tree_printf(format: Tree, params: Tree*) = {
- val Literal(Constant(s_format: String)) = format
- val paramsStack = scala.collection.mutable.Stack(params: _*)
- val parsed = s_format.split("(?<=%[\\w%])|(?=%[\\w%])") map {
- case "%d" => createTempValDef(paramsStack.pop, classOf[Int])
- case "%s" => createTempValDef(paramsStack.pop, classOf[String])
- case "%%" => (None, Literal(Constant("%")))
- case part => (None, Literal(Constant(part)))
- }
-
- val evals = for ((Some(eval), _) <- parsed if eval != None) yield eval
- val prints = for ((_, ref) <- parsed) yield {
- val print = Select(Select(Ident(newTermName("scala")), newTermName("Predef")), newTermName("print"))
- Apply(print, List(ref))
- }
-
- Block((evals ++ prints).toList, Literal(Constant(())))
- }
-
- tree_printf(format, params: _*)
- }
-}
diff --git a/test/files/macros/Test.scala b/test/files/macros/Test.scala
deleted file mode 100644
index d8cdcf6756..0000000000
--- a/test/files/macros/Test.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-// macros should be built separately from their clients, so simple "scalac Printf.scala Test.scala" won't work
-// 1) first build the printf macro with "scalac -Xmacros Printf.scala"
-// 2) the build this file with "scalac -cp <output directory of compiling Printf.scala> Test.scala"
-
-object Test extends App {
- import Printf._
- printf("hello %s", "world")
-} \ No newline at end of file
diff --git a/test/files/macros/macros_v0001.bat b/test/files/macros/macros_v0001.bat
deleted file mode 100644
index 3395d2e3c1..0000000000
--- a/test/files/macros/macros_v0001.bat
+++ /dev/null
@@ -1,40 +0,0 @@
-@echo off
-
-set scalahome=%~dp0\..\..\..
-set scaladeps=%scalahome%\lib\jline.jar;%scalahome%\lib\fjbg.jar
-set scalalib=%scalahome%\build\pack\lib\scala-library.jar
-if not exist "%scalalib%" set scalalib=%scalahome%\build\locker\classes\library
-set scalacomp="%scalahome%\build\pack\lib\scala-compiler.jar"
-if not exist "%scalacomp%" set scalacomp=%scalahome%\build\locker\classes\compiler
-set stdcp=%scaladeps%;%scalalib%;%scalacomp%
-
-echo Compiling macros...
-set cp=%stdcp%
-call :scalac -Xmacros "%~dp0\Printf.scala"
-
-echo Compiling the program...
-set cp=%stdcp%;%~dp0.
-call :scalac "%~dp0\Test.scala"
-
-echo.
-echo NOW LOOK!!!
-echo ===============================================
-set cp=%stdcp%;%~dp0.
-call :scala Test
-echo.
-echo ===============================================
-goto :eof
-
-:scalac
-setlocal
-call set args=%*
-rem echo java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.Main %args%
-java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.Main %args%
-endlocal&goto :eof
-
-:scala
-setlocal
-call set args=%*
-rem echo java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner %args%
-java -cp "%cp%" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner %args%
-endlocal&goto :eof
diff --git a/test/files/macros/macros_v0001.sh b/test/files/macros/macros_v0001.sh
deleted file mode 100644
index abe09836bb..0000000000
--- a/test/files/macros/macros_v0001.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-set -o errexit
-
-if [[ $(uname -s) == CYGWIN* ]]; then cpsep=";"; else cpsep=":"; fi
-scripthome="$(dirname "$0")"
-scalahome="$scripthome/../../.."
-scaladeps="$scalahome/lib/jline.jar;$scalahome/lib/fjbg.jar"
-scalalib="$scalahome/build/pack/lib/scala-library.jar"
-if [ ! -f "$scalalib" ]; then scalalib="$scalahome/build/locker/classes/library"; fi
-scalacomp="$scalahome/build/pack/lib/scala-compiler.jar"
-if [ ! -f "$scalacomp" ]; then scalacomp="$scalahome/build/locker/classes/compiler"; fi
-stdcp="$scaladeps$cpsep$scalalib$cpsep$scalacomp"
-function scalac { java -cp "$cp" -Dscala.usejavacp=true scala.tools.nsc.Main $*; }
-function scala { java -cp "$cp" -Dscala.usejavacp=true scala.tools.nsc.MainGenericRunner $*; }
-
-echo "Compiling macros..."
-cp="$stdcp"
-scalac -Xmacros "$scripthome/Printf.scala"
-
-echo "Compiling the program..."
-cp="$stdcp$cpsep$scripthome"
-scalac "$scripthome/Test.scala"
-
-echo ""
-echo "NOW LOOK"
-echo "==============================================="
-cp="$stdcp$cpsep$scripthome"
-scala Test
-echo ""
-echo "==============================================="
diff --git a/test/files/neg/applydynamic_sip.check b/test/files/neg/applydynamic_sip.check
new file mode 100644
index 0000000000..8845f68a52
--- /dev/null
+++ b/test/files/neg/applydynamic_sip.check
@@ -0,0 +1,10 @@
+applydynamic_sip.scala:7: error: applyDynamic does not support passing a vararg parameter
+ qual.sel(a, a2: _*)
+ ^
+applydynamic_sip.scala:8: error: applyDynamicNamed does not support passing a vararg parameter
+ qual.sel(arg = a, a2: _*)
+ ^
+applydynamic_sip.scala:9: error: applyDynamicNamed does not support passing a vararg parameter
+ qual.sel(arg, arg2 = "a2", a2: _*)
+ ^
+three errors found
diff --git a/test/files/neg/applydynamic_sip.scala b/test/files/neg/applydynamic_sip.scala
new file mode 100644
index 0000000000..362461577b
--- /dev/null
+++ b/test/files/neg/applydynamic_sip.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ val qual: Dynamic = ???
+ val expr = "expr"
+ val a = "a"
+ val a2 = "a2"
+
+ qual.sel(a, a2: _*)
+ qual.sel(arg = a, a2: _*)
+ qual.sel(arg, arg2 = "a2", a2: _*)
+} \ No newline at end of file
diff --git a/test/files/neg/array-not-seq.check b/test/files/neg/array-not-seq.check
index c16ecdad72..a3a639e772 100644
--- a/test/files/neg/array-not-seq.check
+++ b/test/files/neg/array-not-seq.check
@@ -1,7 +1,13 @@
array-not-seq.scala:2: error: An Array will no longer match as Seq[_].
def f1(x: Any) = x.isInstanceOf[Seq[_]]
^
-error: An Array will no longer match as Seq[_].
-error: An Array will no longer match as Seq[_].
-error: An Array will no longer match as Seq[_].
+array-not-seq.scala:4: error: An Array will no longer match as Seq[_].
+ case _: Seq[_] => true
+ ^
+array-not-seq.scala:16: error: An Array will no longer match as Seq[_].
+ case (Some(_: Seq[_]), Nil, _) => 1
+ ^
+array-not-seq.scala:17: error: An Array will no longer match as Seq[_].
+ case (None, List(_: List[_], _), _) => 2
+ ^
four errors found
diff --git a/test/files/neg/checksensible.check b/test/files/neg/checksensible.check
index d785179a56..23af94180a 100644
--- a/test/files/neg/checksensible.check
+++ b/test/files/neg/checksensible.check
@@ -1,100 +1,100 @@
-checksensible.scala:13: error: comparing a fresh object using `eq' will always yield false
- (new AnyRef) eq (new AnyRef)
- ^
-checksensible.scala:14: error: comparing a fresh object using `ne' will always yield true
- (new AnyRef) ne (new AnyRef)
- ^
-checksensible.scala:15: error: comparing a fresh object using `eq' will always yield false
- Shmoopie eq (new AnyRef)
- ^
-checksensible.scala:16: error: comparing a fresh object using `eq' will always yield false
- (Shmoopie: AnyRef) eq (new AnyRef)
- ^
-checksensible.scala:17: error: comparing a fresh object using `eq' will always yield false
- (new AnyRef) eq Shmoopie
- ^
-checksensible.scala:18: error: comparing a fresh object using `eq' will always yield false
- (new AnyRef) eq null
- ^
-checksensible.scala:19: error: comparing a fresh object using `eq' will always yield false
- null eq new AnyRef
- ^
-checksensible.scala:26: error: comparing values of types Unit and Int using `==' will always yield false
- (c = 1) == 0
- ^
-checksensible.scala:27: error: comparing values of types Int and Unit using `==' will always yield false
- 0 == (c = 1)
- ^
-checksensible.scala:29: error: comparing values of types Int and String using `==' will always yield false
- 1 == "abc"
- ^
-checksensible.scala:33: error: comparing values of types Some[Int] and Int using `==' will always yield false
- Some(1) == 1 // as above
- ^
-checksensible.scala:38: error: comparing a fresh object using `==' will always yield false
- new AnyRef == 1
- ^
-checksensible.scala:41: error: comparing values of types Int and Boolean using `==' will always yield false
- 1 == (new java.lang.Boolean(true))
- ^
-checksensible.scala:43: error: comparing values of types Int and Boolean using `!=' will always yield true
- 1 != true
- ^
-checksensible.scala:44: error: comparing values of types Unit and Boolean using `==' will always yield false
- () == true
- ^
-checksensible.scala:45: error: comparing values of types Unit and Unit using `==' will always yield true
- () == ()
- ^
-checksensible.scala:46: error: comparing values of types Unit and Unit using `==' will always yield true
- () == println
- ^
-checksensible.scala:47: error: comparing values of types Unit and scala.runtime.BoxedUnit using `==' will always yield true
- () == scala.runtime.BoxedUnit.UNIT // these should warn for always being true/false
- ^
-checksensible.scala:48: error: comparing values of types scala.runtime.BoxedUnit and Unit using `!=' will always yield false
- scala.runtime.BoxedUnit.UNIT != ()
- ^
-checksensible.scala:51: error: comparing values of types Int and Unit using `!=' will always yield true
- (1 != println)
- ^
-checksensible.scala:52: error: comparing values of types Int and Symbol using `!=' will always yield true
- (1 != 'sym)
- ^
-checksensible.scala:58: error: comparing a fresh object using `==' will always yield false
- ((x: Int) => x + 1) == null
- ^
-checksensible.scala:59: error: comparing a fresh object using `==' will always yield false
- Bep == ((_: Int) + 1)
- ^
-checksensible.scala:61: error: comparing a fresh object using `==' will always yield false
- new Object == new Object
- ^
-checksensible.scala:62: error: comparing a fresh object using `==' will always yield false
- new Object == "abc"
- ^
-checksensible.scala:63: error: comparing a fresh object using `!=' will always yield true
- new Exception() != new Exception()
- ^
-checksensible.scala:66: error: comparing values of types Int and Null using `==' will always yield false
- if (foo.length == null) "plante" else "plante pas"
- ^
-checksensible.scala:71: error: comparing values of types Bip and Bop using `==' will always yield false
- (x1 == x2)
- ^
-checksensible.scala:81: error: comparing values of types EqEqRefTest.this.C3 and EqEqRefTest.this.Z1 using `==' will always yield false
- c3 == z1
- ^
-checksensible.scala:82: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `==' will always yield false
- z1 == c3
- ^
-checksensible.scala:83: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `!=' will always yield true
- z1 != c3
- ^
-checksensible.scala:84: error: comparing values of types EqEqRefTest.this.C3 and String using `!=' will always yield true
- c3 != "abc"
- ^
-checksensible.scala:95: error: comparing values of types Unit and Int using `!=' will always yield true
- while ((c = in.read) != -1)
- ^
-33 errors found
+checksensible.scala:13: error: comparing a fresh object using `eq' will always yield false
+ (new AnyRef) eq (new AnyRef)
+ ^
+checksensible.scala:14: error: comparing a fresh object using `ne' will always yield true
+ (new AnyRef) ne (new AnyRef)
+ ^
+checksensible.scala:15: error: comparing a fresh object using `eq' will always yield false
+ Shmoopie eq (new AnyRef)
+ ^
+checksensible.scala:16: error: comparing a fresh object using `eq' will always yield false
+ (Shmoopie: AnyRef) eq (new AnyRef)
+ ^
+checksensible.scala:17: error: comparing a fresh object using `eq' will always yield false
+ (new AnyRef) eq Shmoopie
+ ^
+checksensible.scala:18: error: comparing a fresh object using `eq' will always yield false
+ (new AnyRef) eq null
+ ^
+checksensible.scala:19: error: comparing a fresh object using `eq' will always yield false
+ null eq new AnyRef
+ ^
+checksensible.scala:26: error: comparing values of types Unit and Int using `==' will always yield false
+ (c = 1) == 0
+ ^
+checksensible.scala:27: error: comparing values of types Int and Unit using `==' will always yield false
+ 0 == (c = 1)
+ ^
+checksensible.scala:29: error: comparing values of types Int and String using `==' will always yield false
+ 1 == "abc"
+ ^
+checksensible.scala:33: error: comparing values of types Some[Int] and Int using `==' will always yield false
+ Some(1) == 1 // as above
+ ^
+checksensible.scala:38: error: comparing a fresh object using `==' will always yield false
+ new AnyRef == 1
+ ^
+checksensible.scala:41: error: comparing values of types Int and Boolean using `==' will always yield false
+ 1 == (new java.lang.Boolean(true))
+ ^
+checksensible.scala:43: error: comparing values of types Int and Boolean using `!=' will always yield true
+ 1 != true
+ ^
+checksensible.scala:44: error: comparing values of types Unit and Boolean using `==' will always yield false
+ () == true
+ ^
+checksensible.scala:45: error: comparing values of types Unit and Unit using `==' will always yield true
+ () == ()
+ ^
+checksensible.scala:46: error: comparing values of types Unit and Unit using `==' will always yield true
+ () == println
+ ^
+checksensible.scala:47: error: comparing values of types Unit and scala.runtime.BoxedUnit using `==' will always yield true
+ () == scala.runtime.BoxedUnit.UNIT // these should warn for always being true/false
+ ^
+checksensible.scala:48: error: comparing values of types scala.runtime.BoxedUnit and Unit using `!=' will always yield false
+ scala.runtime.BoxedUnit.UNIT != ()
+ ^
+checksensible.scala:51: error: comparing values of types Int and Unit using `!=' will always yield true
+ (1 != println)
+ ^
+checksensible.scala:52: error: comparing values of types Int and Symbol using `!=' will always yield true
+ (1 != 'sym)
+ ^
+checksensible.scala:58: error: comparing a fresh object using `==' will always yield false
+ ((x: Int) => x + 1) == null
+ ^
+checksensible.scala:59: error: comparing a fresh object using `==' will always yield false
+ Bep == ((_: Int) + 1)
+ ^
+checksensible.scala:61: error: comparing a fresh object using `==' will always yield false
+ new Object == new Object
+ ^
+checksensible.scala:62: error: comparing a fresh object using `==' will always yield false
+ new Object == "abc"
+ ^
+checksensible.scala:63: error: comparing a fresh object using `!=' will always yield true
+ new Exception() != new Exception()
+ ^
+checksensible.scala:66: error: comparing values of types Int and Null using `==' will always yield false
+ if (foo.length == null) "plante" else "plante pas"
+ ^
+checksensible.scala:71: error: comparing values of types Bip and Bop using `==' will always yield false
+ (x1 == x2)
+ ^
+checksensible.scala:81: error: comparing values of types EqEqRefTest.this.C3 and EqEqRefTest.this.Z1 using `==' will always yield false
+ c3 == z1
+ ^
+checksensible.scala:82: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `==' will always yield false
+ z1 == c3
+ ^
+checksensible.scala:83: error: comparing values of types EqEqRefTest.this.Z1 and EqEqRefTest.this.C3 using `!=' will always yield true
+ z1 != c3
+ ^
+checksensible.scala:84: error: comparing values of types EqEqRefTest.this.C3 and String using `!=' will always yield true
+ c3 != "abc"
+ ^
+checksensible.scala:95: error: comparing values of types Unit and Int using `!=' will always yield true
+ while ((c = in.read) != -1)
+ ^
+33 errors found
diff --git a/test/files/neg/classtags_contextbound_a.check b/test/files/neg/classtags_contextbound_a.check
new file mode 100644
index 0000000000..a4fd37506d
--- /dev/null
+++ b/test/files/neg/classtags_contextbound_a.check
@@ -0,0 +1,4 @@
+classtags_contextbound_a.scala:2: error: No ArrayTag available for T
+ def foo[T] = Array[T]()
+ ^
+one error found
diff --git a/test/files/neg/classtags_contextbound_a.scala b/test/files/neg/classtags_contextbound_a.scala
new file mode 100644
index 0000000000..d18beda341
--- /dev/null
+++ b/test/files/neg/classtags_contextbound_a.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo[T] = Array[T]()
+ println(foo[Int].getClass)
+} \ No newline at end of file
diff --git a/test/files/neg/classtags_contextbound_b.check b/test/files/neg/classtags_contextbound_b.check
new file mode 100644
index 0000000000..f1f48bed72
--- /dev/null
+++ b/test/files/neg/classtags_contextbound_b.check
@@ -0,0 +1,4 @@
+classtags_contextbound_b.scala:3: error: No ClassTag available for T
+ def foo[T] = mkArray[T]
+ ^
+one error found
diff --git a/test/files/neg/classtags_contextbound_b.scala b/test/files/neg/classtags_contextbound_b.scala
new file mode 100644
index 0000000000..3247a8ff29
--- /dev/null
+++ b/test/files/neg/classtags_contextbound_b.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ def mkArray[T: ClassTag] = Array[T]()
+ def foo[T] = mkArray[T]
+ println(foo[Int].getClass)
+} \ No newline at end of file
diff --git a/test/files/neg/classtags_contextbound_c.check b/test/files/neg/classtags_contextbound_c.check
new file mode 100644
index 0000000000..a1c5eddfe1
--- /dev/null
+++ b/test/files/neg/classtags_contextbound_c.check
@@ -0,0 +1,4 @@
+classtags_contextbound_c.scala:2: error: No ArrayTag available for T
+ def mkArray[T] = Array[T]()
+ ^
+one error found
diff --git a/test/files/neg/classtags_contextbound_c.scala b/test/files/neg/classtags_contextbound_c.scala
new file mode 100644
index 0000000000..0b63f8407e
--- /dev/null
+++ b/test/files/neg/classtags_contextbound_c.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ def mkArray[T] = Array[T]()
+ def foo[T: ClassTag] = mkArray[T]
+ println(foo[Int].getClass)
+} \ No newline at end of file
diff --git a/test/files/neg/classtags_dont_use_typetags.check b/test/files/neg/classtags_dont_use_typetags.check
new file mode 100644
index 0000000000..c7d2fba35b
--- /dev/null
+++ b/test/files/neg/classtags_dont_use_typetags.check
@@ -0,0 +1,4 @@
+classtags_dont_use_typetags.scala:2: error: No ArrayTag available for T
+ def foo[T: TypeTag] = Array[T]()
+ ^
+one error found
diff --git a/test/files/neg/classtags_dont_use_typetags.scala b/test/files/neg/classtags_dont_use_typetags.scala
new file mode 100644
index 0000000000..0f675f71aa
--- /dev/null
+++ b/test/files/neg/classtags_dont_use_typetags.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ def foo[T: TypeTag] = Array[T]()
+} \ No newline at end of file
diff --git a/test/files/neg/exhausting.flags b/test/files/neg/exhausting.flags
index e8fb65d50c..b7eb21d5f5 100644
--- a/test/files/neg/exhausting.flags
+++ b/test/files/neg/exhausting.flags
@@ -1 +1 @@
--Xfatal-warnings \ No newline at end of file
+-Xfatal-warnings -Xoldpatmat
diff --git a/test/files/neg/gadts1.check b/test/files/neg/gadts1.check
index 44d2b114d6..0441f604c9 100644
--- a/test/files/neg/gadts1.check
+++ b/test/files/neg/gadts1.check
@@ -11,4 +11,7 @@ gadts1.scala:20: error: type mismatch;
required: a
case Cell[a](x: Int) => c.x = 5
^
-three errors found
+gadts1.scala:20: error: Could not typecheck extractor call: case class <none> with arguments List((x @ (_: Int)))
+ case Cell[a](x: Int) => c.x = 5
+ ^
+four errors found
diff --git a/test/files/neg/interop_classmanifests_arenot_concretetypetags.check b/test/files/neg/interop_classmanifests_arenot_concretetypetags.check
new file mode 100644
index 0000000000..d6fa564df4
--- /dev/null
+++ b/test/files/neg/interop_classmanifests_arenot_concretetypetags.check
@@ -0,0 +1,4 @@
+interop_classmanifests_arenot_concretetypetags.scala:3: error: No ConcreteTypeTag available for T
+ println(concreteTypeTag[T])
+ ^
+one error found
diff --git a/test/files/neg/interop_classmanifests_arenot_concretetypetags.scala b/test/files/neg/interop_classmanifests_arenot_concretetypetags.scala
new file mode 100644
index 0000000000..5b1ed55e47
--- /dev/null
+++ b/test/files/neg/interop_classmanifests_arenot_concretetypetags.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ def classManifestIsnotConcreteTypeTag[T: ClassManifest] = {
+ println(concreteTypeTag[T])
+ }
+
+ classManifestIsnotConcreteTypeTag[Int]
+ classManifestIsnotConcreteTypeTag[String]
+ classManifestIsnotConcreteTypeTag[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/neg/interop_classtags_arenot_manifests.check b/test/files/neg/interop_classtags_arenot_manifests.check
new file mode 100644
index 0000000000..95f6a94d4b
--- /dev/null
+++ b/test/files/neg/interop_classtags_arenot_manifests.check
@@ -0,0 +1,7 @@
+interop_classtags_arenot_manifests.scala:3: error: No Manifest available for T.
+ println(manifest[T])
+ ^
+interop_classtags_arenot_manifests.scala:11: error: No Manifest available for T.
+ println(manifest[T])
+ ^
+two errors found
diff --git a/test/files/neg/interop_classtags_arenot_manifests.scala b/test/files/neg/interop_classtags_arenot_manifests.scala
new file mode 100644
index 0000000000..7351f7e305
--- /dev/null
+++ b/test/files/neg/interop_classtags_arenot_manifests.scala
@@ -0,0 +1,17 @@
+object Test extends App {
+ def arrayTagIsnotManifest[T: ArrayTag] = {
+ println(manifest[T])
+ }
+
+ arrayTagIsnotManifest[Int]
+ arrayTagIsnotManifest[String]
+ arrayTagIsnotManifest[Array[Int]]
+
+ def classTagIsnotManifest[T: ClassTag] = {
+ println(manifest[T])
+ }
+
+ classTagIsnotManifest[Int]
+ classTagIsnotManifest[String]
+ classTagIsnotManifest[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/neg/interop_erasuretags_arenot_classmanifests.check b/test/files/neg/interop_erasuretags_arenot_classmanifests.check
new file mode 100644
index 0000000000..4bb81108d1
--- /dev/null
+++ b/test/files/neg/interop_erasuretags_arenot_classmanifests.check
@@ -0,0 +1,4 @@
+interop_erasuretags_arenot_classmanifests.scala:3: error: could not find implicit value for parameter m: ClassManifest[T]
+ println(classManifest[T])
+ ^
+one error found
diff --git a/test/files/neg/interop_erasuretags_arenot_classmanifests.scala b/test/files/neg/interop_erasuretags_arenot_classmanifests.scala
new file mode 100644
index 0000000000..cf7d1ac257
--- /dev/null
+++ b/test/files/neg/interop_erasuretags_arenot_classmanifests.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ def erasureTagIsnotClassManifest[T: ErasureTag] = {
+ println(classManifest[T])
+ }
+
+ erasureTagIsnotClassManifest[Int]
+ erasureTagIsnotClassManifest[String]
+ erasureTagIsnotClassManifest[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/neg/interop_erasuretags_arenot_manifests.check b/test/files/neg/interop_erasuretags_arenot_manifests.check
new file mode 100644
index 0000000000..da3c03d371
--- /dev/null
+++ b/test/files/neg/interop_erasuretags_arenot_manifests.check
@@ -0,0 +1,4 @@
+interop_erasuretags_arenot_manifests.scala:3: error: No Manifest available for T.
+ println(manifest[T])
+ ^
+one error found
diff --git a/test/files/neg/interop_erasuretags_arenot_manifests.scala b/test/files/neg/interop_erasuretags_arenot_manifests.scala
new file mode 100644
index 0000000000..5c326549d8
--- /dev/null
+++ b/test/files/neg/interop_erasuretags_arenot_manifests.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ def erasureTagIsnotManifest[T: ErasureTag] = {
+ println(manifest[T])
+ }
+
+ erasureTagIsnotManifest[Int]
+ erasureTagIsnotManifest[String]
+ erasureTagIsnotManifest[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/neg/interop_typetags_arenot_classmanifests.check b/test/files/neg/interop_typetags_arenot_classmanifests.check
new file mode 100644
index 0000000000..9ed4fd43d4
--- /dev/null
+++ b/test/files/neg/interop_typetags_arenot_classmanifests.check
@@ -0,0 +1,4 @@
+interop_typetags_arenot_classmanifests.scala:3: error: could not find implicit value for parameter m: ClassManifest[T]
+ println(classManifest[T])
+ ^
+one error found
diff --git a/test/files/neg/interop_typetags_arenot_classmanifests.scala b/test/files/neg/interop_typetags_arenot_classmanifests.scala
new file mode 100644
index 0000000000..b1fbb7b5a6
--- /dev/null
+++ b/test/files/neg/interop_typetags_arenot_classmanifests.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ def typeTagIsnotClassManifest[T: TypeTag] = {
+ println(classManifest[T])
+ }
+
+ typeTagIsnotClassManifest[Int]
+ typeTagIsnotClassManifest[String]
+ typeTagIsnotClassManifest[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/neg/interop_typetags_arenot_manifests.check b/test/files/neg/interop_typetags_arenot_manifests.check
new file mode 100644
index 0000000000..7761a747ff
--- /dev/null
+++ b/test/files/neg/interop_typetags_arenot_manifests.check
@@ -0,0 +1,4 @@
+interop_typetags_arenot_manifests.scala:3: error: No Manifest available for T.
+ println(manifest[T])
+ ^
+one error found
diff --git a/test/files/neg/interop_typetags_arenot_manifests.scala b/test/files/neg/interop_typetags_arenot_manifests.scala
new file mode 100644
index 0000000000..4e2a04489b
--- /dev/null
+++ b/test/files/neg/interop_typetags_arenot_manifests.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ def typeTagIsnotManifest[T: TypeTag] = {
+ println(manifest[T])
+ }
+
+ typeTagIsnotManifest[Int]
+ typeTagIsnotManifest[String]
+ typeTagIsnotManifest[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-argtype-mismatch.flags b/test/files/neg/macro-argtype-mismatch.flags
index 7fea2ff901..cd66464f2f 100644
--- a/test/files/neg/macro-argtype-mismatch.flags
+++ b/test/files/neg/macro-argtype-mismatch.flags
@@ -1 +1 @@
--Xmacros \ No newline at end of file
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-argtype-mismatch/Macros_1.scala b/test/files/neg/macro-argtype-mismatch/Macros_1.scala
deleted file mode 100644
index 4b5f98ba37..0000000000
--- a/test/files/neg/macro-argtype-mismatch/Macros_1.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-object Macros {
- def macro foo(x: Int) = x
-} \ No newline at end of file
diff --git a/test/files/neg/macro-basic-mamdmi.check b/test/files/neg/macro-basic-mamdmi.check
new file mode 100644
index 0000000000..eef444f7b3
--- /dev/null
+++ b/test/files/neg/macro-basic-mamdmi.check
@@ -0,0 +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)
+if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath in the second phase pointing to the output of the first phase
+ println(foo(2) + Macros.bar(2) * new Macros().quux(4))
+ ^
+one error found
diff --git a/test/files/neg/macro-basic-mamdmi.flags b/test/files/neg/macro-basic-mamdmi.flags
new file mode 100644
index 0000000000..5e5dd6ce79
--- /dev/null
+++ b/test/files/neg/macro-basic-mamdmi.flags
@@ -0,0 +1 @@
+-language:experimental.macros
diff --git a/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala b/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala
new file mode 100644
index 0000000000..e9876e32e9
--- /dev/null
+++ b/test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala
@@ -0,0 +1,37 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1))))
+ Expr[Int](body)
+ }
+
+ def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2))))
+ Expr[Int](body)
+ }
+
+ def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3))))
+ Expr[Int](body)
+ }
+}
+
+object Macros {
+ object Shmacros {
+ def foo(x: Int): Int = macro Impls.foo
+ }
+ def bar(x: Int): Int = macro Impls.bar
+}
+
+class Macros {
+ def quux(x: Int): Int = macro Impls.quux
+}
+
+object Test extends App {
+ import Macros.Shmacros._
+ println(foo(2) + Macros.bar(2) * new Macros().quux(4))
+} \ No newline at end of file
diff --git a/test/files/neg/macro-cyclic.check b/test/files/neg/macro-cyclic.check
new file mode 100644
index 0000000000..608381e0e8
--- /dev/null
+++ b/test/files/neg/macro-cyclic.check
@@ -0,0 +1,4 @@
+Impls_Macros_1.scala:5: error: could not find implicit value for parameter e: SourceLocation
+ c.reify { implicitly[SourceLocation] }
+ ^
+one error found
diff --git a/test/files/neg/macro-cyclic.flags b/test/files/neg/macro-cyclic.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-cyclic.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-cyclic/Impls_Macros_1.scala b/test/files/neg/macro-cyclic/Impls_Macros_1.scala
new file mode 100644
index 0000000000..1ea06fc968
--- /dev/null
+++ b/test/files/neg/macro-cyclic/Impls_Macros_1.scala
@@ -0,0 +1,25 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl(c: Context) = {
+ c.reify { implicitly[SourceLocation] }
+ }
+
+ implicit def sourceLocation: SourceLocation1 = macro impl
+}
+
+trait SourceLocation {
+ /** Source location of the outermost call */
+ val outer: SourceLocation
+
+ /** The name of the source file */
+ val fileName: String
+
+ /** The line number */
+ val line: Int
+
+ /** The character offset */
+ val charOffset: Int
+}
+
+case class SourceLocation1(val outer: SourceLocation, val fileName: String, val line: Int, val charOffset: Int) extends SourceLocation
diff --git a/test/files/neg/macro-deprecate-idents.check b/test/files/neg/macro-deprecate-idents.check
new file mode 100644
index 0000000000..f8a7e519df
--- /dev/null
+++ b/test/files/neg/macro-deprecate-idents.check
@@ -0,0 +1,52 @@
+macro-deprecate-idents.scala:2: error: macro is now a reserved word; usage as an identifier is deprecated
+ val macro = ???
+ ^
+macro-deprecate-idents.scala:6: error: macro is now a reserved word; usage as an identifier is deprecated
+ var macro = ???
+ ^
+macro-deprecate-idents.scala:10: error: macro is now a reserved word; usage as an identifier is deprecated
+ type macro = Int
+ ^
+macro-deprecate-idents.scala:14: error: macro is now a reserved word; usage as an identifier is deprecated
+ class macro
+ ^
+macro-deprecate-idents.scala:18: error: macro is now a reserved word; usage as an identifier is deprecated
+ class macro
+ ^
+macro-deprecate-idents.scala:22: error: macro is now a reserved word; usage as an identifier is deprecated
+ object macro
+ ^
+macro-deprecate-idents.scala:26: error: macro is now a reserved word; usage as an identifier is deprecated
+ object macro
+ ^
+macro-deprecate-idents.scala:30: error: macro is now a reserved word; usage as an identifier is deprecated
+ trait macro
+ ^
+macro-deprecate-idents.scala:34: error: macro is now a reserved word; usage as an identifier is deprecated
+ trait macro
+ ^
+macro-deprecate-idents.scala:37: error: macro is now a reserved word; usage as an identifier is deprecated
+package macro {
+ ^
+macro-deprecate-idents.scala:38: error: macro is now a reserved word; usage as an identifier is deprecated
+ package macro.bar {
+ ^
+macro-deprecate-idents.scala:43: error: macro is now a reserved word; usage as an identifier is deprecated
+ package macro.foo {
+ ^
+macro-deprecate-idents.scala:48: error: macro is now a reserved word; usage as an identifier is deprecated
+ val Some(macro) = Some(42)
+ ^
+macro-deprecate-idents.scala:49: error: macro is now a reserved word; usage as an identifier is deprecated
+ macro match {
+ ^
+macro-deprecate-idents.scala:50: error: macro is now a reserved word; usage as an identifier is deprecated
+ case macro => println(macro)
+ ^
+macro-deprecate-idents.scala:50: error: macro is now a reserved word; usage as an identifier is deprecated
+ case macro => println(macro)
+ ^
+macro-deprecate-idents.scala:55: error: macro is now a reserved word; usage as an identifier is deprecated
+ def macro = 2
+ ^
+17 errors found
diff --git a/test/files/neg/macro-deprecate-idents.flags b/test/files/neg/macro-deprecate-idents.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/neg/macro-deprecate-idents.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/macro-deprecate-idents.scala b/test/files/neg/macro-deprecate-idents.scala
new file mode 100644
index 0000000000..23c398e341
--- /dev/null
+++ b/test/files/neg/macro-deprecate-idents.scala
@@ -0,0 +1,56 @@
+object Test1 {
+ val macro = ???
+}
+
+object Test2 {
+ var macro = ???
+}
+
+object Test3 {
+ type macro = Int
+}
+
+package test4 {
+ class macro
+}
+
+object Test5 {
+ class macro
+}
+
+package test6 {
+ object macro
+}
+
+object Test7 {
+ object macro
+}
+
+package test8 {
+ trait macro
+}
+
+object Test9 {
+ trait macro
+}
+
+package macro {
+ package macro.bar {
+ }
+}
+
+package foo {
+ package macro.foo {
+ }
+}
+
+object Test12 {
+ val Some(macro) = Some(42)
+ macro match {
+ case macro => println(macro)
+ }
+}
+
+object Test13 {
+ def macro = 2
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-a.check b/test/files/neg/macro-invalidimpl-a.check
new file mode 100644
index 0000000000..855fe2d169
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-a.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object
+ def foo(x: Any) = macro impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidimpl-a.flags b/test/files/neg/macro-invalidimpl-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-a/Impls_1.scala b/test/files/neg/macro-invalidimpl-a/Impls_1.scala
new file mode 100644
index 0000000000..c2f1843b8b
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-a/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+class Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala
new file mode 100644
index 0000000000..2220ddae0c
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala
@@ -0,0 +1,9 @@
+object Macros {
+ val impls = new Impls
+ def foo(x: Any) = macro impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-b.check b/test/files/neg/macro-invalidimpl-b.check
new file mode 100644
index 0000000000..855fe2d169
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-b.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object
+ def foo(x: Any) = macro impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidimpl-b.flags b/test/files/neg/macro-invalidimpl-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-b/Impls_1.scala b/test/files/neg/macro-invalidimpl-b/Impls_1.scala
new file mode 100644
index 0000000000..7b1620d117
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-b/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala
new file mode 100644
index 0000000000..81e40837d2
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala
@@ -0,0 +1,9 @@
+object Macros {
+ val impls = Impls
+ def foo(x: Any) = macro impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-c.check b/test/files/neg/macro-invalidimpl-c.check
new file mode 100644
index 0000000000..722ec3c7bd
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-c.check
@@ -0,0 +1,4 @@
+Impls_Macros_1.scala:8: error: macro implementation must be in statically accessible object
+ def foo(x: Any) = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidimpl-c.flags b/test/files/neg/macro-invalidimpl-c.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-c.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala b/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala
new file mode 100644
index 0000000000..657e2d4260
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+class Macros {
+ object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+ }
+
+ def foo(x: Any) = macro Impls.foo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-c/Test_2.scala b/test/files/neg/macro-invalidimpl-c/Test_2.scala
new file mode 100644
index 0000000000..e75a8ba101
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-c/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ new Macros().foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-d.check b/test/files/neg/macro-invalidimpl-d.check
new file mode 100644
index 0000000000..6fedfa74fc
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-d.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:2: error: macro implementation must be in statically accessible object
+ def foo(x: Any) = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidimpl-d.flags b/test/files/neg/macro-invalidimpl-d.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-d.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-d/Impls_1.scala b/test/files/neg/macro-invalidimpl-d/Impls_1.scala
new file mode 100644
index 0000000000..f18e699a1e
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-d/Impls_1.scala
@@ -0,0 +1,7 @@
+import scala.reflect.makro.{Context => Ctx}
+
+trait MacroHelpers {
+ object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = x
+ }
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala
new file mode 100644
index 0000000000..067ab1ddec
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala
@@ -0,0 +1,7 @@
+class Macros extends MacroHelpers {
+ def foo(x: Any) = macro Impls.foo
+}
+
+object Test extends App {
+ println(new Macros().foo(42))
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-e.check b/test/files/neg/macro-invalidimpl-e.check
new file mode 100644
index 0000000000..61d1e05b87
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-e.check
@@ -0,0 +1,13 @@
+Macros_Test_2.scala:2: error: ambiguous reference to overloaded definition,
+both method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing
+and method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any])Nothing
+match expected type ?
+ def foo(x: Any) = macro Impls.foo
+ ^
+Macros_Test_2.scala:3: error: ambiguous reference to overloaded definition,
+both method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing
+and method foo in object Impls of type (c: scala.reflect.makro.Context)(x: c.Expr[Any])Nothing
+match expected type ?
+ def foo(x: Any, y: Any) = macro Impls.foo
+ ^
+two errors found
diff --git a/test/files/neg/macro-invalidimpl-e.flags b/test/files/neg/macro-invalidimpl-e.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-e.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-e/Impls_1.scala b/test/files/neg/macro-invalidimpl-e/Impls_1.scala
new file mode 100644
index 0000000000..ad3eed5cd5
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-e/Impls_1.scala
@@ -0,0 +1,6 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+ def foo(c: Ctx)(x: c.Expr[Any], y: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala
new file mode 100644
index 0000000000..6edde08167
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala
@@ -0,0 +1,9 @@
+object Macros {
+ def foo(x: Any) = macro Impls.foo
+ def foo(x: Any, y: Any) = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-f.check b/test/files/neg/macro-invalidimpl-f.check
new file mode 100644
index 0000000000..ec82faa58c
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-f.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context)(): c.Expr[Unit]
+ found : (c: scala.reflect.makro.Context): c.Expr[Unit]
+number of parameter sections differ
+ def bar1() = macro Impls.fooNullary
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidimpl-f.flags b/test/files/neg/macro-invalidimpl-f.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-f.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-f/Impls_1.scala b/test/files/neg/macro-invalidimpl-f/Impls_1.scala
new file mode 100644
index 0000000000..06c6efbb1f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-f/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def fooNullary(c: Ctx) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))
+ Expr[Unit](body)
+ }
+
+ def fooEmpty(c: Ctx)() = fooNullary(c)
+}
diff --git a/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala
new file mode 100644
index 0000000000..493edf1df8
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala
@@ -0,0 +1,9 @@
+object Macros {
+ def bar1() = macro Impls.fooNullary
+}
+
+object Test extends App {
+ Macros.bar1
+ Macros.bar1()
+ println("kkthxbai")
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-g.check b/test/files/neg/macro-invalidimpl-g.check
new file mode 100644
index 0000000000..9c01f01dc8
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-g.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context): c.Expr[Unit]
+ found : (c: scala.reflect.makro.Context)(): c.Expr[Unit]
+number of parameter sections differ
+ def foo1 = macro Impls.fooEmpty
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidimpl-g.flags b/test/files/neg/macro-invalidimpl-g.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-g.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-g/Impls_1.scala b/test/files/neg/macro-invalidimpl-g/Impls_1.scala
new file mode 100644
index 0000000000..06c6efbb1f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-g/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def fooNullary(c: Ctx) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))
+ Expr[Unit](body)
+ }
+
+ def fooEmpty(c: Ctx)() = fooNullary(c)
+}
diff --git a/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala
new file mode 100644
index 0000000000..5561db9f9a
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo1 = macro Impls.fooEmpty
+}
+
+object Test extends App {
+ Macros.foo1
+ println("kkthxbai")
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-h.check b/test/files/neg/macro-invalidimpl-h.check
new file mode 100644
index 0000000000..cc7fc794d3
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-h.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:2: error: type arguments [String] do not conform to method foo's type parameter bounds [U <: Int]
+ def foo = macro Impls.foo[String]
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidimpl-h.flags b/test/files/neg/macro-invalidimpl-h.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-h.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidimpl-h/Impls_1.scala b/test/files/neg/macro-invalidimpl-h/Impls_1.scala
new file mode 100644
index 0000000000..7db8bcd324
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-h/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U <: Int](c: Ctx) = ???
+}
diff --git a/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala
new file mode 100644
index 0000000000..218c7aec7f
--- /dev/null
+++ b/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo[String]
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidret-nontree.check b/test/files/neg/macro-invalidret-nontree.check
new file mode 100644
index 0000000000..0b793cf421
--- /dev/null
+++ b/test/files/neg/macro-invalidret-nontree.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context): c.Expr[Any]
+ found : (c: scala.reflect.makro.Context): Int
+type mismatch for return type: Int does not conform to c.Expr[Any]
+ def foo = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidret-nontree.flags b/test/files/neg/macro-invalidret-nontree.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidret-nontree.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidret-nontree/Impls_1.scala b/test/files/neg/macro-invalidret-nontree/Impls_1.scala
new file mode 100644
index 0000000000..efc8d4bfec
--- /dev/null
+++ b/test/files/neg/macro-invalidret-nontree/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = 2
+}
diff --git a/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala
new file mode 100644
index 0000000000..96a8de2832
--- /dev/null
+++ b/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidret-nonuniversetree.check b/test/files/neg/macro-invalidret-nonuniversetree.check
new file mode 100644
index 0000000000..4fc06b5ceb
--- /dev/null
+++ b/test/files/neg/macro-invalidret-nonuniversetree.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context): c.Expr[Any]
+ found : (c: scala.reflect.makro.Context): reflect.mirror.Literal
+type mismatch for return type: reflect.mirror.Literal does not conform to c.Expr[Any]
+ def foo = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidret-nonuniversetree.flags b/test/files/neg/macro-invalidret-nonuniversetree.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidret-nonuniversetree.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala
new file mode 100644
index 0000000000..86b7c8d8d0
--- /dev/null
+++ b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = scala.reflect.mirror.Literal(scala.reflect.mirror.Constant(42))
+}
diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala
new file mode 100644
index 0000000000..96a8de2832
--- /dev/null
+++ b/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidshape-a.check b/test/files/neg/macro-invalidshape-a.check
new file mode 100644
index 0000000000..246b5c3226
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-a.check
@@ -0,0 +1,6 @@
+Macros_Test_2.scala:2: error: macro body has wrong shape:
+ required: macro <reference to implementation object>.<implementation method name>
+ or : macro <implementation method name>
+ def foo(x: Any) = macro 2
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidshape-a.flags b/test/files/neg/macro-invalidshape-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidshape-a/Impls_1.scala b/test/files/neg/macro-invalidshape-a/Impls_1.scala
new file mode 100644
index 0000000000..7b1620d117
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-a/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala
new file mode 100644
index 0000000000..ffff17d1e7
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Any) = macro 2
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidshape-b.check b/test/files/neg/macro-invalidshape-b.check
new file mode 100644
index 0000000000..59701d023b
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-b.check
@@ -0,0 +1,6 @@
+Macros_Test_2.scala:2: error: macro body has wrong shape:
+ required: macro <reference to implementation object>.<implementation method name>
+ or : macro <implementation method name>
+ def foo(x: Any) = macro Impls.foo(null)(null)
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidshape-b.flags b/test/files/neg/macro-invalidshape-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidshape-b/Impls_1.scala b/test/files/neg/macro-invalidshape-b/Impls_1.scala
new file mode 100644
index 0000000000..7b1620d117
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-b/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala
new file mode 100644
index 0000000000..b67cd32a6e
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Any) = macro Impls.foo(null)(null)
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidshape-c.check b/test/files/neg/macro-invalidshape-c.check
new file mode 100644
index 0000000000..84d8c35222
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-c.check
@@ -0,0 +1,6 @@
+Macros_Test_2.scala:2: error: macro body has wrong shape:
+ required: macro <reference to implementation object>.<implementation method name>
+ or : macro <implementation method name>
+ def foo(x: Any) = macro {2; Impls.foo}
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidshape-c.flags b/test/files/neg/macro-invalidshape-c.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-c.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidshape-c/Impls_1.scala b/test/files/neg/macro-invalidshape-c/Impls_1.scala
new file mode 100644
index 0000000000..7b1620d117
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-c/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala
new file mode 100644
index 0000000000..552c3710c7
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Any) = macro {2; Impls.foo}
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidshape-d.check b/test/files/neg/macro-invalidshape-d.check
new file mode 100644
index 0000000000..f0d77e2f2d
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-d.check
@@ -0,0 +1,8 @@
+Macros_Test_2.scala:2: warning: macro is now a reserved word; usage as an identifier is deprecated
+ def foo(x: Any) = {2; macro Impls.foo}
+ ^
+Macros_Test_2.scala:2: error: ';' expected but '.' found.
+ def foo(x: Any) = {2; macro Impls.foo}
+ ^
+one warning found
+one error found
diff --git a/test/files/neg/macro-invalidshape-d.flags b/test/files/neg/macro-invalidshape-d.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-d.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidshape-d/Impls_1.scala b/test/files/neg/macro-invalidshape-d/Impls_1.scala
new file mode 100644
index 0000000000..7b1620d117
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-d/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala
new file mode 100644
index 0000000000..bacd9a6e7c
--- /dev/null
+++ b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Any) = {2; macro Impls.foo}
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-context-bounds.check b/test/files/neg/macro-invalidsig-context-bounds.check
new file mode 100644
index 0000000000..dd68e5db1b
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-context-bounds.check
@@ -0,0 +1,4 @@
+Impls_1.scala:4: error: macro implementations cannot have implicit parameters other than TypeTag evidences
+ def foo[U: c.TypeTag: Numeric](c: Ctx) = {
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-context-bounds.flags b/test/files/neg/macro-invalidsig-context-bounds.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-context-bounds.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala b/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala
new file mode 100644
index 0000000000..2eb2ab3947
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala
@@ -0,0 +1,8 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U: c.TypeTag: Numeric](c: Ctx) = {
+ import c.mirror._
+ Literal(Constant(42))
+ }
+}
diff --git a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala
new file mode 100644
index 0000000000..5b4602f328
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo[U] = macro Impls.foo[U]
+}
+
+object Test extends App {
+ import Macros._
+ println(foo[String])
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-ctx-badargc.check b/test/files/neg/macro-invalidsig-ctx-badargc.check
new file mode 100644
index 0000000000..1e1621ab61
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badargc.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context): c.Expr[Any]
+ found : : Nothing
+number of parameter sections differ
+ def foo = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-ctx-badargc.flags b/test/files/neg/macro-invalidsig-ctx-badargc.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badargc.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala
new file mode 100644
index 0000000000..da28944d27
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.api.{Mirror => Ctx}
+
+object Impls {
+ def foo = ???
+}
diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala
new file mode 100644
index 0000000000..96a8de2832
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-ctx-badtype.check b/test/files/neg/macro-invalidsig-ctx-badtype.check
new file mode 100644
index 0000000000..3913a8e3cb
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badtype.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context): c.Expr[Any]
+ found : (c: scala.reflect.api.Mirror): Nothing
+type mismatch for parameter c: scala.reflect.makro.Context does not conform to scala.reflect.api.Mirror
+ def foo = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-ctx-badtype.flags b/test/files/neg/macro-invalidsig-ctx-badtype.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badtype.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala
new file mode 100644
index 0000000000..747a2e9ca8
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.api.{Mirror => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = ???
+}
diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala
new file mode 100644
index 0000000000..96a8de2832
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs.check b/test/files/neg/macro-invalidsig-ctx-badvarargs.check
new file mode 100644
index 0000000000..18e3d6201f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badvarargs.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context): c.Expr[Any]
+ found : (cs: scala.reflect.makro.Context*): Nothing
+types incompatible for parameter cs: corresponding is not a vararg parameter
+ def foo = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs.flags b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala
new file mode 100644
index 0000000000..b2fb2539ec
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(cs: Ctx*) = ???
+}
diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala
new file mode 100644
index 0000000000..96a8de2832
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-ctx-noctx.check b/test/files/neg/macro-invalidsig-ctx-noctx.check
new file mode 100644
index 0000000000..66fa7c3514
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-noctx.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context)(x: c.Expr[Any]): c.Expr[Any]
+ found : (c: scala.reflect.makro.Context): Nothing
+number of parameter sections differ
+ def foo(x: Any) = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-ctx-noctx.flags b/test/files/neg/macro-invalidsig-ctx-noctx.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-noctx.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala
new file mode 100644
index 0000000000..1e0ed755af
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = ???
+}
diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala
new file mode 100644
index 0000000000..e053cf99df
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Any) = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-implicit-params.check b/test/files/neg/macro-invalidsig-implicit-params.check
new file mode 100644
index 0000000000..0dd1c27b50
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-implicit-params.check
@@ -0,0 +1,4 @@
+Impls_Macros_1.scala:4: error: macro implementations cannot have implicit parameters other than TypeTag evidences
+ def foo_targs[T, U: c.TypeTag](c: Ctx)(implicit x: c.Expr[Int]) = {
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-implicit-params.flags b/test/files/neg/macro-invalidsig-implicit-params.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-implicit-params.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala
new file mode 100644
index 0000000000..662ad2ab52
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala
@@ -0,0 +1,18 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo_targs[T, U: c.TypeTag](c: Ctx)(implicit x: c.Expr[Int]) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val body = Block(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.tpe)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + implicitly[c.TypeTag[U]].tpe)))),
+ Literal(Constant(())))
+ Expr[Unit](body)
+ }
+}
+
+class Macros[T] {
+ def foo_targs[U](x: Int) = macro Impls.foo_targs[T, U]
+}
diff --git a/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala b/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala
new file mode 100644
index 0000000000..90e850df21
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ println("foo_targs:")
+ new Macros[Int]().foo_targs[String](42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-params-badargc.check b/test/files/neg/macro-invalidsig-params-badargc.check
new file mode 100644
index 0000000000..6de8c5e95a
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badargc.check
@@ -0,0 +1,7 @@
+Impls_Macros_1.scala:8: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context)(x: c.Expr[Int]): c.Expr[Any]
+ found : (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): Nothing
+parameter lists have different length, found extra parameter y: c.Expr[Int]
+ def foo(x: Int) = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-params-badargc.flags b/test/files/neg/macro-invalidsig-params-badargc.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badargc.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala
new file mode 100644
index 0000000000..4b449f35ed
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = ???
+}
+
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+}
diff --git a/test/files/neg/macro-noexpand/Test_2.scala b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala
index 0bed592883..cbd6232073 100644
--- a/test/files/neg/macro-noexpand/Test_2.scala
+++ b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala
@@ -1,4 +1,4 @@
object Test extends App {
import Macros._
- foo(x)
+ foo(42)
} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-params-badtype.check b/test/files/neg/macro-invalidsig-params-badtype.check
new file mode 100644
index 0000000000..71a65aec84
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badtype.check
@@ -0,0 +1,7 @@
+Impls_Macros_1.scala:8: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context)(x: c.Expr[Int]): c.Expr[Any]
+ found : (c: scala.reflect.makro.Context)(x: c.mirror.Tree): Nothing
+type mismatch for parameter x: c.Expr[Int] does not conform to c.mirror.Tree
+ def foo(x: Int) = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-params-badtype.flags b/test/files/neg/macro-invalidsig-params-badtype.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badtype.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala
new file mode 100644
index 0000000000..29220c1c82
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.mirror.Tree) = ???
+}
+
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+}
diff --git a/test/files/neg/macro-argtype-mismatch/Test_2.scala b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala
index 18feb69425..cbd6232073 100644
--- a/test/files/neg/macro-argtype-mismatch/Test_2.scala
+++ b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala
@@ -1,4 +1,4 @@
object Test extends App {
import Macros._
- foo("2")
+ foo(42)
} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-params-badvarargs.check b/test/files/neg/macro-invalidsig-params-badvarargs.check
new file mode 100644
index 0000000000..0827680299
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badvarargs.check
@@ -0,0 +1,7 @@
+Impls_Macros_1.scala:8: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any]
+ found : (c: scala.reflect.makro.Context)(xs: c.Expr[Int]*): Nothing
+parameter lists have different length, required extra parameter y: c.Expr[Int]
+ def foo(x: Int, y: Int) = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-params-badvarargs.flags b/test/files/neg/macro-invalidsig-params-badvarargs.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badvarargs.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala
new file mode 100644
index 0000000000..2ee1c2767c
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(xs: c.Expr[Int]*) = ???
+}
+
+object Macros {
+ def foo(x: Int, y: Int) = macro Impls.foo
+}
diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala
new file mode 100644
index 0000000000..fa50ac4f73
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros._
+ foo(42, 100)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-params-namemismatch.check b/test/files/neg/macro-invalidsig-params-namemismatch.check
new file mode 100644
index 0000000000..ca7270cca8
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-namemismatch.check
@@ -0,0 +1,7 @@
+Impls_Macros_1.scala:8: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any]
+ found : (c: scala.reflect.makro.Context)(y: c.Expr[Int], x: c.Expr[Int]): Nothing
+parameter names differ: x != y
+ def foo(x: Int, y: Int) = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-params-namemismatch.flags b/test/files/neg/macro-invalidsig-params-namemismatch.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-namemismatch.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala
new file mode 100644
index 0000000000..89c5347647
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(y: c.Expr[Int], x: c.Expr[Int]) = ???
+}
+
+object Macros {
+ def foo(x: Int, y: Int) = macro Impls.foo
+}
diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala
new file mode 100644
index 0000000000..fa50ac4f73
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros._
+ foo(42, 100)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-badtype.check b/test/files/neg/macro-invalidsig-tparams-badtype.check
new file mode 100644
index 0000000000..bd1acc4a0a
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-badtype.check
@@ -0,0 +1,7 @@
+Macros_Test_2.scala:2: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context): c.Expr[Any]
+ found : (c: scala.reflect.makro.Context)(U: c.mirror.Type): Nothing
+number of parameter sections differ
+ def foo[U] = macro Impls.foo[U]
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-tparams-badtype.flags b/test/files/neg/macro-invalidsig-tparams-badtype.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-badtype.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala
new file mode 100644
index 0000000000..b43251df33
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U](c: Ctx)(U: c.mirror.Type) = ???
+}
diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala
new file mode 100644
index 0000000000..a82e813221
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo[U] = macro Impls.foo[U]
+}
+
+object Test extends App {
+ import Macros._
+ foo[Int]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a.check b/test/files/neg/macro-invalidsig-tparams-bounds-a.check
new file mode 100644
index 0000000000..6ba80b45c0
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-bounds-a.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:2: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String]
+ def foo[U] = macro Impls.foo[U]
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a.flags b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala
new file mode 100644
index 0000000000..88b85d48f4
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U <: String](c: Ctx) = ???
+}
diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala
new file mode 100644
index 0000000000..a82e813221
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo[U] = macro Impls.foo[U]
+}
+
+object Test extends App {
+ import Macros._
+ foo[Int]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b.check b/test/files/neg/macro-invalidsig-tparams-bounds-b.check
new file mode 100644
index 0000000000..50f0944acc
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-bounds-b.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:2: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String]
+ def foo[U <: Int] = macro Impls.foo[U]
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b.flags b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala
new file mode 100644
index 0000000000..88b85d48f4
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U <: String](c: Ctx) = ???
+}
diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala
new file mode 100644
index 0000000000..eed6369a16
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo[U <: Int] = macro Impls.foo[U]
+}
+
+object Test extends App {
+ import Macros._
+ foo[Int]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a.check b/test/files/neg/macro-invalidsig-tparams-notparams-a.check
new file mode 100644
index 0000000000..5b4ef42ea5
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-a.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:2: error: macro implementation reference needs type arguments
+ def foo = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a.flags b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala
new file mode 100644
index 0000000000..bbe5b4e519
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U: c.TypeTag](c: Ctx) = ???
+}
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala
new file mode 100644
index 0000000000..96a8de2832
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b.check b/test/files/neg/macro-invalidsig-tparams-notparams-b.check
new file mode 100644
index 0000000000..261e3b8293
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-b.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:3: error: macro implementation reference needs type arguments
+ def foo[V] = macro Impls.foo
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b.flags b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala
new file mode 100644
index 0000000000..db79ddbcd8
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T: c.TypeTag, U: c.TypeTag, V](c: Ctx)(implicit V: c.TypeTag[V]): c.Expr[Unit] = {
+ println(implicitly[c.TypeTag[T]])
+ println(implicitly[c.TypeTag[U]])
+ println(V)
+ c.literalUnit
+ }
+}
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala
new file mode 100644
index 0000000000..7d02bf613a
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala
@@ -0,0 +1,11 @@
+class D[T] {
+ class C[U] {
+ def foo[V] = macro Impls.foo
+ }
+}
+
+object Test extends App {
+ val outer1 = new D[Int]
+ val outer2 = new outer1.C[String]
+ outer2.foo[Boolean]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c.check b/test/files/neg/macro-invalidsig-tparams-notparams-c.check
new file mode 100644
index 0000000000..b64a469cc3
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-c.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:3: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.makro.Context)(implicit evidence$1: c.TypeTag[T], implicit evidence$2: c.TypeTag[U], implicit V: c.TypeTag[V])c.Expr[Unit]
+ def foo[V] = macro Impls.foo[V]
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c.flags b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala
new file mode 100644
index 0000000000..43c5a2acd5
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T: c.TypeTag, U: c.TypeTag, V](c: Ctx)(implicit V: c.TypeTag[V]): c.Expr[Unit] = {
+ import c.mirror._
+ println(implicitly[c.TypeTag[T]])
+ println(implicitly[c.TypeTag[U]])
+ println(V)
+ c.literalUnit
+ }
+}
diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala
new file mode 100644
index 0000000000..109e142e52
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala
@@ -0,0 +1,11 @@
+class D[T] {
+ class C[U] {
+ def foo[V] = macro Impls.foo[V]
+ }
+}
+
+object Test extends App {
+ val outer1 = new D[Int]
+ val outer2 = new outer1.C[String]
+ outer2.foo[Boolean]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check
new file mode 100644
index 0000000000..52beda5b61
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badargs.check
@@ -0,0 +1,6 @@
+Macros_Test_2.scala:7: error: type mismatch;
+ found : String("42")
+ required: Int
+ val s: String = foo("42")
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidusage-badargs.flags b/test/files/neg/macro-invalidusage-badargs.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badargs.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-badargs/Impls_1.scala b/test/files/neg/macro-invalidusage-badargs/Impls_1.scala
new file mode 100644
index 0000000000..2346a6106d
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badargs/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = x
+}
diff --git a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala
new file mode 100644
index 0000000000..a6af1bb277
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ val s: String = foo("42")
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-badbounds.check b/test/files/neg/macro-invalidusage-badbounds.check
new file mode 100644
index 0000000000..fd0b64533e
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badbounds.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:7: error: type arguments [Int] do not conform to macro method foo's type parameter bounds [U <: String]
+ foo[Int]
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidusage-badbounds.flags b/test/files/neg/macro-invalidusage-badbounds.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badbounds.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala
new file mode 100644
index 0000000000..88b85d48f4
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U <: String](c: Ctx) = ???
+}
diff --git a/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala
new file mode 100644
index 0000000000..3139599108
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo[U <: String] = macro Impls.foo[U]
+}
+
+object Test extends App {
+ import Macros._
+ foo[Int]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-badtargs.check b/test/files/neg/macro-invalidusage-badtargs.check
new file mode 100644
index 0000000000..61ef6f5af7
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badtargs.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:7: error: macro method foo: (x: Int)Int does not take type parameters.
+ val s: String = foo[String](42)
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidusage-badtargs.flags b/test/files/neg/macro-invalidusage-badtargs.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badtargs.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala b/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala
new file mode 100644
index 0000000000..2346a6106d
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badtargs/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = x
+}
diff --git a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala
new file mode 100644
index 0000000000..c54093b637
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ val s: String = foo[String](42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax.check b/test/files/neg/macro-invalidusage-methodvaluesyntax.check
new file mode 100644
index 0000000000..27b2023202
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-methodvaluesyntax.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:6: error: macros cannot be eta-expanded
+ val firstClassFoo = Macros.foo _
+ ^
+one error found
diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax.flags b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala b/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala
new file mode 100644
index 0000000000..8e52613b6d
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala
new file mode 100644
index 0000000000..343cec99b5
--- /dev/null
+++ b/test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ val firstClassFoo = Macros.foo _
+ firstClassFoo
+} \ No newline at end of file
diff --git a/test/files/neg/macro-noexpand.check b/test/files/neg/macro-noexpand.check
index c15d54bb32..c829bbab71 100644
--- a/test/files/neg/macro-noexpand.check
+++ b/test/files/neg/macro-noexpand.check
@@ -1,4 +1,4 @@
-Test_2.scala:3: error: not found: value x
+Macros_Test_2.scala:7: error: not found: value x
foo(x)
^
one error found
diff --git a/test/files/neg/macro-noexpand.flags b/test/files/neg/macro-noexpand.flags
index 7fea2ff901..cd66464f2f 100644
--- a/test/files/neg/macro-noexpand.flags
+++ b/test/files/neg/macro-noexpand.flags
@@ -1 +1 @@
--Xmacros \ No newline at end of file
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-noexpand/Impls_1.scala b/test/files/neg/macro-noexpand/Impls_1.scala
new file mode 100644
index 0000000000..7b1620d117
--- /dev/null
+++ b/test/files/neg/macro-noexpand/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-noexpand/Macros_1.scala b/test/files/neg/macro-noexpand/Macros_1.scala
deleted file mode 100644
index 7a6aadf6a1..0000000000
--- a/test/files/neg/macro-noexpand/Macros_1.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-object Macros {
- def macro foo(x: Any) = ???
-} \ No newline at end of file
diff --git a/test/files/neg/macro-noexpand/Macros_Test_2.scala b/test/files/neg/macro-noexpand/Macros_Test_2.scala
new file mode 100644
index 0000000000..e783e2b53e
--- /dev/null
+++ b/test/files/neg/macro-noexpand/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Any) = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo(x)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-noncompilertree.flags b/test/files/neg/macro-noncompilertree.flags
index 7fea2ff901..cd66464f2f 100644
--- a/test/files/neg/macro-noncompilertree.flags
+++ b/test/files/neg/macro-noncompilertree.flags
@@ -1 +1 @@
--Xmacros \ No newline at end of file
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-noncompilertree/Macros_1.scala b/test/files/neg/macro-noncompilertree/Macros_1.scala
deleted file mode 100644
index eb1253e5e9..0000000000
--- a/test/files/neg/macro-noncompilertree/Macros_1.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-object Macros {
- def macro foo = scala.reflect.mirror.Literal(scala.reflect.mirror.Constant(2))
-} \ No newline at end of file
diff --git a/test/files/neg/macro-nontree.flags b/test/files/neg/macro-nontree.flags
index 7fea2ff901..cd66464f2f 100644
--- a/test/files/neg/macro-nontree.flags
+++ b/test/files/neg/macro-nontree.flags
@@ -1 +1 @@
--Xmacros \ No newline at end of file
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-nontree/Macros_1.scala b/test/files/neg/macro-nontree/Macros_1.scala
deleted file mode 100644
index 2433974a85..0000000000
--- a/test/files/neg/macro-nontree/Macros_1.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-object Macros {
- def macro foo = 2
-} \ No newline at end of file
diff --git a/test/files/neg/macro-nontypeablebody.check b/test/files/neg/macro-nontypeablebody.check
new file mode 100644
index 0000000000..0cfc864df8
--- /dev/null
+++ b/test/files/neg/macro-nontypeablebody.check
@@ -0,0 +1,4 @@
+Macros_Test_2.scala:2: error: value foo2 is not a member of object Impls
+ def foo(x: Any) = macro Impls.foo2
+ ^
+one error found
diff --git a/test/files/neg/macro-nontypeablebody.flags b/test/files/neg/macro-nontypeablebody.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-nontypeablebody.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-nontypeablebody/Impls_1.scala b/test/files/neg/macro-nontypeablebody/Impls_1.scala
new file mode 100644
index 0000000000..7b1620d117
--- /dev/null
+++ b/test/files/neg/macro-nontypeablebody/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = ???
+}
diff --git a/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala b/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala
new file mode 100644
index 0000000000..2031893970
--- /dev/null
+++ b/test/files/neg/macro-nontypeablebody/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(x: Any) = macro Impls.foo2
+}
+
+object Test extends App {
+ import Macros._
+ foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.check b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check
new file mode 100644
index 0000000000..4d95dfc45c
--- /dev/null
+++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.check
@@ -0,0 +1,5 @@
+Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int;
+ macro method foo cannot override an abstract method
+ def foo(x: Int) = macro Impls.impl
+ ^
+one error found
diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala
new file mode 100644
index 0000000000..cb0b152852
--- /dev/null
+++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def impl(c: Ctx)(x: c.Expr[Int]) = x
+}
+
+trait Foo {
+ def foo(x: Int): Int
+}
+
+object Macros extends Foo {
+ def foo(x: Int) = macro Impls.impl
+}
diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala
new file mode 100644
index 0000000000..7e3357ec28
--- /dev/null
+++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val designator: Macros.type = Macros
+ designator.foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.check b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check
new file mode 100644
index 0000000000..4d95dfc45c
--- /dev/null
+++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check
@@ -0,0 +1,5 @@
+Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int;
+ macro method foo cannot override an abstract method
+ def foo(x: Int) = macro Impls.impl
+ ^
+one error found
diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala
new file mode 100644
index 0000000000..cb0b152852
--- /dev/null
+++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def impl(c: Ctx)(x: c.Expr[Int]) = x
+}
+
+trait Foo {
+ def foo(x: Int): Int
+}
+
+object Macros extends Foo {
+ def foo(x: Int) = macro Impls.impl
+}
diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala
new file mode 100644
index 0000000000..08fff30baf
--- /dev/null
+++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val designator: Foo = Macros
+ designator.foo(42)
+} \ No newline at end of file
diff --git a/test/files/neg/macro-override-method-overrides-macro.check b/test/files/neg/macro-override-method-overrides-macro.check
new file mode 100644
index 0000000000..42edb0ff23
--- /dev/null
+++ b/test/files/neg/macro-override-method-overrides-macro.check
@@ -0,0 +1,5 @@
+Macros_Test_2.scala:8: error: overriding macro method foo in class B of type (x: String)Unit;
+ method foo cannot override a macro
+ override def foo(x: String) = println("fooDString")
+ ^
+one error found
diff --git a/test/files/neg/macro-override-method-overrides-macro.flags b/test/files/neg/macro-override-method-overrides-macro.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/macro-override-method-overrides-macro.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala b/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala
new file mode 100644
index 0000000000..0b127f5a59
--- /dev/null
+++ b/test/files/neg/macro-override-method-overrides-macro/Impls_1.scala
@@ -0,0 +1,15 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def impl(c: Ctx)(tag: String, x: c.Expr[_]) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree))
+ Expr[Unit](body)
+ }
+
+ def fooBString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBString", x)
+ def fooBInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBInt", x)
+ def fooDInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooDInt", x)
+ def fooZString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooZString", x)
+}
diff --git a/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala b/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala
new file mode 100644
index 0000000000..36821b05d8
--- /dev/null
+++ b/test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala
@@ -0,0 +1,15 @@
+class B {
+ def foo(x: String) = macro Impls.fooBString
+ def foo(x: Int) = macro Impls.fooBInt
+ def foo(x: Boolean) = println("fooBBoolean")
+}
+
+class D extends B {
+ override def foo(x: String) = println("fooDString")
+ override def foo(x: Int) = macro Impls.fooDInt
+}
+
+class Z extends D {
+ override def foo(x: String) = macro Impls.fooZString
+ override def foo(x: Boolean) = println("fooZBoolean")
+}
diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check
new file mode 100644
index 0000000000..39e90f827e
--- /dev/null
+++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check
@@ -0,0 +1,7 @@
+Test.scala:5: error: No ConcreteTypeTag available for C[T]
+ println(implicitly[ConcreteTypeTag[C[T]]])
+ ^
+Test.scala:6: error: No ConcreteTypeTag available for List[C[T]]
+ println(implicitly[ConcreteTypeTag[List[C[T]]]])
+ ^
+two errors found
diff --git a/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala
new file mode 100644
index 0000000000..1302999da6
--- /dev/null
+++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooNoTypeTagHK[C[_], T] = {
+ println(implicitly[ConcreteTypeTag[C[T]]])
+ println(implicitly[ConcreteTypeTag[List[C[T]]]])
+ }
+ fooNoTypeTagHK[List, Int]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check
new file mode 100644
index 0000000000..164ca3543f
--- /dev/null
+++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check
@@ -0,0 +1,7 @@
+Test.scala:5: error: No ConcreteTypeTag available for T
+ println(implicitly[ConcreteTypeTag[T]])
+ ^
+Test.scala:6: error: No ConcreteTypeTag available for List[T]
+ println(implicitly[ConcreteTypeTag[List[T]]])
+ ^
+two errors found
diff --git a/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala
new file mode 100644
index 0000000000..d2276ce333
--- /dev/null
+++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooNoTypeTag[T] = {
+ println(implicitly[ConcreteTypeTag[T]])
+ println(implicitly[ConcreteTypeTag[List[T]]])
+ }
+ fooNoTypeTag[Int]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag.check b/test/files/neg/macro-reify-groundtypetag-usetypetag.check
new file mode 100644
index 0000000000..164ca3543f
--- /dev/null
+++ b/test/files/neg/macro-reify-groundtypetag-usetypetag.check
@@ -0,0 +1,7 @@
+Test.scala:5: error: No ConcreteTypeTag available for T
+ println(implicitly[ConcreteTypeTag[T]])
+ ^
+Test.scala:6: error: No ConcreteTypeTag available for List[T]
+ println(implicitly[ConcreteTypeTag[List[T]]])
+ ^
+two errors found
diff --git a/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala
new file mode 100644
index 0000000000..d82cdc33e9
--- /dev/null
+++ b/test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooTypeTag[T: TypeTag] = {
+ println(implicitly[ConcreteTypeTag[T]])
+ println(implicitly[ConcreteTypeTag[List[T]]])
+ }
+ fooTypeTag[Int]
+} \ No newline at end of file
diff --git a/test/files/neg/macro-without-xmacros-a.check b/test/files/neg/macro-without-xmacros-a.check
new file mode 100644
index 0000000000..fd2667dbb8
--- /dev/null
+++ b/test/files/neg/macro-without-xmacros-a.check
@@ -0,0 +1,17 @@
+Macros_2.scala:5: error: macro definition needs to be enabled
+by making the implicit value language.experimental.macros visible.
+This can be achieved by adding the import clause 'import language.experimental.macros'
+or by setting the compiler option -language:experimental.macros.
+See the Scala docs for value scala.language.experimental.macros for a discussion
+why the feature needs to be explicitly enabled.
+ def foo(x: Int): Int = macro foo_impl
+ ^
+Macros_2.scala:7: error: macro definition needs to be enabled
+by making the implicit value language.experimental.macros visible.
+ def bar(x: Int): Int = macro bar_impl
+ ^
+Macros_2.scala:11: error: macro definition needs to be enabled
+by making the implicit value language.experimental.macros visible.
+ def quux(x: Int): Int = macro quux_impl
+ ^
+three errors found
diff --git a/test/files/neg/macro-without-xmacros-a/Impls_1.scala b/test/files/neg/macro-without-xmacros-a/Impls_1.scala
new file mode 100644
index 0000000000..e6cee46e85
--- /dev/null
+++ b/test/files/neg/macro-without-xmacros-a/Impls_1.scala
@@ -0,0 +1,18 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))))
+ }
+
+ def bar_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))))
+ }
+
+ def quux_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))))
+ }
+}
diff --git a/test/files/neg/macro-without-xmacros-a/Macros_2.scala b/test/files/neg/macro-without-xmacros-a/Macros_2.scala
new file mode 100644
index 0000000000..62f9dcf505
--- /dev/null
+++ b/test/files/neg/macro-without-xmacros-a/Macros_2.scala
@@ -0,0 +1,12 @@
+import Impls._
+
+object Macros {
+ object Shmacros {
+ def foo(x: Int): Int = macro foo_impl
+ }
+ def bar(x: Int): Int = macro bar_impl
+}
+
+class Macros {
+ def quux(x: Int): Int = macro quux_impl
+} \ No newline at end of file
diff --git a/test/files/run/macro-basic/Test_2.scala b/test/files/neg/macro-without-xmacros-a/Test_3.scala
index e9a10e20c9..e9a10e20c9 100644
--- a/test/files/run/macro-basic/Test_2.scala
+++ b/test/files/neg/macro-without-xmacros-a/Test_3.scala
diff --git a/test/files/neg/macro-without-xmacros-b.check b/test/files/neg/macro-without-xmacros-b.check
new file mode 100644
index 0000000000..2d675b8319
--- /dev/null
+++ b/test/files/neg/macro-without-xmacros-b.check
@@ -0,0 +1,17 @@
+Macros_2.scala:3: error: macro definition needs to be enabled
+by making the implicit value language.experimental.macros visible.
+This can be achieved by adding the import clause 'import language.experimental.macros'
+or by setting the compiler option -language:experimental.macros.
+See the Scala docs for value scala.language.experimental.macros for a discussion
+why the feature needs to be explicitly enabled.
+ def foo(x: Int): Int = macro Impls.foo_impl
+ ^
+Macros_2.scala:5: error: macro definition needs to be enabled
+by making the implicit value language.experimental.macros visible.
+ def bar(x: Int): Int = macro Impls.bar_impl
+ ^
+Macros_2.scala:9: error: macro definition needs to be enabled
+by making the implicit value language.experimental.macros visible.
+ def quux(x: Int): Int = macro Impls.quux_impl
+ ^
+three errors found
diff --git a/test/files/neg/macro-without-xmacros-b/Impls_1.scala b/test/files/neg/macro-without-xmacros-b/Impls_1.scala
new file mode 100644
index 0000000000..e6cee46e85
--- /dev/null
+++ b/test/files/neg/macro-without-xmacros-b/Impls_1.scala
@@ -0,0 +1,18 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))))
+ }
+
+ def bar_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))))
+ }
+
+ def quux_impl(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3)))))
+ }
+}
diff --git a/test/files/neg/macro-without-xmacros-b/Macros_2.scala b/test/files/neg/macro-without-xmacros-b/Macros_2.scala
new file mode 100644
index 0000000000..de7080c7e8
--- /dev/null
+++ b/test/files/neg/macro-without-xmacros-b/Macros_2.scala
@@ -0,0 +1,10 @@
+object Macros {
+ object Shmacros {
+ def foo(x: Int): Int = macro Impls.foo_impl
+ }
+ def bar(x: Int): Int = macro Impls.bar_impl
+}
+
+class Macros {
+ def quux(x: Int): Int = macro Impls.quux_impl
+} \ No newline at end of file
diff --git a/test/files/neg/macro-without-xmacros-b/Test_3.scala b/test/files/neg/macro-without-xmacros-b/Test_3.scala
new file mode 100644
index 0000000000..e9a10e20c9
--- /dev/null
+++ b/test/files/neg/macro-without-xmacros-b/Test_3.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros.Shmacros._
+ println(foo(2) + Macros.bar(2) * new Macros().quux(4))
+} \ No newline at end of file
diff --git a/test/files/neg/override-object-flag.check b/test/files/neg/override-object-flag.check
index 152d31ff8a..344165138d 100644
--- a/test/files/neg/override-object-flag.check
+++ b/test/files/neg/override-object-flag.check
@@ -1,4 +1,4 @@
-override-object-flag.scala:3: error: overriding object Foo in trait A of type object B.this.Foo;
+override-object-flag.scala:3: error: overriding object Foo in trait A;
object Foo cannot override final member
trait B extends A { override object Foo }
^
diff --git a/test/files/neg/override-object-no.check b/test/files/neg/override-object-no.check
index f9fb37381b..52bad2b937 100644
--- a/test/files/neg/override-object-no.check
+++ b/test/files/neg/override-object-no.check
@@ -10,7 +10,7 @@ an overriding object must conform to the overridden object's class bound;
required: Object{def g: Int}
trait Quux2 extends Quux1 { override object Bar { def g = "abc" } } // err
^
-override-object-no.scala:25: error: overriding object Bar in trait Quux3 of type object Quux4.this.Bar;
+override-object-no.scala:25: error: overriding object Bar in trait Quux3;
object Bar cannot override final member
trait Quux4 extends Quux3 { override object Bar } // err
^
diff --git a/test/files/neg/pat_unreachable.flags b/test/files/neg/pat_unreachable.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/neg/pat_unreachable.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/neg/patmat-type-check.check b/test/files/neg/patmat-type-check.check
index e045841ce1..ab4451f089 100644
--- a/test/files/neg/patmat-type-check.check
+++ b/test/files/neg/patmat-type-check.check
@@ -3,19 +3,31 @@ patmat-type-check.scala:22: error: scrutinee is incompatible with pattern type;
required: String
def f1 = "bob".reverse match { case Seq('b', 'o', 'b') => true } // fail
^
+patmat-type-check.scala:22: error: value _1 is not a member of object Seq
+ def f1 = "bob".reverse match { case Seq('b', 'o', 'b') => true } // fail
+ ^
patmat-type-check.scala:23: error: scrutinee is incompatible with pattern type;
found : Seq[A]
required: Array[Char]
def f2 = "bob".toArray match { case Seq('b', 'o', 'b') => true } // fail
^
+patmat-type-check.scala:23: error: value _1 is not a member of object Seq
+ def f2 = "bob".toArray match { case Seq('b', 'o', 'b') => true } // fail
+ ^
patmat-type-check.scala:27: error: scrutinee is incompatible with pattern type;
found : Seq[A]
required: Test.Bop2
def f3(x: Bop2) = x match { case Seq('b', 'o', 'b') => true } // fail
^
+patmat-type-check.scala:27: error: value _1 is not a member of object Seq
+ def f3(x: Bop2) = x match { case Seq('b', 'o', 'b') => true } // fail
+ ^
patmat-type-check.scala:30: error: scrutinee is incompatible with pattern type;
found : Seq[A]
required: Test.Bop3[Char]
def f4[T](x: Bop3[Char]) = x match { case Seq('b', 'o', 'b') => true } // fail
^
-four errors found
+patmat-type-check.scala:30: error: value _1 is not a member of object Seq
+ def f4[T](x: Bop3[Char]) = x match { case Seq('b', 'o', 'b') => true } // fail
+ ^
+8 errors found
diff --git a/test/files/neg/patmatexhaust.flags b/test/files/neg/patmatexhaust.flags
index e8fb65d50c..b7eb21d5f5 100644
--- a/test/files/neg/patmatexhaust.flags
+++ b/test/files/neg/patmatexhaust.flags
@@ -1 +1 @@
--Xfatal-warnings \ No newline at end of file
+-Xfatal-warnings -Xoldpatmat
diff --git a/test/files/neg/reify_ann2a.check b/test/files/neg/reify_ann2a.check
deleted file mode 100644
index 2afe37e1d8..0000000000
--- a/test/files/neg/reify_ann2a.check
+++ /dev/null
@@ -1,4 +0,0 @@
-reify_ann2a.scala:9: error: exception during macro expansion: implementation restriction: cannot reify annotation @ann(immutable.this.List.apply[String]("1a")) which involves a symbol declared inside the block being reified
- val tree = scala.reflect.Code.lift{
- ^
-one error found
diff --git a/test/files/neg/reify_ann2b.check b/test/files/neg/reify_ann2b.check
index ceb70689f1..b9dd84c1ee 100644
--- a/test/files/neg/reify_ann2b.check
+++ b/test/files/neg/reify_ann2b.check
@@ -1,7 +1,4 @@
-reify_ann2b.scala:10: error: inner classes cannot be classfile annotations
- class ann(bar: String) extends ClassfileAnnotation
- ^
-reify_ann2b.scala:9: error: exception during macro expansion: implementation restriction: cannot reify annotation @ann(bar = "1a") which involves a symbol declared inside the block being reified
- val tree = scala.reflect.Code.lift{
- ^
-two errors found
+reify_ann2b.scala:6: error: inner classes cannot be classfile annotations
+ class ann(bar: String) extends ClassfileAnnotation
+ ^
+one error found
diff --git a/test/files/neg/reify_ann2b.scala b/test/files/neg/reify_ann2b.scala
index b43567c2a7..6b6da8f790 100644
--- a/test/files/neg/reify_ann2b.scala
+++ b/test/files/neg/reify_ann2b.scala
@@ -1,12 +1,8 @@
-import scala.reflect._
-import scala.reflect.api._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
// test 1: reify
- val tree = scala.reflect.Code.lift{
+ val tree = reify{
class ann(bar: String) extends ClassfileAnnotation
@ann(bar="1a") @ann(bar="1b") class C[@ann(bar="2a") @ann(bar="2b") T](@ann(bar="3a") @ann(bar="3b") x: T @ann(bar="4a") @ann(bar="4b")) {
@@ -20,8 +16,7 @@ object Test extends App {
println(tree.toString)
// test 2: import and typecheck
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val ttree = toolbox.typeCheck(tree)
println(ttree.toString)
diff --git a/test/files/neg/saferJavaConversions.check b/test/files/neg/saferJavaConversions.check
new file mode 100644
index 0000000000..0e53d2c437
--- /dev/null
+++ b/test/files/neg/saferJavaConversions.check
@@ -0,0 +1,6 @@
+saferJavaConversions.scala:13: error: type mismatch;
+ found : String("a")
+ required: Foo
+ val v = map.get("a") // now this is a type error
+ ^
+one error found
diff --git a/test/files/neg/saferJavaConversions.scala b/test/files/neg/saferJavaConversions.scala
new file mode 100644
index 0000000000..f0611204e6
--- /dev/null
+++ b/test/files/neg/saferJavaConversions.scala
@@ -0,0 +1,20 @@
+
+case class Foo(s: String)
+
+object Test {
+ def f1 = {
+ import scala.collection.JavaConversions._
+ val map: Map[Foo, String] = Map(Foo("a") -> "a", Foo("b") -> "b")
+ val v = map.get("a") // should be a type error, actually returns null
+ }
+ def f2 = {
+ import scala.collection.convert.wrapAsScala._
+ val map: Map[Foo, String] = Map(Foo("a") -> "a", Foo("b") -> "b")
+ val v = map.get("a") // now this is a type error
+ }
+ def f3 = {
+ import scala.collection.convert.wrapAsJava._
+ val map: Map[Foo, String] = Map(Foo("a") -> "a", Foo("b") -> "b")
+ val v = map.get("a")
+ }
+}
diff --git a/test/files/neg/sealed-java-enums.flags b/test/files/neg/sealed-java-enums.flags
index e709c65918..312f3a87ec 100644
--- a/test/files/neg/sealed-java-enums.flags
+++ b/test/files/neg/sealed-java-enums.flags
@@ -1 +1 @@
--Xexperimental -Xfatal-warnings
+-Xexperimental -Xfatal-warnings -Xoldpatmat
diff --git a/test/files/neg/switch.flags b/test/files/neg/switch.flags
new file mode 100644
index 0000000000..809e9ff2f2
--- /dev/null
+++ b/test/files/neg/switch.flags
@@ -0,0 +1 @@
+ -Xoldpatmat
diff --git a/test/files/neg/t0418.check b/test/files/neg/t0418.check
index 4e9ad2f9ae..50931a1bca 100644
--- a/test/files/neg/t0418.check
+++ b/test/files/neg/t0418.check
@@ -4,4 +4,7 @@ t0418.scala:2: error: not found: value Foo12340771
t0418.scala:2: error: not found: value x
null match { case Foo12340771.Bar(x) => x }
^
-two errors found
+t0418.scala:2: error: Could not typecheck extractor call: case class <none> with arguments List((x @ _))
+ null match { case Foo12340771.Bar(x) => x }
+ ^
+three errors found
diff --git a/test/files/neg/t112706A.check b/test/files/neg/t112706A.check
index 30d0c3ec91..fb18b31be1 100644
--- a/test/files/neg/t112706A.check
+++ b/test/files/neg/t112706A.check
@@ -3,4 +3,7 @@ t112706A.scala:5: error: constructor cannot be instantiated to expected type;
required: String
case Tuple2(node,_) =>
^
-one error found
+t112706A.scala:5: error: Could not typecheck extractor call: case class Tuple2 with arguments List((node @ _), _)
+ case Tuple2(node,_) =>
+ ^
+two errors found
diff --git a/test/files/neg/t1878.check b/test/files/neg/t1878.check
index 128741a022..b47367e12c 100644
--- a/test/files/neg/t1878.check
+++ b/test/files/neg/t1878.check
@@ -9,10 +9,13 @@ t1878.scala:3: error: scrutinee is incompatible with pattern type;
t1878.scala:3: error: not found: value f
val err1 = "" match { case Seq(f @ _*, ',') => f }
^
+t1878.scala:3: error: value _2 is not a member of object Seq
+ val err1 = "" match { case Seq(f @ _*, ',') => f }
+ ^
t1878.scala:9: error: _* may only come last
val List(List(_*, arg2), _) = List(List(1,2,3), List(4,5,6))
^
t1878.scala:13: error: _* may only come last
case <p> { _* } </p> =>
^
-5 errors found
+6 errors found
diff --git a/test/files/neg/t2386.check b/test/files/neg/t2386.check
deleted file mode 100644
index 1a01696a9a..0000000000
--- a/test/files/neg/t2386.check
+++ /dev/null
@@ -1,4 +0,0 @@
-t2386.scala:2: error: could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[Array[_ >: String with Int]]
- val a = Array(Array(1, 2), Array("a","b"))
- ^
-one error found
diff --git a/test/files/neg/t2386.scala b/test/files/neg/t2386.scala
deleted file mode 100644
index 56146cc5c3..0000000000
--- a/test/files/neg/t2386.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-object Test {
- val a = Array(Array(1, 2), Array("a","b"))
-}
diff --git a/test/files/neg/t2775.check b/test/files/neg/t2775.check
index a30d35fdd9..f357221cd9 100644
--- a/test/files/neg/t2775.check
+++ b/test/files/neg/t2775.check
@@ -1,4 +1,4 @@
-t2775.scala:1: error: cannot find class manifest for element type B.this.T
-trait B[S] { type T = S; val c = new Array[T](1) }
- ^
-one error found
+t2775.scala:1: error: cannot find class tag for element type B.this.T
+trait B[S] { type T = S; val c = new Array[T](1) }
+ ^
+one error found
diff --git a/test/files/neg/t3098.flags b/test/files/neg/t3098.flags
index e8fb65d50c..b7eb21d5f5 100644
--- a/test/files/neg/t3098.flags
+++ b/test/files/neg/t3098.flags
@@ -1 +1 @@
--Xfatal-warnings \ No newline at end of file
+-Xfatal-warnings -Xoldpatmat
diff --git a/test/files/neg/t3392.check b/test/files/neg/t3392.check
index 842d63eec9..3a39098c4e 100644
--- a/test/files/neg/t3392.check
+++ b/test/files/neg/t3392.check
@@ -1,4 +1,7 @@
t3392.scala:9: error: not found: value x
case x@A(x/*<-- refers to the pattern that includes this comment*/.Ex(42)) =>
^
-one error found
+t3392.scala:9: error: Could not typecheck extractor call: case class <none> with arguments List(42)
+ case x@A(x/*<-- refers to the pattern that includes this comment*/.Ex(42)) =>
+ ^
+two errors found
diff --git a/test/files/neg/t3507.check b/test/files/neg/t3507-old.check
index 8e538e4a8b..5c58444cb3 100644
--- a/test/files/neg/t3507.check
+++ b/test/files/neg/t3507-old.check
@@ -1,4 +1,4 @@
-t3507.scala:13: error: No Manifest available for _1.b.c.type.
- mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier
- ^
-one error found
+t3507-old.scala:13: error: No Manifest available for _1.b.c.type.
+ mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier
+ ^
+one error found
diff --git a/test/files/neg/t3507.scala b/test/files/neg/t3507-old.scala
index 32688d3934..32688d3934 100644
--- a/test/files/neg/t3507.scala
+++ b/test/files/neg/t3507-old.scala
diff --git a/test/files/neg/t3683a.flags b/test/files/neg/t3683a.flags
index 85d8eb2ba2..b7eb21d5f5 100644
--- a/test/files/neg/t3683a.flags
+++ b/test/files/neg/t3683a.flags
@@ -1 +1 @@
--Xfatal-warnings
+-Xfatal-warnings -Xoldpatmat
diff --git a/test/files/neg/t3692.check b/test/files/neg/t3692-new.check
index 96ddd2a461..e013daca74 100644
--- a/test/files/neg/t3692.check
+++ b/test/files/neg/t3692-new.check
@@ -1,4 +1,4 @@
-t3692.scala:15: error: unreachable code
- case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
- ^
-one error found
+t3692-new.scala:15: error: unreachable code
+ case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
+ ^
+one error found
diff --git a/test/files/neg/t3692-new.flags b/test/files/neg/t3692-new.flags
new file mode 100644
index 0000000000..82becdfbfd
--- /dev/null
+++ b/test/files/neg/t3692-new.flags
@@ -0,0 +1 @@
+ -Xoldpatmat \ No newline at end of file
diff --git a/test/files/neg/t3692-new.scala b/test/files/neg/t3692-new.scala
new file mode 100644
index 0000000000..46874b02e3
--- /dev/null
+++ b/test/files/neg/t3692-new.scala
@@ -0,0 +1,19 @@
+import java.lang.Integer
+
+object Tester {
+ def main(args: Array[String]) = {
+ val map = Map("John" -> 1, "Josh" -> 2)
+ new Tester().toJavaMap(map)
+ }
+}
+
+class Tester {
+ private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: ClassTag[T], m2: ClassTag[V]): java.util.Map[_, _] = {
+ map match {
+ case m0: Map[Int, Int] => new java.util.HashMap[Integer, Integer]
+ case m1: Map[Int, V] => new java.util.HashMap[Integer, V]
+ case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
+ case _ => new java.util.HashMap[T, V]
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/neg/t3692-old.check b/test/files/neg/t3692-old.check
new file mode 100644
index 0000000000..9da7033239
--- /dev/null
+++ b/test/files/neg/t3692-old.check
@@ -0,0 +1,8 @@
+t3692-old.scala:6: warning: object Manifest in package reflect is deprecated: Use `@scala.reflect.ConcreteTypeTag` instead
+ new ManifestTester().toJavaMap(map)
+ ^
+t3692-old.scala:15: error: unreachable code
+ case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
+ ^
+one warning found
+one error found
diff --git a/test/files/neg/t3692-old.flags b/test/files/neg/t3692-old.flags
new file mode 100644
index 0000000000..82becdfbfd
--- /dev/null
+++ b/test/files/neg/t3692-old.flags
@@ -0,0 +1 @@
+ -Xoldpatmat \ No newline at end of file
diff --git a/test/files/neg/t3692.scala b/test/files/neg/t3692-old.scala
index 151535ae94..151535ae94 100644
--- a/test/files/neg/t3692.scala
+++ b/test/files/neg/t3692-old.scala
diff --git a/test/files/neg/t3816.check b/test/files/neg/t3816.check
index 3658e76b64..40621f8962 100644
--- a/test/files/neg/t3816.check
+++ b/test/files/neg/t3816.check
@@ -1,4 +1,4 @@
-t3816.scala:30: error: stable identifier required, but syncID found.
+t3816.scala:30: error: stable identifier required, but `syncID` found.
case Some( `syncID` ) =>
^
t3816.scala:38: error: stable identifier required, but Test.this.foo found.
diff --git a/test/files/neg/t4134.check b/test/files/neg/t4134.check
new file mode 100644
index 0000000000..35a1820b0a
--- /dev/null
+++ b/test/files/neg/t4134.check
@@ -0,0 +1,4 @@
+t4134.scala:22: error: Member method f of mixin trait T2 is missing a concrete super implementation.
+class Konkret extends T3
+ ^
+one error found
diff --git a/test/files/neg/t4134.scala b/test/files/neg/t4134.scala
new file mode 100644
index 0000000000..678e4806ef
--- /dev/null
+++ b/test/files/neg/t4134.scala
@@ -0,0 +1,30 @@
+
+
+
+trait T1 {
+ def f: String
+}
+
+trait T2 extends T1 {
+ abstract override def f: String = "goo"
+ def something = super.f // So the "abstract override" is needed
+}
+
+trait Q1 {
+ def f: String = "bippy"
+}
+
+//trait T3 extends Q1 with T2 {
+trait T3 extends T2 with Q1 {
+ abstract override def f: String = super[Q1].f + " " + super[T2].f + " hoo"
+}
+
+class Konkret extends T3
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val k = new Konkret
+ println(k.f)
+ println(k.something)
+ }
+}
diff --git a/test/files/neg/t418.check b/test/files/neg/t418.check
index 1489547823..c06088ba9d 100644
--- a/test/files/neg/t418.check
+++ b/test/files/neg/t418.check
@@ -4,4 +4,7 @@ t418.scala:2: error: not found: value Foo12340771
t418.scala:2: error: not found: value x
null match { case Foo12340771.Bar(x) => x }
^
-two errors found
+t418.scala:2: error: Could not typecheck extractor call: case class <none> with arguments List((x @ _))
+ null match { case Foo12340771.Bar(x) => x }
+ ^
+three errors found
diff --git a/test/files/neg/t4425.check b/test/files/neg/t4425.check
index 4ff4b1eec0..0f2fe6f2d1 100644
--- a/test/files/neg/t4425.check
+++ b/test/files/neg/t4425.check
@@ -1,4 +1,4 @@
-t4425.scala:3: error: erroneous or inaccessible type
+t4425.scala:3: error: isInstanceOf cannot test if value types are references.
42 match { case _ X _ => () }
^
one error found
diff --git a/test/files/neg/t4515.check b/test/files/neg/t4515.check
index a60d16295f..856d252a0f 100644
--- a/test/files/neg/t4515.check
+++ b/test/files/neg/t4515.check
@@ -1,6 +1,6 @@
t4515.scala:37: error: type mismatch;
- found : _0(in value $anonfun) where type _0(in value $anonfun)
- required: (some other)_0(in value $anonfun)
+ found : _0(in method apply) where type _0(in method apply)
+ required: (some other)_0(in method apply)
handler.onEvent(target, ctx.getEvent, node, ctx)
^
one error found
diff --git a/test/files/neg/t4987.check b/test/files/neg/t4987.check
new file mode 100644
index 0000000000..8d7344d27b
--- /dev/null
+++ b/test/files/neg/t4987.check
@@ -0,0 +1,4 @@
+t4987.scala:2: error: constructor Foo2 in class Foo2 cannot be accessed in object Bar2
+object Bar2 { new Foo2(0, 0) }
+ ^
+one error found
diff --git a/test/files/neg/t4987.scala b/test/files/neg/t4987.scala
new file mode 100644
index 0000000000..e55acd4127
--- /dev/null
+++ b/test/files/neg/t4987.scala
@@ -0,0 +1,2 @@
+class Foo2 private (a: Int, b: Int)
+object Bar2 { new Foo2(0, 0) }
diff --git a/test/files/neg/t5063.check b/test/files/neg/t5063.check
new file mode 100644
index 0000000000..84690d0a1d
--- /dev/null
+++ b/test/files/neg/t5063.check
@@ -0,0 +1,4 @@
+t5063.scala:2: error: value + is not a member of Object
+ super.+("")
+ ^
+one error found
diff --git a/test/files/neg/t5063.scala b/test/files/neg/t5063.scala
new file mode 100644
index 0000000000..5b34b53fb7
--- /dev/null
+++ b/test/files/neg/t5063.scala
@@ -0,0 +1,3 @@
+class A {
+ super.+("")
+}
diff --git a/test/files/neg/t5067.check b/test/files/neg/t5067.check
index 32491766d7..395eda7442 100644
--- a/test/files/neg/t5067.check
+++ b/test/files/neg/t5067.check
@@ -1,6 +1,6 @@
t5067.scala:3: error: type mismatch;
- found : ((Int, Int)) => Int
- required: (Int, Int) => Int
- override def tupled: (Int, Int) => Int = super.tupled
- ^
+ found : ((Int, Int, Int)) => Int
+ required: (Int, Int, Int) => Int
+ override def tupled: (Int, Int, Int) => Int = super.tupled
+ ^
one error found
diff --git a/test/files/neg/t5067.scala b/test/files/neg/t5067.scala
index f8235c0e83..0a961d2f40 100644
--- a/test/files/neg/t5067.scala
+++ b/test/files/neg/t5067.scala
@@ -1,4 +1,4 @@
-class Foo extends Function2[Int, Int, Int] {
- def apply(x: Int, y: Int) = x + y
- override def tupled: (Int, Int) => Int = super.tupled
+class Foo extends Function3[Int, Int, Int, Int] {
+ def apply(x: Int, y: Int, z: Int) = x + y + z
+ override def tupled: (Int, Int, Int) => Int = super.tupled
}
diff --git a/test/files/neg/t5334_1.check b/test/files/neg/t5334_1.check
new file mode 100644
index 0000000000..1d5a7cbc01
--- /dev/null
+++ b/test/files/neg/t5334_1.check
@@ -0,0 +1,4 @@
+t5334_1.scala:4: error: implementation restriction: cannot reify block of type C that involves a type declared inside the block being reified. consider casting the return value to a suitable type
+ reify {
+ ^
+one error found
diff --git a/test/files/neg/t5334_1.scala b/test/files/neg/t5334_1.scala
new file mode 100644
index 0000000000..a7de5a0915
--- /dev/null
+++ b/test/files/neg/t5334_1.scala
@@ -0,0 +1,8 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ reify {
+ class C { override def toString = "C" }
+ new C
+ }.eval
+}
diff --git a/test/files/neg/t5334_2.check b/test/files/neg/t5334_2.check
new file mode 100644
index 0000000000..a62bfff7a5
--- /dev/null
+++ b/test/files/neg/t5334_2.check
@@ -0,0 +1,4 @@
+t5334_2.scala:4: error: implementation restriction: cannot reify block of type List[(C, C)] that involves a type declared inside the block being reified. consider casting the return value to a suitable type
+ reify {
+ ^
+one error found
diff --git a/test/files/neg/t5334_2.scala b/test/files/neg/t5334_2.scala
new file mode 100644
index 0000000000..fc6dfcd0c1
--- /dev/null
+++ b/test/files/neg/t5334_2.scala
@@ -0,0 +1,8 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ reify {
+ class C { override def toString() = "C" }
+ List((new C, new C))
+ }.eval
+}
diff --git a/test/files/neg/t5452-new.check b/test/files/neg/t5452-new.check
new file mode 100644
index 0000000000..bbd3734f74
--- /dev/null
+++ b/test/files/neg/t5452-new.check
@@ -0,0 +1,8 @@
+t5452-new.scala:28: error: overloaded method value apply with alternatives:
+ ()Queryable[CoffeesTable] <and>
+ (t: Tree)(implicit evidence$2: ClassTag[CoffeesTable])Nothing <and>
+ (implicit evidence$1: ClassTag[CoffeesTable])Nothing
+ cannot be applied to (Queryable[CoffeesTable])
+ Queryable[CoffeesTable]( q.treeFilter(null) )
+ ^
+one error found
diff --git a/test/files/neg/t5452-new.scala b/test/files/neg/t5452-new.scala
new file mode 100644
index 0000000000..c829de7d7c
--- /dev/null
+++ b/test/files/neg/t5452-new.scala
@@ -0,0 +1,29 @@
+// /scala/trac/5452/a.scala
+// Mon Feb 13 22:52:36 PST 2012
+
+// import scala.reflect.mirror._
+
+trait Tree
+
+object Bip {
+ def ??? = sys.error("")
+}
+import Bip._
+
+case class Queryable[T]() {
+ def treeFilter( t:Tree ) : Queryable[T] = ???
+}
+
+object Queryable {
+ def apply[T:ClassTag] = ???
+ def apply[T:ClassTag]( t:Tree ) = ???
+}
+
+trait CoffeesTable{
+ def sales : Int
+}
+
+object Test extends App{
+ val q = new Queryable[CoffeesTable]
+ Queryable[CoffeesTable]( q.treeFilter(null) )
+}
diff --git a/test/files/neg/t5452.check b/test/files/neg/t5452-old.check
index 2f35a45509..e5872a5759 100644
--- a/test/files/neg/t5452.check
+++ b/test/files/neg/t5452-old.check
@@ -1,8 +1,8 @@
-t5452.scala:28: error: overloaded method value apply with alternatives:
- ()Queryable[CoffeesTable] <and>
- (t: Tree)(implicit evidence$2: Manifest[CoffeesTable])Nothing <and>
- (implicit evidence$1: Manifest[CoffeesTable])Nothing
- cannot be applied to (Queryable[CoffeesTable])
- Queryable[CoffeesTable]( q.treeFilter(null) )
- ^
-one error found
+t5452-old.scala:28: error: overloaded method value apply with alternatives:
+ ()Queryable[CoffeesTable] <and>
+ (t: Tree)(implicit evidence$2: Manifest[CoffeesTable])Nothing <and>
+ (implicit evidence$1: Manifest[CoffeesTable])Nothing
+ cannot be applied to (Queryable[CoffeesTable])
+ Queryable[CoffeesTable]( q.treeFilter(null) )
+ ^
+one error found
diff --git a/test/files/neg/t5452.scala b/test/files/neg/t5452-old.scala
index 1032db7a4b..1032db7a4b 100644
--- a/test/files/neg/t5452.scala
+++ b/test/files/neg/t5452-old.scala
diff --git a/test/files/neg/t5510.check b/test/files/neg/t5510.check
new file mode 100644
index 0000000000..60da3bed40
--- /dev/null
+++ b/test/files/neg/t5510.check
@@ -0,0 +1,19 @@
+t5510.scala:2: error: unclosed string literal
+ val s1 = s"xxx
+ ^
+t5510.scala:3: error: unclosed string literal
+ val s2 = s"xxx $x
+ ^
+t5510.scala:4: error: unclosed string literal
+ val s3 = s"xxx $$
+ ^
+t5510.scala:5: error: unclosed string literal
+ val s4 = ""s"
+ ^
+t5510.scala:6: error: unclosed multi-line string literal
+ val s5 = ""s""" $s1 $s2 s"
+ ^
+t5510.scala:7: error: '}' expected but eof found.
+}
+ ^
+6 errors found
diff --git a/test/files/neg/t5510.scala b/test/files/neg/t5510.scala
new file mode 100644
index 0000000000..12630eb2cd
--- /dev/null
+++ b/test/files/neg/t5510.scala
@@ -0,0 +1,7 @@
+object Test {
+ val s1 = s"xxx
+ val s2 = s"xxx $x
+ val s3 = s"xxx $$
+ val s4 = ""s"
+ val s5 = ""s""" $s1 $s2 s"
+}
diff --git a/test/files/neg/t5580a.check b/test/files/neg/t5580a.check
new file mode 100644
index 0000000000..50a31857d5
--- /dev/null
+++ b/test/files/neg/t5580a.check
@@ -0,0 +1,6 @@
+t5580a.scala:9: error: polymorphic expression cannot be instantiated to expected type;
+ found : [A]scala.collection.mutable.Set[A]
+ required: scala.collection.mutable.Map[bar,scala.collection.mutable.Set[bar]]
+ if (map.get(tmp).isEmpty) map.put(tmp,collection.mutable.Set())
+ ^
+one error found
diff --git a/test/files/neg/t5580a.scala b/test/files/neg/t5580a.scala
new file mode 100644
index 0000000000..742f0e85ea
--- /dev/null
+++ b/test/files/neg/t5580a.scala
@@ -0,0 +1,11 @@
+import scala.collection.mutable.WeakHashMap
+
+class bar{ }
+class foo{
+ val map = WeakHashMap[AnyRef, collection.mutable.Map[bar, collection.mutable.Set[bar]]]()
+
+ def test={
+ val tmp:bar=null
+ if (map.get(tmp).isEmpty) map.put(tmp,collection.mutable.Set())
+ }
+}
diff --git a/test/files/neg/t5589neg.check b/test/files/neg/t5589neg.check
index b3ff16d7e4..fb6858a397 100644
--- a/test/files/neg/t5589neg.check
+++ b/test/files/neg/t5589neg.check
@@ -22,6 +22,9 @@ t5589neg.scala:4: error: constructor cannot be instantiated to expected type;
t5589neg.scala:4: error: not found: value y2
def f7(x: Either[Int, (String, Int)]) = for (y1 @ Tuple1(y2) <- x.right) yield ((y1, y2))
^
+t5589neg.scala:4: error: Could not typecheck extractor call: case class Tuple1 with arguments List((y2 @ _))
+ def f7(x: Either[Int, (String, Int)]) = for (y1 @ Tuple1(y2) <- x.right) yield ((y1, y2))
+ ^
t5589neg.scala:5: error: constructor cannot be instantiated to expected type;
found : (T1, T2, T3)
required: (String, Int)
@@ -34,4 +37,4 @@ t5589neg.scala:5: error: not found: value y2
def f8(x: Either[Int, (String, Int)]) = for ((y1, y2, y3) <- x.right) yield ((y1, y2))
^
two warnings found
-7 errors found
+8 errors found
diff --git a/test/files/neg/t5663-badwarneq.check b/test/files/neg/t5663-badwarneq.check
new file mode 100644
index 0000000000..00c2234e9d
--- /dev/null
+++ b/test/files/neg/t5663-badwarneq.check
@@ -0,0 +1,22 @@
+t5663-badwarneq.scala:42: error: comparing case class values of types Some[Int] and None.type using `==' will always yield false
+ println(new Some(1) == None) // Should complain on type, was: spuriously complains on fresh object
+ ^
+t5663-badwarneq.scala:43: error: comparing case class values of types Some[Int] and Thing using `==' will always yield false
+ println(Some(1) == new Thing(1)) // Should complain on type, was: spuriously complains on fresh object
+ ^
+t5663-badwarneq.scala:51: error: ThingOne and Thingy are unrelated: they will most likely never compare equal
+ println(t1 == t2) // true, but apparently unrelated, a compromise warning
+ ^
+t5663-badwarneq.scala:52: error: ThingThree and Thingy are unrelated: they will most likely never compare equal
+ println(t4 == t2) // true, complains because ThingThree is final and Thingy not a subclass, stronger claim than unrelated
+ ^
+t5663-badwarneq.scala:55: error: comparing case class values of types ThingTwo and Some[Int] using `==' will always yield false
+ println(t3 == Some(1)) // false, warn on different cases
+ ^
+t5663-badwarneq.scala:56: error: comparing values of types ThingOne and Cousin using `==' will always yield false
+ println(t1 == c) // should warn
+ ^
+t5663-badwarneq.scala:64: error: comparing case class values of types Simple and SimpleSibling.type using `==' will always yield false
+ println(new Simple() == SimpleSibling) // like Some(1) == None, but needn't be final case
+ ^
+7 errors found
diff --git a/test/files/neg/t5663-badwarneq.flags b/test/files/neg/t5663-badwarneq.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/t5663-badwarneq.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/t5663-badwarneq.scala b/test/files/neg/t5663-badwarneq.scala
new file mode 100644
index 0000000000..56ec389c03
--- /dev/null
+++ b/test/files/neg/t5663-badwarneq.scala
@@ -0,0 +1,76 @@
+
+// alias
+trait Thingy
+
+class Gramps
+
+// sibling classes that extend a case class
+case class Thing(i: Int) extends Gramps
+class ThingOne(x:Int) extends Thing(x)
+class ThingTwo(y:Int) extends Thing(y) with Thingy
+final class ThingThree(z:Int) extends Thing(z)
+
+// not case cousin
+class Cousin extends Gramps
+
+class SimpleParent
+case class Simple() extends SimpleParent
+case object SimpleSibling extends SimpleParent
+
+/* It's not possible to run partest without -deprecation.
+ * Since detecting the warnings requires a neg test with
+ * -Xfatal-warnings, and deprecation terminates the compile,
+ * we'll just comment out the nasty part. The point was
+ * just to show there's nothing special about a trait
+ * that extends a case class, which is only permitted
+ * (deprecatingly) by omitting the parens.
+ *
+// common ancestor is something else
+class AnyThing
+case class SomeThing extends AnyThing // deprecation
+class OtherThing extends AnyThing
+
+// how you inherit caseness doesn't matter
+trait InThing extends SomeThing
+class MyThing extends InThing
+*/
+
+object Test {
+ def main(a: Array[String]) {
+ // nothing to do with Gavin
+ println(new Some(1) == new Some(1)) // OK, true
+ println(new Some(1) == None) // Should complain on type, was: spuriously complains on fresh object
+ println(Some(1) == new Thing(1)) // Should complain on type, was: spuriously complains on fresh object
+
+ val t1 = new ThingOne(11)
+ val t2: Thingy = new ThingTwo(11)
+ val t3 = new ThingTwo(11)
+ val t4 = new ThingThree(11)
+ val c = new Cousin
+
+ println(t1 == t2) // true, but apparently unrelated, a compromise warning
+ println(t4 == t2) // true, complains because ThingThree is final and Thingy not a subclass, stronger claim than unrelated
+ println(t2 == t3) // OK, two Thingy
+ println(t3 == t2) // ditto with case receiver
+ println(t3 == Some(1)) // false, warn on different cases
+ println(t1 == c) // should warn
+
+ // don't warn on fresh cases
+ println(new ThingOne(11) == t1) // OK, was: two cases not warnable on trunk
+ println(new ThingTwo(11) == t2) // true, was: spuriously complains on fresh object
+ println(new ThingOne(11) == t3) // two cases not warnable on trunk
+ println(new ThingTwo(11) == t3) // ditto
+
+ println(new Simple() == SimpleSibling) // like Some(1) == None, but needn't be final case
+
+ /*
+ val mine = new MyThing
+ val some = new SomeThing
+ val other = new OtherThing
+ println(mine == some) // OK, two Something
+ println(some == mine)
+ println(mine == other) // OK, two Anything?
+ println(mine == t1) // false
+ */
+ }
+}
diff --git a/test/files/neg/t5666.check b/test/files/neg/t5666.check
new file mode 100644
index 0000000000..2b8b9077bb
--- /dev/null
+++ b/test/files/neg/t5666.check
@@ -0,0 +1,10 @@
+t5666.scala:2: error: class Any is abstract; cannot be instantiated
+ new Any
+ ^
+t5666.scala:3: error: class AnyVal is abstract; cannot be instantiated
+ new AnyVal
+ ^
+t5666.scala:13: error: class Nothing is abstract; cannot be instantiated
+ new Nothing
+ ^
+three errors found
diff --git a/test/files/neg/t5666.scala b/test/files/neg/t5666.scala
new file mode 100644
index 0000000000..ffaeaacdaf
--- /dev/null
+++ b/test/files/neg/t5666.scala
@@ -0,0 +1,14 @@
+object t5666 {
+ new Any
+ new AnyVal
+ new Double
+ new Float
+ new Long
+ new Int
+ new Char
+ new Short
+ new Byte
+ new Boolean
+ new Unit
+ new Nothing
+} \ No newline at end of file
diff --git a/test/files/neg/t5689.check b/test/files/neg/t5689.check
new file mode 100644
index 0000000000..6abc4c13f6
--- /dev/null
+++ b/test/files/neg/t5689.check
@@ -0,0 +1,7 @@
+t5689.scala:4: error: macro implementation has wrong shape:
+ required: (c: scala.reflect.makro.Context)(i: c.Expr[Double]): c.Expr[String]
+ found : (c: scala.reflect.makro.Context)(i: c.Expr[Double]): c.Expr[Int]
+type mismatch for return type: c.Expr[Int] does not conform to c.Expr[String]
+ def returnsString(i: Double): String = macro returnsIntImpl
+ ^
+one error found
diff --git a/test/files/neg/t5689.flags b/test/files/neg/t5689.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/t5689.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/t5689.scala b/test/files/neg/t5689.scala
new file mode 100644
index 0000000000..ef7a45b364
--- /dev/null
+++ b/test/files/neg/t5689.scala
@@ -0,0 +1,6 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def returnsString(i: Double): String = macro returnsIntImpl
+ def returnsIntImpl(c: Context)(i: c.Expr[Double]): c.Expr[Int] = ???
+}
diff --git a/test/files/neg/t961.check b/test/files/neg/t961.check
index 48273f764d..14d39b0f42 100644
--- a/test/files/neg/t961.check
+++ b/test/files/neg/t961.check
@@ -1,4 +1,4 @@
-t961.scala:11: error: object Temp.B does not take parameters
+t961.scala:11: error: Temp.B.type does not take parameters
B() match {
^
one error found
diff --git a/test/files/neg/tailrec.check b/test/files/neg/tailrec.check
index ad92731b2c..946d3421e6 100644
--- a/test/files/neg/tailrec.check
+++ b/test/files/neg/tailrec.check
@@ -4,9 +4,9 @@ tailrec.scala:45: error: could not optimize @tailrec annotated method facfail: i
tailrec.scala:50: error: could not optimize @tailrec annotated method fail1: it is neither private nor final so can be overridden
@tailrec def fail1(x: Int): Int = fail1(x)
^
-tailrec.scala:55: error: could not optimize @tailrec annotated method fail2: it contains a recursive call not in tail position
- case x :: xs => x :: fail2[T](xs)
- ^
+tailrec.scala:53: error: could not optimize @tailrec annotated method fail2: it contains a recursive call not in tail position
+ @tailrec final def fail2[T](xs: List[T]): List[T] = xs match {
+ ^
tailrec.scala:59: error: could not optimize @tailrec annotated method fail3: it is called recursively with different type arguments
@tailrec final def fail3[T](x: Int): Int = fail3(x - 1)
^
diff --git a/test/files/neg/unreachablechar.flags b/test/files/neg/unreachablechar.flags
new file mode 100644
index 0000000000..809e9ff2f2
--- /dev/null
+++ b/test/files/neg/unreachablechar.flags
@@ -0,0 +1 @@
+ -Xoldpatmat
diff --git a/test/files/neg/valueclasses.check b/test/files/neg/valueclasses.check
index 756a0474fa..4f042faded 100644
--- a/test/files/neg/valueclasses.check
+++ b/test/files/neg/valueclasses.check
@@ -40,7 +40,4 @@ class V12[@specialized T, U](val x: (T, U)) extends AnyVal // fail
valueclasses.scala:31: error: value class needs to have exactly one public val parameter
class V13(x: Int) extends AnyVal // fail
^
-valueclasses.scala:45: error: value class must have public primary constructor
-final class TOD private (val secondsOfDay: Int) extends AnyVal { // should fail with private constructor
- ^
-15 errors found
+14 errors found
diff --git a/test/files/neg/valueclasses.scala b/test/files/neg/valueclasses.scala
index e405d95489..7cac94ab11 100644
--- a/test/files/neg/valueclasses.scala
+++ b/test/files/neg/valueclasses.scala
@@ -29,26 +29,3 @@ class V11[T](val x: List[T]) extends AnyVal // ok
class V12[@specialized T, U](val x: (T, U)) extends AnyVal // fail
class V13(x: Int) extends AnyVal // fail
-
-
-package time {
-
-object TOD {
- final val SecondsPerDay = 86400
-
- def apply(seconds: Int) = {
- val n = seconds % SecondsPerDay
- new TOD(if (n >= 0) n else n + SecondsPerDay)
- }
-}
-
-final class TOD private (val secondsOfDay: Int) extends AnyVal { // should fail with private constructor
- def hours = secondsOfDay / 3600
- def minutes = (secondsOfDay / 60) % 60
- def seconds = secondsOfDay % 60
-
- override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
-}
-}
-
-
diff --git a/test/files/neg/variances.check b/test/files/neg/variances.check
index dc72b05e1e..0643e533b7 100644
--- a/test/files/neg/variances.check
+++ b/test/files/neg/variances.check
@@ -1,16 +1,19 @@
variances.scala:4: error: covariant type A occurs in contravariant position in type test.Vector[A] of value x
- def append(x: Vector[A]): Vector[A]
+ def append(x: Vector[A]): Vector[A]
^
-variances.scala:14: error: covariant type A occurs in contravariant position in type A of value a
- private[this] def setA(a : A) = this.a = a
- ^
-variances.scala:16: error: covariant type A occurs in invariant position in supertype test.C[A] of object Baz
+variances.scala:18: error: covariant type A occurs in contravariant position in type A of value a
+ private def setA3(a : A) = this.a = a
+ ^
+variances.scala:19: error: covariant type A occurs in contravariant position in type A of value a
+ protected def setA4(a : A) = this.a = a
+ ^
+variances.scala:21: error: covariant type A occurs in invariant position in supertype test.C[A] of object Baz
object Baz extends C[A]
^
-variances.scala:63: error: covariant type A occurs in contravariant position in type => test.Covariant.T[A]{val m: A => A} of value x
+variances.scala:74: error: covariant type A occurs in contravariant position in type => test.Covariant.T[A]{val m: A => A} of value x
val x: T[A] {
^
-variances.scala:79: error: covariant type T occurs in contravariant position in type => test.TestAlias.B[C.this.A] of method foo
+variances.scala:90: error: covariant type T occurs in contravariant position in type => test.TestAlias.B[C.this.A] of method foo
def foo: B[A]
^
-5 errors found
+6 errors found
diff --git a/test/files/neg/variances.scala b/test/files/neg/variances.scala
index 726bc35270..10ca111cd0 100644
--- a/test/files/neg/variances.scala
+++ b/test/files/neg/variances.scala
@@ -1,7 +1,7 @@
package test
trait Vector[+A] {
- def append(x: Vector[A]): Vector[A]
+ def append(x: Vector[A]): Vector[A]
private[this] def append3(x: Vector[A]): Vector[A] = append(x)
}
@@ -11,19 +11,27 @@ object Covariant {
class Foo[+A] {
private[this] var a : A = _
def getA : A = a
- private[this] def setA(a : A) = this.a = a
-
+ // allowed
+ private[this] def setA1(a : A) = this.a = a
+ protected[this] def setA2(a : A) = this.a = a
+ // forbidden
+ private def setA3(a : A) = this.a = a
+ protected def setA4(a : A) = this.a = a
+
object Baz extends C[A]
trait Convert[B] {
def b2a(b : B) : A
- def doit(b : B) = setA(b2a(b))
+ def doit1(b : B) = setA1(b2a(b))
+ def doit2(b : B) = setA2(b2a(b))
+ def doit3(b : B) = setA3(b2a(b))
+ def doit4(b : B) = setA4(b2a(b))
}
}
class Foo2[+A] {
private[this] var a : A = _
def getA : A = a
- private[this] def setA(a : A) = this.a = a
-
+ private[this] def setA(a : A) = this.a = a
+
{
trait Convert[B] {
def b2a(b : B) : A
@@ -35,8 +43,8 @@ object Covariant {
class Foo3[+A] {
private[this] var a : A = _
def getA : A = a
- private[this] def setA(a : A) = this.a = a
-
+ private[this] def setA(a : A) = this.a = a
+
private[this] trait Convert[B] {
def b2a(b : B) : A
def doit(b : B) = setA(b2a(b))
@@ -54,7 +62,10 @@ object Covariant {
}
def main(args : Array[String]) {
val test = new Test
- test.c.doit(test.b)
+ test.c.doit1(test.b)
+ test.c.doit2(test.b)
+ test.c.doit3(test.b)
+ test.c.doit4(test.b)
val x : java.lang.Character = test.a.getA
Console.println("XXX " + x)
}
diff --git a/test/files/pos/contextbounds-implicits-new.scala b/test/files/pos/contextbounds-implicits-new.scala
new file mode 100644
index 0000000000..71b3cca36f
--- /dev/null
+++ b/test/files/pos/contextbounds-implicits-new.scala
@@ -0,0 +1,8 @@
+/* Tests implicit parameters in the presence of context bounds.
+ * See Section 7.4 of the Scala Language Specification.
+ */
+class C {
+
+ def f[T: TypeTag, S: TypeTag](x: T, y: S)(implicit p: C) { }
+
+}
diff --git a/test/files/pos/contextbounds-implicits.scala b/test/files/pos/contextbounds-implicits-old.scala
index f9113ee320..f9113ee320 100644
--- a/test/files/pos/contextbounds-implicits.scala
+++ b/test/files/pos/contextbounds-implicits-old.scala
diff --git a/test/files/pos/generic-sigs.scala b/test/files/pos/generic-sigs.scala
index 40ec044656..b112766056 100644
--- a/test/files/pos/generic-sigs.scala
+++ b/test/files/pos/generic-sigs.scala
@@ -1,3 +1,5 @@
+import language.existentials
+
object A {
def f1 = List(classOf[Int], classOf[String])
def f2 = List(classOf[String], classOf[Int])
@@ -15,4 +17,4 @@ object A {
class Boppy[+T1,-T2]
def g1 = new Boppy[t forSome { type t <: Int }, u forSome { type u <: String }]
-} \ No newline at end of file
+}
diff --git a/test/files/pos/hkarray.flags b/test/files/pos/hkarray.flags
index e8fb65d50c..e745d8bbe3 100644
--- a/test/files/pos/hkarray.flags
+++ b/test/files/pos/hkarray.flags
@@ -1 +1 @@
--Xfatal-warnings \ No newline at end of file
+-Xfatal-warnings -language:higherKinds \ No newline at end of file
diff --git a/test/files/pos/implicits-new.scala b/test/files/pos/implicits-new.scala
new file mode 100644
index 0000000000..7eb7e100c3
--- /dev/null
+++ b/test/files/pos/implicits-new.scala
@@ -0,0 +1,89 @@
+// #1435
+object t1435 {
+ implicit def a(s:String):String = error("")
+ implicit def a(i:Int):String = error("")
+ implicit def b(i:Int):String = error("")
+}
+
+class C1435 {
+ val v:String = {
+ import t1435.a
+ 2
+ }
+}
+
+// #1492
+class C1492 {
+
+ class X
+
+ def foo(x: X => X) {}
+
+ foo ( implicit x => implicitly[X] )
+ foo { implicit x => implicitly[X] }
+}
+
+// #1579
+object Test1579 {
+ class Column
+ class Query[E](val value: E)
+ class Invoker(q: Any) { val foo = null }
+
+ implicit def unwrap[C](q: Query[C]) = q.value
+ implicit def invoker(q: Query[Column]) = new Invoker(q)
+
+ val q = new Query(new Column)
+ q.foo
+}
+// #1625
+object Test1625 {
+
+ class Wrapped(x:Any) {
+ def unwrap() = x
+ }
+
+ implicit def byName[A](x: =>A) = new Wrapped(x)
+
+ implicit def byVal[A](x: A) = x
+
+ def main(args: Array[String]) = {
+
+// val res:Wrapped = 7 // works
+
+ val res = 7.unwrap() // doesn't work
+
+ println("=> result: " + res)
+ }
+}
+
+object Test2188 {
+ implicit def toJavaList[A: ArrayTag](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*)
+
+ val x: java.util.List[String] = List("foo")
+}
+
+object TestNumericWidening {
+ val y = 1
+ val x: java.lang.Long = y
+}
+
+// #2709
+package foo2709 {
+ class A
+ class B
+
+ package object bar {
+ implicit def a2b(a: A): B = new B
+ }
+
+ package bar {
+ object test {
+ new A: B
+ }
+ }
+}
+
+// Problem with specs
+object specsProblem {
+ println(implicitly[ConcreteTypeTag[Class[_]]])
+}
diff --git a/test/files/pos/implicits.scala b/test/files/pos/implicits-old.scala
index 2c01dd0ba8..2c01dd0ba8 100644
--- a/test/files/pos/implicits.scala
+++ b/test/files/pos/implicits-old.scala
diff --git a/test/files/pos/liftcode_polymorphic.scala b/test/files/pos/liftcode_polymorphic.scala
index 3d4b159c83..9c59b34bee 100644
--- a/test/files/pos/liftcode_polymorphic.scala
+++ b/test/files/pos/liftcode_polymorphic.scala
@@ -1,3 +1,5 @@
+import scala.reflect.mirror._
+
object Append extends Application {
def append[A](l1: List[A], l2: List[A]):List[A] =
@@ -6,6 +8,6 @@ object Append extends Application {
case x::xs => x :: append(xs, l2)
}
- println(scala.reflect.Code.lift(append _).tree)
+ println(reify(append _).tree)
}
diff --git a/test/files/pos/macro-deprecate-dont-touch-backquotedidents.flags b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala
new file mode 100644
index 0000000000..69a7333011
--- /dev/null
+++ b/test/files/pos/macro-deprecate-dont-touch-backquotedidents.scala
@@ -0,0 +1,56 @@
+object Test1 {
+ val `macro` = ???
+}
+
+object Test2 {
+ var `macro` = ???
+}
+
+object Test3 {
+ type `macro` = Int
+}
+
+package test4 {
+ class `macro`
+}
+
+object Test5 {
+ class `macro`
+}
+
+package test6 {
+ object `macro`
+}
+
+object Test7 {
+ object `macro`
+}
+
+package test8 {
+ trait `macro`
+}
+
+object Test9 {
+ trait `macro`
+}
+
+package `macro` {
+ package `macro`.bar {
+ }
+}
+
+package foo {
+ package `macro`.foo {
+ }
+}
+
+//object Test12 {
+// val Some(`macro`) = Some(42)
+// `macro` match {
+// case `macro` => println(`macro`)
+// }
+//}
+
+object Test13 {
+ def `macro` = 2
+} \ No newline at end of file
diff --git a/test/files/pos/macros.scala b/test/files/pos/macros.scala
deleted file mode 100644
index 303610d464..0000000000
--- a/test/files/pos/macros.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-object Test {
-
- class C {
- def macro foo[T](xs: List[T]): T = (T, xs) match {
- case (t1: Type, t2: Tree) => t2
- }
- }
-}
diff --git a/test/files/pos/manifest1-new.scala b/test/files/pos/manifest1-new.scala
new file mode 100644
index 0000000000..645bd42665
--- /dev/null
+++ b/test/files/pos/manifest1-new.scala
@@ -0,0 +1,21 @@
+import scala.reflect.TypeTag
+
+object Test {
+ def foo[T](x: T)(implicit m: TypeTag[T]) {
+ foo(List(x))
+ }
+ foo(1)
+ foo("abc")
+ foo(List(1, 2, 3))
+ val x: List[Int] with Ordered[List[Int]] = null
+ foo(x)
+ foo[x.type](x)
+ abstract class C { type T = String; val x: T }
+ val c = new C { val x = "abc" }
+ foo(c.x)
+ abstract class D { type T; implicit val m: TypeTag[T]; val x: T }
+ val stringm = implicitly[TypeTag[String]]
+ val d: D = new D { type T = String; val m = stringm; val x = "x" }
+ import d.m
+ foo(d.x)
+}
diff --git a/test/files/pos/manifest1.scala b/test/files/pos/manifest1-old.scala
index 8901aa7437..8901aa7437 100644
--- a/test/files/pos/manifest1.scala
+++ b/test/files/pos/manifest1-old.scala
diff --git a/test/files/pos/nothing_manifest_disambig-new.scala b/test/files/pos/nothing_manifest_disambig-new.scala
new file mode 100644
index 0000000000..a60b0fdbf8
--- /dev/null
+++ b/test/files/pos/nothing_manifest_disambig-new.scala
@@ -0,0 +1,10 @@
+object Test {
+ def mani[T: TypeTag](xs: T) = xs
+ mani(List())
+
+ def listElMani[T: TypeTag](xs: List[T]) = xs
+ listElMani(List())
+
+ def foo[A, C](m : C)(implicit ev: C <:< Traversable[A], mani: TypeTag[A]): (C, A, TypeTag[A]) = (m, m.head, mani)
+ foo(List(1,2,3))
+} \ No newline at end of file
diff --git a/test/files/pos/nothing_manifest_disambig.scala b/test/files/pos/nothing_manifest_disambig-old.scala
index 076742033f..076742033f 100644
--- a/test/files/pos/nothing_manifest_disambig.scala
+++ b/test/files/pos/nothing_manifest_disambig-old.scala
diff --git a/test/files/pos/spec-constr-new.scala b/test/files/pos/spec-constr-new.scala
new file mode 100644
index 0000000000..7cd02b0680
--- /dev/null
+++ b/test/files/pos/spec-constr-new.scala
@@ -0,0 +1,7 @@
+class SparseArray2[@specialized(Int) T:ArrayTag](val maxSize: Int, initialLength:Int = 3) {
+ private var data = new Array[T](initialLength);
+ private var index = new Array[Int](initialLength);
+
+ // comment out to compile correctly
+ data.length + 3;
+}
diff --git a/test/files/pos/spec-constr.scala b/test/files/pos/spec-constr-old.scala
index e908b65a41..e908b65a41 100644
--- a/test/files/pos/spec-constr.scala
+++ b/test/files/pos/spec-constr-old.scala
diff --git a/test/files/pos/spec-doubledef-new.scala b/test/files/pos/spec-doubledef-new.scala
new file mode 100644
index 0000000000..33f1e82b6e
--- /dev/null
+++ b/test/files/pos/spec-doubledef-new.scala
@@ -0,0 +1,28 @@
+object Test {
+ def fn[@specialized T, @specialized U](t : T => Int, u : U => Int) : T =
+ null.asInstanceOf[T]
+}
+
+trait A[@specialized(Int) T] {
+ var value: T
+ def getWith[@specialized(Int) Z](f: T => Z) = f(value)
+}
+
+class C extends A[Int] {
+ var value = 10
+ override def getWith[@specialized(Int) Z](f: Int => Z) = f(value)
+}
+
+abstract class B[T, @specialized(scala.Int) U : TypeTag, @specialized(scala.Int) V <% Ordered[V]] {
+ val u: U
+ val v: V
+
+ def f(t: T, v2: V): Pair[U, V] = {
+ val m: Array[U] = null
+ if (m.isEmpty) {
+ Pair(u, v)
+ } else {
+ Pair(u, v2)
+ }
+ }
+}
diff --git a/test/files/pos/spec-doubledef.scala b/test/files/pos/spec-doubledef-old.scala
index 86b0d857d3..86b0d857d3 100644
--- a/test/files/pos/spec-doubledef.scala
+++ b/test/files/pos/spec-doubledef-old.scala
diff --git a/test/files/pos/spec-fields-new.scala b/test/files/pos/spec-fields-new.scala
new file mode 100644
index 0000000000..ddd8bd6624
--- /dev/null
+++ b/test/files/pos/spec-fields-new.scala
@@ -0,0 +1,10 @@
+abstract class Foo[@specialized T: ArrayTag, U <: Ordered[U]](x: T, size: Int) {
+ var y: T
+ var z: T = x
+
+ def initialSize = 16
+ val array = new Array[T](initialSize + size)
+
+ def getZ = z
+ def setZ(zz: T) = z = zz
+}
diff --git a/test/files/pos/spec-fields.scala b/test/files/pos/spec-fields-old.scala
index 26a8c4ffbd..26a8c4ffbd 100644
--- a/test/files/pos/spec-fields.scala
+++ b/test/files/pos/spec-fields-old.scala
diff --git a/test/files/pos/spec-params-new.scala b/test/files/pos/spec-params-new.scala
new file mode 100644
index 0000000000..5fe0c82d40
--- /dev/null
+++ b/test/files/pos/spec-params-new.scala
@@ -0,0 +1,32 @@
+class Foo[@specialized A: ArrayTag] {
+
+ // conflicting in bounds, expect a normalized member calling m
+ // and bridge + implementation in specialized subclasses
+ // and overloads here according to specialization on A
+ def m1[@specialized B <: A](x: B, y: A) =
+ goal(x)
+
+ // conflicting, unsolvable, expect a warning
+ def m2[@specialized B <: String](x: B) = x.concat("a")
+
+ // conflicting in bounds, no mention of other spec members
+ // expect an overload here plus implementation in
+ // compatible specialized subclasses
+ def m3[@specialized B >: A](x: B) = ()
+
+ // non-conflicting, expect a normalized overload implementation here
+ def m4[@specialized T, U <: Ordered[T]](x: T, y: U) = ()
+
+ // non-conflicting, expect a normalized overload implementation here
+ def m5[@specialized B](x: B) = x
+
+ // non-conflicting, expect a normalized implementation here
+ // and specialized implementations for all expansions in specialized subclasses
+ def m6[@specialized B](x: B, y: A) =
+ goal(y)
+
+ def goal(x: A) = {
+ val xs = new Array[A](1)
+ xs(0) = x
+ }
+}
diff --git a/test/files/pos/spec-params.scala b/test/files/pos/spec-params-old.scala
index f522512846..f522512846 100644
--- a/test/files/pos/spec-params.scala
+++ b/test/files/pos/spec-params-old.scala
diff --git a/test/files/pos/spec-sparsearray-new.scala b/test/files/pos/spec-sparsearray-new.scala
new file mode 100644
index 0000000000..0659bf7926
--- /dev/null
+++ b/test/files/pos/spec-sparsearray-new.scala
@@ -0,0 +1,24 @@
+import scala.collection.mutable.MapLike
+
+class SparseArray[@specialized(Int) T:ArrayTag] extends collection.mutable.Map[Int,T] with collection.mutable.MapLike[Int,T,SparseArray[T]] {
+ override def get(x: Int) = {
+ val ind = findOffset(x)
+ if(ind < 0) None else Some(error("ignore"))
+ }
+
+ /**
+ * Returns the offset into index and data for the requested vector
+ * index. If the requested index is not found, the return value is
+ * negative and can be converted into an insertion point with -(rv+1).
+ */
+ private def findOffset(i : Int) : Int = {
+ error("impl doesn't matter")
+ }
+
+ override def apply(i : Int) : T = { error("ignore") }
+ override def update(i : Int, value : T) = error("ignore")
+ override def empty = new SparseArray[T]
+ def -=(ind: Int) = error("ignore")
+ def +=(kv: (Int,T)) = error("ignore")
+ override final def iterator = error("ignore")
+}
diff --git a/test/files/pos/spec-sparsearray.scala b/test/files/pos/spec-sparsearray-old.scala
index ea7710a785..ea7710a785 100644
--- a/test/files/pos/spec-sparsearray.scala
+++ b/test/files/pos/spec-sparsearray-old.scala
diff --git a/test/files/pos/t1381-new.scala b/test/files/pos/t1381-new.scala
new file mode 100644
index 0000000000..8781ef4fdb
--- /dev/null
+++ b/test/files/pos/t1381-new.scala
@@ -0,0 +1,31 @@
+import scala.reflect.TypeTag
+
+class D[V <: Variable]
+
+class ID[V<:IV] extends D[V] {
+ type E = V#ValueType
+ def index(value:E) : Int = 0
+ // Comment this out to eliminate crash. Or see below
+ def index(values:E*) : Iterable[Int] = null
+}
+
+abstract class Variable {
+ type VT <: Variable
+ def d : D[VT] = null
+}
+
+abstract class PV[T](initval:T) extends Variable {
+ type VT <: PV[T]
+ type ValueType = T
+}
+
+trait IV extends Variable {
+ type ValueType
+}
+
+abstract class EV[T](initval:T) extends PV[T](initval) with IV {
+ type VT <: EV[T]
+ override def d : ID[VT] = null
+ // Comment this out to eliminate crash
+ protected var indx = d.index(initval)
+}
diff --git a/test/files/pos/t1381.scala b/test/files/pos/t1381-old.scala
index 0762891898..0762891898 100644
--- a/test/files/pos/t1381.scala
+++ b/test/files/pos/t1381-old.scala
diff --git a/test/files/pos/t1439.flags b/test/files/pos/t1439.flags
index 779916d58f..1e70f5c5c7 100644
--- a/test/files/pos/t1439.flags
+++ b/test/files/pos/t1439.flags
@@ -1 +1 @@
--unchecked -Xfatal-warnings \ No newline at end of file
+-unchecked -Xfatal-warnings -Xoldpatmat -language:higherKinds
diff --git a/test/files/pos/t2795-new.scala b/test/files/pos/t2795-new.scala
new file mode 100644
index 0000000000..af9c4e8b1c
--- /dev/null
+++ b/test/files/pos/t2795-new.scala
@@ -0,0 +1,17 @@
+package t1
+
+trait Element[T] {
+}
+
+trait Config {
+ type T <: Element[T]
+ implicit val m: ArrayTag[T]
+ // XXX Following works fine:
+ // type T <: Element[_]
+}
+
+trait Transform { self: Config =>
+ def processBlock(block: Array[T]): Unit = {
+ var X = new Array[T](1)
+ }
+}
diff --git a/test/files/pos/t2795.scala b/test/files/pos/t2795-old.scala
index 935cb1f444..935cb1f444 100644
--- a/test/files/pos/t2795.scala
+++ b/test/files/pos/t2795-old.scala
diff --git a/test/files/pos/t3272.scala b/test/files/pos/t3272.scala
new file mode 100644
index 0000000000..8efd5ded2c
--- /dev/null
+++ b/test/files/pos/t3272.scala
@@ -0,0 +1,8 @@
+trait A {
+ trait C[+T] {
+ protected[this] def f(t: T) {}
+ }
+ trait D[T] extends C[T] {
+ def g(t: T) { f(t) }
+ }
+}
diff --git a/test/files/pos/t3363-new.scala b/test/files/pos/t3363-new.scala
new file mode 100644
index 0000000000..270462745c
--- /dev/null
+++ b/test/files/pos/t3363-new.scala
@@ -0,0 +1,18 @@
+object TestCase {
+
+ //now matter if you put (abstract) class or trait it will fail in all cases
+ trait MapOps[T]
+
+ //if fs was reduced to List (generic type with one parameter) then the code compiles
+ //if you inherit from MapOps[T] instead of MapOps[F] then code compiles fine
+ implicit def map2ops[T,F](fs: Map[T,F]) = new MapOps[F] {
+ //if you remove this line, then code compiles
+ lazy val m: TypeTag[T] = error("just something to make it compile")
+ def is(xs: List[T]) = List(xs)
+ }
+
+ def main(args: Array[String]) {
+ println(Map(1 -> "2") is List(2))
+ }
+
+ }
diff --git a/test/files/pos/t3363.scala b/test/files/pos/t3363-old.scala
index bae54084ea..bae54084ea 100755..100644
--- a/test/files/pos/t3363.scala
+++ b/test/files/pos/t3363-old.scala
diff --git a/test/files/pos/t3498-new.scala b/test/files/pos/t3498-new.scala
new file mode 100644
index 0000000000..653c50042a
--- /dev/null
+++ b/test/files/pos/t3498-new.scala
@@ -0,0 +1,15 @@
+abstract class A[T, @specialized(scala.Int) U : ArrayTag] {
+ def f(state: T): Array[U]
+}
+
+abstract class B extends A[ Array[Byte], Int ] {
+ type T = Array[Byte]
+ type U = Int
+
+ val N = 0
+
+ def f(state: T): Array[U] =
+ {
+ new Array[U](N + state(N))
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t3498.scala b/test/files/pos/t3498-old.scala
index bcc90ca64c..bcc90ca64c 100644
--- a/test/files/pos/t3498.scala
+++ b/test/files/pos/t3498-old.scala
diff --git a/test/files/pos/t4545.scala b/test/files/pos/t4545.scala
new file mode 100644
index 0000000000..8c7a3236c4
--- /dev/null
+++ b/test/files/pos/t4545.scala
@@ -0,0 +1,14 @@
+object Test {
+ def f[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T](table: Tuple20[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T])(fun: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) => Unit) {
+ }
+ def g[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U](table: Tuple21[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U])(fun: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) => Unit) {
+ }
+
+ def g20 = f(
+ ( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
+ ) { case ((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t)) => () }
+
+ def g21 = g(
+ (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
+ ) { case ((a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u)) => () }
+}
diff --git a/test/files/pos/t4910.scala b/test/files/pos/t4910.scala
new file mode 100644
index 0000000000..c66fd523f5
--- /dev/null
+++ b/test/files/pos/t4910.scala
@@ -0,0 +1,6 @@
+class A {
+ implicit object foo
+ // it compiles if we uncomment this
+ // implicit val bar = foo
+ implicitly[foo.type]
+}
diff --git a/test/files/pos/t5223.scala b/test/files/pos/t5223.scala
index 51682e9254..398630dc61 100644
--- a/test/files/pos/t5223.scala
+++ b/test/files/pos/t5223.scala
@@ -1,6 +1,6 @@
-import scala.reflect._
+import scala.reflect.mirror._
object Foo extends App {
- Code.lift{def printf(format: String, args: Any*): String = null }
- Code.lift{def printf(format: String, args: Any*): String = ("abc": @cloneable)}
+ reify{def printf(format: String, args: Any*): String = null }
+ reify{def printf(format: String, args: Any*): String = ("abc": @cloneable)}
}
diff --git a/test/files/pos/t531.scala b/test/files/pos/t531.scala
index 856926de4f..5176912ef0 100644
--- a/test/files/pos/t531.scala
+++ b/test/files/pos/t531.scala
@@ -1,8 +1,9 @@
+import scala.reflect.mirror._
+
object Test extends App {
- import scala.reflect._;
def titi = {
var truc = 0
- val tata = Code.lift{() => {
+ val tata = reify{() => {
truc = 6
}}
()
diff --git a/test/files/pos/t532.scala b/test/files/pos/t532.scala
index f864bbf45e..a319fdfa27 100644
--- a/test/files/pos/t532.scala
+++ b/test/files/pos/t532.scala
@@ -1,8 +1,9 @@
+import scala.reflect.mirror._
+
object Test extends App {
- import scala.reflect._;
def titi: Unit = {
var truc = 0
- val tata = Code.lift{() => {
+ val tata = reify{() => {
truc = truc + 6
}}
()
diff --git a/test/files/pos/t5580b.scala b/test/files/pos/t5580b.scala
new file mode 100644
index 0000000000..d5a4a0a2b2
--- /dev/null
+++ b/test/files/pos/t5580b.scala
@@ -0,0 +1,19 @@
+/** It's a pos test because it does indeed compile,
+ * not so much because I'm glad it does. Testing
+ * that error messages created and discarded during
+ * implicit search don't blow it up.
+ */
+
+import scala.collection.mutable.WeakHashMap
+import scala.collection.JavaConversions._
+
+class bar { }
+
+class foo {
+ val map = WeakHashMap[AnyRef, collection.mutable.Map[bar, collection.mutable.Set[bar]]]()
+
+ def test={
+ val tmp:bar=null
+ if (map.get(tmp).isEmpty) map.put(tmp,collection.mutable.Set())
+ }
+}
diff --git a/test/files/pos/t5604/ReplConfig.scala b/test/files/pos/t5604/ReplConfig.scala
new file mode 100644
index 0000000000..8c589eba60
--- /dev/null
+++ b/test/files/pos/t5604/ReplConfig.scala
@@ -0,0 +1,53 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+import util.Exceptional.unwrap
+import util.stackTraceString
+
+trait ReplConfig {
+ lazy val replProps = new ReplProps
+
+ class TapMaker[T](x: T) {
+ def tapInfo(msg: => String): T = tap(x => replinfo(parens(x)))
+ def tapDebug(msg: => String): T = tap(x => repldbg(parens(x)))
+ def tapTrace(msg: => String): T = tap(x => repltrace(parens(x)))
+ def tap[U](f: T => U): T = {
+ f(x)
+ x
+ }
+ }
+
+ private def parens(x: Any) = "(" + x + ")"
+ private def echo(msg: => String) =
+ try Console println msg
+ catch { case x: AssertionError => Console.println("Assertion error printing debugging output: " + x) }
+
+ private[nsc] def repldbg(msg: => String) = if (isReplDebug) echo(msg)
+ private[nsc] def repltrace(msg: => String) = if (isReplTrace) echo(msg)
+ private[nsc] def replinfo(msg: => String) = if (isReplInfo) echo(msg)
+
+ private[nsc] def logAndDiscard[T](label: String, alt: => T): PartialFunction[Throwable, T] = {
+ case t =>
+ repldbg(label + ": " + unwrap(t))
+ repltrace(stackTraceString(unwrap(t)))
+ alt
+ }
+ private[nsc] def substituteAndLog[T](alt: => T)(body: => T): T =
+ substituteAndLog("" + alt, alt)(body)
+ private[nsc] def substituteAndLog[T](label: String, alt: => T)(body: => T): T = {
+ try body
+ catch logAndDiscard(label, alt)
+ }
+ private[nsc] def squashAndLog(label: String)(body: => Unit): Unit =
+ substituteAndLog(label, ())(body)
+
+ def isReplTrace: Boolean = replProps.trace
+ def isReplDebug: Boolean = replProps.debug || isReplTrace
+ def isReplInfo: Boolean = replProps.info || isReplDebug
+ def isReplPower: Boolean = replProps.power
+}
diff --git a/test/files/pos/t5604/ReplReporter.scala b/test/files/pos/t5604/ReplReporter.scala
new file mode 100644
index 0000000000..130af990ad
--- /dev/null
+++ b/test/files/pos/t5604/ReplReporter.scala
@@ -0,0 +1,30 @@
+/* NSC -- new Scala compiler
+ * Copyright 2002-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+import reporters._
+import IMain._
+
+class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.in, new ReplStrippingWriter(intp)) {
+ override def printMessage(msg: String) {
+ // Avoiding deadlock if the compiler starts logging before
+ // the lazy val is complete.
+ if (intp.isInitializeComplete) {
+ if (intp.totalSilence) {
+ if (isReplTrace)
+ super.printMessage("[silent] " + msg)
+ }
+ else super.printMessage(msg)
+ }
+ else Console.println("[init] " + msg)
+ }
+
+ override def displayPrompt() {
+ if (intp.totalSilence) ()
+ else super.displayPrompt()
+ }
+}
diff --git a/test/files/pos/t5644/BoxesRunTime.java b/test/files/pos/t5644/BoxesRunTime.java
new file mode 100644
index 0000000000..241bf79ac8
--- /dev/null
+++ b/test/files/pos/t5644/BoxesRunTime.java
@@ -0,0 +1,836 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala.runtime;
+
+import java.io.*;
+import scala.math.ScalaNumber;
+
+/** An object (static class) that defines methods used for creating,
+ * reverting, and calculating with, boxed values. There are four classes
+ * of methods in this object:
+ * - Convenience boxing methods which call the static valueOf method
+ * on the boxed class, thus utilizing the JVM boxing cache.
+ * - Convenience unboxing methods returning default value on null.
+ * - The generalised comparison method to be used when an object may
+ * be a boxed value.
+ * - Standard value operators for boxed number and quasi-number values.
+ *
+ * @author Gilles Dubochet
+ * @author Martin Odersky
+ * @contributor Stepan Koltsov
+ * @version 2.0 */
+public final class BoxesRunTime
+{
+ private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7;
+
+ /** We don't need to return BYTE and SHORT, as everything which might
+ * care widens to INT.
+ */
+ private static int typeCode(Object a) {
+ if (a instanceof java.lang.Integer) return INT;
+ if (a instanceof java.lang.Double) return DOUBLE;
+ if (a instanceof java.lang.Long) return LONG;
+ if (a instanceof java.lang.Character) return CHAR;
+ if (a instanceof java.lang.Float) return FLOAT;
+ if ((a instanceof java.lang.Byte) || (a instanceof java.lang.Short)) return INT;
+ return OTHER;
+ }
+
+ private static int eqTypeCode(Number a) {
+ int code = typeCode(a);
+ if (code == CHAR)
+ return OTHER;
+ else
+ return code;
+ }
+
+ private static String boxDescription(Object a) {
+ return "" + a.getClass().getSimpleName() + "(" + a + ")";
+ }
+
+/* BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING */
+
+ public static java.lang.Boolean boxToBoolean(boolean b) {
+ return java.lang.Boolean.valueOf(b);
+ }
+
+ public static java.lang.Character boxToCharacter(char c) {
+ return java.lang.Character.valueOf(c);
+ }
+
+ public static java.lang.Byte boxToByte(byte b) {
+ return java.lang.Byte.valueOf(b);
+ }
+
+ public static java.lang.Short boxToShort(short s) {
+ return java.lang.Short.valueOf(s);
+ }
+
+ public static java.lang.Integer boxToInteger(int i) {
+ return java.lang.Integer.valueOf(i);
+ }
+
+ public static java.lang.Long boxToLong(long l) {
+ return java.lang.Long.valueOf(l);
+ }
+
+ public static java.lang.Float boxToFloat(float f) {
+ return java.lang.Float.valueOf(f);
+ }
+
+ public static java.lang.Double boxToDouble(double d) {
+ // System.out.println("box " + d);
+ // (new Throwable()).printStackTrace();
+ return java.lang.Double.valueOf(d);
+ }
+
+/* UNBOXING ... UNBOXING ... UNBOXING ... UNBOXING ... UNBOXING ... UNBOXING ... UNBOXING */
+
+ public static boolean unboxToBoolean(Object b) {
+ return b == null ? false : ((java.lang.Boolean)b).booleanValue();
+ }
+
+ public static char unboxToChar(Object c) {
+ return c == null ? 0 : ((java.lang.Character)c).charValue();
+ }
+
+ public static byte unboxToByte(Object b) {
+ return b == null ? 0 : ((java.lang.Byte)b).byteValue();
+ }
+
+ public static short unboxToShort(Object s) {
+ return s == null ? 0 : ((java.lang.Short)s).shortValue();
+ }
+
+ public static int unboxToInt(Object i) {
+ return i == null ? 0 : ((java.lang.Integer)i).intValue();
+ }
+
+ public static long unboxToLong(Object l) {
+ return l == null ? 0 : ((java.lang.Long)l).longValue();
+ }
+
+ public static float unboxToFloat(Object f) {
+ return f == null ? 0.0f : ((java.lang.Float)f).floatValue();
+ }
+
+ public static double unboxToDouble(Object d) {
+ // System.out.println("unbox " + d);
+ return d == null ? 0.0d : ((java.lang.Double)d).doubleValue();
+ }
+
+ /* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */
+
+ public static boolean equals(Object x, Object y) {
+ if (x == y) return true;
+ return equals2(x, y);
+ }
+
+ /** Since all applicable logic has to be present in the equals method of a ScalaNumber
+ * in any case, we dispatch to it as soon as we spot one on either side.
+ */
+ public static boolean equals2(Object x, Object y) {
+ if (x instanceof java.lang.Number)
+ return equalsNumObject((java.lang.Number)x, y);
+ if (x instanceof java.lang.Character)
+ return equalsCharObject((java.lang.Character)x, y);
+ if (x == null)
+ return y == null;
+
+ return x.equals(y);
+ }
+
+ public static boolean equalsNumObject(java.lang.Number xn, Object y) {
+ if (y instanceof java.lang.Number)
+ return equalsNumNum(xn, (java.lang.Number)y);
+ if (y instanceof java.lang.Character)
+ return equalsNumChar(xn, (java.lang.Character)y);
+ if (xn == null)
+ return y == null;
+
+ return xn.equals(y);
+ }
+
+ public static boolean equalsNumNum(java.lang.Number xn, java.lang.Number yn) {
+ int xcode = eqTypeCode(xn);
+ int ycode = eqTypeCode(yn);
+ switch (ycode > xcode ? ycode : xcode) {
+ case INT:
+ return xn.intValue() == yn.intValue();
+ case LONG:
+ return xn.longValue() == yn.longValue();
+ case FLOAT:
+ return xn.floatValue() == yn.floatValue();
+ case DOUBLE:
+ return xn.doubleValue() == yn.doubleValue();
+ default:
+ if ((yn instanceof ScalaNumber) && !(xn instanceof ScalaNumber))
+ return yn.equals(xn);
+ }
+ if (xn == null)
+ return yn == null;
+
+ return xn.equals(yn);
+ }
+
+ public static boolean equalsCharObject(java.lang.Character xc, Object y) {
+ if (y instanceof java.lang.Character)
+ return xc.charValue() == ((java.lang.Character)y).charValue();
+ if (y instanceof java.lang.Number)
+ return equalsNumChar((java.lang.Number)y, xc);
+ if (xc == null)
+ return y == null;
+
+ return xc.equals(y);
+ }
+
+ private static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) {
+ if (yc == null)
+ return xn == null;
+
+ char ch = yc.charValue();
+ switch (eqTypeCode(xn)) {
+ case INT:
+ return xn.intValue() == ch;
+ case LONG:
+ return xn.longValue() == ch;
+ case FLOAT:
+ return xn.floatValue() == ch;
+ case DOUBLE:
+ return xn.doubleValue() == ch;
+ default:
+ return xn.equals(yc);
+ }
+ }
+
+ /** Hashcode algorithm is driven by the requirements imposed
+ * by primitive equality semantics, namely that equal objects
+ * have equal hashCodes. The first priority are the integral/char
+ * types, which already have the same hashCodes for the same
+ * values except for Long. So Long's hashCode is altered to
+ * conform to Int's for all values in Int's range.
+ *
+ * Float is problematic because it's far too small to hold
+ * all the Ints, so for instance Int.MaxValue.toFloat claims
+ * to be == to each of the largest 64 Ints. There is no way
+ * to preserve equals/hashCode alignment without compromising
+ * the hashCode distribution, so Floats are only guaranteed
+ * to have the same hashCode for whole Floats in the range
+ * Short.MinValue to Short.MaxValue (2^16 total.)
+ *
+ * Double has its hashCode altered to match the entire Int range,
+ * but is not guaranteed beyond that. (But could/should it be?
+ * The hashCode is only 32 bits so this is a more tractable
+ * issue than Float's, but it might be better simply to exclude it.)
+ *
+ * Note: BigInt and BigDecimal, being arbitrary precision, could
+ * be made consistent with all other types for the Int range, but
+ * as yet have not.
+ *
+ * Note: Among primitives, Float.NaN != Float.NaN, but the boxed
+ * verisons are equal. This still needs reconciliation.
+ */
+ public static int hashFromLong(java.lang.Long n) {
+ int iv = n.intValue();
+ if (iv == n.longValue()) return iv;
+ else return n.hashCode();
+ }
+ public static int hashFromDouble(java.lang.Double n) {
+ int iv = n.intValue();
+ double dv = n.doubleValue();
+ if (iv == dv) return iv;
+
+ long lv = n.longValue();
+ if (lv == dv) return java.lang.Long.valueOf(lv).hashCode();
+ else return n.hashCode();
+ }
+ public static int hashFromFloat(java.lang.Float n) {
+ int iv = n.intValue();
+ float fv = n.floatValue();
+ if (iv == fv) return iv;
+
+ long lv = n.longValue();
+ if (lv == fv) return java.lang.Long.valueOf(lv).hashCode();
+ else return n.hashCode();
+ }
+ public static int hashFromNumber(java.lang.Number n) {
+ if (n instanceof java.lang.Long) return hashFromLong((java.lang.Long)n);
+ else if (n instanceof java.lang.Double) return hashFromDouble((java.lang.Double)n);
+ else if (n instanceof java.lang.Float) return hashFromFloat((java.lang.Float)n);
+ else return n.hashCode();
+ }
+ public static int hashFromObject(Object a) {
+ if (a instanceof Number) return hashFromNumber((Number)a);
+ else return a.hashCode();
+ }
+
+ private static int unboxCharOrInt(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).intValue();
+ }
+ private static long unboxCharOrLong(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).longValue();
+ }
+ private static float unboxCharOrFloat(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).floatValue();
+ }
+ private static double unboxCharOrDouble(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).doubleValue();
+ }
+
+/* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */
+
+ /** arg1 + arg2 */
+ public static Object add(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ return boxToInteger(unboxCharOrInt(arg1, code1) + unboxCharOrInt(arg2, code2));
+ }
+ if (maxcode <= LONG) {
+ return boxToLong(unboxCharOrLong(arg1, code1) + unboxCharOrLong(arg2, code2));
+ }
+ if (maxcode <= FLOAT) {
+ return boxToFloat(unboxCharOrFloat(arg1, code1) + unboxCharOrFloat(arg2, code2));
+ }
+ if (maxcode <= DOUBLE) {
+ return boxToDouble(unboxCharOrDouble(arg1, code1) + unboxCharOrDouble(arg2, code2));
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 - arg2 */
+ public static Object subtract(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ return boxToInteger(unboxCharOrInt(arg1, code1) - unboxCharOrInt(arg2, code2));
+ }
+ if (maxcode <= LONG) {
+ return boxToLong(unboxCharOrLong(arg1, code1) - unboxCharOrLong(arg2, code2));
+ }
+ if (maxcode <= FLOAT) {
+ return boxToFloat(unboxCharOrFloat(arg1, code1) - unboxCharOrFloat(arg2, code2));
+ }
+ if (maxcode <= DOUBLE) {
+ return boxToDouble(unboxCharOrDouble(arg1, code1) - unboxCharOrDouble(arg2, code2));
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 * arg2 */
+ public static Object multiply(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ return boxToInteger(unboxCharOrInt(arg1, code1) * unboxCharOrInt(arg2, code2));
+ }
+ if (maxcode <= LONG) {
+ return boxToLong(unboxCharOrLong(arg1, code1) * unboxCharOrLong(arg2, code2));
+ }
+ if (maxcode <= FLOAT) {
+ return boxToFloat(unboxCharOrFloat(arg1, code1) * unboxCharOrFloat(arg2, code2));
+ }
+ if (maxcode <= DOUBLE) {
+ return boxToDouble(unboxCharOrDouble(arg1, code1) * unboxCharOrDouble(arg2, code2));
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 / arg2 */
+ public static Object divide(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) / unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) / unboxCharOrLong(arg2, code2));
+ if (maxcode <= FLOAT)
+ return boxToFloat(unboxCharOrFloat(arg1, code1) / unboxCharOrFloat(arg2, code2));
+ if (maxcode <= DOUBLE)
+ return boxToDouble(unboxCharOrDouble(arg1, code1) / unboxCharOrDouble(arg2, code2));
+
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 % arg2 */
+ public static Object takeModulo(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) % unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) % unboxCharOrLong(arg2, code2));
+ if (maxcode <= FLOAT)
+ return boxToFloat(unboxCharOrFloat(arg1, code1) % unboxCharOrFloat(arg2, code2));
+ if (maxcode <= DOUBLE)
+ return boxToDouble(unboxCharOrDouble(arg1, code1) % unboxCharOrDouble(arg2, code2));
+
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 >> arg2 */
+ public static Object shiftSignedRight(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ if (code1 <= INT) {
+ int val1 = unboxCharOrInt(arg1, code1);
+ if (code2 <= INT) {
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToInteger(val1 >> val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToInteger(val1 >> val2);
+ }
+ }
+ if (code1 <= LONG) {
+ long val1 = unboxCharOrLong(arg1, code1);
+ if (code2 <= INT) {
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToLong(val1 >> val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToLong(val1 >> val2);
+ }
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 << arg2 */
+ public static Object shiftSignedLeft(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ if (code1 <= INT) {
+ int val1 = unboxCharOrInt(arg1, code1);
+ if (code2 <= INT) {
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToInteger(val1 << val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToInteger(val1 << val2);
+ }
+ }
+ if (code1 <= LONG) {
+ long val1 = unboxCharOrLong(arg1, code1);
+ if (code2 <= INT) {
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToLong(val1 << val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToLong(val1 << val2);
+ }
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 >>> arg2 */
+ public static Object shiftLogicalRight(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ if (code1 <= INT) {
+ int val1 = unboxCharOrInt(arg1, code1);
+ if (code2 <= INT) {
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToInteger(val1 >>> val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToInteger(val1 >>> val2);
+ }
+ }
+ if (code1 <= LONG) {
+ long val1 = unboxCharOrLong(arg1, code1);
+ if (code2 <= INT) {
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToLong(val1 >>> val2);
+ }
+ if (code2 <= LONG) {
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToLong(val1 >>> val2);
+ }
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** -arg */
+ public static Object negate(Object arg) throws NoSuchMethodException {
+ int code = typeCode(arg);
+ if (code <= INT) {
+ int val = unboxCharOrInt(arg, code);
+ return boxToInteger(-val);
+ }
+ if (code <= LONG) {
+ long val = unboxCharOrLong(arg, code);
+ return boxToLong(-val);
+ }
+ if (code <= FLOAT) {
+ float val = unboxCharOrFloat(arg, code);
+ return boxToFloat(-val);
+ }
+ if (code <= DOUBLE) {
+ double val = unboxCharOrDouble(arg, code);
+ return boxToDouble(-val);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** +arg */
+ public static Object positive(Object arg) throws NoSuchMethodException {
+ int code = typeCode(arg);
+ if (code <= INT) {
+ return boxToInteger(+unboxCharOrInt(arg, code));
+ }
+ if (code <= LONG) {
+ return boxToLong(+unboxCharOrLong(arg, code));
+ }
+ if (code <= FLOAT) {
+ return boxToFloat(+unboxCharOrFloat(arg, code));
+ }
+ if (code <= DOUBLE) {
+ return boxToDouble(+unboxCharOrDouble(arg, code));
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 & arg2 */
+ public static Object takeAnd(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue());
+ else
+ throw new NoSuchMethodException();
+ }
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) & unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) & unboxCharOrLong(arg2, code2));
+
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 | arg2 */
+ public static Object takeOr(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue());
+ else
+ throw new NoSuchMethodException();
+ }
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) | unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) | unboxCharOrLong(arg2, code2));
+
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 ^ arg2 */
+ public static Object takeXor(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue());
+ else
+ throw new NoSuchMethodException();
+ }
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) ^ unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) ^ unboxCharOrLong(arg2, code2));
+
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 && arg2 */
+ public static Object takeConditionalAnd(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) {
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() && ((java.lang.Boolean) arg2).booleanValue());
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** arg1 || arg2 */
+ public static Object takeConditionalOr(Object arg1, Object arg2) throws NoSuchMethodException {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean)) {
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() || ((java.lang.Boolean) arg2).booleanValue());
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** ~arg */
+ public static Object complement(Object arg) throws NoSuchMethodException {
+ int code = typeCode(arg);
+ if (code <= INT) {
+ return boxToInteger(~unboxCharOrInt(arg, code));
+ }
+ if (code <= LONG) {
+ return boxToLong(~unboxCharOrLong(arg, code));
+ }
+ throw new NoSuchMethodException();
+ }
+
+ /** !arg */
+ public static Object takeNot(Object arg) throws NoSuchMethodException {
+ if (arg instanceof Boolean) {
+ return boxToBoolean(!((java.lang.Boolean) arg).booleanValue());
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static Object testEqual(Object arg1, Object arg2) throws NoSuchMethodException {
+ return boxToBoolean(arg1 == arg2);
+ }
+
+ public static Object testNotEqual(Object arg1, Object arg2) throws NoSuchMethodException {
+ return boxToBoolean(arg1 != arg2);
+ }
+
+ public static Object testLessThan(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToBoolean(val1 < val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToBoolean(val1 < val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
+ return boxToBoolean(val1 < val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
+ return boxToBoolean(val1 < val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static Object testLessOrEqualThan(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToBoolean(val1 <= val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToBoolean(val1 <= val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
+ return boxToBoolean(val1 <= val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
+ return boxToBoolean(val1 <= val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static Object testGreaterOrEqualThan(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToBoolean(val1 >= val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToBoolean(val1 >= val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
+ return boxToBoolean(val1 >= val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
+ return boxToBoolean(val1 >= val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static Object testGreaterThan(Object arg1, Object arg2) throws NoSuchMethodException {
+ int code1 = typeCode(arg1);
+ int code2 = typeCode(arg2);
+ int maxcode = (code1 < code2) ? code2 : code1;
+ if (maxcode <= INT) {
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
+ return boxToBoolean(val1 > val2);
+ }
+ if (maxcode <= LONG) {
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
+ return boxToBoolean(val1 > val2);
+ }
+ if (maxcode <= FLOAT) {
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
+ return boxToBoolean(val1 > val2);
+ }
+ if (maxcode <= DOUBLE) {
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
+ return boxToBoolean(val1 > val2);
+ }
+ throw new NoSuchMethodException();
+ }
+
+ public static boolean isBoxedNumberOrBoolean(Object arg) {
+ return (arg instanceof java.lang.Boolean) || isBoxedNumber(arg);
+ }
+ public static boolean isBoxedNumber(Object arg) {
+ return (
+ (arg instanceof java.lang.Integer)
+ || (arg instanceof java.lang.Long)
+ || (arg instanceof java.lang.Double)
+ || (arg instanceof java.lang.Float)
+ || (arg instanceof java.lang.Short)
+ || (arg instanceof java.lang.Character)
+ || (arg instanceof java.lang.Byte)
+ );
+ }
+
+ /** arg.toChar */
+ public static java.lang.Character toCharacter(Object arg) throws NoSuchMethodException {
+ if (arg instanceof java.lang.Integer) return boxToCharacter((char)unboxToInt(arg));
+ if (arg instanceof java.lang.Short) return boxToCharacter((char)unboxToShort(arg));
+ if (arg instanceof java.lang.Character) return (java.lang.Character)arg;
+ if (arg instanceof java.lang.Long) return boxToCharacter((char)unboxToLong(arg));
+ if (arg instanceof java.lang.Byte) return boxToCharacter((char)unboxToByte(arg));
+ if (arg instanceof java.lang.Float) return boxToCharacter((char)unboxToFloat(arg));
+ if (arg instanceof java.lang.Double) return boxToCharacter((char)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toByte */
+ public static java.lang.Byte toByte(Object arg) throws NoSuchMethodException {
+ if (arg instanceof java.lang.Integer) return boxToByte((byte)unboxToInt(arg));
+ if (arg instanceof java.lang.Character) return boxToByte((byte)unboxToChar(arg));
+ if (arg instanceof java.lang.Byte) return (java.lang.Byte)arg;
+ if (arg instanceof java.lang.Long) return boxToByte((byte)unboxToLong(arg));
+ if (arg instanceof java.lang.Short) return boxToByte((byte)unboxToShort(arg));
+ if (arg instanceof java.lang.Float) return boxToByte((byte)unboxToFloat(arg));
+ if (arg instanceof java.lang.Double) return boxToByte((byte)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toShort */
+ public static java.lang.Short toShort(Object arg) throws NoSuchMethodException {
+ if (arg instanceof java.lang.Integer) return boxToShort((short)unboxToInt(arg));
+ if (arg instanceof java.lang.Long) return boxToShort((short)unboxToLong(arg));
+ if (arg instanceof java.lang.Character) return boxToShort((short)unboxToChar(arg));
+ if (arg instanceof java.lang.Byte) return boxToShort((short)unboxToByte(arg));
+ if (arg instanceof java.lang.Short) return (java.lang.Short)arg;
+ if (arg instanceof java.lang.Float) return boxToShort((short)unboxToFloat(arg));
+ if (arg instanceof java.lang.Double) return boxToShort((short)unboxToDouble(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toInt */
+ public static java.lang.Integer toInteger(Object arg) throws NoSuchMethodException {
+ if (arg instanceof java.lang.Integer) return (java.lang.Integer)arg;
+ if (arg instanceof java.lang.Long) return boxToInteger((int)unboxToLong(arg));
+ if (arg instanceof java.lang.Double) return boxToInteger((int)unboxToDouble(arg));
+ if (arg instanceof java.lang.Float) return boxToInteger((int)unboxToFloat(arg));
+ if (arg instanceof java.lang.Character) return boxToInteger((int)unboxToChar(arg));
+ if (arg instanceof java.lang.Byte) return boxToInteger((int)unboxToByte(arg));
+ if (arg instanceof java.lang.Short) return boxToInteger((int)unboxToShort(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toLong */
+ public static java.lang.Long toLong(Object arg) throws NoSuchMethodException {
+ if (arg instanceof java.lang.Integer) return boxToLong((long)unboxToInt(arg));
+ if (arg instanceof java.lang.Double) return boxToLong((long)unboxToDouble(arg));
+ if (arg instanceof java.lang.Float) return boxToLong((long)unboxToFloat(arg));
+ if (arg instanceof java.lang.Long) return (java.lang.Long)arg;
+ if (arg instanceof java.lang.Character) return boxToLong((long)unboxToChar(arg));
+ if (arg instanceof java.lang.Byte) return boxToLong((long)unboxToByte(arg));
+ if (arg instanceof java.lang.Short) return boxToLong((long)unboxToShort(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toFloat */
+ public static java.lang.Float toFloat(Object arg) throws NoSuchMethodException {
+ if (arg instanceof java.lang.Integer) return boxToFloat((float)unboxToInt(arg));
+ if (arg instanceof java.lang.Long) return boxToFloat((float)unboxToLong(arg));
+ if (arg instanceof java.lang.Float) return (java.lang.Float)arg;
+ if (arg instanceof java.lang.Double) return boxToFloat((float)unboxToDouble(arg));
+ if (arg instanceof java.lang.Character) return boxToFloat((float)unboxToChar(arg));
+ if (arg instanceof java.lang.Byte) return boxToFloat((float)unboxToByte(arg));
+ if (arg instanceof java.lang.Short) return boxToFloat((float)unboxToShort(arg));
+ throw new NoSuchMethodException();
+ }
+
+ /** arg.toDouble */
+ public static java.lang.Double toDouble(Object arg) throws NoSuchMethodException {
+ if (arg instanceof java.lang.Integer) return boxToDouble((double)unboxToInt(arg));
+ if (arg instanceof java.lang.Float) return boxToDouble((double)unboxToFloat(arg));
+ if (arg instanceof java.lang.Double) return (java.lang.Double)arg;
+ if (arg instanceof java.lang.Long) return boxToDouble((double)unboxToLong(arg));
+ if (arg instanceof java.lang.Character) return boxToDouble((double)unboxToChar(arg));
+ if (arg instanceof java.lang.Byte) return boxToDouble((double)unboxToByte(arg));
+ if (arg instanceof java.lang.Short) return boxToDouble((double)unboxToShort(arg));
+ throw new NoSuchMethodException();
+ }
+
+}
diff --git a/test/files/pos/t5644/other.scala b/test/files/pos/t5644/other.scala
new file mode 100644
index 0000000000..50388fd9ec
--- /dev/null
+++ b/test/files/pos/t5644/other.scala
@@ -0,0 +1,3 @@
+class Foo {
+ List(1) exists(_ == (null: Any))
+}
diff --git a/test/files/pos/t5706.flags b/test/files/pos/t5706.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/pos/t5706.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/pos/t5706.scala b/test/files/pos/t5706.scala
new file mode 100644
index 0000000000..847acb693f
--- /dev/null
+++ b/test/files/pos/t5706.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.Context
+
+class Logger {
+ def error(message: String) = macro Impls.error
+}
+
+object Impls {
+ type LoggerContext = Context { type PrefixType = Logger }
+ def error(c: LoggerContext)(message: c.Expr[String]): c.Expr[Unit] = ???
+}
diff --git a/test/files/pos/virtpatmat_alts_subst.flags b/test/files/pos/virtpatmat_alts_subst.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_alts_subst.flags
+++ b/test/files/pos/virtpatmat_alts_subst.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_anonfun_for.flags b/test/files/pos/virtpatmat_anonfun_for.flags
index 23e3dc7d26..e69de29bb2 100644
--- a/test/files/pos/virtpatmat_anonfun_for.flags
+++ b/test/files/pos/virtpatmat_anonfun_for.flags
@@ -1 +0,0 @@
--Yvirtpatmat \ No newline at end of file
diff --git a/test/files/pos/virtpatmat_binding_opt.flags b/test/files/pos/virtpatmat_binding_opt.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_binding_opt.flags
+++ b/test/files/pos/virtpatmat_binding_opt.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_castbinder.flags b/test/files/pos/virtpatmat_castbinder.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_castbinder.flags
+++ b/test/files/pos/virtpatmat_castbinder.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_exist1.flags b/test/files/pos/virtpatmat_exist1.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_exist1.flags
+++ b/test/files/pos/virtpatmat_exist1.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_exist2.flags b/test/files/pos/virtpatmat_exist2.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_exist2.flags
+++ b/test/files/pos/virtpatmat_exist2.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_exist3.flags b/test/files/pos/virtpatmat_exist3.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_exist3.flags
+++ b/test/files/pos/virtpatmat_exist3.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_exist_uncurry.scala b/test/files/pos/virtpatmat_exist_uncurry.scala
new file mode 100644
index 0000000000..e017da6343
--- /dev/null
+++ b/test/files/pos/virtpatmat_exist_uncurry.scala
@@ -0,0 +1,6 @@
+object Test {
+ trait Leaf[T] {
+ def collect[U](f: PartialFunction[Leaf[_], U]): List[U]
+ def leaves: List[Leaf[T]] = collect { case l: Leaf[T] => l }
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/virtpatmat_gadt_array.flags b/test/files/pos/virtpatmat_gadt_array.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_gadt_array.flags
+++ b/test/files/pos/virtpatmat_gadt_array.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_infer_single_1.flags b/test/files/pos/virtpatmat_infer_single_1.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_infer_single_1.flags
+++ b/test/files/pos/virtpatmat_infer_single_1.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_instof_valuetype.flags b/test/files/pos/virtpatmat_instof_valuetype.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_instof_valuetype.flags
+++ b/test/files/pos/virtpatmat_instof_valuetype.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/pos/virtpatmat_obj_in_case.flags b/test/files/pos/virtpatmat_obj_in_case.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/pos/virtpatmat_obj_in_case.flags
+++ b/test/files/pos/virtpatmat_obj_in_case.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check
index 3385ef12b7..c50e171b4e 100644
--- a/test/files/presentation/callcc-interpreter.check
+++ b/test/files/presentation/callcc-interpreter.check
@@ -52,7 +52,7 @@ retrieved 64 members
`method wait(x$1: Long, x$2: Int)Unit`
`method x=> callccInterpreter.type`
`method →[B](y: B)(callccInterpreter.type, B)`
-`object Wrongobject callccInterpreter.Wrong`
+`object WrongcallccInterpreter.Wrong.type`
`trait TermcallccInterpreter.Term`
`trait ValuecallccInterpreter.Value`
`type AnswercallccInterpreter.Answer`
diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check
index ae202001eb..2b48a80d38 100644
--- a/test/files/presentation/ide-bug-1000531.check
+++ b/test/files/presentation/ide-bug-1000531.check
@@ -99,7 +99,7 @@ retrieved 123 members
`method synchronized[T0](x$1: T0)T0`
`method take(n: Int)Iterator[B]`
`method takeWhile(p: B => Boolean)Iterator[B]`
-`method toArray[B >: B](implicit evidence$1: ClassManifest[B])Array[B]`
+`method toArray[B >: B](implicit evidence$1: ArrayTag[B])Array[B]`
`method toBuffer[B >: B]=> scala.collection.mutable.Buffer[B]`
`method toIndexedSeq=> scala.collection.immutable.IndexedSeq[B]`
`method toIterable=> Iterable[B]`
diff --git a/test/files/presentation/memory-leaks.check b/test/files/presentation/memory-leaks.check
new file mode 100644
index 0000000000..86fb07757d
--- /dev/null
+++ b/test/files/presentation/memory-leaks.check
@@ -0,0 +1,54 @@
+reload: Trees.scala, Typers.scala, Types.scala
+reload: Trees.scala
+reload: Types.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+reload: Typers.scala
+No leaks detected.
diff --git a/test/files/presentation/memory-leaks/MemoryLeaksTest.scala b/test/files/presentation/memory-leaks/MemoryLeaksTest.scala
new file mode 100644
index 0000000000..45b38da85b
--- /dev/null
+++ b/test/files/presentation/memory-leaks/MemoryLeaksTest.scala
@@ -0,0 +1,126 @@
+import java.io.PrintWriter
+import java.io.FileOutputStream
+import java.util.Calendar
+
+import scala.tools.nsc.interactive.tests._
+import scala.tools.nsc.util._
+import scala.tools.nsc.io._
+
+/** This test runs the presentation compiler on the Scala compiler project itself and records memory consumption.
+ *
+ * The test scenario is to open Typers, Trees and Types, then repeatedly add and remove one character
+ * in Typers.scala. Each step causes the parser, namer, and type checker to run.
+ *
+ * At each step we record the memory usage after the GC has run. At the end of the test,
+ * simple linear regression is used to compute the straight line that best fits the
+ * curve, and if the slope is higher than 1 (meaning a leak of 1MB/run), we fail the test.
+ *
+ * The Scala compiler sources are assumed to be under 'basedir/src/compiler'.
+ *
+ * The individual data points are saved under 'usedMem-<date>.txt', under the test project
+ * directory. Use the cool graph-it.R (https://github.com/scala-ide/scala-ide/blob/master/org.scala-ide.sdt.core.tests/graph-it.R)
+ * script to see the memory curve for the given test run.
+ */
+object Test extends InteractiveTest {
+ final val mega = 1024 * 1024
+
+ override def main(args: Array[String]) {
+ memoryConsumptionTest()
+ compiler.askShutdown()
+ }
+
+ def batchSource(name: String) =
+ new BatchSourceFile(AbstractFile.getFile(name))
+
+ def memoryConsumptionTest() {
+ val N = 50
+ val filename = "usedmem-%tF.txt".format(Calendar.getInstance.getTime)
+
+ val typerUnit = AbstractFile.getFile(baseDir.parent.parent.parent.parent / "src/compiler/scala/tools/nsc/typechecker/Typers.scala")
+ val typesUnit = AbstractFile.getFile(baseDir.parent.parent.parent.parent / "src/compiler/scala/reflect/internal/Types.scala")
+ val treesUnit = AbstractFile.getFile(baseDir.parent.parent.parent.parent / "src/compiler/scala/reflect/internal/Trees.scala")
+
+ askReload(Seq(new BatchSourceFile(typerUnit), new BatchSourceFile(typesUnit), new BatchSourceFile(treesUnit)))
+ typeCheckWith(treesUnit, new String(treesUnit.toCharArray))
+ typeCheckWith(typesUnit, new String(typesUnit.toCharArray))
+
+ val originalTyper = new String(typerUnit.toCharArray)
+
+ val (prefix, postfix) = originalTyper.splitAt(originalTyper.indexOf("import global._"))
+ val changedTyper = prefix + " a\n " + postfix
+
+ val usedMem = for (i <- 1 to N) yield {
+ val src = if (i % 2 == 0) originalTyper else changedTyper
+
+ val usedMem = withGC {
+ typeCheckWith(typerUnit, src)
+ }
+
+ usedMem / mega // report size in MB
+ }
+
+ //dumpDataToFile(filename, usedMem)
+ // drop the first two measurements, since the compiler needs some memory when initializing
+ val (a, b) = linearModel((3L to N).toSeq, usedMem.drop(2))
+ //println("LinearModel: constant: %.4f\tslope:%.4f".format(a, b))
+
+ if (b > 1.0)
+ println("Rate of memory consumption is alarming! %.4f MB/run".format(b))
+ else
+ println("No leaks detected.")
+ }
+
+ private def typeCheckWith(file: AbstractFile, src: String) = {
+ val sourceFile = new BatchSourceFile(file, src.toCharArray)
+ askReload(Seq(sourceFile))
+ askLoadedTyped(sourceFile).get // block until it's here
+ }
+
+ private def dumpDataToFile(filename: String, usedMem: Seq[Long]) {
+ val outputFile = new PrintWriter(new FileOutputStream(filename))
+ outputFile.println("\tusedMem")
+ for ((dataPoint, i) <- usedMem.zipWithIndex) {
+ outputFile.println("%d\t%d".format(i, dataPoint))
+ }
+ outputFile.close()
+ }
+
+
+ /** Return the linear model of these values, (a, b). First value is the constant factor,
+ * second value is the slope, i.e. `y = a + bx`
+ *
+ * The linear model of a set of points is a straight line that minimizes the square distance
+ * between the each point and the line.
+ *
+ * See: http://en.wikipedia.org/wiki/Simple_linear_regression
+ */
+ def linearModel(xs: Seq[Long], ys: Seq[Long]): (Double, Double) = {
+ require(xs.length == ys.length)
+
+ def mean(v: Seq[Long]): Double = v.sum.toDouble / v.length
+
+ val meanXs = mean(xs)
+ val meanYs = mean(ys)
+
+ val beta = (mean((xs, ys).zipped.map(_ * _)) - meanXs * meanYs) / (mean(xs.map(x => x * x)) - meanXs * meanXs)
+ val alfa = meanYs - beta * meanXs
+
+ (alfa, beta)
+ }
+
+ /** Run the given closure and return the amount of used memory at the end of its execution.
+ *
+ * Runs the GC before and after the execution of `f'.
+ */
+ def withGC(f: => Unit): Long = {
+ val r = Runtime.getRuntime
+ System.gc()
+
+ f;
+
+ System.gc()
+
+ r.totalMemory() - r.freeMemory()
+ }
+
+} \ No newline at end of file
diff --git a/test/files/presentation/patmat.check b/test/files/presentation/patmat.check
new file mode 100644
index 0000000000..29fd8b8e68
--- /dev/null
+++ b/test/files/presentation/patmat.check
@@ -0,0 +1,36 @@
+reload: PatMatTests.scala
+
+askHyperlinkPos for `CaseOne` at (12,18) PatMatTests.scala
+================================================================================
+[response] found askHyperlinkPos for `CaseOne` at (5,12) PatMatTests.scala
+================================================================================
+
+askHyperlinkPos for `first` at (14,21) PatMatTests.scala
+================================================================================
+[response] found askHyperlinkPos for `first` at (12,29) PatMatTests.scala
+================================================================================
+
+askHyperlinkPos for `tmp` at (15,19) PatMatTests.scala
+================================================================================
+[response] found askHyperlinkPos for `tmp` at (13,13) PatMatTests.scala
+================================================================================
+
+askHyperlinkPos for `CaseTwo` at (17,18) PatMatTests.scala
+================================================================================
+[response] found askHyperlinkPos for `CaseTwo` at (6,12) PatMatTests.scala
+================================================================================
+
+askHyperlinkPos for `mystring` at (18,24) PatMatTests.scala
+================================================================================
+[response] found askHyperlinkPos for `mystring` at (17,25) PatMatTests.scala
+================================================================================
+
+askHyperlinkPos for `x` at (25,13) PatMatTests.scala
+================================================================================
+[response] found askHyperlinkPos for `x` at (23,10) PatMatTests.scala
+================================================================================
+
+askHyperlinkPos for `y` at (25,21) PatMatTests.scala
+================================================================================
+[response] found askHyperlinkPos for `y` at (23,13) PatMatTests.scala
+================================================================================
diff --git a/test/files/presentation/patmat.flags b/test/files/presentation/patmat.flags
new file mode 100644
index 0000000000..468b48c9e3
--- /dev/null
+++ b/test/files/presentation/patmat.flags
@@ -0,0 +1,3 @@
+# This test will fail in the new pattern matcher because
+# it generates trees whose positions are not transparent
+-Xoldpatmat
diff --git a/test/files/presentation/patmat/Runner.scala b/test/files/presentation/patmat/Runner.scala
new file mode 100644
index 0000000000..3d19f2d948
--- /dev/null
+++ b/test/files/presentation/patmat/Runner.scala
@@ -0,0 +1,11 @@
+import scala.tools.nsc.interactive.tests.InteractiveTest
+
+object Test extends InteractiveTest {
+ override def runTests() {
+ // make sure typer is done.. the virtual pattern matcher might translate
+ // some trees and mess up positions. But we'll catch it red handed!
+ sourceFiles foreach (src => askLoadedTyped(src).get)
+ super.runTests()
+ }
+
+} \ No newline at end of file
diff --git a/test/files/presentation/patmat/src/PatMatTests.scala b/test/files/presentation/patmat/src/PatMatTests.scala
new file mode 100644
index 0000000000..bbd0f2e7ed
--- /dev/null
+++ b/test/files/presentation/patmat/src/PatMatTests.scala
@@ -0,0 +1,28 @@
+package patmat
+
+abstract class BaseType
+
+case class CaseOne(x: Int, y: List[Int]) extends BaseType
+case class CaseTwo(str: String) extends BaseType
+
+class PatMatTests {
+
+ def foo(x: BaseType) {
+ x match {
+ case CaseOne/*#*/(10, first :: second :: Nil) =>
+ val tmp = 23
+ println(first/*#*/)
+ println(tmp/*#*/)
+
+ case CaseTwo/*#*/(mystring) =>
+ println(mystring/*#*/)
+ }
+ }
+
+ def multipleAssign() {
+ val (x, y) = ("abc", "def")
+
+ println(x/*#*/, y/*#*/)
+ }
+
+} \ No newline at end of file
diff --git a/test/files/run/Meter.check b/test/files/run/Meter.check
index 7562f9a1bf..b7e2eac125 100644
--- a/test/files/run/Meter.check
+++ b/test/files/run/Meter.check
@@ -11,11 +11,3 @@ Array(1.0m, 2.0m)
1.0m
>>>1.0m<<< 1.0m
>>>2.0m<<< 2.0m
-testing wrapped arrays
-FlatArray(1.0m, 2.0m)
-1.0m
->>>1.0m<<< 1.0m
->>>2.0m<<< 2.0m
-FlatArray(2.0m, 3.0m)
-ArrayBuffer(1.0, 2.0)
-FlatArray(0.3048ft, 0.6096ft)
diff --git a/test/files/run/Meter.scala b/test/files/run/Meter.scala
index 515e46de24..d94f338ca9 100644
--- a/test/files/run/Meter.scala
+++ b/test/files/run/Meter.scala
@@ -80,23 +80,23 @@ object Test extends App {
println(m)
foo(arr)
}
-
- { println("testing wrapped arrays")
- import collection.mutable.FlatArray
- val arr = FlatArray(x, y + x)
- println(arr)
- def foo(x: FlatArray[Meter]) {
- for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) }
- }
- val m = arr(0)
- println(m)
- foo(arr)
- val ys: Seq[Meter] = arr map (_ + new Meter(1))
- println(ys)
- val zs = arr map (_ / Meter(1))
- println(zs)
- val fs = arr map (_.toFoot)
- println(fs)
- }
+ //
+ // { println("testing wrapped arrays")
+ // import collection.mutable.FlatArray
+ // val arr = FlatArray(x, y + x)
+ // println(arr)
+ // def foo(x: FlatArray[Meter]) {
+ // for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) }
+ // }
+ // val m = arr(0)
+ // println(m)
+ // foo(arr)
+ // val ys: Seq[Meter] = arr map (_ + new Meter(1))
+ // println(ys)
+ // val zs = arr map (_ / Meter(1))
+ // println(zs)
+ // val fs = arr map (_.toFoot)
+ // println(fs)
+ // }
}
diff --git a/test/files/run/MeterCaseClass.check b/test/files/run/MeterCaseClass.check
index 08370d2097..2528753657 100644
--- a/test/files/run/MeterCaseClass.check
+++ b/test/files/run/MeterCaseClass.check
@@ -11,11 +11,3 @@ Array(Meter(1.0), Meter(2.0))
Meter(1.0)
>>>Meter(1.0)<<< Meter(1.0)
>>>Meter(2.0)<<< Meter(2.0)
-testing wrapped arrays
-FlatArray(Meter(1.0), Meter(2.0))
-Meter(1.0)
->>>Meter(1.0)<<< Meter(1.0)
->>>Meter(2.0)<<< Meter(2.0)
-FlatArray(Meter(2.0), Meter(3.0))
-ArrayBuffer(1.0, 2.0)
-FlatArray(0.3048ft, 0.6096ft)
diff --git a/test/files/run/MeterCaseClass.scala b/test/files/run/MeterCaseClass.scala
index 8459163f31..e5979cf761 100644
--- a/test/files/run/MeterCaseClass.scala
+++ b/test/files/run/MeterCaseClass.scala
@@ -77,23 +77,23 @@ object Test extends App {
println(m)
foo(arr)
}
-
- { println("testing wrapped arrays")
- import collection.mutable.FlatArray
- val arr = FlatArray(x, y + x)
- println(arr)
- def foo(x: FlatArray[Meter]) {
- for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) }
- }
- val m = arr(0)
- println(m)
- foo(arr)
- val ys: Seq[Meter] = arr map (_ + new Meter(1))
- println(ys)
- val zs = arr map (_ / Meter(1))
- println(zs)
- val fs = arr map (_.toFoot)
- println(fs)
- }
+ //
+ // { println("testing wrapped arrays")
+ // import collection.mutable.FlatArray
+ // val arr = FlatArray(x, y + x)
+ // println(arr)
+ // def foo(x: FlatArray[Meter]) {
+ // for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) }
+ // }
+ // val m = arr(0)
+ // println(m)
+ // foo(arr)
+ // val ys: Seq[Meter] = arr map (_ + new Meter(1))
+ // println(ys)
+ // val zs = arr map (_ / Meter(1))
+ // println(zs)
+ // val fs = arr map (_.toFoot)
+ // println(fs)
+ // }
}
diff --git a/test/files/run/applydynamic_sip.check b/test/files/run/applydynamic_sip.check
new file mode 100644
index 0000000000..d94db4417e
--- /dev/null
+++ b/test/files/run/applydynamic_sip.check
@@ -0,0 +1,22 @@
+qual.applyDynamic(sel)()
+qual.applyDynamic(sel)(a)
+qual.applyDynamic(sel)(a)
+.apply(a2)
+qual.applyDynamic(sel)(a)
+qual.applyDynamic(sel)(a)
+.apply(a2)
+qual.applyDynamicNamed(sel)((arg,a))
+qual.applyDynamicNamed(sel)((arg,a))
+qual.applyDynamicNamed(sel)((,a), (arg2,a2))
+qual.updateDynamic(sel)(expr)
+qual.selectDynamic(sel)
+qual.selectDynamic(sel)
+qual.selectDynamic(sel)
+.update(1, expr)
+qual.selectDynamic(sel)
+.update(expr)
+qual.selectDynamic(sel)
+.apply(1)
+qual.selectDynamic(sel)
+.apply
+.update(1, 1)
diff --git a/test/files/run/applydynamic_sip.scala b/test/files/run/applydynamic_sip.scala
new file mode 100644
index 0000000000..57cb4349f7
--- /dev/null
+++ b/test/files/run/applydynamic_sip.scala
@@ -0,0 +1,58 @@
+object Test extends App {
+ object stubUpdate {
+ def update(as: Any*) = println(".update"+as.toList.mkString("(",", ", ")"))
+ }
+
+ object stub {
+ def apply = {println(".apply"); stubUpdate}
+ def apply(as: Any*) = println(".apply"+as.toList.mkString("(",", ", ")"))
+ def update(as: Any*) = println(".update"+as.toList.mkString("(",", ", ")"))
+ }
+ class MyDynamic extends Dynamic {
+ def applyDynamic[T](n: String)(as: Any*) = {println("qual.applyDynamic("+ n +")"+ as.toList.mkString("(",", ", ")")); stub}
+ def applyDynamicNamed[T](n: String)(as: (String, Any)*) = {println("qual.applyDynamicNamed("+ n +")"+ as.toList.mkString("(",", ", ")")); stub}
+ def selectDynamic[T](n: String) = {println("qual.selectDynamic("+ n +")"); stub}
+ def updateDynamic(n: String)(x: Any): Unit = {println("qual.updateDynamic("+ n +")("+ x +")")}
+ }
+ val qual = new MyDynamic
+ val expr = "expr"
+ val a = "a"
+ val a2 = "a2"
+ type T = String
+
+ // If qual.sel is followed by a potential type argument list [Ts] and an argument list (arg1, …, argn) where none of the arguments argi are named:
+ // qual.applyDynamic(“sel”)(arg1, …, argn)
+ qual.sel()
+ qual.sel(a)
+ // qual.sel(a, a2: _*) -- should not accept varargs?
+ qual.sel(a)(a2)
+ qual.sel[T](a)
+ qual.sel[T](a)(a2)
+
+ // If qual.sel is followed by a potential type argument list [Ts]
+ // and a non-empty named argument list (x1 = arg1, …, xn = argn) where some name prefixes xi = might be missing:
+ // qual.applyDynamicNamed(“sel”)(xs1 -> arg1, …, xsn -> argn)
+ qual.sel(arg = a)
+ qual.sel[T](arg = a)
+ qual.sel(a, arg2 = "a2")
+ // qual.sel(a)(a2, arg2 = "a2")
+ // qual.sel[T](a)(a2, arg2 = "a2")
+ // qual.sel(arg = a, a2: _*)
+ // qual.sel(arg, arg2 = "a2", a2: _*)
+
+ // If qual.sel appears immediately on the left-hand side of an assigment
+ // qual.updateDynamic(“sel”)(expr)
+ qual.sel = expr
+
+ // If qual.sel, possibly applied to type arguments, but is
+ // not applied to explicit value arguments,
+ // nor immediately followed by an assignment operator:
+ // qual.selectDynamic[Ts](“sel”)
+ qual.sel
+ qual.sel[T]
+
+ qual.sel(1) = expr // parser turns this into qual.sel.update(1, expr)
+ qual.sel() = expr // parser turns this into qual.sel.update(expr)
+ qual.sel.apply(1)
+ qual.sel.apply(1) = 1
+} \ No newline at end of file
diff --git a/test/files/run/arrayclone-new.scala b/test/files/run/arrayclone-new.scala
new file mode 100644
index 0000000000..a4ba021409
--- /dev/null
+++ b/test/files/run/arrayclone-new.scala
@@ -0,0 +1,106 @@
+object Test extends App{
+ BooleanArrayClone;
+ ByteArrayClone;
+ ShortArrayClone;
+ CharArrayClone;
+ IntArrayClone;
+ LongArrayClone;
+ FloatArrayClone;
+ DoubleArrayClone;
+ ObjectArrayClone;
+ PolymorphicArrayClone;
+}
+
+object BooleanArrayClone{
+ val it : Array[Boolean] = Array(true, false);
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = false;
+ assert(it(0) == true)
+}
+
+object ByteArrayClone{
+ val it : Array[Byte] = Array(1, 0);
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = 0;
+ assert(it(0) == 1)
+}
+
+object ShortArrayClone{
+ val it : Array[Short] = Array(1, 0);
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = 0;
+ assert(it(0) == 1)
+}
+
+object CharArrayClone{
+ val it : Array[Char] = Array(1, 0);
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = 0;
+ assert(it(0) == 1)
+}
+
+object IntArrayClone{
+ val it : Array[Int] = Array(1, 0);
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = 0;
+ assert(it(0) == 1)
+}
+
+object LongArrayClone{
+ val it : Array[Long] = Array(1, 0);
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = 0;
+ assert(it(0) == 1)
+}
+
+object FloatArrayClone{
+ val it : Array[Float] = Array(1, 0);
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = 0;
+ assert(it(0) == 1)
+}
+
+object DoubleArrayClone{
+ val it : Array[Double] = Array(1, 0);
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = 0;
+ assert(it(0) == 1)
+}
+
+object ObjectArrayClone{
+ val it : Array[String] = Array("1", "0");
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = "0";
+ assert(it(0) == "1")
+}
+
+object PolymorphicArrayClone{
+ def testIt[T](it : Array[T], one : T, zero : T) = {
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = zero;
+ assert(it(0) == one)
+ }
+
+ testIt(Array("one", "two"), "one", "two");
+
+ class Mangler[T: ArrayTag](ts : T*){
+ // this will always be a BoxedAnyArray even after we've unboxed its contents.
+ val it = ts.toArray[T];
+ }
+
+ val mangled = new Mangler[Int](0, 1);
+
+ val y : Array[Int] = mangled.it; // make sure it's unboxed
+
+ testIt(mangled.it, 0, 1);
+}
diff --git a/test/files/run/arrayclone.scala b/test/files/run/arrayclone-old.scala
index c9f7556b47..c9f7556b47 100644
--- a/test/files/run/arrayclone.scala
+++ b/test/files/run/arrayclone-old.scala
diff --git a/test/files/run/arraytags_basic.check b/test/files/run/arraytags_basic.check
new file mode 100644
index 0000000000..92816b91bd
--- /dev/null
+++ b/test/files/run/arraytags_basic.check
@@ -0,0 +1,36 @@
+class [I
+class [[I
+class [[[I
+class [Lscala.collection.immutable.List;
+class [[Lscala.collection.immutable.List;
+class [[[Lscala.collection.immutable.List;
+class [Lscala.collection.immutable.List;
+class [[Lscala.collection.immutable.List;
+class [[[Lscala.collection.immutable.List;
+class [Lscala.collection.immutable.Map;
+class [[Lscala.collection.immutable.Map;
+class [[[Lscala.collection.immutable.Map;
+class [[I
+class [[[I
+class [[[[I
+class [[Lscala.collection.immutable.List;
+class [[[Lscala.collection.immutable.List;
+class [[[[Lscala.collection.immutable.List;
+class [[Lscala.collection.immutable.List;
+class [[[Lscala.collection.immutable.List;
+class [[[[Lscala.collection.immutable.List;
+class [[Lscala.collection.immutable.Map;
+class [[[Lscala.collection.immutable.Map;
+class [[[[Lscala.collection.immutable.Map;
+class [[[I
+class [[[[I
+class [[[[[I
+class [[[Lscala.collection.immutable.List;
+class [[[[Lscala.collection.immutable.List;
+class [[[[[Lscala.collection.immutable.List;
+class [[[Lscala.collection.immutable.List;
+class [[[[Lscala.collection.immutable.List;
+class [[[[[Lscala.collection.immutable.List;
+class [[[Lscala.collection.immutable.Map;
+class [[[[Lscala.collection.immutable.Map;
+class [[[[[Lscala.collection.immutable.Map;
diff --git a/test/files/run/arraytags_basic.scala b/test/files/run/arraytags_basic.scala
new file mode 100644
index 0000000000..edc20e9bc1
--- /dev/null
+++ b/test/files/run/arraytags_basic.scala
@@ -0,0 +1,22 @@
+object Test extends App {
+ def test[T: ArrayTag] = {
+ println(implicitly[ArrayTag[T]].newArray(10).getClass)
+ println(implicitly[ArrayTag[T]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[T]]].wrap.newArray(10).getClass)
+ }
+
+ test[Int]
+ test[List[Int]]
+ test[List[String]]
+ test[Map[Int, String]]
+
+ test[Array[Int]]
+ test[Array[List[Int]]]
+ test[Array[List[String]]]
+ test[Array[Map[Int, String]]]
+
+ test[Array[Array[Int]]]
+ test[Array[Array[List[Int]]]]
+ test[Array[Array[List[String]]]]
+ test[Array[Array[Map[Int, String]]]]
+} \ No newline at end of file
diff --git a/test/files/run/arraytags_core.check b/test/files/run/arraytags_core.check
new file mode 100644
index 0000000000..82ed84ad78
--- /dev/null
+++ b/test/files/run/arraytags_core.check
@@ -0,0 +1,48 @@
+class [B
+class [[B
+class [[[B
+class [S
+class [[S
+class [[[S
+class [C
+class [[C
+class [[[C
+class [I
+class [[I
+class [[[I
+class [J
+class [[J
+class [[[J
+class [F
+class [[F
+class [[[F
+class [D
+class [[D
+class [[[D
+class [Z
+class [[Z
+class [[[Z
+class [Lscala.runtime.BoxedUnit;
+class [[Lscala.runtime.BoxedUnit;
+class [[[Lscala.runtime.BoxedUnit;
+class [Ljava.lang.Object;
+class [[Ljava.lang.Object;
+class [[[Ljava.lang.Object;
+class [Ljava.lang.Object;
+class [[Ljava.lang.Object;
+class [[[Ljava.lang.Object;
+class [Ljava.lang.Object;
+class [[Ljava.lang.Object;
+class [[[Ljava.lang.Object;
+class [Ljava.lang.Object;
+class [[Ljava.lang.Object;
+class [[[Ljava.lang.Object;
+class [Lscala.runtime.Null$;
+class [[Lscala.runtime.Null$;
+class [[[Lscala.runtime.Null$;
+class [Lscala.runtime.Nothing$;
+class [[Lscala.runtime.Nothing$;
+class [[[Lscala.runtime.Nothing$;
+class [Ljava.lang.String;
+class [[Ljava.lang.String;
+class [[[Ljava.lang.String;
diff --git a/test/files/run/arraytags_core.scala b/test/files/run/arraytags_core.scala
new file mode 100644
index 0000000000..a59ae24f30
--- /dev/null
+++ b/test/files/run/arraytags_core.scala
@@ -0,0 +1,50 @@
+object Test extends App {
+ println(implicitly[ArrayTag[Byte]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Byte]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Byte]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Short]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Short]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Short]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Char]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Char]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Char]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Int]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Int]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Int]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Long]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Long]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Long]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Float]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Float]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Float]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Double]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Double]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Double]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Boolean]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Boolean]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Boolean]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Unit]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Unit]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Unit]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Any]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Any]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Any]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Object]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Object]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Object]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[AnyVal]].newArray(10).getClass)
+ println(implicitly[ArrayTag[AnyVal]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[AnyVal]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[AnyRef]].newArray(10).getClass)
+ println(implicitly[ArrayTag[AnyRef]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[AnyRef]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Null]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Null]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Null]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Nothing]].newArray(10).getClass)
+ println(implicitly[ArrayTag[Nothing]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[Nothing]]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[String]].newArray(10).getClass)
+ println(implicitly[ArrayTag[String]].wrap.newArray(10).getClass)
+ println(implicitly[ArrayTag[Array[String]]].wrap.newArray(10).getClass)
+} \ No newline at end of file
diff --git a/test/files/run/arraytags_usage.check b/test/files/run/arraytags_usage.check
new file mode 100644
index 0000000000..b1d02b7bfe
--- /dev/null
+++ b/test/files/run/arraytags_usage.check
@@ -0,0 +1,3 @@
+class [I
+class [I
+class [I
diff --git a/test/files/run/arraytags_usage.scala b/test/files/run/arraytags_usage.scala
new file mode 100644
index 0000000000..60b0a8f218
--- /dev/null
+++ b/test/files/run/arraytags_usage.scala
@@ -0,0 +1,15 @@
+object Test extends App {
+ def foo[T] = {
+ class MyArrayTag extends ArrayTag[T] {
+ def wrap: ArrayTag[Array[T]] = ???
+ def newArray(len: Int): Array[T] = new Array[Int](len).asInstanceOf[Array[T]]
+ }
+
+ implicit val tag = new MyArrayTag()
+ println(Array[T]().getClass)
+ }
+
+ foo[Int]
+ foo[String]
+ foo[Array[String]]
+} \ No newline at end of file
diff --git a/test/files/run/classtags_contextbound.check b/test/files/run/classtags_contextbound.check
new file mode 100644
index 0000000000..4104d544ba
--- /dev/null
+++ b/test/files/run/classtags_contextbound.check
@@ -0,0 +1 @@
+class [I
diff --git a/test/files/run/classtags_contextbound.scala b/test/files/run/classtags_contextbound.scala
new file mode 100644
index 0000000000..5bb0ae8d80
--- /dev/null
+++ b/test/files/run/classtags_contextbound.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ def mkArray[T: ClassTag] = Array[T]()
+ def foo[T: ClassTag] = mkArray[T]
+ println(foo[Int].getClass)
+} \ No newline at end of file
diff --git a/test/files/run/classtags_core.check b/test/files/run/classtags_core.check
new file mode 100644
index 0000000000..ebccfcd54c
--- /dev/null
+++ b/test/files/run/classtags_core.check
@@ -0,0 +1,32 @@
+true
+ClassTag[byte]
+true
+ClassTag[short]
+true
+ClassTag[char]
+true
+ClassTag[int]
+true
+ClassTag[long]
+true
+ClassTag[float]
+true
+ClassTag[double]
+true
+ClassTag[boolean]
+true
+ClassTag[void]
+true
+ClassTag[class java.lang.Object]
+true
+ClassTag[class java.lang.Object]
+true
+ClassTag[class java.lang.Object]
+true
+ClassTag[class java.lang.Object]
+true
+ClassTag[class scala.runtime.Null$]
+true
+ClassTag[class scala.runtime.Nothing$]
+true
+ClassTag[class java.lang.String]
diff --git a/test/files/run/classtags_core.scala b/test/files/run/classtags_core.scala
new file mode 100644
index 0000000000..9f2031377d
--- /dev/null
+++ b/test/files/run/classtags_core.scala
@@ -0,0 +1,34 @@
+object Test extends App {
+ println(implicitly[ClassTag[Byte]] eq ClassTag.Byte)
+ println(implicitly[ClassTag[Byte]])
+ println(implicitly[ClassTag[Short]] eq ClassTag.Short)
+ println(implicitly[ClassTag[Short]])
+ println(implicitly[ClassTag[Char]] eq ClassTag.Char)
+ println(implicitly[ClassTag[Char]])
+ println(implicitly[ClassTag[Int]] eq ClassTag.Int)
+ println(implicitly[ClassTag[Int]])
+ println(implicitly[ClassTag[Long]] eq ClassTag.Long)
+ println(implicitly[ClassTag[Long]])
+ println(implicitly[ClassTag[Float]] eq ClassTag.Float)
+ println(implicitly[ClassTag[Float]])
+ println(implicitly[ClassTag[Double]] eq ClassTag.Double)
+ println(implicitly[ClassTag[Double]])
+ println(implicitly[ClassTag[Boolean]] eq ClassTag.Boolean)
+ println(implicitly[ClassTag[Boolean]])
+ println(implicitly[ClassTag[Unit]] eq ClassTag.Unit)
+ println(implicitly[ClassTag[Unit]])
+ println(implicitly[ClassTag[Any]] eq ClassTag.Any)
+ println(implicitly[ClassTag[Any]])
+ println(implicitly[ClassTag[Object]] eq ClassTag.Object)
+ println(implicitly[ClassTag[Object]])
+ println(implicitly[ClassTag[AnyVal]] eq ClassTag.AnyVal)
+ println(implicitly[ClassTag[AnyVal]])
+ println(implicitly[ClassTag[AnyRef]] eq ClassTag.AnyRef)
+ println(implicitly[ClassTag[AnyRef]])
+ println(implicitly[ClassTag[Null]] eq ClassTag.Null)
+ println(implicitly[ClassTag[Null]])
+ println(implicitly[ClassTag[Nothing]] eq ClassTag.Nothing)
+ println(implicitly[ClassTag[Nothing]])
+ println(implicitly[ClassTag[String]] eq ClassTag.String)
+ println(implicitly[ClassTag[String]])
+} \ No newline at end of file
diff --git a/test/files/run/classtags_multi.check b/test/files/run/classtags_multi.check
new file mode 100644
index 0000000000..3a7f16c3a0
--- /dev/null
+++ b/test/files/run/classtags_multi.check
@@ -0,0 +1,5 @@
+ClassTag[int]
+ClassTag[class [I]
+ClassTag[class [[I]
+ClassTag[class [[[I]
+ClassTag[class [[[[I]
diff --git a/test/files/run/classtags_multi.scala b/test/files/run/classtags_multi.scala
new file mode 100644
index 0000000000..5aafb55223
--- /dev/null
+++ b/test/files/run/classtags_multi.scala
@@ -0,0 +1,7 @@
+object Test extends App {
+ println(classTag[Int])
+ println(classTag[Array[Int]])
+ println(classTag[Array[Array[Int]]])
+ println(classTag[Array[Array[Array[Int]]]])
+ println(classTag[Array[Array[Array[Array[Int]]]]])
+} \ No newline at end of file
diff --git a/test/files/run/classtags_use_concretetypetags.scala b/test/files/run/classtags_use_concretetypetags.scala
new file mode 100644
index 0000000000..57e7085cec
--- /dev/null
+++ b/test/files/run/classtags_use_concretetypetags.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ def foo[T: ConcreteTypeTag] = Array[T]()
+} \ No newline at end of file
diff --git a/test/files/run/compiler-asSeenFrom.check b/test/files/run/compiler-asSeenFrom.check
index f198e61072..96e257d303 100644
--- a/test/files/run/compiler-asSeenFrom.check
+++ b/test/files/run/compiler-asSeenFrom.check
@@ -187,69 +187,69 @@ class J {
D[A1]#J[T4] Z.dZ.J[P] D[A1]#J[P]
}
class D { // after parser
- private val cD: ll.C[List[T3]]
+ private[this] val cD: ll.C[List[T3]]
val cD: ll.C[List[T3]]
}
class D { // after uncurry
- private val cD: ll.C[List[T3]]
+ private[this] val cD: ll.C[List[T3]]
val cD(): ll.C[List[T3]]
}
class D { // after erasure
- private val cD: ll.C
+ private[this] val cD: ll.C
val cD(): ll.C
}
object Z { // after parser
def kz[P <: ll.Z.dZ.J[ll.A2]]: ll.Z.dZ.J[P]
- private val jZ: ll.Z.dZ.J[ll.A2]
+ private[this] val jZ: ll.Z.dZ.J[ll.A2]
val jZ: ll.Z.dZ.J[ll.A2]
- private val dZ: ll.D[ll.A1]
+ private[this] val dZ: ll.D[ll.A1]
val dZ: ll.D[ll.A1]
}
object Z { // after uncurry
def kz[P <: ll.Z.dZ.J[ll.A2]](): ll.Z.dZ.J[P]
- private val jZ: ll.Z.dZ.J[ll.A2]
+ private[this] val jZ: ll.Z.dZ.J[ll.A2]
val jZ(): ll.Z.dZ.J[ll.A2]
- private val dZ: ll.D[ll.A1]
+ private[this] val dZ: ll.D[ll.A1]
val dZ(): ll.D[ll.A1]
}
object Z { // after erasure
def kz(): ll.D#J
- private val jZ: ll.D#J
+ private[this] val jZ: ll.D#J
val jZ(): ll.D#J
- private val dZ: ll.D
+ private[this] val dZ: ll.D
val dZ(): ll.D
}
object Z { // after flatten
def kz(): ll.D#D$J
- private val jZ: ll.D#D$J
+ private[this] val jZ: ll.D#D$J
val jZ(): ll.D#D$J
- private val dZ: ll.D
+ private[this] val dZ: ll.D
val dZ(): ll.D
}
value dZ { // after parser
- private val cD: ll.C[List[T3]]
+ private[this] val cD: ll.C[List[T3]]
val cD: ll.C[List[T3]]
}
value dZ { // after parser
- private val cD: ll.C[List[T3]]
+ private[this] val cD: ll.C[List[T3]]
val cD: ll.C[List[T3]]
}
value dZ { // after uncurry
- private val cD: ll.C[List[T3]]
+ private[this] val cD: ll.C[List[T3]]
val cD(): ll.C[List[T3]]
}
value dZ { // after erasure
- private val cD: ll.C
+ private[this] val cD: ll.C
val cD(): ll.C
}
@@ -307,17 +307,17 @@ method kz { // after parser
}
value $outer { // after parser
- private val cD: ll.C[List[T3]]
+ private[this] val cD: ll.C[List[T3]]
val cD: ll.C[List[T3]]
}
value $outer { // after uncurry
- private val cD: ll.C[List[T3]]
+ private[this] val cD: ll.C[List[T3]]
val cD(): ll.C[List[T3]]
}
value $outer { // after erasure
- private val cD: ll.C
+ private[this] val cD: ll.C
val cD(): ll.C
}
diff --git a/test/files/run/concretetypetags_core.check b/test/files/run/concretetypetags_core.check
new file mode 100644
index 0000000000..f124aa6a35
--- /dev/null
+++ b/test/files/run/concretetypetags_core.check
@@ -0,0 +1,32 @@
+true
+ConcreteTypeTag[Byte]
+true
+ConcreteTypeTag[Short]
+true
+ConcreteTypeTag[Char]
+true
+ConcreteTypeTag[Int]
+true
+ConcreteTypeTag[Long]
+true
+ConcreteTypeTag[Float]
+true
+ConcreteTypeTag[Double]
+true
+ConcreteTypeTag[Boolean]
+true
+ConcreteTypeTag[Unit]
+true
+ConcreteTypeTag[Any]
+true
+ConcreteTypeTag[Object]
+true
+ConcreteTypeTag[AnyVal]
+true
+ConcreteTypeTag[AnyRef]
+true
+ConcreteTypeTag[Null]
+true
+ConcreteTypeTag[Nothing]
+true
+ConcreteTypeTag[String]
diff --git a/test/files/run/concretetypetags_core.scala b/test/files/run/concretetypetags_core.scala
new file mode 100644
index 0000000000..b6cfea3895
--- /dev/null
+++ b/test/files/run/concretetypetags_core.scala
@@ -0,0 +1,34 @@
+object Test extends App {
+ println(implicitly[ConcreteTypeTag[Byte]] eq ConcreteTypeTag.Byte)
+ println(implicitly[ConcreteTypeTag[Byte]])
+ println(implicitly[ConcreteTypeTag[Short]] eq ConcreteTypeTag.Short)
+ println(implicitly[ConcreteTypeTag[Short]])
+ println(implicitly[ConcreteTypeTag[Char]] eq ConcreteTypeTag.Char)
+ println(implicitly[ConcreteTypeTag[Char]])
+ println(implicitly[ConcreteTypeTag[Int]] eq ConcreteTypeTag.Int)
+ println(implicitly[ConcreteTypeTag[Int]])
+ println(implicitly[ConcreteTypeTag[Long]] eq ConcreteTypeTag.Long)
+ println(implicitly[ConcreteTypeTag[Long]])
+ println(implicitly[ConcreteTypeTag[Float]] eq ConcreteTypeTag.Float)
+ println(implicitly[ConcreteTypeTag[Float]])
+ println(implicitly[ConcreteTypeTag[Double]] eq ConcreteTypeTag.Double)
+ println(implicitly[ConcreteTypeTag[Double]])
+ println(implicitly[ConcreteTypeTag[Boolean]] eq ConcreteTypeTag.Boolean)
+ println(implicitly[ConcreteTypeTag[Boolean]])
+ println(implicitly[ConcreteTypeTag[Unit]] eq ConcreteTypeTag.Unit)
+ println(implicitly[ConcreteTypeTag[Unit]])
+ println(implicitly[ConcreteTypeTag[Any]] eq ConcreteTypeTag.Any)
+ println(implicitly[ConcreteTypeTag[Any]])
+ println(implicitly[ConcreteTypeTag[Object]] eq ConcreteTypeTag.Object)
+ println(implicitly[ConcreteTypeTag[Object]])
+ println(implicitly[ConcreteTypeTag[AnyVal]] eq ConcreteTypeTag.AnyVal)
+ println(implicitly[ConcreteTypeTag[AnyVal]])
+ println(implicitly[ConcreteTypeTag[AnyRef]] eq ConcreteTypeTag.AnyRef)
+ println(implicitly[ConcreteTypeTag[AnyRef]])
+ println(implicitly[ConcreteTypeTag[Null]] eq ConcreteTypeTag.Null)
+ println(implicitly[ConcreteTypeTag[Null]])
+ println(implicitly[ConcreteTypeTag[Nothing]] eq ConcreteTypeTag.Nothing)
+ println(implicitly[ConcreteTypeTag[Nothing]])
+ println(implicitly[ConcreteTypeTag[String]] eq ConcreteTypeTag.String)
+ println(implicitly[ConcreteTypeTag[String]])
+} \ No newline at end of file
diff --git a/test/files/run/concretetypetags_multi.check b/test/files/run/concretetypetags_multi.check
new file mode 100644
index 0000000000..613106985c
--- /dev/null
+++ b/test/files/run/concretetypetags_multi.check
@@ -0,0 +1,5 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[Array[Int]]
+ConcreteTypeTag[Array[Array[Int]]]
+ConcreteTypeTag[Array[Array[Array[Int]]]]
+ConcreteTypeTag[Array[Array[Array[Array[Int]]]]]
diff --git a/test/files/run/concretetypetags_multi.scala b/test/files/run/concretetypetags_multi.scala
new file mode 100644
index 0000000000..7e19d7db34
--- /dev/null
+++ b/test/files/run/concretetypetags_multi.scala
@@ -0,0 +1,7 @@
+object Test extends App {
+ println(concreteTypeTag[Int])
+ println(concreteTypeTag[Array[Int]])
+ println(concreteTypeTag[Array[Array[Int]]])
+ println(concreteTypeTag[Array[Array[Array[Int]]]])
+ println(concreteTypeTag[Array[Array[Array[Array[Int]]]]])
+} \ No newline at end of file
diff --git a/test/files/run/concurrent-map-conversions.scala b/test/files/run/concurrent-map-conversions.scala
new file mode 100644
index 0000000000..0350b69642
--- /dev/null
+++ b/test/files/run/concurrent-map-conversions.scala
@@ -0,0 +1,36 @@
+
+
+
+
+
+object Test {
+
+ def main(args: Array[String]) {
+ testConversions()
+ testConverters()
+ }
+
+ def needPackageConcurrentMap(map: collection.concurrent.Map[Int, Int]) {
+ }
+ def needJavaConcurrent(map: java.util.concurrent.ConcurrentMap[Int, Int]) {
+ }
+
+ def testConversions() {
+ import collection.JavaConversions._
+ val skiplist = new java.util.concurrent.ConcurrentSkipListMap[Int, Int]
+ val ctrie = new collection.concurrent.TrieMap[Int, Int]
+
+ needPackageConcurrentMap(skiplist)
+ needJavaConcurrent(ctrie)
+ }
+
+ def testConverters() {
+ import collection.JavaConverters._
+ val skiplist = new java.util.concurrent.ConcurrentSkipListMap[Int, Int]
+ val ctrie = new collection.concurrent.TrieMap[Int, Int]
+
+ needPackageConcurrentMap(skiplist.asScala)
+ needJavaConcurrent(ctrie.asJava)
+ }
+
+}
diff --git a/test/files/run/constrained-types.check b/test/files/run/constrained-types.check
index ac8817cb08..37784a20ca 100644
--- a/test/files/run/constrained-types.check
+++ b/test/files/run/constrained-types.check
@@ -75,9 +75,13 @@ scala> var four = "four"
four: String = four
scala> val four2 = m(four) // should have an existential bound
+warning: there were 1 feature warnings; re-run with -feature for details
+warning: there were 1 feature warnings; re-run with -feature for details
four2: String @Annot(x) forSome { val x: String } = four
scala> val four3 = four2 // should have the same type as four2
+warning: there were 1 feature warnings; re-run with -feature for details
+warning: there were 1 feature warnings; re-run with -feature for details
four3: String @Annot(x) forSome { val x: String } = four
scala> val stuff = m("stuff") // should not crash
@@ -100,6 +104,8 @@ scala> def m = {
val y : String @Annot(x) = x
y
} // x should not escape the local scope with a narrow type
+warning: there were 1 feature warnings; re-run with -feature for details
+warning: there were 1 feature warnings; re-run with -feature for details
m: String @Annot(x) forSome { val x: String }
scala>
@@ -113,6 +119,7 @@ scala> def n(y: String) = {
}
m("stuff".stripMargin)
} // x should be existentially bound
+warning: there were 1 feature warnings; re-run with -feature for details
n: (y: String)String @Annot(x) forSome { val x: String }
scala>
diff --git a/test/files/run/ctries/DumbHash.scala b/test/files/run/ctries-new/DumbHash.scala
index 8ef325b67c..8ef325b67c 100644
--- a/test/files/run/ctries/DumbHash.scala
+++ b/test/files/run/ctries-new/DumbHash.scala
diff --git a/test/files/run/ctries/Wrap.scala b/test/files/run/ctries-new/Wrap.scala
index 7b645c1612..7b645c1612 100644
--- a/test/files/run/ctries/Wrap.scala
+++ b/test/files/run/ctries-new/Wrap.scala
diff --git a/test/files/run/ctries/concmap.scala b/test/files/run/ctries-new/concmap.scala
index bf8cc9d12f..3ec0256afb 100644
--- a/test/files/run/ctries/concmap.scala
+++ b/test/files/run/ctries-new/concmap.scala
@@ -1,7 +1,7 @@
-import collection.mutable.ConcurrentTrieMap
+import collection.concurrent.TrieMap
object ConcurrentMapSpec extends Spec {
@@ -11,13 +11,13 @@ object ConcurrentMapSpec extends Spec {
def test() {
"support put" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) assert(ct.put(new Wrap(i), i) == None)
for (i <- 0 until initsz) assert(ct.put(new Wrap(i), -i) == Some(i))
}
"support put if absent" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) ct.update(new Wrap(i), i)
for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i))
for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i))
@@ -26,7 +26,7 @@ object ConcurrentMapSpec extends Spec {
}
"support remove if mapped to a specific value" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) ct.update(new Wrap(i), i)
for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), -i - 1) == false)
for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == true)
@@ -34,7 +34,7 @@ object ConcurrentMapSpec extends Spec {
}
"support replace if mapped to a specific value" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) ct.update(new Wrap(i), i)
for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i - 1, -i - 2) == false)
for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == true)
@@ -43,7 +43,7 @@ object ConcurrentMapSpec extends Spec {
}
"support replace if present" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) ct.update(new Wrap(i), i)
for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i) == Some(i))
for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i) == Some(-i))
@@ -56,7 +56,7 @@ object ConcurrentMapSpec extends Spec {
}
"support replace if mapped to a specific value, using several threads" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
val sz = 55000
for (i <- 0 until sz) ct.update(new Wrap(i), i)
@@ -89,7 +89,7 @@ object ConcurrentMapSpec extends Spec {
}
"support put if absent, several threads" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
val sz = 110000
class Updater(offs: Int) extends Thread {
@@ -110,7 +110,7 @@ object ConcurrentMapSpec extends Spec {
}
"support remove if mapped to a specific value, several threads" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
val sz = 55000
for (i <- 0 until sz) ct.update(new Wrap(i), i)
@@ -132,7 +132,7 @@ object ConcurrentMapSpec extends Spec {
}
"have all or none of the elements depending on the oddity" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
val sz = 65000
for (i <- 0 until sz) ct(new Wrap(i)) = i
@@ -165,7 +165,7 @@ object ConcurrentMapSpec extends Spec {
}
"compute size correctly" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
val sz = 36450
for (i <- 0 until sz) ct(new Wrap(i)) = i
@@ -174,7 +174,7 @@ object ConcurrentMapSpec extends Spec {
}
"compute size correctly in parallel" in {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
val sz = 36450
for (i <- 0 until sz) ct(new Wrap(i)) = i
val pct = ct.par
diff --git a/test/files/run/ctries/iterator.scala b/test/files/run/ctries-new/iterator.scala
index dbfab6b8a9..b953a40e00 100644
--- a/test/files/run/ctries/iterator.scala
+++ b/test/files/run/ctries-new/iterator.scala
@@ -3,7 +3,7 @@
import collection._
-import collection.mutable.ConcurrentTrieMap
+import collection.concurrent.TrieMap
@@ -11,7 +11,7 @@ object IteratorSpec extends Spec {
def test() {
"work for an empty trie" in {
- val ct = new ConcurrentTrieMap
+ val ct = new TrieMap
val it = ct.iterator
it.hasNext shouldEqual (false)
@@ -19,7 +19,7 @@ object IteratorSpec extends Spec {
}
def nonEmptyIteratorCheck(sz: Int) {
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.put(new Wrap(i), i)
val it = ct.iterator
@@ -84,7 +84,7 @@ object IteratorSpec extends Spec {
}
def nonEmptyCollideCheck(sz: Int) {
- val ct = new ConcurrentTrieMap[DumbHash, Int]
+ val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until sz) ct.put(new DumbHash(i), i)
val it = ct.iterator
@@ -144,7 +144,7 @@ object IteratorSpec extends Spec {
val W = 15
val S = 5
val checks = 5
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.put(new Wrap(i), i)
class Modifier extends Thread {
@@ -156,7 +156,7 @@ object IteratorSpec extends Spec {
}
}
- def consistentIteration(ct: ConcurrentTrieMap[Wrap, Int], checks: Int) {
+ def consistentIteration(ct: TrieMap[Wrap, Int], checks: Int) {
class Iter extends Thread {
override def run() {
val snap = ct.readOnlySnapshot()
@@ -185,7 +185,7 @@ object IteratorSpec extends Spec {
val sgroupsize = 10
val sgroupnum = 5
val removerslowdown = 50
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.put(new Wrap(i), i)
class Remover extends Thread {
@@ -227,7 +227,7 @@ object IteratorSpec extends Spec {
val sgroupsize = 10
val sgroupnum = 10
val inserterslowdown = 50
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
class Inserter extends Thread {
override def run() {
@@ -265,7 +265,7 @@ object IteratorSpec extends Spec {
"work on a yet unevaluated snapshot" in {
val sz = 50000
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.update(new Wrap(i), i)
val snap = ct.snapshot()
@@ -276,7 +276,7 @@ object IteratorSpec extends Spec {
"be duplicated" in {
val sz = 50
- val ct = collection.parallel.mutable.ParConcurrentTrieMap((0 until sz) zip (0 until sz): _*)
+ val ct = collection.parallel.mutable.ParTrieMap((0 until sz) zip (0 until sz): _*)
val it = ct.splitter
for (_ <- 0 until (sz / 2)) it.next()
val dupit = it.dup
diff --git a/test/files/run/ctries/lnode.scala b/test/files/run/ctries-new/lnode.scala
index e480795956..92a31088e5 100644
--- a/test/files/run/ctries/lnode.scala
+++ b/test/files/run/ctries-new/lnode.scala
@@ -1,7 +1,7 @@
-import collection.mutable.ConcurrentTrieMap
+import collection.concurrent.TrieMap
object LNodeSpec extends Spec {
@@ -11,19 +11,19 @@ object LNodeSpec extends Spec {
def test() {
"accept elements with the same hash codes" in {
- val ct = new ConcurrentTrieMap[DumbHash, Int]
+ val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
}
"lookup elements with the same hash codes" in {
- val ct = new ConcurrentTrieMap[DumbHash, Int]
+ val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == Some(i))
for (i <- initsz until secondsz) assert(ct.get(new DumbHash(i)) == None)
}
"remove elements with the same hash codes" in {
- val ct = new ConcurrentTrieMap[DumbHash, Int]
+ val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
for (i <- 0 until initsz) {
val remelem = ct.remove(new DumbHash(i))
@@ -33,7 +33,7 @@ object LNodeSpec extends Spec {
}
"put elements with the same hash codes if absent" in {
- val ct = new ConcurrentTrieMap[DumbHash, Int]
+ val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) ct.put(new DumbHash(i), i)
for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i)
for (i <- 0 until initsz) assert(ct.putIfAbsent(new DumbHash(i), i) == Some(i))
@@ -42,7 +42,7 @@ object LNodeSpec extends Spec {
}
"replace elements with the same hash codes" in {
- val ct = new ConcurrentTrieMap[DumbHash, Int]
+ val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None)
for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i)
for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i) == Some(i))
@@ -51,7 +51,7 @@ object LNodeSpec extends Spec {
}
"remove elements with the same hash codes if mapped to a specific value" in {
- val ct = new ConcurrentTrieMap[DumbHash, Int]
+ val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None)
for (i <- 0 until initsz) assert(ct.remove(new DumbHash(i), i) == true)
}
diff --git a/test/files/run/ctries-new/main.scala b/test/files/run/ctries-new/main.scala
new file mode 100644
index 0000000000..1d40dab6c5
--- /dev/null
+++ b/test/files/run/ctries-new/main.scala
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+object Test {
+
+ def main(args: Array[String]) {
+ ConcurrentMapSpec.test()
+ IteratorSpec.test()
+ LNodeSpec.test()
+ SnapshotSpec.test()
+ }
+
+}
+
+
+trait Spec {
+
+ implicit def str2ops(s: String) = new {
+ def in[U](body: =>U) {
+ // just execute body
+ body
+ }
+ }
+
+ implicit def any2ops(a: Any) = new {
+ def shouldEqual(other: Any) = assert(a == other)
+ }
+
+ def evaluating[U](body: =>U) = new {
+ def shouldProduce[T <: Throwable: ClassTag]() = {
+ var produced = false
+ try body
+ catch {
+ case e => if (e.getClass == implicitly[ClassTag[T]].erasure) produced = true
+ } finally {
+ assert(produced, "Did not produce exception of type: " + implicitly[ClassTag[T]])
+ }
+ }
+ }
+
+}
diff --git a/test/files/run/ctries/snapshot.scala b/test/files/run/ctries-new/snapshot.scala
index 3c816130b3..5fe77d445b 100644
--- a/test/files/run/ctries/snapshot.scala
+++ b/test/files/run/ctries-new/snapshot.scala
@@ -3,7 +3,7 @@
import collection._
-import collection.mutable.ConcurrentTrieMap
+import collection.concurrent.TrieMap
@@ -11,11 +11,11 @@ object SnapshotSpec extends Spec {
def test() {
"support snapshots" in {
- val ctn = new ConcurrentTrieMap
+ val ctn = new TrieMap
ctn.snapshot()
ctn.readOnlySnapshot()
- val ct = new ConcurrentTrieMap[Int, Int]
+ val ct = new TrieMap[Int, Int]
for (i <- 0 until 100) ct.put(i, i)
ct.snapshot()
ct.readOnlySnapshot()
@@ -24,7 +24,7 @@ object SnapshotSpec extends Spec {
"empty 2 quiescent snapshots in isolation" in {
val sz = 4000
- class Worker(trie: ConcurrentTrieMap[Wrap, Int]) extends Thread {
+ class Worker(trie: TrieMap[Wrap, Int]) extends Thread {
override def run() {
for (i <- 0 until sz) {
assert(trie.remove(new Wrap(i)) == Some(i))
@@ -35,7 +35,7 @@ object SnapshotSpec extends Spec {
}
}
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.put(new Wrap(i), i)
val snapt = ct.snapshot()
@@ -96,7 +96,7 @@ object SnapshotSpec extends Spec {
}
// traverses the trie `rep` times and modifies each entry
- class Modifier(trie: ConcurrentTrieMap[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread {
+ class Modifier(trie: TrieMap[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread {
setName("Modifier %d".format(index))
override def run() {
@@ -110,7 +110,7 @@ object SnapshotSpec extends Spec {
}
// removes all the elements from the trie
- class Remover(trie: ConcurrentTrieMap[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread {
+ class Remover(trie: TrieMap[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread {
setName("Remover %d".format(index))
override def run() {
@@ -123,7 +123,7 @@ object SnapshotSpec extends Spec {
val N = 100
val W = 10
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
val readonly = ct.readOnlySnapshot()
val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
@@ -141,7 +141,7 @@ object SnapshotSpec extends Spec {
val W = 100
val S = 5000
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
val threads = for (i <- 0 until W) yield new Remover(ct, i, W, sz)
@@ -156,7 +156,7 @@ object SnapshotSpec extends Spec {
val W = 10
val S = 7000
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
@@ -165,7 +165,7 @@ object SnapshotSpec extends Spec {
threads.foreach(_.join())
}
- def consistentNonReadOnly(name: String, trie: ConcurrentTrieMap[Wrap, Int], sz: Int, N: Int) {
+ def consistentNonReadOnly(name: String, trie: TrieMap[Wrap, Int], sz: Int, N: Int) {
@volatile var e: Exception = null
// reads possible entries once and stores them
@@ -223,7 +223,7 @@ object SnapshotSpec extends Spec {
val W = 10
val S = 400
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
@@ -241,7 +241,7 @@ object SnapshotSpec extends Spec {
val S = 10
val modifytimes = 1200
val snaptimes = 600
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
class Snapshooter extends Thread {
diff --git a/test/files/run/ctries-old/DumbHash.scala b/test/files/run/ctries-old/DumbHash.scala
new file mode 100644
index 0000000000..8ef325b67c
--- /dev/null
+++ b/test/files/run/ctries-old/DumbHash.scala
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+class DumbHash(val i: Int) {
+ override def equals(other: Any) = other match {
+ case that: DumbHash => that.i == this.i
+ case _ => false
+ }
+ override def hashCode = i % 5
+ override def toString = "DH(%s)".format(i)
+}
diff --git a/test/files/run/ctries-old/Wrap.scala b/test/files/run/ctries-old/Wrap.scala
new file mode 100644
index 0000000000..7b645c1612
--- /dev/null
+++ b/test/files/run/ctries-old/Wrap.scala
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+case class Wrap(i: Int) {
+ override def hashCode = i * 0x9e3775cd
+}
diff --git a/test/files/run/ctries-old/concmap.scala b/test/files/run/ctries-old/concmap.scala
new file mode 100644
index 0000000000..3ec0256afb
--- /dev/null
+++ b/test/files/run/ctries-old/concmap.scala
@@ -0,0 +1,188 @@
+
+
+
+import collection.concurrent.TrieMap
+
+
+object ConcurrentMapSpec extends Spec {
+
+ val initsz = 500
+ val secondsz = 750
+
+ def test() {
+ "support put" in {
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until initsz) assert(ct.put(new Wrap(i), i) == None)
+ for (i <- 0 until initsz) assert(ct.put(new Wrap(i), -i) == Some(i))
+ }
+
+ "support put if absent" in {
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until initsz) ct.update(new Wrap(i), i)
+ for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i))
+ for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i))
+ for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), -i) == None)
+ for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), i) == Some(-i))
+ }
+
+ "support remove if mapped to a specific value" in {
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until initsz) ct.update(new Wrap(i), i)
+ for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), -i - 1) == false)
+ for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == true)
+ for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == false)
+ }
+
+ "support replace if mapped to a specific value" in {
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until initsz) ct.update(new Wrap(i), i)
+ for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i - 1, -i - 2) == false)
+ for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == true)
+ for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == false)
+ for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i, 0) == false)
+ }
+
+ "support replace if present" in {
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until initsz) ct.update(new Wrap(i), i)
+ for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i) == Some(i))
+ for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i) == Some(-i))
+ for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i) == None)
+ }
+
+ def assertEqual(a: Any, b: Any) = {
+ if (a != b) println(a, b)
+ assert(a == b)
+ }
+
+ "support replace if mapped to a specific value, using several threads" in {
+ val ct = new TrieMap[Wrap, Int]
+ val sz = 55000
+ for (i <- 0 until sz) ct.update(new Wrap(i), i)
+
+ class Updater(index: Int, offs: Int) extends Thread {
+ override def run() {
+ var repeats = 0
+ for (i <- 0 until sz) {
+ val j = (offs + i) % sz
+ var k = Int.MaxValue
+ do {
+ if (k != Int.MaxValue) repeats += 1
+ k = ct.lookup(new Wrap(j))
+ } while (!ct.replace(new Wrap(j), k, -k))
+ }
+ //println("Thread %d repeats: %d".format(index, repeats))
+ }
+ }
+
+ val threads = for (i <- 0 until 16) yield new Updater(i, sz / 32 * i)
+ threads.foreach(_.start())
+ threads.foreach(_.join())
+
+ for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), i)
+
+ val threads2 = for (i <- 0 until 15) yield new Updater(i, sz / 32 * i)
+ threads2.foreach(_.start())
+ threads2.foreach(_.join())
+
+ for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), -i)
+ }
+
+ "support put if absent, several threads" in {
+ val ct = new TrieMap[Wrap, Int]
+ val sz = 110000
+
+ class Updater(offs: Int) extends Thread {
+ override def run() {
+ for (i <- 0 until sz) {
+ val j = (offs + i) % sz
+ ct.putIfAbsent(new Wrap(j), j)
+ assert(ct.lookup(new Wrap(j)) == j)
+ }
+ }
+ }
+
+ val threads = for (i <- 0 until 16) yield new Updater(sz / 32 * i)
+ threads.foreach(_.start())
+ threads.foreach(_.join())
+
+ for (i <- 0 until sz) assert(ct(new Wrap(i)) == i)
+ }
+
+ "support remove if mapped to a specific value, several threads" in {
+ val ct = new TrieMap[Wrap, Int]
+ val sz = 55000
+ for (i <- 0 until sz) ct.update(new Wrap(i), i)
+
+ class Remover(offs: Int) extends Thread {
+ override def run() {
+ for (i <- 0 until sz) {
+ val j = (offs + i) % sz
+ ct.remove(new Wrap(j), j)
+ assert(ct.get(new Wrap(j)) == None)
+ }
+ }
+ }
+
+ val threads = for (i <- 0 until 16) yield new Remover(sz / 32 * i)
+ threads.foreach(_.start())
+ threads.foreach(_.join())
+
+ for (i <- 0 until sz) assert(ct.get(new Wrap(i)) == None)
+ }
+
+ "have all or none of the elements depending on the oddity" in {
+ val ct = new TrieMap[Wrap, Int]
+ val sz = 65000
+ for (i <- 0 until sz) ct(new Wrap(i)) = i
+
+ class Modifier(index: Int, offs: Int) extends Thread {
+ override def run() {
+ for (j <- 0 until sz) {
+ val i = (offs + j) % sz
+ var success = false
+ do {
+ if (ct.contains(new Wrap(i))) {
+ success = ct.remove(new Wrap(i)) != None
+ } else {
+ success = ct.putIfAbsent(new Wrap(i), i) == None
+ }
+ } while (!success)
+ }
+ }
+ }
+
+ def modify(n: Int) = {
+ val threads = for (i <- 0 until n) yield new Modifier(i, sz / n * i)
+ threads.foreach(_.start())
+ threads.foreach(_.join())
+ }
+
+ modify(16)
+ for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), Some(i))
+ modify(15)
+ for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), None)
+ }
+
+ "compute size correctly" in {
+ val ct = new TrieMap[Wrap, Int]
+ val sz = 36450
+ for (i <- 0 until sz) ct(new Wrap(i)) = i
+
+ assertEqual(ct.size, sz)
+ assertEqual(ct.size, sz)
+ }
+
+ "compute size correctly in parallel" in {
+ val ct = new TrieMap[Wrap, Int]
+ val sz = 36450
+ for (i <- 0 until sz) ct(new Wrap(i)) = i
+ val pct = ct.par
+
+ assertEqual(pct.size, sz)
+ assertEqual(pct.size, sz)
+ }
+
+ }
+
+}
diff --git a/test/files/run/ctries-old/iterator.scala b/test/files/run/ctries-old/iterator.scala
new file mode 100644
index 0000000000..b953a40e00
--- /dev/null
+++ b/test/files/run/ctries-old/iterator.scala
@@ -0,0 +1,289 @@
+
+
+
+
+import collection._
+import collection.concurrent.TrieMap
+
+
+
+object IteratorSpec extends Spec {
+
+ def test() {
+ "work for an empty trie" in {
+ val ct = new TrieMap
+ val it = ct.iterator
+
+ it.hasNext shouldEqual (false)
+ evaluating { it.next() }.shouldProduce [NoSuchElementException]
+ }
+
+ def nonEmptyIteratorCheck(sz: Int) {
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct.put(new Wrap(i), i)
+
+ val it = ct.iterator
+ val tracker = mutable.Map[Wrap, Int]()
+ for (i <- 0 until sz) {
+ assert(it.hasNext == true)
+ tracker += it.next
+ }
+
+ it.hasNext shouldEqual (false)
+ evaluating { it.next() }.shouldProduce [NoSuchElementException]
+ tracker.size shouldEqual (sz)
+ tracker shouldEqual (ct)
+ }
+
+ "work for a 1 element trie" in {
+ nonEmptyIteratorCheck(1)
+ }
+
+ "work for a 2 element trie" in {
+ nonEmptyIteratorCheck(2)
+ }
+
+ "work for a 3 element trie" in {
+ nonEmptyIteratorCheck(3)
+ }
+
+ "work for a 5 element trie" in {
+ nonEmptyIteratorCheck(5)
+ }
+
+ "work for a 10 element trie" in {
+ nonEmptyIteratorCheck(10)
+ }
+
+ "work for a 20 element trie" in {
+ nonEmptyIteratorCheck(20)
+ }
+
+ "work for a 50 element trie" in {
+ nonEmptyIteratorCheck(50)
+ }
+
+ "work for a 100 element trie" in {
+ nonEmptyIteratorCheck(100)
+ }
+
+ "work for a 1k element trie" in {
+ nonEmptyIteratorCheck(1000)
+ }
+
+ "work for a 5k element trie" in {
+ nonEmptyIteratorCheck(5000)
+ }
+
+ "work for a 75k element trie" in {
+ nonEmptyIteratorCheck(75000)
+ }
+
+ "work for a 250k element trie" in {
+ nonEmptyIteratorCheck(500000)
+ }
+
+ def nonEmptyCollideCheck(sz: Int) {
+ val ct = new TrieMap[DumbHash, Int]
+ for (i <- 0 until sz) ct.put(new DumbHash(i), i)
+
+ val it = ct.iterator
+ val tracker = mutable.Map[DumbHash, Int]()
+ for (i <- 0 until sz) {
+ assert(it.hasNext == true)
+ tracker += it.next
+ }
+
+ it.hasNext shouldEqual (false)
+ evaluating { it.next() }.shouldProduce [NoSuchElementException]
+ tracker.size shouldEqual (sz)
+ tracker shouldEqual (ct)
+ }
+
+ "work for colliding hashcodes, 2 element trie" in {
+ nonEmptyCollideCheck(2)
+ }
+
+ "work for colliding hashcodes, 3 element trie" in {
+ nonEmptyCollideCheck(3)
+ }
+
+ "work for colliding hashcodes, 5 element trie" in {
+ nonEmptyCollideCheck(5)
+ }
+
+ "work for colliding hashcodes, 10 element trie" in {
+ nonEmptyCollideCheck(10)
+ }
+
+ "work for colliding hashcodes, 100 element trie" in {
+ nonEmptyCollideCheck(100)
+ }
+
+ "work for colliding hashcodes, 500 element trie" in {
+ nonEmptyCollideCheck(500)
+ }
+
+ "work for colliding hashcodes, 5k element trie" in {
+ nonEmptyCollideCheck(5000)
+ }
+
+ def assertEqual(a: Map[Wrap, Int], b: Map[Wrap, Int]) {
+ if (a != b) {
+ println(a.size + " vs " + b.size)
+ // println(a)
+ // println(b)
+ // println(a.toSeq.sortBy((x: (Wrap, Int)) => x._1.i))
+ // println(b.toSeq.sortBy((x: (Wrap, Int)) => x._1.i))
+ }
+ assert(a == b)
+ }
+
+ "be consistent when taken with concurrent modifications" in {
+ val sz = 25000
+ val W = 15
+ val S = 5
+ val checks = 5
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct.put(new Wrap(i), i)
+
+ class Modifier extends Thread {
+ override def run() {
+ for (i <- 0 until sz) ct.putIfAbsent(new Wrap(i), i) match {
+ case Some(_) => ct.remove(new Wrap(i))
+ case None =>
+ }
+ }
+ }
+
+ def consistentIteration(ct: TrieMap[Wrap, Int], checks: Int) {
+ class Iter extends Thread {
+ override def run() {
+ val snap = ct.readOnlySnapshot()
+ val initial = mutable.Map[Wrap, Int]()
+ for (kv <- snap) initial += kv
+
+ for (i <- 0 until checks) {
+ assertEqual(snap.iterator.toMap, initial)
+ }
+ }
+ }
+
+ val iter = new Iter
+ iter.start()
+ iter.join()
+ }
+
+ val threads = for (_ <- 0 until W) yield new Modifier
+ threads.foreach(_.start())
+ for (_ <- 0 until S) consistentIteration(ct, checks)
+ threads.foreach(_.join())
+ }
+
+ "be consistent with a concurrent removal with a well defined order" in {
+ val sz = 150000
+ val sgroupsize = 10
+ val sgroupnum = 5
+ val removerslowdown = 50
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct.put(new Wrap(i), i)
+
+ class Remover extends Thread {
+ override def run() {
+ for (i <- 0 until sz) {
+ assert(ct.remove(new Wrap(i)) == Some(i))
+ for (i <- 0 until removerslowdown) ct.get(new Wrap(i)) // slow down, mate
+ }
+ //println("done removing")
+ }
+ }
+
+ def consistentIteration(it: Iterator[(Wrap, Int)]) = {
+ class Iter extends Thread {
+ override def run() {
+ val elems = it.toBuffer
+ if (elems.nonEmpty) {
+ val minelem = elems.minBy((x: (Wrap, Int)) => x._1.i)._1.i
+ assert(elems.forall(_._1.i >= minelem))
+ }
+ }
+ }
+ new Iter
+ }
+
+ val remover = new Remover
+ remover.start()
+ for (_ <- 0 until sgroupnum) {
+ val iters = for (_ <- 0 until sgroupsize) yield consistentIteration(ct.iterator)
+ iters.foreach(_.start())
+ iters.foreach(_.join())
+ }
+ //println("done with iterators")
+ remover.join()
+ }
+
+ "be consistent with a concurrent insertion with a well defined order" in {
+ val sz = 150000
+ val sgroupsize = 10
+ val sgroupnum = 10
+ val inserterslowdown = 50
+ val ct = new TrieMap[Wrap, Int]
+
+ class Inserter extends Thread {
+ override def run() {
+ for (i <- 0 until sz) {
+ assert(ct.put(new Wrap(i), i) == None)
+ for (i <- 0 until inserterslowdown) ct.get(new Wrap(i)) // slow down, mate
+ }
+ //println("done inserting")
+ }
+ }
+
+ def consistentIteration(it: Iterator[(Wrap, Int)]) = {
+ class Iter extends Thread {
+ override def run() {
+ val elems = it.toSeq
+ if (elems.nonEmpty) {
+ val maxelem = elems.maxBy((x: (Wrap, Int)) => x._1.i)._1.i
+ assert(elems.forall(_._1.i <= maxelem))
+ }
+ }
+ }
+ new Iter
+ }
+
+ val inserter = new Inserter
+ inserter.start()
+ for (_ <- 0 until sgroupnum) {
+ val iters = for (_ <- 0 until sgroupsize) yield consistentIteration(ct.iterator)
+ iters.foreach(_.start())
+ iters.foreach(_.join())
+ }
+ //println("done with iterators")
+ inserter.join()
+ }
+
+ "work on a yet unevaluated snapshot" in {
+ val sz = 50000
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct.update(new Wrap(i), i)
+
+ val snap = ct.snapshot()
+ val it = snap.iterator
+
+ while (it.hasNext) it.next()
+ }
+
+ "be duplicated" in {
+ val sz = 50
+ val ct = collection.parallel.mutable.ParTrieMap((0 until sz) zip (0 until sz): _*)
+ val it = ct.splitter
+ for (_ <- 0 until (sz / 2)) it.next()
+ val dupit = it.dup
+
+ it.toList shouldEqual dupit.toList
+ }
+
+ }
+
+}
diff --git a/test/files/run/ctries-old/lnode.scala b/test/files/run/ctries-old/lnode.scala
new file mode 100644
index 0000000000..92a31088e5
--- /dev/null
+++ b/test/files/run/ctries-old/lnode.scala
@@ -0,0 +1,61 @@
+
+
+
+import collection.concurrent.TrieMap
+
+
+object LNodeSpec extends Spec {
+
+ val initsz = 1500
+ val secondsz = 1750
+
+ def test() {
+ "accept elements with the same hash codes" in {
+ val ct = new TrieMap[DumbHash, Int]
+ for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
+ }
+
+ "lookup elements with the same hash codes" in {
+ val ct = new TrieMap[DumbHash, Int]
+ for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
+ for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == Some(i))
+ for (i <- initsz until secondsz) assert(ct.get(new DumbHash(i)) == None)
+ }
+
+ "remove elements with the same hash codes" in {
+ val ct = new TrieMap[DumbHash, Int]
+ for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
+ for (i <- 0 until initsz) {
+ val remelem = ct.remove(new DumbHash(i))
+ assert(remelem == Some(i), "removing " + i + " yields " + remelem)
+ }
+ for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == None)
+ }
+
+ "put elements with the same hash codes if absent" in {
+ val ct = new TrieMap[DumbHash, Int]
+ for (i <- 0 until initsz) ct.put(new DumbHash(i), i)
+ for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i)
+ for (i <- 0 until initsz) assert(ct.putIfAbsent(new DumbHash(i), i) == Some(i))
+ for (i <- initsz until secondsz) assert(ct.putIfAbsent(new DumbHash(i), i) == None)
+ for (i <- initsz until secondsz) assert(ct.lookup(new DumbHash(i)) == i)
+ }
+
+ "replace elements with the same hash codes" in {
+ val ct = new TrieMap[DumbHash, Int]
+ for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None)
+ for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == i)
+ for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i) == Some(i))
+ for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == -i)
+ for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i, i) == true)
+ }
+
+ "remove elements with the same hash codes if mapped to a specific value" in {
+ val ct = new TrieMap[DumbHash, Int]
+ for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None)
+ for (i <- 0 until initsz) assert(ct.remove(new DumbHash(i), i) == true)
+ }
+
+ }
+
+}
diff --git a/test/files/run/ctries/main.scala b/test/files/run/ctries-old/main.scala
index 8db7fcef54..8db7fcef54 100644
--- a/test/files/run/ctries/main.scala
+++ b/test/files/run/ctries-old/main.scala
diff --git a/test/files/run/ctries-old/snapshot.scala b/test/files/run/ctries-old/snapshot.scala
new file mode 100644
index 0000000000..5fe77d445b
--- /dev/null
+++ b/test/files/run/ctries-old/snapshot.scala
@@ -0,0 +1,267 @@
+
+
+
+
+import collection._
+import collection.concurrent.TrieMap
+
+
+
+object SnapshotSpec extends Spec {
+
+ def test() {
+ "support snapshots" in {
+ val ctn = new TrieMap
+ ctn.snapshot()
+ ctn.readOnlySnapshot()
+
+ val ct = new TrieMap[Int, Int]
+ for (i <- 0 until 100) ct.put(i, i)
+ ct.snapshot()
+ ct.readOnlySnapshot()
+ }
+
+ "empty 2 quiescent snapshots in isolation" in {
+ val sz = 4000
+
+ class Worker(trie: TrieMap[Wrap, Int]) extends Thread {
+ override def run() {
+ for (i <- 0 until sz) {
+ assert(trie.remove(new Wrap(i)) == Some(i))
+ for (j <- 0 until sz)
+ if (j <= i) assert(trie.get(new Wrap(j)) == None)
+ else assert(trie.get(new Wrap(j)) == Some(j))
+ }
+ }
+ }
+
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct.put(new Wrap(i), i)
+ val snapt = ct.snapshot()
+
+ val original = new Worker(ct)
+ val snapshot = new Worker(snapt)
+ original.start()
+ snapshot.start()
+ original.join()
+ snapshot.join()
+
+ for (i <- 0 until sz) {
+ assert(ct.get(new Wrap(i)) == None)
+ assert(snapt.get(new Wrap(i)) == None)
+ }
+ }
+
+ def consistentReadOnly(name: String, readonly: Map[Wrap, Int], sz: Int, N: Int) {
+ @volatile var e: Exception = null
+
+ // reads possible entries once and stores them
+ // then reads all these N more times to check if the
+ // state stayed the same
+ class Reader(trie: Map[Wrap, Int]) extends Thread {
+ setName("Reader " + name)
+
+ override def run() =
+ try check()
+ catch {
+ case ex: Exception => e = ex
+ }
+
+ def check() {
+ val initial = mutable.Map[Wrap, Int]()
+ for (i <- 0 until sz) trie.get(new Wrap(i)) match {
+ case Some(i) => initial.put(new Wrap(i), i)
+ case None => // do nothing
+ }
+
+ for (k <- 0 until N) {
+ for (i <- 0 until sz) {
+ val tres = trie.get(new Wrap(i))
+ val ires = initial.get(new Wrap(i))
+ if (tres != ires) println(i, "initially: " + ires, "traversal %d: %s".format(k, tres))
+ assert(tres == ires)
+ }
+ }
+ }
+ }
+
+ val reader = new Reader(readonly)
+ reader.start()
+ reader.join()
+
+ if (e ne null) {
+ e.printStackTrace()
+ throw e
+ }
+ }
+
+ // traverses the trie `rep` times and modifies each entry
+ class Modifier(trie: TrieMap[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread {
+ setName("Modifier %d".format(index))
+
+ override def run() {
+ for (k <- 0 until rep) {
+ for (i <- 0 until sz) trie.putIfAbsent(new Wrap(i), i) match {
+ case Some(_) => trie.remove(new Wrap(i))
+ case None => // do nothing
+ }
+ }
+ }
+ }
+
+ // removes all the elements from the trie
+ class Remover(trie: TrieMap[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread {
+ setName("Remover %d".format(index))
+
+ override def run() {
+ for (i <- 0 until sz) trie.remove(new Wrap((i + sz / totremovers * index) % sz))
+ }
+ }
+
+ "have a consistent quiescent read-only snapshot" in {
+ val sz = 10000
+ val N = 100
+ val W = 10
+
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct(new Wrap(i)) = i
+ val readonly = ct.readOnlySnapshot()
+ val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
+
+ threads.foreach(_.start())
+ consistentReadOnly("qm", readonly, sz, N)
+ threads.foreach(_.join())
+ }
+
+ // now, we check non-quiescent snapshots, as these permit situations
+ // where a thread is caught in the middle of the update when a snapshot is taken
+
+ "have a consistent non-quiescent read-only snapshot, concurrent with removes only" in {
+ val sz = 1250
+ val W = 100
+ val S = 5000
+
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct(new Wrap(i)) = i
+ val threads = for (i <- 0 until W) yield new Remover(ct, i, W, sz)
+
+ threads.foreach(_.start())
+ for (i <- 0 until S) consistentReadOnly("non-qr", ct.readOnlySnapshot(), sz, 5)
+ threads.foreach(_.join())
+ }
+
+ "have a consistent non-quiescent read-only snapshot, concurrent with modifications" in {
+ val sz = 1000
+ val N = 7000
+ val W = 10
+ val S = 7000
+
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct(new Wrap(i)) = i
+ val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
+
+ threads.foreach(_.start())
+ for (i <- 0 until S) consistentReadOnly("non-qm", ct.readOnlySnapshot(), sz, 5)
+ threads.foreach(_.join())
+ }
+
+ def consistentNonReadOnly(name: String, trie: TrieMap[Wrap, Int], sz: Int, N: Int) {
+ @volatile var e: Exception = null
+
+ // reads possible entries once and stores them
+ // then reads all these N more times to check if the
+ // state stayed the same
+ class Worker extends Thread {
+ setName("Worker " + name)
+
+ override def run() =
+ try check()
+ catch {
+ case ex: Exception => e = ex
+ }
+
+ def check() {
+ val initial = mutable.Map[Wrap, Int]()
+ for (i <- 0 until sz) trie.get(new Wrap(i)) match {
+ case Some(i) => initial.put(new Wrap(i), i)
+ case None => // do nothing
+ }
+
+ for (k <- 0 until N) {
+ // modify
+ for ((key, value) <- initial) {
+ val oldv = if (k % 2 == 0) value else -value
+ val newv = -oldv
+ trie.replace(key, oldv, newv)
+ }
+
+ // check
+ for (i <- 0 until sz) if (initial.contains(new Wrap(i))) {
+ val expected = if (k % 2 == 0) -i else i
+ //println(trie.get(new Wrap(i)))
+ assert(trie.get(new Wrap(i)) == Some(expected))
+ } else {
+ assert(trie.get(new Wrap(i)) == None)
+ }
+ }
+ }
+ }
+
+ val worker = new Worker
+ worker.start()
+ worker.join()
+
+ if (e ne null) {
+ e.printStackTrace()
+ throw e
+ }
+ }
+
+ "have a consistent non-quiescent snapshot, concurrent with modifications" in {
+ val sz = 9000
+ val N = 1000
+ val W = 10
+ val S = 400
+
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct(new Wrap(i)) = i
+ val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
+
+ threads.foreach(_.start())
+ for (i <- 0 until S) {
+ consistentReadOnly("non-qm", ct.snapshot(), sz, 5)
+ consistentNonReadOnly("non-qsnap", ct.snapshot(), sz, 5)
+ }
+ threads.foreach(_.join())
+ }
+
+ "work when many concurrent snapshots are taken, concurrent with modifications" in {
+ val sz = 12000
+ val W = 10
+ val S = 10
+ val modifytimes = 1200
+ val snaptimes = 600
+ val ct = new TrieMap[Wrap, Int]
+ for (i <- 0 until sz) ct(new Wrap(i)) = i
+
+ class Snapshooter extends Thread {
+ setName("Snapshooter")
+ override def run() {
+ for (k <- 0 until snaptimes) {
+ val snap = ct.snapshot()
+ for (i <- 0 until sz) snap.remove(new Wrap(i))
+ for (i <- 0 until sz) assert(!snap.contains(new Wrap(i)))
+ }
+ }
+ }
+
+ val mods = for (i <- 0 until W) yield new Modifier(ct, i, modifytimes, sz)
+ val shooters = for (i <- 0 until S) yield new Snapshooter
+ val threads = mods ++ shooters
+ threads.foreach(_.start())
+ threads.foreach(_.join())
+ }
+
+ }
+
+}
diff --git a/test/files/run/delay-bad.check b/test/files/run/delay-bad.check
new file mode 100644
index 0000000000..9d9c828a03
--- /dev/null
+++ b/test/files/run/delay-bad.check
@@ -0,0 +1,47 @@
+
+
+// new C { }
+-A -B -C
+
+// new C { 5 }
+-A -B -C
+ A+ B+ C+
+
+// new D()
+-A -B -C -D
+ A+ B+ C+ D+
+
+// new D() { }
+-A -B -C -D
+ A+ B+ C+ D+
+
+// new D() { val x = 5 }
+-A -B -C -D
+ A+ B+ C+ D+
+ A+ B+ C+ D+
+
+// new { val x = 5 } with D()
+-A -B -C -D
+ A+ B+ C+ D+
+
+// new E() { val x = 5 }
+-A -B -C -D
+ A+ B+ C+ D+ E+ -E
+ A+ B+ C+ D+ E+
+ A+ B+ C+ D+ E+
+
+// new { val x = 5 } with E()
+-A -B -C -D
+ A+ B+ C+ D+ E+ -E
+ A+ B+ C+ D+ E+
+
+// new { val x = 5 } with E() { }
+-A -B -C -D
+ A+ B+ C+ D+ E+ -E
+ A+ B+ C+ D+ E+
+
+// new { val x = 5 } with E() { 5 }
+-A -B -C -D
+ A+ B+ C+ D+ E+ -E
+ A+ B+ C+ D+ E+
+ A+ B+ C+ D+ E+
diff --git a/test/files/run/delay-bad.scala b/test/files/run/delay-bad.scala
new file mode 100644
index 0000000000..43acc1ea3d
--- /dev/null
+++ b/test/files/run/delay-bad.scala
@@ -0,0 +1,77 @@
+trait A extends DelayedInit
+{
+ print("-A")
+
+ def delayedInit(body: => Unit) = {
+ body
+ postConstructionCode
+ }
+ def postConstructionCode: Unit = {
+ print("\n A+")
+ }
+}
+trait B extends A {
+ print(" -B")
+ override def postConstructionCode: Unit = {
+ super.postConstructionCode
+ print(" B+")
+ }
+}
+
+trait C extends B {
+ print(" -C")
+ override def postConstructionCode: Unit = {
+ super.postConstructionCode
+ print(" C+")
+ }
+}
+
+class D() extends C {
+ print(" -D")
+ override def postConstructionCode: Unit = {
+ super.postConstructionCode
+ print(" D+")
+ }
+}
+class E() extends D() {
+ print(" -E")
+ override def postConstructionCode: Unit = {
+ super.postConstructionCode
+ print(" E+")
+ }
+}
+
+object Test {
+ def p(msg: String) = println("\n\n// " + msg)
+
+ def main(args: Array[String]) {
+ val f: A => Unit = _ => ()
+
+ p("new C { }")
+ f(new C { })
+ p("new C { 5 }")
+ f(new C { 5 })
+
+ p("new D()")
+ f(new D())
+ p("new D() { }")
+ f(new D() { })
+
+ p("new D() { val x = 5 }")
+ f(new D() { val x = 5 })
+ p("new { val x = 5 } with D()")
+ f(new { val x = 5 } with D())
+
+ p("new E() { val x = 5 }")
+ f(new E() { val x = 5 })
+ p("new { val x = 5 } with E()")
+ f(new { val x = 5 } with E())
+
+ p("new { val x = 5 } with E() { }")
+ f(new { val x = 5 } with E() { })
+ p("new { val x = 5 } with E() { 5 }")
+ f(new { val x = 5 } with E() { 5 })
+
+ println("")
+ }
+}
diff --git a/test/files/run/delay-good.check b/test/files/run/delay-good.check
new file mode 100644
index 0000000000..8eb04c7cff
--- /dev/null
+++ b/test/files/run/delay-good.check
@@ -0,0 +1,41 @@
+
+
+// new C { }
+-A -B -C
+ A+ B+ C+
+
+// new C { 5 }
+-A -B -C
+ A+ B+ C+
+
+// new D()
+-A -B -C -D
+ A+ B+ C+ D+
+
+// new D() { }
+-A -B -C -D
+ A+ B+ C+ D+
+
+// new D() { val x = 5 }
+-A -B -C -D
+ A+ B+ C+ D+
+
+// new { val x = 5 } with D()
+-A -B -C -D
+ A+ B+ C+ D+
+
+// new E() { val x = 5 }
+-A -B -C -D -E
+ A+ B+ C+ D+ E+
+
+// new { val x = 5 } with E()
+-A -B -C -D -E
+ A+ B+ C+ D+ E+
+
+// new { val x = 5 } with E() { }
+-A -B -C -D -E
+ A+ B+ C+ D+ E+
+
+// new { val x = 5 } with E() { 5 }
+-A -B -C -D -E
+ A+ B+ C+ D+ E+
diff --git a/test/files/run/delay-good.scala b/test/files/run/delay-good.scala
new file mode 100644
index 0000000000..2e4487b92c
--- /dev/null
+++ b/test/files/run/delay-good.scala
@@ -0,0 +1,77 @@
+trait A
+{
+ print("-A")
+
+ def delayedInit(body: => Unit) = {
+ body
+ postConstructionCode
+ }
+ def postConstructionCode: Unit = {
+ print("\n A+")
+ }
+}
+trait B extends A {
+ print(" -B")
+ override def postConstructionCode: Unit = {
+ super.postConstructionCode
+ print(" B+")
+ }
+}
+
+trait C extends B {
+ print(" -C")
+ override def postConstructionCode: Unit = {
+ super.postConstructionCode
+ print(" C+")
+ }
+}
+
+class D() extends C {
+ print(" -D")
+ override def postConstructionCode: Unit = {
+ super.postConstructionCode
+ print(" D+")
+ }
+}
+class E() extends D() {
+ print(" -E")
+ override def postConstructionCode: Unit = {
+ super.postConstructionCode
+ print(" E+")
+ }
+}
+
+object Test {
+ def p(msg: String) = println("\n\n// " + msg)
+
+ def main(args: Array[String]) {
+ val f: A => Unit = _.postConstructionCode
+
+ p("new C { }")
+ f(new C { })
+ p("new C { 5 }")
+ f(new C { 5 })
+
+ p("new D()")
+ f(new D())
+ p("new D() { }")
+ f(new D() { })
+
+ p("new D() { val x = 5 }")
+ f(new D() { val x = 5 })
+ p("new { val x = 5 } with D()")
+ f(new { val x = 5 } with D())
+
+ p("new E() { val x = 5 }")
+ f(new E() { val x = 5 })
+ p("new { val x = 5 } with E()")
+ f(new { val x = 5 } with E())
+
+ p("new { val x = 5 } with E() { }")
+ f(new { val x = 5 } with E() { })
+ p("new { val x = 5 } with E() { 5 }")
+ f(new { val x = 5 } with E() { 5 })
+
+ println("")
+ }
+}
diff --git a/test/files/run/dynamic-proxy.check b/test/files/run/dynamic-proxy.check
new file mode 100644
index 0000000000..d1b85daff4
--- /dev/null
+++ b/test/files/run/dynamic-proxy.check
@@ -0,0 +1,20 @@
+noargs
+noargs
+nullary
+value
+symbolic
+symbolic with args
+non-existent method
+before mutation
+mutation 1
+after mutation 1
+mutation 2
+after mutation 2
+overloaded with object
+overloaded with primitive
+overloaded with object in var
+overloaded with object in var 2
+typeArgs: I am a car
+default: 4
+default: 3
+named: 6
diff --git a/test/files/run/dynamic-proxy.flags b/test/files/run/dynamic-proxy.flags
new file mode 100644
index 0000000000..48fd867160
--- /dev/null
+++ b/test/files/run/dynamic-proxy.flags
@@ -0,0 +1 @@
+-Xexperimental
diff --git a/test/files/run/dynamic-proxy.scala b/test/files/run/dynamic-proxy.scala
new file mode 100644
index 0000000000..ab5a8b1d66
--- /dev/null
+++ b/test/files/run/dynamic-proxy.scala
@@ -0,0 +1,72 @@
+import scala.reflect._
+
+class Car{ override def toString = "I am a car" }
+object x{
+ def nullary = "nullary"
+ def noargs() = "noargs"
+ def - = "symbolic"
+ def $(s:String) = "symbolic with args"
+ val value = "value"
+ def overloaded(i:Int) = "overloaded with primitive"
+ def overloaded(s:String) = s
+ def default( a:Int, b:Int = 2 ) = "default: "+(a+b)
+ def named( a:Int, b:Int, c:Int ) = "named: "+(a+b+c)
+ def typeArgs[T]( v:T ) = "typeArgs: "+v
+ var mutable = "before mutation"
+ def multiArgLists( a:String )( b:String ) = "multiArgList " + a + b
+ def bar( s:String )(implicit car:Car) = s + car.toString
+}
+
+object Test extends App{
+ val d = new DynamicProxy{ val dynamicProxyTarget = x }
+
+ println( d.noargs )
+ println( d.noargs() )
+ println( d.nullary )
+ println( d.value )
+ println( d.- )
+ println( d.$("x") )
+
+ try{
+ println( d.test )
+ } catch {
+ case _ => println("non-existent method")
+ }
+
+ println( d.mutable )
+
+ println("mutation 1")
+ d.mutable_=("after mutation 1")
+ println( d.mutable )
+
+ println("mutation 2")
+ d.mutable = "after mutation 2"
+ println( d.mutable )
+
+ println( d.overloaded("overloaded with object") )
+ println( d.overloaded(1) )
+
+ // test some non-constant arguments
+ def s = "overloaded with object in var"
+ println( d.overloaded(s) )
+ println( d.overloaded(s + " 2") )
+
+ val car = new Car
+ println( d.typeArgs(car) ) // inferred
+ // println( d.typeArgs[Car](car) ) // explicit not working (yet)
+
+ println( d.default( 1,3 ) )
+ println( d.default( 1 ) )
+
+ println( d.named(1,c=3,b=2) ) // applyDynamicNamed seems to be broken
+
+ // println( d.multiArgLists("a")("b") ) // not working yet
+
+ /*
+ // may never work
+ // testing implicit parameters (first test works when moving x into TestDynamicReflect)
+ implicit val car2 = new Car
+ println( d.bar( "Yeah, ") ); // FAILS: could not find implicit value for parameter car
+ {println( d.bar( "Yeah, ") )} // FAILS: could not find implicit value for parameter car
+ */
+}
diff --git a/test/files/run/erasuretags_abstract.check b/test/files/run/erasuretags_abstract.check
new file mode 100644
index 0000000000..17e7204664
--- /dev/null
+++ b/test/files/run/erasuretags_abstract.check
@@ -0,0 +1,4 @@
+class java.lang.Object
+class java.lang.Object
+class java.lang.Object
+int
diff --git a/test/files/run/erasuretags_abstract.scala b/test/files/run/erasuretags_abstract.scala
new file mode 100644
index 0000000000..8e4ad0d090
--- /dev/null
+++ b/test/files/run/erasuretags_abstract.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ def foo1[T] = erasureTag[T]
+ println(foo1[Int].erasure)
+ println(foo1[String].erasure)
+ println(foo1[Array[Int]].erasure)
+
+ def foo2[T <: Int] = erasureTag[T]
+ println(foo2[Int].erasure)
+} \ No newline at end of file
diff --git a/test/files/run/erasuretags_basic.check b/test/files/run/erasuretags_basic.check
new file mode 100644
index 0000000000..c02a4d32af
--- /dev/null
+++ b/test/files/run/erasuretags_basic.check
@@ -0,0 +1,24 @@
+int
+class [I
+class scala.collection.immutable.List
+class [Lscala.collection.immutable.List;
+class scala.collection.immutable.List
+class [Lscala.collection.immutable.List;
+interface scala.collection.immutable.Map
+class [Lscala.collection.immutable.Map;
+class [I
+class [[I
+class [Lscala.collection.immutable.List;
+class [[Lscala.collection.immutable.List;
+class [Lscala.collection.immutable.List;
+class [[Lscala.collection.immutable.List;
+class [Lscala.collection.immutable.Map;
+class [[Lscala.collection.immutable.Map;
+class [[I
+class [[[I
+class [[Lscala.collection.immutable.List;
+class [[[Lscala.collection.immutable.List;
+class [[Lscala.collection.immutable.List;
+class [[[Lscala.collection.immutable.List;
+class [[Lscala.collection.immutable.Map;
+class [[[Lscala.collection.immutable.Map;
diff --git a/test/files/run/erasuretags_basic.scala b/test/files/run/erasuretags_basic.scala
new file mode 100644
index 0000000000..d894fdf2e9
--- /dev/null
+++ b/test/files/run/erasuretags_basic.scala
@@ -0,0 +1,21 @@
+object Test extends App {
+ def test[T: ErasureTag] = {
+ println(implicitly[ErasureTag[T]].erasure)
+ println(implicitly[ErasureTag[Array[T]]].erasure)
+ }
+
+ test[Int]
+ test[List[Int]]
+ test[List[String]]
+ test[Map[Int, String]]
+
+ test[Array[Int]]
+ test[Array[List[Int]]]
+ test[Array[List[String]]]
+ test[Array[Map[Int, String]]]
+
+ test[Array[Array[Int]]]
+ test[Array[Array[List[Int]]]]
+ test[Array[Array[List[String]]]]
+ test[Array[Array[Map[Int, String]]]]
+} \ No newline at end of file
diff --git a/test/files/run/erasuretags_core.check b/test/files/run/erasuretags_core.check
new file mode 100644
index 0000000000..2c544678d1
--- /dev/null
+++ b/test/files/run/erasuretags_core.check
@@ -0,0 +1,32 @@
+byte
+class [B
+short
+class [S
+char
+class [C
+int
+class [I
+long
+class [J
+float
+class [F
+double
+class [D
+boolean
+class [Z
+void
+class [Lscala.runtime.BoxedUnit;
+class java.lang.Object
+class [Ljava.lang.Object;
+class java.lang.Object
+class [Ljava.lang.Object;
+class java.lang.Object
+class [Ljava.lang.Object;
+class java.lang.Object
+class [Ljava.lang.Object;
+class scala.runtime.Null$
+class [Lscala.runtime.Null$;
+class scala.runtime.Nothing$
+class [Lscala.runtime.Nothing$;
+class java.lang.String
+class [Ljava.lang.String;
diff --git a/test/files/run/erasuretags_core.scala b/test/files/run/erasuretags_core.scala
new file mode 100644
index 0000000000..5ed06dcd31
--- /dev/null
+++ b/test/files/run/erasuretags_core.scala
@@ -0,0 +1,34 @@
+object Test extends App {
+ println(implicitly[ErasureTag[Byte]].erasure)
+ println(implicitly[ErasureTag[Array[Byte]]].erasure)
+ println(implicitly[ErasureTag[Short]].erasure)
+ println(implicitly[ErasureTag[Array[Short]]].erasure)
+ println(implicitly[ErasureTag[Char]].erasure)
+ println(implicitly[ErasureTag[Array[Char]]].erasure)
+ println(implicitly[ErasureTag[Int]].erasure)
+ println(implicitly[ErasureTag[Array[Int]]].erasure)
+ println(implicitly[ErasureTag[Long]].erasure)
+ println(implicitly[ErasureTag[Array[Long]]].erasure)
+ println(implicitly[ErasureTag[Float]].erasure)
+ println(implicitly[ErasureTag[Array[Float]]].erasure)
+ println(implicitly[ErasureTag[Double]].erasure)
+ println(implicitly[ErasureTag[Array[Double]]].erasure)
+ println(implicitly[ErasureTag[Boolean]].erasure)
+ println(implicitly[ErasureTag[Array[Boolean]]].erasure)
+ println(implicitly[ErasureTag[Unit]].erasure)
+ println(implicitly[ErasureTag[Array[Unit]]].erasure)
+ println(implicitly[ErasureTag[Any]].erasure)
+ println(implicitly[ErasureTag[Array[Any]]].erasure)
+ println(implicitly[ErasureTag[Object]].erasure)
+ println(implicitly[ErasureTag[Array[Object]]].erasure)
+ println(implicitly[ErasureTag[AnyVal]].erasure)
+ println(implicitly[ErasureTag[Array[AnyVal]]].erasure)
+ println(implicitly[ErasureTag[AnyRef]].erasure)
+ println(implicitly[ErasureTag[Array[AnyRef]]].erasure)
+ println(implicitly[ErasureTag[Null]].erasure)
+ println(implicitly[ErasureTag[Array[Null]]].erasure)
+ println(implicitly[ErasureTag[Nothing]].erasure)
+ println(implicitly[ErasureTag[Array[Nothing]]].erasure)
+ println(implicitly[ErasureTag[String]].erasure)
+ println(implicitly[ErasureTag[Array[String]]].erasure)
+} \ No newline at end of file
diff --git a/test/files/run/erasuretags_usage.scala b/test/files/run/erasuretags_usage.scala
new file mode 100644
index 0000000000..16e53af071
--- /dev/null
+++ b/test/files/run/erasuretags_usage.scala
@@ -0,0 +1,12 @@
+object Test extends App {
+ def foo[T] = {
+ class MyErasureTag(_erasure: Class[_]) extends ErasureTag[T] {
+ def erasure: Class[T] = _erasure.asInstanceOf[Class[T]]
+ }
+
+ implicit val tag = new MyErasureTag(classOf[Int])
+ println(typeTag[T])
+ println(typeTag[T].tpe)
+ println(typeTag[T].erasure)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/existentials-in-compiler.check b/test/files/run/existentials-in-compiler.check
index 83e3cdf435..4df4b0ca96 100644
--- a/test/files/run/existentials-in-compiler.check
+++ b/test/files/run/existentials-in-compiler.check
@@ -100,8 +100,8 @@ abstract trait Cov31[+A, +B, C <: (A, B)] extends Object
abstract trait Cov32[+A, B, C <: (A, B)] extends Object
extest.Cov32[A,B,C] forSome { +A; B; C <: (A, B) }
-abstract trait Cov33[+A, -B, C <: (A, _$10) forSome { type _$10 }] extends Object
- extest.Cov33[A,B,C] forSome { +A; -B; C <: (A, _$10) forSome { type _$10 } }
+abstract trait Cov33[+A, -B, C <: Tuple2[A, _]] extends Object
+ extest.Cov33[A,B,C] forSome { +A; -B; C <: Tuple2[A, _] }
abstract trait Cov34[A, +B, C <: (A, B)] extends Object
extest.Cov34[A,B,C] forSome { A; +B; C <: (A, B) }
@@ -109,14 +109,14 @@ abstract trait Cov34[A, +B, C <: (A, B)] extends Object
abstract trait Cov35[A, B, C <: (A, B)] extends Object
extest.Cov35[A,B,C] forSome { A; B; C <: (A, B) }
-abstract trait Cov36[A, -B, C <: (A, _$11) forSome { type _$11 }] extends Object
- extest.Cov36[A,B,C] forSome { A; -B; C <: (A, _$11) forSome { type _$11 } }
+abstract trait Cov36[A, -B, C <: Tuple2[A, _]] extends Object
+ extest.Cov36[A,B,C] forSome { A; -B; C <: Tuple2[A, _] }
-abstract trait Cov37[-A, +B, C <: (_$12, B) forSome { type _$12 }] extends Object
- extest.Cov37[A,B,C] forSome { -A; +B; C <: (_$12, B) forSome { type _$12 } }
+abstract trait Cov37[-A, +B, C <: Tuple2[_, B]] extends Object
+ extest.Cov37[A,B,C] forSome { -A; +B; C <: Tuple2[_, B] }
-abstract trait Cov38[-A, B, C <: (_$13, B) forSome { type _$13 }] extends Object
- extest.Cov38[A,B,C] forSome { -A; B; C <: (_$13, B) forSome { type _$13 } }
+abstract trait Cov38[-A, B, C <: Tuple2[_, B]] extends Object
+ extest.Cov38[A,B,C] forSome { -A; B; C <: Tuple2[_, B] }
abstract trait Cov39[-A, -B, C <: Tuple2[_, _]] extends Object
extest.Cov39[_, _, _ <: Tuple2[_, _]]
diff --git a/test/files/run/existentials3-new.check b/test/files/run/existentials3-new.check
new file mode 100644
index 0000000000..66674fbbd6
--- /dev/null
+++ b/test/files/run/existentials3-new.check
@@ -0,0 +1,24 @@
+ConcreteTypeTag[Bar.type], t=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton
+ConcreteTypeTag[Bar], t=AbstractTypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar}
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=f3
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=f4
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=f5
+ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0
+ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0
+ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with Test.ToS
+ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS
+TypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List
+ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List
+ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List
+ConcreteTypeTag[Bar.type], t=AbstractTypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton
+ConcreteTypeTag[Bar], t=AbstractTypeRef, s= <: Test.ToS with Product with Serializable{def copy(): Bar}
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=g3
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=g4
+ConcreteTypeTag[Test.ToS], t=RefinedType, s=g5
+ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0
+ConcreteTypeTag[() => Test.ToS], t=TypeRef, s=class Function0
+ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with Test.ToS
+ConcreteTypeTag[$anon], t=AbstractTypeRef, s= <: B with A with Test.ToS
+TypeTag[List[Object{type T1}#T1]], t=TypeRef, s=class List
+ConcreteTypeTag[List[Seq[Int]]], t=TypeRef, s=class List
+ConcreteTypeTag[List[Seq[U forSome { type U <: Int }]]], t=TypeRef, s=class List
diff --git a/test/files/run/existentials3-new.scala b/test/files/run/existentials3-new.scala
new file mode 100644
index 0000000000..32129a04c6
--- /dev/null
+++ b/test/files/run/existentials3-new.scala
@@ -0,0 +1,78 @@
+object Test {
+ trait ToS { final override def toString = getClass.getName }
+
+ def f1 = { case class Bar() extends ToS; Bar }
+ def f2 = { case class Bar() extends ToS; Bar() }
+ def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar }
+ def f4 = { class Bar() extends ToS; new Bar() }
+ def f5 = { object Bar extends ToS; Bar }
+ def f6 = { () => { object Bar extends ToS ; Bar } }
+ def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f }
+
+ def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } }
+ def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } }
+
+ def f10 = { class A { type T1 } ; List[A#T1]() }
+ def f11 = { abstract class A extends Seq[Int] ; List[A]() }
+ def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() }
+
+ val g1 = { case class Bar() extends ToS; Bar }
+ val g2 = { case class Bar() extends ToS; Bar() }
+ val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar }
+ val g4 = { class Bar() extends ToS; new Bar() }
+ val g5 = { object Bar extends ToS; Bar }
+ val g6 = { () => { object Bar extends ToS ; Bar } }
+ val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f }
+
+ val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } }
+ val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } }
+
+ val g10 = { class A { type T1 } ; List[A#T1]() }
+ val g11 = { abstract class A extends Seq[Int] ; List[A]() }
+ val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() }
+
+ def printTag(t: TypeTag[_]) = {
+ val s = if (t.sym.isFreeType) t.sym.typeSignature.toString else t.sym.toString
+ println("%s, t=%s, s=%s".format(t, t.tpe.kind, s))
+ }
+ def m[T: ConcreteTypeTag](x: T) = printTag(concreteTypeTag[T])
+ def m2[T: TypeTag](x: T) = printTag(typeTag[T])
+
+ // tags do work for f10/g10
+ def main(args: Array[String]): Unit = {
+ m(f1)
+ m(f2)
+ m(f3)
+ m(f4)
+ m(f5)
+ m(f6)
+ m(f7)
+ m(f8)
+ m(f9)
+ m2(f10)
+ m(f11)
+ m(f12)
+ m(g1)
+ m(g2)
+ m(g3)
+ m(g4)
+ m(g5)
+ m(g6)
+ m(g7)
+ m(g8)
+ m(g9)
+ m2(g10)
+ m(g11)
+ m(g12)
+ }
+}
+
+object Misc {
+ trait Bippy { def bippy = "I'm Bippy!" }
+ object o1 {
+ def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) }
+ def f2 = f1.head.bippy
+ }
+ def g1 = o1.f1 _
+ def g2 = o1.f2 _
+}
diff --git a/test/files/run/existentials3.check b/test/files/run/existentials3-old.check
index 36a458dacc..e166e53ba8 100644
--- a/test/files/run/existentials3.check
+++ b/test/files/run/existentials3-old.check
@@ -1,22 +1,22 @@
-_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
-_ <: Object with Test$ToS with scala.Product with scala.Serializable
-Object with Test$ToS
-Object with Test$ToS
-Object with Test$ToS
-scala.Function0[Object with Test$ToS]
-scala.Function0[Object with Test$ToS]
-_ <: Object with _ <: Object with Object with Test$ToS
-_ <: Object with _ <: Object with _ <: Object with Test$ToS
-scala.collection.immutable.List[Object with scala.collection.Seq[Int]]
-scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]]
-_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
-_ <: Object with Test$ToS with scala.Product with scala.Serializable
-Object with Test$ToS
-Object with Test$ToS
-Object with Test$ToS
-scala.Function0[Object with Test$ToS]
-scala.Function0[Object with Test$ToS]
-_ <: Object with _ <: Object with Object with Test$ToS
-_ <: Object with _ <: Object with _ <: Object with Test$ToS
-scala.collection.immutable.List[Object with scala.collection.Seq[Int]]
-scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]]
+_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
+_ <: Object with Test$ToS with scala.Product with scala.Serializable
+Object with Test$ToS
+Object with Test$ToS
+Object with Test$ToS
+scala.Function0[Object with Test$ToS]
+scala.Function0[Object with Test$ToS]
+_ <: Object with _ <: Object with Object with Test$ToS
+_ <: Object with _ <: Object with _ <: Object with Test$ToS
+scala.collection.immutable.List[Object with scala.collection.Seq[Int]]
+scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]]
+_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
+_ <: Object with Test$ToS with scala.Product with scala.Serializable
+Object with Test$ToS
+Object with Test$ToS
+Object with Test$ToS
+scala.Function0[Object with Test$ToS]
+scala.Function0[Object with Test$ToS]
+_ <: Object with _ <: Object with Object with Test$ToS
+_ <: Object with _ <: Object with _ <: Object with Test$ToS
+scala.collection.immutable.List[Object with scala.collection.Seq[Int]]
+scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]]
diff --git a/test/files/run/existentials3.scala b/test/files/run/existentials3-old.scala
index bb80d366cc..944160ff12 100644
--- a/test/files/run/existentials3.scala
+++ b/test/files/run/existentials3-old.scala
@@ -11,11 +11,11 @@ object Test {
def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } }
def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } }
-
+
def f10 = { class A { type T1 } ; List[A#T1]() }
def f11 = { abstract class A extends Seq[Int] ; List[A]() }
def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() }
-
+
val g1 = { case class Bar() extends ToS; Bar }
val g2 = { case class Bar() extends ToS; Bar() }
val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar }
@@ -30,9 +30,9 @@ object Test {
val g10 = { class A { type T1 } ; List[A#T1]() }
val g11 = { abstract class A extends Seq[Int] ; List[A]() }
val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() }
-
+
def m[T: Manifest](x: T) = println(manifest[T])
-
+
// manifests don't work for f10/g10
def main(args: Array[String]): Unit = {
m(f1)
diff --git a/test/files/run/finalvar.check b/test/files/run/finalvar.check
new file mode 100644
index 0000000000..2496293972
--- /dev/null
+++ b/test/files/run/finalvar.check
@@ -0,0 +1,6 @@
+(2,2,2,2,1)
+(2,2,2,2)
+(2,2,2,2,1001)
+(2,2,2,2)
+2
+10
diff --git a/test/files/run/finalvar.flags b/test/files/run/finalvar.flags
new file mode 100644
index 0000000000..aee3039bec
--- /dev/null
+++ b/test/files/run/finalvar.flags
@@ -0,0 +1 @@
+-Yoverride-vars -Yinline \ No newline at end of file
diff --git a/test/files/run/finalvar.scala b/test/files/run/finalvar.scala
new file mode 100644
index 0000000000..010813e520
--- /dev/null
+++ b/test/files/run/finalvar.scala
@@ -0,0 +1,37 @@
+object Final {
+ class X(final var x: Int) { }
+ def f = new X(0).x += 1
+}
+
+class A {
+ var x = 1
+ def y0 = x
+ def y1 = this.x
+ def y2 = (this: A).x
+}
+
+class B extends A {
+ override def x = 2
+ def z = super.x
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ Final.f
+ val a = new B
+ println((a.x, a.y0, a.y1, a.y2, a.z))
+ val a0: A = a
+ println((a0.x, a0.y0, a0.y1, a0.y2))
+ a.x = 1001
+ println((a.x, a.y0, a.y1, a.y2, a.z))
+ println((a0.x, a0.y0, a0.y1, a0.y2))
+
+ val d = new D
+ println(d.w)
+ d.ten
+ println(d.w)
+ }
+}
+
+class C { var w = 1 ; def ten = this.w = 10 }
+class D extends C { override var w = 2 } \ No newline at end of file
diff --git a/test/files/run/getClassTest.check b/test/files/run/getClassTest-new.check
index 94e86c3889..94e86c3889 100644
--- a/test/files/run/getClassTest.check
+++ b/test/files/run/getClassTest-new.check
diff --git a/test/files/run/getClassTest-new.scala b/test/files/run/getClassTest-new.scala
new file mode 100644
index 0000000000..89778ca2d3
--- /dev/null
+++ b/test/files/run/getClassTest-new.scala
@@ -0,0 +1,66 @@
+class AnyVals {
+ def f1 = (5: Any).getClass
+ def f2 = (5: AnyVal).getClass
+ def f3 = 5.getClass
+ def f4 = (5: java.lang.Integer).getClass
+ def f5 = (5.asInstanceOf[AnyRef]).getClass
+
+ // scalap says:
+ //
+ // def f1 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ }
+ // def f2 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ }
+ // def f3 : java.lang.Class[scala.Int] = { /* compiled code */ }
+ // def f4 : java.lang.Class[?0] forSome {type ?0 <: java.lang.Integer} = { /* compiled code */ }
+ // def f5 : java.lang.Class[?0] forSome {type ?0 <: scala.AnyRef} = { /* compiled code */ }
+ //
+ // java generic signature says:
+ //
+ // f1: java.lang.Class<?>
+ // f2: java.lang.Class<?>
+ // f3: java.lang.Class<java.lang.Object>
+ // f4: java.lang.Class<? extends java.lang.Integer>
+ // f5: java.lang.Class<?>
+}
+
+class AnyRefs {
+ class A
+ class B extends A
+
+ def f1 = (new B: Any).getClass().newInstance()
+ def f2 = (new B: AnyRef).getClass().newInstance()
+ def f3 = (new B: A).getClass().newInstance()
+ def f4 = (new B: B).getClass().newInstance()
+
+ def f0[T >: B] = (new B: T).getClass().newInstance()
+
+ def f5 = f0[Any]
+ def f6 = f0[AnyRef]
+ def f7 = f0[A]
+ def f8 = f0[B]
+}
+
+class MoreAnyRefs {
+ trait A
+ trait B
+
+ // don't leak anon/refinements
+ def f1 = (new A with B { }).getClass()
+ def f2 = (new B with A { }).getClass()
+ def f3 = (new { def bippy() = 5 }).getClass()
+ def f4 = (new A { def bippy() = 5 }).getClass()
+}
+
+object Test {
+ def returnTypes[T: ClassTag] = (
+ classTag[T].erasure.getMethods.toList
+ filter (_.getName startsWith "f")
+ sortBy (_.getName)
+ map (m => m.getName + ": " + m.getGenericReturnType.toString)
+ )
+
+ def main(args: Array[String]): Unit = {
+ returnTypes[AnyVals] foreach println
+ returnTypes[AnyRefs] foreach println
+ returnTypes[MoreAnyRefs] foreach println
+ }
+}
diff --git a/test/files/run/getClassTest-old.check b/test/files/run/getClassTest-old.check
new file mode 100644
index 0000000000..94e86c3889
--- /dev/null
+++ b/test/files/run/getClassTest-old.check
@@ -0,0 +1,18 @@
+f1: java.lang.Class<?>
+f2: java.lang.Class<?>
+f3: java.lang.Class<java.lang.Object>
+f4: java.lang.Class<? extends java.lang.Integer>
+f5: java.lang.Class<?>
+f0: T
+f1: class java.lang.Object
+f2: class java.lang.Object
+f3: class AnyRefs$A
+f4: class AnyRefs$B
+f5: class java.lang.Object
+f6: class java.lang.Object
+f7: class AnyRefs$A
+f8: class AnyRefs$B
+f1: java.lang.Class<? extends MoreAnyRefs$A>
+f2: java.lang.Class<? extends MoreAnyRefs$B>
+f3: java.lang.Class<?>
+f4: java.lang.Class<? extends MoreAnyRefs$A>
diff --git a/test/files/run/getClassTest.scala b/test/files/run/getClassTest-old.scala
index 2485cd2c71..951cc8d931 100644
--- a/test/files/run/getClassTest.scala
+++ b/test/files/run/getClassTest-old.scala
@@ -4,7 +4,7 @@ class AnyVals {
def f3 = 5.getClass
def f4 = (5: java.lang.Integer).getClass
def f5 = (5.asInstanceOf[AnyRef]).getClass
-
+
// scalap says:
//
// def f1 : java.lang.Class[?0] forSome {type ?0} = { /* compiled code */ }
@@ -19,18 +19,18 @@ class AnyVals {
// f2: java.lang.Class<?>
// f3: java.lang.Class<java.lang.Object>
// f4: java.lang.Class<? extends java.lang.Integer>
- // f5: java.lang.Class<?>
+ // f5: java.lang.Class<?>
}
class AnyRefs {
class A
class B extends A
-
+
def f1 = (new B: Any).getClass().newInstance()
def f2 = (new B: AnyRef).getClass().newInstance()
def f3 = (new B: A).getClass().newInstance()
def f4 = (new B: B).getClass().newInstance()
-
+
def f0[T >: B] = (new B: T).getClass().newInstance()
def f5 = f0[Any]
@@ -52,7 +52,7 @@ class MoreAnyRefs {
object Test {
def returnTypes[T: Manifest] = (
- manifest[T].erasure.getMethods.toList
+ manifest[T].erasure.getMethods.toList
filter (_.getName startsWith "f")
sortBy (_.getName)
map (m => m.getName + ": " + m.getGenericReturnType.toString)
diff --git a/test/files/run/implicitclasses.scala b/test/files/run/implicitclasses.scala
new file mode 100644
index 0000000000..886d4dede0
--- /dev/null
+++ b/test/files/run/implicitclasses.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+
+ implicit class C(s: String) {
+ def nElems = s.length
+ }
+
+ assert("abc".nElems == 3)
+
+}
+
diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check
index 7a8a744bfa..a5d7e93334 100644
--- a/test/files/run/inline-ex-handlers.check
+++ b/test/files/run/inline-ex-handlers.check
@@ -1,40 +1,48 @@
172c172
-< locals: value x$1, value temp1
+< locals: value x$1, value x1, value x2, value x
---
-> locals: value x$1, value temp1, variable boxed1
+> locals: value x$1, value x1, value x2, value x, variable boxed1
174c174
-< blocks: [1,2,3,4]
+< blocks: [1,2,3,5,6,7]
---
-> blocks: [1,2,3]
-187,189d186
-< 92 JUMP 4
+> blocks: [1,3,5,6]
+180,182d179
+< 92 JUMP 2
<
-< 4:
-195a193,194
+< 2:
+194,196d190
+< 92 JUMP 7
+<
+< 7:
+204a199,200
> 92 STORE_LOCAL(variable boxed1)
> 92 LOAD_LOCAL(variable boxed1)
-386c385
-< blocks: [1,2,3,4,5,7,8,10]
+395c391
+< blocks: [1,2,3,4,5,8,11,13,14,16]
---
-> blocks: [1,2,3,4,5,7,8,10,11]
-410c409,418
+> blocks: [1,2,3,5,8,11,13,14,16,17]
+419c415,424
< 103 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$1)
-> ? JUMP 11
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 17
>
-> 11:
-> 101 LOAD_LOCAL(value ex$1)
-> 101 STORE_LOCAL(value temp2)
-> 101 SCOPE_ENTER value temp2
-> 101 LOAD_LOCAL(value temp2)
-> 101 IS_INSTANCE REF(class MyException)
-> 101 CZJUMP (BOOL)NE ? 4 : 5
-501c509
+> 17:
+> 101 LOAD_LOCAL(value ex5)
+> 101 STORE_LOCAL(value x3)
+> 101 SCOPE_ENTER value x3
+> 106 LOAD_LOCAL(value x3)
+> 106 IS_INSTANCE REF(class MyException)
+> 106 CZJUMP (BOOL)NE ? 5 : 11
+432,434d436
+< 101 JUMP 4
+<
+< 4:
+522c524
< blocks: [1,2,3,4,6,7,8,9,10]
---
> blocks: [1,2,3,4,6,7,8,9,10,11,12,13]
-530c538,543
+551c553,558
< 306 THROW(MyException)
---
> ? JUMP 11
@@ -43,7 +51,7 @@
> ? LOAD_LOCAL(variable monitor4)
> 305 MONITOR_EXIT
> ? JUMP 12
-536c549,555
+557c564,570
< ? THROW(Throwable)
---
> ? JUMP 12
@@ -53,7 +61,7 @@
> 304 MONITOR_EXIT
> ? STORE_LOCAL(value t)
> ? JUMP 13
-542c561,574
+563c576,589
< ? THROW(Throwable)
---
> ? STORE_LOCAL(value t)
@@ -70,29 +78,30 @@
> 310 CALL_PRIMITIVE(EndConcat)
> 310 CALL_METHOD scala.Predef.println (dynamic)
> 310 JUMP 2
-566c598
+587c613
< catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6
---
> catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6
-569c601
+590c616
< catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10) starting at: 3
---
> catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10, 11, 12) starting at: 3
-601c633
+622c648
< blocks: [1,2,3,4,5,6,7,9,10]
---
> blocks: [1,2,3,4,5,6,7,9,10,11,12]
-625c657,663
+646c672,673
< 78 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
> ? JUMP 11
->
+647a675,679
> 11:
> 81 LOAD_LOCAL(value e)
> ? STORE_LOCAL(variable exc1)
> ? JUMP 12
-654c692,706
+>
+675c707,721
< 81 THROW(Exception)
---
> ? STORE_LOCAL(variable exc1)
@@ -110,57 +119,53 @@
> 84 STORE_LOCAL(variable result)
> 84 LOAD_LOCAL(variable exc1)
> 84 THROW(Throwable)
-676c728
+697c743
< catch (<none>) in ArrayBuffer(4, 6, 7, 9) starting at: 3
---
> catch (<none>) in ArrayBuffer(4, 6, 7, 9, 11) starting at: 3
-702c754
-< blocks: [1,2,3,4,5,6,7,8,11,12,13,14,15,16,18,19]
+723c769
+< blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31]
---
-> blocks: [1,2,3,4,5,6,7,8,11,12,13,14,15,16,18,19,20,21,22]
-726c778,787
+> blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31,32,33,34]
+747c793,800
< 172 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$4)
-> ? JUMP 20
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 32
>
-> 20:
-> 170 LOAD_LOCAL(value ex$4)
-> 170 STORE_LOCAL(value temp11)
-> 170 SCOPE_ENTER value temp11
-> 170 LOAD_LOCAL(value temp11)
-> 170 IS_INSTANCE REF(class MyException)
-> 170 CZJUMP (BOOL)NE ? 12 : 13
-780c841,842
+> 32:
+> 170 LOAD_LOCAL(value ex5)
+> 170 STORE_LOCAL(value x3)
+> 170 SCOPE_ENTER value x3
+> 170 JUMP 18
+803c856,857
< 177 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$5)
-> ? JUMP 21
-784c846,855
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 33
+807c861,868
< 170 THROW(Throwable)
---
-> ? STORE_LOCAL(value ex$5)
-> ? JUMP 21
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 33
>
-> 21:
-> 169 LOAD_LOCAL(value ex$5)
-> 169 STORE_LOCAL(value temp14)
-> 169 SCOPE_ENTER value temp14
-> 169 LOAD_LOCAL(value temp14)
-> 169 IS_INSTANCE REF(class MyException)
-> 169 CZJUMP (BOOL)NE ? 5 : 6
-815c886,887
+> 33:
+> 169 LOAD_LOCAL(value ex5)
+> 169 STORE_LOCAL(value x3)
+> 169 SCOPE_ENTER value x3
+> 169 JUMP 5
+840c901,902
< 182 THROW(MyException)
---
> ? STORE_LOCAL(variable exc2)
-> ? JUMP 22
-819c891,905
+> ? JUMP 34
+844c906,907
< 169 THROW(Throwable)
---
> ? STORE_LOCAL(variable exc2)
-> ? JUMP 22
->
-> 22:
+> ? JUMP 34
+845a909,921
+> 34:
> 184 LOAD_MODULE object Predef
> 184 CONSTANT("finally")
> 184 CALL_METHOD scala.Predef.println (dynamic)
@@ -172,57 +177,60 @@
> 185 STORE_LOCAL(variable result)
> 185 LOAD_LOCAL(variable exc2)
> 185 THROW(Throwable)
-841c927
-< catch (Throwable) in ArrayBuffer(11, 12, 13, 14, 15, 16, 18) starting at: 4
+>
+866c942
+< catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30) starting at: 4
---
-> catch (Throwable) in ArrayBuffer(11, 12, 13, 14, 15, 16, 18, 20) starting at: 4
-844c930
-< catch (<none>) in ArrayBuffer(4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 18) starting at: 3
+> catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30, 32) starting at: 4
+869c945
+< catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30) starting at: 3
---
-> catch (<none>) in ArrayBuffer(4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 18, 20, 21) starting at: 3
-870c956
-< blocks: [1,2,3,6,7,8,10,11,13]
+> catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30, 32, 33) starting at: 3
+895c971
+< blocks: [1,2,3,6,7,8,11,14,16,17,19]
---
-> blocks: [1,2,3,6,7,8,10,11,13,14]
-894c980,989
+> blocks: [1,2,3,6,7,8,11,14,16,17,19,20]
+919c995,1002
< 124 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$2)
-> ? JUMP 14
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 20
>
-> 14:
-> 122 LOAD_LOCAL(value ex$2)
-> 122 STORE_LOCAL(value temp5)
-> 122 SCOPE_ENTER value temp5
-> 122 LOAD_LOCAL(value temp5)
-> 122 IS_INSTANCE REF(class MyException)
-> 122 CZJUMP (BOOL)NE ? 7 : 8
-942c1037
-< catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 10, 11, 13) starting at: 3
----
-> catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 10, 11, 13, 14) starting at: 3
-968c1063
-< blocks: [1,2,3,4,5,9,10,11,13]
----
-> blocks: [1,2,3,4,5,9,10,11,13,14]
-992c1087,1096
+> 20:
+> 122 LOAD_LOCAL(value ex5)
+> 122 STORE_LOCAL(value x3)
+> 122 SCOPE_ENTER value x3
+> 122 JUMP 7
+979c1062
+< catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19) starting at: 3
+---
+> catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19, 20) starting at: 3
+1005c1088
+< blocks: [1,2,3,4,5,8,11,15,16,17,19]
+---
+> blocks: [1,2,3,5,8,11,15,16,17,19,20]
+1029c1112,1121
< 148 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$3)
-> ? JUMP 14
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 20
>
-> 14:
-> 145 LOAD_LOCAL(value ex$3)
-> 145 STORE_LOCAL(value temp8)
-> 145 SCOPE_ENTER value temp8
-> 145 LOAD_LOCAL(value temp8)
-> 145 IS_INSTANCE REF(class MyException)
-> 145 CZJUMP (BOOL)NE ? 4 : 5
-1236c1340
+> 20:
+> 145 LOAD_LOCAL(value ex5)
+> 145 STORE_LOCAL(value x3)
+> 145 SCOPE_ENTER value x3
+> 154 LOAD_LOCAL(value x3)
+> 154 IS_INSTANCE REF(class MyException)
+> 154 CZJUMP (BOOL)NE ? 5 : 11
+1050,1052d1141
+< 145 JUMP 4
+<
+< 4:
+1285c1374
< blocks: [1,2,3,4,5,7]
---
> blocks: [1,2,3,4,5,7,8]
-1260c1364,1371
+1309c1398,1405
< 38 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
@@ -233,33 +241,37 @@
> 42 CONSTANT("IllegalArgumentException")
> 42 CALL_METHOD scala.Predef.println (dynamic)
> 42 JUMP 2
-1309c1420
-< blocks: [1,2,3,4,5,7,8,10,11,13]
+1358c1454
+< blocks: [1,2,3,4,5,8,11,13,14,16,17,19]
---
-> blocks: [1,2,3,4,5,7,8,10,11,13,14]
-1333c1444,1445
+> blocks: [1,2,3,5,8,11,13,14,16,17,19,20]
+1382c1478,1479
< 203 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$6)
-> ? JUMP 14
-1353c1465,1474
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 20
+1402c1499,1508
< 209 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$6)
-> ? JUMP 14
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 20
>
-> 14:
-> 200 LOAD_LOCAL(value ex$6)
-> 200 STORE_LOCAL(value temp17)
-> 200 SCOPE_ENTER value temp17
-> 200 LOAD_LOCAL(value temp17)
-> 200 IS_INSTANCE REF(class MyException)
-> 200 CZJUMP (BOOL)NE ? 4 : 5
-1416c1537
+> 20:
+> 200 LOAD_LOCAL(value ex5)
+> 200 STORE_LOCAL(value x3)
+> 200 SCOPE_ENTER value x3
+> 212 LOAD_LOCAL(value x3)
+> 212 IS_INSTANCE REF(class MyException)
+> 212 CZJUMP (BOOL)NE ? 5 : 11
+1415,1417d1520
+< 200 JUMP 4
+<
+< 4:
+1477c1580
< blocks: [1,2,3,4,5,7]
---
> blocks: [1,2,3,4,5,7,8]
-1440c1561,1568
+1501c1604,1611
< 58 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
@@ -270,11 +282,11 @@
> 62 CONSTANT("RuntimeException")
> 62 CALL_METHOD scala.Predef.println (dynamic)
> 62 JUMP 2
-1489c1617
+1550c1660
< blocks: [1,2,3,4]
---
> blocks: [1,2,3,4,5]
-1509c1637,1642
+1570c1680,1685
< 229 THROW(MyException)
---
> ? JUMP 5
@@ -283,19 +295,19 @@
> ? LOAD_LOCAL(variable monitor1)
> 228 MONITOR_EXIT
> 228 THROW(Throwable)
-1515c1648
+1576c1691
< ? THROW(Throwable)
---
> 228 THROW(Throwable)
-1543c1676
+1604c1719
< locals: value args, variable result, variable monitor2, variable monitorResult1
---
> locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1
-1545c1678
+1606c1721
< blocks: [1,2,3,4]
---
> blocks: [1,2,3,4,5]
-1568c1701,1709
+1629c1744,1752
< 245 THROW(MyException)
---
> ? STORE_LOCAL(value exception$1)
@@ -307,7 +319,7 @@
> ? LOAD_LOCAL(variable monitor2)
> 244 MONITOR_EXIT
> 244 THROW(Throwable)
-1574c1715
+1635c1758
< ? THROW(Throwable)
---
> 244 THROW(Throwable)
diff --git a/test/files/run/inner-parse.check b/test/files/run/inner-parse.check
new file mode 100644
index 0000000000..87ea9ddeb5
--- /dev/null
+++ b/test/files/run/inner-parse.check
@@ -0,0 +1,86 @@
+file Test$$anonfun$main$1.class
+class Test$$anonfun$main$1 extends scala.runtime.AbstractFunction1$mcVL$sp
+ interface scala.Serializable
+ inner/anon anonymous class: Test$$anonfun$main$1
+ descriptor <clinit> ()V
+ descriptor apply (Lscala/Tuple2;)V
+ descriptor apply (Ljava/lang/Object;)Ljava/lang/Object;
+ descriptor cwd$1 Ljava/lang/String;
+ descriptor serialVersionUID J
+ descriptor <init> (Ljava/lang/String;)V
+ signature apply (Lscala/Tuple2<Ljava/lang/String;Lscala/reflect/internal/JvmClassInfo;>;)V
+
+file Test$.class
+class Test$ extends java.lang.Object
+ inner/anon anonymous class: Test$$anonfun$main$1
+ descriptor <clinit> ()V
+ descriptor MODULE$ LTest$;
+ descriptor main ([Ljava/lang/String;)V
+ descriptor <init> ()V
+
+file Test.class
+class Test extends java.lang.Object
+ inner/anon anonymous class: Test$$anonfun$main$1
+ descriptor main ([Ljava/lang/String;)V
+
+file j/J_1$B$C$D.class
+class j.J_1$B$C$D extends java.lang.Object
+ inner B j.J_1$B in j.J_1
+ inner C j.J_1$B$C in j.J_1$B
+ inner/enclosing D enclosing class: j.J_1$B$C
+ descriptor <init> (Lj/J_1$B$C;)V
+ descriptor this$2 Lj/J_1$B$C;
+
+file j/J_1$B$C.class
+class j.J_1$B$C extends java.lang.Object
+ inner B j.J_1$B in j.J_1
+ inner/enclosing C enclosing class: j.J_1$B
+ inner/nested D member class: j.J_1$B$C$D
+ descriptor <init> (Lj/J_1$B;)V
+ descriptor this$1 Lj/J_1$B;
+
+file j/J_1$B.class
+class j.J_1$B extends java.lang.Object
+ inner/enclosing B enclosing class: j.J_1
+ inner/nested C member class: j.J_1$B$C
+ descriptor <init> (Lj/J_1;)V
+ descriptor this$0 Lj/J_1;
+
+file j/J_1.class
+class j.J_1 extends java.lang.Object
+ interface java.util.RandomAccess
+ inner/nested B member class: j.J_1$B
+ descriptor <init> ()V
+
+file s/J_1$B$C$D.class
+class s.J_1$B$C$D extends java.lang.Object
+ inner B s.J_1$B in s.J_1
+ inner C s.J_1$B$C in s.J_1$B
+ inner/enclosing D enclosing class: s.J_1$B$C
+ descriptor $outer Ls/J_1$B$C;
+ descriptor s$J_1$B$C$D$$$outer ()Ls/J_1$B$C;
+ descriptor <init> (Ls/J_1$B$C;)V
+
+file s/J_1$B$C.class
+class s.J_1$B$C extends java.lang.Object
+ inner B s.J_1$B in s.J_1
+ inner/enclosing C enclosing class: s.J_1$B
+ inner/nested D member class: s.J_1$B$C$D
+ descriptor $outer Ls/J_1$B;
+ descriptor s$J_1$B$C$$$outer ()Ls/J_1$B;
+ descriptor <init> (Ls/J_1$B;)V
+
+file s/J_1$B.class
+class s.J_1$B extends java.lang.Object
+ inner/enclosing B enclosing class: s.J_1
+ inner/nested C member class: s.J_1$B$C
+ descriptor $outer Ls/J_1;
+ descriptor s$J_1$B$$$outer ()Ls/J_1;
+ descriptor <init> (Ls/J_1;)V
+
+file s/J_1.class
+class s.J_1 extends java.lang.Object
+ interface java.util.RandomAccess
+ inner/nested B member class: s.J_1$B
+ descriptor <init> ()V
+
diff --git a/test/files/run/inner-parse/J_1.java b/test/files/run/inner-parse/J_1.java
new file mode 100644
index 0000000000..920ab951ab
--- /dev/null
+++ b/test/files/run/inner-parse/J_1.java
@@ -0,0 +1,9 @@
+package j;
+
+public class J_1 implements java.util.RandomAccess { // "random" marker interface
+ class B {
+ class C {
+ class D { }
+ }
+ }
+}
diff --git a/test/files/run/inner-parse/S_2.scala b/test/files/run/inner-parse/S_2.scala
new file mode 100644
index 0000000000..fd144a40b7
--- /dev/null
+++ b/test/files/run/inner-parse/S_2.scala
@@ -0,0 +1,9 @@
+package s;
+
+class J_1 extends java.util.RandomAccess {
+ class B {
+ class C {
+ class D { }
+ }
+ }
+}
diff --git a/test/files/run/inner-parse/S_3.scala b/test/files/run/inner-parse/S_3.scala
new file mode 100644
index 0000000000..296a651460
--- /dev/null
+++ b/test/files/run/inner-parse/S_3.scala
@@ -0,0 +1,12 @@
+import scala.reflect.internal.JvmClassInfo
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val cwd = sys.props("partest.output")
+
+ for ((f, info) <- JvmClassInfo.classInfoList(cwd)) {
+ println("file " + f.stripPrefix(cwd + "/"))
+ println(info)
+ }
+ }
+}
diff --git a/test/files/run/interop_classmanifests_arepartially_typetags.check b/test/files/run/interop_classmanifests_arepartially_typetags.check
new file mode 100644
index 0000000000..3dfcdccbec
--- /dev/null
+++ b/test/files/run/interop_classmanifests_arepartially_typetags.check
@@ -0,0 +1,6 @@
+T
+int
+T
+class java.lang.String
+T
+class [I
diff --git a/test/files/run/interop_classmanifests_arepartially_typetags.scala b/test/files/run/interop_classmanifests_arepartially_typetags.scala
new file mode 100644
index 0000000000..9bc1f32e86
--- /dev/null
+++ b/test/files/run/interop_classmanifests_arepartially_typetags.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ def classManifestIspartiallyTypeTag[T: ClassManifest] = {
+ println(typeTag[T].tpe)
+ println(typeTag[T].erasure)
+ }
+
+ classManifestIspartiallyTypeTag[Int]
+ classManifestIspartiallyTypeTag[String]
+ classManifestIspartiallyTypeTag[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/run/interop_classtags_are_classmanifests.check b/test/files/run/interop_classtags_are_classmanifests.check
new file mode 100644
index 0000000000..02393dff23
--- /dev/null
+++ b/test/files/run/interop_classtags_are_classmanifests.check
@@ -0,0 +1,6 @@
+Int
+java.lang.String
+Array[Int]
+Int
+java.lang.String
+Array[Int]
diff --git a/test/files/run/interop_classtags_are_classmanifests.scala b/test/files/run/interop_classtags_are_classmanifests.scala
new file mode 100644
index 0000000000..309c99a3f5
--- /dev/null
+++ b/test/files/run/interop_classtags_are_classmanifests.scala
@@ -0,0 +1,17 @@
+object Test extends App {
+ def arrayTagIsClassManifest[T: ArrayTag] = {
+ println(classManifest[T])
+ }
+
+ arrayTagIsClassManifest[Int]
+ arrayTagIsClassManifest[String]
+ arrayTagIsClassManifest[Array[Int]]
+
+ def classTagIsClassManifest[T: ClassTag] = {
+ println(classManifest[T])
+ }
+
+ classTagIsClassManifest[Int]
+ classTagIsClassManifest[String]
+ classTagIsClassManifest[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/run/interop_concretetypetags_are_classmanifests.check b/test/files/run/interop_concretetypetags_are_classmanifests.check
new file mode 100644
index 0000000000..c59e92d4eb
--- /dev/null
+++ b/test/files/run/interop_concretetypetags_are_classmanifests.check
@@ -0,0 +1,3 @@
+Int
+java.lang.String
+Array[Int]
diff --git a/test/files/run/interop_concretetypetags_are_classmanifests.scala b/test/files/run/interop_concretetypetags_are_classmanifests.scala
new file mode 100644
index 0000000000..b578d7e626
--- /dev/null
+++ b/test/files/run/interop_concretetypetags_are_classmanifests.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ def concreteTypeTagIsClassManifest[T: ConcreteTypeTag] = {
+ println(classManifest[T])
+ }
+
+ concreteTypeTagIsClassManifest[Int]
+ concreteTypeTagIsClassManifest[String]
+ concreteTypeTagIsClassManifest[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/run/interop_concretetypetags_are_manifests.check b/test/files/run/interop_concretetypetags_are_manifests.check
new file mode 100644
index 0000000000..c59e92d4eb
--- /dev/null
+++ b/test/files/run/interop_concretetypetags_are_manifests.check
@@ -0,0 +1,3 @@
+Int
+java.lang.String
+Array[Int]
diff --git a/test/files/run/interop_concretetypetags_are_manifests.scala b/test/files/run/interop_concretetypetags_are_manifests.scala
new file mode 100644
index 0000000000..731410bc10
--- /dev/null
+++ b/test/files/run/interop_concretetypetags_are_manifests.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ def concreteTypeTagIsManifest[T: ConcreteTypeTag] = {
+ println(manifest[T])
+ }
+
+ concreteTypeTagIsManifest[Int]
+ concreteTypeTagIsManifest[String]
+ concreteTypeTagIsManifest[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/run/interop_manifests_are_classtags.check b/test/files/run/interop_manifests_are_classtags.check
new file mode 100644
index 0000000000..07ff6b984a
--- /dev/null
+++ b/test/files/run/interop_manifests_are_classtags.check
@@ -0,0 +1,24 @@
+Int
+Int
+List()
+List(0, 0, 0, 0, 0)
+java.lang.String
+java.lang.String
+List()
+List(null, null, null, null, null)
+Array[Int]
+Array[Int]
+List()
+List(null, null, null, null, null)
+Int
+Int
+List()
+List(0, 0, 0, 0, 0)
+java.lang.String
+java.lang.String
+List()
+List(null, null, null, null, null)
+Array[Int]
+Array[Int]
+List()
+List(null, null, null, null, null)
diff --git a/test/files/run/interop_manifests_are_classtags.scala b/test/files/run/interop_manifests_are_classtags.scala
new file mode 100644
index 0000000000..582cea3467
--- /dev/null
+++ b/test/files/run/interop_manifests_are_classtags.scala
@@ -0,0 +1,23 @@
+object Test extends App {
+ def classManifestIsClassTag[T: ClassManifest] = {
+ println(arrayTag[T])
+ println(erasureTag[T])
+ println(Array[T]().toList)
+ println(new Array[T](5).toList)
+ }
+
+ classManifestIsClassTag[Int]
+ classManifestIsClassTag[String]
+ classManifestIsClassTag[Array[Int]]
+
+ def manifestIsClassTag[T: Manifest] = {
+ println(arrayTag[T])
+ println(erasureTag[T])
+ println(Array[T]().toList)
+ println(new Array[T](5).toList)
+ }
+
+ manifestIsClassTag[Int]
+ manifestIsClassTag[String]
+ manifestIsClassTag[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/run/interop_manifests_are_concretetypetags.check b/test/files/run/interop_manifests_are_concretetypetags.check
new file mode 100644
index 0000000000..edab85ecf1
--- /dev/null
+++ b/test/files/run/interop_manifests_are_concretetypetags.check
@@ -0,0 +1,6 @@
+Int
+int
+String
+class java.lang.String
+Array[Int]
+class [I
diff --git a/test/files/run/interop_manifests_are_concretetypetags.scala b/test/files/run/interop_manifests_are_concretetypetags.scala
new file mode 100644
index 0000000000..0b82a56d0a
--- /dev/null
+++ b/test/files/run/interop_manifests_are_concretetypetags.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ def manifestIsConcreteTypeTag[T: Manifest] = {
+ println(concreteTypeTag[T].tpe)
+ println(concreteTypeTag[T].erasure)
+ }
+
+ manifestIsConcreteTypeTag[Int]
+ manifestIsConcreteTypeTag[String]
+ manifestIsConcreteTypeTag[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/run/interop_manifests_are_typetags.check b/test/files/run/interop_manifests_are_typetags.check
new file mode 100644
index 0000000000..edab85ecf1
--- /dev/null
+++ b/test/files/run/interop_manifests_are_typetags.check
@@ -0,0 +1,6 @@
+Int
+int
+String
+class java.lang.String
+Array[Int]
+class [I
diff --git a/test/files/run/interop_manifests_are_typetags.scala b/test/files/run/interop_manifests_are_typetags.scala
new file mode 100644
index 0000000000..03a7b7b6d5
--- /dev/null
+++ b/test/files/run/interop_manifests_are_typetags.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ def manifestIsTypeTag[T: Manifest] = {
+ println(typeTag[T].tpe)
+ println(typeTag[T].erasure)
+ }
+
+ manifestIsTypeTag[Int]
+ manifestIsTypeTag[String]
+ manifestIsTypeTag[Array[Int]]
+} \ No newline at end of file
diff --git a/test/files/run/is-valid-num.scala b/test/files/run/is-valid-num.scala
index f919a21dee..402eff99d6 100644
--- a/test/files/run/is-valid-num.scala
+++ b/test/files/run/is-valid-num.scala
@@ -1,20 +1,312 @@
object Test {
def x = BigInt("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
def y = BigDecimal("" + (Short.MaxValue + 1) + ".0")
-
+ def y1 = BigDecimal("0.1")
+ def y2 = BigDecimal("0.5")
+
def l1 = Int.MaxValue.toLong + 1
def l2 = Int.MinValue.toLong - 1
def main(args: Array[String]): Unit = {
+// assert(x.isWhole, x)
+ assert(!x.isValidDouble, x)
+ assert(!x.isValidFloat, x)
assert(!x.isValidLong, x)
assert(!x.isValidInt, x)
assert(!x.isValidChar, x)
+ assert(!x.isValidShort, x)
assert(!x.isValidByte, x)
+// assert(y.isWhole, y)
assert(!y.isValidShort, y)
assert(y.isValidChar, y)
assert(y.isValidInt, y)
+ assert(y.isValidFloat, y)
+ assert(y.isValidDouble, y)
+ assert(y.isValidLong, y)
+ assert(!y.isValidByte, y)
+// assert(!y1.isWhole)
+ assert(!y1.isValidLong, y1)
+ assert(!y1.isValidFloat, y1)
+ assert(!y1.isValidDouble, y1)
+ assert(!y1.isValidInt, y1)
+ assert(!y1.isValidChar, y1)
+ assert(!y1.isValidShort, y1)
+ assert(!y1.isValidByte, y1)
+ assert(!y2.isValidLong, y2)
+ assert(y2.isValidFloat, y2)
+ assert(y2.isValidDouble, y2)
assert(!l1.isValidInt && (l1 - 1).isValidInt, l1)
assert(!l2.isValidInt && (l2 + 1).isValidInt, l2)
+
+ testBigInts()
+ testNonWholeDoubles()
+ testNaNs()
+ }
+
+ def testBigInts() {
+ def biExp2(e: Int) = BigInt(1) << e
+ def checkBigInt2(bi: BigInt) { checkBigInt(-bi); checkBigInt(bi) }
+
+ val pf = 24
+ val pd = 53
+
+ checkBigInt(BigInt(0))
+ checkBigInt2(biExp2(0))
+
+ checkBigInt2(biExp2(7) - 1)
+ checkBigInt2(biExp2(7))
+ checkBigInt2(biExp2(7) + 1)
+
+ checkBigInt2(biExp2(8) - 1)
+ checkBigInt2(biExp2(8))
+ checkBigInt2(biExp2(8) + 1)
+
+ checkBigInt2(biExp2(15) - 1)
+ checkBigInt2(biExp2(15))
+ checkBigInt2(biExp2(15) + 1)
+
+ checkBigInt2(biExp2(16) - 1)
+ checkBigInt2(biExp2(16))
+ checkBigInt2(biExp2(16) + 1)
+
+ checkBigInt2(biExp2(pf) - 1)
+ checkBigInt2(biExp2(pf))
+ checkBigInt2(biExp2(pf) + 1)
+ checkBigInt2(biExp2(pf) + 2)
+ checkBigInt2(biExp2(pf) - 2)
+ checkBigInt2(biExp2(pf + 1) - 1)
+ checkBigInt2(biExp2(pf + 1))
+ checkBigInt2(biExp2(pf + 1) + 1)
+ checkBigInt2(biExp2(pf + 1) + 2)
+ checkBigInt2(biExp2(pf + 1) + 3)
+ checkBigInt2(biExp2(pf + 1) + 4)
+
+ checkBigInt2(biExp2(31) - 1)
+ checkBigInt2(biExp2(31))
+ checkBigInt2(biExp2(31) + 1)
+
+ checkBigInt2(biExp2(32) - 1)
+ checkBigInt2(biExp2(32))
+ checkBigInt2(biExp2(32) + 1)
+ checkBigInt2(biExp2(32) + biExp2(64 - pf))
+ checkBigInt2(biExp2(32) + biExp2(64 - pf + 1))
+
+ checkBigInt2(biExp2(pd) - 1)
+ checkBigInt2(biExp2(pd))
+ checkBigInt2(biExp2(pd) + 1)
+ checkBigInt2(biExp2(pd) + 2)
+ checkBigInt2(biExp2(pd + 1) - 2)
+ checkBigInt2(biExp2(pd + 1) - 1)
+ checkBigInt2(biExp2(pd + 1))
+ checkBigInt2(biExp2(pd + 1) + 1)
+ checkBigInt2(biExp2(pd + 1) + 2)
+ checkBigInt2(biExp2(pd + 1) + 3)
+ checkBigInt2(biExp2(pd + 1) + 4)
+
+ checkBigInt2(biExp2(63) - 1)
+ checkBigInt2(biExp2(63))
+ checkBigInt2(biExp2(63) + 1)
+ checkBigInt2(biExp2(63) + biExp2(63 - pd))
+ checkBigInt2(biExp2(63) + biExp2(63 - pd + 1))
+ checkBigInt2(biExp2(63) + biExp2(63 - pf))
+ checkBigInt2(biExp2(63) + biExp2(63 - pf + 1))
+
+ checkBigInt2(biExp2(64) - 1)
+ checkBigInt2(biExp2(64))
+ checkBigInt2(biExp2(64) + 1)
+ checkBigInt2(biExp2(64) + biExp2(64 - pd))
+ checkBigInt2(biExp2(64) + biExp2(64 - pd + 1))
+ checkBigInt2(biExp2(64) + biExp2(64 - pf))
+ checkBigInt2(biExp2(64) + biExp2(64 - pf + 1))
+
+ checkBigInt2(biExp2(127))
+ checkBigInt2(biExp2(128) - biExp2(128 - pf))
+ checkBigInt2(biExp2(128) - biExp2(128 - pf - 1))
+ checkBigInt2(biExp2(128))
+
+ checkBigInt2(biExp2(1023))
+ checkBigInt2(biExp2(1024) - biExp2(1024 - pd))
+ checkBigInt2(biExp2(1024) - biExp2(1024 - pd - 1))
+ checkBigInt2(biExp2(1024))
+ }
+
+ def testNonWholeDoubles() {
+ checkNonWholeDouble(0.5)
+ checkNonWholeDouble(-math.E)
+ checkNonWholeDouble((1L << 51).toDouble + 0.5)
+ checkNonWholeDouble((1L << 23).toDouble + 0.5)
+ checkNonWholeDouble(Double.PositiveInfinity)
+ checkNonWholeDouble(Double.NegativeInfinity)
+ }
+
+ def testNaNs() {
+ assert(!Double.NaN.isWhole, Double.NaN)
+// assert(!Double.NaN.isValidDouble, Double.NaN)
+// assert(!Double.NaN.isValidFloat, Double.NaN)
+// assert(!Double.NaN.isValidLong, Double.NaN)
+ assert(!Double.NaN.isValidInt, Double.NaN)
+ assert(!Double.NaN.isValidChar, Double.NaN)
+ assert(!Double.NaN.isValidShort, Double.NaN)
+ assert(!Double.NaN.isValidByte, Double.NaN)
+
+ assert(!Float.NaN.isWhole, Float.NaN)
+// assert(!Float.NaN.isValidDouble, Float.NaN)
+// assert(!Float.NaN.isValidFloat, Float.NaN)
+// assert(!Float.NaN.isValidLong, Float.NaN)
+ assert(!Float.NaN.isValidInt, Float.NaN)
+ assert(!Float.NaN.isValidChar, Float.NaN)
+ assert(!Float.NaN.isValidShort, Float.NaN)
+ assert(!Float.NaN.isValidByte, Float.NaN)
+ }
+
+ def checkNonWholeDouble(d: Double) {
+ val f = d.toFloat
+ val isFloat = f == d
+
+ if (!d.isInfinity) {
+ val bd = BigDecimal(new java.math.BigDecimal(d))
+// assert(!bd.isWhole, bd)
+ assert(bd.isValidDouble, bd)
+ assert(bd.isValidFloat == isFloat, bd)
+ assert(!bd.isValidLong, bd)
+ assert(!bd.isValidInt, bd)
+ assert(!bd.isValidChar, bd)
+ assert(!bd.isValidShort, bd)
+ assert(!bd.isValidByte, bd)
+ }
+
+ assert(!d.isWhole, d)
+// assert(d.isValidDouble, d)
+// assert(d.isValidFloat == isFloat, d)
+// assert(!d.isValidLong, d)
+ assert(!d.isValidInt, d)
+ assert(!d.isValidChar, d)
+ assert(!d.isValidShort, d)
+ assert(!d.isValidByte, d)
+
+ if (isFloat) {
+ assert(!f.isWhole, f)
+// assert(f.isValidDouble, f)
+// assert(f.isValidFloat == isFloat, f)
+// assert(!f.isValidLong, f)
+ assert(!f.isValidInt, f)
+ assert(!f.isValidChar, f)
+ assert(!f.isValidShort, f)
+ assert(!f.isValidByte, f)
+ }
+ }
+
+ def checkBigInt(bi: BigInt) {
+ val bd = BigDecimal(bi, java.math.MathContext.UNLIMITED)
+ val isByte = bi >= Byte.MinValue && bi <= Byte.MaxValue
+ val isShort = bi >= Short.MinValue && bi <= Short.MaxValue
+ val isChar = bi >= Char.MinValue && bi <= Char.MaxValue
+ val isInt = bi >= Int.MinValue && bi <= Int.MaxValue
+ val isLong = bi >= Long.MinValue && bi <= Long.MaxValue
+ val isFloat = !bi.toFloat.isInfinity && bd.compare(BigDecimal(new java.math.BigDecimal(bi.toFloat))) == 0
+ val isDouble = !bi.toDouble.isInfinity && bd.compare(BigDecimal(new java.math.BigDecimal(bi.toDouble))) == 0
+
+// assert(bd.isWhole, bd)
+ assert(bd.isValidDouble == isDouble, bd)
+ assert(bd.isValidFloat == isFloat, bd)
+ assert(bd.isValidLong == isLong, bd)
+ assert(bd.isValidInt == isInt, bd)
+ assert(bd.isValidChar == isChar, bd)
+ assert(bd.isValidShort == isShort, bd)
+ assert(bd.isValidByte == isByte, bd)
+
+// assert(bi.isWhole, bi)
+ assert(bi.isValidDouble == isDouble, bi)
+ assert(bi.isValidFloat == isFloat, bi)
+ assert(bi.isValidLong == isLong, bi)
+ assert(bi.isValidInt == isInt, bi)
+ assert(bi.isValidChar == isChar, bi)
+ assert(bi.isValidShort == isShort, bi)
+ assert(bi.isValidByte == isByte, bi)
+
+ if (isDouble) {
+ val d = bi.toDouble
+ assert(d.isWhole, d)
+// assert(d.isValidDouble == isDouble, d)
+// assert(d.isValidFloat == isFloat, d)
+// assert(d.isValidLong == isLong, d)
+ assert(d.isValidInt == isInt, d)
+ assert(d.isValidChar == isChar, d)
+ assert(d.isValidShort == isShort, d)
+ assert(d.isValidByte == isByte, d)
+ }
+
+ if (isFloat) {
+ val f = bi.toFloat
+ assert(f.isWhole, f)
+// assert(f.isValidDouble == isDouble, f)
+// assert(f.isValidFloat == isFloat, f)
+// assert(f.isValidLong == isLong, f)
+ assert(f.isValidInt == isInt, f)
+ assert(f.isValidChar == isChar, f)
+ assert(f.isValidShort == isShort, f)
+ assert(f.isValidByte == isByte, f)
+ }
+
+ if (isLong) {
+ val l = bi.toLong
+ assert(l.isWhole, l)
+// assert(l.isValidDouble == isDouble, l)
+// assert(l.isValidFloat == isFloat, l)
+// assert(l.isValidLong == isLong, l)
+ assert(l.isValidInt == isInt, l)
+ assert(l.isValidChar == isChar, l)
+ assert(l.isValidShort == isShort, l)
+ assert(l.isValidByte == isByte, l)
+ }
+
+ if (isInt) {
+ val i = bi.toInt
+ assert(i.isWhole, i)
+// assert(i.isValidDouble == isDouble, i)
+// assert(i.isValidFloat == isFloat, i)
+// assert(i.isValidLong == isLong, i)
+ assert(i.isValidInt == isInt, i)
+ assert(i.isValidChar == isChar, i)
+ assert(i.isValidShort == isShort, i)
+ assert(i.isValidByte == isByte, i)
+ }
+
+ if (isChar) {
+ val c = bi.toChar
+ assert(c.isWhole, c)
+// assert(c.isValidDouble == isDouble, c)
+// assert(c.isValidFloat == isFloat, c)
+// assert(c.isValidLong == isLong, c)
+ assert(c.isValidInt == isInt, c)
+ assert(c.isValidChar == isChar, c)
+ assert(c.isValidShort == isShort, c)
+ assert(c.isValidByte == isByte, c)
+ }
+
+ if (isShort) {
+ val s = bi.toShort
+ assert(s.isWhole, s)
+// assert(s.isValidDouble == isDouble, s)
+// assert(s.isValidFloat == isFloat, s)
+// assert(s.isValidLong == isLong, s)
+ assert(s.isValidInt == isInt, s)
+ assert(s.isValidChar == isChar, s)
+ assert(s.isValidShort == isShort, s)
+ assert(s.isValidByte == isByte, s)
+ }
+
+ if (isByte) {
+ val b = bi.toByte
+ assert(b.isWhole, b)
+// assert(b.isValidDouble == isDouble, b)
+// assert(b.isValidFloat == isFloat, b)
+// assert(b.isValidLong == isLong, b)
+ assert(b.isValidInt == isInt, b)
+ assert(b.isValidChar == isChar, b)
+ assert(b.isValidShort == isShort, b)
+ assert(b.isValidByte == isByte, b)
+ }
}
}
diff --git a/test/files/run/lift-and-unlift.scala b/test/files/run/lift-and-unlift.scala
index b944c70155..a4a5d9502e 100644
--- a/test/files/run/lift-and-unlift.scala
+++ b/test/files/run/lift-and-unlift.scala
@@ -2,7 +2,7 @@ import Function.unlift
object Test {
def evens1(x: Int) = if (x % 2 == 0) Some(x) else None
- def evens2: PartialFunction[Int, Int] = {
+ val evens2: PartialFunction[Int, Int] = {
case x if x % 2 == 0 => x
}
@@ -21,7 +21,7 @@ object Test {
})
assert(f1 eq f3.lift)
- // Hmm, why is this not true:
- // assert(f2 eq f4.lift)
+ assert(f4 eq unlift(f2))
+ assert(f4 eq evens2)
}
}
diff --git a/test/files/run/macro-abort-fresh.check b/test/files/run/macro-abort-fresh.check
new file mode 100644
index 0000000000..28057c2883
--- /dev/null
+++ b/test/files/run/macro-abort-fresh.check
@@ -0,0 +1,6 @@
+$1$
+qwe1
+qwe2
+reflective compilation has failed:
+
+blargh
diff --git a/test/files/run/macro-abort-fresh.flags b/test/files/run/macro-abort-fresh.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-abort-fresh.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-abort-fresh/Macros_1.scala b/test/files/run/macro-abort-fresh/Macros_1.scala
new file mode 100644
index 0000000000..4186c4c4a6
--- /dev/null
+++ b/test/files/run/macro-abort-fresh/Macros_1.scala
@@ -0,0 +1,15 @@
+import scala.reflect.makro.Context
+
+object Impls {
+ def impl(c: Context) = {
+ import c.mirror._
+ println(c.fresh())
+ println(c.fresh("qwe"))
+ println(c.fresh(newTypeName("qwe")))
+ c.abort(NoPosition, "blargh")
+ }
+}
+
+object Macros {
+ def foo = macro Impls.impl
+} \ No newline at end of file
diff --git a/test/files/run/macro-abort-fresh/Test_2.scala b/test/files/run/macro-abort-fresh/Test_2.scala
new file mode 100644
index 0000000000..ecf48b9752
--- /dev/null
+++ b/test/files/run/macro-abort-fresh/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Select(Ident("Macros"), newTermName("foo"))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+} \ No newline at end of file
diff --git a/test/files/run/macro-basic-ma-md-mi.check b/test/files/run/macro-basic-ma-md-mi.check
new file mode 100644
index 0000000000..b74e882ae3
--- /dev/null
+++ b/test/files/run/macro-basic-ma-md-mi.check
@@ -0,0 +1 @@
+31 \ No newline at end of file
diff --git a/test/files/run/macro-basic-ma-md-mi.flags b/test/files/run/macro-basic-ma-md-mi.flags
new file mode 100644
index 0000000000..5e5dd6ce79
--- /dev/null
+++ b/test/files/run/macro-basic-ma-md-mi.flags
@@ -0,0 +1 @@
+-language:experimental.macros
diff --git a/test/files/run/macro-basic-ma-md-mi/Impls_1.scala b/test/files/run/macro-basic-ma-md-mi/Impls_1.scala
new file mode 100644
index 0000000000..3f23e349d5
--- /dev/null
+++ b/test/files/run/macro-basic-ma-md-mi/Impls_1.scala
@@ -0,0 +1,21 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1))))
+ Expr[Int](body)
+ }
+
+ def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2))))
+ Expr[Int](body)
+ }
+
+ def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3))))
+ Expr[Int](body)
+ }
+}
diff --git a/test/files/run/macro-basic-ma-md-mi/Macros_2.scala b/test/files/run/macro-basic-ma-md-mi/Macros_2.scala
new file mode 100644
index 0000000000..5279043746
--- /dev/null
+++ b/test/files/run/macro-basic-ma-md-mi/Macros_2.scala
@@ -0,0 +1,10 @@
+object Macros {
+ object Shmacros {
+ def foo(x: Int): Int = macro Impls.foo
+ }
+ def bar(x: Int): Int = macro Impls.bar
+}
+
+class Macros {
+ def quux(x: Int): Int = macro Impls.quux
+} \ No newline at end of file
diff --git a/test/files/run/macro-basic-ma-md-mi/Test_3.scala b/test/files/run/macro-basic-ma-md-mi/Test_3.scala
new file mode 100644
index 0000000000..e9a10e20c9
--- /dev/null
+++ b/test/files/run/macro-basic-ma-md-mi/Test_3.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros.Shmacros._
+ println(foo(2) + Macros.bar(2) * new Macros().quux(4))
+} \ No newline at end of file
diff --git a/test/files/run/macro-basic-ma-mdmi.check b/test/files/run/macro-basic-ma-mdmi.check
new file mode 100644
index 0000000000..b74e882ae3
--- /dev/null
+++ b/test/files/run/macro-basic-ma-mdmi.check
@@ -0,0 +1 @@
+31 \ No newline at end of file
diff --git a/test/files/run/macro-basic-ma-mdmi.flags b/test/files/run/macro-basic-ma-mdmi.flags
new file mode 100644
index 0000000000..5e5dd6ce79
--- /dev/null
+++ b/test/files/run/macro-basic-ma-mdmi.flags
@@ -0,0 +1 @@
+-language:experimental.macros
diff --git a/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala b/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala
new file mode 100644
index 0000000000..44bfe861e3
--- /dev/null
+++ b/test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala
@@ -0,0 +1,32 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1))))
+ Expr[Int](body)
+ }
+
+ def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2))))
+ Expr[Int](body)
+ }
+
+ def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3))))
+ Expr[Int](body)
+ }
+}
+
+object Macros {
+ object Shmacros {
+ def foo(x: Int): Int = macro Impls.foo
+ }
+ def bar(x: Int): Int = macro Impls.bar
+}
+
+class Macros {
+ def quux(x: Int): Int = macro Impls.quux
+} \ No newline at end of file
diff --git a/test/files/run/macro-basic-ma-mdmi/Test_2.scala b/test/files/run/macro-basic-ma-mdmi/Test_2.scala
new file mode 100644
index 0000000000..e9a10e20c9
--- /dev/null
+++ b/test/files/run/macro-basic-ma-mdmi/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros.Shmacros._
+ println(foo(2) + Macros.bar(2) * new Macros().quux(4))
+} \ No newline at end of file
diff --git a/test/files/run/macro-basic-mamd-mi.check b/test/files/run/macro-basic-mamd-mi.check
new file mode 100644
index 0000000000..b74e882ae3
--- /dev/null
+++ b/test/files/run/macro-basic-mamd-mi.check
@@ -0,0 +1 @@
+31 \ No newline at end of file
diff --git a/test/files/run/macro-basic-mamd-mi.flags b/test/files/run/macro-basic-mamd-mi.flags
new file mode 100644
index 0000000000..5e5dd6ce79
--- /dev/null
+++ b/test/files/run/macro-basic-mamd-mi.flags
@@ -0,0 +1 @@
+-language:experimental.macros
diff --git a/test/files/run/macro-basic-mamd-mi/Impls_1.scala b/test/files/run/macro-basic-mamd-mi/Impls_1.scala
new file mode 100644
index 0000000000..82d2cce2f5
--- /dev/null
+++ b/test/files/run/macro-basic-mamd-mi/Impls_1.scala
@@ -0,0 +1,19 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))))
+ }
+
+ def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))))
+ }
+
+ def quux(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3))))
+ Expr[Int](body)
+ }
+}
diff --git a/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala b/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala
new file mode 100644
index 0000000000..d3746894f0
--- /dev/null
+++ b/test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala
@@ -0,0 +1,15 @@
+object Macros {
+ object Shmacros {
+ def foo(x: Int): Int = macro Impls.foo
+ }
+ def bar(x: Int): Int = macro Impls.bar
+}
+
+class Macros {
+ def quux(x: Int): Int = macro Impls.quux
+}
+
+object Test extends App {
+ import Macros.Shmacros._
+ println(foo(2) + Macros.bar(2) * new Macros().quux(4))
+} \ No newline at end of file
diff --git a/test/files/run/macro-basic.check b/test/files/run/macro-basic.check
deleted file mode 100644
index d434014897..0000000000
--- a/test/files/run/macro-basic.check
+++ /dev/null
@@ -1 +0,0 @@
-10
diff --git a/test/files/run/macro-basic.flags b/test/files/run/macro-basic.flags
deleted file mode 100644
index 06a7b31f11..0000000000
--- a/test/files/run/macro-basic.flags
+++ /dev/null
@@ -1 +0,0 @@
--Xmacros
diff --git a/test/files/run/macro-basic/Macros_1.scala b/test/files/run/macro-basic/Macros_1.scala
deleted file mode 100644
index c2ea183abe..0000000000
--- a/test/files/run/macro-basic/Macros_1.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-object Macros {
- object Shmacros {
- def macro foo(x: Int): Int = x
- }
- def macro bar(x: Int): Int = x
-}
-
-class Macros {
- def macro quux(x: Int): Int = x
-} \ No newline at end of file
diff --git a/test/files/run/macro-bodyexpandstoimpl.check b/test/files/run/macro-bodyexpandstoimpl.check
new file mode 100644
index 0000000000..f70d7bba4a
--- /dev/null
+++ b/test/files/run/macro-bodyexpandstoimpl.check
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/test/files/run/macro-bodyexpandstoimpl.flags b/test/files/run/macro-bodyexpandstoimpl.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-bodyexpandstoimpl.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala
new file mode 100644
index 0000000000..5c5ec2c999
--- /dev/null
+++ b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala
@@ -0,0 +1,12 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = x
+
+ def refToFoo(dummy: Int) = macro refToFoo_impl
+ def refToFoo_impl(c: Ctx)(dummy: c.Expr[Int]) = {
+ import c.mirror._
+ val body = Select(Ident(newTermName("Impls")), newTermName("foo"))
+ Expr[Int](body)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala b/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala
new file mode 100644
index 0000000000..2934201a16
--- /dev/null
+++ b/test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def foo(x: Int) = macro Impls.refToFoo(42)
+}
+
+object Test extends App {
+ import Macros._
+ println(foo(42))
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-annotation.check b/test/files/run/macro-declared-in-annotation.check
new file mode 100644
index 0000000000..1ea14b4e20
--- /dev/null
+++ b/test/files/run/macro-declared-in-annotation.check
@@ -0,0 +1 @@
+it works
diff --git a/test/files/run/macro-declared-in-annotation.flags b/test/files/run/macro-declared-in-annotation.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-annotation.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-annotation/Impls_1.scala b/test/files/run/macro-declared-in-annotation/Impls_1.scala
new file mode 100644
index 0000000000..a1234a7374
--- /dev/null
+++ b/test/files/run/macro-declared-in-annotation/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(List(printPrefix), Literal(Constant("this is deprecated")))
+ Expr[String](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-annotation/Macros_2.scala b/test/files/run/macro-declared-in-annotation/Macros_2.scala
new file mode 100644
index 0000000000..a565849aa9
--- /dev/null
+++ b/test/files/run/macro-declared-in-annotation/Macros_2.scala
@@ -0,0 +1,8 @@
+class foo(val bar: String) extends StaticAnnotation
+
+object Api {
+ // foo in ann must have a different name
+ // otherwise, we get bitten by https://issues.scala-lang.org/browse/SI-5544
+ @foo({def fooInAnn = macro Impls.foo; fooInAnn})
+ def foo = println("it works")
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-annotation/Test_3.scala b/test/files/run/macro-declared-in-annotation/Test_3.scala
new file mode 100644
index 0000000000..866487f028
--- /dev/null
+++ b/test/files/run/macro-declared-in-annotation/Test_3.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Api.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-anonymous.check b/test/files/run/macro-declared-in-anonymous.check
new file mode 100644
index 0000000000..09b8d015a6
--- /dev/null
+++ b/test/files/run/macro-declared-in-anonymous.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](Test.this.macros)
+it works
diff --git a/test/files/run/macro-declared-in-anonymous.flags b/test/files/run/macro-declared-in-anonymous.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-anonymous.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-anonymous/Impls_1.scala b/test/files/run/macro-declared-in-anonymous/Impls_1.scala
new file mode 100644
index 0000000000..c0827ace31
--- /dev/null
+++ b/test/files/run/macro-declared-in-anonymous/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala b/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala
new file mode 100644
index 0000000000..8bd8c172c9
--- /dev/null
+++ b/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val macros = new { def foo = macro Impls.foo }
+ macros.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-block.check b/test/files/run/macro-declared-in-block.check
new file mode 100644
index 0000000000..a61fd13087
--- /dev/null
+++ b/test/files/run/macro-declared-in-block.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](<empty>)
+it works
diff --git a/test/files/run/macro-declared-in-block.flags b/test/files/run/macro-declared-in-block.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-block.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-block/Impls_1.scala b/test/files/run/macro-declared-in-block/Impls_1.scala
new file mode 100644
index 0000000000..c0827ace31
--- /dev/null
+++ b/test/files/run/macro-declared-in-block/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-block/Macros_Test_2.scala b/test/files/run/macro-declared-in-block/Macros_Test_2.scala
new file mode 100644
index 0000000000..69088e24bc
--- /dev/null
+++ b/test/files/run/macro-declared-in-block/Macros_Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ {
+ def foo = macro Impls.foo
+ foo
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class-class.check b/test/files/run/macro-declared-in-class-class.check
new file mode 100644
index 0000000000..480c2f906f
--- /dev/null
+++ b/test/files/run/macro-declared-in-class-class.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](new Test.this.outer.Macros())
+it works
diff --git a/test/files/run/macro-declared-in-class-class.flags b/test/files/run/macro-declared-in-class-class.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-class-class.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class-class/Impls_1.scala b/test/files/run/macro-declared-in-class-class/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-class-class/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala
new file mode 100644
index 0000000000..871857a97f
--- /dev/null
+++ b/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+class Macros {
+ class Macros {
+ def foo = macro Impls.foo
+ }
+}
+
+object Test extends App {
+ val outer = new Macros()
+ new outer.Macros().foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class-object.check b/test/files/run/macro-declared-in-class-object.check
new file mode 100644
index 0000000000..f7ba5a53cb
--- /dev/null
+++ b/test/files/run/macro-declared-in-class-object.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](Test.this.outer.Macros)
+it works
diff --git a/test/files/run/macro-declared-in-class-object.flags b/test/files/run/macro-declared-in-class-object.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-class-object.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class-object/Impls_1.scala b/test/files/run/macro-declared-in-class-object/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-class-object/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala
new file mode 100644
index 0000000000..994f9fe935
--- /dev/null
+++ b/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+class Macros {
+ object Macros {
+ def foo = macro Impls.foo
+ }
+}
+
+object Test extends App {
+ val outer = new Macros()
+ outer.Macros.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class.check b/test/files/run/macro-declared-in-class.check
new file mode 100644
index 0000000000..946851e4bb
--- /dev/null
+++ b/test/files/run/macro-declared-in-class.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](new Macros())
+it works
diff --git a/test/files/run/macro-declared-in-class.flags b/test/files/run/macro-declared-in-class.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-class.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class/Impls_1.scala b/test/files/run/macro-declared-in-class/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-class/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-class/Macros_Test_2.scala
new file mode 100644
index 0000000000..1b9d13e775
--- /dev/null
+++ b/test/files/run/macro-declared-in-class/Macros_Test_2.scala
@@ -0,0 +1,7 @@
+class Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ new Macros().foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-default-param.check b/test/files/run/macro-declared-in-default-param.check
new file mode 100644
index 0000000000..00052ad018
--- /dev/null
+++ b/test/files/run/macro-declared-in-default-param.check
@@ -0,0 +1,5 @@
+prefix = Expr[Nothing](<empty>)
+it works
+it works
+prefix = Expr[Nothing](<empty>)
+it works
diff --git a/test/files/run/macro-declared-in-default-param.flags b/test/files/run/macro-declared-in-default-param.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-default-param.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-default-param/Impls_1.scala b/test/files/run/macro-declared-in-default-param/Impls_1.scala
new file mode 100644
index 0000000000..e45095812a
--- /dev/null
+++ b/test/files/run/macro-declared-in-default-param/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(List(printPrefix), Literal(Constant("it works")))
+ Expr[String](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala b/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala
new file mode 100644
index 0000000000..356029e63e
--- /dev/null
+++ b/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala
@@ -0,0 +1,7 @@
+object Test extends App {
+ def foo(bar: String = { def foo = macro Impls.foo; foo }) = println(bar)
+
+ foo()
+ foo("it works")
+ foo()
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-implicit-class.check b/test/files/run/macro-declared-in-implicit-class.check
new file mode 100644
index 0000000000..b3640ceaa7
--- /dev/null
+++ b/test/files/run/macro-declared-in-implicit-class.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](Macros.foo("2"))
+Some(2)
diff --git a/test/files/run/macro-declared-in-implicit-class.flags b/test/files/run/macro-declared-in-implicit-class.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-implicit-class.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala
new file mode 100644
index 0000000000..8605d4a8be
--- /dev/null
+++ b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala
@@ -0,0 +1,19 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def toOptionOfInt(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, newTermName("x")), newTermName("toInt")))))
+ Expr[Option[Int]](body)
+ }
+}
+
+object Macros {
+ implicit def foo(x: String): Foo = new Foo(x)
+
+ class Foo(val x: String) {
+ def toOptionOfInt = macro Impls.toOptionOfInt
+ }
+}
diff --git a/test/files/run/macro-declared-in-implicit-class/Test_2.scala b/test/files/run/macro-declared-in-implicit-class/Test_2.scala
new file mode 100644
index 0000000000..d0bc9cc38c
--- /dev/null
+++ b/test/files/run/macro-declared-in-implicit-class/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros._
+ println("2".toOptionOfInt)
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-method.check b/test/files/run/macro-declared-in-method.check
new file mode 100644
index 0000000000..a61fd13087
--- /dev/null
+++ b/test/files/run/macro-declared-in-method.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](<empty>)
+it works
diff --git a/test/files/run/macro-declared-in-method.flags b/test/files/run/macro-declared-in-method.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-method.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-method/Impls_1.scala b/test/files/run/macro-declared-in-method/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-method/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-method/Macros_Test_2.scala b/test/files/run/macro-declared-in-method/Macros_Test_2.scala
new file mode 100644
index 0000000000..ed5c8b7c43
--- /dev/null
+++ b/test/files/run/macro-declared-in-method/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Test extends App {
+ def bar() = {
+ def foo = macro Impls.foo
+ foo
+ }
+
+ bar()
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object-class.check b/test/files/run/macro-declared-in-object-class.check
new file mode 100644
index 0000000000..480c2f906f
--- /dev/null
+++ b/test/files/run/macro-declared-in-object-class.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](new Test.this.outer.Macros())
+it works
diff --git a/test/files/run/macro-declared-in-object-class.flags b/test/files/run/macro-declared-in-object-class.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-object-class.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object-class/Impls_1.scala b/test/files/run/macro-declared-in-object-class/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-object-class/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala b/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala
new file mode 100644
index 0000000000..204deed61c
--- /dev/null
+++ b/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+object Macros {
+ class Macros {
+ def foo = macro Impls.foo
+ }
+}
+
+object Test extends App {
+ val outer = Macros
+ new outer.Macros().foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object-object.check b/test/files/run/macro-declared-in-object-object.check
new file mode 100644
index 0000000000..f7ba5a53cb
--- /dev/null
+++ b/test/files/run/macro-declared-in-object-object.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](Test.this.outer.Macros)
+it works
diff --git a/test/files/run/macro-declared-in-object-object.flags b/test/files/run/macro-declared-in-object-object.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-object-object.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object-object/Impls_1.scala b/test/files/run/macro-declared-in-object-object/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-object-object/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala
new file mode 100644
index 0000000000..e261a50f3d
--- /dev/null
+++ b/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+object Macros {
+ object Macros {
+ def foo = macro Impls.foo
+ }
+}
+
+object Test extends App {
+ val outer = Macros
+ outer.Macros.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object.check b/test/files/run/macro-declared-in-object.check
new file mode 100644
index 0000000000..05a8cc48ea
--- /dev/null
+++ b/test/files/run/macro-declared-in-object.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](Macros)
+it works
diff --git a/test/files/run/macro-declared-in-object.flags b/test/files/run/macro-declared-in-object.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-object.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object/Impls_1.scala b/test/files/run/macro-declared-in-object/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-object/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-object/Macros_Test_2.scala
new file mode 100644
index 0000000000..a5a4862ba0
--- /dev/null
+++ b/test/files/run/macro-declared-in-object/Macros_Test_2.scala
@@ -0,0 +1,7 @@
+object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ Macros.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-package-object.check b/test/files/run/macro-declared-in-package-object.check
new file mode 100644
index 0000000000..6f797f3c68
--- /dev/null
+++ b/test/files/run/macro-declared-in-package-object.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](Macros.`package`)
+it works
diff --git a/test/files/run/macro-declared-in-package-object.flags b/test/files/run/macro-declared-in-package-object.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-package-object.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-package-object/Impls_1.scala b/test/files/run/macro-declared-in-package-object/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-package-object/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala b/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala
new file mode 100644
index 0000000000..54a5962e80
--- /dev/null
+++ b/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+package object Macros {
+ def foo = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-refinement.check b/test/files/run/macro-declared-in-refinement.check
new file mode 100644
index 0000000000..861cd43b01
--- /dev/null
+++ b/test/files/run/macro-declared-in-refinement.check
@@ -0,0 +1,2 @@
+prefix = Expr[Nothing](Test.this.macros)
+it works
diff --git a/test/files/run/macro-declared-in-refinement.flags b/test/files/run/macro-declared-in-refinement.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-refinement.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-refinement/Impls_1.scala b/test/files/run/macro-declared-in-refinement/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-refinement/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala b/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala
new file mode 100644
index 0000000000..f746c2da57
--- /dev/null
+++ b/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala
@@ -0,0 +1,6 @@
+class Base
+
+object Test extends App {
+ val macros = new Base { def foo = macro Impls.foo }
+ macros.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-trait.check b/test/files/run/macro-declared-in-trait.check
new file mode 100644
index 0000000000..d5d9e4e457
--- /dev/null
+++ b/test/files/run/macro-declared-in-trait.check
@@ -0,0 +1,15 @@
+prefix = Expr[Nothing]({
+ final class $anon extends Object with Base {
+ def <init>(): anonymous class $anon = {
+ $anon.super.<init>();
+ ()
+ };
+ <empty>
+ };
+ new $anon()
+})
+it works
+prefix = Expr[Nothing](Macros)
+it works
+prefix = Expr[Nothing](new Macros())
+it works
diff --git a/test/files/run/macro-declared-in-trait.flags b/test/files/run/macro-declared-in-trait.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-declared-in-trait.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-trait/Impls_1.scala b/test/files/run/macro-declared-in-trait/Impls_1.scala
new file mode 100644
index 0000000000..c2e6933582
--- /dev/null
+++ b/test/files/run/macro-declared-in-trait/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
+ val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-declared-in-trait/Macros_Test_2.scala b/test/files/run/macro-declared-in-trait/Macros_Test_2.scala
new file mode 100644
index 0000000000..f75906b636
--- /dev/null
+++ b/test/files/run/macro-declared-in-trait/Macros_Test_2.scala
@@ -0,0 +1,13 @@
+trait Base {
+ def foo = macro Impls.foo
+}
+
+object Macros extends Base
+
+class Macros extends Base
+
+object Test extends App {
+ (new Base {}).foo
+ Macros.foo
+ new Macros().foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-a.check b/test/files/run/macro-def-infer-return-type-a.check
new file mode 100644
index 0000000000..f70d7bba4a
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-a.check
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-a.flags b/test/files/run/macro-def-infer-return-type-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-a/Impls_1.scala b/test/files/run/macro-def-infer-return-type-a/Impls_1.scala
new file mode 100644
index 0000000000..2346a6106d
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-a/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = x
+}
diff --git a/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala
new file mode 100644
index 0000000000..60fe9dc1c2
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo(x: Int) = macro Impls.foo
+ println(foo(42))
+} \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-b.check b/test/files/run/macro-def-infer-return-type-b.check
new file mode 100644
index 0000000000..f34d257c82
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-b.check
@@ -0,0 +1,6 @@
+reflective compilation has failed:
+
+exception during macro expansion:
+java.lang.Error: an implementation is missing
+ at Impls$.foo(Impls_Macros_1.scala:5)
+
diff --git a/test/files/run/macro-def-infer-return-type-b.flags b/test/files/run/macro-def-infer-return-type-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala b/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala
new file mode 100644
index 0000000000..8640713846
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T](c: Ctx)(x: c.Expr[T]) =
+ throw new Error("an implementation is missing")
+}
+
+object Macros {
+ def foo[T](x: T) = macro Impls.foo[T]
+} \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-b/Test_2.scala b/test/files/run/macro-def-infer-return-type-b/Test_2.scala
new file mode 100644
index 0000000000..f8f15b4224
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-b/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+} \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-c.check b/test/files/run/macro-def-infer-return-type-c.check
new file mode 100644
index 0000000000..f70d7bba4a
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-c.check
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-c.flags b/test/files/run/macro-def-infer-return-type-c.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-c.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-c/Impls_1.scala b/test/files/run/macro-def-infer-return-type-c/Impls_1.scala
new file mode 100644
index 0000000000..f3e53bbea7
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-c/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T](c: Ctx)(x: c.Expr[T]): c.Expr[T] = x
+}
diff --git a/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala
new file mode 100644
index 0000000000..967d16f6de
--- /dev/null
+++ b/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo[T](x: T) = macro Impls.foo[T]
+ println(foo(42))
+} \ No newline at end of file
diff --git a/test/files/run/macro-def-path-dependent-a.check b/test/files/run/macro-def-path-dependent-a.check
new file mode 100644
index 0000000000..1ea14b4e20
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-a.check
@@ -0,0 +1 @@
+it works
diff --git a/test/files/run/macro-def-path-dependent-a.flags b/test/files/run/macro-def-path-dependent-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala
new file mode 100644
index 0000000000..d7167e671c
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala
@@ -0,0 +1,21 @@
+import scala.reflect.makro.{Context => Ctx}
+
+trait Exprs {
+ self: Universe =>
+
+ class Expr[T]
+}
+
+trait Reifiers {
+ self: Universe =>
+
+ type Expr[T]
+
+ def reify[T](expr: T) = macro Impls.reify[T]
+}
+
+trait Universe extends Exprs with Reifiers
+
+object Impls {
+ def reify[T](cc: Ctx{ type PrefixType = Reifiers })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ???
+}
diff --git a/test/files/run/macro-def-path-dependent-a/Test_2.scala b/test/files/run/macro-def-path-dependent-a/Test_2.scala
new file mode 100644
index 0000000000..7dffc5107d
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-a/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println("it works")
+} \ No newline at end of file
diff --git a/test/files/run/macro-def-path-dependent-b.check b/test/files/run/macro-def-path-dependent-b.check
new file mode 100644
index 0000000000..1ea14b4e20
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-b.check
@@ -0,0 +1 @@
+it works
diff --git a/test/files/run/macro-def-path-dependent-b.flags b/test/files/run/macro-def-path-dependent-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala
new file mode 100644
index 0000000000..44af6949a7
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala
@@ -0,0 +1,20 @@
+import scala.reflect.makro.{Context => Ctx}
+
+trait Exprs {
+ self: Universe =>
+
+ class Expr[T]
+}
+
+trait Reifiers {
+ self: Universe =>
+
+}
+
+trait Universe extends Exprs with Reifiers {
+ def reify[T](expr: T) = macro Impls.reify[T]
+}
+
+object Impls {
+ def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ???
+}
diff --git a/test/files/run/macro-def-path-dependent-b/Test_2.scala b/test/files/run/macro-def-path-dependent-b/Test_2.scala
new file mode 100644
index 0000000000..7dffc5107d
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-b/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println("it works")
+} \ No newline at end of file
diff --git a/test/files/run/macro-def-path-dependent-c.check b/test/files/run/macro-def-path-dependent-c.check
new file mode 100644
index 0000000000..1ea14b4e20
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-c.check
@@ -0,0 +1 @@
+it works
diff --git a/test/files/run/macro-def-path-dependent-c.flags b/test/files/run/macro-def-path-dependent-c.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-c.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala
new file mode 100644
index 0000000000..305146c48b
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala
@@ -0,0 +1,20 @@
+import scala.reflect.makro.{Context => Ctx}
+
+trait Exprs {
+ self: Universe =>
+
+ class Expr[T]
+}
+
+trait Reifiers {
+ self: Universe =>
+
+}
+
+trait Universe extends Exprs with Reifiers {
+ def reify[T](expr: T): Expr[T] = macro Impls.reify[T]
+}
+
+object Impls {
+ def reify[T](cc: Ctx{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = ???
+}
diff --git a/test/files/run/macro-def-path-dependent-c/Test_2.scala b/test/files/run/macro-def-path-dependent-c/Test_2.scala
new file mode 100644
index 0000000000..7dffc5107d
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-c/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println("it works")
+} \ No newline at end of file
diff --git a/test/files/run/macro-def-path-dependent-d.check b/test/files/run/macro-def-path-dependent-d.check
new file mode 100644
index 0000000000..1ea14b4e20
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-d.check
@@ -0,0 +1 @@
+it works
diff --git a/test/files/run/macro-def-path-dependent-d.flags b/test/files/run/macro-def-path-dependent-d.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-d.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala
new file mode 100644
index 0000000000..32f03e778e
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala
@@ -0,0 +1,8 @@
+import scala.reflect.makro.Context
+import scala.reflect.api.Universe
+
+object Test {
+ def materializeTypeTag[T](u: Universe)(e: T) = macro materializeTypeTag_impl[T]
+
+ def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe])(e: c.Expr[T]): c.Expr[u.value.TypeTag[T]] = ???
+}
diff --git a/test/files/run/macro-def-path-dependent-d/Test_2.scala b/test/files/run/macro-def-path-dependent-d/Test_2.scala
new file mode 100644
index 0000000000..7dffc5107d
--- /dev/null
+++ b/test/files/run/macro-def-path-dependent-d/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println("it works")
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit.check b/test/files/run/macro-expand-implicit-macro-has-implicit.check
new file mode 100644
index 0000000000..2f562a182f
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-has-implicit.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit.flags b/test/files/run/macro-expand-implicit-macro-has-implicit.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-has-implicit.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala
new file mode 100644
index 0000000000..39db275e1c
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(x.tree))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala
new file mode 100644
index 0000000000..ffb04dc80b
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ implicit val x = 42
+ def foo(implicit x: Int) = macro Impls.foo
+ foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit.check b/test/files/run/macro-expand-implicit-macro-is-implicit.check
new file mode 100644
index 0000000000..42abf4579b
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-implicit.check
@@ -0,0 +1,2 @@
+Some(2)
+2
diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit.flags b/test/files/run/macro-expand-implicit-macro-is-implicit.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-implicit.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala
new file mode 100644
index 0000000000..0262485994
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[String]): c.Expr[Option[Int]] = {
+ import c.mirror._
+ val body = Apply(Ident(definitions.SomeModule), List(Select(x.tree, newTermName("toInt"))))
+ Expr[Option[Int]](body)
+ }
+}
diff --git a/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala
new file mode 100644
index 0000000000..81ebd63c5f
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+object Macros {
+ implicit def foo(x: String): Option[Int] = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ println("2": Option[Int])
+ val s: Int = "2" getOrElse 0
+ println(s)
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-implicit-macro-is-val.check b/test/files/run/macro-expand-implicit-macro-is-val.check
new file mode 100644
index 0000000000..78c6baefdd
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-val.check
@@ -0,0 +1 @@
+2
diff --git a/test/files/run/macro-expand-implicit-macro-is-val.flags b/test/files/run/macro-expand-implicit-macro-is-val.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-val.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala
new file mode 100644
index 0000000000..510d8502f6
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.mirror._
+ val body = Literal(Constant(2))
+ Expr[Int](body)
+ }
+}
diff --git a/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala
new file mode 100644
index 0000000000..b91b1016c9
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ implicit def foo = macro Impls.foo
+ def bar(implicit x: Int) = println(x)
+ bar
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-implicit-macro-is-view.check b/test/files/run/macro-expand-implicit-macro-is-view.check
new file mode 100644
index 0000000000..78c6baefdd
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-view.check
@@ -0,0 +1 @@
+2
diff --git a/test/files/run/macro-expand-implicit-macro-is-view.flags b/test/files/run/macro-expand-implicit-macro-is-view.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-view.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala b/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala
new file mode 100644
index 0000000000..0262485994
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[String]): c.Expr[Option[Int]] = {
+ import c.mirror._
+ val body = Apply(Ident(definitions.SomeModule), List(Select(x.tree, newTermName("toInt"))))
+ Expr[Option[Int]](body)
+ }
+}
diff --git a/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala b/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala
new file mode 100644
index 0000000000..0ff1fb80ca
--- /dev/null
+++ b/test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala
@@ -0,0 +1,9 @@
+object Macros {
+ implicit def foo(x: String): Option[Int] = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ def bar[T <% Option[Int]](x: T) = println(x)
+ println("2")
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-multiple-arglists.check b/test/files/run/macro-expand-multiple-arglists.check
new file mode 100644
index 0000000000..c24b6ae77d
--- /dev/null
+++ b/test/files/run/macro-expand-multiple-arglists.check
@@ -0,0 +1 @@
+38 \ No newline at end of file
diff --git a/test/files/run/macro-expand-multiple-arglists.flags b/test/files/run/macro-expand-multiple-arglists.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-multiple-arglists.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-multiple-arglists/Impls_1.scala b/test/files/run/macro-expand-multiple-arglists/Impls_1.scala
new file mode 100644
index 0000000000..ae1c50eace
--- /dev/null
+++ b/test/files/run/macro-expand-multiple-arglists/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int])(y: c.Expr[Int]) = {
+ import c.mirror._
+ val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree))
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala b/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala
new file mode 100644
index 0000000000..fa4504b0ea
--- /dev/null
+++ b/test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo(x: Int)(y: Int) = macro Impls.foo
+ foo(40)(2)
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-nullary-generic.check b/test/files/run/macro-expand-nullary-generic.check
new file mode 100644
index 0000000000..6dfe04af12
--- /dev/null
+++ b/test/files/run/macro-expand-nullary-generic.check
@@ -0,0 +1,6 @@
+it works ConcreteTypeTag[Int]
+it works ConcreteTypeTag[Int]
+it works ConcreteTypeTag[Int]
+it works ConcreteTypeTag[Int]
+it works ConcreteTypeTag[Int]
+kkthxbai
diff --git a/test/files/run/macro-expand-nullary-generic.flags b/test/files/run/macro-expand-nullary-generic.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-nullary-generic.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-nullary-generic/Impls_1.scala b/test/files/run/macro-expand-nullary-generic/Impls_1.scala
new file mode 100644
index 0000000000..10352594f5
--- /dev/null
+++ b/test/files/run/macro-expand-nullary-generic/Impls_1.scala
@@ -0,0 +1,14 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def impl[T: c.TypeTag](c: Ctx) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works " + implicitly[c.TypeTag[T]]))))
+ Expr[Unit](body)
+ }
+
+ def fooNullary[T: c.TypeTag](c: Ctx) = impl[T](c)
+ def fooEmpty[T: c.TypeTag](c: Ctx)() = impl[T](c)
+ def barNullary[T: c.TypeTag](c: Ctx)(x: c.Expr[Int]) = impl[T](c)
+ def barEmpty[T: c.TypeTag](c: Ctx)(x: c.Expr[Int])() = impl[T](c)
+}
diff --git a/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala b/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala
new file mode 100644
index 0000000000..2d5cf53c3c
--- /dev/null
+++ b/test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala
@@ -0,0 +1,15 @@
+object Macros {
+ def foo1[T] = macro Impls.fooNullary[T]
+ def foo2[T]() = macro Impls.fooEmpty[T]
+ def bar1[T](x: Int) = macro Impls.barNullary[T]
+ def bar2[T](x: Int)() = macro Impls.barEmpty[T]
+}
+
+object Test extends App {
+ Macros.foo1[Int]
+ Macros.foo2[Int]
+ Macros.foo2[Int]()
+ Macros.bar1[Int](42)
+ Macros.bar2[Int](42)()
+ println("kkthxbai")
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-nullary-nongeneric.check b/test/files/run/macro-expand-nullary-nongeneric.check
new file mode 100644
index 0000000000..9ab5f3a2bc
--- /dev/null
+++ b/test/files/run/macro-expand-nullary-nongeneric.check
@@ -0,0 +1,6 @@
+it works
+it works
+it works
+it works
+it works
+kkthxbai
diff --git a/test/files/run/macro-expand-nullary-nongeneric.flags b/test/files/run/macro-expand-nullary-nongeneric.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-nullary-nongeneric.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala
new file mode 100644
index 0000000000..7dc58abba8
--- /dev/null
+++ b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala
@@ -0,0 +1,14 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def impl(c: Ctx) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))
+ Expr[Unit](body)
+ }
+
+ def fooNullary(c: Ctx) = impl(c)
+ def fooEmpty(c: Ctx)() = impl(c)
+ def barNullary(c: Ctx)(x: c.Expr[Int]) = impl(c)
+ def barEmpty(c: Ctx)(x: c.Expr[Int])() = impl(c)
+}
diff --git a/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala b/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala
new file mode 100644
index 0000000000..1f6d717956
--- /dev/null
+++ b/test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala
@@ -0,0 +1,15 @@
+object Macros {
+ def foo1 = macro Impls.fooNullary
+ def foo2() = macro Impls.fooEmpty
+ def bar1(x: Int) = macro Impls.barNullary
+ def bar2(x: Int)() = macro Impls.barEmpty
+}
+
+object Test extends App {
+ Macros.foo1
+ Macros.foo2
+ Macros.foo2()
+ Macros.bar1(42)
+ Macros.bar2(42)()
+ println("kkthxbai")
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-overload.check b/test/files/run/macro-expand-overload.check
new file mode 100644
index 0000000000..9d9989d85f
--- /dev/null
+++ b/test/files/run/macro-expand-overload.check
@@ -0,0 +1,6 @@
+(fooObjectString,Expr[Nothing](Macros),42)
+(fooObjectInt,Expr[Nothing](Macros),42)
+fooObjectBoolean
+(fooClassString,Expr[Nothing](new Macros()),42)
+(fooClassInt,Expr[Nothing](new Macros()),42)
+fooClassBoolean
diff --git a/test/files/run/macro-expand-overload.flags b/test/files/run/macro-expand-overload.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-overload.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-overload/Impls_1.scala b/test/files/run/macro-expand-overload/Impls_1.scala
new file mode 100644
index 0000000000..1dc4adc20e
--- /dev/null
+++ b/test/files/run/macro-expand-overload/Impls_1.scala
@@ -0,0 +1,15 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def impl(c: Ctx)(tag: String, x: c.Expr[_]) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree))
+ Expr[Unit](body)
+ }
+
+ def fooObjectString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooObjectString", x)
+ def fooObjectInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooObjectInt", x)
+ def fooClassString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooClassString", x)
+ def fooClassInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooClassInt", x)
+}
diff --git a/test/files/run/macro-expand-overload/Macros_Test_2.scala b/test/files/run/macro-expand-overload/Macros_Test_2.scala
new file mode 100644
index 0000000000..7f61f85184
--- /dev/null
+++ b/test/files/run/macro-expand-overload/Macros_Test_2.scala
@@ -0,0 +1,20 @@
+object Macros {
+ def foo(x: String) = macro Impls.fooObjectString
+ def foo(x: Int) = macro Impls.fooObjectInt
+ def foo(x: Boolean) = println("fooObjectBoolean")
+}
+
+class Macros {
+ def foo(x: String) = macro Impls.fooClassString
+ def foo(x: Int) = macro Impls.fooClassInt
+ def foo(x: Boolean) = println("fooClassBoolean")
+}
+
+object Test extends App {
+ Macros.foo("42")
+ Macros.foo(42)
+ Macros.foo(true)
+ new Macros().foo("42")
+ new Macros().foo(42)
+ new Macros().foo(true)
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-override.check b/test/files/run/macro-expand-override.check
new file mode 100644
index 0000000000..486bec7098
--- /dev/null
+++ b/test/files/run/macro-expand-override.check
@@ -0,0 +1,15 @@
+(fooBString,Expr[Nothing](Test.this.dd),42)
+(fooDInt,Expr[Nothing](Test.this.dd),42)
+fooBBoolean
+(fooBString,Expr[Nothing](Test.this.db),42)
+(fooBInt,Expr[Nothing](Test.this.db),42)
+fooBBoolean
+(fooZString,Expr[Nothing](Test.this.zz),42)
+(fooDInt,Expr[Nothing](Test.this.zz),42)
+fooZBoolean
+(fooBString,Expr[Nothing](Test.this.zd),42)
+(fooDInt,Expr[Nothing](Test.this.zd),42)
+fooZBoolean
+(fooBString,Expr[Nothing](Test.this.zb),42)
+(fooBInt,Expr[Nothing](Test.this.zb),42)
+fooZBoolean
diff --git a/test/files/run/macro-expand-override.flags b/test/files/run/macro-expand-override.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-override.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-override/Impls_1.scala b/test/files/run/macro-expand-override/Impls_1.scala
new file mode 100644
index 0000000000..0b127f5a59
--- /dev/null
+++ b/test/files/run/macro-expand-override/Impls_1.scala
@@ -0,0 +1,15 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def impl(c: Ctx)(tag: String, x: c.Expr[_]) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(tag)), Literal(Constant(prefix.toString)), x.tree))
+ Expr[Unit](body)
+ }
+
+ def fooBString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBString", x)
+ def fooBInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooBInt", x)
+ def fooDInt(c: Ctx)(x: c.Expr[_]) = impl(c)("fooDInt", x)
+ def fooZString(c: Ctx)(x: c.Expr[_]) = impl(c)("fooZString", x)
+}
diff --git a/test/files/run/macro-expand-override/Macros_Test_2.scala b/test/files/run/macro-expand-override/Macros_Test_2.scala
new file mode 100644
index 0000000000..f162773c95
--- /dev/null
+++ b/test/files/run/macro-expand-override/Macros_Test_2.scala
@@ -0,0 +1,43 @@
+class B {
+ def foo(x: String) = macro Impls.fooBString
+ def foo(x: Int) = macro Impls.fooBInt
+ def foo(x: Boolean) = println("fooBBoolean")
+}
+
+class D extends B {
+ //override def foo(x: String) = println("fooDString") => method cannot override a macro
+ override def foo(x: Int) = macro Impls.fooDInt
+}
+
+class Z extends D {
+ override def foo(x: String) = macro Impls.fooZString
+ override def foo(x: Boolean) = println("fooZBoolean")
+}
+
+object Test extends App {
+
+ val dd: D = new D()
+ dd.foo("42")
+ dd.foo(42)
+ dd.foo(true)
+
+ val db: B = new D()
+ db.foo("42")
+ db.foo(42)
+ db.foo(true)
+
+ val zz: Z = new Z()
+ zz.foo("42")
+ zz.foo(42)
+ zz.foo(true)
+
+ val zd: D = new Z()
+ zd.foo("42")
+ zd.foo(42)
+ zd.foo(true)
+
+ val zb: B = new Z()
+ zb.foo("42")
+ zb.foo(42)
+ zb.foo(true)
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-recursive.check b/test/files/run/macro-expand-recursive.check
new file mode 100644
index 0000000000..1ea14b4e20
--- /dev/null
+++ b/test/files/run/macro-expand-recursive.check
@@ -0,0 +1 @@
+it works
diff --git a/test/files/run/macro-expand-recursive.flags b/test/files/run/macro-expand-recursive.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-recursive.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-recursive/Impls_1.scala b/test/files/run/macro-expand-recursive/Impls_1.scala
new file mode 100644
index 0000000000..6eff805989
--- /dev/null
+++ b/test/files/run/macro-expand-recursive/Impls_1.scala
@@ -0,0 +1,15 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works"))))
+ Expr[Unit](body)
+ }
+
+ def fooFoo(c: Ctx) = {
+ import c.mirror._
+ val body = Select(Ident(newTermName("Macros")), newTermName("foo"))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-recursive/Macros_Test_2.scala b/test/files/run/macro-expand-recursive/Macros_Test_2.scala
new file mode 100644
index 0000000000..6ff691bdb1
--- /dev/null
+++ b/test/files/run/macro-expand-recursive/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo
+ def fooFoo = macro Impls.fooFoo
+}
+
+object Test extends App {
+ Macros.fooFoo
+} \ No newline at end of file
diff --git a/test/pending/run/t5271_1.check b/test/files/run/macro-expand-tparams-bounds-a.check
index e69de29bb2..e69de29bb2 100644
--- a/test/pending/run/t5271_1.check
+++ b/test/files/run/macro-expand-tparams-bounds-a.check
diff --git a/test/files/run/macro-expand-tparams-bounds-a.flags b/test/files/run/macro-expand-tparams-bounds-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala
new file mode 100644
index 0000000000..5019d5d4a7
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U <: String](c: Ctx): c.Expr[Unit] = c.literalUnit
+}
diff --git a/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala
new file mode 100644
index 0000000000..b498e6f65b
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo[U <: String] = macro Impls.foo[U]
+}
+
+object Test extends App {
+ import Macros._
+ foo[String]
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-bounds-b.check b/test/files/run/macro-expand-tparams-bounds-b.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-b.check
diff --git a/test/files/run/macro-expand-tparams-bounds-b.flags b/test/files/run/macro-expand-tparams-bounds-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala
new file mode 100644
index 0000000000..abd68696b6
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala
@@ -0,0 +1,7 @@
+import scala.reflect.makro.{Context => Ctx}
+
+class C
+
+object Impls {
+ def foo[U <: C](c: Ctx): c.Expr[Unit] = c.literalUnit
+}
diff --git a/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala
new file mode 100644
index 0000000000..1a261e9f73
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+class D extends C
+
+object Macros {
+ def foo[T <: D] = macro Impls.foo[T]
+}
+
+object Test extends App {
+ import Macros._
+ foo[D]
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-explicit.check b/test/files/run/macro-expand-tparams-explicit.check
new file mode 100644
index 0000000000..5670e27c4e
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-explicit.check
@@ -0,0 +1 @@
+ConcreteTypeTag[Int]
diff --git a/test/files/run/macro-expand-tparams-explicit.flags b/test/files/run/macro-expand-tparams-explicit.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-explicit.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-explicit/Impls_1.scala b/test/files/run/macro-expand-tparams-explicit/Impls_1.scala
new file mode 100644
index 0000000000..957d8331fc
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-explicit/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U: c.TypeTag](c: Ctx) = {
+ import c.mirror._
+ val U = implicitly[c.TypeTag[U]]
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala
new file mode 100644
index 0000000000..e72c27881a
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo[U] = macro Impls.foo[U]
+ foo[Int]
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-implicit.check b/test/files/run/macro-expand-tparams-implicit.check
new file mode 100644
index 0000000000..e57fc1217b
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-implicit.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[String]
diff --git a/test/files/run/macro-expand-tparams-implicit.flags b/test/files/run/macro-expand-tparams-implicit.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-implicit.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-implicit/Impls_1.scala b/test/files/run/macro-expand-tparams-implicit/Impls_1.scala
new file mode 100644
index 0000000000..c25d12be60
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-implicit/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = {
+ import c.mirror._
+ val U = implicitly[c.TypeTag[U]]
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala
new file mode 100644
index 0000000000..f8c573f509
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ def foo[U](x: U) = macro Impls.foo[U]
+ foo(42)
+ foo("42")
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-only-in-impl.flags b/test/files/run/macro-expand-tparams-only-in-impl.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-only-in-impl.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala
new file mode 100644
index 0000000000..5019d5d4a7
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U <: String](c: Ctx): c.Expr[Unit] = c.literalUnit
+}
diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala
new file mode 100644
index 0000000000..218c7aec7f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo = macro Impls.foo[String]
+}
+
+object Test extends App {
+ import Macros._
+ foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-optional.check b/test/files/run/macro-expand-tparams-optional.check
new file mode 100644
index 0000000000..3bacd7a4e0
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-optional.check
@@ -0,0 +1 @@
+don't know U
diff --git a/test/files/run/macro-expand-tparams-optional.flags b/test/files/run/macro-expand-tparams-optional.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-optional.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-optional/Impls_1.scala b/test/files/run/macro-expand-tparams-optional/Impls_1.scala
new file mode 100644
index 0000000000..37efb009c4
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-optional/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U](c: Ctx) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("don't know U"))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala
new file mode 100644
index 0000000000..e72c27881a
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo[U] = macro Impls.foo[U]
+ foo[Int]
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-a.check b/test/files/run/macro-expand-tparams-prefix-a.check
new file mode 100644
index 0000000000..922be1a6dd
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-a.check
@@ -0,0 +1,4 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[Int]
+ConcreteTypeTag[String]
+ConcreteTypeTag[Boolean]
diff --git a/test/files/run/macro-expand-tparams-prefix-a.flags b/test/files/run/macro-expand-tparams-prefix-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala
new file mode 100644
index 0000000000..c25d12be60
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = {
+ import c.mirror._
+ val U = implicitly[c.TypeTag[U]]
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(U.toString))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala
new file mode 100644
index 0000000000..81ccb7ff42
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ class C[T] {
+ def foo[U](x: U) = macro Impls.foo[U]
+ }
+
+ new C[Int]().foo(42)
+ new C[Boolean]().foo(42)
+ new C[Int]().foo("42")
+ new C[String]().foo(true)
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-b.check b/test/files/run/macro-expand-tparams-prefix-b.check
new file mode 100644
index 0000000000..a336bb51ec
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-b.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Boolean] ConcreteTypeTag[Int]
+ConcreteTypeTag[Boolean] ConcreteTypeTag[String]
diff --git a/test/files/run/macro-expand-tparams-prefix-b.flags b/test/files/run/macro-expand-tparams-prefix-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala
new file mode 100644
index 0000000000..8af3ecc9ae
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T: c.TypeTag, U: c.TypeTag](c: Ctx)(x: c.Expr[U]) = {
+ import c.mirror._
+ val T = implicitly[c.TypeTag[T]]
+ val U = implicitly[c.TypeTag[U]]
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString + " " + U.toString))))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala
new file mode 100644
index 0000000000..a4a0acfe8b
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ class C[T] {
+ def foo[U](x: U) = macro Impls.foo[T, U]
+ }
+
+ object D extends C[Boolean]
+
+ D.foo(42)
+ D.foo("42")
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-c1.check b/test/files/run/macro-expand-tparams-prefix-c1.check
new file mode 100644
index 0000000000..87f295aa49
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-c1.check
@@ -0,0 +1,3 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[String]
+ConcreteTypeTag[Boolean]
diff --git a/test/files/run/macro-expand-tparams-prefix-c1.flags b/test/files/run/macro-expand-tparams-prefix-c1.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-c1.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala
new file mode 100644
index 0000000000..4da5a9b823
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala
@@ -0,0 +1,12 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = {
+ import c.mirror._
+ Expr(Block(List(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))),
+ Literal(Constant(()))))
+ }
+}
diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala
new file mode 100644
index 0000000000..4fa0c8cb33
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala
@@ -0,0 +1,11 @@
+class D[T] {
+ class C[U] {
+ def foo[V] = macro Impls.foo[T, U, V]
+ }
+}
+
+object Test extends App {
+ val outer1 = new D[Int]
+ val outer2 = new outer1.C[String]
+ outer2.foo[Boolean]
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-c2.check b/test/files/run/macro-expand-tparams-prefix-c2.check
new file mode 100644
index 0000000000..87f295aa49
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-c2.check
@@ -0,0 +1,3 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[String]
+ConcreteTypeTag[Boolean]
diff --git a/test/files/run/macro-expand-tparams-prefix-c2.flags b/test/files/run/macro-expand-tparams-prefix-c2.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-c2.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala b/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..4d137a4aef
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala
@@ -0,0 +1,18 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = {
+ import c.mirror._
+ Expr(Block(List(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))),
+ Literal(Constant(()))))
+ }
+}
+
+class D[T] {
+ class C[U] {
+ def foo[V] = macro Impls.foo[T, U, V]
+ }
+}
diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala
new file mode 100644
index 0000000000..e729d4a536
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ val outer1 = new D[Int]
+ val outer2 = new outer1.C[String]
+ outer2.foo[Boolean]
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-d1.check b/test/files/run/macro-expand-tparams-prefix-d1.check
new file mode 100644
index 0000000000..ca7a220475
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-d1.check
@@ -0,0 +1,3 @@
+TypeTag[T]
+TypeTag[U]
+ConcreteTypeTag[Boolean]
diff --git a/test/files/run/macro-expand-tparams-prefix-d1.flags b/test/files/run/macro-expand-tparams-prefix-d1.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-d1.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala
new file mode 100644
index 0000000000..4da5a9b823
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala
@@ -0,0 +1,12 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = {
+ import c.mirror._
+ Expr(Block(List(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))),
+ Literal(Constant(()))))
+ }
+}
diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala
new file mode 100644
index 0000000000..8222a6d1e8
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala
@@ -0,0 +1,11 @@
+object Test extends App {
+ class D[T] {
+ class C[U] {
+ def foo[V] = macro Impls.foo[T, U, V]
+ foo[Boolean]
+ }
+ }
+
+ val outer1 = new D[Int]
+ new outer1.C[String]
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check
new file mode 100644
index 0000000000..fd1d654cf8
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check
@@ -0,0 +1,4 @@
+reflective compilation has failed:
+
+no `: _*' annotation allowed here
+(such annotations are only allowed in arguments to *-parameters)
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala
new file mode 100644
index 0000000000..d97f0af786
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(xs: c.Expr[Int]*) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), xs.map(_.tree).toList)
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala
new file mode 100644
index 0000000000..01fc9d4462
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+object Macros {
+ def foo(xs: Int*) = macro Impls.foo
+}
+
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Typed(Apply(Ident(definitions.ListModule), List(Literal(Constant(1)), Literal(Constant(2)))), Ident(tpnme.WILDCARD_STAR))))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check
new file mode 100644
index 0000000000..835137b4a2
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check
@@ -0,0 +1 @@
+List(1, 2, 3, 4, 5)
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala
new file mode 100644
index 0000000000..f9667d78b8
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(xs: c.Expr[Int]*) = {
+ import c.mirror._
+ val stripped_xs = xs map (_.tree) toList match {
+ case List(Typed(stripped, Ident(wildstar))) if wildstar == tpnme.WILDCARD_STAR => List(stripped)
+ case _ => ???
+ }
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), stripped_xs)
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala
new file mode 100644
index 0000000000..f127ebcde7
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(xs: Int*) = macro Impls.foo
+}
+
+object Test extends App {
+ val numbers = List(1, 2, 3, 4, 5)
+ Macros.foo(numbers: _*)
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs.check b/test/files/run/macro-expand-varargs-explicit-over-varargs.check
new file mode 100644
index 0000000000..835137b4a2
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-varargs.check
@@ -0,0 +1 @@
+List(1, 2, 3, 4, 5)
diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs.flags b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala b/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala
new file mode 100644
index 0000000000..8c609daa0e
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def myprintln(xs: Int*) = {
+ println(xs)
+ }
+
+ def foo(c: Ctx)(xs: c.Expr[Int]*) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(newTermName("Impls")), newTermName("myprintln")), xs.map(_.tree).toList)
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala
new file mode 100644
index 0000000000..f127ebcde7
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Macros {
+ def foo(xs: Int*) = macro Impls.foo
+}
+
+object Test extends App {
+ val numbers = List(1, 2, 3, 4, 5)
+ Macros.foo(numbers: _*)
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check
new file mode 100644
index 0000000000..0a6596858c
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check
@@ -0,0 +1 @@
+(1,2,3,4,5)
diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala
new file mode 100644
index 0000000000..d97f0af786
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(xs: c.Expr[Int]*) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), xs.map(_.tree).toList)
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala
new file mode 100644
index 0000000000..2311ca0b95
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala
@@ -0,0 +1,7 @@
+object Macros {
+ def foo(xs: Int*) = macro Impls.foo
+}
+
+object Test extends App {
+ Macros.foo(1, 2, 3, 4, 5)
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs.check b/test/files/run/macro-expand-varargs-implicit-over-varargs.check
new file mode 100644
index 0000000000..f25fa141d3
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-implicit-over-varargs.check
@@ -0,0 +1 @@
+WrappedArray(1, 2, 3, 4, 5)
diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs.flags b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala b/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala
new file mode 100644
index 0000000000..8c609daa0e
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def myprintln(xs: Int*) = {
+ println(xs)
+ }
+
+ def foo(c: Ctx)(xs: c.Expr[Int]*) = {
+ import c.mirror._
+ val body = Apply(Select(Ident(newTermName("Impls")), newTermName("myprintln")), xs.map(_.tree).toList)
+ Expr[Unit](body)
+ }
+}
diff --git a/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala
new file mode 100644
index 0000000000..2311ca0b95
--- /dev/null
+++ b/test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala
@@ -0,0 +1,7 @@
+object Macros {
+ def foo(xs: Int*) = macro Impls.foo
+}
+
+object Test extends App {
+ Macros.foo(1, 2, 3, 4, 5)
+} \ No newline at end of file
diff --git a/test/files/run/macro-impl-default-params.check b/test/files/run/macro-impl-default-params.check
new file mode 100644
index 0000000000..eaf94458e6
--- /dev/null
+++ b/test/files/run/macro-impl-default-params.check
@@ -0,0 +1,5 @@
+foo_targs:
+invoking foo_targs...
+type of prefix is: Nothing
+type of prefix tree is: Macros[Int]
+U is: String
diff --git a/test/files/run/macro-impl-default-params.flags b/test/files/run/macro-impl-default-params.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-impl-default-params.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-impl-default-params/Impls_Macros_1.scala b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala
new file mode 100644
index 0000000000..cece1c09e4
--- /dev/null
+++ b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala
@@ -0,0 +1,20 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo_targs[T, U: c.TypeTag](c: Ctx = null)(x: c.Expr[Int] = null) = {
+ import c.{prefix => prefix}
+ import c.mirror._
+ val U = implicitly[c.TypeTag[U]]
+ val body = Block(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.tpe)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix tree is: " + prefix.tree.tpe)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + U.tpe)))),
+ Literal(Constant(())))
+ Expr[Unit](body)
+ }
+}
+
+class Macros[T] {
+ def foo_targs[U](x: Int) = macro Impls.foo_targs[T, U]
+}
diff --git a/test/files/run/macro-impl-default-params/Test_2.scala b/test/files/run/macro-impl-default-params/Test_2.scala
new file mode 100644
index 0000000000..90e850df21
--- /dev/null
+++ b/test/files/run/macro-impl-default-params/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ println("foo_targs:")
+ new Macros[Int]().foo_targs[String](42)
+} \ No newline at end of file
diff --git a/test/files/run/macro-impl-rename-context.check b/test/files/run/macro-impl-rename-context.check
new file mode 100644
index 0000000000..753edcd970
--- /dev/null
+++ b/test/files/run/macro-impl-rename-context.check
@@ -0,0 +1,2 @@
+foo
+invoking foo...
diff --git a/test/files/run/macro-impl-rename-context.flags b/test/files/run/macro-impl-rename-context.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-impl-rename-context.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala
new file mode 100644
index 0000000000..000e351f4d
--- /dev/null
+++ b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala
@@ -0,0 +1,15 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(unconventionalName: Ctx)(x: unconventionalName.Expr[Int]) = {
+ import unconventionalName.mirror._
+ val body = Block(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo...")))),
+ Literal(Constant(())))
+ Expr[Unit](body)
+ }
+}
+
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+}
diff --git a/test/files/run/macro-impl-rename-context/Test_2.scala b/test/files/run/macro-impl-rename-context/Test_2.scala
new file mode 100644
index 0000000000..bd9c493544
--- /dev/null
+++ b/test/files/run/macro-impl-rename-context/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ println("foo")
+ Macros.foo(42)
+} \ No newline at end of file
diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check
new file mode 100644
index 0000000000..e21e05157a
--- /dev/null
+++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check
@@ -0,0 +1,5 @@
+reflective compilation has failed:
+
+type mismatch;
+ found : String("42")
+ required: Int
diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala
new file mode 100644
index 0000000000..828ccf34e2
--- /dev/null
+++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala
@@ -0,0 +1,12 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx): c.Expr[Int] = {
+ import c.mirror._
+ Expr(Literal(Constant("42")))
+ }
+}
+
+object Macros {
+ def foo: Int = macro Impls.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala
new file mode 100644
index 0000000000..ecf48b9752
--- /dev/null
+++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Select(Ident("Macros"), newTermName("foo"))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+} \ No newline at end of file
diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check
diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-invalidret-nontypeable.check b/test/files/run/macro-invalidret-nontypeable.check
new file mode 100644
index 0000000000..eee08528e2
--- /dev/null
+++ b/test/files/run/macro-invalidret-nontypeable.check
@@ -0,0 +1,3 @@
+reflective compilation has failed:
+
+not found: value IDoNotExist
diff --git a/test/files/run/macro-invalidret-nontypeable.flags b/test/files/run/macro-invalidret-nontypeable.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-invalidret-nontypeable.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala
new file mode 100644
index 0000000000..f3a0476a35
--- /dev/null
+++ b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx) = {
+ import c.mirror._
+ val body = Ident("IDoNotExist")
+ Expr[Int](body)
+ }
+}
+
+object Macros {
+ def foo = macro Impls.foo
+}
diff --git a/test/files/run/macro-invalidret-nontypeable/Test_2.scala b/test/files/run/macro-invalidret-nontypeable/Test_2.scala
new file mode 100644
index 0000000000..ecf48b9752
--- /dev/null
+++ b/test/files/run/macro-invalidret-nontypeable/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Select(Ident("Macros"), newTermName("foo"))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+} \ No newline at end of file
diff --git a/test/files/run/macro-invalidusage-badret.check b/test/files/run/macro-invalidusage-badret.check
new file mode 100644
index 0000000000..5bdc484644
--- /dev/null
+++ b/test/files/run/macro-invalidusage-badret.check
@@ -0,0 +1,5 @@
+reflective compilation has failed:
+
+type mismatch;
+ found : Int(42)
+ required: String
diff --git a/test/files/run/macro-invalidusage-badret.flags b/test/files/run/macro-invalidusage-badret.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-invalidusage-badret.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala b/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala
new file mode 100644
index 0000000000..c63ad01677
--- /dev/null
+++ b/test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = x
+}
+
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+}
diff --git a/test/files/run/macro-invalidusage-badret/Test_2.scala b/test/files/run/macro-invalidusage-badret/Test_2.scala
new file mode 100644
index 0000000000..aeb3c26eaa
--- /dev/null
+++ b/test/files/run/macro-invalidusage-badret/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Typed(Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))), Ident(newTypeName("String")))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+} \ No newline at end of file
diff --git a/test/files/run/macro-invalidusage-partialapplication.check b/test/files/run/macro-invalidusage-partialapplication.check
new file mode 100644
index 0000000000..73f57b0b81
--- /dev/null
+++ b/test/files/run/macro-invalidusage-partialapplication.check
@@ -0,0 +1,3 @@
+reflective compilation has failed:
+
+macros cannot be partially applied
diff --git a/test/files/run/macro-invalidusage-partialapplication.flags b/test/files/run/macro-invalidusage-partialapplication.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-invalidusage-partialapplication.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala b/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala
new file mode 100644
index 0000000000..449b91d074
--- /dev/null
+++ b/test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala
@@ -0,0 +1,14 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int])(y: c.Expr[Int]) = {
+ import c.mirror._
+ val sum = Apply(Select(x.tree, newTermName("$plus")), List(y.tree))
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum))
+ Expr[Unit](body)
+ }
+}
+
+object Macros {
+ def foo(x: Int)(y: Int) = macro Impls.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-invalidusage-partialapplication/Test_2.scala b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala
new file mode 100644
index 0000000000..293d906048
--- /dev/null
+++ b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(40))))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+}
diff --git a/test/files/run/macro-openmacros.check b/test/files/run/macro-openmacros.check
new file mode 100644
index 0000000000..a4b06a1e1a
--- /dev/null
+++ b/test/files/run/macro-openmacros.check
@@ -0,0 +1,3 @@
+List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0))
+List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +1), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0))
+List(MacroContext(foo@source-Test_2.scala,line-2,offset=35 +2), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +1), MacroContext(foo@source-Test_2.scala,line-2,offset=35 +0))
diff --git a/test/files/run/macro-openmacros.flags b/test/files/run/macro-openmacros.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-openmacros.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-openmacros/Impls_Macros_1.scala b/test/files/run/macro-openmacros/Impls_Macros_1.scala
new file mode 100644
index 0000000000..9fd658656e
--- /dev/null
+++ b/test/files/run/macro-openmacros/Impls_Macros_1.scala
@@ -0,0 +1,26 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl(c: Context): c.Expr[Unit] = {
+ // we're macros, so we can reflect against our source path
+ // so we don't need any partests to clean up after us!
+ val c.CompilationUnit(file, _, _) = c.enclosingUnit
+ val dir = file.getParentFile
+ def normalizePaths(s: String) = {
+ val base = (dir.getCanonicalPath + java.io.File.separator).replace('\\', '/')
+ var regex = """\Q%s\E""" format base
+ val isWin = System.getProperty("os.name", "") startsWith "Windows"
+ if (isWin) regex = "(?i)" + regex
+ s.replace('\\', '/').replaceAll(regex, "")
+ }
+
+ import c.mirror._
+ val next = if (c.enclosingMacros.length < 3) Expr[Unit](Select(Ident(staticModule("Macros")), newTermName("foo"))) else c.literalUnit
+ c.reify {
+ println(c.literal(normalizePaths(c.enclosingMacros.toString)).eval)
+ next.eval
+ }
+ }
+
+ def foo = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/macro-openmacros/Test_2.scala b/test/files/run/macro-openmacros/Test_2.scala
new file mode 100644
index 0000000000..5d19639cdd
--- /dev/null
+++ b/test/files/run/macro-openmacros/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.foo
+}
diff --git a/test/files/run/macro-quasiinvalidbody-c.check b/test/files/run/macro-quasiinvalidbody-c.check
new file mode 100644
index 0000000000..f70d7bba4a
--- /dev/null
+++ b/test/files/run/macro-quasiinvalidbody-c.check
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/test/files/run/macro-quasiinvalidbody-c.flags b/test/files/run/macro-quasiinvalidbody-c.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-quasiinvalidbody-c.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala b/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala
new file mode 100644
index 0000000000..7cb810c86b
--- /dev/null
+++ b/test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = x
+ }
+
+ def foo(x: Any) = macro Impls.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-quasiinvalidbody-c/Test_2.scala b/test/files/run/macro-quasiinvalidbody-c/Test_2.scala
new file mode 100644
index 0000000000..dec29aa857
--- /dev/null
+++ b/test/files/run/macro-quasiinvalidbody-c/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros._
+ println(foo(42))
+} \ No newline at end of file
diff --git a/test/files/run/macro-range.flags b/test/files/run/macro-range.flags
index 06a7b31f11..5e5dd6ce79 100644
--- a/test/files/run/macro-range.flags
+++ b/test/files/run/macro-range.flags
@@ -1 +1 @@
--Xmacros
+-language:experimental.macros
diff --git a/test/files/run/macro-range/Common_1.scala b/test/files/run/macro-range/Common_1.scala
new file mode 100644
index 0000000000..bd46e1f529
--- /dev/null
+++ b/test/files/run/macro-range/Common_1.scala
@@ -0,0 +1,48 @@
+import reflect.api.Modifier
+import reflect.makro.Context
+
+abstract class RangeDefault {
+ val from, to: Int
+ def foreach(f: Int => Unit) = {
+ var i = from
+ while (i < to) { f(i); i += 1 }
+ }
+}
+
+/** This class should go into reflect.macro once it is a bit more stable. */
+abstract class Utils {
+ val context: Context
+ import context.mirror._
+
+ class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer {
+ override def transform(tree: Tree): Tree = tree match {
+ case Ident(_) =>
+ def subst(from: List[Symbol], to: List[Tree]): Tree =
+ if (from.isEmpty) tree
+ else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`?
+ else subst(from.tail, to.tail);
+ subst(from, to)
+ case _ =>
+ val tree1 = super.transform(tree)
+ if (tree1 ne tree) tree1.tpe = null
+ tree1
+ }
+ }
+ def makeApply(fn: Tree, args: List[Tree]): Tree = fn match {
+ case Function(vparams, body) =>
+ new TreeSubstituter(vparams map (_.symbol), args) transform body
+ case Block(stats, expr) =>
+ Block(stats, makeApply(expr, args))
+ case _ =>
+ // todo. read the compiler config and print if -Ydebug is set
+ //println("no beta on "+fn+" "+fn.getClass)
+ Apply(fn, args)
+ }
+ def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = {
+ val continu = Apply(Ident(lname), Nil)
+ val rhs = If(cond, Block(List(body), continu), Literal(Constant()))
+ LabelDef(lname, Nil, rhs)
+ }
+ def makeBinop(left: Tree, op: String, right: Tree): Tree =
+ Apply(Select(left, newTermName(op)), List(right))
+}
diff --git a/test/files/run/macro-range/Expansion_Impossible_2.scala b/test/files/run/macro-range/Expansion_Impossible_2.scala
new file mode 100644
index 0000000000..051afff99c
--- /dev/null
+++ b/test/files/run/macro-range/Expansion_Impossible_2.scala
@@ -0,0 +1,53 @@
+import reflect.api.Modifier
+import reflect.makro.Context
+
+object Impls {
+ def foreach(c: Context)(f: c.Expr[Int => Unit]): c.Expr[Unit] = {
+ // todo. read the compiler config and print if -Ydebug is set
+ //println("macro-expand, _this = "+ _this)
+ object utils extends Utils { val context: c.type = c }
+ import utils._
+ import c.mirror._
+
+ val initName = newTermName("<init>")
+ // Either:
+ // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } }
+ // or:
+ // scala"($_this: RangeDefault).foreach($f)"
+ Expr(c.prefix.tree match {
+ case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" =>
+ val iname = newTermName("$i")
+ val hname = newTermName("$h")
+ def iref = Ident(iname)
+ def href = Ident(hname)
+ val labelname = newTermName("$while")
+ val cond = makeBinop(iref, "$less", href)
+ val body = Block(
+ List(makeApply(f.tree, List(iref))),
+ Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1)))))
+ val generated =
+ Block(
+ List(
+ ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo),
+ ValDef(Modifiers(), hname, TypeTree(), hi)),
+ makeWhile(labelname, cond, body))
+ // todo. read the compiler config and print if -Ydebug is set
+ //tools.nsc.util.trace("generated: ")(generated)
+ generated
+ case _ =>
+ Apply(
+ Select(
+ Typed(c.prefix.tree, Ident(newTypeName("RangeDefault"))),
+ newTermName("foreach")),
+ List(f.tree))
+ })
+ }
+}
+
+class Range(val from: Int, val to: Int) extends RangeDefault {
+ override def foreach(f: Int => Unit): Unit = macro Impls.foreach
+}
+
+object Test extends App {
+ new Range(1, 10) foreach println
+} \ No newline at end of file
diff --git a/test/files/run/macro-range/Expansion_Possible_3.scala b/test/files/run/macro-range/Expansion_Possible_3.scala
new file mode 100644
index 0000000000..e7ecbcc362
--- /dev/null
+++ b/test/files/run/macro-range/Expansion_Possible_3.scala
@@ -0,0 +1,7 @@
+class Range(val from: Int, val to: Int) extends RangeDefault {
+ override def foreach(f: Int => Unit): Unit = macro Impls.foreach
+}
+
+object Test extends App {
+ new Range(1, 10) foreach println
+} \ No newline at end of file
diff --git a/test/files/run/macro-range/macro_range_1.scala b/test/files/run/macro-range/macro_range_1.scala
deleted file mode 100644
index fdfe7169ad..0000000000
--- a/test/files/run/macro-range/macro_range_1.scala
+++ /dev/null
@@ -1,99 +0,0 @@
-import reflect.api.Modifier
-import reflect.macro.Context
-
-abstract class RangeDefault {
- val from, to: Int
- def foreach(f: Int => Unit) = {
- var i = from
- while (i < to) { f(i); i += 1 }
- }
-}
-
-/** This class should go into reflect.macro once it is a bit more stable. */
-abstract class Utils {
- val context: Context
- import context._
-
- class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer {
- override def transform(tree: Tree): Tree = tree match {
- case Ident(_) =>
- def subst(from: List[Symbol], to: List[Tree]): Tree =
- if (from.isEmpty) tree
- else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`?
- else subst(from.tail, to.tail);
- subst(from, to)
- case _ =>
- val tree1 = super.transform(tree)
- if (tree1 ne tree) tree1.tpe = null
- tree1
- }
- }
- def makeApply(fn: Tree, args: List[Tree]): Tree = fn match {
- case Function(vparams, body) =>
- new TreeSubstituter(vparams map (_.symbol), args) transform body
- case Block(stats, expr) =>
- Block(stats, makeApply(expr, args))
- case _ =>
- // todo. read the compiler config and print if -Ydebug is set
- //println("no beta on "+fn+" "+fn.getClass)
- Apply(fn, args)
- }
- def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = {
- val continu = Apply(Ident(lname), Nil)
- val rhs = If(cond, Block(List(body), continu), Literal(Constant()))
- LabelDef(lname, Nil, rhs)
- }
- def makeBinop(left: Tree, op: String, right: Tree): Tree =
- Apply(Select(left, newTermName(op)), List(right))
-}
-
-class Range(val from: Int, val to: Int) extends RangeDefault {
- override def macro foreach(f: Int => Unit): Unit = {
- // todo. read the compiler config and print if -Ydebug is set
- //println("macro-expand, _this = "+ _this)
- import _context._
- object utils extends Utils {
- val context: _context.type = _context
- }
- import utils._
-
- val initName = newTermName("<init>")
- // Either:
- // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } }
- // or:
- // scala"($_this: RangeDefault).foreach($f)"
- _this match {
- case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" =>
- val iname = newTermName("$i")
- val hname = newTermName("$h")
- def iref = Ident(iname)
- def href = Ident(hname)
- val labelname = newTermName("$while")
- val cond = makeBinop(iref, "$less", href)
- val body = Block(
- List(makeApply(f, List(iref))),
- Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1)))))
- val generated =
- Block(
- List(
- ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo),
- ValDef(Modifiers(), hname, TypeTree(), hi)),
- makeWhile(labelname, cond, body))
- // todo. read the compiler config and print if -Ydebug is set
- //tools.nsc.util.trace("generated: ")(generated)
- generated
- case _ =>
- Apply(
- Select(
- Typed(_this, Ident(newTypeName("RangeDefault"))),
- newTermName("foreach")),
- List(f))
- }
- }
-}
-
-object Test extends App {
-
- new Range(1, 10) foreach println
-
-}
diff --git a/test/files/run/macro-range/macro_range_2.scala b/test/files/run/macro-range/macro_range_2.scala
deleted file mode 100644
index fdfe7169ad..0000000000
--- a/test/files/run/macro-range/macro_range_2.scala
+++ /dev/null
@@ -1,99 +0,0 @@
-import reflect.api.Modifier
-import reflect.macro.Context
-
-abstract class RangeDefault {
- val from, to: Int
- def foreach(f: Int => Unit) = {
- var i = from
- while (i < to) { f(i); i += 1 }
- }
-}
-
-/** This class should go into reflect.macro once it is a bit more stable. */
-abstract class Utils {
- val context: Context
- import context._
-
- class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer {
- override def transform(tree: Tree): Tree = tree match {
- case Ident(_) =>
- def subst(from: List[Symbol], to: List[Tree]): Tree =
- if (from.isEmpty) tree
- else if (tree.symbol == from.head) to.head.duplicate // TODO: does it ever make sense *not* to perform a shallowDuplicate on `to.head`?
- else subst(from.tail, to.tail);
- subst(from, to)
- case _ =>
- val tree1 = super.transform(tree)
- if (tree1 ne tree) tree1.tpe = null
- tree1
- }
- }
- def makeApply(fn: Tree, args: List[Tree]): Tree = fn match {
- case Function(vparams, body) =>
- new TreeSubstituter(vparams map (_.symbol), args) transform body
- case Block(stats, expr) =>
- Block(stats, makeApply(expr, args))
- case _ =>
- // todo. read the compiler config and print if -Ydebug is set
- //println("no beta on "+fn+" "+fn.getClass)
- Apply(fn, args)
- }
- def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = {
- val continu = Apply(Ident(lname), Nil)
- val rhs = If(cond, Block(List(body), continu), Literal(Constant()))
- LabelDef(lname, Nil, rhs)
- }
- def makeBinop(left: Tree, op: String, right: Tree): Tree =
- Apply(Select(left, newTermName(op)), List(right))
-}
-
-class Range(val from: Int, val to: Int) extends RangeDefault {
- override def macro foreach(f: Int => Unit): Unit = {
- // todo. read the compiler config and print if -Ydebug is set
- //println("macro-expand, _this = "+ _this)
- import _context._
- object utils extends Utils {
- val context: _context.type = _context
- }
- import utils._
-
- val initName = newTermName("<init>")
- // Either:
- // scala"{ var i = $low; val h = $hi; while (i < h) { $f(i); i = i + 1 } }
- // or:
- // scala"($_this: RangeDefault).foreach($f)"
- _this match {
- case Apply(Select(New(tpt), initName), List(lo, hi)) if tpt.symbol.fullName == "Range" =>
- val iname = newTermName("$i")
- val hname = newTermName("$h")
- def iref = Ident(iname)
- def href = Ident(hname)
- val labelname = newTermName("$while")
- val cond = makeBinop(iref, "$less", href)
- val body = Block(
- List(makeApply(f, List(iref))),
- Assign(iref, makeBinop(iref, "$plus", Literal(Constant(1)))))
- val generated =
- Block(
- List(
- ValDef(Modifiers(Set(Modifier.mutable)), iname, TypeTree(), lo),
- ValDef(Modifiers(), hname, TypeTree(), hi)),
- makeWhile(labelname, cond, body))
- // todo. read the compiler config and print if -Ydebug is set
- //tools.nsc.util.trace("generated: ")(generated)
- generated
- case _ =>
- Apply(
- Select(
- Typed(_this, Ident(newTypeName("RangeDefault"))),
- newTermName("foreach")),
- List(f))
- }
- }
-}
-
-object Test extends App {
-
- new Range(1, 10) foreach println
-
-}
diff --git a/test/files/run/macro-reflective-ma-normal-mdmi.check b/test/files/run/macro-reflective-ma-normal-mdmi.check
new file mode 100644
index 0000000000..ac4213d6e9
--- /dev/null
+++ b/test/files/run/macro-reflective-ma-normal-mdmi.check
@@ -0,0 +1 @@
+43 \ No newline at end of file
diff --git a/test/files/run/macro-reflective-ma-normal-mdmi.flags b/test/files/run/macro-reflective-ma-normal-mdmi.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reflective-ma-normal-mdmi.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala b/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala
new file mode 100644
index 0000000000..f6caf89dca
--- /dev/null
+++ b/test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1))))
+ Expr[Int](body)
+ }
+}
+
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala
new file mode 100644
index 0000000000..632708a125
--- /dev/null
+++ b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ println(Expr(tree).eval)
+}
diff --git a/test/files/run/macro-reflective-mamd-normal-mi.check b/test/files/run/macro-reflective-mamd-normal-mi.check
new file mode 100644
index 0000000000..ac4213d6e9
--- /dev/null
+++ b/test/files/run/macro-reflective-mamd-normal-mi.check
@@ -0,0 +1 @@
+43 \ No newline at end of file
diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala
new file mode 100644
index 0000000000..dc7d42d23e
--- /dev/null
+++ b/test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1))))
+ Expr[Int](body)
+ }
+}
diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala
new file mode 100644
index 0000000000..cf34f1685d
--- /dev/null
+++ b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala
@@ -0,0 +1,17 @@
+//object Macros {
+// def foo(x: Int) = macro Impls.foo
+//}
+
+object Test extends App {
+ import scala.reflect.mirror._
+
+ val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo"))
+ val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.asType), EmptyTree)
+ val macrodef = DefDef(Modifiers(Set(scala.reflect.api.Modifier.`macro`)), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody)
+ val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(EmptyTypeName), EmptyTypeName), nme.CONSTRUCTOR), List())))
+ val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef)))
+ val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Block(macrodef, module, macroapp)
+ val toolbox = mkToolBox(options = "-language:experimental.macros")
+ println(toolbox.runExpr(tree))
+}
diff --git a/test/files/run/macro-reify-basic.check b/test/files/run/macro-reify-basic.check
new file mode 100644
index 0000000000..f35d3e67b4
--- /dev/null
+++ b/test/files/run/macro-reify-basic.check
@@ -0,0 +1 @@
+hello world
diff --git a/test/files/run/macro-reify-basic.flags b/test/files/run/macro-reify-basic.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-basic.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-basic/Macros_1.scala b/test/files/run/macro-reify-basic/Macros_1.scala
new file mode 100644
index 0000000000..b2243d131c
--- /dev/null
+++ b/test/files/run/macro-reify-basic/Macros_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def foo(s: String) = macro Impls.foo
+
+ object Impls {
+ def foo(c: Ctx)(s: c.Expr[String]) = c.reify {
+ println("hello " + s.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-basic/Test_2.scala b/test/files/run/macro-reify-basic/Test_2.scala
new file mode 100644
index 0000000000..0a762f7ad7
--- /dev/null
+++ b/test/files/run/macro-reify-basic/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.foo("world")
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-eval-eval.check b/test/files/run/macro-reify-eval-eval.check
new file mode 100644
index 0000000000..f35d3e67b4
--- /dev/null
+++ b/test/files/run/macro-reify-eval-eval.check
@@ -0,0 +1 @@
+hello world
diff --git a/test/files/run/macro-reify-eval-eval.flags b/test/files/run/macro-reify-eval-eval.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-eval-eval.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-eval-eval/Macros_1.scala b/test/files/run/macro-reify-eval-eval/Macros_1.scala
new file mode 100644
index 0000000000..6b8ac94f0e
--- /dev/null
+++ b/test/files/run/macro-reify-eval-eval/Macros_1.scala
@@ -0,0 +1,12 @@
+import scala.reflect.makro.{Context => Ctx}
+import scala.reflect.{mirror => mr}
+
+object Macros {
+ def foo = macro Impls.foo
+
+ object Impls {
+ def foo(c: Ctx) = c.reify {
+ { c.reify(c.reify("hello world")) }.eval.eval
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-eval-eval/Test_2.scala b/test/files/run/macro-reify-eval-eval/Test_2.scala
new file mode 100644
index 0000000000..f697da6020
--- /dev/null
+++ b/test/files/run/macro-reify-eval-eval/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println(Macros.foo)
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-eval-outside-reify.check b/test/files/run/macro-reify-eval-outside-reify.check
new file mode 100644
index 0000000000..2f562a182f
--- /dev/null
+++ b/test/files/run/macro-reify-eval-outside-reify.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/macro-reify-eval-outside-reify.flags b/test/files/run/macro-reify-eval-outside-reify.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-eval-outside-reify.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala b/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala
new file mode 100644
index 0000000000..13b603d610
--- /dev/null
+++ b/test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = c.literal(x.eval)
+}
+
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+}
diff --git a/test/files/run/macro-reify-eval-outside-reify/Test_2.scala b/test/files/run/macro-reify-eval-outside-reify/Test_2.scala
new file mode 100644
index 0000000000..632708a125
--- /dev/null
+++ b/test/files/run/macro-reify-eval-outside-reify/Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ println(Expr(tree).eval)
+}
diff --git a/test/files/run/macro-reify-freevars.check b/test/files/run/macro-reify-freevars.check
new file mode 100644
index 0000000000..068742f0b6
--- /dev/null
+++ b/test/files/run/macro-reify-freevars.check
@@ -0,0 +1,3 @@
+reflective compilation has failed:
+
+Macro expansion contains free term variable code defined by map in Macros_1.scala:8:9. Have you forgotten to use eval when splicing this variable into a reifee? If you have troubles tracking free term variables, consider using -Xlog-free-terms
diff --git a/test/files/run/macro-reify-freevars.flags b/test/files/run/macro-reify-freevars.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-freevars.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-freevars/Macros_1.scala b/test/files/run/macro-reify-freevars/Macros_1.scala
new file mode 100644
index 0000000000..3cc559a0af
--- /dev/null
+++ b/test/files/run/macro-reify-freevars/Macros_1.scala
@@ -0,0 +1,19 @@
+package scala.collection.slick
+object QueryableMacros{
+ def map[T:c.TypeTag, S:c.TypeTag]
+ (c: scala.reflect.makro.Context)
+ (projection: c.mirror.Expr[T => S])
+ : c.mirror.Expr[scala.collection.slick.Queryable[S]] = {
+ import c.mirror._
+ val code = EmptyTree
+ c.reify{
+ Queryable.factory[S]( code.asInstanceOf[reflect.mirror.Tree] )
+ }
+ }
+}
+class Queryable[T]{
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:scala.reflect.mirror.Tree ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-freevars/Test_2.scala b/test/files/run/macro-reify-freevars/Test_2.scala
new file mode 100644
index 0000000000..e7077f9c7f
--- /dev/null
+++ b/test/files/run/macro-reify-freevars/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val q = New(AppliedTypeTree(Select(Select(Select(Ident("scala"), newTermName("collection")), newTermName("slick")), newTypeName("Queryable")), List(Ident("Int"))))
+ val x = ValDef(NoMods, newTermName("x"), Ident("Int"), EmptyTree)
+ val fn = Function(List(x), Apply(Select(Ident(newTermName("x")), newTermName("$plus")), List(Literal(Constant("5")))))
+ val tree = Apply(Select(q, newTermName("map")), List(fn))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams.check b/test/files/run/macro-reify-groundtypetag-notypeparams.check
new file mode 100644
index 0000000000..d75b3c72b2
--- /dev/null
+++ b/test/files/run/macro-reify-groundtypetag-notypeparams.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[List[Int]]
diff --git a/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala
new file mode 100644
index 0000000000..d2f8fab5ec
--- /dev/null
+++ b/test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala
@@ -0,0 +1,6 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ println(implicitly[ConcreteTypeTag[Int]])
+ println(implicitly[ConcreteTypeTag[List[Int]]])
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags.check b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check
new file mode 100644
index 0000000000..d75b3c72b2
--- /dev/null
+++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[List[Int]]
diff --git a/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala
new file mode 100644
index 0000000000..6d7eab5f9a
--- /dev/null
+++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooTypeTag[T: ConcreteTypeTag] = {
+ println(implicitly[ConcreteTypeTag[T]])
+ println(implicitly[ConcreteTypeTag[List[T]]])
+ }
+ fooTypeTag[Int]
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a.check b/test/files/run/macro-reify-nested-a.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/macro-reify-nested-a.check
diff --git a/test/files/run/macro-reify-nested-a.flags b/test/files/run/macro-reify-nested-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-nested-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala
new file mode 100644
index 0000000000..1ce8f44671
--- /dev/null
+++ b/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala
@@ -0,0 +1,43 @@
+import scala.reflect.makro.Context
+
+case class Utils[C <: Context]( c:C ) {
+ import c.mirror._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.mirror.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reified::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reified)
+ case Apply(Select(_this, termname), reified::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reified)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.TypeTag]( c:C )( name:String, projection:c.mirror.Expr[_] ) = {
+ import c.mirror._
+ val element_type = implicitly[c.TypeTag[S]].tpe
+ val foo = Expr[reflect.mirror.Expr[Queryable[S]]](
+ c.reifyTree( c.reflectMirrorPrefix, c.typeCheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, newTermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.reify{ Queryable.factory[S]( foo.eval )}
+ }
+ def map[T:c.TypeTag, S:c.TypeTag]
+ (c: scala.reflect.makro.Context)
+ (projection: c.mirror.Expr[T => S]): c.mirror.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:scala.reflect.mirror.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a/Test_2.scala b/test/files/run/macro-reify-nested-a/Test_2.scala
new file mode 100644
index 0000000000..fa0eb378af
--- /dev/null
+++ b/test/files/run/macro-reify-nested-a/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1))
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b.check b/test/files/run/macro-reify-nested-b.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b.check
diff --git a/test/files/run/macro-reify-nested-b.flags b/test/files/run/macro-reify-nested-b.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala
new file mode 100644
index 0000000000..1ce8f44671
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala
@@ -0,0 +1,43 @@
+import scala.reflect.makro.Context
+
+case class Utils[C <: Context]( c:C ) {
+ import c.mirror._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.mirror.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reified::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reified)
+ case Apply(Select(_this, termname), reified::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reified)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.TypeTag]( c:C )( name:String, projection:c.mirror.Expr[_] ) = {
+ import c.mirror._
+ val element_type = implicitly[c.TypeTag[S]].tpe
+ val foo = Expr[reflect.mirror.Expr[Queryable[S]]](
+ c.reifyTree( c.reflectMirrorPrefix, c.typeCheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, newTermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.reify{ Queryable.factory[S]( foo.eval )}
+ }
+ def map[T:c.TypeTag, S:c.TypeTag]
+ (c: scala.reflect.makro.Context)
+ (projection: c.mirror.Expr[T => S]): c.mirror.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:scala.reflect.mirror.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b/Test_2.scala b/test/files/run/macro-reify-nested-b/Test_2.scala
new file mode 100644
index 0000000000..fa13f57ffb
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-ref-to-packageless.check b/test/files/run/macro-reify-ref-to-packageless.check
new file mode 100644
index 0000000000..2f562a182f
--- /dev/null
+++ b/test/files/run/macro-reify-ref-to-packageless.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/macro-reify-ref-to-packageless.flags b/test/files/run/macro-reify-ref-to-packageless.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-ref-to-packageless.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala b/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala
new file mode 100644
index 0000000000..2f2d05678d
--- /dev/null
+++ b/test/files/run/macro-reify-ref-to-packageless/Impls_1.scala
@@ -0,0 +1,6 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ val `Answer to the Ultimate Question of Life, the Universe, and Everything` = 42
+ def foo(c: Ctx) = c.reify { `Answer to the Ultimate Question of Life, the Universe, and Everything` }
+}
diff --git a/test/files/run/macro-reify-ref-to-packageless/Test_2.scala b/test/files/run/macro-reify-ref-to-packageless/Test_2.scala
new file mode 100644
index 0000000000..9d475f756d
--- /dev/null
+++ b/test/files/run/macro-reify-ref-to-packageless/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo = macro Impls.foo
+ println(foo)
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-tagful-a.check b/test/files/run/macro-reify-tagful-a.check
new file mode 100644
index 0000000000..8a701df6a5
--- /dev/null
+++ b/test/files/run/macro-reify-tagful-a.check
@@ -0,0 +1 @@
+List(hello world)
diff --git a/test/files/run/macro-reify-tagful-a.flags b/test/files/run/macro-reify-tagful-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-tagful-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-tagful-a/Macros_1.scala b/test/files/run/macro-reify-tagful-a/Macros_1.scala
new file mode 100644
index 0000000000..2ff12091a1
--- /dev/null
+++ b/test/files/run/macro-reify-tagful-a/Macros_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def foo[T](s: T) = macro Impls.foo[T]
+
+ object Impls {
+ def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify {
+ List(s.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-tagful-a/Test_2.scala b/test/files/run/macro-reify-tagful-a/Test_2.scala
new file mode 100644
index 0000000000..4d27166341
--- /dev/null
+++ b/test/files/run/macro-reify-tagful-a/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val list: List[String] = Macros.foo("hello world")
+ println(list)
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-tagless-a.check b/test/files/run/macro-reify-tagless-a.check
new file mode 100644
index 0000000000..4ee11190d6
--- /dev/null
+++ b/test/files/run/macro-reify-tagless-a.check
@@ -0,0 +1,3 @@
+reflective compilation has failed:
+
+Macro expansion contains free type variable T defined by foo in Impls_Macros_1.scala:7:13. Have you forgotten to use c.TypeTag annotation for this type parameter? If you have troubles tracking free type variables, consider using -Xlog-free-types
diff --git a/test/files/run/macro-reify-tagless-a.flags b/test/files/run/macro-reify-tagless-a.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-tagless-a.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala b/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala
new file mode 100644
index 0000000000..45e39d7d1c
--- /dev/null
+++ b/test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def foo[T](s: T) = macro Impls.foo[T]
+
+ object Impls {
+ def foo[T](c: Ctx)(s: c.Expr[T]) = c.reify {
+ List[T](s.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-tagless-a/Test_2.scala b/test/files/run/macro-reify-tagless-a/Test_2.scala
new file mode 100644
index 0000000000..94efbd0c37
--- /dev/null
+++ b/test/files/run/macro-reify-tagless-a/Test_2.scala
@@ -0,0 +1,12 @@
+object Test extends App {
+ //val list: List[String] = Macros.foo("hello world")
+ //println(list)
+
+ import scala.reflect.mirror._
+ val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass)))
+ val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world"))))
+ val list = ValDef(NoMods, newTermName("list"), tpt, rhs)
+ val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name))))
+ try Expr(tree).eval
+ catch { case ex: Throwable => println(ex.getMessage) }
+}
diff --git a/test/files/run/macro-reify-typetag-notypeparams.check b/test/files/run/macro-reify-typetag-notypeparams.check
new file mode 100644
index 0000000000..d75b3c72b2
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-notypeparams.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[List[Int]]
diff --git a/test/files/run/macro-reify-typetag-notypeparams/Test.scala b/test/files/run/macro-reify-typetag-notypeparams/Test.scala
new file mode 100644
index 0000000000..041a44273d
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-notypeparams/Test.scala
@@ -0,0 +1,6 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ println(implicitly[TypeTag[Int]])
+ println(implicitly[TypeTag[List[Int]]])
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-typetag-typeparams-notags.check b/test/files/run/macro-reify-typetag-typeparams-notags.check
new file mode 100644
index 0000000000..11d78ece41
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-typeparams-notags.check
@@ -0,0 +1,2 @@
+TypeTag[T]
+TypeTag[List[T]]
diff --git a/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala b/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala
new file mode 100644
index 0000000000..a89499e7fe
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-typeparams-notags/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooNoTypeTag[T] = {
+ println(implicitly[TypeTag[T]])
+ println(implicitly[TypeTag[List[T]]])
+ }
+ fooNoTypeTag[Int]
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-typetag-typeparams-tags.check b/test/files/run/macro-reify-typetag-typeparams-tags.check
new file mode 100644
index 0000000000..458593c449
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-typeparams-tags.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Int]
+*ConcreteTypeTag[List[Int]]
diff --git a/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala b/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala
new file mode 100644
index 0000000000..b32680a4b8
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-typeparams-tags/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooTypeTag[T: TypeTag] = {
+ println(implicitly[TypeTag[T]])
+ println(implicitly[TypeTag[List[T]]])
+ }
+ fooTypeTag[Int]
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag.check b/test/files/run/macro-reify-typetag-usegroundtypetag.check
new file mode 100644
index 0000000000..458593c449
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-usegroundtypetag.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Int]
+*ConcreteTypeTag[List[Int]]
diff --git a/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala
new file mode 100644
index 0000000000..de235f51cc
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooTypeTag[T: ConcreteTypeTag] = {
+ println(implicitly[TypeTag[T]])
+ println(implicitly[TypeTag[List[T]]])
+ }
+ fooTypeTag[Int]
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-unreify.check b/test/files/run/macro-reify-unreify.check
new file mode 100644
index 0000000000..a5334cc355
--- /dev/null
+++ b/test/files/run/macro-reify-unreify.check
@@ -0,0 +1 @@
+hello world = Expr[String("hello world")]("hello world")
diff --git a/test/files/run/macro-reify-unreify.flags b/test/files/run/macro-reify-unreify.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-unreify.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-unreify/Macros_1.scala b/test/files/run/macro-reify-unreify/Macros_1.scala
new file mode 100644
index 0000000000..1b0b9c6421
--- /dev/null
+++ b/test/files/run/macro-reify-unreify/Macros_1.scala
@@ -0,0 +1,19 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def foo(s: String) = macro Impls.foo
+
+ object Impls {
+ def foo(c: Ctx)(s: c.Expr[String]) = {
+ import c.mirror._
+
+ val world = c.reifyTree(c.reflectMirrorPrefix, s.tree)
+ val greeting = c.reifyTree(c.reflectMirrorPrefix, c.typeCheck(Apply(Select(Literal(Constant("hello ")), newTermName("$plus")), List(c.unreifyTree(world)))))
+ val typedGreeting = Expr[String](greeting)
+
+ c.reify {
+ println("hello " + s.eval + " = " + typedGreeting.eval)
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-unreify/Test_2.scala b/test/files/run/macro-reify-unreify/Test_2.scala
new file mode 100644
index 0000000000..0a762f7ad7
--- /dev/null
+++ b/test/files/run/macro-reify-unreify/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.foo("world")
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-value-outside-reify.check b/test/files/run/macro-reify-value-outside-reify.check
new file mode 100644
index 0000000000..2f562a182f
--- /dev/null
+++ b/test/files/run/macro-reify-value-outside-reify.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/macro-reify-value-outside-reify.flags b/test/files/run/macro-reify-value-outside-reify.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-reify-value-outside-reify.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala b/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala
new file mode 100644
index 0000000000..28ec1ace67
--- /dev/null
+++ b/test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = c.literal(x.value)
+}
+
+object Macros {
+ def foo(x: Int) = macro Impls.foo
+}
diff --git a/test/files/run/macro-reify-value-outside-reify/Test_2.scala b/test/files/run/macro-reify-value-outside-reify/Test_2.scala
new file mode 100644
index 0000000000..128cad4510
--- /dev/null
+++ b/test/files/run/macro-reify-value-outside-reify/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import scala.reflect.mirror._
+ val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ try println(Expr(tree).eval)
+ catch { case ex: Throwable => println(ex.getMessage) }
+}
diff --git a/test/files/run/macro-repl-basic.check b/test/files/run/macro-repl-basic.check
index f8f0d3ad29..9e0f9aa1a2 100644
--- a/test/files/run/macro-repl-basic.check
+++ b/test/files/run/macro-repl-basic.check
@@ -1,25 +1,54 @@
-Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala>
-
-scala> object Macros {
- object Shmacros {
- def macro foo(x: Int): Int = x
- }
- def macro bar(x: Int): Int = x
-}; class Macros {
- def macro quux(x: Int): Int = x
-}
-defined module Macros
-defined class Macros
-
-scala>
-
-scala> import Macros.Shmacros._
-import Macros.Shmacros._
-
-scala> println(foo(2) + Macros.bar(2) * new Macros().quux(4))
-10
-
-scala>
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import language.experimental.macros
+import language.experimental.macros
+
+scala> import scala.reflect.makro.{Context => Ctx}
+import scala.reflect.makro.{Context=>Ctx}
+
+scala>
+
+scala> object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int]) = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1))))
+ Expr[Int](body)
+ }
+
+ def bar(c: Ctx)(x: c.Expr[Int]) = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2))))
+ Expr[Int](body)
+ }
+
+ def quux(c: Ctx)(x: c.Expr[Int]) = {
+ import c.mirror._
+ val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3))))
+ Expr[Int](body)
+ }
+}
+defined module Impls
+
+scala> object Macros {
+ object Shmacros {
+ def foo(x: Int): Int = macro Impls.foo
+ }
+ def bar(x: Int): Int = macro Impls.bar
+}; class Macros {
+ def quux(x: Int): Int = macro Impls.quux
+}
+defined module Macros
+defined class Macros
+
+scala>
+
+scala> import Macros.Shmacros._
+import Macros.Shmacros._
+
+scala> println(foo(2) + Macros.bar(2) * new Macros().quux(4))
+31
+
+scala>
diff --git a/test/files/run/macro-repl-basic.scala b/test/files/run/macro-repl-basic.scala
index 9b1a53343b..e8849b4b56 100644
--- a/test/files/run/macro-repl-basic.scala
+++ b/test/files/run/macro-repl-basic.scala
@@ -1,18 +1,39 @@
import scala.tools.partest.ReplTest
object Test extends ReplTest {
- override def extraSettings = "-Xmacros"
def code = """
+ |import language.experimental.macros
+ |import scala.reflect.makro.{Context => Ctx}
+ |
+ |object Impls {
+ | def foo(c: Ctx)(x: c.Expr[Int]) = {
+ | import c.mirror._
+ | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1))))
+ | Expr[Int](body)
+ | }
+ |
+ | def bar(c: Ctx)(x: c.Expr[Int]) = {
+ | import c.mirror._
+ | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2))))
+ | Expr[Int](body)
+ | }
+ |
+ | def quux(c: Ctx)(x: c.Expr[Int]) = {
+ | import c.mirror._
+ | val body = Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(3))))
+ | Expr[Int](body)
+ | }
+ |}
|object Macros {
| object Shmacros {
- | def macro foo(x: Int): Int = x
+ | def foo(x: Int): Int = macro Impls.foo
| }
- | def macro bar(x: Int): Int = x
+ | def bar(x: Int): Int = macro Impls.bar
|}; class Macros {
- | def macro quux(x: Int): Int = x
+ | def quux(x: Int): Int = macro Impls.quux
|}
|
|import Macros.Shmacros._
|println(foo(2) + Macros.bar(2) * new Macros().quux(4))
|""".stripMargin
-} \ No newline at end of file
+}
diff --git a/test/files/run/macro-repl-dontexpand.check b/test/files/run/macro-repl-dontexpand.check
index d2bb89b6f7..35845f0cff 100644
--- a/test/files/run/macro-repl-dontexpand.check
+++ b/test/files/run/macro-repl-dontexpand.check
@@ -3,7 +3,10 @@ Type :help for more information.
scala>
-scala> def macro foo = ???
+scala> def bar(c: scala.reflect.makro.Context) = ???
+bar: (c: scala.reflect.makro.Context)Nothing
+
+scala> def foo = macro bar
foo: Any
scala>
diff --git a/test/files/run/macro-repl-dontexpand.scala b/test/files/run/macro-repl-dontexpand.scala
index 254bce894c..cd1b2e1969 100644
--- a/test/files/run/macro-repl-dontexpand.scala
+++ b/test/files/run/macro-repl-dontexpand.scala
@@ -1,8 +1,9 @@
import scala.tools.partest.ReplTest
object Test extends ReplTest {
- override def extraSettings = "-Xmacros"
+ override def extraSettings = "-language:experimental.macros"
def code = """
- |def macro foo = ???
+ |def bar(c: scala.reflect.makro.Context) = ???
+ |def foo = macro bar
|""".stripMargin
-} \ No newline at end of file
+}
diff --git a/test/files/run/macro-rettype-mismatch.flags b/test/files/run/macro-rettype-mismatch.flags
index 7fea2ff901..cd66464f2f 100644
--- a/test/files/run/macro-rettype-mismatch.flags
+++ b/test/files/run/macro-rettype-mismatch.flags
@@ -1 +1 @@
--Xmacros \ No newline at end of file
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-rettype-mismatch/Macros_1.scala b/test/files/run/macro-rettype-mismatch/Macros_1.scala
deleted file mode 100644
index 64e5b93468..0000000000
--- a/test/files/run/macro-rettype-mismatch/Macros_1.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-object Macros {
- def macro foo(x: Int): String = x
-} \ No newline at end of file
diff --git a/test/files/run/macro-rettype-mismatch/Test_2.scala b/test/files/run/macro-rettype-mismatch/Test_2.scala
deleted file mode 100644
index 39a7c7ad1a..0000000000
--- a/test/files/run/macro-rettype-mismatch/Test_2.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
-object Test extends App {
- import scala.reflect.mirror._
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(2))))
-
- val stderr = new java.io.ByteArrayOutputStream()
- Console.setErr(new java.io.PrintStream(stderr))
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- try { toolbox.runExpr(tree) }
- catch { case ex: Throwable => println(stderr); println(ex) }
-}
diff --git a/test/files/run/macro-settings.check b/test/files/run/macro-settings.check
new file mode 100644
index 0000000000..33784d1c15
--- /dev/null
+++ b/test/files/run/macro-settings.check
@@ -0,0 +1 @@
+List(hello=1)
diff --git a/test/files/run/macro-settings.flags b/test/files/run/macro-settings.flags
new file mode 100644
index 0000000000..15479e30b8
--- /dev/null
+++ b/test/files/run/macro-settings.flags
@@ -0,0 +1 @@
+-language:experimental.macros -Xmacro-settings:hello=1 \ No newline at end of file
diff --git a/test/files/run/macro-settings/Impls_Macros_1.scala b/test/files/run/macro-settings/Impls_Macros_1.scala
new file mode 100644
index 0000000000..8c7254c79a
--- /dev/null
+++ b/test/files/run/macro-settings/Impls_Macros_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.Context
+
+object Impls {
+ def impl(c: Context) = c.reify {
+ println(c.literal(c.settings.toString).eval)
+ }
+}
+
+object Macros {
+ def foo = macro Impls.impl
+} \ No newline at end of file
diff --git a/test/files/run/macro-settings/Test_2.scala b/test/files/run/macro-settings/Test_2.scala
new file mode 100644
index 0000000000..acfddae942
--- /dev/null
+++ b/test/files/run/macro-settings/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ Macros.foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-sip19-revised.check b/test/files/run/macro-sip19-revised.check
new file mode 100644
index 0000000000..aa2fbd11d3
--- /dev/null
+++ b/test/files/run/macro-sip19-revised.check
@@ -0,0 +1,5 @@
+hey, i've been called from SourceLocation1(null,Test_2.scala,11,251)
+hey, i've been called from SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222)
+hey, i've been called from SourceLocation1(SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222),Test_2.scala,8,222)
+hey, i've been called from SourceLocation1(SourceLocation1(SourceLocation1(SourceLocation1(null,Test_2.scala,11,251),Test_2.scala,8,222),Test_2.scala,8,222),Test_2.scala,6,180)
+2
diff --git a/test/files/run/macro-sip19-revised.flags b/test/files/run/macro-sip19-revised.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-sip19-revised.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-sip19-revised/Impls_Macros_1.scala b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala
new file mode 100644
index 0000000000..e8f6e1df85
--- /dev/null
+++ b/test/files/run/macro-sip19-revised/Impls_Macros_1.scala
@@ -0,0 +1,34 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl(c: Context) = {
+ import c.mirror._
+
+ val inscope = c.inferImplicitValue(staticClass("SourceLocation").asType)
+ val outer = Expr[SourceLocation](if (!inscope.isEmpty) inscope else Literal(Constant(null)))
+
+ val Apply(fun, args) = c.enclosingImplicits(0)._2
+ val fileName = fun.pos.fileInfo.getName
+ val line = fun.pos.line
+ val charOffset = fun.pos.point
+ c.reify { SourceLocation1(outer.eval, c.literal(fileName).eval, c.literal(line).eval, c.literal(charOffset).eval) }
+ }
+
+ implicit def sourceLocation: SourceLocation1 = macro impl
+}
+
+trait SourceLocation {
+ /** Source location of the outermost call */
+ val outer: SourceLocation
+
+ /** The name of the source file */
+ val fileName: String
+
+ /** The line number */
+ val line: Int
+
+ /** The character offset */
+ val charOffset: Int
+}
+
+case class SourceLocation1(val outer: SourceLocation, val fileName: String, val line: Int, val charOffset: Int) extends SourceLocation
diff --git a/test/files/run/macro-sip19-revised/Test_2.scala b/test/files/run/macro-sip19-revised/Test_2.scala
new file mode 100644
index 0000000000..d9a4d7d4fc
--- /dev/null
+++ b/test/files/run/macro-sip19-revised/Test_2.scala
@@ -0,0 +1,12 @@
+import Macros._
+
+object Test extends App {
+ def foo(x: Int, y: Int)(implicit loc: SourceLocation): Int = {
+ println("hey, i've been called from %s".format(loc))
+ if (x < y) foo(y, x)
+ else if (y == 0) x
+ else foo(x - y, y)
+ }
+
+ println(foo(4, 2))
+}
diff --git a/test/files/run/macro-sip19.check b/test/files/run/macro-sip19.check
new file mode 100644
index 0000000000..6b317ccb47
--- /dev/null
+++ b/test/files/run/macro-sip19.check
@@ -0,0 +1,5 @@
+hey, i've been called from SourceLocation(Test_2.scala,15,366)
+hey, i've been called from SourceLocation(Test_2.scala,11,331)
+hey, i've been called from SourceLocation(Test_2.scala,11,331)
+hey, i've been called from SourceLocation(Test_2.scala,9,285)
+2
diff --git a/test/files/run/macro-sip19.flags b/test/files/run/macro-sip19.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-sip19.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-sip19/Impls_Macros_1.scala b/test/files/run/macro-sip19/Impls_Macros_1.scala
new file mode 100644
index 0000000000..39b29ad64c
--- /dev/null
+++ b/test/files/run/macro-sip19/Impls_Macros_1.scala
@@ -0,0 +1,25 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl(c: Context) = {
+ import c.mirror._
+ val Apply(fun, args) = c.enclosingImplicits(0)._2
+ val fileName = fun.pos.fileInfo.getName
+ val line = fun.pos.line
+ val charOffset = fun.pos.point
+ c.reify { SourceLocation(c.literal(fileName).eval, c.literal(line).eval, c.literal(charOffset).eval) }
+ }
+
+ implicit def sourceLocation: SourceLocation = macro impl
+}
+
+case class SourceLocation(
+ /** The name of the source file */
+ val fileName: String,
+
+ /** The line number */
+ val line: Int,
+
+ /** The character offset */
+ val charOffset: Int
+)
diff --git a/test/files/run/macro-sip19/Test_2.scala b/test/files/run/macro-sip19/Test_2.scala
new file mode 100644
index 0000000000..32326e6352
--- /dev/null
+++ b/test/files/run/macro-sip19/Test_2.scala
@@ -0,0 +1,16 @@
+import Macros._
+
+object Test extends App {
+ def foo(x: Int, y: Int)(implicit loc0: SourceLocation): Int = {
+ var loc = loc0;
+ {
+ var loc0 = 0 // shadow loc0 to disambiguate with the implicit macro
+ println("hey, i've been called from %s".format(loc))
+ if (x < y) foo(y, x)
+ else if (y == 0) x
+ else foo(x - y, y)
+ }
+ }
+
+ println(foo(4, 2))
+}
diff --git a/test/files/run/macro-typecheck-implicitsdisabled.check b/test/files/run/macro-typecheck-implicitsdisabled.check
new file mode 100644
index 0000000000..aa6c8e1f07
--- /dev/null
+++ b/test/files/run/macro-typecheck-implicitsdisabled.check
@@ -0,0 +1,2 @@
+scala.this.Predef.any2ArrowAssoc[Int](1).->[Int](2)
+scala.reflect.internal.Types$TypeError: value -> is not a member of Int
diff --git a/test/files/run/macro-typecheck-implicitsdisabled.flags b/test/files/run/macro-typecheck-implicitsdisabled.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-typecheck-implicitsdisabled.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala
new file mode 100644
index 0000000000..4f0f76aed6
--- /dev/null
+++ b/test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala
@@ -0,0 +1,28 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl_with_implicits_enabled(c: Context) = {
+ import c.mirror._
+
+ val tree1 = Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2))))
+ val ttree1 = c.typeCheck(tree1, withImplicitViewsDisabled = false)
+ c.literal(ttree1.toString)
+ }
+
+ def foo_with_implicits_enabled = macro impl_with_implicits_enabled
+
+ def impl_with_implicits_disabled(c: Context) = {
+ import c.mirror._
+
+ try {
+ val tree2 = Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2))))
+ val ttree2 = c.typeCheck(tree2, withImplicitViewsDisabled = true)
+ c.literal(ttree2.toString)
+ } catch {
+ case ex: Throwable =>
+ c.literal(ex.toString)
+ }
+ }
+
+ def foo_with_implicits_disabled = macro impl_with_implicits_disabled
+} \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala b/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala
new file mode 100644
index 0000000000..127e955f0e
--- /dev/null
+++ b/test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ println(Macros.foo_with_implicits_enabled)
+ println(Macros.foo_with_implicits_disabled)
+} \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check
new file mode 100644
index 0000000000..3e1057520b
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled.check
@@ -0,0 +1,5 @@
+{
+ val $mr: reflect.mirror.type = scala.reflect.`package`.mirror;
+ $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)), classOf[scala.Int]))
+}
+mr.reify[Int](2)
diff --git a/test/files/run/macro-typecheck-macrosdisabled.flags b/test/files/run/macro-typecheck-macrosdisabled.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala
new file mode 100644
index 0000000000..3de9367994
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala
@@ -0,0 +1,29 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl_with_macros_enabled(c: Context) = {
+ import c.mirror._
+
+ val mr = Select(Select(Select(Ident(newTermName("scala")), newTermName("reflect")), newTermName("package")), newTermName("mirror"))
+ val tree1 = Apply(Select(mr, newTermName("reify")), List(Literal(Constant(2))))
+ val ttree1 = c.typeCheck(tree1, withMacrosDisabled = false)
+ c.literal(ttree1.toString)
+ }
+
+ def foo_with_macros_enabled = macro impl_with_macros_enabled
+
+ def impl_with_macros_disabled(c: Context) = {
+ import c.mirror._
+
+ val mrPkg = staticModule("scala.reflect.package")
+ val mrSym = selectTerm(mrPkg, "mirror")
+ val NullaryMethodType(mrTpe) = mrSym.typeSignature
+ val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror)
+
+ val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2))))
+ val ttree2 = c.typeCheck(tree2, withMacrosDisabled = true)
+ c.literal(ttree2.toString)
+ }
+
+ def foo_with_macros_disabled = macro impl_with_macros_disabled
+} \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala b/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala
new file mode 100644
index 0000000000..bdba39195b
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ println(Macros.foo_with_macros_enabled)
+ println(Macros.foo_with_macros_disabled)
+} \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-macrosdisabled2.check b/test/files/run/macro-typecheck-macrosdisabled2.check
new file mode 100644
index 0000000000..02da6ad0c7
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled2.check
@@ -0,0 +1,5 @@
+{
+ val $mr: reflect.mirror.type = scala.reflect.`package`.mirror;
+ $mr.Expr.apply[Array[Int]]($mr.Apply.apply($mr.Select.apply($mr.Select.apply($mr.Ident($mr.staticModule("scala")), $mr.newTermName("Array")), $mr.newTermName("apply")), scala.collection.immutable.List.apply[$mr.Literal]($mr.Literal.apply($mr.Constant.apply(2)))))($mr.ConcreteTypeTag.apply[Array[Int]]($mr.TypeRef.apply($mr.thisModuleType("scala"), $mr.staticClass("scala.Array"), scala.collection.immutable.List.apply[$mr.Type]($mr.staticClass("scala.Int").asTypeConstructor)), ScalaRunTime.this.arrayClass(classOf[scala.Int])))
+}
+mr.reify[Array[Int]](scala.Array.apply(2))
diff --git a/test/files/run/macro-typecheck-macrosdisabled2.flags b/test/files/run/macro-typecheck-macrosdisabled2.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled2.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala b/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..1b840a6204
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled2/Impls_Macros_1.scala
@@ -0,0 +1,29 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl_with_macros_enabled(c: Context) = {
+ import c.mirror._
+
+ val mr = Select(Select(Select(Ident(newTermName("scala")), newTermName("reflect")), newTermName("package")), newTermName("mirror"))
+ val tree1 = Apply(Select(mr, newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), List(Literal(Constant(2))))))
+ val ttree1 = c.typeCheck(tree1, withMacrosDisabled = false)
+ c.literal(ttree1.toString)
+ }
+
+ def foo_with_macros_enabled = macro impl_with_macros_enabled
+
+ def impl_with_macros_disabled(c: Context) = {
+ import c.mirror._
+
+ val mrPkg = staticModule("scala.reflect.package")
+ val mrSym = selectTerm(mrPkg, "mirror")
+ val NullaryMethodType(mrTpe) = mrSym.typeSignature
+ val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror)
+
+ val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), List(Literal(Constant(2))))))
+ val ttree2 = c.typeCheck(tree2, withMacrosDisabled = true)
+ c.literal(ttree2.toString)
+ }
+
+ def foo_with_macros_disabled = macro impl_with_macros_disabled
+} \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-macrosdisabled2/Test_2.scala b/test/files/run/macro-typecheck-macrosdisabled2/Test_2.scala
new file mode 100644
index 0000000000..bdba39195b
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled2/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ println(Macros.foo_with_macros_enabled)
+ println(Macros.foo_with_macros_disabled)
+} \ No newline at end of file
diff --git a/test/files/run/macro-undetparams-consfromsls.check b/test/files/run/macro-undetparams-consfromsls.check
new file mode 100644
index 0000000000..49e9140d5a
--- /dev/null
+++ b/test/files/run/macro-undetparams-consfromsls.check
@@ -0,0 +1,5 @@
+A = ConcreteTypeTag[Int]
+B = ConcreteTypeTag[Nothing]
+List(1)
+A = ConcreteTypeTag[Any]
+List(abc, 1)
diff --git a/test/files/run/macro-undetparams-consfromsls.flags b/test/files/run/macro-undetparams-consfromsls.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-undetparams-consfromsls.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala b/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala
new file mode 100644
index 0000000000..c22ff96028
--- /dev/null
+++ b/test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala
@@ -0,0 +1,17 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def cons_impl[A: c.TypeTag](c: Context)(x: c.Expr[A], xs: c.Expr[List[A]]): c.Expr[List[A]] = c.reify {
+ println("A = " + c.literal(implicitly[c.TypeTag[A]].toString).eval)
+ x.eval :: xs.eval
+ }
+
+ def nil_impl[B: c.TypeTag](c: Context): c.Expr[List[B]] = c.reify {
+ println("B = " + c.literal(implicitly[c.TypeTag[B]].toString).eval)
+ Nil
+ }
+
+ def cons[A](x: A, xs: List[A]): List[A] = macro cons_impl[A]
+
+ def nil[B]: List[B] = macro nil_impl[B]
+} \ No newline at end of file
diff --git a/test/files/run/macro-undetparams-consfromsls/Test_2.scala b/test/files/run/macro-undetparams-consfromsls/Test_2.scala
new file mode 100644
index 0000000000..f2c2ce0051
--- /dev/null
+++ b/test/files/run/macro-undetparams-consfromsls/Test_2.scala
@@ -0,0 +1,7 @@
+object Test extends App {
+ import Macros._
+ val xs = cons(1, nil)
+ println(xs)
+ val ys = cons("abc", xs)
+ println(ys)
+} \ No newline at end of file
diff --git a/test/files/run/macro-undetparams-implicitval.check b/test/files/run/macro-undetparams-implicitval.check
new file mode 100644
index 0000000000..6c2b601aa5
--- /dev/null
+++ b/test/files/run/macro-undetparams-implicitval.check
@@ -0,0 +1 @@
+ConcreteTypeTag[Nothing]
diff --git a/test/files/run/macro-undetparams-implicitval.flags b/test/files/run/macro-undetparams-implicitval.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-undetparams-implicitval.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-undetparams-implicitval/Test.scala b/test/files/run/macro-undetparams-implicitval/Test.scala
new file mode 100644
index 0000000000..5278295451
--- /dev/null
+++ b/test/files/run/macro-undetparams-implicitval/Test.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo[T: TypeTag] = println(implicitly[TypeTag[T]])
+ foo
+} \ No newline at end of file
diff --git a/test/files/run/macro-undetparams-macroitself.check b/test/files/run/macro-undetparams-macroitself.check
new file mode 100644
index 0000000000..e57fc1217b
--- /dev/null
+++ b/test/files/run/macro-undetparams-macroitself.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[String]
diff --git a/test/files/run/macro-undetparams-macroitself.flags b/test/files/run/macro-undetparams-macroitself.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-undetparams-macroitself.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala b/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala
new file mode 100644
index 0000000000..9d65e8b0da
--- /dev/null
+++ b/test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala
@@ -0,0 +1,7 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl[T: c.TypeTag](c: Context)(foo: c.Expr[T]): c.Expr[Unit] = c.reify { println(c.literal(implicitly[c.TypeTag[T]].toString).eval) }
+
+ def foo[T](foo: T) = macro impl[T]
+} \ No newline at end of file
diff --git a/test/files/run/macro-undetparams-macroitself/Test_2.scala b/test/files/run/macro-undetparams-macroitself/Test_2.scala
new file mode 100644
index 0000000000..1a93ff1304
--- /dev/null
+++ b/test/files/run/macro-undetparams-macroitself/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ Macros.foo(42)
+ Macros.foo("42")
+} \ No newline at end of file
diff --git a/test/files/run/manifests-new.scala b/test/files/run/manifests-new.scala
new file mode 100644
index 0000000000..4485ce9124
--- /dev/null
+++ b/test/files/run/manifests-new.scala
@@ -0,0 +1,147 @@
+object Test
+{
+ object Variances extends Enumeration {
+ val CO, IN, CONTRA = Value
+ }
+ import Variances.{ CO, IN, CONTRA }
+
+ object SubtypeRelationship extends Enumeration {
+ val NONE, SAME, SUB, SUPER = Value
+ }
+ import SubtypeRelationship.{ NONE, SAME, SUB, SUPER }
+
+ class VarianceTester[T, U, CC[_]](expected: Variances.Value)(
+ implicit ev1: TypeTag[T], ev2: TypeTag[U], ev3: TypeTag[CC[T]], ev4: TypeTag[CC[U]]) {
+
+ def elements = List(ev1.tpe <:< ev2.tpe, ev2.tpe <:< ev1.tpe)
+ def containers = List(ev3.tpe <:< ev4.tpe, ev4.tpe <:< ev3.tpe)
+
+ def isUnrelated = typeCompare[T, U] == NONE
+ def isSame = typeCompare[T, U] == SAME
+ def isSub = typeCompare[T, U] == SUB
+ def isSuper = typeCompare[T, U] == SUPER
+
+ def showsCovariance = (elements == containers)
+ def showsContravariance = (elements == containers.reverse)
+ def showsInvariance = containers forall (_ == isSame)
+
+ def allContainerVariances = List(showsCovariance, showsInvariance, showsContravariance)
+
+ def showsExpectedVariance =
+ if (isUnrelated) allContainerVariances forall (_ == false)
+ else if (isSame) allContainerVariances forall (_ == true)
+ else expected match {
+ case CO => showsCovariance && !showsContravariance && !showsInvariance
+ case IN => showsInvariance && !showsCovariance && !showsContravariance
+ case CONTRA => showsContravariance && !showsCovariance && !showsInvariance
+ }
+ }
+
+ def showsCovariance[T, U, CC[_]](implicit ev1: TypeTag[T], ev2: TypeTag[U], ev3: TypeTag[CC[T]], ev4: TypeTag[CC[U]]) =
+ new VarianceTester[T, U, CC](CO) showsExpectedVariance
+
+ def showsInvariance[T, U, CC[_]](implicit ev1: TypeTag[T], ev2: TypeTag[U], ev3: TypeTag[CC[T]], ev4: TypeTag[CC[U]]) =
+ new VarianceTester[T, U, CC](IN) showsExpectedVariance
+
+ def showsContravariance[T, U, CC[_]](implicit ev1: TypeTag[T], ev2: TypeTag[U], ev3: TypeTag[CC[T]], ev4: TypeTag[CC[U]]) =
+ new VarianceTester[T, U, CC](CONTRA) showsExpectedVariance
+
+ def typeCompare[T, U](implicit ev1: TypeTag[T], ev2: TypeTag[U]) = (ev1.tpe <:< ev2.tpe, ev2.tpe <:< ev1.tpe) match {
+ case (true, true) => SAME
+ case (true, false) => SUB
+ case (false, true) => SUPER
+ case (false, false) => NONE
+ }
+
+ def assertAnyRef[T: TypeTag] = List(
+ typeTag[T].tpe <:< typeTag[Any].tpe,
+ typeTag[T].tpe <:< typeTag[AnyRef].tpe,
+ !(typeTag[T].tpe <:< typeTag[AnyVal].tpe)
+ ) foreach (assert(_, "assertAnyRef"))
+
+ def assertAnyVal[T: TypeTag] = List(
+ typeTag[T].tpe <:< typeTag[Any].tpe,
+ !(typeTag[T].tpe <:< typeTag[AnyRef].tpe),
+ typeTag[T].tpe <:< typeTag[AnyVal].tpe
+ ) foreach (assert(_, "assertAnyVal"))
+
+ def assertSameType[T: TypeTag, U: TypeTag] = assert(typeCompare[T, U] == SAME, "assertSameType")
+ def assertSuperType[T: TypeTag, U: TypeTag] = assert(typeCompare[T, U] == SUPER, "assertSuperType")
+ def assertSubType[T: TypeTag, U: TypeTag] = assert(typeCompare[T, U] == SUB, "assertSubType")
+ def assertNoRelationship[T: TypeTag, U: TypeTag] = assert(typeCompare[T, U] == NONE, "assertNoRelationship")
+
+ def testVariancesVia[T: TypeTag, U: TypeTag] = assert(
+ typeCompare[T, U] == SUB &&
+ showsCovariance[T, U, List] &&
+ showsInvariance[T, U, Set],
+ "testVariancesVia"
+ )
+
+ def runAllTests = {
+ assertAnyVal[AnyVal]
+ assertAnyVal[Unit]
+ assertAnyVal[Int]
+ assertAnyVal[Double]
+ assertAnyVal[Boolean]
+ assertAnyVal[Char]
+
+ assertAnyRef[AnyRef]
+ assertAnyRef[java.lang.Object]
+ assertAnyRef[java.lang.Integer]
+ assertAnyRef[java.lang.Double]
+ assertAnyRef[java.lang.Boolean]
+ assertAnyRef[java.lang.Character]
+ assertAnyRef[String]
+ assertAnyRef[scala.List[String]]
+ assertAnyRef[scala.List[_]]
+
+ // variance doesn't work yet
+ // testVariancesVia[String, Any]
+ // testVariancesVia[String, AnyRef]
+
+ assertSubType[List[String], List[Any]]
+ assertSubType[List[String], List[AnyRef]]
+ assertNoRelationship[List[String], List[AnyVal]]
+
+ assertSubType[List[Int], List[Any]]
+ assertSubType[List[Int], List[AnyVal]]
+ assertNoRelationship[List[Int], List[AnyRef]]
+
+ // Nothing
+ assertSubType[Nothing, Any]
+ assertSubType[Nothing, AnyVal]
+ assertSubType[Nothing, AnyRef]
+ assertSubType[Nothing, String]
+ assertSubType[Nothing, List[String]]
+ assertSubType[Nothing, Null]
+ assertSameType[Nothing, Nothing]
+
+ // Null
+ assertSubType[Null, Any]
+ assertNoRelationship[Null, AnyVal]
+ assertSubType[Null, AnyRef]
+ assertSubType[Null, String]
+ assertSubType[Null, List[String]]
+ assertSameType[Null, Null]
+ assertSuperType[Null, Nothing]
+
+ // Any
+ assertSameType[Any, Any]
+ assertSuperType[Any, AnyVal]
+ assertSuperType[Any, AnyRef]
+ assertSuperType[Any, String]
+ assertSuperType[Any, List[String]]
+ assertSuperType[Any, Null]
+ assertSuperType[Any, Nothing]
+
+ // Misc unrelated types
+ assertNoRelationship[Unit, AnyRef]
+ assertNoRelationship[Unit, Int]
+ assertNoRelationship[Int, Long]
+ assertNoRelationship[Boolean, String]
+ assertNoRelationship[List[Boolean], List[String]]
+ assertNoRelationship[Set[Boolean], Set[String]]
+ }
+
+ def main(args: Array[String]): Unit = runAllTests
+}
diff --git a/test/files/run/manifests.scala b/test/files/run/manifests-old.scala
index 6b6ea80b34..621689a254 100644
--- a/test/files/run/manifests.scala
+++ b/test/files/run/manifests-old.scala
@@ -4,15 +4,15 @@ object Test
val CO, IN, CONTRA = Value
}
import Variances.{ CO, IN, CONTRA }
-
+
object SubtypeRelationship extends Enumeration {
val NONE, SAME, SUB, SUPER = Value
}
import SubtypeRelationship.{ NONE, SAME, SUB, SUPER }
-
+
class VarianceTester[T, U, CC[_]](expected: Variances.Value)(
implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) {
-
+
def elements = List(ev1 <:< ev2, ev2 <:< ev1)
def containers = List(ev3 <:< ev4, ev4 <:< ev3)
@@ -20,13 +20,13 @@ object Test
def isSame = typeCompare[T, U] == SAME
def isSub = typeCompare[T, U] == SUB
def isSuper = typeCompare[T, U] == SUPER
-
+
def showsCovariance = (elements == containers)
def showsContravariance = (elements == containers.reverse)
def showsInvariance = containers forall (_ == isSame)
def allContainerVariances = List(showsCovariance, showsInvariance, showsContravariance)
-
+
def showsExpectedVariance =
if (isUnrelated) allContainerVariances forall (_ == false)
else if (isSame) allContainerVariances forall (_ == true)
@@ -36,64 +36,55 @@ object Test
case CONTRA => showsContravariance && !showsCovariance && !showsInvariance
}
}
-
+
def showsCovariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) =
new VarianceTester[T, U, CC](CO) showsExpectedVariance
def showsInvariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) =
new VarianceTester[T, U, CC](IN) showsExpectedVariance
-
+
def showsContravariance[T, U, CC[_]](implicit ev1: Manifest[T], ev2: Manifest[U], ev3: Manifest[CC[T]], ev4: Manifest[CC[U]]) =
new VarianceTester[T, U, CC](CONTRA) showsExpectedVariance
-
- def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[U]) = {
- // checking types as well
- if ((ev1 <:< ev2) != (ev1.tpe <:< ev2.tpe))
- println("Failed! " + ((ev1, ev2)))
-
- if ((ev2 <:< ev1) != (ev2.tpe <:< ev1.tpe))
- println("Failed! " + ((ev2, ev1)))
-
- (ev1 <:< ev2, ev2 <:< ev1) match {
- case (true, true) => SAME
- case (true, false) => SUB
- case (false, true) => SUPER
- case (false, false) => NONE
- }
+
+ def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[U]) = (ev1 <:< ev2, ev2 <:< ev1) match {
+ case (true, true) => SAME
+ case (true, false) => SUB
+ case (false, true) => SUPER
+ case (false, false) => NONE
}
-
+
def assertAnyRef[T: Manifest] = List(
manifest[T] <:< manifest[Any],
manifest[T] <:< manifest[AnyRef],
!(manifest[T] <:< manifest[AnyVal])
) foreach (assert(_, "assertAnyRef"))
-
+
def assertAnyVal[T: Manifest] = List(
manifest[T] <:< manifest[Any],
!(manifest[T] <:< manifest[AnyRef]),
manifest[T] <:< manifest[AnyVal]
) foreach (assert(_, "assertAnyVal"))
-
+
def assertSameType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SAME, "assertSameType")
def assertSuperType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SUPER, "assertSuperType")
def assertSubType[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == SUB, "assertSubType")
def assertNoRelationship[T: Manifest, U: Manifest] = assert(typeCompare[T, U] == NONE, "assertNoRelationship")
-
+
def testVariancesVia[T: Manifest, U: Manifest] = assert(
- typeCompare[T, U] == SUB &&
+ typeCompare[T, U] == SUB &&
showsCovariance[T, U, List] &&
showsInvariance[T, U, Set],
"testVariancesVia"
)
-
+
def runAllTests = {
assertAnyVal[AnyVal]
assertAnyVal[Unit]
- assertAnyVal[Int]
- assertAnyVal[Double]
+ assertAnyVal[Int]
+ assertAnyVal[Double]
assertAnyVal[Boolean]
assertAnyVal[Char]
-
+
assertAnyRef[AnyRef]
assertAnyRef[java.lang.Object]
assertAnyRef[java.lang.Integer]
@@ -103,7 +94,7 @@ object Test
assertAnyRef[String]
assertAnyRef[scala.List[String]]
assertAnyRef[scala.List[_]]
-
+
// variance doesn't work yet
// testVariancesVia[String, Any]
// testVariancesVia[String, AnyRef]
@@ -111,11 +102,11 @@ object Test
assertSubType[List[String], List[Any]]
assertSubType[List[String], List[AnyRef]]
assertNoRelationship[List[String], List[AnyVal]]
-
+
assertSubType[List[Int], List[Any]]
assertSubType[List[Int], List[AnyVal]]
assertNoRelationship[List[Int], List[AnyRef]]
-
+
// Nothing
assertSubType[Nothing, Any]
assertSubType[Nothing, AnyVal]
@@ -124,7 +115,7 @@ object Test
assertSubType[Nothing, List[String]]
assertSubType[Nothing, Null]
assertSameType[Nothing, Nothing]
-
+
// Null
assertSubType[Null, Any]
assertNoRelationship[Null, AnyVal]
@@ -133,7 +124,7 @@ object Test
assertSubType[Null, List[String]]
assertSameType[Null, Null]
assertSuperType[Null, Nothing]
-
+
// Any
assertSameType[Any, Any]
assertSuperType[Any, AnyVal]
@@ -142,7 +133,7 @@ object Test
assertSuperType[Any, List[String]]
assertSuperType[Any, Null]
assertSuperType[Any, Nothing]
-
+
// Misc unrelated types
assertNoRelationship[Unit, AnyRef]
assertNoRelationship[Unit, Int]
@@ -153,4 +144,4 @@ object Test
}
def main(args: Array[String]): Unit = runAllTests
-}
+} \ No newline at end of file
diff --git a/test/files/run/numbereq.scala b/test/files/run/numbereq.scala
index 77a217df36..a1f11da205 100644
--- a/test/files/run/numbereq.scala
+++ b/test/files/run/numbereq.scala
@@ -16,7 +16,20 @@ object Test {
base ::: extras
}
-
+
+ def mkNumbers(x: BigInt): List[AnyRef] = {
+ List(
+ List(BigDecimal(x, java.math.MathContext.UNLIMITED)),
+ List(x),
+ if (x.isValidDouble) List(new java.lang.Double(x.toDouble)) else Nil,
+ if (x.isValidFloat) List(new java.lang.Float(x.toFloat)) else Nil,
+ if (x.isValidLong) List(new java.lang.Long(x.toLong)) else Nil,
+ if (x.isValidInt) List(new java.lang.Integer(x.toInt)) else Nil,
+ if (x.isValidShort) List(new java.lang.Short(x.toShort)) else Nil,
+ if (x.isValidByte) List(new java.lang.Byte(x.toByte)) else Nil,
+ if (x.isValidChar) List(new java.lang.Character(x.toChar)) else Nil
+ ).flatten
+ }
def main(args: Array[String]): Unit = {
val ints = (0 to 15).toList map (Short.MinValue >> _)
@@ -37,5 +50,23 @@ object Test {
assert(x == y, "%s/%s != %s/%s".format(x, x.getClass, y, y.getClass))
assert(x.## == y.##, "%s != %s".format(x.getClass, y.getClass))
}
+
+ val bigInts = (0 to 1024).toList map (BigInt(-1) << _)
+ val bigInts2 = bigInts map (x => -x)
+ val bigInts3 = bigInts map (_ + 1)
+ val bigInts4 = bigInts2 map (_ - 1)
+
+ val setneg1b = bigInts map mkNumbers
+ val setneg2b = bigInts3 map mkNumbers
+ val setpos1b = bigInts2 map mkNumbers
+ val setpos2b = bigInts4 map mkNumbers
+
+ val sets2 = setneg1 ++ setneg1b ++ setneg2 ++ setneg2b ++ List(zero) ++ setpos1 ++ setpos1b ++ setpos2 ++ setpos2b
+
+ for (set <- sets2 ; x <- set ; y <- set) {
+// println("'%s' == '%s' (%s == %s) (%s == %s)".format(x, y, x.hashCode, y.hashCode, x.##, y.##))
+ assert(x == y, "%s/%s != %s/%s".format(x, x.getClass, y, y.getClass))
+// assert(x.## == y.##, "%s != %s".format(x.getClass, y.getClass)) Disable until Double.## is fixed (SI-5640)
+ }
}
-} \ No newline at end of file
+}
diff --git a/test/files/run/option-fold.check b/test/files/run/option-fold.check
new file mode 100644
index 0000000000..4e3fe99f98
--- /dev/null
+++ b/test/files/run/option-fold.check
@@ -0,0 +1,5 @@
+List()
+List(5)
+-1
+0
+1
diff --git a/test/files/run/option-fold.scala b/test/files/run/option-fold.scala
new file mode 100644
index 0000000000..d554ba4f9b
--- /dev/null
+++ b/test/files/run/option-fold.scala
@@ -0,0 +1,19 @@
+object Test {
+ sealed class A
+ case object B extends A
+ case class C(x: Int) extends A
+
+ def f[T](x: Option[T]) = x.fold(List.empty[T])(List(_))
+ def g(x: Option[A]) = x.fold(-1) {
+ case B => 0
+ case C(x) => x
+ }
+
+ def main(args: Array[String]): Unit = {
+ println(f(None))
+ println(f(Some(5)))
+ println(g(None))
+ println(g(Some(B)))
+ println(g(Some(C(1))))
+ }
+}
diff --git a/test/files/run/patmat_unapp_abstype.check b/test/files/run/patmat_unapp_abstype-new.check
index ac28ccdb95..72239d16cd 100644
--- a/test/files/run/patmat_unapp_abstype.check
+++ b/test/files/run/patmat_unapp_abstype-new.check
@@ -1,2 +1,4 @@
TypeRef
none of the above
+Bar
+Foo
diff --git a/test/files/run/patmat_unapp_abstype-new.flags b/test/files/run/patmat_unapp_abstype-new.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/run/patmat_unapp_abstype-new.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/run/patmat_unapp_abstype-new.scala b/test/files/run/patmat_unapp_abstype-new.scala
new file mode 100644
index 0000000000..45496f08a2
--- /dev/null
+++ b/test/files/run/patmat_unapp_abstype-new.scala
@@ -0,0 +1,83 @@
+// abstract types and extractors, oh my!
+trait TypesAPI {
+ trait Type
+
+ // an alternative fix (implemented in the virtual pattern matcher, is to replace the isInstanceOf by a manifest-based run-time test)
+ // that's what typeRefMani is for
+ type TypeRef <: Type //; implicit def typeRefMani: Manifest[TypeRef]
+ val TypeRef: TypeRefExtractor; trait TypeRefExtractor {
+ def apply(x: Int): TypeRef
+ def unapply(x: TypeRef): Option[(Int)]
+ }
+
+ // just for illustration, should follow the same pattern as TypeRef
+ case class MethodType(n: Int) extends Type
+}
+
+// user should not be exposed to the implementation
+trait TypesUser extends TypesAPI {
+ def shouldNotCrash(tp: Type): Unit = {
+ tp match {
+ case TypeRef(x) => println("TypeRef")
+ // the above checks tp.isInstanceOf[TypeRef], which is erased to tp.isInstanceOf[Type]
+ // before calling TypeRef.unapply(tp), which will then crash unless tp.isInstanceOf[TypesImpl#TypeRef] (which is not implied by tp.isInstanceOf[Type])
+ // tp.isInstanceOf[TypesImpl#TypeRef] is equivalent to classOf[TypesImpl#TypeRef].isAssignableFrom(tp.getClass)
+ // this is equivalent to manifest
+ // it is NOT equivalent to manifest[Type] <:< typeRefMani
+ case MethodType(x) => println("MethodType")
+ case _ => println("none of the above")
+ }
+ }
+}
+
+trait TypesImpl extends TypesAPI {
+ object TypeRef extends TypeRefExtractor // this will have a bridged unapply(x: Type) = unapply(x.asInstanceOf[TypeRef])
+ case class TypeRef(n: Int) extends Type // this has a bridge from TypesAPI#Type to TypesImpl#TypeRef
+ // --> the cast in the bridge will fail because the pattern matcher can't type test against the abstract types in TypesUser
+ //lazy val typeRefMani = manifest[TypeRef]
+}
+
+trait Foos {
+ trait Bar
+ type Foo <: Bar
+ trait FooExtractor {
+ def unapply(foo: Foo): Option[Int]
+ }
+ val Foo: FooExtractor
+}
+
+trait RealFoos extends Foos {
+ class Foo(val x: Int) extends Bar
+ object Foo extends FooExtractor {
+ def unapply(foo: Foo): Option[Int] = Some(foo.x)
+ }
+}
+
+trait Intermed extends Foos {
+ def crash(bar: Bar): Unit =
+ bar match {
+ case Foo(x) => println("Foo")
+ case _ => println("Bar")
+ }
+}
+
+object TestUnappStaticallyKnownSynthetic extends TypesImpl with TypesUser {
+ def test() = {
+ shouldNotCrash(TypeRef(10)) // should and does print "TypeRef"
+ // once #1697/#2337 are fixed, this should generate the correct output
+ shouldNotCrash(MethodType(10)) // should print "MethodType" but prints "none of the above" -- good one, pattern matcher!
+ }
+}
+
+object TestUnappDynamicSynth extends RealFoos with Intermed {
+ case class FooToo(n: Int) extends Bar
+ def test() = {
+ crash(FooToo(10))
+ crash(new Foo(5))
+ }
+}
+
+object Test extends App {
+ TestUnappStaticallyKnownSynthetic.test()
+ TestUnappDynamicSynth.test()
+}
diff --git a/test/files/run/patmat_unapp_abstype-old.check b/test/files/run/patmat_unapp_abstype-old.check
new file mode 100644
index 0000000000..72239d16cd
--- /dev/null
+++ b/test/files/run/patmat_unapp_abstype-old.check
@@ -0,0 +1,4 @@
+TypeRef
+none of the above
+Bar
+Foo
diff --git a/test/files/run/patmat_unapp_abstype-old.flags b/test/files/run/patmat_unapp_abstype-old.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/run/patmat_unapp_abstype-old.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/run/patmat_unapp_abstype-old.scala b/test/files/run/patmat_unapp_abstype-old.scala
new file mode 100644
index 0000000000..45496f08a2
--- /dev/null
+++ b/test/files/run/patmat_unapp_abstype-old.scala
@@ -0,0 +1,83 @@
+// abstract types and extractors, oh my!
+trait TypesAPI {
+ trait Type
+
+ // an alternative fix (implemented in the virtual pattern matcher, is to replace the isInstanceOf by a manifest-based run-time test)
+ // that's what typeRefMani is for
+ type TypeRef <: Type //; implicit def typeRefMani: Manifest[TypeRef]
+ val TypeRef: TypeRefExtractor; trait TypeRefExtractor {
+ def apply(x: Int): TypeRef
+ def unapply(x: TypeRef): Option[(Int)]
+ }
+
+ // just for illustration, should follow the same pattern as TypeRef
+ case class MethodType(n: Int) extends Type
+}
+
+// user should not be exposed to the implementation
+trait TypesUser extends TypesAPI {
+ def shouldNotCrash(tp: Type): Unit = {
+ tp match {
+ case TypeRef(x) => println("TypeRef")
+ // the above checks tp.isInstanceOf[TypeRef], which is erased to tp.isInstanceOf[Type]
+ // before calling TypeRef.unapply(tp), which will then crash unless tp.isInstanceOf[TypesImpl#TypeRef] (which is not implied by tp.isInstanceOf[Type])
+ // tp.isInstanceOf[TypesImpl#TypeRef] is equivalent to classOf[TypesImpl#TypeRef].isAssignableFrom(tp.getClass)
+ // this is equivalent to manifest
+ // it is NOT equivalent to manifest[Type] <:< typeRefMani
+ case MethodType(x) => println("MethodType")
+ case _ => println("none of the above")
+ }
+ }
+}
+
+trait TypesImpl extends TypesAPI {
+ object TypeRef extends TypeRefExtractor // this will have a bridged unapply(x: Type) = unapply(x.asInstanceOf[TypeRef])
+ case class TypeRef(n: Int) extends Type // this has a bridge from TypesAPI#Type to TypesImpl#TypeRef
+ // --> the cast in the bridge will fail because the pattern matcher can't type test against the abstract types in TypesUser
+ //lazy val typeRefMani = manifest[TypeRef]
+}
+
+trait Foos {
+ trait Bar
+ type Foo <: Bar
+ trait FooExtractor {
+ def unapply(foo: Foo): Option[Int]
+ }
+ val Foo: FooExtractor
+}
+
+trait RealFoos extends Foos {
+ class Foo(val x: Int) extends Bar
+ object Foo extends FooExtractor {
+ def unapply(foo: Foo): Option[Int] = Some(foo.x)
+ }
+}
+
+trait Intermed extends Foos {
+ def crash(bar: Bar): Unit =
+ bar match {
+ case Foo(x) => println("Foo")
+ case _ => println("Bar")
+ }
+}
+
+object TestUnappStaticallyKnownSynthetic extends TypesImpl with TypesUser {
+ def test() = {
+ shouldNotCrash(TypeRef(10)) // should and does print "TypeRef"
+ // once #1697/#2337 are fixed, this should generate the correct output
+ shouldNotCrash(MethodType(10)) // should print "MethodType" but prints "none of the above" -- good one, pattern matcher!
+ }
+}
+
+object TestUnappDynamicSynth extends RealFoos with Intermed {
+ case class FooToo(n: Int) extends Bar
+ def test() = {
+ crash(FooToo(10))
+ crash(new Foo(5))
+ }
+}
+
+object Test extends App {
+ TestUnappStaticallyKnownSynthetic.test()
+ TestUnappDynamicSynth.test()
+}
diff --git a/test/files/run/patmat_unapp_abstype.scala b/test/files/run/patmat_unapp_abstype.scala
deleted file mode 100644
index e5adec5c16..0000000000
--- a/test/files/run/patmat_unapp_abstype.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-// abstract types and extractors, oh my!
-trait TypesAPI {
- trait Type
-
- // an alternative fix (implemented in the virtual pattern matcher, is to replace the isInstanceOf by a manifest-based run-time test)
- // that's what typeRefMani is for
- type TypeRef <: Type //; implicit def typeRefMani: Manifest[TypeRef]
- val TypeRef: TypeRefExtractor; trait TypeRefExtractor {
- def apply(x: Int): TypeRef
- def unapply(x: TypeRef): Option[(Int)]
- }
-
- // just for illustration, should follow the same pattern as TypeRef
- case class MethodType(n: Int) extends Type
-}
-
-// user should not be exposed to the implementation
-trait TypesUser extends TypesAPI {
- def shouldNotCrash(tp: Type): Unit = {
- tp match {
- case TypeRef(x) => println("TypeRef")
- case MethodType(x) => println("MethodType")
- case _ => println("none of the above")
- }
- }
-}
-
-trait TypesImpl extends TypesAPI {
- object TypeRef extends TypeRefExtractor // this will have a bridged unapply(x: Type) = unapply(x.asInstanceOf[TypeRef])
- case class TypeRef(n: Int) extends Type // this has a bridge from TypesAPI#Type to TypesImpl#TypeRef
- // --> the cast in the bridge will fail because the pattern matcher can't type test against the abstract types in TypesUser
- //lazy val typeRefMani = manifest[TypeRef]
-}
-
-object Test extends TypesImpl with TypesUser with App {
- shouldNotCrash(TypeRef(10)) // should and does print "TypeRef"
- // once #1697/#2337 are fixed, this should generate the correct output
- shouldNotCrash(MethodType(10)) // should print "MethodType" but prints "none of the above" -- good one, pattern matcher!
-} \ No newline at end of file
diff --git a/test/files/run/phantomValueClass.check b/test/files/run/phantomValueClass.check
new file mode 100644
index 0000000000..323fae03f4
--- /dev/null
+++ b/test/files/run/phantomValueClass.check
@@ -0,0 +1 @@
+foobar
diff --git a/test/files/run/phantomValueClass.scala b/test/files/run/phantomValueClass.scala
new file mode 100644
index 0000000000..f6509f2189
--- /dev/null
+++ b/test/files/run/phantomValueClass.scala
@@ -0,0 +1,10 @@
+final class Phantom[A](val s: String) extends AnyVal {
+ def compose(p: Phantom[A]): Phantom[A] = new Phantom[A](s+p.s)
+}
+
+object Test extends App {
+ val x = new Phantom[Int]("foo")
+ val y = new Phantom[Int]("bar")
+ val z = x compose y
+ println(z.s)
+}
diff --git a/test/files/run/primitive-sigs-2-new.check b/test/files/run/primitive-sigs-2-new.check
new file mode 100644
index 0000000000..b82ddbeaff
--- /dev/null
+++ b/test/files/run/primitive-sigs-2-new.check
@@ -0,0 +1,7 @@
+T<java.lang.Object>
+List(A, char, class java.lang.Object)
+a
+public <T> java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.ArrayTag<T>)
+public float[] Arr.arr3(float[][])
+public scala.collection.immutable.List<java.lang.Character> Arr.arr2(java.lang.Character[])
+public scala.collection.immutable.List<java.lang.Object> Arr.arr1(int[])
diff --git a/test/files/run/primitive-sigs-2-new.scala b/test/files/run/primitive-sigs-2-new.scala
new file mode 100644
index 0000000000..7e13014cb2
--- /dev/null
+++ b/test/files/run/primitive-sigs-2-new.scala
@@ -0,0 +1,31 @@
+import java.{ lang => jl }
+
+trait T[A] {
+ def f(): A
+}
+class C extends T[Char] {
+ def f(): Char = 'a'
+}
+class Arr {
+ def arr1(xs: Array[Int]): List[Int] = xs.toList
+ def arr2(xs: Array[jl.Character]): List[jl.Character] = xs.toList
+ def arr3(xss: Array[Array[Float]]): Array[Float] = xss map (_.sum)
+ def arr4[T: ArrayTag](xss: Array[Array[T]]): Array[T] = xss map (_.head)
+}
+
+object Test {
+ val c1: Class[_] = classOf[T[_]]
+ val c2: Class[_] = classOf[C]
+ val c3: Class[_] = classOf[Arr]
+
+ val c1m = c1.getMethods.toList filter (_.getName == "f") map (_.getGenericReturnType.toString)
+ val c2m = c2.getMethods.toList filter (_.getName == "f") map (_.getGenericReturnType.toString)
+ val c3m = c3.getDeclaredMethods.toList map (_.toGenericString)
+
+ def main(args: Array[String]): Unit = {
+ println(c2.getGenericInterfaces.map(_.toString).sorted mkString " ")
+ println(c1m ++ c2m sorted)
+ println(new C f)
+ c3m.sorted foreach println
+ }
+}
diff --git a/test/files/run/primitive-sigs-2.check b/test/files/run/primitive-sigs-2-old.check
index feb0619525..9132b4d8ae 100644
--- a/test/files/run/primitive-sigs-2.check
+++ b/test/files/run/primitive-sigs-2-old.check
@@ -1,7 +1,7 @@
-T<java.lang.Object>
-List(A, char, class java.lang.Object)
-a
-public <T> java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest<T>)
-public float[] Arr.arr3(float[][])
-public scala.collection.immutable.List<java.lang.Character> Arr.arr2(java.lang.Character[])
-public scala.collection.immutable.List<java.lang.Object> Arr.arr1(int[])
+T<java.lang.Object>
+List(A, char, class java.lang.Object)
+a
+public <T> java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest<T>)
+public float[] Arr.arr3(float[][])
+public scala.collection.immutable.List<java.lang.Character> Arr.arr2(java.lang.Character[])
+public scala.collection.immutable.List<java.lang.Object> Arr.arr1(int[])
diff --git a/test/files/run/primitive-sigs-2.scala b/test/files/run/primitive-sigs-2-old.scala
index b7152f7e3d..b7152f7e3d 100644
--- a/test/files/run/primitive-sigs-2.scala
+++ b/test/files/run/primitive-sigs-2-old.scala
diff --git a/test/files/run/reflect-overload.scala b/test/files/run/reflect-overload.scala
new file mode 100644
index 0000000000..af82a1948d
--- /dev/null
+++ b/test/files/run/reflect-overload.scala
@@ -0,0 +1,16 @@
+object Test extends App {
+ import reflect.mirror._
+
+ val s = "hello world"
+ val sc = symbolOfInstance(s)
+ val st = sc.asType
+ val m = st member newTermName("indexOf")
+ val IntType = definitions.IntClass.asType
+ val indexOf = m resolveOverloaded(actuals = List(IntType))
+ assert(invoke(s, indexOf)('w') == 6)
+ assert((invoke(s, indexOf)('w') match { case x: Int => x }) == 6)
+
+ val m2 = st member newTermName("substring")
+ val substring = m2 resolveOverloaded(actuals = List(IntType, IntType))
+ assert(invoke(s, substring)(2, 6) == "llo ")
+}
diff --git a/test/files/run/reflection-implClass-new.scala b/test/files/run/reflection-implClass-new.scala
new file mode 100644
index 0000000000..27374f2106
--- /dev/null
+++ b/test/files/run/reflection-implClass-new.scala
@@ -0,0 +1,38 @@
+/**
+ * Tries to load a symbol for the `Foo$class` using Scala reflection.
+ * Since trait implementation classes do not get pickling information
+ * symbol for them should be created using fallback mechanism
+ * that exposes Java reflection information dressed up in
+ * a Scala symbol.
+ */
+object Test extends App with Outer {
+ import scala.reflect.mirror
+
+ assert(mirror.classToSymbol(classTag[Foo].erasure).typeSignature.declaration(mirror.newTermName("bar")).typeSignature ==
+ mirror.classToSymbol(classTag[Bar].erasure).typeSignature.declaration(mirror.newTermName("foo")).typeSignature)
+
+ val s1 = implClass(classTag[Foo].erasure)
+ assert(s1 != mirror.NoSymbol)
+ assert(s1.typeSignature != mirror.NoType)
+ assert(s1.companionSymbol.typeSignature != mirror.NoType)
+ assert(s1.companionSymbol.typeSignature.declaration(mirror.newTermName("bar")) != mirror.NoSymbol)
+ val s2 = implClass(classTag[Bar].erasure)
+ assert(s2 != mirror.NoSymbol)
+ assert(s2.typeSignature != mirror.NoType)
+ assert(s2.companionSymbol.typeSignature != mirror.NoType)
+ assert(s2.companionSymbol.typeSignature.declaration(mirror.newTermName("foo")) != mirror.NoSymbol)
+ def implClass(clazz: Class[_]) = {
+ val implClass = Class.forName(clazz.getName + "$class")
+ mirror.classToSymbol(implClass)
+ }
+}
+
+trait Foo {
+ def bar = 1
+}
+
+trait Outer {
+ trait Bar {
+ def foo = 1
+ }
+}
diff --git a/test/files/run/reflection-implClass.scala b/test/files/run/reflection-implClass-old.scala
index 7718b52f33..6583624d8b 100644
--- a/test/files/run/reflection-implClass.scala
+++ b/test/files/run/reflection-implClass-old.scala
@@ -1,5 +1,5 @@
-/**
- * Tries to load a symbol for the `Foo$class` using Scala reflection.
+/**
+ * Tries to load a symbol for the `Foo$class` using Scala reflection.
* Since trait implementation classes do not get pickling information
* symbol for them should be created using fallback mechanism
* that exposes Java reflection information dressed up in
diff --git a/test/files/run/reify-repl-fail-gracefully.check b/test/files/run/reify-repl-fail-gracefully.check
new file mode 100644
index 0000000000..680db12667
--- /dev/null
+++ b/test/files/run/reify-repl-fail-gracefully.check
@@ -0,0 +1,21 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import language.experimental.macros
+import language.experimental.macros
+
+scala> import scala.reflect.mirror._
+import scala.reflect.mirror._
+
+scala>
+
+scala> reify
+<console>:12: error: macros cannot be partially applied
+ reify
+ ^
+
+scala>
+
+scala>
diff --git a/test/files/run/reify-repl-fail-gracefully.scala b/test/files/run/reify-repl-fail-gracefully.scala
new file mode 100644
index 0000000000..d7a06e8da8
--- /dev/null
+++ b/test/files/run/reify-repl-fail-gracefully.scala
@@ -0,0 +1,10 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+ |import language.experimental.macros
+ |import scala.reflect.mirror._
+ |
+ |reify
+ """.stripMargin
+}
diff --git a/test/files/run/reify_ann1a.check b/test/files/run/reify_ann1a.check
index 66dce778a8..a3944ae1ee 100644
--- a/test/files/run/reify_ann1a.check
+++ b/test/files/run/reify_ann1a.check
@@ -1,30 +1,30 @@
-{
- @new ann(immutable.this.List.apply[String]("1a")) @new ann(immutable.this.List.apply[String]("1b")) class C[@new ann(immutable.this.List.apply[String]("2a")) @new ann(immutable.this.List.apply[String]("2b")) T] extends scala.AnyRef {
- @new ann(immutable.this.List.apply[String]("3a")) @new ann(immutable.this.List.apply[String]("3b")) <paramaccessor> private[this] val x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b")) = _;
- def <init>(@new ann(immutable.this.List.apply[String]("3a")) @new ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b"))) = {
- super.<init>();
- ()
- };
- @new ann(immutable.this.List.apply[String]("5a")) @new ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = {
- @new ann(immutable.this.List.apply[String]("7a")) @new ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.$plus(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")));
- val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")));
- r.$plus(s)
- }
- };
- ()
-}
-{
- @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends scala.AnyRef {
- @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) <paramaccessor> private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _;
- def <init>(@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = {
- C.super.<init>();
- ()
- };
- @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = {
- @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")));
- val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")));
- r.+(s)
- }
- };
- ()
-}
+{
+ @new ann(immutable.this.List.apply("1a")) @new ann(immutable.this.List.apply("1b")) class C[@new ann(immutable.this.List.apply("2a")) @new ann(immutable.this.List.apply("2b")) T >: Nothing <: Any] extends Object {
+ @new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) <paramaccessor> private[this] val x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b")) = _;
+ def <init>(@new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b"))) = {
+ super.<init>();
+ ()
+ };
+ @new ann(immutable.this.List.apply("5a")) @new ann(immutable.this.List.apply("5b")) def f(x: Int @ann(immutable.this.List.apply("6a")) @ann(immutable.this.List.apply("6b"))) = {
+ @new ann(immutable.this.List.apply("7a")) @new ann(immutable.this.List.apply("7b")) val r = x.$plus(3): @ann(immutable.this.List.apply("8a")): @ann(immutable.this.List.apply("8b"));
+ val s = (4: Int @ann(immutable.this.List.apply("9a")) @ann(immutable.this.List.apply("9b")));
+ r.$plus(s)
+ }
+ };
+ ()
+}
+{
+ @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends Object {
+ @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) <paramaccessor> private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _;
+ def <init>(@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = {
+ C.super.<init>();
+ ()
+ };
+ @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = {
+ @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")));
+ val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")));
+ r.+(s)
+ }
+ };
+ ()
+}
diff --git a/test/files/run/reify_ann1a.scala b/test/files/run/reify_ann1a.scala
index 1ca170904b..1f5d1daccd 100644
--- a/test/files/run/reify_ann1a.scala
+++ b/test/files/run/reify_ann1a.scala
@@ -1,14 +1,10 @@
-import scala.reflect._
-import scala.reflect.api._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
class ann(bar: List[String]) extends StaticAnnotation
object Test extends App {
// test 1: reify
- val tree = scala.reflect.Code.lift{
+ val tree = reify{
@ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) {
@ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = {
@ann(bar=List("7a")) @ann(bar=List("7b")) val r = (x + 3): @ann(bar=List("8a")) @ann(bar=List("8b"))
@@ -20,8 +16,7 @@ object Test extends App {
println(tree.toString)
// test 2: import and typecheck
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val ttree = toolbox.typeCheck(tree)
println(ttree.toString)
diff --git a/test/files/run/reify_ann1b.check b/test/files/run/reify_ann1b.check
index 9bc65a422e..bae838f15f 100644
--- a/test/files/run/reify_ann1b.check
+++ b/test/files/run/reify_ann1b.check
@@ -1,30 +1,30 @@
-{
- @new ann(bar = "1a") @new ann(bar = "1b") class C[@new ann(bar = "2a") @new ann(bar = "2b") T] extends scala.AnyRef {
- @new ann(bar = "3a") @new ann(bar = "3b") <paramaccessor> private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _;
- def <init>(@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = {
- super.<init>();
- ()
- };
- @new ann(bar = "5a") @new ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = {
- @new ann(bar = "7a") @new ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.$plus(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a"));
- val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a"));
- r.$plus(s)
- }
- };
- ()
-}
-{
- @ann(bar = "1a") @ann(bar = "1b") class C[@ann(bar = "2a") @ann(bar = "2b") T] extends scala.AnyRef {
- @ann(bar = "3a") @ann(bar = "3b") <paramaccessor> private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _;
- def <init>(@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = {
- C.super.<init>();
- ()
- };
- @ann(bar = "5a") @ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = {
- @ann(bar = "7a") @ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.+(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a"));
- val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a"));
- r.+(s)
- }
- };
- ()
-}
+{
+ @new ann(bar = "1a") @new ann(bar = "1b") class C[@new ann(bar = "2a") @new ann(bar = "2b") T >: Nothing <: Any] extends Object {
+ @new ann(bar = "3a") @new ann(bar = "3b") <paramaccessor> private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _;
+ def <init>(@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = {
+ super.<init>();
+ ()
+ };
+ @new ann(bar = "5a") @new ann(bar = "5b") def f(x: Int @ann(bar = "6a") @ann(bar = "6b")) = {
+ @new ann(bar = "7a") @new ann(bar = "7b") val r = x.$plus(3): @ann(bar = "8a"): @ann(bar = "8b");
+ val s = (4: Int @ann(bar = "9a") @ann(bar = "9b"));
+ r.$plus(s)
+ }
+ };
+ ()
+}
+{
+ @ann(bar = "1a") @ann(bar = "1b") class C[@ann(bar = "2a") @ann(bar = "2b") T] extends Object {
+ @ann(bar = "3a") @ann(bar = "3b") <paramaccessor> private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _;
+ def <init>(@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = {
+ C.super.<init>();
+ ()
+ };
+ @ann(bar = "5a") @ann(bar = "5b") def f(x: Int @ann(bar = "6b") @ann(bar = "6a")): Int = {
+ @ann(bar = "7a") @ann(bar = "7b") val r: Int @ann(bar = "8b") @ann(bar = "8a") = ((x.+(3): Int @ann(bar = "8a")): Int @ann(bar = "8b") @ann(bar = "8a"));
+ val s: Int @ann(bar = "9b") @ann(bar = "9a") = (4: Int @ann(bar = "9b") @ann(bar = "9a"));
+ r.+(s)
+ }
+ };
+ ()
+}
diff --git a/test/files/run/reify_ann1b.scala b/test/files/run/reify_ann1b.scala
index 9bdc712227..13d861a15c 100644
--- a/test/files/run/reify_ann1b.scala
+++ b/test/files/run/reify_ann1b.scala
@@ -1,14 +1,10 @@
-import scala.reflect._
-import scala.reflect.api._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
class ann(bar: String) extends ClassfileAnnotation
object Test extends App {
// test 1: reify
- val tree = scala.reflect.Code.lift{
+ val tree = reify{
@ann(bar="1a") @ann(bar="1b") class C[@ann(bar="2a") @ann(bar="2b") T](@ann(bar="3a") @ann(bar="3b") x: T @ann(bar="4a") @ann(bar="4b")) {
@ann(bar="5a") @ann(bar="5b") def f(x: Int @ann(bar="6a") @ann(bar="6b")) = {
@ann(bar="7a") @ann(bar="7b") val r = (x + 3): @ann(bar="8a") @ann(bar="8b")
@@ -20,8 +16,7 @@ object Test extends App {
println(tree.toString)
// test 2: import and typecheck
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val ttree = toolbox.typeCheck(tree)
println(ttree.toString)
diff --git a/test/files/run/reify_ann2a.check b/test/files/run/reify_ann2a.check
new file mode 100644
index 0000000000..5022c50ca8
--- /dev/null
+++ b/test/files/run/reify_ann2a.check
@@ -0,0 +1,44 @@
+{
+ class ann extends StaticAnnotation {
+ <paramaccessor> private[this] val bar: List[String] = _;
+ def <init>(bar: List[String]) = {
+ super.<init>();
+ ()
+ }
+ };
+ @new ann(immutable.this.List.apply("1a")) @new ann(immutable.this.List.apply("1b")) class C[@new ann(immutable.this.List.apply("2a")) @new ann(immutable.this.List.apply("2b")) T >: Nothing <: Any] extends Object {
+ @new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) <paramaccessor> private[this] val x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b")) = _;
+ def <init>(@new ann(immutable.this.List.apply("3a")) @new ann(immutable.this.List.apply("3b")) x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b"))) = {
+ super.<init>();
+ ()
+ };
+ @new ann(immutable.this.List.apply("5a")) @new ann(immutable.this.List.apply("5b")) def f(x: Int @ann(immutable.this.List.apply("6a")) @ann(immutable.this.List.apply("6b"))) = {
+ @new ann(immutable.this.List.apply("7a")) @new ann(immutable.this.List.apply("7b")) val r = x.$plus(3): @ann(immutable.this.List.apply("8a")): @ann(immutable.this.List.apply("8b"));
+ val s = (4: Int @ann(immutable.this.List.apply("9a")) @ann(immutable.this.List.apply("9b")));
+ r.$plus(s)
+ }
+ };
+ ()
+}
+{
+ class ann extends scala.annotation.Annotation with scala.annotation.StaticAnnotation {
+ <paramaccessor> private[this] val bar: List[String] = _;
+ def <init>(bar: List[String]): ann = {
+ ann.super.<init>();
+ ()
+ }
+ };
+ @ann(immutable.this.List.apply[String]("1a")) @ann(immutable.this.List.apply[String]("1b")) class C[@ann(immutable.this.List.apply[String]("2a")) @ann(immutable.this.List.apply[String]("2b")) T] extends Object {
+ @ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) <paramaccessor> private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _;
+ def <init>(@ann(immutable.this.List.apply[String]("3a")) @ann(immutable.this.List.apply[String]("3b")) x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a"))): C[T] = {
+ C.super.<init>();
+ ()
+ };
+ @ann(immutable.this.List.apply[String]("5a")) @ann(immutable.this.List.apply[String]("5b")) def f(x: Int @ann(immutable.this.List.apply[String]("6b")) @ann(immutable.this.List.apply[String]("6a"))): Int = {
+ @ann(immutable.this.List.apply[String]("7a")) @ann(immutable.this.List.apply[String]("7b")) val r: Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")) = ((x.+(3): Int @ann(immutable.this.List.apply[String]("8a"))): Int @ann(immutable.this.List.apply[String]("8b")) @ann(immutable.this.List.apply[String]("8a")));
+ val s: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")) = (4: Int @ann(immutable.this.List.apply[String]("9b")) @ann(immutable.this.List.apply[String]("9a")));
+ r.+(s)
+ }
+ };
+ ()
+}
diff --git a/test/files/neg/reify_ann2a.scala b/test/files/run/reify_ann2a.scala
index 8de0984074..370abadba0 100644
--- a/test/files/neg/reify_ann2a.scala
+++ b/test/files/run/reify_ann2a.scala
@@ -1,12 +1,8 @@
-import scala.reflect._
-import scala.reflect.api._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
// test 1: reify
- val tree = scala.reflect.Code.lift{
+ val tree = reify{
class ann(bar: List[String]) extends StaticAnnotation
@ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) {
@@ -20,8 +16,7 @@ object Test extends App {
println(tree.toString)
// test 2: import and typecheck
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val ttree = toolbox.typeCheck(tree)
println(ttree.toString)
diff --git a/test/files/run/reify_ann3.check b/test/files/run/reify_ann3.check
new file mode 100644
index 0000000000..9452a9701e
--- /dev/null
+++ b/test/files/run/reify_ann3.check
@@ -0,0 +1,21 @@
+{
+ class Tree[A >: Nothing <: Any, B >: Nothing <: Any] extends Object {
+ @new inline @getter() final <paramaccessor> val key: A = _;
+ def <init>(key: A) = {
+ super.<init>();
+ ()
+ }
+ };
+ ()
+}
+{
+ class Tree[A, B] extends Object {
+ final <paramaccessor> private[this] val key: A = _;
+ @inline @scala.annotation.meta.getter final <stable> <accessor> <paramaccessor> def key: A = Tree.this.key;
+ def <init>(key: A): Tree[A,B] = {
+ Tree.super.<init>();
+ ()
+ }
+ };
+ ()
+}
diff --git a/test/files/run/reify_ann3.scala b/test/files/run/reify_ann3.scala
new file mode 100644
index 0000000000..d65e641619
--- /dev/null
+++ b/test/files/run/reify_ann3.scala
@@ -0,0 +1,19 @@
+import scala.reflect.mirror._
+import scala.annotation._
+import scala.annotation.meta._
+
+object Test extends App {
+ // test 1: reify
+ val tree = reify{
+ class Tree[A, +B](@(inline @getter) final val key: A)
+ }.tree
+ println(tree.toString)
+
+ // test 2: import and typecheck
+ val toolbox = mkToolBox()
+ val ttree = toolbox.typeCheck(tree)
+ println(ttree.toString)
+
+ // test 3: import and compile
+ toolbox.runExpr(tree)
+}
diff --git a/test/files/run/reify_ann4.check b/test/files/run/reify_ann4.check
new file mode 100644
index 0000000000..406ee7bc08
--- /dev/null
+++ b/test/files/run/reify_ann4.check
@@ -0,0 +1,32 @@
+{
+ class D extends StaticAnnotation {
+ def <init>() = {
+ super.<init>();
+ ()
+ }
+ };
+ class C extends Object {
+ def <init>() = {
+ super.<init>();
+ ()
+ }
+ };
+ val c1 = new C @D();
+ ()
+}
+{
+ class D extends scala.annotation.Annotation with scala.annotation.StaticAnnotation {
+ def <init>(): D = {
+ D.super.<init>();
+ ()
+ }
+ };
+ class C extends Object {
+ def <init>(): C = {
+ C.super.<init>();
+ ()
+ }
+ };
+ val c1: C = new C @D();
+ ()
+}
diff --git a/test/files/run/reify_ann4.scala b/test/files/run/reify_ann4.scala
new file mode 100644
index 0000000000..5655812689
--- /dev/null
+++ b/test/files/run/reify_ann4.scala
@@ -0,0 +1,23 @@
+import scala.reflect.mirror._
+import scala.annotation._
+import scala.annotation.meta._
+
+object Test extends App {
+ // test 1: reify
+ val tree = reify{
+ class D extends StaticAnnotation
+ class C
+ val c1 = new C @D
+ //val c2 = (new C) @D // illegal syntax
+ //val c3 = c1 @D // illegal syntax
+ }.tree
+ println(tree.toString)
+
+ // test 2: import and typecheck
+ val toolbox = mkToolBox()
+ val ttree = toolbox.typeCheck(tree)
+ println(ttree.toString)
+
+ // test 3: import and compile
+ toolbox.runExpr(tree)
+}
diff --git a/test/files/run/reify_ann5.check b/test/files/run/reify_ann5.check
new file mode 100644
index 0000000000..ecf08eebb2
--- /dev/null
+++ b/test/files/run/reify_ann5.check
@@ -0,0 +1,22 @@
+{
+ class C extends Object {
+ @new inline @beanGetter() @new BeanProperty() <paramaccessor> val x: Int = _;
+ def <init>(x: Int) = {
+ super.<init>();
+ ()
+ }
+ };
+ ()
+}
+{
+ class C extends Object {
+ @scala.beans.BeanProperty <paramaccessor> private[this] val x: Int = _;
+ <stable> <accessor> <paramaccessor> def x: Int = C.this.x;
+ def <init>(x: Int): C = {
+ C.super.<init>();
+ ()
+ };
+ @inline @scala.annotation.meta.beanGetter def getX(): Int = C.this.x
+ };
+ ()
+}
diff --git a/test/files/run/reify_ann5.scala b/test/files/run/reify_ann5.scala
new file mode 100644
index 0000000000..aecc61de46
--- /dev/null
+++ b/test/files/run/reify_ann5.scala
@@ -0,0 +1,20 @@
+import scala.reflect.mirror._
+import scala.annotation._
+import scala.annotation.meta._
+import scala.beans._
+
+object Test extends App {
+ // test 1: reify
+ val tree = reify{
+ class C(@BeanProperty @(inline @beanGetter) val x: Int)
+ }.tree
+ println(tree.toString)
+
+ // test 2: import and typecheck
+ val toolbox = mkToolBox()
+ val ttree = toolbox.typeCheck(tree)
+ println(ttree.toString)
+
+ // test 3: import and compile
+ toolbox.runExpr(tree)
+}
diff --git a/test/files/run/reify_anonymous.scala b/test/files/run/reify_anonymous.scala
index af16f2f8fd..cd740f0190 100644
--- a/test/files/run/reify_anonymous.scala
+++ b/test/files/run/reify_anonymous.scala
@@ -1,13 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
println(new {def x = 2; def y = x * x}.y)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_classfileann_a.check b/test/files/run/reify_classfileann_a.check
index 419d916907..685ecf5de6 100644
--- a/test/files/run/reify_classfileann_a.check
+++ b/test/files/run/reify_classfileann_a.check
@@ -1,18 +1,18 @@
-{
- @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends scala.AnyRef {
- def <init>() = {
- super.<init>();
- ()
- }
- };
- ()
-}
-{
- @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends scala.AnyRef {
- def <init>(): C = {
- C.super.<init>();
- ()
- }
- };
- ()
-}
+{
+ @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends Object {
+ def <init>() = {
+ super.<init>();
+ ()
+ }
+ };
+ ()
+}
+{
+ @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends Object {
+ def <init>(): C = {
+ C.super.<init>();
+ ()
+ }
+ };
+ ()
+}
diff --git a/test/files/run/reify_classfileann_a.scala b/test/files/run/reify_classfileann_a.scala
index c77bd3b8a2..c3e7d8d2e9 100644
--- a/test/files/run/reify_classfileann_a.scala
+++ b/test/files/run/reify_classfileann_a.scala
@@ -1,21 +1,16 @@
-import scala.reflect._
-import scala.reflect.api._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation
object Test extends App {
// test 1: reify
- val tree = scala.reflect.Code.lift{
+ val tree = reify{
@ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) class C
}.tree
println(tree.toString)
// test 2: import and typecheck
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val ttree = toolbox.typeCheck(tree)
println(ttree.toString)
diff --git a/test/files/run/reify_classfileann_b.check b/test/files/run/reify_classfileann_b.check
new file mode 100644
index 0000000000..0aac9aeb2a
--- /dev/null
+++ b/test/files/run/reify_classfileann_b.check
@@ -0,0 +1,20 @@
+{
+ class C extends Object {
+ def <init>() = {
+ super.<init>();
+ ()
+ };
+ def x: Int = 2: @ann(bar = "1",quux = Array("2", "3"),baz = new ann(bar = "4"))
+ };
+ ()
+}
+{
+ class C extends Object {
+ def <init>(): C = {
+ C.super.<init>();
+ ()
+ };
+ def x: Int = (2: Int(2) @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")))
+ };
+ ()
+}
diff --git a/test/pending/run/reify_classfileann_b.scala b/test/files/run/reify_classfileann_b.scala
index c31826377a..4e50494af3 100644
--- a/test/pending/run/reify_classfileann_b.scala
+++ b/test/files/run/reify_classfileann_b.scala
@@ -1,14 +1,10 @@
-import scala.reflect._
-import scala.reflect.api._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation
object Test extends App {
// test 1: reify
- val tree = scala.reflect.Code.lift{
+ val tree = reify{
class C {
def x: Int = {
2: @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4"))
@@ -17,8 +13,11 @@ object Test extends App {
}.tree
println(tree.toString)
- // test 2: import and compile
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ // test 2: import and typecheck
+ val toolbox = mkToolBox()
+ val ttree = toolbox.typeCheck(tree)
+ println(ttree.toString)
+
+ // test 3: import and compile
toolbox.runExpr(tree)
} \ No newline at end of file
diff --git a/test/files/run/reify_closure1.scala b/test/files/run/reify_closure1.scala
index 7cb3aff17d..3f5c8a8724 100644
--- a/test/files/run/reify_closure1.scala
+++ b/test/files/run/reify_closure1.scala
@@ -1,15 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
def foo[T](ys: List[T]): Int => Int = {
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reify{(x: Int) => {
x
}}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(fun.tree)
dyn.asInstanceOf[Int => Int]
}
diff --git a/test/files/run/reify_closure2a.scala b/test/files/run/reify_closure2a.scala
index cf367aa63f..f5669a0e2c 100644
--- a/test/files/run/reify_closure2a.scala
+++ b/test/files/run/reify_closure2a.scala
@@ -1,15 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
def foo(y: Int): Int => Int = {
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reify{(x: Int) => {
x + y
}}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(fun.tree)
dyn.asInstanceOf[Int => Int]
}
diff --git a/test/files/run/reify_closure3a.scala b/test/files/run/reify_closure3a.scala
index d322b970b6..056a705d7d 100644
--- a/test/files/run/reify_closure3a.scala
+++ b/test/files/run/reify_closure3a.scala
@@ -1,17 +1,14 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
def foo(y: Int): Int => Int = {
def y1 = y
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reify{(x: Int) => {
x + y1
}}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(fun.tree)
dyn.asInstanceOf[Int => Int]
}
diff --git a/test/files/run/reify_closure4a.scala b/test/files/run/reify_closure4a.scala
index bbedd7e092..a63d20e561 100644
--- a/test/files/run/reify_closure4a.scala
+++ b/test/files/run/reify_closure4a.scala
@@ -1,17 +1,14 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
def foo(y: Int): Int => Int = {
val y1 = y
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reify{(x: Int) => {
x + y1
}}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(fun.tree)
dyn.asInstanceOf[Int => Int]
}
diff --git a/test/files/run/reify_closure5a.scala b/test/files/run/reify_closure5a.scala
index 193e18103a..2e8b413f4c 100644
--- a/test/files/run/reify_closure5a.scala
+++ b/test/files/run/reify_closure5a.scala
@@ -1,19 +1,18 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- def foo[T](ys: List[T]): Int => Int = {
- val fun = reflect.Code.lift{(x: Int) => {
+ def foo[T: TypeTag](ys: List[T]): Int => Int = {
+ val fun = reify{(x: Int) => {
x + ys.length
}}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(fun.tree)
dyn.asInstanceOf[Int => Int]
}
- println(foo(List(1, 2, 3))(10))
- println(foo(List(1, 2, 3, 4))(10))
+ var fun1 = foo(List(1, 2, 3))
+ println(fun1(10))
+ var fun2 = foo(List(1, 2, 3, 4))
+ println(fun2(10))
}
diff --git a/test/files/run/reify_closure6.scala b/test/files/run/reify_closure6.scala
index 6aff83cb94..2cbd4ce819 100644
--- a/test/files/run/reify_closure6.scala
+++ b/test/files/run/reify_closure6.scala
@@ -1,13 +1,11 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
var q = 0
- def foo[T](ys: List[T]): Int => Int = {
+ def foo[T: TypeTag](ys: List[T]): Int => Int = {
val z = 1
var y = 0
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reify{(x: Int) => {
y += 1
q += 1
println("q = " + q)
@@ -15,13 +13,14 @@ object Test extends App {
x + ys.length * z + q + y
}}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(fun.tree)
dyn.asInstanceOf[Int => Int]
}
- println("first invocation = " + foo(List(1, 2, 3))(10))
- println("second invocation = " + foo(List(1, 2, 3, 4))(10))
+ val fun1 = foo(List(1, 2, 3))
+ println("first invocation = " + fun1(10))
+ val fun2 = foo(List(1, 2, 3, 4))
+ println("second invocation = " + fun2(10))
println("q after second invocation = " + q)
} \ No newline at end of file
diff --git a/test/files/run/reify_closure7.scala b/test/files/run/reify_closure7.scala
index 46002d8d6c..b9f87dbdeb 100644
--- a/test/files/run/reify_closure7.scala
+++ b/test/files/run/reify_closure7.scala
@@ -1,14 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
var q = 0
var clo: Int => Int = null
- def foo[T](ys: List[T]): Int => Int = {
+ def foo[T: TypeTag](ys: List[T]): Int => Int = {
val z = 1
var y = 0
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reify{(x: Int) => {
y += 1
q += 1
println("q = " + q)
@@ -17,8 +15,7 @@ object Test extends App {
}}
if (clo == null) {
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(fun.tree)
clo = dyn.asInstanceOf[Int => Int]
}
@@ -26,6 +23,8 @@ object Test extends App {
clo
}
- println("first invocation = " + foo(List(1, 2, 3))(10))
- println("second invocation = " + foo(List(1, 2, 3, 4))(10))
+ val fun1 = foo(List(1, 2, 3))
+ println("first invocation = " + fun1(10))
+ val fun2 = foo(List(1, 2, 3, 4))
+ println("second invocation = " + fun2(10))
}
diff --git a/test/files/run/reify_closure8a.scala b/test/files/run/reify_closure8a.scala
index 805d8ff855..9de121b42f 100644
--- a/test/files/run/reify_closure8a.scala
+++ b/test/files/run/reify_closure8a.scala
@@ -1,15 +1,11 @@
-import scala.reflect.Code._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
class Foo(val y: Int) {
- def fun = lift{y}
+ def fun = reify{y}
}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(new Foo(10).fun.tree)
val foo = dyn.asInstanceOf[Int]
println(foo)
diff --git a/test/files/run/reify_closure8b.check b/test/files/run/reify_closure8b.check
new file mode 100644
index 0000000000..e0ec7d2c8f
--- /dev/null
+++ b/test/files/run/reify_closure8b.check
@@ -0,0 +1,3 @@
+scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective compilation has failed:
+
+value y is not a member of Test.Foo
diff --git a/test/files/run/reify_closure8b.scala b/test/files/run/reify_closure8b.scala
new file mode 100644
index 0000000000..431da3230e
--- /dev/null
+++ b/test/files/run/reify_closure8b.scala
@@ -0,0 +1,18 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ // will fail because y is a private field
+ // reification doesn't magically make unavailable stuff available
+ class Foo(y: Int) {
+ def fun = reify{y}
+ }
+
+ try {
+ val dyn = mkToolBox().runExpr(new Foo(10).fun.tree)
+ val foo = dyn.asInstanceOf[Int]
+ println(foo)
+ } catch {
+ case ex: Throwable =>
+ println(ex)
+ }
+}
diff --git a/test/files/run/reify_closures10.scala b/test/files/run/reify_closures10.scala
index b6ec8e8911..0ccce77a94 100644
--- a/test/files/run/reify_closures10.scala
+++ b/test/files/run/reify_closures10.scala
@@ -1,14 +1,10 @@
-import scala.reflect.Code._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
val x = 2
val y = 3
- val code = lift{println(x + y); x + y}
+ val code = reify{println(x + y); x + y}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
println(toolbox.runExpr(code.tree))
}
diff --git a/test/files/run/reify_complex.scala b/test/files/run/reify_complex.scala
index 0d9aeb28c5..ecc25ffca5 100644
--- a/test/files/run/reify_complex.scala
+++ b/test/files/run/reify_complex.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class Complex(val re: Double, val im: Double) {
def + (that: Complex) =
new Complex(re + that.re, im + that.im)
@@ -22,9 +20,5 @@ object Test extends App {
}
val x = new Complex(2, 1); val y = new Complex(1, 3)
println(x + y)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_extendbuiltins.scala b/test/files/run/reify_extendbuiltins.scala
index 0aaec7cdf2..f95e9ab6ec 100644
--- a/test/files/run/reify_extendbuiltins.scala
+++ b/test/files/run/reify_extendbuiltins.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
def fact(n: Int): BigInt =
if (n == 0) 1 else fact(n-1) * n
class Factorizer(n: Int) {
@@ -12,9 +10,5 @@ object Test extends App {
implicit def int2fact(n: Int) = new Factorizer(n)
println("10! = " + (10!))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_for1.scala b/test/files/run/reify_for1.scala
index d1b60d878b..9d1e32f7e5 100644
--- a/test/files/run/reify_for1.scala
+++ b/test/files/run/reify_for1.scala
@@ -1,15 +1,9 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
val sumOfSquares1 = (for (i <- 1 to 100; if (i % 3 == 0)) yield Math.pow(i, 2)).sum
val sumOfSquares2 = (1 to 100).filter(_ % 3 == 0).map(Math.pow(_, 2)).sum
assert(sumOfSquares1 == sumOfSquares2)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_fors.flags b/test/files/run/reify_fors.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/run/reify_fors.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/run/reify_fors.scala b/test/files/run/reify_fors.scala
index 27ee85d18b..635fce049e 100644
--- a/test/files/run/reify_fors.scala
+++ b/test/files/run/reify_fors.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
object Persons {
/** A list of persons. To create a list, we use Predef.List
* which takes a variable number of arguments and constructs
@@ -98,9 +96,5 @@ object Test extends App {
val ys = List(2.0, 1.0, 3.0)
println("scalProd(" + xs + ", " + ys +") = " + scalProd(xs, ys))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_generic.scala b/test/files/run/reify_generic.scala
index 6a4ff148c4..7033c4e237 100644
--- a/test/files/run/reify_generic.scala
+++ b/test/files/run/reify_generic.scala
@@ -1,14 +1,8 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
val product = List(1, 2, 3).head * List[Any](4, 2, 0).head.asInstanceOf[Int]
println(product)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_generic2.scala b/test/files/run/reify_generic2.scala
index 9413f41eb5..8f9def318e 100644
--- a/test/files/run/reify_generic2.scala
+++ b/test/files/run/reify_generic2.scala
@@ -1,15 +1,9 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class C
val product = List(new C, new C).length * List[C](new C, new C).length
println(product)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_getter.scala b/test/files/run/reify_getter.scala
index 33f36888a7..8bae293e72 100644
--- a/test/files/run/reify_getter.scala
+++ b/test/files/run/reify_getter.scala
@@ -1,18 +1,15 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
class C {
val x = 2
}
new C().x
- };
+ }
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val evaluated = toolbox.runExpr(code.tree)
println("evaluated = " + evaluated)
}
diff --git a/test/files/run/reify_implicits.check b/test/files/run/reify_implicits-new.check
index e3aeb20f6b..e3aeb20f6b 100644
--- a/test/files/run/reify_implicits.check
+++ b/test/files/run/reify_implicits-new.check
diff --git a/test/files/run/reify_implicits-new.scala b/test/files/run/reify_implicits-new.scala
new file mode 100644
index 0000000000..69198391d1
--- /dev/null
+++ b/test/files/run/reify_implicits-new.scala
@@ -0,0 +1,14 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ reify {
+ implicit def arrayWrapper[A : ArrayTag](x: Array[A]) =
+ new {
+ def sort(p: (A, A) => Boolean) = {
+ util.Sorting.stableSort(x, p); x
+ }
+ }
+ val x = Array(2, 3, 1, 4)
+ println("x = "+ x.sort((x: Int, y: Int) => x < y).toList)
+ }.eval
+}
diff --git a/test/files/run/reify_implicits-old.check b/test/files/run/reify_implicits-old.check
new file mode 100644
index 0000000000..e3aeb20f6b
--- /dev/null
+++ b/test/files/run/reify_implicits-old.check
@@ -0,0 +1 @@
+x = List(1, 2, 3, 4)
diff --git a/test/files/run/reify_implicits.scala b/test/files/run/reify_implicits-old.scala
index 953eabe6c2..60971c3cfb 100644
--- a/test/files/run/reify_implicits.scala
+++ b/test/files/run/reify_implicits-old.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
implicit def arrayWrapper[A : ClassManifest](x: Array[A]) =
new {
def sort(p: (A, A) => Boolean) = {
@@ -12,9 +10,5 @@ object Test extends App {
}
val x = Array(2, 3, 1, 4)
println("x = "+ x.sort((x: Int, y: Int) => x < y).toList)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_inheritance.scala b/test/files/run/reify_inheritance.scala
index 78a64c264e..dd86c355a3 100644
--- a/test/files/run/reify_inheritance.scala
+++ b/test/files/run/reify_inheritance.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class C {
def x = 2
def y = x * x
@@ -14,9 +12,5 @@ object Test extends App {
}
println(new D().y * new C().x)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_inner1.scala b/test/files/run/reify_inner1.scala
index 546fe36d16..ea77ece6df 100644
--- a/test/files/run/reify_inner1.scala
+++ b/test/files/run/reify_inner1.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class C {
class D {
val x = 2
@@ -13,9 +11,5 @@ object Test extends App {
val outer = new C()
val inner = new outer.D()
println(inner.x)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_inner2.scala b/test/files/run/reify_inner2.scala
index 613614b989..67c403f7e5 100644
--- a/test/files/run/reify_inner2.scala
+++ b/test/files/run/reify_inner2.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class C {
object D {
val x = 2
@@ -13,9 +11,5 @@ object Test extends App {
val outer = new C()
val inner = outer.D
println(inner.x)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_inner3.scala b/test/files/run/reify_inner3.scala
index e9fb636dce..ad401d81da 100644
--- a/test/files/run/reify_inner3.scala
+++ b/test/files/run/reify_inner3.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
object C {
class D {
val x = 2
@@ -13,9 +11,5 @@ object Test extends App {
val outer = C
val inner = new outer.D
println(inner.x)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_inner4.scala b/test/files/run/reify_inner4.scala
index 33870b0983..140c8e9ed4 100644
--- a/test/files/run/reify_inner4.scala
+++ b/test/files/run/reify_inner4.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
object C {
object D {
val x = 2
@@ -13,9 +11,5 @@ object Test extends App {
val outer = C
val inner = outer.D
println(inner.x)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_maps.flags b/test/files/run/reify_maps.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/run/reify_maps.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/run/reify_maps.scala b/test/files/run/reify_maps.scala
index d3d95ffa24..3fcc21892f 100644
--- a/test/files/run/reify_maps.scala
+++ b/test/files/run/reify_maps.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
val colors = Map("red" -> 0xFF0000,
"turquoise" -> 0x00FFFF,
"black" -> 0x000000,
@@ -17,9 +15,5 @@ object Test extends App {
"Unknown color: " + name
}
)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_metalevel_breach_+0_refers_to_1.check b/test/files/run/reify_metalevel_breach_+0_refers_to_1.check
new file mode 100644
index 0000000000..5bfed17f8e
--- /dev/null
+++ b/test/files/run/reify_metalevel_breach_+0_refers_to_1.check
@@ -0,0 +1 @@
+evaluated = 2 \ No newline at end of file
diff --git a/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala b/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala
new file mode 100644
index 0000000000..fe23bc8438
--- /dev/null
+++ b/test/files/run/reify_metalevel_breach_+0_refers_to_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val code = reify{
+ val x = 2
+ val inner = reify{x}
+ inner.eval
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check
new file mode 100644
index 0000000000..5bfed17f8e
--- /dev/null
+++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check
@@ -0,0 +1 @@
+evaluated = 2 \ No newline at end of file
diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala
new file mode 100644
index 0000000000..5d98a38592
--- /dev/null
+++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala
@@ -0,0 +1,11 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val x = 2
+ val outer = reify{reify{x}}
+ val code = reify{outer.eval.eval}
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check
new file mode 100644
index 0000000000..5bfed17f8e
--- /dev/null
+++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check
@@ -0,0 +1 @@
+evaluated = 2 \ No newline at end of file
diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala
new file mode 100644
index 0000000000..ca31d83acd
--- /dev/null
+++ b/test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val x = 2
+ val code = reify{
+ {
+ val inner = reify{reify{x}}
+ inner.eval
+ }.eval
+ }
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_1.check b/test/files/run/reify_metalevel_breach_-1_refers_to_1.check
new file mode 100644
index 0000000000..5bfed17f8e
--- /dev/null
+++ b/test/files/run/reify_metalevel_breach_-1_refers_to_1.check
@@ -0,0 +1 @@
+evaluated = 2 \ No newline at end of file
diff --git a/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala b/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala
new file mode 100644
index 0000000000..56d85c6ba1
--- /dev/null
+++ b/test/files/run/reify_metalevel_breach_-1_refers_to_1.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val code = reify{
+ val x = 2
+ val inner = reify{reify{x}}
+ inner.eval.eval
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_nested_inner_refers_to_global.check b/test/files/run/reify_nested_inner_refers_to_global.check
new file mode 100644
index 0000000000..7ff4c83d37
--- /dev/null
+++ b/test/files/run/reify_nested_inner_refers_to_global.check
@@ -0,0 +1 @@
+evaluated = 2
diff --git a/test/files/run/reify_nested_inner_refers_to_global.scala b/test/files/run/reify_nested_inner_refers_to_global.scala
new file mode 100644
index 0000000000..14899bcf99
--- /dev/null
+++ b/test/files/run/reify_nested_inner_refers_to_global.scala
@@ -0,0 +1,14 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val code = {
+ val x = 2
+ reify{
+ reify{x}.eval
+ }
+ }
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_nested_inner_refers_to_local.check b/test/files/run/reify_nested_inner_refers_to_local.check
new file mode 100644
index 0000000000..5bfed17f8e
--- /dev/null
+++ b/test/files/run/reify_nested_inner_refers_to_local.check
@@ -0,0 +1 @@
+evaluated = 2 \ No newline at end of file
diff --git a/test/files/run/reify_nested_inner_refers_to_local.scala b/test/files/run/reify_nested_inner_refers_to_local.scala
new file mode 100644
index 0000000000..fd56585f72
--- /dev/null
+++ b/test/files/run/reify_nested_inner_refers_to_local.scala
@@ -0,0 +1,12 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val code = reify{
+ val x = 2
+ reify{x}.eval
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_nested_outer_refers_to_global.check b/test/files/run/reify_nested_outer_refers_to_global.check
new file mode 100644
index 0000000000..7ff4c83d37
--- /dev/null
+++ b/test/files/run/reify_nested_outer_refers_to_global.check
@@ -0,0 +1 @@
+evaluated = 2
diff --git a/test/files/run/reify_nested_outer_refers_to_global.scala b/test/files/run/reify_nested_outer_refers_to_global.scala
new file mode 100644
index 0000000000..f34e4fe04b
--- /dev/null
+++ b/test/files/run/reify_nested_outer_refers_to_global.scala
@@ -0,0 +1,16 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val code = {
+ val x = 2
+ val outer = reify{x}
+ reify{
+ val x = 42
+ outer.eval
+ };
+ }
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_nested_outer_refers_to_local.check b/test/files/run/reify_nested_outer_refers_to_local.check
new file mode 100644
index 0000000000..7ff4c83d37
--- /dev/null
+++ b/test/files/run/reify_nested_outer_refers_to_local.check
@@ -0,0 +1 @@
+evaluated = 2
diff --git a/test/files/run/reify_nested_outer_refers_to_local.scala b/test/files/run/reify_nested_outer_refers_to_local.scala
new file mode 100644
index 0000000000..e16c851d8d
--- /dev/null
+++ b/test/files/run/reify_nested_outer_refers_to_local.scala
@@ -0,0 +1,16 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val outer = {
+ val x = 2
+ reify{x}
+ }
+ val code = reify{
+ val x = 42
+ outer.eval
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_newimpl_01.check b/test/files/run/reify_newimpl_01.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_newimpl_01.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_01.scala b/test/files/run/reify_newimpl_01.scala
new file mode 100644
index 0000000000..f7539a15b0
--- /dev/null
+++ b/test/files/run/reify_newimpl_01.scala
@@ -0,0 +1,11 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val x = 2
+ val code = reify {
+ x
+ }
+ println(code.eval)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_02.check b/test/files/run/reify_newimpl_02.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_newimpl_02.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_02.scala b/test/files/run/reify_newimpl_02.scala
new file mode 100644
index 0000000000..2c085efa04
--- /dev/null
+++ b/test/files/run/reify_newimpl_02.scala
@@ -0,0 +1,11 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var x = 2
+ val code = reify {
+ x
+ }
+ println(code.eval)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_03.check b/test/files/run/reify_newimpl_03.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_newimpl_03.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_03.scala b/test/files/run/reify_newimpl_03.scala
new file mode 100644
index 0000000000..361cfc50bb
--- /dev/null
+++ b/test/files/run/reify_newimpl_03.scala
@@ -0,0 +1,11 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val code = reify {
+ val x = 2
+ reify{x}.eval
+ }
+ println(code.eval)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_04.check b/test/files/run/reify_newimpl_04.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_newimpl_04.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_04.scala b/test/files/run/reify_newimpl_04.scala
new file mode 100644
index 0000000000..d80a7c9ffd
--- /dev/null
+++ b/test/files/run/reify_newimpl_04.scala
@@ -0,0 +1,11 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val code = reify {
+ var x = 2
+ reify{x}.eval
+ }
+ println(code.eval)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_05.check b/test/files/run/reify_newimpl_05.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_newimpl_05.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_05.scala b/test/files/run/reify_newimpl_05.scala
new file mode 100644
index 0000000000..85c1711bdb
--- /dev/null
+++ b/test/files/run/reify_newimpl_05.scala
@@ -0,0 +1,12 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val code = reify {
+ var x = 2
+ def y = x // forcibly captures x
+ reify{x}.eval
+ }
+ println(code.eval)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_06.check b/test/files/run/reify_newimpl_06.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_newimpl_06.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_06.scala b/test/files/run/reify_newimpl_06.scala
new file mode 100644
index 0000000000..257b54167a
--- /dev/null
+++ b/test/files/run/reify_newimpl_06.scala
@@ -0,0 +1,11 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C(val y: Int) {
+ val code = reify {
+ reify{y}.eval
+ }
+ }
+
+ println(new C(2).code.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_09.check b/test/files/run/reify_newimpl_09.check
new file mode 100644
index 0000000000..220bd6875a
--- /dev/null
+++ b/test/files/run/reify_newimpl_09.check
@@ -0,0 +1 @@
+List(2) \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_09.scala b/test/files/run/reify_newimpl_09.scala
new file mode 100644
index 0000000000..2c81945a2a
--- /dev/null
+++ b/test/files/run/reify_newimpl_09.scala
@@ -0,0 +1,11 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ type T = Int
+ val code = reify {
+ List[T](2)
+ }
+ println(code.eval)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_10.check b/test/files/run/reify_newimpl_10.check
new file mode 100644
index 0000000000..220bd6875a
--- /dev/null
+++ b/test/files/run/reify_newimpl_10.check
@@ -0,0 +1 @@
+List(2) \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_10.scala b/test/files/run/reify_newimpl_10.scala
new file mode 100644
index 0000000000..6e70b4d216
--- /dev/null
+++ b/test/files/run/reify_newimpl_10.scala
@@ -0,0 +1,12 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ type T = Int
+ implicit val tt = implicitly[TypeTag[String]].asInstanceOf[TypeTag[T]] // this "mistake" is made for a reason!
+ val code = reify {
+ List[T](2)
+ }
+ println(code.eval)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_11.check b/test/files/run/reify_newimpl_11.check
new file mode 100644
index 0000000000..e2a8206132
--- /dev/null
+++ b/test/files/run/reify_newimpl_11.check
@@ -0,0 +1,2 @@
+scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed:
+unresolved free type variables (namely: T defined by C in reify_newimpl_11.scala:4:11). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types
diff --git a/test/files/run/reify_newimpl_11.scala b/test/files/run/reify_newimpl_11.scala
new file mode 100644
index 0000000000..4e91c7a457
--- /dev/null
+++ b/test/files/run/reify_newimpl_11.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C[T] {
+ val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ println(code.eval)
+ }
+
+ try {
+ new C[Int]
+ } catch {
+ case ex: Throwable =>
+ println(ex)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_12.check b/test/files/run/reify_newimpl_12.check
new file mode 100644
index 0000000000..220bd6875a
--- /dev/null
+++ b/test/files/run/reify_newimpl_12.check
@@ -0,0 +1 @@
+List(2) \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_12.scala b/test/files/run/reify_newimpl_12.scala
new file mode 100644
index 0000000000..433168ce28
--- /dev/null
+++ b/test/files/run/reify_newimpl_12.scala
@@ -0,0 +1,12 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C[T: TypeTag] {
+ val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ println(code.eval)
+ }
+
+ new C[Int]
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_13.check b/test/files/run/reify_newimpl_13.check
new file mode 100644
index 0000000000..7c47310cf2
--- /dev/null
+++ b/test/files/run/reify_newimpl_13.check
@@ -0,0 +1,2 @@
+scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed:
+unresolved free type variables (namely: T defined by C in reify_newimpl_13.scala:5:13). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types
diff --git a/test/files/run/reify_newimpl_13.scala b/test/files/run/reify_newimpl_13.scala
new file mode 100644
index 0000000000..dd1980b74f
--- /dev/null
+++ b/test/files/run/reify_newimpl_13.scala
@@ -0,0 +1,19 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ class C[T] {
+ val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ println(code.eval)
+ }
+
+ try {
+ new C[Int]
+ } catch {
+ case ex: Throwable =>
+ println(ex)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_14.check b/test/files/run/reify_newimpl_14.check
new file mode 100644
index 0000000000..220bd6875a
--- /dev/null
+++ b/test/files/run/reify_newimpl_14.check
@@ -0,0 +1 @@
+List(2) \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_14.scala b/test/files/run/reify_newimpl_14.scala
new file mode 100644
index 0000000000..3f52f19cfb
--- /dev/null
+++ b/test/files/run/reify_newimpl_14.scala
@@ -0,0 +1,14 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ class C[T: TypeTag] {
+ val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ println(code.eval)
+ }
+
+ new C[Int]
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_15.check b/test/files/run/reify_newimpl_15.check
new file mode 100644
index 0000000000..220bd6875a
--- /dev/null
+++ b/test/files/run/reify_newimpl_15.check
@@ -0,0 +1 @@
+List(2) \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_15.scala b/test/files/run/reify_newimpl_15.scala
new file mode 100644
index 0000000000..b707b2583d
--- /dev/null
+++ b/test/files/run/reify_newimpl_15.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C {
+ type T = Int
+ val code = reify {
+ List[T](2)
+ }
+ println(code.eval)
+ }
+
+ new C
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_16.check b/test/files/run/reify_newimpl_16.check
new file mode 100644
index 0000000000..220bd6875a
--- /dev/null
+++ b/test/files/run/reify_newimpl_16.check
@@ -0,0 +1 @@
+List(2) \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_16.scala b/test/files/run/reify_newimpl_16.scala
new file mode 100644
index 0000000000..98fc15878c
--- /dev/null
+++ b/test/files/run/reify_newimpl_16.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ class C {
+ type T = Int
+ val code = reify {
+ List[T](2)
+ }
+ println(code.eval)
+ }
+
+ new C
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_17.check b/test/files/run/reify_newimpl_17.check
new file mode 100644
index 0000000000..0fb9ddfc2d
--- /dev/null
+++ b/test/files/run/reify_newimpl_17.check
@@ -0,0 +1,2 @@
+scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed:
+unresolved free type variables (namely: U defined by C in reify_newimpl_17.scala:4:11). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types
diff --git a/test/files/run/reify_newimpl_17.scala b/test/files/run/reify_newimpl_17.scala
new file mode 100644
index 0000000000..331777fcfb
--- /dev/null
+++ b/test/files/run/reify_newimpl_17.scala
@@ -0,0 +1,18 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C[U] {
+ type T = U
+ val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ println(code.eval)
+ }
+
+ try {
+ new C[Int]
+ } catch {
+ case ex: Throwable =>
+ println(ex)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_18.check b/test/files/run/reify_newimpl_18.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_18.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_18.scala b/test/files/run/reify_newimpl_18.scala
new file mode 100644
index 0000000000..704e54928a
--- /dev/null
+++ b/test/files/run/reify_newimpl_18.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C[U: TypeTag] {
+ type T = U
+ val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ println(code.eval)
+ }
+
+ new C[Int]
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_19.check b/test/files/run/reify_newimpl_19.check
new file mode 100644
index 0000000000..32f9300f53
--- /dev/null
+++ b/test/files/run/reify_newimpl_19.check
@@ -0,0 +1,2 @@
+scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective toolbox has failed:
+unresolved free type variables (namely: T defined by C in reify_newimpl_19.scala:5:10). have you forgot to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types
diff --git a/test/files/run/reify_newimpl_19.scala b/test/files/run/reify_newimpl_19.scala
new file mode 100644
index 0000000000..0ea8ae6992
--- /dev/null
+++ b/test/files/run/reify_newimpl_19.scala
@@ -0,0 +1,18 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C {
+ type T
+ val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ println(code.eval)
+ }
+
+ try {
+ new C { val T = Int }
+ } catch {
+ case ex: Throwable =>
+ println(ex)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_20.check b/test/files/run/reify_newimpl_20.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_20.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_20.scala b/test/files/run/reify_newimpl_20.scala
new file mode 100644
index 0000000000..16895a449e
--- /dev/null
+++ b/test/files/run/reify_newimpl_20.scala
@@ -0,0 +1,14 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C {
+ type T
+ implicit val tt: TypeTag[T] = implicitly[TypeTag[Int]].asInstanceOf[TypeTag[T]]
+ val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ println(code.eval)
+ }
+
+ new C { type T = String } // this "mistake" is made for a reason!
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_21.check b/test/files/run/reify_newimpl_21.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_21.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_21.scala b/test/files/run/reify_newimpl_21.scala
new file mode 100644
index 0000000000..99f9ac9089
--- /dev/null
+++ b/test/files/run/reify_newimpl_21.scala
@@ -0,0 +1,18 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ trait C {
+ type T
+ implicit val tt: TypeTag[T]
+ lazy val code = reify {
+ List[T](2.asInstanceOf[T])
+ }
+ }
+
+ class D extends C {
+ type T = String // this "mistake" is made for a reason!
+ override val tt: TypeTag[T] = implicitly[TypeTag[Int]].asInstanceOf[TypeTag[T]]
+ }
+
+ println((new D).code.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_22.check b/test/files/run/reify_newimpl_22.check
new file mode 100644
index 0000000000..51699cbc29
--- /dev/null
+++ b/test/files/run/reify_newimpl_22.check
@@ -0,0 +1,23 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import scala.reflect.mirror._
+import scala.reflect.mirror._
+
+scala> {
+ val x = 2
+ val code = reify {
+ x
+ }
+ println(code.eval)
+}
+<console>:13: free term: Ident(newTermName("x")) defined by res0 in <console>:12:21
+ val code = reify {
+ ^
+2
+
+scala>
+
+scala>
diff --git a/test/files/run/reify_newimpl_22.scala b/test/files/run/reify_newimpl_22.scala
new file mode 100644
index 0000000000..a211ad360c
--- /dev/null
+++ b/test/files/run/reify_newimpl_22.scala
@@ -0,0 +1,15 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ override def extraSettings = "-Xlog-free-terms"
+ def code = """
+import scala.reflect.mirror._
+{
+ val x = 2
+ val code = reify {
+ x
+ }
+ println(code.eval)
+}
+ """
+}
diff --git a/test/files/run/reify_newimpl_23.check b/test/files/run/reify_newimpl_23.check
new file mode 100644
index 0000000000..33d15190fb
--- /dev/null
+++ b/test/files/run/reify_newimpl_23.check
@@ -0,0 +1,22 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import scala.reflect.mirror._
+import scala.reflect.mirror._
+
+scala> def foo[T]{
+ val code = reify {
+ List[T]()
+ }
+ println(code.eval)
+}
+<console>:11: free type: Ident(newTypeName("T")) defined by foo in <console>:10:16
+ val code = reify {
+ ^
+foo: [T]=> Unit
+
+scala>
+
+scala>
diff --git a/test/files/run/reify_newimpl_23.scala b/test/files/run/reify_newimpl_23.scala
new file mode 100644
index 0000000000..15da4e497e
--- /dev/null
+++ b/test/files/run/reify_newimpl_23.scala
@@ -0,0 +1,14 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ override def extraSettings = "-Xlog-free-types"
+ def code = """
+import scala.reflect.mirror._
+def foo[T]{
+ val code = reify {
+ List[T]()
+ }
+ println(code.eval)
+}
+ """
+}
diff --git a/test/files/run/reify_newimpl_24.check b/test/files/run/reify_newimpl_24.check
new file mode 100644
index 0000000000..66b18c790e
--- /dev/null
+++ b/test/files/run/reify_newimpl_24.check
@@ -0,0 +1,24 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import scala.reflect.mirror._
+import scala.reflect.mirror._
+
+scala> {
+ val x = 2
+ val code = reify {
+ val y = reify { x }
+ y.eval
+ }
+ println(code.eval)
+}
+<console>:15: this splice cannot be resolved statically
+ y.eval
+ ^
+2
+
+scala>
+
+scala>
diff --git a/test/files/run/reify_newimpl_24.scala b/test/files/run/reify_newimpl_24.scala
new file mode 100644
index 0000000000..7b21eeeb10
--- /dev/null
+++ b/test/files/run/reify_newimpl_24.scala
@@ -0,0 +1,16 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ override def extraSettings = "-Xlog-runtime-splices"
+ def code = """
+import scala.reflect.mirror._
+{
+ val x = 2
+ val code = reify {
+ val y = reify { x }
+ y.eval
+ }
+ println(code.eval)
+}
+ """
+}
diff --git a/test/files/run/reify_newimpl_25.check b/test/files/run/reify_newimpl_25.check
new file mode 100644
index 0000000000..37ff83c9ee
--- /dev/null
+++ b/test/files/run/reify_newimpl_25.check
@@ -0,0 +1,21 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import scala.reflect.mirror._
+import scala.reflect.mirror._
+
+scala> {
+ val x = "2"
+ val tt = implicitly[TypeTag[x.type]]
+ println(tt)
+}
+<console>:13: free term: Ident(newTermName("x")) defined by res0 in <console>:12:21
+ val tt = implicitly[TypeTag[x.type]]
+ ^
+ConcreteTypeTag[x.type]
+
+scala>
+
+scala>
diff --git a/test/files/run/reify_newimpl_25.scala b/test/files/run/reify_newimpl_25.scala
new file mode 100644
index 0000000000..1f66f5e681
--- /dev/null
+++ b/test/files/run/reify_newimpl_25.scala
@@ -0,0 +1,13 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ override def extraSettings = "-Xlog-free-terms"
+ def code = """
+import scala.reflect.mirror._
+{
+ val x = "2"
+ val tt = implicitly[TypeTag[x.type]]
+ println(tt)
+}
+ """
+}
diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check
new file mode 100644
index 0000000000..d92b3bd817
--- /dev/null
+++ b/test/files/run/reify_newimpl_26.check
@@ -0,0 +1,23 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import scala.reflect.mirror._
+import scala.reflect.mirror._
+
+scala> def foo[T]{
+ val tt = implicitly[TypeTag[List[T]]]
+ println(tt)
+}
+<console>:11: free type: Ident(newTypeName("T")) defined by foo in <console>:10:16
+ val tt = implicitly[TypeTag[List[T]]]
+ ^
+foo: [T]=> Unit
+
+scala> foo[Int]
+TypeTag[List[T]]
+
+scala>
+
+scala>
diff --git a/test/files/run/reify_newimpl_26.scala b/test/files/run/reify_newimpl_26.scala
new file mode 100644
index 0000000000..f2dd1bfc4e
--- /dev/null
+++ b/test/files/run/reify_newimpl_26.scala
@@ -0,0 +1,13 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ override def extraSettings = "-Xlog-free-types"
+ def code = """
+import scala.reflect.mirror._
+def foo[T]{
+ val tt = implicitly[TypeTag[List[T]]]
+ println(tt)
+}
+foo[Int]
+ """
+}
diff --git a/test/files/run/reify_newimpl_27.check b/test/files/run/reify_newimpl_27.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_27.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_27.scala b/test/files/run/reify_newimpl_27.scala
new file mode 100644
index 0000000000..b3d6d5c865
--- /dev/null
+++ b/test/files/run/reify_newimpl_27.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ object C {
+ type T = Int
+ val code = reify {
+ List[T](2)
+ }
+ println(code.eval)
+ }
+
+ C
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_28.check b/test/files/run/reify_newimpl_28.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_28.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_28.scala b/test/files/run/reify_newimpl_28.scala
new file mode 100644
index 0000000000..f7874b8548
--- /dev/null
+++ b/test/files/run/reify_newimpl_28.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ object C {
+ type T = Int
+ val code = reify {
+ List[T](2)
+ }
+ println(code.eval)
+ }
+
+ C
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_29.check b/test/files/run/reify_newimpl_29.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_29.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_29.scala b/test/files/run/reify_newimpl_29.scala
new file mode 100644
index 0000000000..e32762f335
--- /dev/null
+++ b/test/files/run/reify_newimpl_29.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C {
+ type T = Int
+ val code = reify {
+ List[C#T](2)
+ }
+ println(code.eval)
+ }
+
+ new C
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_30.check b/test/files/run/reify_newimpl_30.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_30.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_30.scala b/test/files/run/reify_newimpl_30.scala
new file mode 100644
index 0000000000..e4ba3221e1
--- /dev/null
+++ b/test/files/run/reify_newimpl_30.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ class C {
+ type T = Int
+ val code = reify {
+ List[C#T](2)
+ }
+ println(code.eval)
+ }
+
+ new C
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_31.check b/test/files/run/reify_newimpl_31.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_31.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_31.scala b/test/files/run/reify_newimpl_31.scala
new file mode 100644
index 0000000000..20a851e32e
--- /dev/null
+++ b/test/files/run/reify_newimpl_31.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ object C {
+ type T = Int
+ val code = reify {
+ List[C.T](2)
+ }
+ println(code.eval)
+ }
+
+ C
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_32.check b/test/files/run/reify_newimpl_32.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_32.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_32.scala b/test/files/run/reify_newimpl_32.scala
new file mode 100644
index 0000000000..788486ec00
--- /dev/null
+++ b/test/files/run/reify_newimpl_32.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ object C {
+ type T = Int
+ val code = reify {
+ List[C.T](2)
+ }
+ println(code.eval)
+ }
+
+ C
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_33.check b/test/files/run/reify_newimpl_33.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_33.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_33.scala b/test/files/run/reify_newimpl_33.scala
new file mode 100644
index 0000000000..84a8258256
--- /dev/null
+++ b/test/files/run/reify_newimpl_33.scala
@@ -0,0 +1,14 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ object C {
+ type T = Int
+ val c = C
+ val code = reify {
+ List[c.T](2)
+ }
+ println(code.eval)
+ }
+
+ C
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_34.check b/test/files/run/reify_newimpl_34.check
new file mode 100644
index 0000000000..a7029974a4
--- /dev/null
+++ b/test/files/run/reify_newimpl_34.check
@@ -0,0 +1 @@
+List(2)
diff --git a/test/files/run/reify_newimpl_34.scala b/test/files/run/reify_newimpl_34.scala
new file mode 100644
index 0000000000..5935ab385c
--- /dev/null
+++ b/test/files/run/reify_newimpl_34.scala
@@ -0,0 +1,16 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ object C {
+ type T = Int
+ lazy val c = C
+ val code = reify {
+ List[c.T](2)
+ }
+ println(code.eval)
+ }
+
+ C
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_36.check b/test/files/run/reify_newimpl_36.check
new file mode 100644
index 0000000000..2f562a182f
--- /dev/null
+++ b/test/files/run/reify_newimpl_36.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/reify_newimpl_36.scala b/test/files/run/reify_newimpl_36.scala
new file mode 100644
index 0000000000..c76efce27a
--- /dev/null
+++ b/test/files/run/reify_newimpl_36.scala
@@ -0,0 +1,14 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val x = 42
+ def foo() = reify(reify(x));
+ {
+ val x = 2
+ val code1 = foo()
+ val code2 = code1.eval
+ println(code2.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_37.check b/test/files/run/reify_newimpl_37.check
new file mode 100644
index 0000000000..2f562a182f
--- /dev/null
+++ b/test/files/run/reify_newimpl_37.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/reify_newimpl_37.scala b/test/files/run/reify_newimpl_37.scala
new file mode 100644
index 0000000000..e83d35dbe1
--- /dev/null
+++ b/test/files/run/reify_newimpl_37.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val x = 42
+ def foo() = reify(reify(reify(x)));
+ {
+ val x = 2
+ val code1 = foo()
+ val code2 = code1.eval
+ val code3 = code2.eval
+ println(code3.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_38.check b/test/files/run/reify_newimpl_38.check
new file mode 100644
index 0000000000..2f562a182f
--- /dev/null
+++ b/test/files/run/reify_newimpl_38.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/reify_newimpl_38.scala b/test/files/run/reify_newimpl_38.scala
new file mode 100644
index 0000000000..70ef49ecf7
--- /dev/null
+++ b/test/files/run/reify_newimpl_38.scala
@@ -0,0 +1,14 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val x = 42
+ def foo() = reify{ val y = x; reify(y) };
+ {
+ val x = 2
+ val code1 = foo()
+ val code2 = code1.eval
+ println(code2.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_39.check b/test/files/run/reify_newimpl_39.check
new file mode 100644
index 0000000000..2f562a182f
--- /dev/null
+++ b/test/files/run/reify_newimpl_39.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/reify_newimpl_39.scala b/test/files/run/reify_newimpl_39.scala
new file mode 100644
index 0000000000..faa45d917d
--- /dev/null
+++ b/test/files/run/reify_newimpl_39.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val x = 42
+ def foo() = reify{ val y = x; reify{ val z = y; reify(z) } };
+ {
+ val x = 2
+ val code1 = foo()
+ val code2 = code1.eval
+ val code3 = code2.eval
+ println(code3.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_40.check b/test/files/run/reify_newimpl_40.check
new file mode 100644
index 0000000000..94c5a65fe0
--- /dev/null
+++ b/test/files/run/reify_newimpl_40.check
@@ -0,0 +1 @@
+74088
diff --git a/test/files/run/reify_newimpl_40.scala b/test/files/run/reify_newimpl_40.scala
new file mode 100644
index 0000000000..a983a92324
--- /dev/null
+++ b/test/files/run/reify_newimpl_40.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ val x = 42
+ def foo() = reify{ val y = x; reify{ val z = y * x; reify(z * x) } };
+ {
+ val x = 2
+ val code1 = foo()
+ val code2 = code1.eval
+ val code3 = code2.eval
+ println(code3.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_41.check b/test/files/run/reify_newimpl_41.check
new file mode 100644
index 0000000000..0b427f2ee6
--- /dev/null
+++ b/test/files/run/reify_newimpl_41.check
@@ -0,0 +1,3 @@
+42
+44
+43 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_41.scala b/test/files/run/reify_newimpl_41.scala
new file mode 100644
index 0000000000..9aedccc98a
--- /dev/null
+++ b/test/files/run/reify_newimpl_41.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var _x = 42
+ def x = { val x0 = _x; _x += 1; x0 }
+ var _y = 1
+ def y = { val y0 = _y + _x; _y += y0; y0 }
+ val code = reify {
+ def foo = y // ensures that y is the first freevar we find
+ println(x)
+ println(y)
+ println(x)
+ }
+ code.eval
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_42.check b/test/files/run/reify_newimpl_42.check
new file mode 100644
index 0000000000..0b427f2ee6
--- /dev/null
+++ b/test/files/run/reify_newimpl_42.check
@@ -0,0 +1,3 @@
+42
+44
+43 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_42.scala b/test/files/run/reify_newimpl_42.scala
new file mode 100644
index 0000000000..1e21bd59bc
--- /dev/null
+++ b/test/files/run/reify_newimpl_42.scala
@@ -0,0 +1,16 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var _x = 42
+ def x = { val x0 = _x; _x += 1; x0 }
+ var _y = 1
+ def y = { val y0 = _y + _x; _y += y0; y0 }
+ val code = reify {
+ println(x)
+ println(y)
+ println(x)
+ }
+ code.eval
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_43.check b/test/files/run/reify_newimpl_43.check
new file mode 100644
index 0000000000..7a754f414c
--- /dev/null
+++ b/test/files/run/reify_newimpl_43.check
@@ -0,0 +1,2 @@
+1
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_43.scala b/test/files/run/reify_newimpl_43.scala
new file mode 100644
index 0000000000..962461db8b
--- /dev/null
+++ b/test/files/run/reify_newimpl_43.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var counter = 0
+ lazy val x = { counter += 1; counter }
+ lazy val y = { counter += 1; counter }
+ val code = reify {
+ def foo = y // ensures that y is the first freevar we find
+ println(x)
+ println(y)
+ }
+ code.eval
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_44.check b/test/files/run/reify_newimpl_44.check
new file mode 100644
index 0000000000..7a754f414c
--- /dev/null
+++ b/test/files/run/reify_newimpl_44.check
@@ -0,0 +1,2 @@
+1
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_44.scala b/test/files/run/reify_newimpl_44.scala
new file mode 100644
index 0000000000..962461db8b
--- /dev/null
+++ b/test/files/run/reify_newimpl_44.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var counter = 0
+ lazy val x = { counter += 1; counter }
+ lazy val y = { counter += 1; counter }
+ val code = reify {
+ def foo = y // ensures that y is the first freevar we find
+ println(x)
+ println(y)
+ }
+ code.eval
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_45.check b/test/files/run/reify_newimpl_45.check
new file mode 100644
index 0000000000..6e14f71e26
--- /dev/null
+++ b/test/files/run/reify_newimpl_45.check
@@ -0,0 +1,2 @@
+List(free type T)
+ima worx: 2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_45.scala b/test/files/run/reify_newimpl_45.scala
new file mode 100644
index 0000000000..b2b52eaf5b
--- /dev/null
+++ b/test/files/run/reify_newimpl_45.scala
@@ -0,0 +1,12 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C[T >: Null] {
+ val code = reify{val x: T = "2".asInstanceOf[T]; println("ima worx: %s".format(x)); x}
+ println(freeTypes(code.tree))
+ val T = freeTypes(code.tree)(0)
+ mkToolBox().runExpr(code.tree, Map(T -> definitions.StringClass.asType))
+ }
+
+ new C[String]
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_47.check b/test/files/run/reify_newimpl_47.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_newimpl_47.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_47.scala b/test/files/run/reify_newimpl_47.scala
new file mode 100644
index 0000000000..bd1bd1fe65
--- /dev/null
+++ b/test/files/run/reify_newimpl_47.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val outer = {
+ val x = 2
+ reify{x}
+ }
+
+ val code = reify{
+ val x = 42
+ outer.eval
+ }
+
+ println(code.eval)
+}
diff --git a/test/files/run/reify_newimpl_48.check b/test/files/run/reify_newimpl_48.check
new file mode 100644
index 0000000000..f11c82a4cb
--- /dev/null
+++ b/test/files/run/reify_newimpl_48.check
@@ -0,0 +1 @@
+9 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_48.scala b/test/files/run/reify_newimpl_48.scala
new file mode 100644
index 0000000000..1522509907
--- /dev/null
+++ b/test/files/run/reify_newimpl_48.scala
@@ -0,0 +1,20 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val outer1 = {
+ val x = 2
+ reify{x}
+ }
+
+ val outer2 = {
+ val x = 3
+ reify{x}
+ }
+
+ val code = reify{
+ val x = 4
+ x + outer1.eval + outer2.eval
+ }
+
+ println(code.eval)
+}
diff --git a/test/files/run/reify_newimpl_49.check b/test/files/run/reify_newimpl_49.check
new file mode 100644
index 0000000000..d8a621df00
--- /dev/null
+++ b/test/files/run/reify_newimpl_49.check
@@ -0,0 +1,3 @@
+3
+3
+5 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_49.scala b/test/files/run/reify_newimpl_49.scala
new file mode 100644
index 0000000000..68d968e28b
--- /dev/null
+++ b/test/files/run/reify_newimpl_49.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var y = 1
+ def x = { y += 2; y }
+ val code = reify {
+ def foo = y // ensures that y is the first freevar we find
+ println(x)
+ println(y)
+ println(x)
+ }
+ code.eval
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_50.check b/test/files/run/reify_newimpl_50.check
new file mode 100644
index 0000000000..d8a621df00
--- /dev/null
+++ b/test/files/run/reify_newimpl_50.check
@@ -0,0 +1,3 @@
+3
+3
+5 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_50.scala b/test/files/run/reify_newimpl_50.scala
new file mode 100644
index 0000000000..b81d72a4eb
--- /dev/null
+++ b/test/files/run/reify_newimpl_50.scala
@@ -0,0 +1,14 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var y = 1
+ def x = { y += 2; y }
+ val code = reify {
+ println(x)
+ println(y)
+ println(x)
+ }
+ code.eval
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_51.check b/test/files/run/reify_newimpl_51.check
new file mode 100644
index 0000000000..9a4ddeacd3
--- /dev/null
+++ b/test/files/run/reify_newimpl_51.check
@@ -0,0 +1,3 @@
+2
+1
+2 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_51.scala b/test/files/run/reify_newimpl_51.scala
new file mode 100644
index 0000000000..ccbae2e160
--- /dev/null
+++ b/test/files/run/reify_newimpl_51.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var counter = 0
+ lazy val x = { counter += 1; counter }
+ lazy val y = { counter += 1; counter }
+ val code = reify {
+ def foo = y // ensures that y is the first freevar we find
+ val bar = reify { println(x * y) }
+ bar.eval
+ println(x)
+ println(y)
+ }
+ code.eval
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_52.check b/test/files/run/reify_newimpl_52.check
new file mode 100644
index 0000000000..9359a2b211
--- /dev/null
+++ b/test/files/run/reify_newimpl_52.check
@@ -0,0 +1,3 @@
+2
+2
+1 \ No newline at end of file
diff --git a/test/files/run/reify_newimpl_52.scala b/test/files/run/reify_newimpl_52.scala
new file mode 100644
index 0000000000..60b16d3618
--- /dev/null
+++ b/test/files/run/reify_newimpl_52.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ var counter = 0
+ lazy val x = { counter += 1; counter }
+ lazy val y = { counter += 1; counter }
+ val code = reify {
+ def foo = y // ensures that y is the first freevar we find
+ val bar = reify { println(y * x) }
+ bar.eval
+ println(x)
+ println(y)
+ }
+ code.eval
+ }
+} \ No newline at end of file
diff --git a/test/files/run/reify_printf.scala b/test/files/run/reify_printf.scala
index cd6052bc5e..dc092c1a85 100644
--- a/test/files/run/reify_printf.scala
+++ b/test/files/run/reify_printf.scala
@@ -1,19 +1,15 @@
import java.io.{ ByteArrayOutputStream, PrintStream }
-import scala.reflect.Code
import scala.reflect.mirror._
import scala.reflect.api._
import scala.reflect.api.Trees
import scala.reflect.internal.Types
-import reflect.runtime.Mirror.ToolBox
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
import scala.util.matching.Regex
object Test extends App {
- val tree = tree_printf(Code.lift("hello %s").tree, Code.lift("world").tree)
+ val tree = tree_printf(reify("hello %s").tree, reify("world").tree)
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter, args mkString " ")
+ import scala.reflect.mirror._
+ val toolbox = mkToolBox()
val output = new ByteArrayOutputStream()
Console.setOut(new PrintStream(output))
@@ -22,6 +18,7 @@ object Test extends App {
assert(output.toString() == "hello world", output.toString() +" == hello world")
/*
+ // upd. Oh, good old times, our very-very first experiments with macros :)
macro def printf(format: String, params: Any*) : String = tree_printf(format: Tree, (params: Seq[Tree]): _*)
*/
diff --git a/test/files/run/reify_sort.scala b/test/files/run/reify_sort.scala
index 5984a64967..0b373b358f 100644
--- a/test/files/run/reify_sort.scala
+++ b/test/files/run/reify_sort.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
/** Nested methods can use and even update everything
* visible in their scope (including local variables or
* arguments of enclosing methods).
@@ -48,9 +46,5 @@ object Test extends App {
println(ar)
sort(ar)
println(ar)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_sort1.scala b/test/files/run/reify_sort1.scala
index 6f365dea26..56125619e9 100644
--- a/test/files/run/reify_sort1.scala
+++ b/test/files/run/reify_sort1.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
def sort(a: List[Int]): List[Int] = {
if (a.length < 2)
a
@@ -18,9 +16,5 @@ object Test extends App {
val xs = List(6, 2, 8, 5, 1)
println(xs)
println(sort(xs))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_this.scala b/test/files/run/reify_this.scala
index ee1f116013..280d735ab6 100644
--- a/test/files/run/reify_this.scala
+++ b/test/files/run/reify_this.scala
@@ -1,30 +1,19 @@
-import scala.reflect._
-import scala.reflect.Code._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
trait Eval {
- def eval(code: Code): Any = eval(code.tree)
-
- def eval(tree: Tree): Any = {
- val settings = new Settings
- val reporter = new ConsoleReporter(settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(tree)
- }
+ def eval(tree: Expr[_]) = tree.eval
}
object Test extends App with Eval {
// select a value from package
- eval(lift{println("foo")})
- eval(lift{println((new Object).toString == (new Object).toString)})
+ eval(reify{println("foo")})
+ eval(reify{println((new Object).toString == (new Object).toString)})
// select a type from package
- eval(lift{val x: Any = 2; println(x)})
- eval(lift{val x: Object = "bar"; println(x)})
+ eval(reify{val x: Any = 2; println(x)})
+ eval(reify{val x: Object = "bar"; println(x)})
// select a value from module
val x = 2
- eval(lift{println(x)})
+ eval(reify{println(x)})
}
diff --git a/test/files/run/reify_timeofday.scala b/test/files/run/reify_timeofday.scala
index 122d7a6d52..481ab04df5 100644
--- a/test/files/run/reify_timeofday.scala
+++ b/test/files/run/reify_timeofday.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class DateError extends Exception
/** Simulating properties in Scala
@@ -39,9 +37,5 @@ object Test extends App {
case de: DateError => println("DateError")
case e: Exception => println("Exception")
}
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/reify_typerefs_1a.check b/test/files/run/reify_typerefs_1a.check
new file mode 100644
index 0000000000..919c298ba3
--- /dev/null
+++ b/test/files/run/reify_typerefs_1a.check
@@ -0,0 +1 @@
+evaluated = List(Expression, Expression) \ No newline at end of file
diff --git a/test/files/run/reify_typerefs_1a.scala b/test/files/run/reify_typerefs_1a.scala
new file mode 100644
index 0000000000..15d8d17835
--- /dev/null
+++ b/test/files/run/reify_typerefs_1a.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+class Expression {
+ override def toString = "Expression"
+}
+
+object Test extends App {
+ val code = reify {
+ List(new Expression, new Expression)
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_typerefs_1b.check b/test/files/run/reify_typerefs_1b.check
new file mode 100644
index 0000000000..919c298ba3
--- /dev/null
+++ b/test/files/run/reify_typerefs_1b.check
@@ -0,0 +1 @@
+evaluated = List(Expression, Expression) \ No newline at end of file
diff --git a/test/files/run/reify_typerefs_1b.scala b/test/files/run/reify_typerefs_1b.scala
new file mode 100644
index 0000000000..06ce1e35ac
--- /dev/null
+++ b/test/files/run/reify_typerefs_1b.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Expression {
+ override def toString = "Expression"
+}
+
+object Test extends App {
+ val code = reify {
+ List(Expression, Expression)
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_typerefs_2a.check b/test/files/run/reify_typerefs_2a.check
new file mode 100644
index 0000000000..919c298ba3
--- /dev/null
+++ b/test/files/run/reify_typerefs_2a.check
@@ -0,0 +1 @@
+evaluated = List(Expression, Expression) \ No newline at end of file
diff --git a/test/files/run/reify_typerefs_2a.scala b/test/files/run/reify_typerefs_2a.scala
new file mode 100644
index 0000000000..d03efea222
--- /dev/null
+++ b/test/files/run/reify_typerefs_2a.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+package foo {
+ class Expression {
+ override def toString = "Expression"
+ }
+}
+
+object Test extends App {
+ val code = reify {
+ List(new foo.Expression, new foo.Expression)
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_typerefs_2b.check b/test/files/run/reify_typerefs_2b.check
new file mode 100644
index 0000000000..919c298ba3
--- /dev/null
+++ b/test/files/run/reify_typerefs_2b.check
@@ -0,0 +1 @@
+evaluated = List(Expression, Expression) \ No newline at end of file
diff --git a/test/files/run/reify_typerefs_2b.scala b/test/files/run/reify_typerefs_2b.scala
new file mode 100644
index 0000000000..3d9f7d61b8
--- /dev/null
+++ b/test/files/run/reify_typerefs_2b.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+package foo {
+ object Expression {
+ override def toString = "Expression"
+ }
+}
+
+object Test extends App {
+ val code = reify {
+ List(foo.Expression, foo.Expression)
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_typerefs_3a.check b/test/files/run/reify_typerefs_3a.check
new file mode 100644
index 0000000000..919c298ba3
--- /dev/null
+++ b/test/files/run/reify_typerefs_3a.check
@@ -0,0 +1 @@
+evaluated = List(Expression, Expression) \ No newline at end of file
diff --git a/test/files/run/reify_typerefs_3a.scala b/test/files/run/reify_typerefs_3a.scala
new file mode 100644
index 0000000000..4128073f60
--- /dev/null
+++ b/test/files/run/reify_typerefs_3a.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+object foo {
+ class Expression {
+ override def toString = "Expression"
+ }
+}
+
+object Test extends App {
+ val code = reify {
+ List(new foo.Expression, new foo.Expression)
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_typerefs_3b.check b/test/files/run/reify_typerefs_3b.check
new file mode 100644
index 0000000000..919c298ba3
--- /dev/null
+++ b/test/files/run/reify_typerefs_3b.check
@@ -0,0 +1 @@
+evaluated = List(Expression, Expression) \ No newline at end of file
diff --git a/test/files/run/reify_typerefs_3b.scala b/test/files/run/reify_typerefs_3b.scala
new file mode 100644
index 0000000000..a7ede00c9c
--- /dev/null
+++ b/test/files/run/reify_typerefs_3b.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+object foo {
+ object Expression {
+ override def toString = "Expression"
+ }
+}
+
+object Test extends App {
+ val code = reify {
+ List(foo.Expression, foo.Expression)
+ };
+
+ val toolbox = mkToolBox()
+ val evaluated = toolbox.runExpr(code.tree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/files/run/reify_varargs.scala b/test/files/run/reify_varargs.scala
index 175cfb5db0..fe8f03b702 100644
--- a/test/files/run/reify_varargs.scala
+++ b/test/files/run/reify_varargs.scala
@@ -1,16 +1,10 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
val msg = java.text.MessageFormat.format(
"On {1} there was {2} on planet {0}.",
"Hoth", "the fifth of August", "a disturbance in the Force")
println("Message="+msg)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/repl-colon-type.check b/test/files/run/repl-colon-type.check
index 66c2fcc77f..cb0b9a6c8b 100644
--- a/test/files/run/repl-colon-type.check
+++ b/test/files/run/repl-colon-type.check
@@ -7,6 +7,12 @@ scala> :type List[1, 2, 3]
<console>:2: error: identifier expected but integer literal found.
List[1, 2, 3]
^
+<console>:3: error: ']' expected but '}' found.
+ }
+ ^
+<console>:1: error: identifier expected but integer literal found.
+ List[1, 2, 3]
+ ^
scala> :type List(1, 2, 3)
@@ -25,7 +31,7 @@ scala> :type def f[T >: Null, U <: String](x: T, y: U) = Set(x, y)
[T >: Null, U <: String](x: T, y: U)scala.collection.immutable.Set[Any]
scala> :type def x = 1 ; def bar[T >: Null <: AnyRef](xyz: T) = 5
-[T >: Null <: AnyRef](xyz: T)Int
+=> Int <and> [T >: Null <: AnyRef](xyz: T)Int
scala>
@@ -39,10 +45,19 @@ scala> :type lazy val f = 5
Int
scala> :type protected lazy val f = 5
-Int
+<console>:2: error: illegal start of statement (no modifiers allowed here)
+ protected lazy val f = 5
+ ^
+<console>:5: error: lazy value f cannot be accessed in object $iw
+ Access to protected value f not permitted because
+ enclosing object $eval in package $line19 is not a subclass of
+ object $iw where target is defined
+ lazy val $result = `f`
+ ^
+
scala> :type def f = 5
-Int
+=> Int
scala> :type def f() = 5
()Int
@@ -54,4 +69,156 @@ scala> :type def g[T](xs: Set[_ <: T]) = Some(xs.head)
scala>
+scala> // verbose!
+
+scala> :type -v List(1,2,3) filter _
+// Type signature
+(Int => Boolean) => List[Int]
+
+// Internal Type structure
+TypeRef(
+ TypeSymbol(abstract trait Function1[-T1, +R] extends Object)
+ args = List(
+ TypeRef(
+ TypeSymbol(abstract trait Function1[-T1, +R] extends Object)
+ args = List(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ TypeRef(TypeSymbol(final class Boolean extends AnyVal))
+ )
+ )
+ TypeRef(
+ TypeSymbol(
+ sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]]
+
+ )
+ args = List(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+ )
+ )
+)
+
+scala> :type -v def f[T >: Null, U <: String](x: T, y: U) = Set(x, y)
+// Type signature
+[T >: Null, U <: String](x: T, y: U)scala.collection.immutable.Set[Any]
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T >: Null), TypeParam(U <: String))
+ resultType = MethodType(
+ params = List(TermSymbol(x: T), TermSymbol(y: U))
+ resultType = TypeRef(
+ TypeSymbol(
+ abstract trait Set[A] extends Iterable[A] with Set[A] with GenericSetTemplate[A,scala.collection.immutable.Set] with SetLike[A,scala.collection.immutable.Set[A]] with Parallelizable[A,scala.collection.parallel.immutable.ParSet[A]]
+
+ )
+ args = List(TypeRef(TypeSymbol(abstract class Any extends )))
+ )
+ )
+)
+
+scala> :type -v def x = 1 ; def bar[T >: Null <: AnyRef](xyz: T) = 5
+// Type signature
+=> Int <and> [T >: Null <: AnyRef](xyz: T)Int
+
+// Internal Type structure
+OverloadedType(
+ alts = List(
+ NullaryMethodType(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+ PolyType(
+ typeParams = List(TypeParam(T >: Null <: AnyRef))
+ resultType = MethodType(
+ params = List(TermSymbol(xyz: T))
+ resultType = TypeRef(
+ TypeSymbol(final class Int extends AnyVal)
+ )
+ )
+ )
+ )
+)
+
+scala> :type -v Nil.combinations _
+// Type signature
+Int => Iterator[List[Nothing]]
+
+// Internal Type structure
+TypeRef(
+ TypeSymbol(abstract trait Function1[-T1, +R] extends Object)
+ args = List(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ TypeRef(
+ TypeSymbol(
+ abstract trait Iterator[+A] extends TraversableOnce[A]
+ )
+ args = List(
+ TypeRef(
+ TypeSymbol(
+ sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]]
+
+ )
+ args = List(
+ TypeRef(
+ TypeSymbol(final abstract class Nothing extends Any)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
+scala> :type -v def f[T <: AnyVal] = List[T]().combinations _
+// Type signature
+[T <: AnyVal]=> Int => Iterator[List[T]]
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T <: AnyVal))
+ resultType = NullaryMethodType(
+ TypeRef(
+ TypeSymbol(abstract trait Function1[-T1, +R] extends Object)
+ args = List(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ TypeRef(
+ TypeSymbol(
+ abstract trait Iterator[+A] extends TraversableOnce[A]
+ )
+ args = List(
+ TypeRef(
+ TypeSymbol(
+ sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]]
+
+ )
+ args = List(TypeParamTypeRef(TypeParam(T <: AnyVal)))
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
+scala> :type -v def f[T, U >: T](x: T, y: List[U]) = x :: y
+// Type signature
+[T, U >: T](x: T, y: List[U])List[U]
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T), TypeParam(U >: T))
+ resultType = MethodType(
+ params = List(TermSymbol(x: T), TermSymbol(y: List[U]))
+ resultType = TypeRef(
+ TypeSymbol(
+ sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A,List] with LinearSeqOptimized[A,List[A]]
+
+ )
+ args = List(TypeParamTypeRef(TypeParam(U >: T)))
+ )
+ )
+)
+
+scala>
+
scala>
diff --git a/test/files/run/repl-colon-type.scala b/test/files/run/repl-colon-type.scala
index 39ab580d2a..c055b215c2 100644
--- a/test/files/run/repl-colon-type.scala
+++ b/test/files/run/repl-colon-type.scala
@@ -18,6 +18,14 @@ object Test extends ReplTest {
|:type def f() = 5
|
|:type def g[T](xs: Set[_ <: T]) = Some(xs.head)
+ |
+ |// verbose!
+ |:type -v List(1,2,3) filter _
+ |:type -v def f[T >: Null, U <: String](x: T, y: U) = Set(x, y)
+ |:type -v def x = 1 ; def bar[T >: Null <: AnyRef](xyz: T) = 5
+ |:type -v Nil.combinations _
+ |:type -v def f[T <: AnyVal] = List[T]().combinations _
+ |:type -v def f[T, U >: T](x: T, y: List[U]) = x :: y
""".stripMargin
}
diff --git a/test/files/run/repl-parens.check b/test/files/run/repl-parens.check
index 69f0a9ce30..4b7ce6b059 100644
--- a/test/files/run/repl-parens.check
+++ b/test/files/run/repl-parens.check
@@ -34,7 +34,7 @@ res7: (Int, Int) = (4,4)
scala> (((2 + 2)), ((2 + 2)), 2)
res8: (Int, Int, Int) = (4,4,2)
-scala> ((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3) mkString)
+scala> (((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3)).mkString)
res9: String = 4423
scala>
diff --git a/test/files/run/repl-parens.scala b/test/files/run/repl-parens.scala
index c1cf9b50e1..e25933b1a2 100644
--- a/test/files/run/repl-parens.scala
+++ b/test/files/run/repl-parens.scala
@@ -11,7 +11,7 @@ object Test extends ReplTest {
5 ; ( (2 + 2 ) ) ; ((5))
(((2 + 2)), ((2 + 2)))
(((2 + 2)), ((2 + 2)), 2)
-((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3) mkString)
+(((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3)).mkString)
55 ; ((2 + 2)) ; (1, 2, 3)
55 ; (x: Int) => x + 1 ; () => ((5))
@@ -26,4 +26,4 @@ foo(5)(10)(15)+foo(5)(10)(15)
List(1) ++ List('a')
""".trim
-} \ No newline at end of file
+}
diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check
index 1e7b6f0cd8..c509434116 100644
--- a/test/files/run/repl-power.check
+++ b/test/files/run/repl-power.check
@@ -1,32 +1,32 @@
-Type in expressions to have them evaluated.
-Type :help for more information.
-
-scala> :power
-** Power User mode enabled - BEEP WHIR GYVE **
-** :phase has been set to 'typer'. **
-** scala.tools.nsc._ has been imported **
-** global._, definitions._ also imported **
-** Try :help, :vals, power.<tab> **
-
-scala> // guarding against "error: reference to global is ambiguous"
-
-scala> global.emptyValDef // "it is imported twice in the same scope by ..."
-res0: $r.global.emptyValDef.type = private val _ = _
-
-scala> val tp = ArrayClass[scala.util.Random] // magic with manifests
-tp: $r.global.Type = Array[scala.util.Random]
-
-scala> tp.memberType(Array_apply) // evidence
-res1: $r.global.Type = (i: Int)scala.util.Random
-
-scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl
-m: $r.treedsl.global.Match =
-10 match {
- case 5 => false
- case _ => true
-}
-
-scala> typed(m).tpe // typed is in scope
-res2: $r.treedsl.global.Type = Boolean
-
-scala>
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala> :power
+** Power User mode enabled - BEEP WHIR GYVE **
+** :phase has been set to 'typer'. **
+** scala.tools.nsc._ has been imported **
+** global._, definitions._ also imported **
+** Try :help, :vals, power.<tab> **
+
+scala> // guarding against "error: reference to global is ambiguous"
+
+scala> global.emptyValDef // "it is imported twice in the same scope by ..."
+res0: $r.global.emptyValDef.type = private val _ = _
+
+scala> val tp = ArrayClass[scala.util.Random] // magic with tags
+tp: $r.global.Type = Array[scala.util.Random]
+
+scala> tp.memberType(Array_apply) // evidence
+res1: $r.global.Type = (i: Int)scala.util.Random
+
+scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl
+m: $r.treedsl.global.Match =
+10 match {
+ case 5 => false
+ case _ => true
+}
+
+scala> typed(m).tpe // typed is in scope
+res2: $r.treedsl.global.Type = Boolean
+
+scala>
diff --git a/test/files/run/repl-power.scala b/test/files/run/repl-power.scala
index 27da3df106..f7c88c63ff 100644
--- a/test/files/run/repl-power.scala
+++ b/test/files/run/repl-power.scala
@@ -5,10 +5,9 @@ object Test extends ReplTest {
:power
// guarding against "error: reference to global is ambiguous"
global.emptyValDef // "it is imported twice in the same scope by ..."
-val tp = ArrayClass[scala.util.Random] // magic with manifests
+val tp = ArrayClass[scala.util.Random] // magic with tags
tp.memberType(Array_apply) // evidence
val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl
typed(m).tpe // typed is in scope
""".trim
}
-
diff --git a/test/files/run/repl-reset.check b/test/files/run/repl-reset.check
index 8c21ab067a..7256b851bb 100644
--- a/test/files/run/repl-reset.check
+++ b/test/files/run/repl-reset.check
@@ -28,7 +28,7 @@ val x3 = 3
case class BippyBungus()
x1 + x2 + x3
-Forgetting all expression results and named terms: BippyBungus, x1, x2, x3
+Forgetting all expression results and named terms: $intp, BippyBungus, x1, x2, x3
Forgetting defined types: BippyBungus
scala> x1 + x2 + x3
diff --git a/test/files/run/repl-suppressed-warnings.scala b/test/files/run/repl-suppressed-warnings.scala
index a78b00f36e..9afbbaf1a5 100644
--- a/test/files/run/repl-suppressed-warnings.scala
+++ b/test/files/run/repl-suppressed-warnings.scala
@@ -1,6 +1,7 @@
import scala.tools.partest.ReplTest
object Test extends ReplTest {
+ override def extraSettings = "-Xoldpatmat"
def code = """
// "Is this thing on?" Not working on first couple
diff --git a/test/files/run/repl-type-verbose.check b/test/files/run/repl-type-verbose.check
new file mode 100644
index 0000000000..103ac3e64d
--- /dev/null
+++ b/test/files/run/repl-type-verbose.check
@@ -0,0 +1,186 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> // verbose!
+
+scala> :type -v def f = 5
+// Type signature
+=> Int
+
+// Internal Type structure
+NullaryMethodType(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+)
+
+scala> :type -v def f() = 5
+// Type signature
+()Int
+
+// Internal Type structure
+NullaryMethodType(
+ resultType = TypeRef(TypeSymbol(final class Int extends AnyVal))
+)
+
+scala> :type -v def f[T] = 5
+// Type signature
+[T]=> Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T))
+ resultType = NullaryMethodType(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+)
+
+scala> :type -v def f[T >: Null] = 5
+// Type signature
+[T >: Null]=> Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T >: Null))
+ resultType = NullaryMethodType(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+)
+
+scala> :type -v def f[T <: String] = 5
+// Type signature
+[T <: String]=> Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T <: String))
+ resultType = NullaryMethodType(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+)
+
+scala> :type -v def f[T]() = 5
+// Type signature
+[T]()Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T))
+ resultType = NullaryMethodType(
+ resultType = TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+)
+
+scala> :type -v def f[T, U]() = 5
+// Type signature
+[T, U]()Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T), TypeParam(U))
+ resultType = NullaryMethodType(
+ resultType = TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+)
+
+scala> :type -v def f[T, U]()() = 5
+// Type signature
+[T, U]()()Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T), TypeParam(U))
+ resultType = NullaryMethodType(
+ resultType = NullaryMethodType(
+ resultType = TypeRef(
+ TypeSymbol(final class Int extends AnyVal)
+ )
+ )
+ )
+)
+
+scala> :type -v def f[T, U <: T] = 5
+// Type signature
+[T, U <: T]=> Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T), TypeParam(U <: T))
+ resultType = NullaryMethodType(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+)
+
+scala> :type -v def f[T, U <: T](x: T)(y: U) = 5
+// Type signature
+[T, U <: T](x: T)(y: U)Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T), TypeParam(U <: T))
+ resultType = MethodType(
+ params = List(TermSymbol(x: T))
+ resultType = MethodType(
+ params = List(TermSymbol(y: U))
+ resultType = TypeRef(
+ TypeSymbol(final class Int extends AnyVal)
+ )
+ )
+ )
+)
+
+scala> :type -v def f[T: Ordering] = 5
+// Type signature
+[T](implicit evidence$1: Ordering[T])Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T))
+ resultType = MethodType(
+ params = List(TermSymbol(implicit evidence$1: Ordering[T]))
+ resultType = TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+)
+
+scala> :type -v def f[T: Ordering] = implicitly[Ordering[T]]
+// Type signature
+[T](implicit evidence$1: Ordering[T])Ordering[T]
+
+// Internal Type structure
+PolyType(
+ typeParams = List(TypeParam(T))
+ resultType = MethodType(
+ params = List(TermSymbol(implicit evidence$1: Ordering[T]))
+ resultType = AliasTypeRef(
+ Alias(type Ordering[T] = scala.math.Ordering[T])
+ args = List(TypeParamTypeRef(TypeParam(T)))
+ normalize = TypeRef(
+ TypeSymbol(
+ abstract trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializable
+
+ )
+ args = List(TypeParamTypeRef(TypeParam(T)))
+ )
+ )
+ )
+)
+
+scala> :type -v def f[T <: { type Bippy = List[Int] ; def g(): Bippy }] = 5
+// Type signature
+[T <: AnyRef{type Bippy = List[Int]; def g(): this.Bippy}]=> Int
+
+// Internal Type structure
+PolyType(
+ typeParams = List(
+ TypeParam(
+ T <: AnyRef{type Bippy = List[Int]; def g(): this.Bippy}
+ )
+ )
+ resultType = NullaryMethodType(
+ TypeRef(TypeSymbol(final class Int extends AnyVal))
+ )
+)
+
+scala>
+
+scala>
diff --git a/test/files/run/repl-type-verbose.scala b/test/files/run/repl-type-verbose.scala
new file mode 100644
index 0000000000..10c390550a
--- /dev/null
+++ b/test/files/run/repl-type-verbose.scala
@@ -0,0 +1,20 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+ |// verbose!
+ |:type -v def f = 5
+ |:type -v def f() = 5
+ |:type -v def f[T] = 5
+ |:type -v def f[T >: Null] = 5
+ |:type -v def f[T <: String] = 5
+ |:type -v def f[T]() = 5
+ |:type -v def f[T, U]() = 5
+ |:type -v def f[T, U]()() = 5
+ |:type -v def f[T, U <: T] = 5
+ |:type -v def f[T, U <: T](x: T)(y: U) = 5
+ |:type -v def f[T: Ordering] = 5
+ |:type -v def f[T: Ordering] = implicitly[Ordering[T]]
+ |:type -v def f[T <: { type Bippy = List[Int] ; def g(): Bippy }] = 5
+ """.stripMargin
+}
diff --git a/test/files/run/si4750.check b/test/files/run/si4750.check
new file mode 100644
index 0000000000..bf55f70df3
--- /dev/null
+++ b/test/files/run/si4750.check
@@ -0,0 +1 @@
+US$ 5.80
diff --git a/test/files/run/si4750.scala b/test/files/run/si4750.scala
new file mode 100644
index 0000000000..96d2c4fec7
--- /dev/null
+++ b/test/files/run/si4750.scala
@@ -0,0 +1,7 @@
+import scala.util.matching.Regex
+
+object Test extends App {
+ val input = "CURRENCY 5.80"
+ println("CURRENCY".r.replaceAllIn(input, Regex quoteReplacement "US$"))
+}
+
diff --git a/test/files/run/t0421.check b/test/files/run/t0421-new.check
index cdcf042f19..cdcf042f19 100644
--- a/test/files/run/t0421.check
+++ b/test/files/run/t0421-new.check
diff --git a/test/files/run/t0421-new.scala b/test/files/run/t0421-new.scala
new file mode 100644
index 0000000000..7de6b7f2c4
--- /dev/null
+++ b/test/files/run/t0421-new.scala
@@ -0,0 +1,30 @@
+// ticket #421
+object Test extends App {
+
+ def transpose[A: ArrayTag](xss: Array[Array[A]]) = {
+ for (i <- Array.range(0, xss(0).length)) yield
+ for (xs <- xss) yield xs(i)
+ }
+
+ def scalprod(xs: Array[Double], ys: Array[Double]) = {
+ var acc = 0.0
+ for ((x, y) <- xs zip ys) acc = acc + x * y
+ acc
+ }
+
+ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
+ val ysst = transpose(yss)
+ val ysst1: Array[Array[Double]] = yss.transpose
+ assert(ysst.deep == ysst1.deep)
+ for (xs <- xss) yield
+ for (yst <- ysst) yield
+ scalprod(xs, yst)
+ }
+
+ val a1 = Array(Array(0, 2, 4), Array(1, 3, 5))
+ println(transpose(a1).deep.mkString("[", ",", "]"))
+
+ println(matmul(Array(Array(2, 3)), Array(Array(5), Array(7))).deep.mkString("[", ",", "]"))
+
+ println(matmul(Array(Array(4)), Array(Array(6, 8))).deep.mkString("[", ",", "]"))
+}
diff --git a/test/files/run/t0421-old.check b/test/files/run/t0421-old.check
new file mode 100644
index 0000000000..cdcf042f19
--- /dev/null
+++ b/test/files/run/t0421-old.check
@@ -0,0 +1,3 @@
+[Array(0, 1),Array(2, 3),Array(4, 5)]
+[Array(31.0)]
+[Array(24.0, 32.0)]
diff --git a/test/files/run/t0421.scala b/test/files/run/t0421-old.scala
index 8d51013924..8d51013924 100644
--- a/test/files/run/t0421.scala
+++ b/test/files/run/t0421-old.scala
diff --git a/test/files/run/t0677-new.scala b/test/files/run/t0677-new.scala
new file mode 100644
index 0000000000..bf7a3971dc
--- /dev/null
+++ b/test/files/run/t0677-new.scala
@@ -0,0 +1,8 @@
+object Test extends App {
+ class X[T: ArrayTag] {
+ val a = Array.ofDim[T](3, 4)
+ }
+ val x = new X[String]
+ x.a(1)(2) = "hello"
+ assert(x.a(1)(2) == "hello")
+}
diff --git a/test/files/run/t0677.scala b/test/files/run/t0677-old.scala
index 6c8a3a7e99..6c8a3a7e99 100644
--- a/test/files/run/t0677.scala
+++ b/test/files/run/t0677-old.scala
diff --git a/test/files/run/t1195-new.check b/test/files/run/t1195-new.check
new file mode 100644
index 0000000000..554e3fd03d
--- /dev/null
+++ b/test/files/run/t1195-new.check
@@ -0,0 +1,6 @@
+ConcreteTypeTag[Bar.type], underlying = <: scala.runtime.AbstractFunction1[Int,Bar] with Serializable{case def unapply(x$0: Bar): Option[Int]} with Singleton
+ConcreteTypeTag[Bar], underlying = <: Product with Serializable{val x: Int; def copy(x: Int): Bar; def copy$default$1: Int; def _1: Int}
+ConcreteTypeTag[Product with Serializable], underlying = Product with Serializable
+ConcreteTypeTag[Bar.type], underlying = <: scala.runtime.AbstractFunction1[Int,Bar] with Serializable{case def unapply(x$0: Bar): Option[Int]} with Singleton
+ConcreteTypeTag[Bar], underlying = <: Product with Serializable{val x: Int; def copy(x: Int): Bar; def copy$default$1: Int; def _1: Int}
+ConcreteTypeTag[Product with Serializable], underlying = Product with Serializable
diff --git a/test/files/run/t1195-new.scala b/test/files/run/t1195-new.scala
new file mode 100644
index 0000000000..6f28a4a167
--- /dev/null
+++ b/test/files/run/t1195-new.scala
@@ -0,0 +1,26 @@
+object Test {
+ def f() = { case class Bar(x: Int); Bar }
+ def g() = { case class Bar(x: Int); Bar(5) }
+ def h() = { case object Bar ; Bar }
+
+ val f1 = f()
+ val g1 = g()
+ val h1 = h()
+
+ def m[T: TypeTag](x: T) = println(typeTag[T] + ", underlying = " + typeTag[T].sym.typeSignature)
+
+ def main(args: Array[String]): Unit = {
+ m(f)
+ m(g)
+ m(h)
+ m(f1)
+ m(g1)
+ m(h1)
+ }
+}
+
+class A1[T] {
+ class B1[U] {
+ def f = { case class D(x: Int) extends A1[String] ; new D(5) }
+ }
+}
diff --git a/test/files/run/t1195.check b/test/files/run/t1195-old.check
index d023bc91f7..eb60eceb17 100644
--- a/test/files/run/t1195.check
+++ b/test/files/run/t1195-old.check
@@ -1,6 +1,6 @@
-_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
-_ <: Object with scala.Product with scala.Serializable
-Object with scala.Product with scala.Serializable
-_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
-_ <: Object with scala.Product with scala.Serializable
-Object with scala.Product with scala.Serializable
+_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
+_ <: Object with scala.Product with scala.Serializable
+Object with scala.Product with scala.Serializable
+_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object
+_ <: Object with scala.Product with scala.Serializable
+Object with scala.Product with scala.Serializable
diff --git a/test/files/run/t1195.scala b/test/files/run/t1195-old.scala
index 81ef5bdb0e..b46a3b70f5 100644
--- a/test/files/run/t1195.scala
+++ b/test/files/run/t1195-old.scala
@@ -6,7 +6,7 @@ object Test {
val f1 = f()
val g1 = g()
val h1 = h()
-
+
def m[T: Manifest](x: T) = println(manifest[T])
def main(args: Array[String]): Unit = {
diff --git a/test/files/run/t2236-new.scala b/test/files/run/t2236-new.scala
new file mode 100644
index 0000000000..bbabe8e7d9
--- /dev/null
+++ b/test/files/run/t2236-new.scala
@@ -0,0 +1,17 @@
+class T[A](implicit val m:TypeTag[A])
+class Foo
+class Bar extends T[Foo]
+object Test extends App {
+ new Bar
+}
+
+object EvidenceTest {
+ trait E[T]
+ trait A[T] { implicit val e: E[T] = null }
+ class B[T : E] extends A[T] { override val e = null }
+
+ def f[T] {
+ implicit val e: E[T] = null
+ new B[T]{}
+ }
+}
diff --git a/test/files/run/t2236.scala b/test/files/run/t2236-old.scala
index 64ed18c805..64ed18c805 100755..100644
--- a/test/files/run/t2236.scala
+++ b/test/files/run/t2236-old.scala
diff --git a/test/files/run/t2386-new.check b/test/files/run/t2386-new.check
new file mode 100644
index 0000000000..98e226f946
--- /dev/null
+++ b/test/files/run/t2386-new.check
@@ -0,0 +1,2 @@
+a(0) = Array(1, 2)
+a(1) = Array("a", "b")
diff --git a/test/files/run/t2386-new.scala b/test/files/run/t2386-new.scala
new file mode 100644
index 0000000000..15d1859759
--- /dev/null
+++ b/test/files/run/t2386-new.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ val a = Array(Array(1, 2), Array("a","b"))
+ println("a(0) = Array(" + (a(0) mkString ", ") + ")")
+ println("a(1) = Array(" + (a(1) map (s => "\"" + s + "\"") mkString ", ") + ")")
+}
diff --git a/test/files/run/t2886.check b/test/files/run/t2886.check
index 5fe1e73a45..8d97a82799 100644
--- a/test/files/run/t2886.check
+++ b/test/files/run/t2886.check
@@ -1,5 +1,5 @@
-((x: scala.Predef.String) => {
- val x$1 = x;
- val x$2 = x;
- Test.test(x$2, x$1)
-})
+((x: String) => {
+ val x$1 = x;
+ val x$2 = x;
+ Test.this.test(x$2, x$1)
+})
diff --git a/test/files/run/t2886.scala b/test/files/run/t2886.scala
new file mode 100644
index 0000000000..e0835a0a44
--- /dev/null
+++ b/test/files/run/t2886.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test {
+ def test(name: String, address: String) = null
+ def main(args: Array[String]) = {
+ val tree = reify((x:String) => test(address=x,name=x)).tree
+ println(tree)
+ }
+}
diff --git a/test/files/run/t3507-new.check b/test/files/run/t3507-new.check
new file mode 100644
index 0000000000..6e4fa4170e
--- /dev/null
+++ b/test/files/run/t3507-new.check
@@ -0,0 +1 @@
+ConcreteTypeTag[_1.b.c.type]
diff --git a/test/files/run/t3507-new.scala b/test/files/run/t3507-new.scala
new file mode 100644
index 0000000000..c7a529e8b8
--- /dev/null
+++ b/test/files/run/t3507-new.scala
@@ -0,0 +1,15 @@
+class A {
+ object b {
+ object c
+ }
+ def m = b.c
+}
+
+object Test extends App {
+ var a: A = new A // mutable
+ val c /*: object _1.b.c forSome { val _1: A } */ = a.m // widening using existential
+
+ def mani[T: TypeTag](x: T) = println(typeTag[T])
+ mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier
+ // --> _1 is not in scope here
+} \ No newline at end of file
diff --git a/test/files/run/t3569.check b/test/files/run/t3569.check
index 24cee4bf00..c73fce419a 100644
--- a/test/files/run/t3569.check
+++ b/test/files/run/t3569.check
@@ -8,10 +8,10 @@ private int Test$X.lval3
private int Test$X.var1
private int Test$X.var2
private int Test$X.var3
+private int Test$X.x
private volatile int Test$X.bitmap$priv$0
-public int Test$X.x
public volatile int Test$X.bitmap$0
-public final int Test$Y.z1
-public final int Test$Y.z2
-public int Test$Y.x
-public int Test$Y.y
+private final int Test$Y.z1
+private final int Test$Y.z2
+private int Test$Y.x
+private int Test$Y.y
diff --git a/test/files/run/t3758.scala b/test/files/run/t3758-old.scala
index 18750b0a9c..f00254afee 100644
--- a/test/files/run/t3758.scala
+++ b/test/files/run/t3758-old.scala
@@ -7,4 +7,4 @@ object Test {
assert(manifest[Array[Int]].typeArguments contains manifest[Int])
assert(manifest[Array[Float]].typeArguments contains manifest[Float])
}
-}
+} \ No newline at end of file
diff --git a/test/files/run/t3835.scala b/test/files/run/t3835.scala
index 49e591195f..c120a61f6e 100644
--- a/test/files/run/t3835.scala
+++ b/test/files/run/t3835.scala
@@ -1,4 +1,9 @@
object Test extends App {
- println((1, 2, 3) match { case (r, \u03b8, \u03c6) => r + \u03b8 + \u03c6 })
- println(1 match { case \u00e9 => \u00e9 })
+ // work around optimizer bug SI-5672 -- generates wrong bytecode for switches in arguments
+ // virtpatmat happily emits a switch for a one-case switch, whereas -Xoldpatmat did not
+ // this is not the focus of this test, hence the temporary workaround
+ def a = (1, 2, 3) match { case (r, \u03b8, \u03c6) => r + \u03b8 + \u03c6 }
+ println(a)
+ def b = (1 match { case \u00e9 => \u00e9 })
+ println(b)
}
diff --git a/test/files/run/t4110-new.check b/test/files/run/t4110-new.check
new file mode 100644
index 0000000000..28f220e1fe
--- /dev/null
+++ b/test/files/run/t4110-new.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[Test.A with Test.B]
+ConcreteTypeTag[Test.A with Test.B]
diff --git a/test/files/run/t4110-new.scala b/test/files/run/t4110-new.scala
new file mode 100644
index 0000000000..3285b82c61
--- /dev/null
+++ b/test/files/run/t4110-new.scala
@@ -0,0 +1,11 @@
+object Test extends App {
+ def inferredType[T : TypeTag](v : T) = println(typeTag[T])
+
+ trait A
+ trait B
+
+ inferredType(new A with B)
+
+ val name = new A with B
+ inferredType(name)
+} \ No newline at end of file
diff --git a/test/files/run/t4110.check b/test/files/run/t4110-old.check
index 8b005989de..8b005989de 100644
--- a/test/files/run/t4110.check
+++ b/test/files/run/t4110-old.check
diff --git a/test/files/run/t4110.scala b/test/files/run/t4110-old.scala
index 4bd377b73e..a42646ce52 100644
--- a/test/files/run/t4110.scala
+++ b/test/files/run/t4110-old.scala
@@ -3,7 +3,7 @@ object Test extends App {
trait A
trait B
-
+
inferredType(new A with B)
val name = new A with B
diff --git a/test/files/run/t4172.check b/test/files/run/t4172.check
index da467e27ea..4598e02d1f 100644
--- a/test/files/run/t4172.check
+++ b/test/files/run/t4172.check
@@ -4,6 +4,8 @@ Type :help for more information.
scala>
scala> val c = { class C { override def toString = "C" }; ((new C, new C { def f = 2 })) }
+warning: there were 1 feature warnings; re-run with -feature for details
+warning: there were 1 feature warnings; re-run with -feature for details
c: (C, C{def f: Int}) forSome { type C <: Object } = (C,C)
scala>
diff --git a/test/files/run/t4317/S_1.scala b/test/files/run/t4317/S_1.scala
index 2de408268c..2756c879eb 100644
--- a/test/files/run/t4317/S_1.scala
+++ b/test/files/run/t4317/S_1.scala
@@ -1,3 +1,5 @@
+import language.existentials
+
object S_1 {
def foo1(x: Class[_ <: AnyRef]) = 0
def foo2(x: Class[_ <: AnyRef], y: Int) = 99
diff --git a/test/files/run/t4658.check b/test/files/run/t4658.check
index 743b0faee3..bb6405175e 100644
--- a/test/files/run/t4658.check
+++ b/test/files/run/t4658.check
@@ -19,8 +19,8 @@ Ranges:
-30
-10
IntRanges:
-Disabled #1
-Disabled #2
+-1073741824
+-1073741824
0
0
55
@@ -39,8 +39,8 @@ Disabled #2
-30
-10
LongRanges:
-Disabled #1
-Disabled #2
+2305843008139952128
+-2305843008139952128
0
0
55
@@ -59,8 +59,8 @@ Disabled #2
-30
-10
BigIntRanges:
-Disabled #1
-Disabled #2
+2305843008139952128
+-2305843008139952128
0
0
55
diff --git a/test/files/run/t4658.scala b/test/files/run/t4658.scala
index e1799fae9b..8c07c50694 100644
--- a/test/files/run/t4658.scala
+++ b/test/files/run/t4658.scala
@@ -20,22 +20,14 @@ object Test {
def numericBigIntRanges = rangeData.map(r => if (r.inclusive) NumericRange.inclusive(BigInt(r.start), BigInt(r.end), BigInt(r.step)) else NumericRange(BigInt(r.start), BigInt(r.end), BigInt(r.step)))
def main(args: Array[String]) {
- // We drop the first two tests for all ranges which don't have a decent sum implementation,
- // because it is just too slow.
println("Ranges:")
ranges.foreach{range => println(range.sum)}
println("IntRanges:")
- println("Disabled #1")
- println("Disabled #2")
- numericIntRanges.drop(2).foreach{range => println(range.sum)}
+ numericIntRanges.foreach{range => println(range.sum)}
println("LongRanges:")
- println("Disabled #1")
- println("Disabled #2")
- numericLongRanges.drop(2).foreach{range => println(range.sum)}
+ numericLongRanges.foreach{range => println(range.sum)}
println("BigIntRanges:")
- println("Disabled #1")
- println("Disabled #2")
- numericBigIntRanges.drop(2).foreach{range => println(range.sum)}
+ numericBigIntRanges.foreach{range => println(range.sum)}
}
} \ No newline at end of file
diff --git a/test/files/run/t4710.check b/test/files/run/t4710.check
index aa2f08d452..7c2b10b098 100644
--- a/test/files/run/t4710.check
+++ b/test/files/run/t4710.check
@@ -2,6 +2,7 @@ Type in expressions to have them evaluated.
Type :help for more information.
scala> def method : String = { implicit def f(s: Symbol) = "" ; 'symbol }
+warning: there were 1 feature warnings; re-run with -feature for details
method: String
scala>
diff --git a/test/files/run/t5224.check b/test/files/run/t5224.check
index 28bc75d4fd..c754f23551 100644
--- a/test/files/run/t5224.check
+++ b/test/files/run/t5224.check
@@ -1,9 +1,9 @@
-{
- @new Foo(bar = "qwe") class C extends scala.AnyRef {
- def <init>() = {
- super.<init>();
- ()
- }
- };
- ()
-}
+{
+ @new Foo(bar = "qwe") class C extends Object {
+ def <init>() = {
+ super.<init>();
+ ()
+ }
+ };
+ ()
+}
diff --git a/test/files/run/t5224.scala b/test/files/run/t5224.scala
index 2226a69a05..93b244e03e 100644
--- a/test/files/run/t5224.scala
+++ b/test/files/run/t5224.scala
@@ -1,9 +1,8 @@
-import scala.reflect._
-import scala.reflect.api._
+import scala.reflect.mirror._
class Foo(bar: String) extends ClassfileAnnotation
object Test extends App {
- val tree = scala.reflect.Code.lift{@Foo(bar = "qwe") class C}.tree
+ val tree = reify{@Foo(bar = "qwe") class C}.tree
println(tree.toString)
} \ No newline at end of file
diff --git a/test/files/run/t5225_1.check b/test/files/run/t5225_1.check
index 719da572c7..40db2468b1 100644
--- a/test/files/run/t5225_1.check
+++ b/test/files/run/t5225_1.check
@@ -1,4 +1,4 @@
-{
- @new transient() @new volatile() var x: Int = 2;
- ()
-}
+{
+ @new transient() @new volatile() var x = 2;
+ ()
+}
diff --git a/test/files/run/t5225_1.scala b/test/files/run/t5225_1.scala
index a655b7dd71..5e1d3b1f17 100644
--- a/test/files/run/t5225_1.scala
+++ b/test/files/run/t5225_1.scala
@@ -1,7 +1,6 @@
-import scala.reflect._
-import scala.reflect.api._
+import scala.reflect.mirror._
object Test extends App {
- val tree = scala.reflect.Code.lift{@transient @volatile var x = 2}.tree
+ val tree = reify{@transient @volatile var x = 2}.tree
println(tree.toString)
} \ No newline at end of file
diff --git a/test/files/run/t5225_2.check b/test/files/run/t5225_2.check
index c4f6b4761e..8cd2ddc1a4 100644
--- a/test/files/run/t5225_2.check
+++ b/test/files/run/t5225_2.check
@@ -1,4 +1,4 @@
-{
- def foo(@new cloneable() x: Int): String = "";
- ()
-}
+{
+ def foo(@new cloneable() x: Int) = "";
+ ()
+}
diff --git a/test/files/run/t5225_2.scala b/test/files/run/t5225_2.scala
index 65ea9b2f73..4cab640fe8 100644
--- a/test/files/run/t5225_2.scala
+++ b/test/files/run/t5225_2.scala
@@ -1,7 +1,6 @@
-import scala.reflect._
-import scala.reflect.api._
+import scala.reflect.mirror._
object Test extends App {
- val tree = scala.reflect.Code.lift{def foo(@cloneable x: Int) = ""}.tree
+ val tree = reify{def foo(@cloneable x: Int) = ""}.tree
println(tree.toString)
} \ No newline at end of file
diff --git a/test/files/run/t5229_1.scala b/test/files/run/t5229_1.scala
index d5af569656..273079a89d 100644
--- a/test/files/run/t5229_1.scala
+++ b/test/files/run/t5229_1.scala
@@ -1,13 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
object C
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5229_2.scala b/test/files/run/t5229_2.scala
index 07f9ac6b84..85bf78ba31 100644
--- a/test/files/run/t5229_2.scala
+++ b/test/files/run/t5229_2.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
object C {
val x = 2
}
@@ -11,8 +9,7 @@ object Test extends App {
println(C.x)
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val evaluated = toolbox.runExpr(code.tree)
println("evaluated = " + evaluated)
}
diff --git a/test/files/run/t5230.scala b/test/files/run/t5230.scala
index d3106ca05c..e0632f591c 100644
--- a/test/files/run/t5230.scala
+++ b/test/files/run/t5230.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
class C {
val x = 2
}
@@ -11,8 +9,7 @@ object Test extends App {
println(new C().x)
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val evaluated = toolbox.runExpr(code.tree)
println("evaluated = " + evaluated)
}
diff --git a/test/files/run/t5258a.scala b/test/files/run/t5258a.scala
deleted file mode 100644
index 8cc4249e06..0000000000
--- a/test/files/run/t5258a.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
-object Test extends App {
- val code = scala.reflect.Code.lift{
- println(classOf[Int])
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
-} \ No newline at end of file
diff --git a/test/files/run/t5266_1.scala b/test/files/run/t5266_1.scala
index 4262bc7a7b..ebb432be71 100644
--- a/test/files/run/t5266_1.scala
+++ b/test/files/run/t5266_1.scala
@@ -1,15 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
def x = 2
println(x)
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val evaluated = toolbox.runExpr(code.tree)
println("evaluated = " + evaluated)
} \ No newline at end of file
diff --git a/test/files/run/t5266_2.scala b/test/files/run/t5266_2.scala
index d0f718dbd7..27c91c35a8 100644
--- a/test/files/run/t5266_2.scala
+++ b/test/files/run/t5266_2.scala
@@ -1,16 +1,13 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
def x = 2
def y = x
println(y)
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val evaluated = toolbox.runExpr(code.tree)
println("evaluated = " + evaluated)
}
diff --git a/test/files/run/t5269.scala b/test/files/run/t5269.scala
index cab99f17e6..9026090b29 100644
--- a/test/files/run/t5269.scala
+++ b/test/files/run/t5269.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
trait Z {
val z = 2
}
@@ -13,9 +11,5 @@ object Test extends App {
}
new X().println()
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5270.scala b/test/files/run/t5270.scala
index 934cc13dea..476b610148 100644
--- a/test/files/run/t5270.scala
+++ b/test/files/run/t5270.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class Y {
def y = 100
}
@@ -17,9 +15,5 @@ object Test extends App {
}
new X().println()
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5271_1.check b/test/files/run/t5271_1.check
index 9b956da17a..5245173228 100644
--- a/test/files/run/t5271_1.check
+++ b/test/files/run/t5271_1.check
@@ -1,11 +1,12 @@
-{
- case class C extends Object with Product with Serializable {
- <caseaccessor> <paramaccessor> val foo : Int = _;
- <caseaccessor> <paramaccessor> val bar : Int = _;
- def <init>(foo: Int, bar: Int) = {
- super.<init>();
- ()
- }
- };
- ()
-}
+{
+ case class C extends Product with Serializable {
+ <caseaccessor> <paramaccessor> val foo: Int = _;
+ <caseaccessor> <paramaccessor> val bar: Int = _;
+ def <init>(foo: Int, bar: Int) = {
+ super.<init>();
+ ()
+ }
+ };
+ ()
+}
+()
diff --git a/test/files/run/t5271_1.scala b/test/files/run/t5271_1.scala
index fbc57aead7..20cafa6a08 100644
--- a/test/files/run/t5271_1.scala
+++ b/test/files/run/t5271_1.scala
@@ -1,13 +1,11 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
case class C(foo: Int, bar: Int)
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
println(code.tree)
+ println(code.eval)
}
diff --git a/test/files/run/t5271_2.check b/test/files/run/t5271_2.check
index 27297febb6..0765b3a6a4 100644
--- a/test/files/run/t5271_2.check
+++ b/test/files/run/t5271_2.check
@@ -1,12 +1,14 @@
-{
- case class C extends Object with Product with Serializable {
- <caseaccessor> <paramaccessor> val foo : Int = _;
- <caseaccessor> <paramaccessor> val bar : Int = _;
- def <init>(foo: Int, bar: Int) = {
- super.<init>();
- ()
- }
- };
- val c = C.apply(2, 2);
- scala.this.Predef.println(c.foo.$times(c.bar))
-}
+{
+ case class C extends Product with Serializable {
+ <caseaccessor> <paramaccessor> val foo: Int = _;
+ <caseaccessor> <paramaccessor> val bar: Int = _;
+ def <init>(foo: Int, bar: Int) = {
+ super.<init>();
+ ()
+ }
+ };
+ val c = C.apply(2, 2);
+ scala.this.Predef.println(c.foo.$times(c.bar))
+}
+4
+()
diff --git a/test/files/run/t5271_2.scala b/test/files/run/t5271_2.scala
index 4bfc574e00..af6491407c 100644
--- a/test/files/run/t5271_2.scala
+++ b/test/files/run/t5271_2.scala
@@ -1,15 +1,13 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
case class C(foo: Int, bar: Int)
val c = C(2, 2)
println(c.foo * c.bar)
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
println(code.tree)
+ println(code.eval)
}
diff --git a/test/files/run/t5271_3.check b/test/files/run/t5271_3.check
index 9331c78959..2b920a36a8 100644
--- a/test/files/run/t5271_3.check
+++ b/test/files/run/t5271_3.check
@@ -1,19 +1,21 @@
-{
- object C extends scala.AnyRef with Serializable {
- def <init>() = {
- super.<init>();
- ()
- };
- def qwe: Int = 4
- };
- case class C extends Object with Product with Serializable {
- <caseaccessor> <paramaccessor> val foo : Int = _;
- <caseaccessor> <paramaccessor> val bar : Int = _;
- def <init>(foo: Int, bar: Int) = {
- super.<init>();
- ()
- }
- };
- val c = C.apply(2, 2);
- scala.this.Predef.println(c.foo.$times(c.bar).$eq$eq(C.qwe))
-}
+{
+ object C extends Object {
+ def <init>() = {
+ super.<init>();
+ ()
+ };
+ def qwe = 4
+ };
+ case class C extends Product with Serializable {
+ <caseaccessor> <paramaccessor> val foo: Int = _;
+ <caseaccessor> <paramaccessor> val bar: Int = _;
+ def <init>(foo: Int, bar: Int) = {
+ super.<init>();
+ ()
+ }
+ };
+ val c = C.apply(2, 2);
+ scala.this.Predef.println(c.foo.$times(c.bar).$eq$eq(C.qwe))
+}
+true
+()
diff --git a/test/files/run/t5271_3.scala b/test/files/run/t5271_3.scala
index a085bdca4c..646b10a8e5 100644
--- a/test/files/run/t5271_3.scala
+++ b/test/files/run/t5271_3.scala
@@ -1,16 +1,14 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
object C { def qwe = 4 }
case class C(foo: Int, bar: Int)
val c = C(2, 2)
println(c.foo * c.bar == C.qwe)
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
println(code.tree)
+ println(code.eval)
}
diff --git a/test/files/run/t5271_4.scala b/test/files/run/t5271_4.scala
index c253b1adca..e13a331d9c 100644
--- a/test/files/run/t5271_4.scala
+++ b/test/files/run/t5271_4.scala
@@ -1,13 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
case object C
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5272_1.flags b/test/files/run/t5272_1.flags
new file mode 100644
index 0000000000..cb8324a345
--- /dev/null
+++ b/test/files/run/t5272_1.flags
@@ -0,0 +1 @@
+-Xoldpatmat \ No newline at end of file
diff --git a/test/files/run/t5272_1.scala b/test/files/run/t5272_1.scala
index 882287f033..46472babf3 100644
--- a/test/files/run/t5272_1.scala
+++ b/test/files/run/t5272_1.scala
@@ -1,16 +1,10 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
2 match {
case 2 => println("okay")
case _ => println("not okay")
}
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5272_2.flags b/test/files/run/t5272_2.flags
new file mode 100644
index 0000000000..cb8324a345
--- /dev/null
+++ b/test/files/run/t5272_2.flags
@@ -0,0 +1 @@
+-Xoldpatmat \ No newline at end of file
diff --git a/test/files/run/t5272_2.scala b/test/files/run/t5272_2.scala
index 48b6a670bb..f5bab44205 100644
--- a/test/files/run/t5272_2.scala
+++ b/test/files/run/t5272_2.scala
@@ -1,15 +1,9 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
2 match {
case x => println("okay" + x)
}
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5273_1.flags b/test/files/run/t5273_1.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/run/t5273_1.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/run/t5273_1.scala b/test/files/run/t5273_1.scala
index 80460a4ae6..1b491923b2 100644
--- a/test/files/run/t5273_1.scala
+++ b/test/files/run/t5273_1.scala
@@ -1,16 +1,10 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
List(1, 2, 3) match {
case foo :: bar :: _ => println(foo * bar)
case _ => println("this is getting out of hand!")
}
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5273_2a.flags b/test/files/run/t5273_2a.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/run/t5273_2a.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/run/t5273_2a.scala b/test/files/run/t5273_2a.scala
index a7a336d8a7..062ff79d11 100644
--- a/test/files/run/t5273_2a.scala
+++ b/test/files/run/t5273_2a.scala
@@ -1,14 +1,8 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
val foo :: bar :: _ = List(1, 2, 3)
println(foo * bar)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5273_2b.flags b/test/files/run/t5273_2b.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/run/t5273_2b.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/run/t5273_2b.scala b/test/files/run/t5273_2b.scala
index 85c40f0607..82f1de89f7 100644
--- a/test/files/run/t5273_2b.scala
+++ b/test/files/run/t5273_2b.scala
@@ -1,15 +1,9 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
val RegexParser = """(.*) \d+([A-Z]+) \| (.*) \|.*""".r
val RegexParser(name, shortname, value) = "American Dollar 1USD | 2,8567 | sometext"
println("name = %s, shortname = %s, value = %s".format(name, shortname, value))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5274_1.scala b/test/files/run/t5274_1.scala
index 74a5b81bcb..7ef332aa05 100644
--- a/test/files/run/t5274_1.scala
+++ b/test/files/run/t5274_1.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
def factorial(n: BigInt): BigInt =
if (n == 0) 1 else n * factorial(n-1)
@@ -11,9 +9,5 @@ object Test extends App {
println("50! = " + f50)
println("49! = " + f49)
println("50!/49! = " + (f50 / f49))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5274_2.scala b/test/files/run/t5274_2.scala
index 5984a64967..0b373b358f 100644
--- a/test/files/run/t5274_2.scala
+++ b/test/files/run/t5274_2.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
/** Nested methods can use and even update everything
* visible in their scope (including local variables or
* arguments of enclosing methods).
@@ -48,9 +46,5 @@ object Test extends App {
println(ar)
sort(ar)
println(ar)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5275.scala b/test/files/run/t5275.scala
index 285d8a18a4..534672be3c 100644
--- a/test/files/run/t5275.scala
+++ b/test/files/run/t5275.scala
@@ -1,14 +1,8 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class C(val foo: Int)
println(new C(2).foo)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5276_1a.scala b/test/files/run/t5276_1a.scala
index b717675824..a6e327c0e7 100644
--- a/test/files/run/t5276_1a.scala
+++ b/test/files/run/t5276_1a.scala
@@ -1,14 +1,8 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
lazy val x = 2
println(x)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5276_1b.scala b/test/files/run/t5276_1b.scala
index 1ff25504ca..1bc3e246c9 100644
--- a/test/files/run/t5276_1b.scala
+++ b/test/files/run/t5276_1b.scala
@@ -1,14 +1,8 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
implicit lazy val x = 2
println(implicitly[Int])
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5276_2a.scala b/test/files/run/t5276_2a.scala
index af5ff2a565..cdd87ddc9e 100644
--- a/test/files/run/t5276_2a.scala
+++ b/test/files/run/t5276_2a.scala
@@ -1,17 +1,11 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class C {
lazy val x = 2
}
println(new C().x)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5276_2b.scala b/test/files/run/t5276_2b.scala
index 63904b2898..2fac951731 100644
--- a/test/files/run/t5276_2b.scala
+++ b/test/files/run/t5276_2b.scala
@@ -1,18 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class C {
implicit lazy val x = 2
def y = implicitly[Int]
}
println(new C().y)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5277_1.scala b/test/files/run/t5277_1.scala
index 0aaec7cdf2..f95e9ab6ec 100644
--- a/test/files/run/t5277_1.scala
+++ b/test/files/run/t5277_1.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
def fact(n: Int): BigInt =
if (n == 0) 1 else fact(n-1) * n
class Factorizer(n: Int) {
@@ -12,9 +10,5 @@ object Test extends App {
implicit def int2fact(n: Int) = new Factorizer(n)
println("10! = " + (10!))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5277_2.scala b/test/files/run/t5277_2.scala
index 91ed55122a..5f1737f503 100644
--- a/test/files/run/t5277_2.scala
+++ b/test/files/run/t5277_2.scala
@@ -1,17 +1,11 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
def p(implicit i: Int) = print(i)
implicit val v = 2
println(p)
println(p(1))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5279.scala b/test/files/run/t5279.scala
index cef58535d5..aab5588877 100644
--- a/test/files/run/t5279.scala
+++ b/test/files/run/t5279.scala
@@ -1,13 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
println(new Integer(10))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5334_1.scala b/test/files/run/t5334_1.scala
index 9887bebf78..49dbea6b68 100644
--- a/test/files/run/t5334_1.scala
+++ b/test/files/run/t5334_1.scala
@@ -1,14 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
class C { override def toString = "C" }
- new C
+ val ret = new C
+ ret.asInstanceOf[Object]
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
println(toolbox.runExpr(code.tree))
}
diff --git a/test/files/run/t5334_2.scala b/test/files/run/t5334_2.scala
index 775a05aaf7..c6a77158dd 100644
--- a/test/files/run/t5334_2.scala
+++ b/test/files/run/t5334_2.scala
@@ -1,14 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ val code = reify {
class C { override def toString() = "C" }
- List((new C, new C))
+ val ret = List((new C, new C))
+ ret.asInstanceOf[List[Any]]
};
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
println(toolbox.runExpr(code.tree))
}
diff --git a/test/files/run/t5335.scala b/test/files/run/t5335.scala
index 8e2ed59db6..a0fe6c5822 100644
--- a/test/files/run/t5335.scala
+++ b/test/files/run/t5335.scala
@@ -1,13 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
println(new {def x = 2}.x)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5415.scala b/test/files/run/t5415.scala
index 3db356da86..c6552f69b3 100644
--- a/test/files/run/t5415.scala
+++ b/test/files/run/t5415.scala
@@ -1,14 +1,10 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import scala.reflect.runtime.Mirror.ToolBox
-
object Test extends App{
case class Queryable2[T]() { def filter(predicate: T => Boolean) = ??? }
trait CoffeesTable{ def sales : Int }
val q = Queryable2[CoffeesTable]()
- val code = scala.reflect.Code.lift{q.filter(_.sales > 5)}
+ import scala.reflect.mirror._
+ val code = reify{q.filter(_.sales > 5)}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val ttree = toolbox.typeCheck(code.tree)
}
diff --git a/test/files/run/t5419.check b/test/files/run/t5419.check
index 7e6d739354..50751b168e 100644
--- a/test/files/run/t5419.check
+++ b/test/files/run/t5419.check
@@ -1 +1 @@
-(5: Int(5) @Foo)
+5: @Foo.asInstanceOf[Int]
diff --git a/test/files/run/t5419.scala b/test/files/run/t5419.scala
index 695786e5c4..d65d8f38c8 100644
--- a/test/files/run/t5419.scala
+++ b/test/files/run/t5419.scala
@@ -1,9 +1,8 @@
-import scala.reflect._
-import scala.reflect.api._
+import scala.reflect.mirror._
class Foo extends StaticAnnotation
object Test extends App {
- val tree = scala.reflect.Code.lift{5: @Foo}.tree
+ val tree = reify{(5: @Foo).asInstanceOf[Int]}.tree
println(tree.toString)
} \ No newline at end of file
diff --git a/test/files/run/t5423.scala b/test/files/run/t5423.scala
index fc507c417b..645c8c7c1d 100644
--- a/test/files/run/t5423.scala
+++ b/test/files/run/t5423.scala
@@ -1,7 +1,4 @@
-import java.lang.Class
import scala.reflect.mirror._
-import scala.reflect.runtime.Mirror.ToolBox
-import scala.reflect.Code
final class table extends StaticAnnotation
@table class A
diff --git a/test/files/run/t5535.check b/test/files/run/t5535.check
new file mode 100644
index 0000000000..8da9829b78
--- /dev/null
+++ b/test/files/run/t5535.check
@@ -0,0 +1,20 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> def h()(i: Int) = 1 + i
+h: ()(i: Int)Int
+
+scala> println(h()(5))
+6
+
+scala> val f = h() _
+f: Int => Int = <function1>
+
+scala> println(f(10))
+11
+
+scala>
+
+scala>
diff --git a/test/files/run/t5535.scala b/test/files/run/t5535.scala
new file mode 100644
index 0000000000..7bc12f3470
--- /dev/null
+++ b/test/files/run/t5535.scala
@@ -0,0 +1,10 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+def h()(i: Int) = 1 + i
+println(h()(5))
+val f = h() _
+println(f(10))
+ """
+}
diff --git a/test/files/run/t5583.check b/test/files/run/t5583.check
new file mode 100644
index 0000000000..39b969fbe7
--- /dev/null
+++ b/test/files/run/t5583.check
@@ -0,0 +1,20 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> var s = 0
+s: Int = 0
+
+scala> for (i <- 1 to 10) {s += i}
+
+scala> for (i <- 1 to 10) {s += i}
+
+scala> for (i <- 1 to 10) {s += i}
+
+scala> println(s)
+165
+
+scala>
+
+scala>
diff --git a/test/files/run/t5583.scala b/test/files/run/t5583.scala
new file mode 100644
index 0000000000..8561a5946f
--- /dev/null
+++ b/test/files/run/t5583.scala
@@ -0,0 +1,11 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+var s = 0
+for (i <- 1 to 10) {s += i}
+for (i <- 1 to 10) {s += i}
+for (i <- 1 to 10) {s += i}
+println(s)
+ """
+}
diff --git a/test/files/run/t5614.check b/test/files/run/t5614.check
new file mode 100644
index 0000000000..f659f2da3b
--- /dev/null
+++ b/test/files/run/t5614.check
@@ -0,0 +1,3 @@
+3
+a
+b
diff --git a/test/files/run/t5614.flags b/test/files/run/t5614.flags
new file mode 100644
index 0000000000..48fd867160
--- /dev/null
+++ b/test/files/run/t5614.flags
@@ -0,0 +1 @@
+-Xexperimental
diff --git a/test/files/run/t5614.scala b/test/files/run/t5614.scala
new file mode 100644
index 0000000000..7c85c33f12
--- /dev/null
+++ b/test/files/run/t5614.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ val str = s"a\nb"
+ println(str.length)
+ println(str)
+}
diff --git a/test/files/run/t5648.check b/test/files/run/t5648.check
new file mode 100644
index 0000000000..1140ff52e2
--- /dev/null
+++ b/test/files/run/t5648.check
@@ -0,0 +1,4 @@
+true
+true
+true
+true
diff --git a/test/files/run/t5648.flags b/test/files/run/t5648.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/run/t5648.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/run/t5648.scala b/test/files/run/t5648.scala
new file mode 100644
index 0000000000..c5cea9e1cb
--- /dev/null
+++ b/test/files/run/t5648.scala
@@ -0,0 +1,10 @@
+case class C(val s: Int*)
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ println(new C(1, 3, 7) == new C(1, 3, 7))
+ println(new C(1, 3, 7) == C(1, 3, 7))
+ println(C(1, 3, 7) == new C(1, 3, 7))
+ println(C(1, 3, 7) == C(1, 3, 7))
+ }
+}
diff --git a/test/files/run/t5680.check b/test/files/run/t5680.check
new file mode 100644
index 0000000000..9fec3b6505
--- /dev/null
+++ b/test/files/run/t5680.check
@@ -0,0 +1,3 @@
+[Lscala.runtime.BoxedUnit
+()
+()
diff --git a/test/files/run/t5680.scala b/test/files/run/t5680.scala
new file mode 100644
index 0000000000..f61cbd6e20
--- /dev/null
+++ b/test/files/run/t5680.scala
@@ -0,0 +1,7 @@
+object Test extends App {
+ val x = Array[Unit]((), ())
+ println(x.toString.substring(0, x.toString.indexOf(";")))
+ println(x(0))
+ x(1) = ()
+ println(x(1))
+} \ No newline at end of file
diff --git a/test/files/run/t5704.check b/test/files/run/t5704.check
new file mode 100644
index 0000000000..7b56bf2bfd
--- /dev/null
+++ b/test/files/run/t5704.check
@@ -0,0 +1 @@
+String \ No newline at end of file
diff --git a/test/files/run/t5704.flags b/test/files/run/t5704.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/t5704.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/t5704.scala b/test/files/run/t5704.scala
new file mode 100644
index 0000000000..8fd721d4e7
--- /dev/null
+++ b/test/files/run/t5704.scala
@@ -0,0 +1,16 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class MyQuerycollection{
+ def findUserByName( name:String ) = {
+ val tree = reify{ "test" == name }.tree
+ val toolbox = mkToolBox()
+ toolbox.typeCheck(tree) match{
+ case Apply(Select(lhs,op),rhs::Nil) =>
+ println(rhs.tpe)
+ }
+ }
+ }
+ val qc = new MyQuerycollection
+ qc.findUserByName("some value")
+}
diff --git a/test/files/run/toolbox_console_reporter.check b/test/files/run/toolbox_console_reporter.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/toolbox_console_reporter.check
diff --git a/test/files/run/toolbox_console_reporter.scala b/test/files/run/toolbox_console_reporter.scala
new file mode 100644
index 0000000000..1da9a6bc16
--- /dev/null
+++ b/test/files/run/toolbox_console_reporter.scala
@@ -0,0 +1,16 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ // todo. cannot test this unfortunately, because ConsoleFrontEnd grabs Console.out too early
+ // todo. and isn't affected by Console.setOut employed by partest to intercept output
+
+ //val toolbox = mkToolBox(frontEnd = mkConsoleFrontEnd(), options = "-deprecation")
+ //toolbox.runExpr(reify{
+ // object Utils {
+ // @deprecated("test", "2.10.0")
+ // def foo { println("hello") }
+ // }
+ //
+ // Utils.foo
+ //})
+}
diff --git a/test/files/run/toolbox_default_reporter_is_silent.check b/test/files/run/toolbox_default_reporter_is_silent.check
new file mode 100644
index 0000000000..ef0493b275
--- /dev/null
+++ b/test/files/run/toolbox_default_reporter_is_silent.check
@@ -0,0 +1 @@
+hello
diff --git a/test/files/run/toolbox_default_reporter_is_silent.scala b/test/files/run/toolbox_default_reporter_is_silent.scala
new file mode 100644
index 0000000000..6908c001a3
--- /dev/null
+++ b/test/files/run/toolbox_default_reporter_is_silent.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val toolbox = mkToolBox()
+ toolbox.runExpr(reify{
+ object Utils {
+ @deprecated("test", "2.10.0")
+ def foo { println("hello") }
+ }
+
+ Utils.foo
+ }.tree)
+}
diff --git a/test/files/run/toolbox_silent_reporter.check b/test/files/run/toolbox_silent_reporter.check
new file mode 100644
index 0000000000..2d05b1e3f8
--- /dev/null
+++ b/test/files/run/toolbox_silent_reporter.check
@@ -0,0 +1,4 @@
+hello
+============compiler messages============
+Info(NoPosition,method foo in object Utils is deprecated: test,WARNING)
+=========================================
diff --git a/test/files/run/toolbox_silent_reporter.scala b/test/files/run/toolbox_silent_reporter.scala
new file mode 100644
index 0000000000..6f5687ba4f
--- /dev/null
+++ b/test/files/run/toolbox_silent_reporter.scala
@@ -0,0 +1,16 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val toolbox = mkToolBox(options = "-deprecation")
+ toolbox.runExpr(reify{
+ object Utils {
+ @deprecated("test", "2.10.0")
+ def foo { println("hello") }
+ }
+
+ Utils.foo
+ }.tree)
+ println("============compiler messages============")
+ toolbox.frontEnd.infos.foreach(println(_))
+ println("=========================================")
+} \ No newline at end of file
diff --git a/test/files/run/toolbox_typecheck_implicitsdisabled.check b/test/files/run/toolbox_typecheck_implicitsdisabled.check
new file mode 100644
index 0000000000..4bc64530ab
--- /dev/null
+++ b/test/files/run/toolbox_typecheck_implicitsdisabled.check
@@ -0,0 +1,5 @@
+{
+ import scala.Predef._;
+ scala.Predef.any2ArrowAssoc[Int](1).->[Int](2)
+}
+scala.reflect.runtime.ToolBoxes$ToolBox$ToolBoxError: reflective typecheck has failed: value -> is not a member of Int
diff --git a/test/files/run/toolbox_typecheck_implicitsdisabled.scala b/test/files/run/toolbox_typecheck_implicitsdisabled.scala
new file mode 100644
index 0000000000..9d52e91f73
--- /dev/null
+++ b/test/files/run/toolbox_typecheck_implicitsdisabled.scala
@@ -0,0 +1,24 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val toolbox = mkToolBox()
+
+ val tree1 = Block(
+ Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))),
+ Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2))))
+ )
+ val ttree1 = toolbox.typeCheck(tree1, withImplicitViewsDisabled = false)
+ println(ttree1)
+
+ try {
+ val tree2 = Block(
+ Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))),
+ Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2))))
+ )
+ val ttree2 = toolbox.typeCheck(tree2, withImplicitViewsDisabled = true)
+ println(ttree2)
+ } catch {
+ case ex: Throwable =>
+ println(ex)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check
new file mode 100644
index 0000000000..c4af175812
--- /dev/null
+++ b/test/files/run/toolbox_typecheck_macrosdisabled.check
@@ -0,0 +1,5 @@
+{
+ val $mr: mr.type = mr;
+ $mr.Expr.apply[Int(2)]($mr.Literal.apply($mr.Constant.apply(2)))($mr.ConcreteTypeTag.apply[Int(2)]($mr.ConstantType.apply($mr.Constant.apply(2)), classOf[scala.Int]))
+}
+mr.reify[Int](2)
diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.scala b/test/files/run/toolbox_typecheck_macrosdisabled.scala
new file mode 100644
index 0000000000..afbbce1736
--- /dev/null
+++ b/test/files/run/toolbox_typecheck_macrosdisabled.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val toolbox = mkToolBox()
+ val mrPkg = staticModule("scala.reflect.package")
+ val mrSym = selectTerm(mrPkg, "mirror")
+ val NullaryMethodType(mrTpe) = mrSym.typeSignature
+ val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror)
+
+ val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2))))
+ val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false)
+ println(ttree1)
+
+ val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2))))
+ val ttree2 = toolbox.typeCheck(tree2, withMacrosDisabled = true)
+ println(ttree2)
+}
diff --git a/test/files/run/toolbox_typecheck_macrosdisabled2.check b/test/files/run/toolbox_typecheck_macrosdisabled2.check
new file mode 100644
index 0000000000..271139b031
--- /dev/null
+++ b/test/files/run/toolbox_typecheck_macrosdisabled2.check
@@ -0,0 +1,5 @@
+{
+ val $mr: mr.type = mr;
+ $mr.Expr.apply[Array[Int]]($mr.Apply.apply($mr.Select.apply($mr.Select.apply($mr.Ident($mr.staticModule("scala")), $mr.newTermName("Array")), $mr.newTermName("apply")), scala.collection.immutable.List.apply[$mr.Literal]($mr.Literal.apply($mr.Constant.apply(2)))))($mr.ConcreteTypeTag.apply[Array[Int]]($mr.TypeRef.apply($mr.thisModuleType("scala"), $mr.staticClass("scala.Array"), scala.collection.immutable.List.apply[$mr.Type]($mr.staticClass("scala.Int").asTypeConstructor)), ScalaRunTime.this.arrayClass(classOf[scala.Int])))
+}
+mr.reify[Array[Int]](scala.Array.apply(2))
diff --git a/test/files/run/toolbox_typecheck_macrosdisabled2.scala b/test/files/run/toolbox_typecheck_macrosdisabled2.scala
new file mode 100644
index 0000000000..b4c76d0600
--- /dev/null
+++ b/test/files/run/toolbox_typecheck_macrosdisabled2.scala
@@ -0,0 +1,17 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val toolbox = mkToolBox()
+ val mrPkg = staticModule("scala.reflect.package")
+ val mrSym = selectTerm(mrPkg, "mirror")
+ val NullaryMethodType(mrTpe) = mrSym.typeSignature
+ val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror)
+
+ val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), List(Literal(Constant(2))))))
+ val ttree1 = toolbox.typeCheck(tree1, withMacrosDisabled = false)
+ println(ttree1)
+
+ val tree2 = Apply(Select(Ident(mr), newTermName("reify")), List(Apply(Select(Ident(newTermName("scala")), newTermName("Array")), List(Literal(Constant(2))))))
+ val ttree2 = toolbox.typeCheck(tree2, withMacrosDisabled = true)
+ println(ttree2)
+}
diff --git a/test/files/run/treePrint.scala b/test/files/run/treePrint.scala
index e0332a705f..4a80e2824d 100644
--- a/test/files/run/treePrint.scala
+++ b/test/files/run/treePrint.scala
@@ -4,7 +4,7 @@ object Test {
import scala.tools.nsc._
import interpreter._
import java.io.{ OutputStream, BufferedReader, StringReader, PrintWriter, Writer, OutputStreamWriter}
-
+
val code = """
def foo = {
var q: Boolean = false
@@ -22,11 +22,11 @@ object Test {
else 20
}
else 30
-
+
(x == 5) || !q || true
}
- """
-
+ """
+
class NullOutputStream extends OutputStream { def write(b: Int) { } }
def main(args: Array[String]) {
@@ -35,7 +35,8 @@ object Test {
settings.Ycompacttrees.value = true
val intp = new IMain(settings, new PrintWriter(new NullOutputStream))
- val power = new Power(intp, new ReplVals { })
+ val vals = new ReplVals { }
+ val power = new Power(intp, vals)
intp.interpret("""def initialize = "Have to interpret something or we get errors." """)
power trees code foreach println
}
diff --git a/test/files/run/tuple-zipped.scala b/test/files/run/tuple-zipped.scala
index a9851346bc..08dcc82de6 100644
--- a/test/files/run/tuple-zipped.scala
+++ b/test/files/run/tuple-zipped.scala
@@ -15,7 +15,7 @@ object Test {
def main(args: Array[String]): Unit = {
for (cc1 <- xss1 ; cc2 <- xss2) {
- val sum1 = (cc1, cc2).zip map { case (x, y) => x + y } sum
+ val sum1 = (cc1 zip cc2) map { case (x, y) => x + y } sum
val sum2 = (cc1, cc2).zipped map (_ + _) sum
assert(sum1 == sum2)
diff --git a/test/files/run/typetags_core.check b/test/files/run/typetags_core.check
new file mode 100644
index 0000000000..f124aa6a35
--- /dev/null
+++ b/test/files/run/typetags_core.check
@@ -0,0 +1,32 @@
+true
+ConcreteTypeTag[Byte]
+true
+ConcreteTypeTag[Short]
+true
+ConcreteTypeTag[Char]
+true
+ConcreteTypeTag[Int]
+true
+ConcreteTypeTag[Long]
+true
+ConcreteTypeTag[Float]
+true
+ConcreteTypeTag[Double]
+true
+ConcreteTypeTag[Boolean]
+true
+ConcreteTypeTag[Unit]
+true
+ConcreteTypeTag[Any]
+true
+ConcreteTypeTag[Object]
+true
+ConcreteTypeTag[AnyVal]
+true
+ConcreteTypeTag[AnyRef]
+true
+ConcreteTypeTag[Null]
+true
+ConcreteTypeTag[Nothing]
+true
+ConcreteTypeTag[String]
diff --git a/test/files/run/typetags_core.scala b/test/files/run/typetags_core.scala
new file mode 100644
index 0000000000..7d6be16379
--- /dev/null
+++ b/test/files/run/typetags_core.scala
@@ -0,0 +1,34 @@
+object Test extends App {
+ println(implicitly[TypeTag[Byte]] eq TypeTag.Byte)
+ println(implicitly[TypeTag[Byte]])
+ println(implicitly[TypeTag[Short]] eq TypeTag.Short)
+ println(implicitly[TypeTag[Short]])
+ println(implicitly[TypeTag[Char]] eq TypeTag.Char)
+ println(implicitly[TypeTag[Char]])
+ println(implicitly[TypeTag[Int]] eq TypeTag.Int)
+ println(implicitly[TypeTag[Int]])
+ println(implicitly[TypeTag[Long]] eq TypeTag.Long)
+ println(implicitly[TypeTag[Long]])
+ println(implicitly[TypeTag[Float]] eq TypeTag.Float)
+ println(implicitly[TypeTag[Float]])
+ println(implicitly[TypeTag[Double]] eq TypeTag.Double)
+ println(implicitly[TypeTag[Double]])
+ println(implicitly[TypeTag[Boolean]] eq TypeTag.Boolean)
+ println(implicitly[TypeTag[Boolean]])
+ println(implicitly[TypeTag[Unit]] eq TypeTag.Unit)
+ println(implicitly[TypeTag[Unit]])
+ println(implicitly[TypeTag[Any]] eq TypeTag.Any)
+ println(implicitly[TypeTag[Any]])
+ println(implicitly[TypeTag[Object]] eq TypeTag.Object)
+ println(implicitly[TypeTag[Object]])
+ println(implicitly[TypeTag[AnyVal]] eq TypeTag.AnyVal)
+ println(implicitly[TypeTag[AnyVal]])
+ println(implicitly[TypeTag[AnyRef]] eq TypeTag.AnyRef)
+ println(implicitly[TypeTag[AnyRef]])
+ println(implicitly[TypeTag[Null]] eq TypeTag.Null)
+ println(implicitly[TypeTag[Null]])
+ println(implicitly[TypeTag[Nothing]] eq TypeTag.Nothing)
+ println(implicitly[TypeTag[Nothing]])
+ println(implicitly[TypeTag[String]] eq TypeTag.String)
+ println(implicitly[TypeTag[String]])
+} \ No newline at end of file
diff --git a/test/files/run/typetags_multi.check b/test/files/run/typetags_multi.check
new file mode 100644
index 0000000000..613106985c
--- /dev/null
+++ b/test/files/run/typetags_multi.check
@@ -0,0 +1,5 @@
+ConcreteTypeTag[Int]
+ConcreteTypeTag[Array[Int]]
+ConcreteTypeTag[Array[Array[Int]]]
+ConcreteTypeTag[Array[Array[Array[Int]]]]
+ConcreteTypeTag[Array[Array[Array[Array[Int]]]]]
diff --git a/test/files/run/typetags_multi.scala b/test/files/run/typetags_multi.scala
new file mode 100644
index 0000000000..868edc2b2a
--- /dev/null
+++ b/test/files/run/typetags_multi.scala
@@ -0,0 +1,7 @@
+object Test extends App {
+ println(typeTag[Int])
+ println(typeTag[Array[Int]])
+ println(typeTag[Array[Array[Int]]])
+ println(typeTag[Array[Array[Array[Int]]]])
+ println(typeTag[Array[Array[Array[Array[Int]]]]])
+} \ No newline at end of file
diff --git a/test/files/run/valueclasses-constr.check b/test/files/run/valueclasses-constr.check
index df37fbc723..785e6fa25b 100644
--- a/test/files/run/valueclasses-constr.check
+++ b/test/files/run/valueclasses-constr.check
@@ -1,2 +1,10 @@
-0
+16
+00:16:40
+16
+00:16:40
+16
+00:16:40
+16
+00:16:40
+16
00:16:40
diff --git a/test/files/run/valueclasses-constr.scala b/test/files/run/valueclasses-constr.scala
index 7a10299386..652d8d8d22 100644
--- a/test/files/run/valueclasses-constr.scala
+++ b/test/files/run/valueclasses-constr.scala
@@ -1,25 +1,79 @@
-object TOD {
- final val SecondsPerDay = 86400
+package test1 {
+ object TOD {
+ final val SecondsPerDay = 86400
- def apply(seconds: Int) = {
- val n = seconds % SecondsPerDay
- new TOD(if (n >= 0) n else n + SecondsPerDay)
- }
+ def apply(seconds: Int) = {
+ val n = seconds % SecondsPerDay
+ new TOD(if (n >= 0) n else n + SecondsPerDay)
+ }
+ }
+
+ final class TOD (val secondsOfDay: Int) extends AnyVal {
+ def hours = secondsOfDay / 3600
+ def minutes = (secondsOfDay / 60) % 60
+ def seconds = secondsOfDay % 60
+
+ override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
+ }
}
+package test2 {
+ object TOD {
+ final val SecondsPerDay = 86400
+
+ def apply(seconds: Int) = {
+ val n = seconds % SecondsPerDay
+ new TOD(if (n >= 0) n else n + SecondsPerDay)
+ }
+ }
+
+ final class TOD private[test2] (val secondsOfDay: Int) extends AnyVal {
+ def hours = secondsOfDay / 3600
+ def minutes = (secondsOfDay / 60) % 60
+ def seconds = secondsOfDay % 60
+
+ override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
+ }
+
+ object Client {
+ def newTOD(x: Int) = new TOD(x)
+ }
+}
+
+package test3 {
+ object TOD {
+ final val SecondsPerDay = 86400
+
+ def apply(seconds: Int) = {
+ val n = seconds % SecondsPerDay
+ new TOD(if (n >= 0) n else n + SecondsPerDay)
+ }
+ }
-final class TOD (val secondsOfDay: Int) extends AnyVal {
- def hours = secondsOfDay / 3600
- def minutes = (secondsOfDay / 60) % 60
- def seconds = secondsOfDay % 60
+ final class TOD private (val secondsOfDay: Int) extends AnyVal {
+ def hours = secondsOfDay / 3600
+ def minutes = (secondsOfDay / 60) % 60
+ def seconds = secondsOfDay % 60
- override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
+ override def toString = "%02d:%02d:%02d".format(hours, minutes, seconds)
+ }
}
object Test extends App {
- val y: TOD = new TOD(1000)
- val x: TOD = TOD(1000)
- println(x.hours)
- println(x)
+ val y1: test1.TOD = new test1.TOD(1000)
+ val y2: test2.TOD = test2.Client.newTOD(1000)
+ val x1: test1.TOD = test1.TOD(1000)
+ val x2: test2.TOD = test2.TOD(1000)
+ val x3: test3.TOD = test3.TOD(1000)
+ println(y1.minutes)
+ println(y1)
+ println(y2.minutes)
+ println(y2)
+ println(x1.minutes)
+ println(x1)
+ println(x2.minutes)
+ println(x2)
+ println(x3.minutes)
+ println(x3)
}
diff --git a/test/files/run/virtpatmat_alts.flags b/test/files/run/virtpatmat_alts.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_alts.flags
+++ b/test/files/run/virtpatmat_alts.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_apply.flags b/test/files/run/virtpatmat_apply.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_apply.flags
+++ b/test/files/run/virtpatmat_apply.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_casting.flags b/test/files/run/virtpatmat_casting.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_casting.flags
+++ b/test/files/run/virtpatmat_casting.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_extends_product.flags b/test/files/run/virtpatmat_extends_product.flags
index ac6b805bd0..8b13789179 100644
--- a/test/files/run/virtpatmat_extends_product.flags
+++ b/test/files/run/virtpatmat_extends_product.flags
@@ -1 +1 @@
--Yvirtpatmat
+
diff --git a/test/files/run/virtpatmat_literal.flags b/test/files/run/virtpatmat_literal.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_literal.flags
+++ b/test/files/run/virtpatmat_literal.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_nested_lists.flags b/test/files/run/virtpatmat_nested_lists.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_nested_lists.flags
+++ b/test/files/run/virtpatmat_nested_lists.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_npe.flags b/test/files/run/virtpatmat_npe.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_npe.flags
+++ b/test/files/run/virtpatmat_npe.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_opt_sharing.flags b/test/files/run/virtpatmat_opt_sharing.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_opt_sharing.flags
+++ b/test/files/run/virtpatmat_opt_sharing.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_partial.flags b/test/files/run/virtpatmat_partial.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_partial.flags
+++ b/test/files/run/virtpatmat_partial.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_partial_backquoted.check b/test/files/run/virtpatmat_partial_backquoted.check
new file mode 100644
index 0000000000..8ab8f29677
--- /dev/null
+++ b/test/files/run/virtpatmat_partial_backquoted.check
@@ -0,0 +1 @@
+Set(You got me!)
diff --git a/test/files/run/virtpatmat_partial_backquoted.scala b/test/files/run/virtpatmat_partial_backquoted.scala
new file mode 100644
index 0000000000..6d92229d6b
--- /dev/null
+++ b/test/files/run/virtpatmat_partial_backquoted.scala
@@ -0,0 +1,12 @@
+object Test extends App {
+ class Region { override def toString = "You got me!" }
+ class SymbolType
+ case class SymbolInfo(tp: SymbolType, regions: List[Region], x: Any)
+
+ def findRegionsWithSymbolType(rawSymbolInfos: Seq[SymbolInfo], symbolType: SymbolType): Set[Region] =
+ rawSymbolInfos.collect { case SymbolInfo(`symbolType`, regions, _) => regions }.flatten.toSet
+
+ val stp = new SymbolType
+ val stp2 = new SymbolType
+ println(findRegionsWithSymbolType(List(SymbolInfo(stp2, List(), null), SymbolInfo(stp, List(new Region), null)), stp))
+} \ No newline at end of file
diff --git a/test/files/run/virtpatmat_staging.flags b/test/files/run/virtpatmat_staging.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_staging.flags
+++ b/test/files/run/virtpatmat_staging.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_stringinterp.check b/test/files/run/virtpatmat_stringinterp.check
new file mode 100644
index 0000000000..7927f4f2d9
--- /dev/null
+++ b/test/files/run/virtpatmat_stringinterp.check
@@ -0,0 +1 @@
+Node(1)
diff --git a/test/files/pos/annotDepMethType.flags b/test/files/run/virtpatmat_stringinterp.flags
index e1b37447c9..e1b37447c9 100644
--- a/test/files/pos/annotDepMethType.flags
+++ b/test/files/run/virtpatmat_stringinterp.flags
diff --git a/test/files/run/virtpatmat_stringinterp.scala b/test/files/run/virtpatmat_stringinterp.scala
new file mode 100644
index 0000000000..213712f17a
--- /dev/null
+++ b/test/files/run/virtpatmat_stringinterp.scala
@@ -0,0 +1,13 @@
+object Test extends App {
+ case class Node(x: Int)
+
+ implicit def sc2xml(sc: StringContext): XMLContext = new XMLContext(sc)
+ class XMLContext(sc: StringContext) {
+ object xml {
+ def unapplySeq(xml: Node): Option[Seq[Node]] = Some(List(Node(1)))
+ }
+ }
+
+ val x: Node = Node(0)
+ x match { case xml"""<foo arg=$a/>""" => println(a) }
+} \ No newline at end of file
diff --git a/test/files/run/virtpatmat_switch.flags b/test/files/run/virtpatmat_switch.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_switch.flags
+++ b/test/files/run/virtpatmat_switch.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_tailcalls_verifyerror.check b/test/files/run/virtpatmat_tailcalls_verifyerror.check
new file mode 100644
index 0000000000..c508d5366f
--- /dev/null
+++ b/test/files/run/virtpatmat_tailcalls_verifyerror.check
@@ -0,0 +1 @@
+false
diff --git a/test/files/run/virtpatmat_tailcalls_verifyerror.flags b/test/files/run/virtpatmat_tailcalls_verifyerror.flags
new file mode 100644
index 0000000000..3f5a3100e4
--- /dev/null
+++ b/test/files/run/virtpatmat_tailcalls_verifyerror.flags
@@ -0,0 +1 @@
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_tailcalls_verifyerror.scala b/test/files/run/virtpatmat_tailcalls_verifyerror.scala
new file mode 100644
index 0000000000..5ce91e8dce
--- /dev/null
+++ b/test/files/run/virtpatmat_tailcalls_verifyerror.scala
@@ -0,0 +1,14 @@
+// shouldn't result in a verify error when run...
+object Test extends App {
+ @annotation.tailrec
+ final def test(meh: Boolean): Boolean = {
+ Some("a") match {
+ case x =>
+ x match {
+ case Some(_) => if(meh) test(false) else false
+ case _ => test(false)
+ }
+ }
+ }
+ println(test(true))
+} \ No newline at end of file
diff --git a/test/files/run/virtpatmat_try.flags b/test/files/run/virtpatmat_try.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_try.flags
+++ b/test/files/run/virtpatmat_try.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_typed.flags b/test/files/run/virtpatmat_typed.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_typed.flags
+++ b/test/files/run/virtpatmat_typed.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_unapply.flags b/test/files/run/virtpatmat_unapply.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_unapply.flags
+++ b/test/files/run/virtpatmat_unapply.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_unapplyprod.flags b/test/files/run/virtpatmat_unapplyprod.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_unapplyprod.flags
+++ b/test/files/run/virtpatmat_unapplyprod.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_unapplyseq.flags b/test/files/run/virtpatmat_unapplyseq.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_unapplyseq.flags
+++ b/test/files/run/virtpatmat_unapplyseq.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
diff --git a/test/files/run/virtpatmat_valdef.check b/test/files/run/virtpatmat_valdef.check
new file mode 100644
index 0000000000..1a45335bd2
--- /dev/null
+++ b/test/files/run/virtpatmat_valdef.check
@@ -0,0 +1 @@
+meh(true,null)
diff --git a/test/files/run/virtpatmat_valdef.scala b/test/files/run/virtpatmat_valdef.scala
new file mode 100644
index 0000000000..f1a9b46cdd
--- /dev/null
+++ b/test/files/run/virtpatmat_valdef.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ // patterns in valdefs...
+ // TODO: irrefutability should indicate we don't actually need to test, just deconstruct
+ val (modified, result) : (Boolean, String) = (true, null)
+ println("meh"+ (modified, result))
+} \ No newline at end of file
diff --git a/test/files/scalacheck/Ctrie.scala b/test/files/scalacheck/Ctrie.scala
index b9d71b88a3..736bf938bc 100644
--- a/test/files/scalacheck/Ctrie.scala
+++ b/test/files/scalacheck/Ctrie.scala
@@ -5,7 +5,7 @@ import org.scalacheck._
import Prop._
import org.scalacheck.Gen._
import collection._
-import collection.mutable.ConcurrentTrieMap
+import collection.concurrent.TrieMap
@@ -16,7 +16,7 @@ case class Wrap(i: Int) {
/** A check mainly oriented towards checking snapshot correctness.
*/
-object Test extends Properties("ConcurrentTrieMap") {
+object Test extends Properties("concurrent.TrieMap") {
/* generators */
@@ -102,7 +102,7 @@ object Test extends Properties("ConcurrentTrieMap") {
(numThreads, numElems) =>
val p = 3 //numThreads
val sz = 102 //numElems
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
// checker
val checker = spawn {
@@ -134,7 +134,7 @@ object Test extends Properties("ConcurrentTrieMap") {
property("update") = forAll(sizes) {
(n: Int) =>
- val ct = new ConcurrentTrieMap[Int, Int]
+ val ct = new TrieMap[Int, Int]
for (i <- 0 until n) ct(i) = i
(0 until n) forall {
case i => ct(i) == i
@@ -143,7 +143,7 @@ object Test extends Properties("ConcurrentTrieMap") {
property("concurrent update") = forAll(threadCountsAndSizes) {
case (p, sz) =>
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
inParallel(p) {
idx =>
@@ -158,7 +158,7 @@ object Test extends Properties("ConcurrentTrieMap") {
property("concurrent remove") = forAll(threadCounts, sizes) {
(p, sz) =>
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(Wrap(i)) = i
inParallel(p) {
@@ -174,7 +174,7 @@ object Test extends Properties("ConcurrentTrieMap") {
property("concurrent putIfAbsent") = forAll(threadCounts, sizes) {
(p, sz) =>
- val ct = new ConcurrentTrieMap[Wrap, Int]
+ val ct = new TrieMap[Wrap, Int]
val results = inParallel(p) {
idx =>
diff --git a/test/files/scalacheck/array-new.scala b/test/files/scalacheck/array-new.scala
new file mode 100644
index 0000000000..18d577ca6d
--- /dev/null
+++ b/test/files/scalacheck/array-new.scala
@@ -0,0 +1,36 @@
+import org.scalacheck._
+import Prop._
+import Gen._
+import Arbitrary._
+import util._
+import Buildable._
+import scala.collection.mutable.ArraySeq
+
+object Test extends Properties("Array") {
+ /** At this moment the authentic scalacheck Array Builder/Arb bits are commented out.
+ */
+ implicit def arbArray[T](implicit a: Arbitrary[T], m: ArrayTag[T]): Arbitrary[Array[T]] =
+ Arbitrary(containerOf[List,T](arbitrary[T]) map (_.toArray))
+
+ val arrGen: Gen[Array[_]] = oneOf(
+ arbitrary[Array[Int]],
+ arbitrary[Array[Array[Int]]],
+ arbitrary[Array[List[String]]],
+ arbitrary[Array[String]],
+ arbitrary[Array[Boolean]],
+ arbitrary[Array[AnyVal]]
+ )
+
+ // inspired by #1857 and #2352
+ property("eq/ne") = forAll(arrGen, arrGen) { (c1, c2) =>
+ (c1 eq c2) || (c1 ne c2)
+ }
+
+ // inspired by #2299
+ def smallInt = choose(1, 10)
+ property("ofDim") = forAll(smallInt, smallInt, smallInt) { (i1, i2, i3) =>
+ val arr = Array.ofDim[String](i1, i2, i3)
+ val flattened = arr flatMap (x => x) flatMap (x => x)
+ flattened.length == i1 * i2 * i3
+ }
+}
diff --git a/test/files/scalacheck/array.scala b/test/files/scalacheck/array-old.scala
index f262bc6320..f262bc6320 100644
--- a/test/files/scalacheck/array.scala
+++ b/test/files/scalacheck/array-old.scala
diff --git a/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala b/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala
index a04c0ff8d4..e141c398fd 100644
--- a/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala
+++ b/test/files/scalacheck/parallel-collections/ParallelCtrieCheck.scala
@@ -19,21 +19,21 @@ abstract class ParallelConcurrentTrieMapCheck[K, V](tp: String) extends Parallel
// ForkJoinTasks.defaultForkJoinPool.setMaximumPoolSize(Runtime.getRuntime.availableProcessors * 2)
// ForkJoinTasks.defaultForkJoinPool.setParallelism(Runtime.getRuntime.availableProcessors * 2)
- type CollType = ParConcurrentTrieMap[K, V]
+ type CollType = ParTrieMap[K, V]
def isCheckingViews = false
def hasStrictOrder = false
def ofSize(vals: Seq[Gen[(K, V)]], sz: Int) = {
- val ct = new mutable.ConcurrentTrieMap[K, V]
+ val ct = new concurrent.TrieMap[K, V]
val gen = vals(rnd.nextInt(vals.size))
for (i <- 0 until sz) ct += sample(gen)
ct
}
def fromTraversable(t: Traversable[(K, V)]) = {
- val pct = new ParConcurrentTrieMap[K, V]
+ val pct = new ParTrieMap[K, V]
var i = 0
for (kv <- t.toList) {
pct += kv
@@ -58,7 +58,7 @@ with PairValues[Int, Int]
def koperators = intoperators
override def printDataStructureDebugInfo(ds: AnyRef) = ds match {
- case pm: ParConcurrentTrieMap[k, v] =>
+ case pm: ParTrieMap[k, v] =>
println("Mutable parallel ctrie")
case _ =>
println("could not match data structure type: " + ds.getClass)
diff --git a/test/files/scalacheck/t2460.scala b/test/files/scalacheck/t2460.scala
new file mode 100644
index 0000000000..196b43789f
--- /dev/null
+++ b/test/files/scalacheck/t2460.scala
@@ -0,0 +1,32 @@
+import org.scalacheck.Prop.forAll
+import org.scalacheck.Properties
+import org.scalacheck.ConsoleReporter.testStatsEx
+import org.scalacheck.{Test => SCTest}
+import org.scalacheck.Gen
+
+object Test extends Properties("Regex : Ticket 2460") {
+
+ val vowel = Gen.oneOf("a", "z")
+
+ val numberOfMatch = forAll(vowel) {
+ (s: String) => "\\s*([a-z])\\s*".r("data").findAllMatchIn((1 to 20).map(_ => s).mkString).size == 20
+ }
+
+ val numberOfGroup = forAll(vowel) {
+ (s: String) => "\\s*([a-z])\\s*([a-z])\\s*".r("data").findAllMatchIn((1 to 20).map(_ => s).mkString).next.groupCount == 2
+ }
+
+ val nameOfGroup = forAll(vowel) {
+ (s: String) => "([a-z])".r("data").findAllMatchIn(s).next.group("data") == s
+ }
+
+ val tests = List(
+ ("numberOfMatch", numberOfMatch),
+ ("numberOfGroup", numberOfGroup),
+ ("nameOfGroup", nameOfGroup)
+ )
+
+ /*tests foreach {
+ case (name, p) => testStatsEx(name, SCTest.check(p))
+ }*/
+}
diff --git a/test/files/scalap/caseClass/result.test b/test/files/scalap/caseClass/result.test
index 7dfe3a0356..6165444026 100644
--- a/test/files/scalap/caseClass/result.test
+++ b/test/files/scalap/caseClass/result.test
@@ -14,3 +14,9 @@ case class CaseClass[A <: scala.Seq[scala.Int]](i : A, s : scala.Predef.String)
override def toString() : java.lang.String = { /* compiled code */ }
override def equals(x$1 : scala.Any) : scala.Boolean = { /* compiled code */ }
}
+object CaseClass extends scala.AnyRef with scala.Serializable {
+ def this() = { /* compiled code */ }
+ final override def toString() : java.lang.String = { /* compiled code */ }
+ def apply[A <: scala.Seq[scala.Int]](i : A, s : scala.Predef.String) : CaseClass[A] = { /* compiled code */ }
+ def unapply[A <: scala.Seq[scala.Int]](x$0 : CaseClass[A]) : scala.Option[scala.Tuple2[A, scala.Predef.String]] = { /* compiled code */ }
+}
diff --git a/test/files/specialized/spec-matrix.check b/test/files/specialized/spec-matrix-new.check
index 5ec3e84597..5ec3e84597 100644
--- a/test/files/specialized/spec-matrix.check
+++ b/test/files/specialized/spec-matrix-new.check
diff --git a/test/files/specialized/spec-matrix-new.scala b/test/files/specialized/spec-matrix-new.scala
new file mode 100644
index 0000000000..65b46e8d48
--- /dev/null
+++ b/test/files/specialized/spec-matrix-new.scala
@@ -0,0 +1,80 @@
+/** Test matrix multiplication with specialization.
+ */
+
+class Matrix[@specialized A: ArrayTag](val rows: Int, val cols: Int) {
+ private val arr: Array[Array[A]] = Array.ofDim[A](rows, cols)
+
+ def apply(i: Int, j: Int): A = {
+ if (i < 0 || i >= rows || j < 0 || j >= cols)
+ throw new NoSuchElementException("Indexes out of bounds: " + (i, j))
+
+ arr(i)(j)
+ }
+
+ def update(i: Int, j: Int, e: A) {
+ arr(i)(j) = e
+ }
+
+ def rowsIterator: Iterator[Array[A]] = new Iterator[Array[A]] {
+ var idx = 0;
+ def hasNext = idx < rows
+ def next = {
+ idx += 1
+ arr(idx - 1)
+ }
+ }
+}
+
+object Test {
+ def main(args: Array[String]) {
+ val m = randomMatrix(200, 100)
+ val n = randomMatrix(100, 200)
+
+ val p = mult(m, n)
+ println(p(0, 0))
+ println("Boxed doubles: " + runtime.BoxesRunTime.doubleBoxCount)
+// println("Boxed integers: " + runtime.BoxesRunTime.integerBoxCount)
+ }
+
+ def randomMatrix(n: Int, m: Int) = {
+ val r = new util.Random(10)
+ val x = new Matrix[Double](n, m)
+ for (i <- 0 until n; j <- 0 until m)
+ x(i, j) = (r.nextInt % 1000).toDouble
+ x
+ }
+
+ def printMatrix[Double](m: Matrix[Double]) {
+ for (i <- 0 until m.rows) {
+ for (j <- 0 until m.cols)
+ print("%5.3f ".format(m(i, j)))
+ println
+ }
+ }
+
+ def multTag[@specialized(Int) T](m: Matrix[T], n: Matrix[T])(implicit at: ArrayTag[T], num: Numeric[T]) {
+ val p = new Matrix[T](m.rows, n.cols)
+ import num._
+
+ for (i <- 0 until m.rows)
+ for (j <- 0 until n.cols) {
+ var sum = num.zero
+ for (k <- 0 until n.rows)
+ sum += m(i, k) * n(k, j)
+ p(i, j) = sum
+ }
+ }
+
+ def mult(m: Matrix[Double], n: Matrix[Double]) = {
+ val p = new Matrix[Double](m.rows, n.cols)
+
+ for (i <- 0 until m.rows)
+ for (j <- 0 until n.cols) {
+ var sum = 0.0
+ for (k <- 0 until n.rows)
+ sum += m(i, k) * n(k, j)
+ p(i, j) = sum
+ }
+ p
+ }
+}
diff --git a/test/files/specialized/spec-matrix-old.check b/test/files/specialized/spec-matrix-old.check
new file mode 100644
index 0000000000..5ec3e84597
--- /dev/null
+++ b/test/files/specialized/spec-matrix-old.check
@@ -0,0 +1,2 @@
+251437.0
+Boxed doubles: 1
diff --git a/test/files/specialized/spec-matrix.scala b/test/files/specialized/spec-matrix-old.scala
index 98735c8c03..98735c8c03 100644
--- a/test/files/specialized/spec-matrix.scala
+++ b/test/files/specialized/spec-matrix-old.scala
diff --git a/test/files/specialized/spec-patmatch.check b/test/files/specialized/spec-patmatch.check
index 33306ab5d9..a2746c0f48 100644
--- a/test/files/specialized/spec-patmatch.check
+++ b/test/files/specialized/spec-patmatch.check
@@ -17,4 +17,4 @@ long
double
float
default
-2 \ No newline at end of file
+10
diff --git a/test/files/speclib/instrumented.jar.desired.sha1 b/test/files/speclib/instrumented.jar.desired.sha1
index 2d4cd04a92..a7da67429e 100644
--- a/test/files/speclib/instrumented.jar.desired.sha1
+++ b/test/files/speclib/instrumented.jar.desired.sha1
@@ -1 +1 @@
-d83c6bf3765ab1378943020a8d9cda8851604ffa ?instrumented.jar
+15f200d9f0f25f9fd871bad2ebb4ba5cfc671db4 ?instrumented.jar
diff --git a/test/instrumented/boxes.patch b/test/instrumented/boxes.patch
index 11c5b37aa8..6c5ff23f9f 100644
--- a/test/instrumented/boxes.patch
+++ b/test/instrumented/boxes.patch
@@ -1,7 +1,8 @@
-9a10,11
+9c9
+<
+---
> /* INSTRUMENTED VERSION */
->
-50a53,61
+51a52,59
> public static int booleanBoxCount = 0;
> public static int characterBoxCount = 0;
> public static int byteBoxCount = 0;
@@ -10,20 +11,19 @@
> public static int longBoxCount = 0;
> public static int floatBoxCount = 0;
> public static int doubleBoxCount = 0;
->
-51a63
-> booleanBoxCount++;
-55a68
-> characterBoxCount++;
-59a73
-> byteBoxCount++;
-63a78
-> shortBoxCount++;
-67a83
-> integerBoxCount++;
-71a88
-> longBoxCount++;
-75a93
-> floatBoxCount++;
-79a98
-> doubleBoxCount++;
+53a62
+> booleanBoxCount += 1;
+57a67
+> characterBoxCount += 1;
+61a72
+> byteBoxCount += 1;
+65a77
+> shortBoxCount += 1;
+69a82
+> integerBoxCount += 1;
+73a87
+> longBoxCount += 1;
+77a92
+> floatBoxCount += 1;
+83a99
+> doubleBoxCount += 1;
diff --git a/test/instrumented/library/scala/runtime/BoxesRunTime.java b/test/instrumented/library/scala/runtime/BoxesRunTime.java
index f06f86f2f2..172ed8ee14 100644
--- a/test/instrumented/library/scala/runtime/BoxesRunTime.java
+++ b/test/instrumented/library/scala/runtime/BoxesRunTime.java
@@ -6,10 +6,8 @@
** |/ **
\* */
-
/* INSTRUMENTED VERSION */
-
package scala.runtime;
import java.io.*;
@@ -33,14 +31,16 @@ public final class BoxesRunTime
{
private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7;
+ /** We don't need to return BYTE and SHORT, as everything which might
+ * care widens to INT.
+ */
private static int typeCode(Object a) {
if (a instanceof java.lang.Integer) return INT;
- if (a instanceof java.lang.Byte) return BYTE;
- if (a instanceof java.lang.Character) return CHAR;
- if (a instanceof java.lang.Long) return LONG;
if (a instanceof java.lang.Double) return DOUBLE;
- if (a instanceof java.lang.Short) return SHORT;
+ if (a instanceof java.lang.Long) return LONG;
+ if (a instanceof java.lang.Character) return CHAR;
if (a instanceof java.lang.Float) return FLOAT;
+ if ((a instanceof java.lang.Byte) || (a instanceof java.lang.Short)) return INT;
return OTHER;
}
@@ -49,7 +49,6 @@ public final class BoxesRunTime
}
/* BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING ... BOXING */
-
public static int booleanBoxCount = 0;
public static int characterBoxCount = 0;
public static int byteBoxCount = 0;
@@ -58,46 +57,46 @@ public final class BoxesRunTime
public static int longBoxCount = 0;
public static int floatBoxCount = 0;
public static int doubleBoxCount = 0;
-
+
public static java.lang.Boolean boxToBoolean(boolean b) {
- booleanBoxCount++;
+ booleanBoxCount += 1;
return java.lang.Boolean.valueOf(b);
}
public static java.lang.Character boxToCharacter(char c) {
- characterBoxCount++;
+ characterBoxCount += 1;
return java.lang.Character.valueOf(c);
}
public static java.lang.Byte boxToByte(byte b) {
- byteBoxCount++;
+ byteBoxCount += 1;
return java.lang.Byte.valueOf(b);
}
public static java.lang.Short boxToShort(short s) {
- shortBoxCount++;
+ shortBoxCount += 1;
return java.lang.Short.valueOf(s);
}
public static java.lang.Integer boxToInteger(int i) {
- integerBoxCount++;
+ integerBoxCount += 1;
return java.lang.Integer.valueOf(i);
}
public static java.lang.Long boxToLong(long l) {
- longBoxCount++;
+ longBoxCount += 1;
return java.lang.Long.valueOf(l);
}
public static java.lang.Float boxToFloat(float f) {
- floatBoxCount++;
+ floatBoxCount += 1;
return java.lang.Float.valueOf(f);
}
public static java.lang.Double boxToDouble(double d) {
- doubleBoxCount++;
// System.out.println("box " + d);
// (new Throwable()).printStackTrace();
+ doubleBoxCount += 1;
return java.lang.Double.valueOf(d);
}
@@ -138,15 +137,6 @@ public final class BoxesRunTime
/* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */
- private static int eqTypeCode(Number a) {
- if ((a instanceof java.lang.Integer) || (a instanceof java.lang.Byte)) return INT;
- if (a instanceof java.lang.Long) return LONG;
- if (a instanceof java.lang.Double) return DOUBLE;
- if (a instanceof java.lang.Short) return INT;
- if (a instanceof java.lang.Float) return FLOAT;
- return OTHER;
- }
-
public static boolean equals(Object x, Object y) {
if (x == y) return true;
return equals2(x, y);
@@ -178,8 +168,8 @@ public final class BoxesRunTime
}
public static boolean equalsNumNum(java.lang.Number xn, java.lang.Number yn) {
- int xcode = eqTypeCode(xn);
- int ycode = eqTypeCode(yn);
+ int xcode = typeCode(xn);
+ int ycode = typeCode(yn);
switch (ycode > xcode ? ycode : xcode) {
case INT:
return xn.intValue() == yn.intValue();
@@ -211,8 +201,11 @@ public final class BoxesRunTime
}
private static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) {
+ if (yc == null)
+ return xn == null;
+
char ch = yc.charValue();
- switch (eqTypeCode(xn)) {
+ switch (typeCode(xn)) {
case INT:
return xn.intValue() == ch;
case LONG:
@@ -222,9 +215,6 @@ public final class BoxesRunTime
case DOUBLE:
return xn.doubleValue() == ch;
default:
- if (xn == null)
- return yc == null;
-
return xn.equals(yc);
}
}
@@ -290,6 +280,31 @@ public final class BoxesRunTime
else return a.hashCode();
}
+ private static int unboxCharOrInt(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).intValue();
+ }
+ private static long unboxCharOrLong(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).longValue();
+ }
+ private static float unboxCharOrFloat(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).floatValue();
+ }
+ private static double unboxCharOrDouble(Object arg1, int code) {
+ if (code == CHAR)
+ return ((java.lang.Character) arg1).charValue();
+ else
+ return ((java.lang.Number) arg1).doubleValue();
+ }
+
/* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */
/** arg1 + arg2 */
@@ -298,24 +313,16 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 + val2);
+ return boxToInteger(unboxCharOrInt(arg1, code1) + unboxCharOrInt(arg2, code2));
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 + val2);
+ return boxToLong(unboxCharOrLong(arg1, code1) + unboxCharOrLong(arg2, code2));
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 + val2);
+ return boxToFloat(unboxCharOrFloat(arg1, code1) + unboxCharOrFloat(arg2, code2));
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 + val2);
+ return boxToDouble(unboxCharOrDouble(arg1, code1) + unboxCharOrDouble(arg2, code2));
}
throw new NoSuchMethodException();
}
@@ -326,24 +333,16 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 - val2);
+ return boxToInteger(unboxCharOrInt(arg1, code1) - unboxCharOrInt(arg2, code2));
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 - val2);
+ return boxToLong(unboxCharOrLong(arg1, code1) - unboxCharOrLong(arg2, code2));
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 - val2);
+ return boxToFloat(unboxCharOrFloat(arg1, code1) - unboxCharOrFloat(arg2, code2));
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 - val2);
+ return boxToDouble(unboxCharOrDouble(arg1, code1) - unboxCharOrDouble(arg2, code2));
}
throw new NoSuchMethodException();
}
@@ -354,24 +353,16 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 * val2);
+ return boxToInteger(unboxCharOrInt(arg1, code1) * unboxCharOrInt(arg2, code2));
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 * val2);
+ return boxToLong(unboxCharOrLong(arg1, code1) * unboxCharOrLong(arg2, code2));
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 * val2);
+ return boxToFloat(unboxCharOrFloat(arg1, code1) * unboxCharOrFloat(arg2, code2));
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 * val2);
+ return boxToDouble(unboxCharOrDouble(arg1, code1) * unboxCharOrDouble(arg2, code2));
}
throw new NoSuchMethodException();
}
@@ -381,26 +372,16 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 / val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 / val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 / val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 / val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) / unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) / unboxCharOrLong(arg2, code2));
+ if (maxcode <= FLOAT)
+ return boxToFloat(unboxCharOrFloat(arg1, code1) / unboxCharOrFloat(arg2, code2));
+ if (maxcode <= DOUBLE)
+ return boxToDouble(unboxCharOrDouble(arg1, code1) / unboxCharOrDouble(arg2, code2));
+
throw new NoSuchMethodException();
}
@@ -409,26 +390,16 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 % val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 % val2);
- }
- if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
- return boxToFloat(val1 % val2);
- }
- if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
- return boxToDouble(val1 % val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) % unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) % unboxCharOrLong(arg2, code2));
+ if (maxcode <= FLOAT)
+ return boxToFloat(unboxCharOrFloat(arg1, code1) % unboxCharOrFloat(arg2, code2));
+ if (maxcode <= DOUBLE)
+ return boxToDouble(unboxCharOrDouble(arg1, code1) % unboxCharOrDouble(arg2, code2));
+
throw new NoSuchMethodException();
}
@@ -437,24 +408,24 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToInteger(val1 >> val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToInteger(val1 >> val2);
}
}
if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToLong(val1 >> val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToLong(val1 >> val2);
}
}
@@ -466,24 +437,24 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToInteger(val1 << val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToInteger(val1 << val2);
}
}
if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToLong(val1 << val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToLong(val1 << val2);
}
}
@@ -495,24 +466,24 @@ public final class BoxesRunTime
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
if (code1 <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToInteger(val1 >>> val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToInteger(val1 >>> val2);
}
}
if (code1 <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
if (code2 <= INT) {
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToLong(val1 >>> val2);
}
if (code2 <= LONG) {
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToLong(val1 >>> val2);
}
}
@@ -523,19 +494,19 @@ public final class BoxesRunTime
public static Object negate(Object arg) throws NoSuchMethodException {
int code = typeCode(arg);
if (code <= INT) {
- int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue();
+ int val = unboxCharOrInt(arg, code);
return boxToInteger(-val);
}
if (code <= LONG) {
- long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue();
+ long val = unboxCharOrLong(arg, code);
return boxToLong(-val);
}
if (code <= FLOAT) {
- float val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).floatValue();
+ float val = unboxCharOrFloat(arg, code);
return boxToFloat(-val);
}
if (code <= DOUBLE) {
- double val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).doubleValue();
+ double val = unboxCharOrDouble(arg, code);
return boxToDouble(-val);
}
throw new NoSuchMethodException();
@@ -545,20 +516,16 @@ public final class BoxesRunTime
public static Object positive(Object arg) throws NoSuchMethodException {
int code = typeCode(arg);
if (code <= INT) {
- int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue();
- return boxToInteger(+val);
+ return boxToInteger(+unboxCharOrInt(arg, code));
}
if (code <= LONG) {
- long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue();
- return boxToLong(+val);
+ return boxToLong(+unboxCharOrLong(arg, code));
}
if (code <= FLOAT) {
- float val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).floatValue();
- return boxToFloat(+val);
+ return boxToFloat(+unboxCharOrFloat(arg, code));
}
if (code <= DOUBLE) {
- double val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).doubleValue();
- return boxToDouble(+val);
+ return boxToDouble(+unboxCharOrDouble(arg, code));
}
throw new NoSuchMethodException();
}
@@ -566,72 +533,60 @@ public final class BoxesRunTime
/** arg1 & arg2 */
public static Object takeAnd(Object arg1, Object arg2) throws NoSuchMethodException {
if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue());
+ else
throw new NoSuchMethodException();
- }
- return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() & ((java.lang.Boolean) arg2).booleanValue());
}
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 & val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 & val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) & unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) & unboxCharOrLong(arg2, code2));
+
throw new NoSuchMethodException();
}
/** arg1 | arg2 */
public static Object takeOr(Object arg1, Object arg2) throws NoSuchMethodException {
if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() | ((java.lang.Boolean) arg2).booleanValue());
+ else
throw new NoSuchMethodException();
- }
- return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() | ((java.lang.Boolean) arg2).booleanValue());
}
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 | val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 | val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) | unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) | unboxCharOrLong(arg2, code2));
+
throw new NoSuchMethodException();
}
/** arg1 ^ arg2 */
public static Object takeXor(Object arg1, Object arg2) throws NoSuchMethodException {
if ((arg1 instanceof Boolean) || (arg2 instanceof Boolean)) {
- if (!((arg1 instanceof Boolean) && (arg2 instanceof Boolean))) {
+ if ((arg1 instanceof Boolean) && (arg2 instanceof Boolean))
+ return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() ^ ((java.lang.Boolean) arg2).booleanValue());
+ else
throw new NoSuchMethodException();
- }
- return boxToBoolean(((java.lang.Boolean) arg1).booleanValue() ^ ((java.lang.Boolean) arg2).booleanValue());
}
int code1 = typeCode(arg1);
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
- if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
- return boxToInteger(val1 ^ val2);
- }
- if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
- return boxToLong(val1 ^ val2);
- }
+
+ if (maxcode <= INT)
+ return boxToInteger(unboxCharOrInt(arg1, code1) ^ unboxCharOrInt(arg2, code2));
+ if (maxcode <= LONG)
+ return boxToLong(unboxCharOrLong(arg1, code1) ^ unboxCharOrLong(arg2, code2));
+
throw new NoSuchMethodException();
}
@@ -655,12 +610,10 @@ public final class BoxesRunTime
public static Object complement(Object arg) throws NoSuchMethodException {
int code = typeCode(arg);
if (code <= INT) {
- int val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).intValue();
- return boxToInteger(~val);
+ return boxToInteger(~unboxCharOrInt(arg, code));
}
if (code <= LONG) {
- long val = (code == CHAR) ? ((java.lang.Character) arg).charValue() : ((java.lang.Number) arg).longValue();
- return boxToLong(~val);
+ return boxToLong(~unboxCharOrLong(arg, code));
}
throw new NoSuchMethodException();
}
@@ -686,23 +639,23 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToBoolean(val1 < val2);
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToBoolean(val1 < val2);
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
return boxToBoolean(val1 < val2);
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
return boxToBoolean(val1 < val2);
}
throw new NoSuchMethodException();
@@ -713,23 +666,23 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToBoolean(val1 <= val2);
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToBoolean(val1 <= val2);
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
return boxToBoolean(val1 <= val2);
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
return boxToBoolean(val1 <= val2);
}
throw new NoSuchMethodException();
@@ -740,23 +693,23 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToBoolean(val1 >= val2);
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToBoolean(val1 >= val2);
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
return boxToBoolean(val1 >= val2);
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
return boxToBoolean(val1 >= val2);
}
throw new NoSuchMethodException();
@@ -767,33 +720,30 @@ public final class BoxesRunTime
int code2 = typeCode(arg2);
int maxcode = (code1 < code2) ? code2 : code1;
if (maxcode <= INT) {
- int val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).intValue();
- int val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).intValue();
+ int val1 = unboxCharOrInt(arg1, code1);
+ int val2 = unboxCharOrInt(arg2, code2);
return boxToBoolean(val1 > val2);
}
if (maxcode <= LONG) {
- long val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).longValue();
- long val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).longValue();
+ long val1 = unboxCharOrLong(arg1, code1);
+ long val2 = unboxCharOrLong(arg2, code2);
return boxToBoolean(val1 > val2);
}
if (maxcode <= FLOAT) {
- float val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).floatValue();
- float val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).floatValue();
+ float val1 = unboxCharOrFloat(arg1, code1);
+ float val2 = unboxCharOrFloat(arg2, code2);
return boxToBoolean(val1 > val2);
}
if (maxcode <= DOUBLE) {
- double val1 = (code1 == CHAR) ? ((java.lang.Character) arg1).charValue() : ((java.lang.Number) arg1).doubleValue();
- double val2 = (code2 == CHAR) ? ((java.lang.Character) arg2).charValue() : ((java.lang.Number) arg2).doubleValue();
+ double val1 = unboxCharOrDouble(arg1, code1);
+ double val2 = unboxCharOrDouble(arg2, code2);
return boxToBoolean(val1 > val2);
}
throw new NoSuchMethodException();
}
-
+
public static boolean isBoxedNumberOrBoolean(Object arg) {
- if (arg instanceof java.lang.Boolean)
- return true;
- else
- return isBoxedNumber(arg);
+ return (arg instanceof java.lang.Boolean) || isBoxedNumber(arg);
}
public static boolean isBoxedNumber(Object arg) {
return (
diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala
index 9eb93a418d..63908fcc29 100644
--- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala
+++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala
@@ -6,9 +6,9 @@
** |/ **
\* */
-package scala.runtime
/* INSTRUMENTED VERSION */
+package scala.runtime
import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator }
import scala.collection.mutable.WrappedArray
@@ -33,10 +33,7 @@ object ScalaRunTime {
clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1))
def isValueClass(clazz: Class[_]) = clazz.isPrimitive()
- var arrayApplyCount = 0
- var arrayUpdateCount = 0
-
- def isTuple(x: Any) = tupleNames(x.getClass.getName)
+ def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName)
def isAnyVal(x: Any) = x match {
case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true
case _ => false
@@ -52,56 +49,68 @@ object ScalaRunTime {
names.toSet
}
+ /** Return the class object representing an array with element class `clazz`.
+ */
+ def arrayClass(clazz: Class[_]): Class[_] = {
+ // newInstance throws an exception if the erasure is Void.TYPE. see SI-5680
+ if (clazz == java.lang.Void.TYPE) classOf[Array[Unit]]
+ else java.lang.reflect.Array.newInstance(clazz, 0).getClass
+ }
+
+ /** Return the class object representing elements in arrays described by a given schematic.
+ */
+ def arrayElementClass(schematic: Any): Class[_] = schematic match {
+ case cls: Class[_] => cls.getComponentType
+ case tag: ClassTag[_] => tag.erasure
+ case tag: ArrayTag[_] => tag.newArray(0).getClass.getComponentType
+ case _ => throw new UnsupportedOperationException("unsupported schematic %s (%s)".format(schematic, if (schematic == null) "null" else schematic.getClass))
+ }
+
/** Return the class object representing an unboxed value type,
* e.g. classOf[int], not classOf[java.lang.Integer]. The compiler
* rewrites expressions like 5.getClass to come here.
*/
- def anyValClass[T <: AnyVal](value: T): Class[T] = (value match {
- case x: Byte => java.lang.Byte.TYPE
- case x: Short => java.lang.Short.TYPE
- case x: Char => java.lang.Character.TYPE
- case x: Int => java.lang.Integer.TYPE
- case x: Long => java.lang.Long.TYPE
- case x: Float => java.lang.Float.TYPE
- case x: Double => java.lang.Double.TYPE
- case x: Boolean => java.lang.Boolean.TYPE
- case x: Unit => java.lang.Void.TYPE
- }).asInstanceOf[Class[T]]
+ def anyValClass[T <: AnyVal : ClassTag](value: T): Class[T] =
+ classTag[T].erasure.asInstanceOf[Class[T]]
+
+ var arrayApplyCount = 0
/** Retrieve generic array element */
def array_apply(xs: AnyRef, idx: Int): Any = {
arrayApplyCount += 1
xs match {
- case x: Array[AnyRef] => x(idx).asInstanceOf[Any]
- case x: Array[Int] => x(idx).asInstanceOf[Any]
- case x: Array[Double] => x(idx).asInstanceOf[Any]
- case x: Array[Long] => x(idx).asInstanceOf[Any]
- case x: Array[Float] => x(idx).asInstanceOf[Any]
- case x: Array[Char] => x(idx).asInstanceOf[Any]
- case x: Array[Byte] => x(idx).asInstanceOf[Any]
- case x: Array[Short] => x(idx).asInstanceOf[Any]
- case x: Array[Boolean] => x(idx).asInstanceOf[Any]
- case x: Array[Unit] => x(idx).asInstanceOf[Any]
- case null => throw new NullPointerException
- }
+ case x: Array[AnyRef] => x(idx).asInstanceOf[Any]
+ case x: Array[Int] => x(idx).asInstanceOf[Any]
+ case x: Array[Double] => x(idx).asInstanceOf[Any]
+ case x: Array[Long] => x(idx).asInstanceOf[Any]
+ case x: Array[Float] => x(idx).asInstanceOf[Any]
+ case x: Array[Char] => x(idx).asInstanceOf[Any]
+ case x: Array[Byte] => x(idx).asInstanceOf[Any]
+ case x: Array[Short] => x(idx).asInstanceOf[Any]
+ case x: Array[Boolean] => x(idx).asInstanceOf[Any]
+ case x: Array[Unit] => x(idx).asInstanceOf[Any]
+ case null => throw new NullPointerException
+ }
}
+ var arrayUpdateCount = 0
+
/** update generic array element */
def array_update(xs: AnyRef, idx: Int, value: Any): Unit = {
arrayUpdateCount += 1
xs match {
- case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef]
- case x: Array[Int] => x(idx) = value.asInstanceOf[Int]
- case x: Array[Double] => x(idx) = value.asInstanceOf[Double]
- case x: Array[Long] => x(idx) = value.asInstanceOf[Long]
- case x: Array[Float] => x(idx) = value.asInstanceOf[Float]
- case x: Array[Char] => x(idx) = value.asInstanceOf[Char]
- case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte]
- case x: Array[Short] => x(idx) = value.asInstanceOf[Short]
- case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean]
- case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit]
- case null => throw new NullPointerException
- }
+ case x: Array[AnyRef] => x(idx) = value.asInstanceOf[AnyRef]
+ case x: Array[Int] => x(idx) = value.asInstanceOf[Int]
+ case x: Array[Double] => x(idx) = value.asInstanceOf[Double]
+ case x: Array[Long] => x(idx) = value.asInstanceOf[Long]
+ case x: Array[Float] => x(idx) = value.asInstanceOf[Float]
+ case x: Array[Char] => x(idx) = value.asInstanceOf[Char]
+ case x: Array[Byte] => x(idx) = value.asInstanceOf[Byte]
+ case x: Array[Short] => x(idx) = value.asInstanceOf[Short]
+ case x: Array[Boolean] => x(idx) = value.asInstanceOf[Boolean]
+ case x: Array[Unit] => x(idx) = value.asInstanceOf[Unit]
+ case null => throw new NullPointerException
+ }
}
/** Get generic array length */
@@ -340,14 +349,14 @@ object ScalaRunTime {
case null => "null"
case "" => "\"\""
case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x
- case x if useOwnToString(x) => x toString
+ case x if useOwnToString(x) => x.toString
case x: AnyRef if isArray(x) => arrayToString(x)
case x: collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")")
case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma
case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")")
- case x => x toString
+ case x => x.toString
}
// The try/catch is defense against iterables which aren't actually designed
diff --git a/test/instrumented/srt.patch b/test/instrumented/srt.patch
index 2f472ff1c0..8d08550165 100644
--- a/test/instrumented/srt.patch
+++ b/test/instrumented/srt.patch
@@ -1,23 +1,26 @@
9a10,11
> /* INSTRUMENTED VERSION */
->
-33a36,38
+>
+43c45,48
+< def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName)
+---
> var arrayApplyCount = 0
> var arrayUpdateCount = 0
->
-35c40,42
+>
+> def isTuple(x: Any) = tupleNames(x.getClass.getName)
+75c80,82
< def array_apply(xs: AnyRef, idx: Int): Any = xs match {
---
> def array_apply(xs: AnyRef, idx: Int): Any = {
> arrayApplyCount += 1
> xs match {
-47a55
+87a95
> }
-50c58,60
+90c98,100
< def array_update(xs: AnyRef, idx: Int, value: Any): Unit = xs match {
---
> def array_update(xs: AnyRef, idx: Int, value: Any): Unit = {
> arrayUpdateCount += 1
> xs match {
-62a73
+101a112
> }
diff --git a/test/pending/neg/reify_packed.check b/test/pending/neg/reify_packed.check
new file mode 100644
index 0000000000..adba330d56
--- /dev/null
+++ b/test/pending/neg/reify_packed.check
@@ -0,0 +1,4 @@
+reify_packed.scala:6: error: implementation restriction: cannot reify block of type List[_$1] that involves a type declared inside the block being reified. consider casting the return value to a suitable type.
+ reify {
+ ^
+one error found
diff --git a/test/pending/neg/reify_packed.scala b/test/pending/neg/reify_packed.scala
new file mode 100644
index 0000000000..0240f2a4b5
--- /dev/null
+++ b/test/pending/neg/reify_packed.scala
@@ -0,0 +1,10 @@
+object Test extends App {
+ reify {
+ class C { override def toString() = "C" }
+ val ret = List((new C, new C))
+ ret.asInstanceOf[List[_]]
+ };
+
+ val toolbox = mkToolBox()
+ println(toolbox.runExpr(code.tree))
+}
diff --git a/test/pending/pos/inference.scala b/test/pending/pos/inference.scala
index d28d003435..3672351fca 100644
--- a/test/pending/pos/inference.scala
+++ b/test/pending/pos/inference.scala
@@ -1,15 +1,15 @@
// inference illuminator
object Test {
- class D1[T1 : Manifest, T2 <: T1 : Manifest](x: T1) { println(manifest[(T1, T2)]) }
- class D2[T1 : Manifest, T2 >: T1 : Manifest](x: T1) { println(manifest[(T1, T2)]) }
- class D3[+T1 : Manifest, T2 <: T1 : Manifest](x: T1) { println(manifest[(T1, T2)]) }
- class D4[-T1 : Manifest, T2 >: T1 : Manifest](x: T1) { println(manifest[(T1, T2)]) }
-
- class E1[T1 : Manifest, T2 <: T1 : Manifest](x: D1[T1, T2]) { println(manifest[(T1, T2)]) }
- class E2[T1 : Manifest, T2 >: T1 : Manifest](x: D2[T1, T2]) { println(manifest[(T1, T2)]) }
- class E3[+T1 : Manifest, T2 <: T1 : Manifest](x: D3[T1, T2]) { println(manifest[(T1, T2)]) }
- class E4[-T1 : Manifest, T2 >: T1 : Manifest](x: D4[T1, T2]) { println(manifest[(T1, T2)]) }
-
+ class D1[T1 : TypeTag, T2 <: T1 : TypeTag](x: T1) { println(typeTag[(T1, T2)]) }
+ class D2[T1 : TypeTag, T2 >: T1 : TypeTag](x: T1) { println(typeTag[(T1, T2)]) }
+ class D3[+T1 : TypeTag, T2 <: T1 : TypeTag](x: T1) { println(typeTag[(T1, T2)]) }
+ class D4[-T1 : TypeTag, T2 >: T1 : TypeTag](x: T1) { println(typeTag[(T1, T2)]) }
+
+ class E1[T1 : TypeTag, T2 <: T1 : TypeTag](x: D1[T1, T2]) { println(typeTag[(T1, T2)]) }
+ class E2[T1 : TypeTag, T2 >: T1 : TypeTag](x: D2[T1, T2]) { println(typeTag[(T1, T2)]) }
+ class E3[+T1 : TypeTag, T2 <: T1 : TypeTag](x: D3[T1, T2]) { println(typeTag[(T1, T2)]) }
+ class E4[-T1 : TypeTag, T2 >: T1 : TypeTag](x: D4[T1, T2]) { println(typeTag[(T1, T2)]) }
+
def main(args: Array[String]): Unit = {
// WHY YOU NO LIKE NOTHING SO MUCH SCALAC?
val d1 = new D1(5)
diff --git a/test/pending/pos/t1476.scala b/test/pending/pos/t1476.scala
new file mode 100644
index 0000000000..1f8e95c28f
--- /dev/null
+++ b/test/pending/pos/t1476.scala
@@ -0,0 +1,23 @@
+abstract class Module {
+ def moduleDemands(): List[Module]
+}
+
+object Test {
+ new Module { owner: Module =>
+ def moduleDemands() = Nil
+
+ val a = new Module { def moduleDemands(): List[Module] = Nil }
+ val b = new Module { def moduleDemands(): List[Module] = owner :: c :: Nil }
+ val c = new Module { def moduleDemands(): List[Module] = owner :: a :: Nil }
+ }
+}
+
+object Test2 {
+ new Module { owner =>
+ def moduleDemands() = Nil
+
+ val a = new Module { def moduleDemands(): List[Module] = Nil }
+ val b = new Module { def moduleDemands(): List[Module] = owner :: c :: Nil }
+ val c = new Module { def moduleDemands(): List[Module] = owner :: a :: Nil }
+ }
+}
diff --git a/test/pending/pos/t5626.scala b/test/pending/pos/t5626.scala
new file mode 100644
index 0000000000..7ab3881827
--- /dev/null
+++ b/test/pending/pos/t5626.scala
@@ -0,0 +1,12 @@
+object Test {
+ val blob0 = new {
+ case class Foo(i : Int)
+ }
+ val foo0 = blob0.Foo(22)
+
+ val blob1 = new {
+ class Foo(i: Int)
+ object Foo { def apply(i: Int): Foo = new Foo(i) }
+ }
+ val foo1 = blob1.Foo(22)
+}
diff --git a/test/pending/run/implicit-classes.scala b/test/pending/run/implicit-classes.scala
new file mode 100644
index 0000000000..02b74de2b0
--- /dev/null
+++ b/test/pending/run/implicit-classes.scala
@@ -0,0 +1,17 @@
+object O {
+ implicit class C(s: String) {
+ def twice = s + s
+ }
+}
+
+/**
+//
+// We'd like to augment object O in Namers so that it also has an implicit method
+object O {
+ implicit class C(s: String) {
+ def twice = s + s
+ }
+ implicit def C(s: String): C = new C(s)
+}
+
+**/
diff --git a/test/files/pos/macros.flags b/test/pending/run/macro-expand-default.flags
index 7fea2ff901..7fea2ff901 100644
--- a/test/files/pos/macros.flags
+++ b/test/pending/run/macro-expand-default.flags
diff --git a/test/pending/run/macro-expand-default/Impls_1.scala b/test/pending/run/macro-expand-default/Impls_1.scala
new file mode 100644
index 0000000000..fefe8fc4e2
--- /dev/null
+++ b/test/pending/run/macro-expand-default/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = {
+ import c.mirror._
+ val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree))
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/pending/run/macro-expand-default/Macros_Test_2.scala b/test/pending/run/macro-expand-default/Macros_Test_2.scala
new file mode 100644
index 0000000000..92fe84d04a
--- /dev/null
+++ b/test/pending/run/macro-expand-default/Macros_Test_2.scala
@@ -0,0 +1,8 @@
+object Test extends App {
+ def foo(x: Int = 2, y: Int = -40) = macro Impls.foo
+ foo(y = -40, x = 2)
+ foo(x = 2, y = -40)
+ foo(x = 100)
+ foo(y = 100)
+ foo()
+} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check
new file mode 100644
index 0000000000..08f7cb9e3e
--- /dev/null
+++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.check
@@ -0,0 +1,6 @@
+openImplicits are: List()
+enclosingImplicits are: List((List[Int],scala.this.Predef.implicitly[List[Int]]))
+typetag is: ConcreteTypeTag[Nothing]
+openImplicits are: List()
+enclosingImplicits are: List((List[String],Test.this.bar[String]))
+typetag is: ConcreteTypeTag[Nothing]
diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala
new file mode 100644
index 0000000000..c096a83c5e
--- /dev/null
+++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.Context
+
+object Impls {
+ def foo[T: c.TypeTag](c: Context): c.Expr[List[T]] = c.reify {
+ println("openImplicits are: " + c.literal(c.openImplicits.toString).eval)
+ println("enclosingImplicits are: " + c.literal(c.enclosingImplicits.toString).eval)
+ println("typetag is: " + c.literal(c.tag[T].toString).eval)
+ null
+ }
+} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala
new file mode 100644
index 0000000000..27d0662799
--- /dev/null
+++ b/test/pending/run/macro-expand-implicit-macro-defeats-type-inference/Macros_Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ implicit def foo[T]: List[T] = macro Impls.foo[T]
+ def bar[T](implicit foo: List[T]) {}
+ implicitly[List[Int]]
+ bar[String]
+} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound.check b/test/pending/run/macro-expand-implicit-macro-has-context-bound.check
new file mode 100644
index 0000000000..ac4213d6e9
--- /dev/null
+++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound.check
@@ -0,0 +1 @@
+43 \ No newline at end of file
diff --git a/test/pending/run/macro-overload.flags b/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags
index 7fea2ff901..7fea2ff901 100644
--- a/test/pending/run/macro-overload.flags
+++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags
diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala
new file mode 100644
index 0000000000..5c50576281
--- /dev/null
+++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U](c: Ctx)(x: c.Expr[U])(evidence: c.Expr[Numeric[U]]) = {
+ import c.mirror._
+ val plusOne = Apply(Select(evidence.tree, newTermName("plus")), List(x.tree, Literal(Constant(1))))
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(plusOne))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala
new file mode 100644
index 0000000000..7d16b773a6
--- /dev/null
+++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ def foo[U: Numeric](x: U) = macro Impls.foo[U]
+ foo(42)
+} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-named.flags b/test/pending/run/macro-expand-named.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-expand-named.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-expand-named/Impls_1.scala b/test/pending/run/macro-expand-named/Impls_1.scala
new file mode 100644
index 0000000000..fefe8fc4e2
--- /dev/null
+++ b/test/pending/run/macro-expand-named/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = {
+ import c.mirror._
+ val sum = Apply(Select(x.tree, newTermName("$minus")), List(y.tree))
+ val body = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(sum))
+ Expr[Unit](body)
+ }
+}
diff --git a/test/pending/run/macro-expand-named/Macros_Test_2.scala b/test/pending/run/macro-expand-named/Macros_Test_2.scala
new file mode 100644
index 0000000000..abebcf8448
--- /dev/null
+++ b/test/pending/run/macro-expand-named/Macros_Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ def foo(x: Int, y: Int) = macro Impls.foo
+ foo(y = -40, x = 2)
+ foo(x = 2, y = -40)
+} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-tparams-prefix-e1.check b/test/pending/run/macro-expand-tparams-prefix-e1.check
new file mode 100644
index 0000000000..4fa05a7678
--- /dev/null
+++ b/test/pending/run/macro-expand-tparams-prefix-e1.check
@@ -0,0 +1,3 @@
+TypeTag(List[Int])
+TypeTag(String)
+TypeTag(Boolean)
diff --git a/test/pending/run/macro-expand-tparams-prefix-e1.flags b/test/pending/run/macro-expand-tparams-prefix-e1.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-expand-tparams-prefix-e1.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala b/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala
new file mode 100644
index 0000000000..bc880fdf77
--- /dev/null
+++ b/test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala
@@ -0,0 +1,12 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = {
+ import c.mirror._
+ Block(List(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))),
+ Literal(Constant(())))
+ }
+}
diff --git a/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala b/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala
new file mode 100644
index 0000000000..5c863804d0
--- /dev/null
+++ b/test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class D[T: TypeTag] {
+ class C[U: TypeTag] {
+ def foo[V] = macro Impls.foo[List[T], U, V]
+ foo[Boolean]
+ }
+ }
+
+ val outer1 = new D[Int]
+ new outer1.C[String]
+} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-tparams-prefix-f1.check b/test/pending/run/macro-expand-tparams-prefix-f1.check
new file mode 100644
index 0000000000..d15226143a
--- /dev/null
+++ b/test/pending/run/macro-expand-tparams-prefix-f1.check
@@ -0,0 +1,3 @@
+TypeTag(List[T])
+TypeTag(U)
+TypeTag(Boolean)
diff --git a/test/pending/run/macro-expand-tparams-prefix-f1.flags b/test/pending/run/macro-expand-tparams-prefix-f1.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-expand-tparams-prefix-f1.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala b/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala
new file mode 100644
index 0000000000..bc880fdf77
--- /dev/null
+++ b/test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala
@@ -0,0 +1,12 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[T, U: c.TypeTag, V](c: Ctx)(implicit T: c.TypeTag[T], V: c.TypeTag[V]): c.Expr[Unit] = {
+ import c.mirror._
+ Block(List(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(T.toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(implicitly[c.TypeTag[U]].toString)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant(V.toString))))),
+ Literal(Constant(())))
+ }
+}
diff --git a/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala b/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala
new file mode 100644
index 0000000000..bc8e7ac75c
--- /dev/null
+++ b/test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class D[T] {
+ class C[U] {
+ def foo[V] = macro Impls.foo[List[T], U, V]
+ foo[Boolean]
+ }
+ }
+
+ val outer1 = new D[Int]
+ new outer1.C[String]
+} \ No newline at end of file
diff --git a/test/pending/run/macro-overload.check b/test/pending/run/macro-overload.check
deleted file mode 100644
index 764f914e48..0000000000
--- a/test/pending/run/macro-overload.check
+++ /dev/null
@@ -1,4 +0,0 @@
-object-Int
-object-String
-class-Int
-class-String \ No newline at end of file
diff --git a/test/pending/run/macro-overload/Macros_1.scala b/test/pending/run/macro-overload/Macros_1.scala
deleted file mode 100644
index f24c69ea7b..0000000000
--- a/test/pending/run/macro-overload/Macros_1.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-object Macros {
- def macro bar(x: Int): Int = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("object-Int"))))
- def macro bar(x: String): String = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("object-String"))))
-}
-
-class Macros {
- def macro bar(x: Int): Int = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("class-Int"))))
- def macro bar(x: String): String = Apply(Select(Select(Ident("scala"), newTermName("Predef")), newTermName("println")), List(Literal(Constant("class-String"))))
-} \ No newline at end of file
diff --git a/test/pending/run/macro-overload/Test_2.scala b/test/pending/run/macro-overload/Test_2.scala
deleted file mode 100644
index 75f6572e03..0000000000
--- a/test/pending/run/macro-overload/Test_2.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-object Test extends App {
- Macros.bar(2)
- Macros.bar("2")
- new Macros.bar(2)
- new Macros.bar("2")
-} \ No newline at end of file
diff --git a/test/pending/run/macro-quasiinvalidbody-a.check b/test/pending/run/macro-quasiinvalidbody-a.check
new file mode 100644
index 0000000000..f70d7bba4a
--- /dev/null
+++ b/test/pending/run/macro-quasiinvalidbody-a.check
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/test/pending/run/macro-quasiinvalidbody-a.flags b/test/pending/run/macro-quasiinvalidbody-a.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-quasiinvalidbody-a.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala b/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala
new file mode 100644
index 0000000000..0da37cd5c0
--- /dev/null
+++ b/test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala
@@ -0,0 +1,5 @@
+import scala.reflect.makro.{Context => Ctx}
+
+trait Impls {
+ def impl(c: Ctx)(x: c.Expr[Any]) = x
+} \ No newline at end of file
diff --git a/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala b/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala
new file mode 100644
index 0000000000..04a43080bd
--- /dev/null
+++ b/test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros extends Impls {
+ def foo(x: Any) = macro impl
+}
+
+object Test extends App {
+ import Macros._
+ println(foo(42))
+} \ No newline at end of file
diff --git a/test/pending/run/macro-quasiinvalidbody-b.check b/test/pending/run/macro-quasiinvalidbody-b.check
new file mode 100644
index 0000000000..f70d7bba4a
--- /dev/null
+++ b/test/pending/run/macro-quasiinvalidbody-b.check
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/test/pending/run/macro-quasiinvalidbody-b.flags b/test/pending/run/macro-quasiinvalidbody-b.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-quasiinvalidbody-b.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala b/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala
new file mode 100644
index 0000000000..d84d04974f
--- /dev/null
+++ b/test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala
@@ -0,0 +1,7 @@
+import scala.reflect.makro.{Context => Ctx}
+
+trait ImplContainer {
+ object Impls {
+ def foo(c: Ctx)(x: c.Expr[Any]) = x
+ }
+} \ No newline at end of file
diff --git a/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala b/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala
new file mode 100644
index 0000000000..82f88b62e4
--- /dev/null
+++ b/test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros extends ImplContainer {
+ def foo(x: Any) = macro Impls.foo
+}
+
+object Test extends App {
+ import Macros._
+ println(foo(42))
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-array.flags b/test/pending/run/macro-reify-array.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-reify-array.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-reify-array/Macros_1.scala b/test/pending/run/macro-reify-array/Macros_1.scala
new file mode 100644
index 0000000000..af42321484
--- /dev/null
+++ b/test/pending/run/macro-reify-array/Macros_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def foo[T](s: String) = macro Impls.foo[T]
+
+ object Impls {
+ def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify {
+ Array(s.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-array/Test_2.scala b/test/pending/run/macro-reify-array/Test_2.scala
new file mode 100644
index 0000000000..e40d5b40e0
--- /dev/null
+++ b/test/pending/run/macro-reify-array/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val arr = Macros.foo("hello", "world")
+ println(arr.getClass)
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-eval-vs-value.flags b/test/pending/run/macro-reify-eval-vs-value.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-reify-eval-vs-value.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala b/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala
new file mode 100644
index 0000000000..98dd93b0f8
--- /dev/null
+++ b/test/pending/run/macro-reify-eval-vs-value/Macros_1.scala
@@ -0,0 +1,25 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def fooEval(s: String) = macro Impls.fooEval
+ def fooValue(s: String) = macro Impls.fooValue
+
+ object Impls {
+ def fooEval(c: Ctx)(s: c.Expr[String]) = c.reify {
+ println("hello " + s.eval)
+ println("hello " + s.eval)
+ }
+
+ def fooValue(c: Ctx)(s: c.Expr[String]) = c.reify {
+ {
+ println("hello " + s.value)
+ def sayHello = println(s.value)
+ sayHello
+ }
+ println("hello " + s.eval);
+ {
+ println("hello " + s.eval)
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-eval-vs-value/Test_2.scala b/test/pending/run/macro-reify-eval-vs-value/Test_2.scala
new file mode 100644
index 0000000000..8e62e6e0e7
--- /dev/null
+++ b/test/pending/run/macro-reify-eval-vs-value/Test_2.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ Macros.fooEval({ println("in ur logz"); "world"})
+ println("======================")
+ Macros.fooValue({ println("i can has cheezburger?"); "world"})
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check
new file mode 100644
index 0000000000..7e4b000c52
--- /dev/null
+++ b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check
@@ -0,0 +1,2 @@
+TypeTag(List[Int])
+TypeTag(List[List[Int]])
diff --git a/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala
new file mode 100644
index 0000000000..ef70a66f1a
--- /dev/null
+++ b/test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooTypeTagHK[C[_]: ConcreteTypeTag, T: ConcreteTypeTag] = {
+ println(implicitly[ConcreteTypeTag[C[T]]])
+ println(implicitly[ConcreteTypeTag[List[C[T]]]])
+ }
+ fooTypeTagHK[List, Int]
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-tagful-b.check b/test/pending/run/macro-reify-tagful-b.check
new file mode 100644
index 0000000000..5bd9fe2156
--- /dev/null
+++ b/test/pending/run/macro-reify-tagful-b.check
@@ -0,0 +1 @@
+List(List(hello world))
diff --git a/test/pending/run/macro-reify-tagful-b.flags b/test/pending/run/macro-reify-tagful-b.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-reify-tagful-b.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-reify-tagful-b/Macros_1.scala b/test/pending/run/macro-reify-tagful-b/Macros_1.scala
new file mode 100644
index 0000000000..38b839330b
--- /dev/null
+++ b/test/pending/run/macro-reify-tagful-b/Macros_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def foo[T](s: T) = macro Impls.foo[List[T]]
+
+ object Impls {
+ def foo[T: c.TypeTag](c: Ctx)(s: c.Expr[T]) = c.reify {
+ List(s.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-tagful-b/Test_2.scala b/test/pending/run/macro-reify-tagful-b/Test_2.scala
new file mode 100644
index 0000000000..142234901f
--- /dev/null
+++ b/test/pending/run/macro-reify-tagful-b/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val list: List[List[String]] = Macros.foo(List("hello world"))
+ println(list)
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-tagless-b.check b/test/pending/run/macro-reify-tagless-b.check
new file mode 100644
index 0000000000..49acd94ad6
--- /dev/null
+++ b/test/pending/run/macro-reify-tagless-b.check
@@ -0,0 +1,3 @@
+error: macro must not return an expr that contains free type variables (namely: T). have you forgot to use c.TypeTag annotations for type parameters external to a reifee?
+
+java.lang.Error: reflective compilation has failed
diff --git a/test/pending/run/macro-reify-tagless-b.flags b/test/pending/run/macro-reify-tagless-b.flags
new file mode 100644
index 0000000000..7fea2ff901
--- /dev/null
+++ b/test/pending/run/macro-reify-tagless-b.flags
@@ -0,0 +1 @@
+-Xmacros \ No newline at end of file
diff --git a/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala b/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala
new file mode 100644
index 0000000000..fac7ba5b98
--- /dev/null
+++ b/test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Macros {
+ def foo[T](s: T) = macro Impls.foo[List[T]]
+
+ object Impls {
+ def foo[T](c: Ctx)(s: c.Expr[T]) = c.reify {
+ List(s.eval)
+ }
+ }
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-tagless-b/Test_2.scala b/test/pending/run/macro-reify-tagless-b/Test_2.scala
new file mode 100644
index 0000000000..419ee42101
--- /dev/null
+++ b/test/pending/run/macro-reify-tagless-b/Test_2.scala
@@ -0,0 +1,11 @@
+object Test extends App {
+ //val list: List[String] = Macros.foo("hello world")
+ //println(list)
+
+ import scala.reflect.mirror._
+ val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass)))
+ val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world"))))
+ val list = ValDef(NoMods, newTermName("list"), tpt, rhs)
+ val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name))))
+ println(tree.eval)
+}
diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-notags.check b/test/pending/run/macro-reify-typetag-hktypeparams-notags.check
new file mode 100644
index 0000000000..db8a19d5f7
--- /dev/null
+++ b/test/pending/run/macro-reify-typetag-hktypeparams-notags.check
@@ -0,0 +1,2 @@
+TypeTag(C[T])
+TypeTag(List[C[T]])
diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala b/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala
new file mode 100644
index 0000000000..9a370189a7
--- /dev/null
+++ b/test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooNoTypeTagHK[C[_], T] = {
+ println(implicitly[TypeTag[C[T]]])
+ println(implicitly[TypeTag[List[C[T]]]])
+ }
+ fooNoTypeTagHK[List, Int]
+} \ No newline at end of file
diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-tags.check b/test/pending/run/macro-reify-typetag-hktypeparams-tags.check
new file mode 100644
index 0000000000..7e4b000c52
--- /dev/null
+++ b/test/pending/run/macro-reify-typetag-hktypeparams-tags.check
@@ -0,0 +1,2 @@
+TypeTag(List[Int])
+TypeTag(List[List[Int]])
diff --git a/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala b/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala
new file mode 100644
index 0000000000..0358da9b0d
--- /dev/null
+++ b/test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala
@@ -0,0 +1,9 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ def fooTypeTagHK[C[_]: TypeTag, T: TypeTag] = {
+ println(implicitly[TypeTag[C[T]]])
+ println(implicitly[TypeTag[List[C[T]]]])
+ }
+ fooTypeTagHK[List, Int]
+} \ No newline at end of file
diff --git a/test/pending/run/reify_addressbook.scala b/test/pending/run/reify_addressbook.scala
index 54dd5545bd..7cb6dc08fd 100644
--- a/test/pending/run/reify_addressbook.scala
+++ b/test/pending/run/reify_addressbook.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
case class Person(name: String, age: Int)
/** An AddressBook takes a variable number of arguments
@@ -62,9 +60,5 @@ object Test extends App {
</html>;
println(page)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/pending/run/reify_brainf_ck.scala b/test/pending/run/reify_brainf_ck.scala
index 0034644b81..e4bcb257bd 100644
--- a/test/pending/run/reify_brainf_ck.scala
+++ b/test/pending/run/reify_brainf_ck.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
import scala.annotation._
trait Func[T] {
@@ -76,9 +74,5 @@ object Test extends App {
<.#>+++++++++++[<+++++>-]<.>++++++++[<++
+>-]<.+++.------.--------.[-]>++++++++[<++++>
-]<+.[-]++++++++++.""")
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/pending/run/reify_callccinterpreter.scala b/test/pending/run/reify_callccinterpreter.scala
index 96ae9c5c17..0e23f75dcc 100644
--- a/test/pending/run/reify_callccinterpreter.scala
+++ b/test/pending/run/reify_callccinterpreter.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
type Answer = Value;
/**
@@ -85,9 +83,5 @@ object Test extends App {
println(test(term0))
println(test(term1))
println(test(term2))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/pending/run/reify_closure2b.scala b/test/pending/run/reify_closure2b.scala
index b9c0063290..f9ed16d309 100644
--- a/test/pending/run/reify_closure2b.scala
+++ b/test/pending/run/reify_closure2b.scala
@@ -1,17 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
object Test extends App {
def foo(y: Int): Int => Int = {
class Foo(y: Int) {
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reflect.mirror.reify{(x: Int) => {
x + y
}}
}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(new Foo(y).fun.tree)
dyn.asInstanceOf[Int => Int]
}
diff --git a/test/pending/run/reify_closure3b.scala b/test/pending/run/reify_closure3b.scala
index 8f161dbff3..8ef0a60c66 100644
--- a/test/pending/run/reify_closure3b.scala
+++ b/test/pending/run/reify_closure3b.scala
@@ -1,19 +1,14 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
object Test extends App {
def foo(y: Int): Int => Int = {
class Foo(y: Int) {
def y1 = y
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reflect.mirror.reify{(x: Int) => {
x + y1
}}
}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(new Foo(y).fun.tree)
dyn.asInstanceOf[Int => Int]
}
diff --git a/test/pending/run/reify_closure4b.scala b/test/pending/run/reify_closure4b.scala
index 238795d4dd..9eeb01b459 100644
--- a/test/pending/run/reify_closure4b.scala
+++ b/test/pending/run/reify_closure4b.scala
@@ -1,19 +1,14 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
object Test extends App {
def foo(y: Int): Int => Int = {
class Foo(y: Int) {
val y1 = y
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reflect.mirror.reify{(x: Int) => {
x + y1
}}
}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(new Foo(y).fun.tree)
dyn.asInstanceOf[Int => Int]
}
diff --git a/test/pending/run/reify_closure5b.scala b/test/pending/run/reify_closure5b.scala
index bdb2583e8a..51f1ec318d 100644
--- a/test/pending/run/reify_closure5b.scala
+++ b/test/pending/run/reify_closure5b.scala
@@ -1,17 +1,12 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
object Test extends App {
def foo[T](ys: List[T]): Int => Int = {
class Foo[T](ys: List[T]) {
- val fun = reflect.Code.lift{(x: Int) => {
+ val fun = reflect.mirror.reify{(x: Int) => {
x + ys.length
}}
}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(new Foo(ys).fun.tree)
dyn.asInstanceOf[Int => Int]
}
diff --git a/test/pending/run/reify_closure8b.check b/test/pending/run/reify_closure8b.check
deleted file mode 100644
index 9a037142aa..0000000000
--- a/test/pending/run/reify_closure8b.check
+++ /dev/null
@@ -1 +0,0 @@
-10 \ No newline at end of file
diff --git a/test/pending/run/reify_closure8b.scala b/test/pending/run/reify_closure8b.scala
deleted file mode 100644
index 38031c217b..0000000000
--- a/test/pending/run/reify_closure8b.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-import scala.reflect.Code._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
-object Test extends App {
- class Foo(y: Int) {
- def fun = lift{y}
- }
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- val dyn = toolbox.runExpr(new Foo(10).fun.tree)
- val foo = dyn.asInstanceOf[Int]
- println(foo)
-}
diff --git a/test/pending/run/reify_closure9a.scala b/test/pending/run/reify_closure9a.scala
index 185f4ffca1..1fc18cfa13 100644
--- a/test/pending/run/reify_closure9a.scala
+++ b/test/pending/run/reify_closure9a.scala
@@ -1,16 +1,11 @@
-import scala.reflect.Code._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
+import scala.reflect.mirror._
object Test extends App {
def foo(y: Int) = {
class Foo(val y: Int) {
- def fun = lift{y}
+ def fun = reify{y}
}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(new Foo(y).fun.tree)
dyn.asInstanceOf[Int]
}
diff --git a/test/pending/run/reify_closure9b.scala b/test/pending/run/reify_closure9b.scala
index ad279fac6d..32b05d00ee 100644
--- a/test/pending/run/reify_closure9b.scala
+++ b/test/pending/run/reify_closure9b.scala
@@ -1,16 +1,11 @@
-import scala.reflect.Code._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
+import scala.reflect.mirror._
object Test extends App {
def foo(y: Int) = {
class Foo(y: Int) {
- def fun = lift{y}
+ def fun = reify{y}
}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(new Foo(y).fun.tree)
dyn.asInstanceOf[Int]
}
diff --git a/test/pending/run/reify_closures11.scala b/test/pending/run/reify_closures11.scala
index 2c4177b8f2..ceb224c6d6 100644
--- a/test/pending/run/reify_closures11.scala
+++ b/test/pending/run/reify_closures11.scala
@@ -1,16 +1,11 @@
-import scala.reflect.Code._
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
+import scala.reflect.mirror._
object Test extends App {
def fun() = {
def z() = 2
- lift{z}
+ reify{z}
}
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
+ val toolbox = mkToolBox()
val dyn = toolbox.runExpr(fun().tree)
val foo = dyn.asInstanceOf[Int]
println(foo)
diff --git a/test/pending/run/reify_csv.scala b/test/pending/run/reify_csv.scala
index a6a616fab0..966521575c 100644
--- a/test/pending/run/reify_csv.scala
+++ b/test/pending/run/reify_csv.scala
@@ -1,6 +1,4 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
val csv = """
@@ -18,7 +16,7 @@ object Test extends App {
val fields = csv.head.split(";").map{_.trim()}.toList
println(fields)
- val code = scala.reflect.Code.lift({
+ reify({
object Csv {
case class record(`phase name`: String, id: String, description: String)
@@ -33,9 +31,5 @@ object Test extends App {
}
Csv.record.parse(csv) foreach println
- })
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }).eval
}
diff --git a/test/pending/run/reify_gadts.scala b/test/pending/run/reify_gadts.scala
index 9feb7a5726..652a7d99d8 100644
--- a/test/pending/run/reify_gadts.scala
+++ b/test/pending/run/reify_gadts.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
/* The syntax tree of a toy language */
abstract class Term[T]
@@ -36,9 +34,5 @@ object Test extends App {
}
println(
eval(If(IsZero(Lit(1)), Lit(41), Succ(Lit(41)))))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/pending/run/reify_lazyevaluation.scala b/test/pending/run/reify_lazyevaluation.scala
index 0720a7c979..1a0c858914 100644
--- a/test/pending/run/reify_lazyevaluation.scala
+++ b/test/pending/run/reify_lazyevaluation.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
object lazyLib {
/** Delay the evaluation of an expression until it is needed. */
@@ -56,9 +54,5 @@ object Test extends App {
println("sl2 = " + sl2)
println("sl2() = " + sl2())
println("sl2 = " + sl2)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/pending/run/reify_newimpl_07.scala b/test/pending/run/reify_newimpl_07.scala
new file mode 100644
index 0000000000..13ca6bda8b
--- /dev/null
+++ b/test/pending/run/reify_newimpl_07.scala
@@ -0,0 +1,13 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ {
+ class C(val y: Int) {
+ val code = reify {
+ reify{y}.eval
+ }
+ }
+
+ println(new C(2).code.eval)
+ }
+} \ No newline at end of file
diff --git a/test/pending/run/reify_newimpl_08.scala b/test/pending/run/reify_newimpl_08.scala
new file mode 100644
index 0000000000..e2faa3c9af
--- /dev/null
+++ b/test/pending/run/reify_newimpl_08.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ val code = reify {
+ class C(val y: Int) {
+ val code = reify {
+ reify{y}.eval
+ }
+ }
+
+ new C(2).code.eval
+ }
+
+ println(code.eval)
+} \ No newline at end of file
diff --git a/test/pending/run/reify_newimpl_35.scala b/test/pending/run/reify_newimpl_35.scala
new file mode 100644
index 0000000000..5e1d163e9e
--- /dev/null
+++ b/test/pending/run/reify_newimpl_35.scala
@@ -0,0 +1,10 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ override def extraSettings = "-Xlog-free-types"
+ def code = """
+import scala.reflect.mirror._
+def foo[T: TypeTag] = reify{List[T]()}
+println(foo)
+ """
+}
diff --git a/test/pending/run/reify_newimpl_46.scala b/test/pending/run/reify_newimpl_46.scala
new file mode 100644
index 0000000000..840d695e83
--- /dev/null
+++ b/test/pending/run/reify_newimpl_46.scala
@@ -0,0 +1,12 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C[T[_] >: Null] {
+ val code = reify{val x: T[String] = null; println("ima worx"); x}
+ println(freeTypes(code))
+ val T = freeTypes(code)(0)
+ mkToolBox().runExpr(code, Map(T -> definitions.ListClass.asType))
+ }
+
+ new C[List]
+} \ No newline at end of file
diff --git a/test/pending/run/reify_newimpl_53.scala b/test/pending/run/reify_newimpl_53.scala
new file mode 100644
index 0000000000..26645dea6a
--- /dev/null
+++ b/test/pending/run/reify_newimpl_53.scala
@@ -0,0 +1,15 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ class C[T >: Null] {
+ val code = reify{
+ val tt = implicitly[TypeTag[T]]
+ println("mah typetag is: %s".format(tt))
+ }
+ println(freeTypes(code))
+ val T = freeTypes(code)(0)
+ mkToolBox().runExpr(code, Map(T -> definitions.StringClass.asType))
+ }
+
+ new C[String]
+} \ No newline at end of file
diff --git a/test/pending/run/reify_properties.scala b/test/pending/run/reify_properties.scala
index 265c344b8e..5cacc262ac 100644
--- a/test/pending/run/reify_properties.scala
+++ b/test/pending/run/reify_properties.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
/** A mutable property whose getter and setter may be customized. */
case class Property[T](init: T) {
private var value: T = init
@@ -54,9 +52,5 @@ object Test extends App {
println("user1: " + user1)
println("user2: " + user2)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/pending/run/reify_simpleinterpreter.scala b/test/pending/run/reify_simpleinterpreter.scala
index 4762afb3cc..2193edeea7 100644
--- a/test/pending/run/reify_simpleinterpreter.scala
+++ b/test/pending/run/reify_simpleinterpreter.scala
@@ -1,9 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
case class M[A](value: A) {
def bind[B](k: A => M[B]): M[B] = k(value)
def map[B](f: A => B): M[B] = bind(x => unitM(f(x)))
@@ -73,9 +71,5 @@ object Test extends App {
println(test(term0))
println(test(term1))
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/files/run/t5258a.check b/test/pending/run/t5258a.check
index 4e0b2da04c..4e0b2da04c 100644
--- a/test/files/run/t5258a.check
+++ b/test/pending/run/t5258a.check
diff --git a/test/pending/run/t5258a.scala b/test/pending/run/t5258a.scala
new file mode 100644
index 0000000000..127829c724
--- /dev/null
+++ b/test/pending/run/t5258a.scala
@@ -0,0 +1,7 @@
+import scala.reflect.mirror._
+
+object Test extends App {
+ reify {
+ println(classOf[Int])
+ }.eval
+} \ No newline at end of file
diff --git a/test/pending/run/t5258b.scala b/test/pending/run/t5258b.scala
index 3a603095b3..82555cde96 100644
--- a/test/pending/run/t5258b.scala
+++ b/test/pending/run/t5258b.scala
@@ -1,14 +1,8 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
class C
println(classOf[C])
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
} \ No newline at end of file
diff --git a/test/pending/run/t5258c.scala b/test/pending/run/t5258c.scala
index b0d16ba0b1..a0a1647486 100644
--- a/test/pending/run/t5258c.scala
+++ b/test/pending/run/t5258c.scala
@@ -1,14 +1,8 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
object E extends Enumeration { val foo, bar = Value }
println(E.foo)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
} \ No newline at end of file
diff --git a/test/pending/run/t5271_1.scala b/test/pending/run/t5271_1.scala
deleted file mode 100644
index afbd8fe465..0000000000
--- a/test/pending/run/t5271_1.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
-object Test extends App {
- val code = scala.reflect.Code.lift{
- case class C(foo: Int, bar: Int)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
-}
diff --git a/test/pending/run/t5271_2.check b/test/pending/run/t5271_2.check
deleted file mode 100644
index b8626c4cff..0000000000
--- a/test/pending/run/t5271_2.check
+++ /dev/null
@@ -1 +0,0 @@
-4
diff --git a/test/pending/run/t5271_2.scala b/test/pending/run/t5271_2.scala
deleted file mode 100644
index d85d945973..0000000000
--- a/test/pending/run/t5271_2.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
-object Test extends App {
- val code = scala.reflect.Code.lift{
- case class C(foo: Int, bar: Int)
- val c = C(2, 2)
- println(c.foo * c.bar)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
-}
diff --git a/test/pending/run/t5271_3.check b/test/pending/run/t5271_3.check
deleted file mode 100644
index f32a5804e2..0000000000
--- a/test/pending/run/t5271_3.check
+++ /dev/null
@@ -1 +0,0 @@
-true \ No newline at end of file
diff --git a/test/pending/run/t5271_3.scala b/test/pending/run/t5271_3.scala
deleted file mode 100644
index 5a624de903..0000000000
--- a/test/pending/run/t5271_3.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
-
-object Test extends App {
- val code = scala.reflect.Code.lift{
- object C { def qwe = 4 }
- case class C(foo: Int, bar: Int)
- val c = C(2, 2)
- println(c.foo * c.bar == C.qwe)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
-}
diff --git a/test/pending/run/t5418.scala b/test/pending/run/t5418.scala
index fe813cf5ae..9b0a954e47 100644
--- a/test/pending/run/t5418.scala
+++ b/test/pending/run/t5418.scala
@@ -1,13 +1,7 @@
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import reflect.runtime.Mirror.ToolBox
+import scala.reflect.mirror._
object Test extends App {
- val code = scala.reflect.Code.lift{
+ reify {
new Object().getClass
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
} \ No newline at end of file
diff --git a/test/pending/run/t5629.check b/test/pending/run/t5629.check
new file mode 100644
index 0000000000..6a2d630f4e
--- /dev/null
+++ b/test/pending/run/t5629.check
@@ -0,0 +1,2 @@
+int child got: 33
+any child got: 33
diff --git a/test/pending/run/t5629.scala b/test/pending/run/t5629.scala
new file mode 100644
index 0000000000..28e74a1c94
--- /dev/null
+++ b/test/pending/run/t5629.scala
@@ -0,0 +1,25 @@
+import scala.{specialized => spec}
+
+trait GrandParent[@spec(Int) -A] {
+ def foo(a:A): Unit
+ def bar[B <: A](b:B): Unit = println("grandparent got: %s" format b)
+}
+
+trait Parent[@spec(Int) -A] extends GrandParent[A] {
+ def foo(a:A) = bar(a)
+}
+
+class IntChild extends Parent[Int] {
+ override def bar[B <: Int](b:B): Unit = println("int child got: %s" format b)
+}
+
+class AnyChild extends Parent[Any] {
+ override def bar[B <: Any](b:B): Unit = println("any child got: %s" format b)
+}
+
+object Test {
+ def main(args:Array[String]) {
+ new IntChild().foo(33)
+ new AnyChild().foo(33)
+ }
+}
diff --git a/test/pending/run/t5692.flags b/test/pending/run/t5692.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/pending/run/t5692.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/pending/run/t5692/Impls_Macros_1.scala b/test/pending/run/t5692/Impls_Macros_1.scala
new file mode 100644
index 0000000000..f9c1e5f12b
--- /dev/null
+++ b/test/pending/run/t5692/Impls_Macros_1.scala
@@ -0,0 +1,9 @@
+import scala.reflect.makro.Context
+
+object Impls {
+ def impl[A](c: reflect.makro.Context) = c.reify(())
+}
+
+object Macros {
+ def decl[A] = macro Impls.impl[A]
+} \ No newline at end of file
diff --git a/test/pending/run/t5692/Test_2.scala b/test/pending/run/t5692/Test_2.scala
new file mode 100644
index 0000000000..29251a5ef5
--- /dev/null
+++ b/test/pending/run/t5692/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ val x = Macros.decl
+ def y() { Macros.decl(); }
+} \ No newline at end of file
diff --git a/test/pending/shootout/meteor.scala b/test/pending/shootout/meteor.scala
index 2fd702753a..154695533b 100644
--- a/test/pending/shootout/meteor.scala
+++ b/test/pending/shootout/meteor.scala
@@ -19,7 +19,7 @@ object meteor {
-// Solver.scala
+// Solver.scala
// import scala.collection.mutable._
final class Solver (n: Int) {
@@ -29,8 +29,8 @@ final class Solver (n: Int) {
private val board = new Board()
- val pieces = Array(
- new Piece(0), new Piece(1), new Piece(2), new Piece(3), new Piece(4),
+ val pieces = Array(
+ new Piece(0), new Piece(1), new Piece(2), new Piece(3), new Piece(4),
new Piece(5), new Piece(6), new Piece(7), new Piece(8), new Piece(9) )
val unplaced = new BitSet(pieces.length)
@@ -71,8 +71,8 @@ final class Solver (n: Int) {
private def puzzleSolved() = {
val b = board.asString
- if (first == null){
- first = b; last = b
+ if (first == null){
+ first = b; last = b
} else {
if (b < first){ first = b } else { if (b > last){ last = b } }
}
@@ -81,7 +81,7 @@ final class Solver (n: Int) {
private def shouldPrune() = {
board.unmark
- !board.cells.forall(c => c.contiguousEmptyCells % Piece.size == 0)
+ !board.cells.forall(c => c.contiguousEmptyCells % Piece.size == 0)
}
@@ -108,8 +108,8 @@ final class Solver (n: Int) {
}
/*
- def printPieces() =
- for (i <- Iterator.range(0,Board.pieces)) pieces(i).print
+ def printPieces() =
+ for (i <- Iterator.range(0,Board.pieces)) pieces(i).print
*/
}
@@ -126,7 +126,7 @@ object Board {
val size = rows * cols
}
-final class Board {
+final class Board {
val cells = boardCells()
val cellsPieceWillFill = new Array[BoardCell](Piece.size)
@@ -134,9 +134,9 @@ final class Board {
def unmark() = for (c <- cells) c.unmark
- def asString() =
- new String( cells map(
- c => if (c.piece == null) '-'.toByte
+ def asString() =
+ new String( cells map(
+ c => if (c.piece == null) '-'.toByte
else (c.piece.number + 48).toByte ))
def firstEmptyCellIndex() = cells.findIndexOf(c => c.isEmpty)
@@ -144,13 +144,13 @@ final class Board {
def add(pieceIndex: Int, boardIndex: Int, p: Piece) = {
cellCount = 0
p.unmark
-
+
find( p.cells(pieceIndex), cells(boardIndex))
- val boardHasSpace = cellCount == Piece.size &&
- cellsPieceWillFill.forall(c => c.isEmpty)
+ val boardHasSpace = cellCount == Piece.size &&
+ cellsPieceWillFill.forall(c => c.isEmpty)
- if (boardHasSpace) cellsPieceWillFill.foreach(c => c.piece = p)
+ if (boardHasSpace) cellsPieceWillFill.foreach(c => c.piece = p)
boardHasSpace
}
@@ -180,10 +180,10 @@ final class Board {
if (row % 2 == 1) {
if (!isLast) c.next(Cell.NE) = a(i-(Board.cols-1))
- c.next(Cell.NW) = a(i-Board.cols)
+ c.next(Cell.NW) = a(i-Board.cols)
if (row != m) {
if (!isLast) c.next(Cell.SE) = a(i+(Board.cols+1))
- c.next(Cell.SW) = a(i+Board.cols)
+ c.next(Cell.SW) = a(i+Board.cols)
}
} else {
if (row != 0) {
@@ -212,9 +212,9 @@ final class Board {
Console.print(i + "\t")
for (j <- Iterator.range(0,Cell.sides)){
val c = cells(i).next(j)
- if (c == null)
- Console.print("-- ")
- else
+ if (c == null)
+ Console.print("-- ")
+ else
Console.printf("{0,number,00} ")(c.number)
}
Console.println("")
@@ -241,7 +241,7 @@ final class Piece(_number: Int) {
val number = _number
val cells = for (i <- Array.range(0,Piece.size)) yield new PieceCell()
- {
+ {
number match {
case 0 => make0
case 1 => make1
@@ -252,7 +252,7 @@ final class Piece(_number: Int) {
case 6 => make6
case 7 => make7
case 8 => make8
- case 9 => make9
+ case 9 => make9
}
}
@@ -395,12 +395,12 @@ final class Piece(_number: Int) {
Console.print(i + "\t")
for (j <- Iterator.range(0,Cell.sides)){
val c = cells(i).next(j)
- if (c == null)
- Console.print("-- ")
- else
+ if (c == null)
+ Console.print("-- ")
+ else
for (k <- Iterator.range(0,Piece.size)){
if (cells(k) == c) Console.printf(" {0,number,0} ")(k)
- }
+ }
}
Console.println("")
}
@@ -418,13 +418,13 @@ final class Piece(_number: Int) {
object Cell {
val NW = 0; val NE = 1
val W = 2; val E = 3
- val SW = 4; val SE = 5
+ val SW = 4; val SE = 5
val sides = 6
}
abstract class Cell {
- implicit def m: Manifest[T]
+ implicit def t: ClassTag[T]
type T
val next = new Array[T](Cell.sides)
var marked = false
@@ -437,7 +437,7 @@ abstract class Cell {
final class BoardCell(_number: Int) extends {
type T = BoardCell
- implicit val m = manifest[BoardCell]
+ implicit val t = classTag[BoardCell]
} with Cell {
val number = _number
var piece: Piece = _
@@ -448,10 +448,10 @@ final class BoardCell(_number: Int) extends {
def contiguousEmptyCells(): Int = {
if (!marked && isEmpty){
mark
- var count = 1
+ var count = 1
for (neighbour <- next)
- if (neighbour != null && neighbour.isEmpty)
+ if (neighbour != null && neighbour.isEmpty)
count = count + neighbour.contiguousEmptyCells
count } else { 0 }
diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala
new file mode 100644
index 0000000000..65d7bdf67c
--- /dev/null
+++ b/test/scaladoc/resources/implicits-base-res.scala
@@ -0,0 +1,148 @@
+/**
+ * Test scaladoc implicits - the bread and butter of the testsuite :)
+ */
+package scala.test.scaladoc.implicits.base
+
+class Foo[T]
+class Bar[T]
+trait MyNumeric[R]
+
+/** Class A
+ * - tests the complete type inference
+ * - the following inherited methods should appear:
+ * {{{
+ * def convToGtColonDoubleA(x: Double) // pimpA3: with a constraint that T <: Double
+ * def convToIntA(x: Int) // pimpA2: with a constraint that T = Int
+ * def convToManifestA(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double
+ * def convToMyNumericA(x: T) // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope
+ * def convToNumericA(x: T) // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope
+ * def convToPimpedA(x: Bar[Foo[T]]) // pimpA5: no constraints
+ * def convToPimpedA(x: S) // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar
+ * def convToTraversableOps(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double
+ * // should not be abstract!
+ * }}}
+ */
+class A[T] {
+ /** This should prevent the implicitly inherited `def convToPimpedA: T` from `pimpA0` from showing up */
+ def convToPimpedA(x: T): T = sys.error("Let's check it out!")
+ /** This should check implicit member elimination in the case of subtyping */
+ def foo(a: T, b: AnyRef): T
+}
+/** Companion object with implicit transformations */
+object A {
+ import language.implicitConversions // according to SIP18
+
+ implicit def pimpA0[V](a: A[V]) = new PimpedA(a)
+ implicit def pimpA1[ZBUR: Numeric](a: A[ZBUR]) = new NumericA[ZBUR](a)
+ implicit def pimpA2(a: A[Int]) = new IntA(a)
+ implicit def pimpA3(a: A[T] forSome { type T <: Double }) = new GtColonDoubleA(a)
+ implicit def pimpA4[S](a: A[Foo[Bar[S]]])(implicit foo: Foo[S], bar: Bar[S]): PimpedA[S] = sys.error("not implemented")
+ implicit def pimpA5[Z](a: A[Z]): PimpedA[Bar[Foo[Z]]] = sys.error("not implemented")
+ implicit def pimpA6[Z: MyNumeric](a: A[Z]) = new MyNumericA[Z](a)
+ // TODO: Add H <: Double and see why it crashes for C and D -- context bounds, need to check!
+ implicit def pimpA7[H <: Double : Manifest](a: A[H]) = new ManifestA[H](a) with MyTraversableOps[H] { def convToTraversableOps(x: H): H = sys.error("no") }
+}
+
+
+/** Class B
+ * - tests the existential type solving
+ * - the following inherited methods should appear:
+ * {{{
+ * def convToGtColonDoubleA(x: Double) // pimpA3: no constraints
+ * def convToManifestA(x: Double) // pimpA7: no constraints
+ * def convToMyNumericA(x: Double) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope
+ * def convToNumericA(x: Double) // pimpA1: no constraintsd
+ * def convToPimpedA(x: Bar[Foo[Double]]) // pimpA5: no constraints
+ * def convToTraversableOps(x: Double) // pimpA7: no constraints
+ * // should not be abstract!
+ * }}}
+ */
+class B extends A[Double]
+object B extends A
+
+
+/** Class C
+ * - tests asSeenFrom
+ * - the following inherited methods should appear:
+ * {{{
+ * def convToIntA(x: Int) // pimpA2: no constraints
+ * def convToMyNumericA(x: Int) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope
+ * def convToNumericA(x: Int) // pimpA1: no constraints
+ * def convToPimpedA(x: Bar[Foo[Int]]) // pimpA5: no constraints
+ * }}}
+ */
+class C extends A[Int]
+object C extends A
+
+
+/** Class D
+ * - tests implicit elimination
+ * - the following inherited methods should appear:
+ * {{{
+ * def convToMyNumericA(x: String) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope
+ * def convToNumericA(x: String) // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope
+ * def convToPimpedA(x: Bar[Foo[String]]) // pimpA5: no constraints
+ * }}}
+ */
+class D extends A[String]
+/** Companion object with implicit transformations */
+object D extends A
+
+
+/** PimpedA class <br/>
+ * - tests simple inheritance and asSeenFrom
+ * - A, B and C should be implicitly converted to this */
+class PimpedA[V](a: A[V]) {
+ /** The convToPimpedA: V documentation... */
+ def convToPimpedA(x: V): V = sys.error("Not implemented")
+}
+
+/** NumericA class <br/>
+ * - tests the implicit conversion between parametric and fixed types
+ * - A, B and C should be implicitly converted to this */
+class NumericA[U: Numeric](a: A[U]) {
+ /** The convToNumericA: U documentation... */
+ def convToNumericA(x: U): U = implicitly[Numeric[U]].zero
+}
+
+/** IntA class <br/>
+ * - tests the interaction between implicit conversion and specific types
+ * - A and C should be implicitly converted to this */
+class IntA(a: A[Int]) {
+ /** The convToIntA: Int documentation... */
+ def convToIntA(x: Int): Int = 0
+}
+
+/** GtColonDoubleA class <br/>
+ * - tests the interaction between implicit conversion and existential types
+ * - A and B should be implicitly converted to this */
+class GtColonDoubleA(a: A[T] forSome { type T <: Double }) {
+ /** The convToGtColonDoubleA: Double documentation... */
+ def convToGtColonDoubleA(x: Double): Double = 0
+}
+
+/** MyNumericA class <br/>
+ * - tests the implicit conversion between parametric and fixed types
+ * - A should be implicitly converted to this */
+class MyNumericA[U: MyNumeric](a: A[U]) {
+ /** The convToMyNumericA: U documentation... */
+ def convToMyNumericA(x: U): U = sys.error("dunno")
+}
+
+/** ManifestA class <br/>
+ * - tests the manifest recognition
+ * - A, B, C, D should be implicitly converted to this */
+class ManifestA[W: Manifest](a: A[W]) {
+ /** The convToManifestA: W documentation... */
+ def convToManifestA(x: W): W = sys.error("dunno")
+}
+
+// [Eugene to Vlad] how do I test typetags here?
+
+/** MyTraversableOps class <br/>
+ * - checks if any abstract members are added - should not happen!
+ */
+trait MyTraversableOps[S] {
+ /** The convToTraversableOps: S documentation... */
+ def convToTraversableOps(x: S): S
+}
diff --git a/test/scaladoc/resources/implicits-chaining-res.scala b/test/scaladoc/resources/implicits-chaining-res.scala
new file mode 100644
index 0000000000..c005d5fe09
--- /dev/null
+++ b/test/scaladoc/resources/implicits-chaining-res.scala
@@ -0,0 +1,50 @@
+/**
+ * Testing scaladoc implicits chaining
+ */
+package scala.test.scaladoc.implicits {
+
+ import language.implicitConversions // according to SIP18
+
+ // the classes involved
+ case class Z[U](a: U)
+ case class Intermediate[T, U](t: T, u: U)
+ class Implicit1[T](b: Implicit2[T])
+ class Implicit2[T](c: Implicit3[T])
+ class Implicit3[T](/* and so on */)
+
+ object chaining {
+
+ // the base conversion
+ implicit def convertToZ[T](a: A[T])(implicit b: Implicit1[T]): Z[A[T]] = Z(a)
+
+ // and the implicit chaining, don't you just love it? :D
+ // implicit1, with one alternative
+ implicit def implicit1[T <: Intermediate[_, _]](implicit b: Implicit2[T]) = new Implicit1[T](b)
+ // implicit2, with two alternatives
+ implicit def implicit2alt1[T <: Intermediate[_ <: String, _]](implicit c: Implicit3[T]) = new Implicit2[T](c)
+ implicit def implicit2alt2[T <: Intermediate[_ <: Double, _]](implicit c: Implicit3[T]) = new Implicit2[T](c)
+ // implicit3, with two alternatives
+ implicit def implicit3alt1[T <: Intermediate[_, _ <: Int]] = new Implicit3[T]()
+ implicit def implicit3alt2[T <: Intermediate[_ <: Double, _ <: AnyRef],X] = new Implicit3[T]()
+
+ // and our targets
+ /** conversion here, with constraints */
+ class A[T]()
+ /** conversion here, no constraints */
+ class B extends A[Intermediate[String, Int]]
+ /** no conversion */
+ class C extends A[Intermediate[String, String]]
+ /** conversion here, no constraints */
+ class D extends A[Intermediate[Double, Int]]
+ /** conversion here, no constraints */
+ class E extends A[Intermediate[Double, String]]
+ /** no conversion */
+ class F extends A[Intermediate[String, Double]]
+
+ object scalacTest {
+ (new B).a
+ (new D).a
+ (new E).a
+ }
+ }
+}
diff --git a/test/scaladoc/resources/implicits-elimination-res.scala b/test/scaladoc/resources/implicits-elimination-res.scala
new file mode 100644
index 0000000000..b23667440c
--- /dev/null
+++ b/test/scaladoc/resources/implicits-elimination-res.scala
@@ -0,0 +1,14 @@
+/**
+ * Testing scaladoc implicits elimination
+ */
+package scala.test.scaladoc.implicits.elimination {
+
+ import language.implicitConversions // according to SIP18
+
+ /** No conversion, as B doesn't bring any member */
+ class A
+ class B { class C; trait V; type T; }
+ object A {
+ implicit def toB(a: A): B = null
+ }
+}
diff --git a/test/scaladoc/resources/implicits-scopes-res.scala b/test/scaladoc/resources/implicits-scopes-res.scala
new file mode 100644
index 0000000000..aaeb43f95b
--- /dev/null
+++ b/test/scaladoc/resources/implicits-scopes-res.scala
@@ -0,0 +1,52 @@
+/**
+ * Testing scaladoc implicit scopes - looking for implicits in the right places
+ */
+package scala.test.scaladoc.implicits.scopes
+import language.implicitConversions // according to SIP18
+
+// TEST1 - In package object
+package object test1 {
+ implicit def toB(a: A): B = null
+}
+package test1 {
+ class A
+ class B { def b = "" }
+}
+
+// TEST2 - In enclosing package - doesn't seem to work even in scalac
+package object test2 {
+ import classes._
+ implicit def toB(a: A): B = null
+}
+package test2 {
+ package classes {
+ class A
+ class B { def b = "" }
+ object test { /* (new A).b won't compile */ }
+ }
+}
+
+// TEST3 - In companion object
+package test3 {
+ class A
+ object A { implicit def toB(a: A): B = null }
+ class B { def b = "" }
+}
+
+// TEST4 - Nested type's companion object
+package test4 {
+ class U[V]
+ class S
+ object S { implicit def toB(a: A): B = null }
+ class A extends U[S]
+ class B { def b = "" }
+}
+
+// TEST5 - In scope
+package test5 {
+ object scope {
+ class A
+ class B { def b = "" }
+ implicit def toB(a: A): B = null
+ }
+}
diff --git a/test/scaladoc/resources/implicits-shadowing-res.scala b/test/scaladoc/resources/implicits-shadowing-res.scala
new file mode 100644
index 0000000000..c5e9493bf3
--- /dev/null
+++ b/test/scaladoc/resources/implicits-shadowing-res.scala
@@ -0,0 +1,64 @@
+/**
+ * Test scaladoc implicits distinguishing -- supress all members by implicit conversion that are shadowed by the
+ * class' own members
+ *
+ * {{{
+ * scala> class A { def foo(t: String) = 4 }
+ * defined class A
+ *
+ * scala> class B { def foo(t: Any) = 5 }
+ * defined class B
+ *
+ * scala> implicit def AtoB(a:A) = new B
+ * AtoB: (a: A)B
+ *
+ * scala> val a = new A
+ * a: A = A@28f553e3
+ *
+ * scala> a.foo("T")
+ * res1: Int = 4
+ *
+ * scala> a.foo(4)
+ * res2: Int = 5
+ * }}}
+ */
+package scala.test.scaladoc.implicits.shadowing
+import language.implicitConversions // according to SIP18
+
+/** conv5, conv8, conv9, conv10, conv11 should be visible */
+class A[T] {
+ def conv1: AnyRef = ???
+ def conv2: T = ???
+ def conv3(l: Int): AnyRef = ???
+ def conv4(l: AnyRef): AnyRef = ???
+ def conv5(l: String): AnyRef = ???
+ def conv6(l: AnyRef): AnyRef = ???
+ def conv7(l: AnyRef): String = ???
+ def conv8(l: String)(m: String): AnyRef = ???
+ def conv9(l: AnyRef)(m: AnyRef): AnyRef = ???
+ def conv10(l: T): T = ???
+ def conv11(l: T): T = ???
+}
+/** conv5, conv8, conv9, conv11 should be visible */
+class B extends A[Int]
+/** conv5, conv8, conv9, conv10, conv11 should be visible */
+class C extends A[Double]
+/** conv5, conv8, conv9, conv10 should be visible */
+class D extends A[AnyRef]
+
+class Z[T] {
+ def conv1: AnyRef = ???
+ def conv2: T = ???
+ def conv3(p: Int): AnyRef = ???
+ def conv4(p: String): AnyRef = ???
+ def conv5(p: AnyRef): AnyRef = ???
+ def conv6(p: AnyRef): String = ???
+ def conv7(p: AnyRef): AnyRef = ???
+ def conv8(p: String, q: String): AnyRef = ???
+ def conv9(p: AnyRef, q: AnyRef): AnyRef = ???
+ def conv10(p: Int): T = ???
+ def conv11(p: String): T = ???
+}
+object A {
+ implicit def AtoZ[T](a: A[T]) = new Z[T]
+}
diff --git a/test/scaladoc/run/SI-5373.check b/test/scaladoc/run/SI-5373.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/SI-5373.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/SI-5373.scala b/test/scaladoc/run/SI-5373.scala
new file mode 100644
index 0000000000..0062abbb2a
--- /dev/null
+++ b/test/scaladoc/run/SI-5373.scala
@@ -0,0 +1,34 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ override def code = """
+ import scala.annotation.bridge
+
+ package scala.test {
+
+ trait A {
+ def foo = ()
+ }
+
+ trait B {
+ @bridge()
+ def foo = ()
+ }
+
+ class C extends A with B
+ }
+ """
+
+ // no need for special settings
+ def scaladocSettings = ""
+
+ def testModel(rootPackage: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // just need to check the member exists, access methods will throw an error if there's a problem
+ rootPackage._package("scala")._package("test")._class("C")._method("foo")
+ }
+} \ No newline at end of file
diff --git a/test/scaladoc/run/implicits-base.check b/test/scaladoc/run/implicits-base.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/implicits-base.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/implicits-base.scala b/test/scaladoc/run/implicits-base.scala
new file mode 100644
index 0000000000..06d017ed70
--- /dev/null
+++ b/test/scaladoc/run/implicits-base.scala
@@ -0,0 +1,180 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+import language._
+
+object Test extends ScaladocModelTest {
+
+ // test a file instead of a piece of code
+ override def resourceFile = "implicits-base-res.scala"
+
+ // start implicits
+ def scaladocSettings = "-implicits -implicits-show-all"
+
+ def testModel(root: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // SEE THE test/resources/implicits-base-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE:
+ val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("base")
+ var conv: ImplicitConversion = null
+
+//// class A ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val A = base._class("A")
+
+ // the method pimped on by pimpA0 should be shadowed by the method in class A
+ assert(A._conversions(A.qualifiedName + ".pimpA0").isEmpty)
+
+ // def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope
+ conv = A._conversion(A.qualifiedName + ".pimpA1")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+ assert(conv._member("convToNumericA").resultType.name == "T")
+
+ // def convToIntA: Int // pimpA2: with a constraint that T = Int
+ conv = A._conversion(A.qualifiedName + ".pimpA2")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+ assert(conv._member("convToIntA").resultType.name == "Int")
+
+ // def convToGtColonDoubleA: Double // pimpA3: with a constraint that T <: Double
+ conv = A._conversion(A.qualifiedName + ".pimpA3")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+ assert(conv._member("convToGtColonDoubleA").resultType.name == "Double")
+
+ // def convToPimpedA: S // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar
+ conv = A._conversion(A.qualifiedName + ".pimpA4")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 3)
+ assert(conv._member("convToPimpedA").resultType.name == "S")
+
+ // def convToPimpedA: Bar[Foo[T]] // pimpA5: no constraints
+ conv = A._conversion(A.qualifiedName + ".pimpA5")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]")
+
+ // def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope
+ conv = A._conversion(A.qualifiedName + ".pimpA6")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+ assert(conv._member("convToMyNumericA").resultType.name == "T")
+
+ // def convToManifestA: T // pimpA7: with 2 constraints: T: Manifest and T <: Double
+ // def convToTraversableOps: T // pimpA7: with 2 constraints: T: Manifest and T <: Double
+ // should not be abstract!
+ conv = A._conversion(A.qualifiedName + ".pimpA7")
+ assert(conv.members.length == 2)
+ assert(conv.constraints.length == 2)
+ assert(conv._member("convToManifestA").resultType.name == "T")
+ assert(conv._member("convToTraversableOps").resultType.name == "T")
+ assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1)
+
+//// class B ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val B = base._class("B")
+
+ // these conversions should not affect B
+ assert(B._conversions(A.qualifiedName + ".pimpA0").isEmpty)
+ assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty)
+ assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty)
+
+ // def convToNumericA: Double // pimpA1: no constraintsd
+ conv = B._conversion(A.qualifiedName + ".pimpA1")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToNumericA").resultType.name == "Double")
+
+ // def convToGtColonDoubleA: Double // pimpA3: no constraints
+ conv = B._conversion(A.qualifiedName + ".pimpA3")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToGtColonDoubleA").resultType.name == "Double")
+
+ // def convToPimpedA: Bar[Foo[Double]] // pimpA5: no constraints
+ conv = B._conversion(A.qualifiedName + ".pimpA5")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]")
+
+ // def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope
+ conv = B._conversion(A.qualifiedName + ".pimpA6")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+ assert(conv._member("convToMyNumericA").resultType.name == "Double")
+
+ // def convToManifestA: Double // pimpA7: no constraints
+ // def convToTraversableOps: Double // pimpA7: no constraints
+ // // should not be abstract!
+ conv = B._conversion(A.qualifiedName + ".pimpA7")
+ assert(conv.members.length == 2)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToManifestA").resultType.name == "Double")
+ assert(conv._member("convToTraversableOps").resultType.name == "Double")
+ assert(conv._member("convToTraversableOps").flags.toString.indexOf("abstract") == -1)
+
+//// class C ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val C = base._class("C")
+
+ // these conversions should not affect C
+ assert(C._conversions(A.qualifiedName + ".pimpA0").isEmpty)
+ assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty)
+ assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty)
+ assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty)
+
+ // def convToNumericA: Int // pimpA1: no constraints
+ conv = C._conversion(A.qualifiedName + ".pimpA1")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToNumericA").resultType.name == "Int")
+
+ // def convToIntA: Int // pimpA2: no constraints
+ conv = C._conversion(A.qualifiedName + ".pimpA2")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToIntA").resultType.name == "Int")
+
+ // def convToPimpedA: Bar[Foo[Int]] // pimpA5: no constraints
+ conv = C._conversion(A.qualifiedName + ".pimpA5")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]")
+
+ // def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope
+ conv = C._conversion(A.qualifiedName + ".pimpA6")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+ assert(conv._member("convToMyNumericA").resultType.name == "Int")
+
+//// class D ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val D = base._class("D")
+
+ // these conversions should not affect D
+ assert(D._conversions(A.qualifiedName + ".pimpA0").isEmpty)
+ assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty)
+ assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty)
+ assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty)
+ assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty)
+
+ // def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope
+ conv = D._conversion(A.qualifiedName + ".pimpA1")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+ assert(conv._member("convToNumericA").resultType.name == "String")
+
+ // def convToPimpedA: Bar[Foo[String]] // pimpA5: no constraints
+ conv = D._conversion(A.qualifiedName + ".pimpA5")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]")
+
+ // def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope
+ conv = D._conversion(A.qualifiedName + ".pimpA6")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+ assert(conv._member("convToMyNumericA").resultType.name == "String")
+ }
+}
diff --git a/test/scaladoc/run/implicits-chaining.check b/test/scaladoc/run/implicits-chaining.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/implicits-chaining.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/implicits-chaining.scala b/test/scaladoc/run/implicits-chaining.scala
new file mode 100644
index 0000000000..858ca9ce61
--- /dev/null
+++ b/test/scaladoc/run/implicits-chaining.scala
@@ -0,0 +1,65 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+import language._
+
+object Test extends ScaladocModelTest {
+
+ // test a file instead of a piece of code
+ override def resourceFile = "implicits-chaining-res.scala"
+
+ // start implicits
+ def scaladocSettings = "-implicits"
+
+ def testModel(root: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE:
+ val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("chaining")
+ var conv: ImplicitConversion = null
+
+//// class A ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val A = base._class("A")
+
+ conv = A._conversion(base.qualifiedName + ".convertToZ")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 1)
+
+//// class B ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val B = base._class("B")
+
+ conv = B._conversion(base.qualifiedName + ".convertToZ")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+
+//// class C ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val C = base._class("C")
+
+ assert(C._conversions(base.qualifiedName + ".convertToZ").isEmpty)
+
+//// class D ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val D = base._class("D")
+
+ conv = D._conversion(base.qualifiedName + ".convertToZ")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+
+//// class E ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val E = base._class("E")
+
+ conv = E._conversion(base.qualifiedName + ".convertToZ")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+
+//// class F ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val F = base._class("F")
+
+ assert(F._conversions(base.qualifiedName + ".convertToZ").isEmpty)
+ }
+}
diff --git a/test/scaladoc/run/implicits-elimination.check b/test/scaladoc/run/implicits-elimination.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/implicits-elimination.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/implicits-elimination.scala b/test/scaladoc/run/implicits-elimination.scala
new file mode 100644
index 0000000000..ed37b9cd90
--- /dev/null
+++ b/test/scaladoc/run/implicits-elimination.scala
@@ -0,0 +1,23 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+import language._
+
+object Test extends ScaladocModelTest {
+
+ // test a file instead of a piece of code
+ override def resourceFile = "implicits-elimination-res.scala"
+
+ // start implicits
+ def scaladocSettings = "-implicits"
+
+ def testModel(root: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // SEE THE test/resources/implicits-elimination-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE:
+ val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("elimination")
+ val A = base._class("A")
+
+ assert(A._conversions(A.qualifiedName + ".toB").isEmpty)
+ }
+}
diff --git a/test/scaladoc/run/implicits-scopes.check b/test/scaladoc/run/implicits-scopes.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/implicits-scopes.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/implicits-scopes.scala b/test/scaladoc/run/implicits-scopes.scala
new file mode 100644
index 0000000000..7b9e80e148
--- /dev/null
+++ b/test/scaladoc/run/implicits-scopes.scala
@@ -0,0 +1,77 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+import language._
+
+object Test extends ScaladocModelTest {
+
+ // test a file instead of a piece of code
+ override def resourceFile = "implicits-scopes-res.scala"
+
+ // start implicits
+ def scaladocSettings = "-implicits"
+
+ def testModel(root: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+ var conv: ImplicitConversion = null
+
+ // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE:
+ val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("scopes")
+
+//// test1 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val doTest1 = {
+ val test1 = base._package("test1")
+ val A = test1._class("A")
+
+ conv = A._conversion(test1.qualifiedName + ".package.toB") // the .package means it's the package object
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ }
+
+//// test2 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val doTest2 = {
+ val test2 = base._package("test2")
+ val classes = test2._package("classes")
+ val A = classes._class("A")
+
+ assert(A._conversions(test2.qualifiedName + ".toB").isEmpty)
+ }
+
+//// test3 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val doTest3 = {
+ val test3 = base._package("test3")
+ val A = test3._class("A")
+
+ conv = A._conversion(A.qualifiedName + ".toB")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ }
+
+//// test4 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val doTest4 = {
+ val test4 = base._package("test4")
+ val A = test4._class("A")
+ val S = test4._object("S")
+
+ conv = A._conversion(S.qualifiedName + ".toB")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ }
+
+//// test5 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val doTest5 = {
+ val test5 = base._package("test5")
+ val scope = test5._object("scope")
+ val A = scope._class("A")
+
+ conv = A._conversion(scope.qualifiedName + ".toB")
+ assert(conv.members.length == 1)
+ assert(conv.constraints.length == 0)
+ }
+ }
+}
diff --git a/test/scaladoc/run/implicits-shadowing.check b/test/scaladoc/run/implicits-shadowing.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/implicits-shadowing.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/implicits-shadowing.scala b/test/scaladoc/run/implicits-shadowing.scala
new file mode 100644
index 0000000000..7835223d21
--- /dev/null
+++ b/test/scaladoc/run/implicits-shadowing.scala
@@ -0,0 +1,70 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ // test a file instead of a piece of code
+ override def resourceFile = "implicits-shadowing-res.scala"
+
+ // start implicits
+ def scaladocSettings = "-implicits"
+
+ def testModel(root: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE:
+ val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("shadowing")
+ var conv: ImplicitConversion = null
+
+//// class A ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val A = base._class("A")
+
+ conv = A._conversion(base._object("A").qualifiedName + ".AtoZ")
+ assert(conv.members.length == 5)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
+ conv._member("conv11")
+ assert(conv.constraints.length == 0)
+
+//// class B ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val B = base._class("B")
+
+ conv = B._conversion(base._object("A").qualifiedName + ".AtoZ")
+ assert(conv.members.length == 4)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv11")
+ assert(conv.constraints.length == 0)
+
+//// class C ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val C = base._class("C")
+
+ conv = C._conversion(base._object("A").qualifiedName + ".AtoZ")
+ assert(conv.members.length == 5)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
+ conv._member("conv11")
+ assert(conv.constraints.length == 0)
+
+//// class D ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ val D = base._class("D")
+
+ conv = D._conversion(base._object("A").qualifiedName + ".AtoZ")
+ assert(conv.members.length == 4)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
+ assert(conv.constraints.length == 0)
+ }
+} \ No newline at end of file
diff --git a/test/scaladoc/scala/html.flags b/test/scaladoc/scala/html.flags
deleted file mode 100644
index b2264ec4f4..0000000000
--- a/test/scaladoc/scala/html.flags
+++ /dev/null
@@ -1 +0,0 @@
--encoding UTF-8 \ No newline at end of file
diff --git a/test/scaladoc/scala/model/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala
index 69c314a64c..68ca68efdd 100644
--- a/test/scaladoc/scala/model/CommentFactoryTest.scala
+++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala
@@ -3,11 +3,12 @@ import org.scalacheck.Prop._
import scala.tools.nsc.Global
import scala.tools.nsc.doc
+import scala.tools.nsc.doc.model._
import scala.tools.nsc.doc.model.comment._
class Factory(val g: Global, val s: doc.Settings)
extends doc.model.ModelFactory(g, s) {
- thisFactory: Factory with CommentFactory with doc.model.TreeFactory =>
+ thisFactory: Factory with ModelFactoryImplicitSupport with CommentFactory with doc.model.TreeFactory =>
def strip(c: Comment): Option[Inline] = {
c.body match {
@@ -28,7 +29,7 @@ object Test extends Properties("CommentFactory") {
val settings = new doc.Settings((str: String) => {})
val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
val g = new Global(settings, reporter)
- (new Factory(g, settings) with CommentFactory with doc.model.TreeFactory)
+ (new Factory(g, settings) with ModelFactoryImplicitSupport with CommentFactory with doc.model.TreeFactory)
}
def parse(src: String, dst: Inline) = {
diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.flags b/test/scaladoc/scalacheck/HtmlFactoryTest.flags
index b2264ec4f4..b2264ec4f4 100644
--- a/test/scaladoc/scala/html/HtmlFactoryTest.flags
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.flags
diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
index 7550faa536..5b6f75426e 100644
--- a/test/scaladoc/scala/html/HtmlFactoryTest.scala
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
@@ -50,7 +50,7 @@ object Test extends Properties("HtmlFactory") {
def createTemplates(basename: String) = {
val result = scala.collection.mutable.Map[String, scala.xml.NodeSeq]()
- createFactory.makeUniverse(List(RESOURCES+basename)) match {
+ createFactory.makeUniverse(Left(List(RESOURCES+basename))) match {
case Some(universe) => {
val index = IndexModelFactory.makeIndex(universe)
(new HtmlFactory(universe, index)).writeTemplates((page) => {
@@ -64,7 +64,7 @@ object Test extends Properties("HtmlFactory") {
}
def createReferenceIndex(basename: String) = {
- createFactory.makeUniverse(List(RESOURCES+basename)) match {
+ createFactory.makeUniverse(Left(List(RESOURCES+basename))) match {
case Some(universe) => {
val index = IndexModelFactory.makeIndex(universe)
val pages = index.firstLetterIndex.map({
@@ -442,8 +442,9 @@ object Test extends Properties("HtmlFactory") {
property("Use cases should override their original members") =
checkText("SI_5054_q1.scala")(
- (None,"""def test(): Int""", true),
- (None,"""def test(implicit lost: Int): Int""", false)
+ (None,"""def test(): Int""", true)
+ //Disabled because the full signature is now displayed
+ //(None,"""def test(implicit lost: Int): Int""", false)
)
property("Use cases should keep their flags - final should not be lost") =
@@ -599,8 +600,9 @@ object Test extends Properties("HtmlFactory") {
T StartT the type of the first argument EndT
arg1 Start1 The T term comment End1
arg2 Start2 The string comment End2
- returns StartRet The return comment EndRet
- Definition Classes InheritDocDerived → InheritDocBase
+ returns StartRet The return comment EndRet""", true),
+ (Some("InheritDocDerived"),
+ """Definition Classes InheritDocDerived → InheritDocBase
Example: StartExample function[Int](3, "something") EndExample
Version StartVer 0.0.2 EndVer
Since StartSince 0.0.1 EndSince
@@ -624,8 +626,9 @@ object Test extends Properties("HtmlFactory") {
T StartT the type of the first argument EndT
arg1 Start1 The T term comment End1
arg2 Start2 The string comment End2
- returns StartRet The return comment EndRet
- Example: StartExample function[Int](3,"something") EndExample
+ returns StartRet The return comment EndRet""", true),
+ (Some("UseCaseInheritDoc"),
+ """Example: StartExample function[Int](3,"something") EndExample
Version StartVer 0.0.2 EndVer
Since StartSince 0.0.1 EndSince
Exceptions thrown
diff --git a/test/scaladoc/scala/IndexScriptTest.scala b/test/scaladoc/scalacheck/IndexScriptTest.scala
index e0372020fd..5aef38e00a 100644
--- a/test/scaladoc/scala/IndexScriptTest.scala
+++ b/test/scaladoc/scalacheck/IndexScriptTest.scala
@@ -24,7 +24,7 @@ object Test extends Properties("IndexScript") {
val indexModelFactory = doc.model.IndexModelFactory
def createIndexScript(path: String) =
- docFactory.makeUniverse(List(path)) match {
+ docFactory.makeUniverse(Left(List(path))) match {
case Some(universe) => {
val index = new IndexScript(universe,
indexModelFactory.makeIndex(universe))
diff --git a/test/scaladoc/scala/IndexTest.scala b/test/scaladoc/scalacheck/IndexTest.scala
index c14fd98297..29e337da2b 100644
--- a/test/scaladoc/scala/IndexTest.scala
+++ b/test/scaladoc/scalacheck/IndexTest.scala
@@ -37,7 +37,7 @@ object Test extends Properties("Index") {
//val original = Console.out
//Console.setOut(stream)
- val result = docFactory.makeUniverse(List(path))
+ val result = docFactory.makeUniverse(Left(List(path)))
// assert(stream.toString == "model contains 2 documentable templates\n")
//Console.setOut(original)
diff --git a/tools/binary-repo-lib.sh b/tools/binary-repo-lib.sh
index 4c5497e803..a22747520c 100755
--- a/tools/binary-repo-lib.sh
+++ b/tools/binary-repo-lib.sh
@@ -88,12 +88,28 @@ pushJarFile() {
# rm $jar
}
+getJarSha() {
+ local jar=$1
+ if [[ ! -f "$jar" ]]; then
+ echo ""
+ elif which sha1sum 2>/dev/null >/dev/null; then
+ shastring=$(sha1sum "$jar")
+ echo "$shastring" | sed 's/ .*//'
+ elif which shasum 2>/dev/null >/dev/null; then
+ shastring=$(shasum "$jar")
+ echo "$shastring" | sed 's/ .*//'
+ else
+ shastring=$(openssl sha1 "$jar")
+ echo "$shastring" | sed 's/^.*= //'
+ fi
+}
+
# Tests whether or not the .desired.sha1 hash matches a given file.
# Arugment 1 - The jar file to test validity.
# Returns: Empty string on failure, "OK" on success.
isJarFileValid() {
local jar=$1
- if [[ ! -f $jar ]]; then
+ if [[ ! -f "$jar" ]]; then
echo ""
else
local jar_dir=$(dirname $jar)
@@ -131,6 +147,27 @@ pushJarFiles() {
fi
}
+
+checkJarSha() {
+ local jar=$1
+ local sha=$2
+ local testsha=$(getJarSha "$jar")
+ if test "$sha" == "$testsha"; then
+ echo "OK"
+ fi
+}
+
+makeCacheLocation() {
+ local uri=$1
+ local sha=$2
+ local cache_loc="$cache_dir/$uri"
+ local cdir=$(dirname $cache_loc)
+ if [[ ! -d "$cdir" ]]; then
+ mkdir -p "$cdir"
+ fi
+ echo "$cache_loc"
+}
+
# Pulls a single binary artifact from a remote repository.
# Argument 1 - The uri to the file that should be downloaded.
# Argument 2 - SHA of the file...
@@ -138,16 +175,19 @@ pushJarFiles() {
pullJarFileToCache() {
local uri=$1
local sha=$2
- local cache_loc=$cache_dir/$uri
- local cdir=$(dirname $cache_loc)
- if [[ ! -d $cdir ]]; then
- mkdir -p $cdir
- fi
+ local cache_loc="$(makeCacheLocation $uri)"
# TODO - Check SHA of local cache is accurate.
- if [[ ! -f $cache_loc ]]; then
+ if test -f "$cache_loc" && test "$(checkJarSha "$cache_loc" "$sha")" != "OK"; then
+ echo "Found bad cached file: $cache_loc"
+ rm -f "$cache_loc"
+ fi
+ if [[ ! -f "$cache_loc" ]]; then
curlDownload $cache_loc ${remote_urlbase}/${uri}
+ if test "$(checkJarSha "$cache_loc" "$sha")" != "OK"; then
+ echo "Trouble downloading $uri. Please try pull-binary-libs again when your internet connection is stable."
+ exit 2
+ fi
fi
- echo "$cache_loc"
}
# Pulls a single binary artifact from a remote repository.
@@ -162,7 +202,8 @@ pullJarFile() {
local version=${sha1% ?$jar_name}
local remote_uri=${version}/${jar#$basedir/}
echo "Resolving [${remote_uri}]"
- local cached_file=$(pullJarFileToCache $remote_uri $version)
+ pullJarFileToCache $remote_uri $version
+ local cached_file=$(makeCacheLocation $remote_uri)
cp $cached_file $jar
}
diff --git a/tools/cleanup-commit b/tools/cleanup-commit
new file mode 100755
index 0000000000..400d434359
--- /dev/null
+++ b/tools/cleanup-commit
@@ -0,0 +1,130 @@
+#!/bin/bash
+
+##
+## The cleanup-commit script
+## -------------------------
+## This little script will cleanup your commit before you send it. You need to add the files to the staged area and
+## run this script. It will automatically cleanup tabs and trailing spaces for the files you added and then add the
+## clean versions to the staging area.
+##
+## Use at your own risk, I spent some time making the script error-proof so it will abort if sees any inconsistency,
+## but of course playing around with your commit might break things. Btw, it saves the original file to file.bak.
+##
+## Happy hacking!
+##
+
+ABORT="Ab0rT0p3r4+|0n"
+
+#
+# Cleanup function
+#
+function cleanup {
+ echo Cleaning up $1...
+ # prepare the ground
+ rm -rf $1.bak
+ # compress <TAB> into double <BLANK> and eliminate trailing <BLANC>s
+ sed -i.bak -e 's/\t/ /g' -e 's/ *$//' $1
+}
+
+
+#
+# Get the git status for the current staged commit
+#
+FULLSTATUS=`git status --porcelain`
+
+if [ $? -ne 0 ]
+then
+ echo "Unable to run git. Check if:"
+ echo " -- git is installed (you can run git in the command line)"
+ echo " -- the current directory is a valid git repository"
+ exit 1
+fi
+
+echo
+
+#
+# Based on the status decide what files will get cleaned up
+#
+CLEANUP_FILES=`echo "$FULLSTATUS" | while read LINE
+do
+
+ STATUS=$(echo $LINE | sed 's/^\(..\).*$/\1/')
+ if [ $? -ne 0 ]
+ then
+ echo "Could not get the status for line: $LINE"
+ echo " -- you have the basic unix tools installed (grep, cut, sed)"
+ echo $ABORT # This goes to CLEANUP_FILES
+ exit 1
+ fi
+
+ FILES=$(echo $LINE | sed 's/^..//')
+ FILE1=$(echo $FILES | cut -d ' ' -f 1)
+ FILE2=$(echo $FILES | cut -d ' ' -f 3)
+
+ case "$STATUS" in
+ [AMRDC]" ")
+ case "$STATUS" in
+ "A "|"M ")
+ echo $FILE1
+ ;;
+ "R ")
+ echo $FILE2
+ ;;
+ "D ")
+ #nothing to do
+ ;;
+ "C ")
+ echo $FILE1
+ echo $FILE2
+ ;;
+ esac
+ ;;
+ "??")
+ # File is not tracked, no need to do anything about it
+ # echo Untracked: $FILE1
+ ;;
+ *)
+ echo "Unstable status of file $FILE1 (\"$STATUS\")" >&2
+ echo "Aborting cleanup!" >&2
+ echo $ABORT # This goes to CLEANUP_FILES
+ exit 1
+ esac
+done; echo $CLEANUP_FILES`
+
+
+#
+# Perform actual cleanup
+#
+case $CLEANUP_FILES in
+*"$ABORT")
+ echo
+ exit 1
+ ;;
+"")
+ echo Nothing to do!
+ ;;
+*)
+ cd $(git rev-parse --show-toplevel)
+
+ if [ $? -ne 0 ]
+ then
+ echo Unexpected error: cannot cd to the repository root
+ echo Aborting cleanup!
+ exit 1
+ fi
+
+ echo "$CLEANUP_FILES" | while read FILE
+ do
+ cleanup $FILE
+ done
+
+ cd - &>/dev/null
+
+ echo
+ echo "Cleanup done: "
+ echo " - original files saved as .bak"
+ echo " - you can do \"git diff\" to see the changes the script did"
+ echo " - you can do \"git commit -a\" to commit the cleaned up files"
+ echo
+ ;;
+esac
diff --git a/tools/dump-class b/tools/dump-class
new file mode 100755
index 0000000000..0b4f2a73fa
--- /dev/null
+++ b/tools/dump-class
@@ -0,0 +1,6 @@
+#!/bin/sh
+#
+
+classpath=$($(dirname $BASH_SOURCE)/quickcp)
+
+java -cp "$classpath" scala.tools.nsc.MainGenericRunner -usejavacp scala.tools.cmd.program.DumpClass "$@" \ No newline at end of file
diff --git a/tools/get-scala-commit-date.bat b/tools/get-scala-commit-date.bat
index a07155533f..2a75073633 100644
--- a/tools/get-scala-commit-date.bat
+++ b/tools/get-scala-commit-date.bat
@@ -1,24 +1,9 @@
-@echo off
-rem
-rem Usage: get-scala-revison.bat [dir]
-rem Figures out current scala commit date of a git clone.
-rem
-rem If no dir is given, current working dir is used.
-
-@setlocal
-set _DIR=
-if "%*"=="" (
- for /f "delims=;" %%i in ('cd') do set "_DIR=%%i"
-) else (
- set "_DIR=%~1"
-)
-cd %_DIR%
-
-rem TODO - Check with a real windows user that this works!
-if exist .git\NUL (
- for /f "tokens=1delims= " in ('git log --format="%ci" -1') do set commitdate=%%a
- echo %commitdate%
-)
-
-:end
-@endlocal
+@echo off
+for %%X in (bash.exe) do (set FOUND=%%~$PATH:X)
+if defined FOUND (
+ bash "%~dp0\get-scala-commit-date"
+) else (
+ rem echo this script does not work with cmd.exe. please, install bash
+ echo unknown
+ exit 1
+) \ No newline at end of file
diff --git a/tools/get-scala-commit-sha.bat b/tools/get-scala-commit-sha.bat
index 7a5afa11b1..390e2d99d0 100644
--- a/tools/get-scala-commit-sha.bat
+++ b/tools/get-scala-commit-sha.bat
@@ -1,21 +1,9 @@
-@echo off
-rem
-rem Usage: get-scala-commit-drift.bat [dir]
-rem Figures out current scala commit drift, of a clone.
-rem
-rem If no dir is given, current working dir is used.
-
-@setlocal
-set _DIR=
-if "%*"=="" (
- for /f "delims=;" %%i in ('cd') do set "_DIR=%%i"
-) else (
- set "_DIR=%~1"
-)
-cd %_DIR%
-
-rem TODO - truncate chars.
-git log -1 --format="%H
-
-:end
-@endlocal
+@echo off
+for %%X in (bash.exe) do (set FOUND=%%~$PATH:X)
+if defined FOUND (
+ bash "%~dp0\get-scala-commit-sha"
+) else (
+ rem echo this script does not work with cmd.exe. please, install bash
+ echo unknown
+ exit 1
+) \ No newline at end of file