summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeather Miller <heather.miller@epfl.ch>2012-04-15 14:51:18 +0200
committerHeather Miller <heather.miller@epfl.ch>2012-04-15 14:51:18 +0200
commite4bea920b42eaa526a9e07ad001f17443d6abeba (patch)
treec786202cc9d0fa5b1a26dfd8e1154cacca7fbaf4
parent23aa1a8d7b08b767f90657baf9bc13a355682671 (diff)
parent364dd41c3e0e33afe6c3ec6e0c04f1d345c4b6ca (diff)
downloadscala-e4bea920b42eaa526a9e07ad001f17443d6abeba.tar.gz
scala-e4bea920b42eaa526a9e07ad001f17443d6abeba.tar.bz2
scala-e4bea920b42eaa526a9e07ad001f17443d6abeba.zip
Merge branch 'master' of https://github.com/scala/scala into wip-sip14-fixes
-rw-r--r--build.xml149
-rw-r--r--gitignore.SAMPLE5
-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--src/compiler/scala/reflect/internal/AnnotationInfos.scala17
-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.scala123
-rw-r--r--src/compiler/scala/reflect/internal/FreeVars.scala60
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala39
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala7
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala1
-rw-r--r--src/compiler/scala/reflect/internal/Positions.scala38
-rw-r--r--src/compiler/scala/reflect/internal/Reporters.scala74
-rw-r--r--src/compiler/scala/reflect/internal/Required.scala2
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala127
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala15
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala113
-rw-r--r--src/compiler/scala/reflect/internal/TreeBuildUtil.scala62
-rw-r--r--src/compiler/scala/reflect/internal/TreeGen.scala2
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala209
-rw-r--r--src/compiler/scala/reflect/internal/TreePrinters.scala17
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala87
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala215
-rw-r--r--src/compiler/scala/reflect/internal/settings/MutableSettings.scala2
-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.scala26
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Enclosures.scala36
-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.scala69
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Reporters.scala44
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Settings.scala36
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Symbols.scala8
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Typers.scala78
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Util.scala34
-rw-r--r--src/compiler/scala/reflect/reify/Errors.scala63
-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.scala154
-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.scala177
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Trees.scala236
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Types.scala163
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Util.scala112
-rw-r--r--src/compiler/scala/reflect/reify/package.scala22
-rw-r--r--src/compiler/scala/reflect/reify/phases/Calculate.scala59
-rw-r--r--src/compiler/scala/reflect/reify/phases/Metalevels.scala150
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reify.scala46
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reshape.scala296
-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.scala36
-rw-r--r--src/compiler/scala/reflect/runtime/RuntimeTypes.scala27
-rw-r--r--src/compiler/scala/reflect/runtime/Settings.scala2
-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/SynchronizedSymbols.scala7
-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.scala20
-rw-r--r--src/compiler/scala/reflect/runtime/package.scala5
-rw-r--r--src/compiler/scala/tools/ant/Scaladoc.scala70
-rw-r--r--src/compiler/scala/tools/cmd/FromString.scala4
-rw-r--r--src/compiler/scala/tools/cmd/gen/AnyVals.scala64
-rw-r--r--src/compiler/scala/tools/nsc/ClassLoaders.scala64
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala17
-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.scala79
-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.scala1
-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.scala85
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala12
-rw-r--r--src/compiler/scala/tools/nsc/ast/FreeVars.scala26
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala33
-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.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala72
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala127
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala100
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala53
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Tokens.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala2
-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.scala3
-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.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocFactory.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/Settings.scala128
-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/page/Template.scala157
-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.css101
-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.scala105
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala519
-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.scala4
-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/core/CoreTestDefs.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala18
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala5
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/NamedParam.scala3
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Phased.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplTokens.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplVals.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/RichClass.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala9
-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/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.scala6
-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.scala4
-rw-r--r--src/compiler/scala/tools/nsc/matching/Matrix.scala3
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala1
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternBindings.scala3
-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.scala4
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala152
-rw-r--r--src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Positions.scala30
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala15
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala18
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala23
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala161
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala48
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala52
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala247
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala76
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala1372
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala152
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala51
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala75
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala77
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala26
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala584
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala17
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala6
-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.scala134
-rw-r--r--src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala2
-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/package.scala2
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala2
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala168
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSPlugin.scala19
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala16
-rw-r--r--src/library/scala/Array.scala13
-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.scala17
-rw-r--r--src/library/scala/Enumeration.scala7
-rw-r--r--src/library/scala/Float.scala163
-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.scala14
-rw-r--r--src/library/scala/Predef.scala68
-rw-r--r--src/library/scala/Short.scala210
-rw-r--r--src/library/scala/Tuple2.scala12
-rw-r--r--src/library/scala/Tuple3.scala13
-rw-r--r--src/library/scala/Unit.scala4
-rw-r--r--src/library/scala/annotation/meta/companionClass.scala17
-rw-r--r--src/library/scala/annotation/meta/companionMethod.scala17
-rw-r--r--src/library/scala/annotation/meta/companionObject.scala (renamed from src/library/scala/reflect/NoManifest.scala)15
-rw-r--r--src/library/scala/annotation/meta/languageFeature.scala (renamed from src/library/scala/reflect/OptManifest.scala)14
-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/IterableLike.scala2
-rw-r--r--src/library/scala/collection/IterableViewLike.scala1
-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/TraversableLike.scala4
-rw-r--r--src/library/scala/collection/TraversableOnce.scala14
-rw-r--r--src/library/scala/collection/TraversableViewLike.scala3
-rw-r--r--src/library/scala/collection/convert/DecorateAsJava.scala2
-rw-r--r--src/library/scala/collection/convert/DecorateAsScala.scala1
-rw-r--r--src/library/scala/collection/convert/WrapAsJava.scala1
-rw-r--r--src/library/scala/collection/convert/WrapAsScala.scala1
-rw-r--r--src/library/scala/collection/generic/ClassManifestTraversableFactory.scala2
-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/GenericClassManifestCompanion.scala1
-rw-r--r--src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala1
-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/immutable/ListSet.scala4
-rw-r--r--src/library/scala/collection/immutable/Stream.scala3
-rw-r--r--src/library/scala/collection/immutable/StringLike.scala2
-rw-r--r--src/library/scala/collection/immutable/TrieIterator.scala2
-rw-r--r--src/library/scala/collection/mutable/ArrayBuilder.scala18
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala12
-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/StringBuilder.scala2
-rw-r--r--src/library/scala/collection/mutable/WrappedArray.scala2
-rw-r--r--src/library/scala/collection/mutable/WrappedArrayBuilder.scala14
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala1
-rw-r--r--src/library/scala/collection/parallel/ParIterableViewLike.scala1
-rw-r--r--src/library/scala/collection/parallel/package.scala1
-rw-r--r--src/library/scala/concurrent/ConcurrentPackageObject.scala2
-rw-r--r--src/library/scala/concurrent/Future.scala1
-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/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/util/Duration.scala175
-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.scala30
-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.scala3
-rw-r--r--src/library/scala/math/BigInt.scala1
-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.scala2
-rw-r--r--src/library/scala/math/Ordered.scala2
-rw-r--r--src/library/scala/math/Ordering.scala1
-rw-r--r--src/library/scala/reflect/ArrayTag.scala19
-rw-r--r--src/library/scala/reflect/ClassManifest.scala263
-rw-r--r--src/library/scala/reflect/ClassTag.scala168
-rw-r--r--src/library/scala/reflect/DynamicProxy.scala74
-rw-r--r--src/library/scala/reflect/Manifest.scala302
-rw-r--r--src/library/scala/reflect/ReflectionUtils.scala26
-rw-r--r--src/library/scala/reflect/TagMaterialization.scala155
-rw-r--r--src/library/scala/reflect/api/Attachment.scala24
-rw-r--r--src/library/scala/reflect/api/ClassLoaders.scala16
-rw-r--r--src/library/scala/reflect/api/Exprs.scala51
-rw-r--r--src/library/scala/reflect/api/FreeVars.scala42
-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.scala4
-rw-r--r--src/library/scala/reflect/api/Positions.scala215
-rw-r--r--src/library/scala/reflect/api/Reporters.scala65
-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.scala68
-rw-r--r--src/library/scala/reflect/api/StandardNames.scala152
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala66
-rw-r--r--src/library/scala/reflect/api/ToolBoxes.scala90
-rw-r--r--src/library/scala/reflect/api/TreeBuildUtil.scala111
-rw-r--r--src/library/scala/reflect/api/TreePrinters.scala6
-rw-r--r--src/library/scala/reflect/api/Trees.scala196
-rw-r--r--src/library/scala/reflect/api/TypeTags.scala194
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala95
-rwxr-xr-xsrc/library/scala/reflect/api/Universe.scala80
-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.scala61
-rw-r--r--src/library/scala/reflect/makro/Enclosures.scala53
-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.scala82
-rw-r--r--src/library/scala/reflect/makro/Reporters.scala39
-rw-r--r--src/library/scala/reflect/makro/Settings.scala38
-rw-r--r--src/library/scala/reflect/makro/Symbols.scala17
-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.scala135
-rw-r--r--src/library/scala/reflect/makro/internal/macroImpl.scala5
-rw-r--r--src/library/scala/reflect/package.scala43
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala6
-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.scala8
-rw-r--r--src/library/scala/util/Marshal.scala3
-rw-r--r--src/library/scala/util/Random.scala23
-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.scala2
-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.scala2
-rw-r--r--src/library/scala/xml/parsing/ConstructingParser.scala4
-rw-r--r--src/partest/scala/tools/partest/ScaladocModelTest.scala78
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleFileManager.scala1
-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--test/disabled/jvm/concurrent-future.check (renamed from test/files/jvm/concurrent-future.check)0
-rw-r--r--test/disabled/jvm/concurrent-future.scala (renamed from test/files/jvm/concurrent-future.scala)0
-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)0
-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/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--[-rwxr-xr-x]test/files/jvm/interpreter.check9
-rw-r--r--test/files/jvm/interpreter.scala9
-rw-r--r--test/files/jvm/manifests.check111
-rw-r--r--test/files/jvm/manifests.scala19
-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/exhausting.flags2
-rw-r--r--test/files/neg/gadts1.check5
-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.scala11
-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/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/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.check8
-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.check4
-rw-r--r--test/files/neg/t3683a.flags2
-rw-r--r--test/files/neg/t3692.check15
-rw-r--r--test/files/neg/t3692.flags1
-rw-r--r--test/files/neg/t418.check5
-rw-r--r--test/files/neg/t4425.check2
-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/t5510.check19
-rw-r--r--test/files/neg/t5510.scala7
-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/tailrec.check6
-rw-r--r--test/files/neg/unreachablechar.flags1
-rw-r--r--test/files/pos/generic-sigs.scala4
-rw-r--r--test/files/pos/hkarray.flags2
-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/t1439.flags2
-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/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/Runner.scala4
-rw-r--r--test/files/presentation/random.check3
-rw-r--r--test/files/run/applydynamic_sip.check22
-rw-r--r--test/files/run/applydynamic_sip.scala58
-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.check30
-rw-r--r--test/files/run/classtags_core.scala32
-rw-r--r--test/files/run/constrained-types.check7
-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/existentials-in-compiler.check16
-rw-r--r--test/files/run/existentials3.check46
-rw-r--r--test/files/run/existentials3.scala20
-rw-r--r--test/files/run/groundtypetags_core.check30
-rw-r--r--test/files/run/groundtypetags_core.scala32
-rw-r--r--test/files/run/implicitclasses.scala10
-rw-r--r--test/files/run/inline-ex-handlers.check261
-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/reify_classfileann_b.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.scala8
-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.scala10
-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.scala8
-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.scala36
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled/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.scala71
-rw-r--r--test/files/run/patmat_unapp_abstype.check2
-rw-r--r--test/files/run/patmat_unapp_abstype.flags1
-rw-r--r--test/files/run/patmat_unapp_abstype.scala54
-rw-r--r--test/files/run/primitive-sigs-2.check14
-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.scala12
-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-parens.check2
-rw-r--r--test/files/run/repl-parens.scala4
-rw-r--r--test/files/run/repl-power.check1
-rw-r--r--test/files/run/repl-suppressed-warnings.scala1
-rw-r--r--test/files/run/t1195.check12
-rw-r--r--test/files/run/t1195.scala4
-rw-r--r--test/files/run/t2886.check10
-rw-r--r--test/files/run/t2886.scala9
-rw-r--r--test/files/run/t3507.check1
-rw-r--r--test/files/run/t3507.scala (renamed from test/files/neg/t3507.scala)6
-rw-r--r--test/files/run/t3758.check6
-rw-r--r--test/files/run/t3758.scala12
-rw-r--r--test/files/run/t3835.scala9
-rw-r--r--test/files/run/t4110.check4
-rw-r--r--test/files/run/t4172.check2
-rw-r--r--test/files/run/t4317/S_1.scala2
-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.check22
-rw-r--r--test/files/run/t5271_1.scala9
-rw-r--r--test/files/run/t5271_2.check24
-rw-r--r--test/files/run/t5271_2.scala9
-rw-r--r--test/files/run/t5271_3.check38
-rw-r--r--test/files/run/t5271_3.scala9
-rw-r--r--test/files/run/t5271_4.scala12
-rw-r--r--test/files/run/t5272_1.scala12
-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/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/treePrint.scala11
-rw-r--r--test/files/run/typetags_core.check30
-rw-r--r--test/files/run/typetags_core.scala32
-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_staging.flags2
-rw-r--r--test/files/run/virtpatmat_stringinterp.check1
-rw-r--r--test/files/run/virtpatmat_stringinterp.flags1
-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.flags2
-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/specialized/spec-patmatch.check2
-rw-r--r--test/pending/neg/reify_packed.check4
-rw-r--r--test/pending/neg/reify_packed.scala10
-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-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.scala5
-rw-r--r--test/pending/run/t5258b.scala12
-rw-r--r--test/pending/run/t5258c.scala12
-rw-r--r--test/pending/run/t5271_1.scala12
-rw-r--r--test/pending/run/t5271_2.scala12
-rw-r--r--test/pending/run/t5271_3.scala12
-rw-r--r--test/pending/run/t5418.scala12
-rw-r--r--test/scaladoc/resources/implicits-base-res.scala147
-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.check2
-rw-r--r--test/scaladoc/run/SI-5373.scala6
-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/scalacheck/CommentFactoryTest.scala5
-rwxr-xr-xtools/binary-repo-lib.sh59
-rwxr-xr-xtools/cleanup-commit130
1420 files changed, 20138 insertions, 6533 deletions
diff --git a/build.xml b/build.xml
index 6a3bc1d4c7..1a0e85a6f0 100644
--- a/build.xml
+++ b/build.xml
@@ -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"/>
@@ -281,7 +281,7 @@ INITIALISATION
<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" />
@@ -314,12 +314,13 @@ INITIALISATION
<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} ${scalac.args.optimise}"/>
+ <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"/>
@@ -336,7 +337,7 @@ INITIALISATION
<!-- 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"> -->
@@ -386,7 +387,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>
<!-- ===========================================================================
@@ -449,7 +450,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>
@@ -509,11 +510,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}">
@@ -635,7 +636,7 @@ PACKED LOCKER BUILD (PALO)
<!-- ===========================================================================
QUICK BUILD (QUICK)
============================================================================ -->
-
+
<target name="quick.start" depends="locker.done"/>
<target name="quick.pre-lib" depends="quick.start">
@@ -659,7 +660,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}"/>
</javac>
<javac
srcdir="${src.dir}/actors"
@@ -723,13 +724,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"/>
@@ -826,7 +827,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"/>
@@ -837,7 +838,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"/>
@@ -862,7 +863,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"/>
@@ -897,7 +898,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"/>
@@ -992,7 +993,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"/>
@@ -1008,9 +1009,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"
@@ -1049,7 +1050,7 @@ PACKED QUICK BUILD (PACK)
</fileset>
</jar>
</target>
-
+
<target name="pack.pre-comp" depends="pack.lib">
<uptodate
property="pack.comp.available"
@@ -1077,7 +1078,7 @@ PACKED QUICK BUILD (PACK)
</fileset>
</copy>
</target>
-
+
<target name="pack.pre-plugins" depends="pack.comp">
<uptodate
property="pack.plugins.available"
@@ -1091,13 +1092,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"
@@ -1111,7 +1112,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"
@@ -1123,10 +1124,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"
@@ -1170,7 +1171,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"/>
@@ -1193,9 +1194,9 @@ 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}">
@@ -1280,7 +1281,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"/>
@@ -1363,7 +1364,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"/>
@@ -1374,7 +1375,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
@@ -1418,13 +1419,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"/>
@@ -1476,9 +1477,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`">
@@ -1494,7 +1495,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
@@ -1511,16 +1512,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">
@@ -1529,7 +1530,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
@@ -1556,16 +1557,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">
@@ -1574,7 +1575,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
@@ -1588,10 +1589,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"/>
@@ -1601,7 +1602,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>
@@ -1609,7 +1610,7 @@ LIBRARIES (MSIL, FJBG maybe later)
<!-- ===========================================================================
DOCUMENTATION
============================================================================ -->
-
+
<target name="docs.start" depends="pack.done">
<macrodef name="doc-uptodate-check">
<attribute name="name" />
@@ -1639,7 +1640,7 @@ DOCUMENTATION
<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>
@@ -1658,13 +1659,14 @@ DOCUMENTATION
destdir="${build-docs.dir}/library"
doctitle="Scala Standard Library API (Scaladoc)"
docversion="${version.number}"
- docfooter="epfl"
+ 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"/>
@@ -1745,7 +1747,8 @@ DOCUMENTATION
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"/>
@@ -1766,7 +1769,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>
@@ -1789,7 +1793,8 @@ DOCUMENTATION
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"/>
@@ -1810,7 +1815,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"/>
@@ -1831,7 +1837,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"/>
@@ -1863,7 +1870,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">
@@ -1937,7 +1944,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>
@@ -2154,7 +2161,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>
@@ -2169,7 +2176,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">
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/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1
index 0bbbea1e7b..3d5a0edfd5 100644
--- a/lib/scala-compiler.jar.desired.sha1
+++ b/lib/scala-compiler.jar.desired.sha1
@@ -1 +1 @@
-f9fcb59f3dbe1b060f8c57d4463dde5e0796951f ?scala-compiler.jar
+52e6cc393c953df8c6cbe710f8d62dce6cd1f671 ?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..028ef2fae2 100644
--- a/lib/scala-library.jar.desired.sha1
+++ b/lib/scala-library.jar.desired.sha1
@@ -1 +1 @@
-1d53671b52f2052c0690fcef9c9989150d8a4704 ?scala-library.jar
+569b35836872765f0b96a6477d7c37a257cc62e7 ?scala-library.jar
diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
index 9a7c79d856..b86c62661a 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])
@@ -270,7 +261,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
}
lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] =
- reflect.ClassManifest.classType(classOf[ClassfileAnnotArg])
+ reflect.ClassManifest[ClassfileAnnotArg](classOf[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 6ef6751720..72fca5da12 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -10,10 +10,29 @@ 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 =>
+ // [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).
@@ -129,6 +148,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
DoubleClass
)
def ScalaValueClassCompanions: List[Symbol] = ScalaValueClasses map (_.companionSymbol)
+ def ScalaPrimitiveValueClasses: List[Symbol] = ScalaValueClasses
}
object definitions extends AbsDefinitions with ValueClassDefinitions {
@@ -446,19 +466,38 @@ 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)
- lazy val PartialManifestClass = getRequiredClass("scala.reflect.ClassManifest")
- lazy val PartialManifestModule = getRequiredModule("scala.reflect.ClassManifest")
- lazy val FullManifestClass = getRequiredClass("scala.reflect.Manifest")
- lazy val FullManifestModule = getRequiredModule("scala.reflect.Manifest")
- 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 ClassTagClass = getRequiredClass("scala.reflect.ClassTag")
+ def ClassTagErasure = getMember(ClassTagClass, nme.erasure)
+ def ClassTagTpe = getMember(ClassTagClass, nme.tpe)
+ lazy val ClassTagModule = getRequiredModule("scala.reflect.ClassTag")
+ lazy val TypeTagsClass = getRequiredClass("scala.reflect.api.TypeTags")
+ lazy val TypeTagClass = getMember(TypeTagsClass, tpnme.TypeTag)
+ def TypeTagTpe = getMember(TypeTagClass, nme.tpe)
+ lazy val TypeTagModule = getMember(TypeTagsClass, nme.TypeTag)
+ lazy val ConcreteTypeTagClass = getMember(TypeTagsClass, tpnme.ConcreteTypeTag)
+ lazy val ConcreteTypeTagModule = getMember(TypeTagsClass, nme.ConcreteTypeTag)
+
+ 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_materializeClassTag = getMember(MacroInternalPackage, nme.materializeClassTag)
+ def MacroInternal_materializeTypeTag = getMember(MacroInternalPackage, nme.materializeTypeTag)
+ def MacroInternal_materializeConcreteTypeTag = getMember(MacroInternalPackage, nme.materializeConcreteTypeTag)
lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature")
lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature")
@@ -467,33 +506,15 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val OptionClass: Symbol = getRequiredClass("scala.Option")
lazy val SomeClass: Symbol = getRequiredClass("scala.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, args map manifestToType: _*)
- case _ =>
- NoType
- }
+ def manifestToType(m: Manifest[_]): Type = importerFromRm.importType(m.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 manifestToSymbol(m: Manifest[_]): Symbol = importerFromRm.importSymbol(m.tpe.typeSymbol)
// The given symbol represents either String.+ or StringAdd.+
def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+
@@ -527,11 +548,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
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 ProductClass = { val arr = mkArityArray("Product", MaxProductArity) ; arr(0) = UnitClass ; arr }
lazy val TupleClass = mkArityArray("Tuple", MaxTupleArity)
lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0)
@@ -905,7 +921,21 @@ 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) || (
@@ -957,6 +987,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
try getModule(fullname.toTermName)
catch { case _: MissingRequirementError => NoSymbol }
+ 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))
@@ -976,7 +1009,13 @@ trait Definitions extends reflect.api.StandardDefinitions {
def getMember(owner: Symbol, name: Name): Symbol = {
getMemberIfDefined(owner, name) orElse {
- throw new FatalError(owner + " does not have a member " + name)
+ if (phase.flatClasses && name.isTypeName && !owner.isPackageObjectOrClass) {
+ val pkg = owner.owner
+ val flatname = nme.flattenedName(owner.name, name)
+ getMember(pkg, flatname)
+ } else {
+ throw new FatalError(owner + " does not have a member " + name)
+ }
}
}
def getMemberIfDefined(owner: Symbol, name: Name): Symbol =
@@ -993,7 +1032,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
def getDeclIfDefined(owner: Symbol, name: Name): Symbol =
owner.info.nonPrivateDecl(name)
-
+
def packageExists(packageName: String): Boolean =
getModuleIfDefined(packageName).isPackage
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/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index c9336e8cf1..ab5e19fca9 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 =>
+ newFreeTerm(importName(x.name).toTermName, importType(x.info), x.value, x.origin, myflags)
+ case x: from.FreeType =>
+ newFreeType(importName(x.name).toTypeName, importType(x.info), x.value, x.origin, myflags)
case x: from.TermSymbol =>
linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol)
case x: from.TypeSkolem =>
@@ -374,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() =>
@@ -425,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/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
index 05578a2042..ac22017569 100644
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ b/src/compiler/scala/reflect/internal/NameManglers.scala
@@ -128,12 +128,7 @@ trait NameManglers {
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
+ /** Return the original name and the types on which this name
* is specialized. For example,
* {{{
* splitSpecializedName("foo$mIcD$sp") == ('foo', "I", "D")
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index 5f38374f20..d2b55d9d39 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 ...
*
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/Reporters.scala b/src/compiler/scala/reflect/internal/Reporters.scala
new file mode 100644
index 0000000000..20d4a1d026
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/Reporters.scala
@@ -0,0 +1,74 @@
+package scala.reflect
+package internal
+
+trait Reporters { self: SymbolTable =>
+
+ import self.{Reporter => ApiReporter}
+ import scala.tools.nsc.reporters._
+ import scala.tools.nsc.reporters.{Reporter => NscReporter}
+ import scala.tools.nsc.Settings
+
+ def mkConsoleReporter(minSeverity: Int = 1): ApiReporter = {
+ val settings = new Settings()
+ if (minSeverity <= 0) settings.verbose.value = true
+ if (minSeverity > 1) settings.nowarn.value = true
+ wrapNscReporter(new ConsoleReporter(settings))
+ }
+
+ abstract class ApiToNscReporterProxy(val apiReporter: ApiReporter) extends AbstractReporter {
+ import apiReporter.{Severity => ApiSeverity}
+ val API_INFO = apiReporter.INFO
+ val API_WARNING = apiReporter.WARNING
+ val API_ERROR = apiReporter.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 =
+ apiReporter.log(pos, msg, nscSeverity match {
+ case NSC_INFO => API_INFO
+ case NSC_WARNING => API_WARNING
+ case NSC_ERROR => API_ERROR
+ })
+
+ def displayPrompt(): Unit =
+ apiReporter.interactive()
+ }
+
+ def wrapApiReporter(apiReporter: ApiReporter): NscReporter = new ApiToNscReporterProxy(apiReporter) {
+ val settings = new Settings()
+ settings.verbose.value = true
+ settings.nowarn.value = false
+ }
+
+ class NscToApiReporterProxy(val nscReporter: NscReporter) extends ApiReporter {
+ val API_INFO = INFO
+ val API_WARNING = WARNING
+ val API_ERROR = ERROR
+
+ def display(info: Info): Unit = info.severity match {
+ case API_INFO => nscReporter.info(info.pos, info.msg, false)
+ case API_WARNING => nscReporter.warning(info.pos, info.msg)
+ case API_ERROR => nscReporter.error(info.pos, info.msg)
+ }
+
+ def interactive(): Unit = nscReporter match {
+ case nscReporter: AbstractReporter => nscReporter.displayPrompt()
+ case _ => // do nothing
+ }
+
+ override def flush(): Unit = {
+ super.flush()
+ nscReporter.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ nscReporter.reset()
+ }
+ }
+
+ def wrapNscReporter(nscReporter: NscReporter): ApiReporter = new NscToApiReporterProxy(nscReporter)
+}
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/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index 0cd3616ba9..bf468affe6 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -9,12 +9,13 @@ package internal
import scala.collection.immutable
import NameTransformer.MODULE_SUFFIX_STRING
import annotation.switch
+import language.implicitConversions
trait StdNames extends NameManglers { self: SymbolTable =>
def encode(str: String): TermName = newTermNameCached(NameTransformer.encode(str))
- implicit def lowerTermNames(n: TermName): String = "" + n
+ implicit def lowerTermNames(n: TermName): String = n.toString
// implicit def stringToTermName(s: String): TermName = newTermName(s)
@@ -44,6 +45,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 +57,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")
@@ -123,6 +126,9 @@ trait StdNames extends NameManglers { self: SymbolTable =>
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>"
@@ -140,10 +146,12 @@ trait StdNames extends NameManglers { self: SymbolTable =>
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"
@@ -185,32 +193,35 @@ trait StdNames extends NameManglers { self: SymbolTable =>
trait TermNames extends Keywords with CommonNames {
// 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 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 MIRROR_PREFIX: NameType = "$mr."
+ val MIRROR_SHORT: NameType = "$mr"
+ val MIRROR_FREE_PREFIX: NameType = "free$"
+ val MIRROR_FREE_THIS_SUFFIX: NameType = "$this"
+ val MIRROR_FREE_VALUE_SUFFIX: NameType = "$value"
+ 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 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 _1 : NameType = "_1"
val _2 : NameType = "_2"
@@ -275,12 +286,38 @@ 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 Apply: NameType = "Apply"
+ val ArrayAnnotArg: NameType = "ArrayAnnotArg"
+ val ConstantType: NameType = "ConstantType"
+ val EmptyPackage: NameType = "EmptyPackage"
+ val EmptyPackageClass: NameType = "EmptyPackageClass"
+ 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 add_ : NameType = "add"
@@ -289,6 +326,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
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"
@@ -311,6 +349,7 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure
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 +361,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 +371,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 +379,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,36 +391,55 @@ 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 map: NameType = "map"
+ val materializeClassTag: NameType = "materializeClassTag"
+ val materializeTypeTag: NameType = "materializeTypeTag"
+ val materializeConcreteTypeTag: NameType = "materializeConcreteTypeTag"
val mirror : NameType = "mirror"
+ val moduleClass : NameType = "moduleClass"
+ val name: NameType = "name"
val ne: NameType = "ne"
val newArray: NameType = "newArray"
+ val newFreeTerm: NameType = "newFreeTerm"
+ val newFreeType: NameType = "newFreeType"
+ val newNestedSymbol: NameType = "newNestedSymbol"
val newScopeWith: NameType = "newScopeWith"
+ val nmeNewTermName: NameType = "newTermName"
+ val nmeNewTypeName: NameType = "newTypeName"
val next: NameType = "next"
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"
@@ -390,12 +450,15 @@ 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"
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index 83a24dce68..0268339ed0 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -16,6 +16,7 @@ abstract class SymbolTable extends api.Universe
with SymbolCreations
with Symbols
with SymbolFlags
+ with FreeVars
with Types
with Kinds
with ExistentialsAndSkolems
@@ -34,6 +35,9 @@ abstract class SymbolTable extends api.Universe
with TypeDebugging
with Importers
with Required
+ with TreeBuildUtil
+ with Reporters
+ with CapturedVariables
{
def rootLoader: LazyType
def log(msg: => AnyRef): Unit
@@ -48,6 +52,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)
@@ -158,7 +169,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.
@@ -256,6 +267,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 04bdb0f4ad..c9947c3c09 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -45,10 +45,15 @@ 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 newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar =
- new FreeVar(name, value) initFlags newFlags setInfo tpe
+ def newFreeTerm(name: TermName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeTerm =
+ new FreeTerm(name, value, origin) initFlags newFlags setInfo info
+
+ /** Create a new free type. Its owner is NoSymbol.
+ */
+ def newFreeType(name: TypeName, info: Type, value: => Any, origin: String, newFlags: Long = 0L): FreeType =
+ new FreeType(name, value, origin) initFlags newFlags setInfo info
/** The original owner of a class. Used by the backend to generate
* EnclosingMethod attributes.
@@ -58,6 +63,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
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 => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags)
@@ -324,7 +332,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[Symbol]] = {
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)
@@ -543,6 +551,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isTypeParameter = false
def isTypeParameterOrSkolem = false
def isTypeSkolem = false
+ def isTypeMacro = false
+ def isFreeType = false
/** Qualities of Terms, always false for TypeSymbols.
*/
@@ -563,13 +573,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
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 isMacro = false
def isMethod = false
def isSourceMethod = false
def isVarargsMethod = false
@@ -613,11 +624,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
@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
-
+
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) }
-
+
/** Default implementation calls the generic string function, which
* will print overloaded flags as <flag1/flag2/flag3>. Subclasses
* of Symbol refine.
@@ -632,7 +643,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
_rawflags = mask
this
}
-
+
final def flags: Long = {
val fs = _rawflags & phase.flagMask
(fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift)
@@ -780,7 +791,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
final def isModuleVar = hasFlag(MODULEVAR)
- /** Is this symbol static (i.e. with no outer instance)? */
+ /** 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? */
@@ -836,6 +851,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
@@ -865,6 +890,25 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isInitialized: Boolean =
validTo != NoPeriod
+ // [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 =
if (isCovariant) 1
@@ -1292,7 +1336,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
@@ -1720,7 +1764,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 ||
@@ -1739,7 +1784,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
false
}
}
- )
+ }
/** The internal representation of classes and objects:
*
@@ -1843,7 +1888,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.
*/
@@ -1946,7 +1991,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Remove private modifier from symbol `sym`s definition. If `sym` is a
* 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
+ * @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) {
@@ -2032,8 +2077,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")
@@ -2054,6 +2101,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)
}
@@ -2216,8 +2264,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** 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 isValue = !(isModule && hasFlag(PACKAGE | JAVA))
+ override def isVariable = isMutable && !isMethod
+ override def isTermMacro = hasFlag(MACRO)
// interesting only for lambda lift. Captured variables are accessed from inner lambdas.
override def isCapturedVariable = hasAllFlags(MUTABLE | CAPTURED) && !hasFlag(METHOD)
@@ -2406,7 +2455,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def isMethod = true
override def isLabel = this hasFlag LABEL
- override def isMacro = this hasFlag MACRO
override def isVarargsMethod = this hasFlag VARARGS
override def isLiftedMethod = this hasFlag LIFTED
@@ -2438,6 +2486,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
extends TypeSymbol(initOwner, initPos, initName) {
type TypeOfClonedSymbol = TypeSymbol
final override def isAliasType = true
+ final override def dealias = info.typeSymbol.dealias
override def cloneSymbolImpl(owner: Symbol, newFlags: Long): TypeSymbol =
owner.newNonClassSymbol(name, pos, newFlags)
}
@@ -2469,7 +2518,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
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
@@ -2877,7 +2927,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
abort("Can't rename a package object to " + name)
}
}
-
+
trait ImplClassSymbol extends ClassSymbol {
override def sourceModule = companionModule
// override def isImplClass = true
@@ -2913,12 +2963,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
}
- 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 FreeTerm(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) {
+ def value = value0
+ override def isFreeTerm = true
+ }
+
+ class FreeType(name0: TypeName, value0: => Any, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) {
+ def value = value0
+ override def isFreeType = true
}
/** An object representing a missing symbol */
@@ -3054,10 +3106,11 @@ 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
}
@@ -3068,7 +3121,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
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..fbcd5043bc
--- /dev/null
+++ b/src/compiler/scala/reflect/internal/TreeBuildUtil.scala
@@ -0,0 +1,62 @@
+package scala.reflect
+package internal
+
+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, origin: String) = newFreeTerm(newTermName(name), info, value, origin)
+
+ def newFreeType(name: String, info: Type, value: => Any, origin: String) = newFreeType(newTypeName(name), info, value, 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..1a374b6e59 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._
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index ce3de94335..039c8e557a 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -531,4 +531,213 @@ 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(_, List(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(_, List(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, String)] = tree match {
+ case FreeTermDef(mrRef, name, binding, origin) =>
+ Some(mrRef, name, binding, origin)
+ case FreeTypeDef(mrRef, name, binding, origin) =>
+ Some(mrRef, name, binding, origin)
+ case _ =>
+ None
+ }
+ }
+
+ object FreeTermDef {
+ lazy val newFreeTermMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeTerm)
+
+ def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match {
+ case ValDef(_, name, _, Apply(Select(mrRef @ Ident(_), newFreeTerm), List(_, _, binding, Literal(Constant(origin: String)))))
+ if mrRef.name == nme.MIRROR_SHORT && newFreeTerm == newFreeTermMethod.name =>
+ Some(mrRef, name, binding, origin)
+ case _ =>
+ None
+ }
+ }
+
+ object FreeTypeDef {
+ lazy val newFreeTypeMethod = getMember(getRequiredClass("scala.reflect.api.TreeBuildUtil"), nme.newFreeType)
+
+ def unapply(tree: Tree): Option[(Tree, TermName, Tree, String)] = tree match {
+ case ValDef(_, name, _, Apply(Select(mrRef1 @ Ident(_), newFreeType), List(_, _, value, Literal(Constant(origin: String)))))
+ if mrRef1.name == nme.MIRROR_SHORT && newFreeType == newFreeTypeMethod.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, 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, origin)
+ case _ =>
+ throw new Error("unsupported free type def: " + showRaw(tree))
+ }
+ 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 7a084304a8..486a3d3567 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, "")
@@ -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})
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index c0d6f54b1a..5f1a8f3fbe 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -103,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
@@ -146,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
@@ -184,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
}
@@ -203,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
}
@@ -235,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
@@ -249,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.
*/
@@ -266,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
@@ -273,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
@@ -363,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
@@ -430,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 575d84eab4..afb1d8061e 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 || settings.YvirtPatmat.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,37 @@ 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 = transformedType(this)
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, _) => notConcreteSym(sym)
+ 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 */
@@ -710,7 +741,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 +756,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))
@@ -910,14 +946,10 @@ trait Types extends api.Types { self: SymbolTable =>
*/
def directObjectString = safeToString
- /** A test whether a type contains any unification type variables. */
+ /** 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 _ =>
@@ -1194,6 +1226,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
@@ -1251,6 +1285,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
@@ -1822,7 +1858,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]
}
}
@@ -2108,6 +2172,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
@@ -2200,10 +2269,10 @@ trait Types extends api.Types { self: SymbolTable =>
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)) {
@@ -2480,39 +2549,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
@@ -2640,21 +2716,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
@@ -2703,6 +2793,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).
@@ -2716,6 +2823,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
@@ -2728,6 +2836,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
@@ -2896,14 +3005,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)
@@ -3001,7 +3109,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"
@@ -3751,6 +3859,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) {
@@ -4563,6 +4673,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)
@@ -4686,7 +4806,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) =>
@@ -5997,8 +6117,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
}
diff --git a/src/compiler/scala/reflect/internal/settings/MutableSettings.scala b/src/compiler/scala/reflect/internal/settings/MutableSettings.scala
index b556c33aba..45ba4ed3e6 100644
--- a/src/compiler/scala/reflect/internal/settings/MutableSettings.scala
+++ b/src/compiler/scala/reflect/internal/settings/MutableSettings.scala
@@ -43,5 +43,5 @@ abstract class MutableSettings extends AbsSettings {
def Yrecursion: IntSetting
def maxClassfileName: IntSetting
def Xexperimental: BooleanSetting
- def YvirtPatmat: BooleanSetting
+ def XoldPatmat: BooleanSetting
} \ No newline at end of file
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..184008658e
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Context.scala
@@ -0,0 +1,26 @@
+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 Reporters
+ with Settings
+ with Symbols
+ with Typers
+ with Util {
+
+ 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..f9a6987e48
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala
@@ -0,0 +1,36 @@
+package scala.reflect.makro
+package runtime
+
+trait Enclosures {
+ self: Context =>
+
+ import mirror._
+
+ // vals are eager to simplify debugging
+ // after all we wouldn't save that much time by making them lazy
+
+ val macroApplication: Tree = expandee
+
+ val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros
+
+ val enclosingImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits
+
+ val enclosingPosition: Position = enclosingMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication.pos).getOrElse(NoPosition)
+
+ val enclosingApplication: Tree = {
+ def loop(context: analyzer.Context): Tree = context match {
+ case analyzer.NoContext => EmptyTree
+ case context if context.tree.isInstanceOf[Apply] => context.tree
+ case context => loop(context.outer)
+ }
+
+ val context = callsiteTyper.context
+ loop(context)
+ }
+
+ val enclosingMethod: Tree = callsiteTyper.context.enclMethod.tree
+
+ val enclosingClass: Tree = callsiteTyper.context.enclClass.tree
+
+ val enclosingUnit: CompilationUnit = currentRun.currentUnit
+} \ 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..2488b06d6c
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
@@ -0,0 +1,69 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Gilles Dubochet
+ */
+
+package scala.reflect.makro
+package runtime
+
+trait Reifiers {
+ self: Context =>
+
+ import mirror._
+
+ lazy val reflectMirrorPrefix: Tree = {
+ // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure?
+ val prefix: Tree = Select(Select(Ident(definitions.ScalaPackage), newTermName("reflect")), newTermName("mirror"))
+ val prefixTpe = typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe
+ typeCheck(prefix) setType prefixTpe
+ }
+
+ def reifyTree(prefix: Tree, tree: Tree): Tree =
+ reifyTopLevel(prefix, tree)
+
+ def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree =
+ reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag)
+
+ def unreifyTree(tree: Tree): Tree =
+ Select(tree, definitions.ExprEval)
+
+ def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = {
+ // [Eugene] the plumbing is not very pretty, but anyways factoring out the reifier seems like a necessary step to me
+ import scala.reflect.reify._
+ val reifier = mkReifier(mirror)(callsiteTyper, prefix, reifee, dontSpliceAtTopLevel, requireConcreteTypeTag)
+
+ try {
+ val result = reifier.reified
+ logFreeVars(expandee.pos, result)
+ result
+ } catch {
+ case ex: reifier.ReificationError =>
+// // this is a "soft" exception - it will normally be caught by the macro
+// // consequently, we need to log the stack trace here, so that it doesn't get lost
+// if (settings.Yreifydebug.value) {
+// val message = new java.io.StringWriter()
+// ex.printStackTrace(new java.io.PrintWriter(message))
+// println(scala.compat.Platform.EOL + message)
+// }
+ val xlated = new ReificationError(ex.pos, ex.msg)
+ xlated.setStackTrace(ex.getStackTrace)
+ throw xlated
+ case ex: reifier.UnexpectedReificationError =>
+ val xlated = new UnexpectedReificationError(ex.pos, ex.msg, ex.cause)
+ xlated.setStackTrace(ex.getStackTrace)
+ throw xlated
+ }
+ }
+
+ class ReificationError(var pos: Position, val msg: String) extends Throwable(msg)
+
+ object ReificationError extends ReificationErrorExtractor {
+ def unapply(error: ReificationError): Option[(Position, String)] = Some((error.pos, error.msg))
+ }
+
+ class UnexpectedReificationError(val pos: Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause)
+
+ object UnexpectedReificationError extends UnexpectedReificationErrorExtractor {
+ def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)] = Some((error.pos, error.msg, error.cause))
+ }
+}
diff --git a/src/compiler/scala/reflect/makro/runtime/Reporters.scala b/src/compiler/scala/reflect/makro/runtime/Reporters.scala
new file mode 100644
index 0000000000..0fd037bdd2
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Reporters.scala
@@ -0,0 +1,44 @@
+package scala.reflect.makro
+package runtime
+
+trait Reporters {
+ self: Context =>
+
+ import mirror._
+
+ def reporter: mirror.Reporter = wrapNscReporter(mirror.reporter)
+
+ def setReporter(reporter: mirror.Reporter): this.type = {
+ mirror.reporter = wrapApiReporter(reporter)
+ this
+ }
+
+ def withReporter[T](reporter: Reporter)(op: => T): T = {
+ val old = mirror.reporter
+ setReporter(reporter)
+ 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/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..552ad2a303
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Symbols.scala
@@ -0,0 +1,8 @@
+package scala.reflect.makro
+package runtime
+
+trait Symbols {
+ self: Context =>
+
+ def isLocatable(sym: Symbol) = sym.isLocatable
+} \ No newline at end of file
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..38e819746d
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala
@@ -0,0 +1,78 @@
+package scala.reflect.makro
+package runtime
+
+trait Typers {
+ self: Context =>
+
+ val openMacros: List[Context] = this :: mirror.analyzer.openMacros
+
+ val 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 = {
+ def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg)
+ trace("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) =>
+ trace(result)
+ result
+ case error @ mirror.analyzer.SilentTypeError(_) =>
+ trace(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 = {
+ def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg)
+ trace("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled))
+ import mirror.analyzer.SearchResult
+ val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.context.withMacrosDisabled[SearchResult] _)
+ def wrapper (inference: => SearchResult) = wrapper1(inference)
+ val context = callsiteTyper.context.makeImplicit(true)
+ wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match {
+ case failure if failure.tree.isEmpty =>
+ trace("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 = {
+ def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg)
+ trace("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous))
+ import mirror.analyzer.SearchResult
+ val wrapper1 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[SearchResult] _) else (callsiteTyper.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))
+ val context = callsiteTyper.context.makeImplicit(reportAmbiguous)
+ wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match {
+ case failure if failure.tree.isEmpty =>
+ trace("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/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala
new file mode 100644
index 0000000000..30c6c06c7b
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/Errors.scala
@@ -0,0 +1,63 @@
+package scala.reflect
+package reify
+
+import scala.tools.nsc.Global
+
+trait Errors {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+
+ class ReificationError(var pos: Position, val msg: String) extends Throwable(msg)
+ class UnexpectedReificationError(val pos: Position, val msg: String, val cause: Throwable = null) extends Throwable(msg)
+
+ lazy val defaultErrorPosition: Position =
+ mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication.pos).getOrElse(NoPosition)
+
+ // 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)
+ }
+} \ No newline at end of file
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..16c26734b2
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -0,0 +1,154 @@
+package scala.reflect
+package reify
+
+import scala.tools.nsc.Global
+
+/** 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 requireConcreteTypeTag: 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 manifestedType = typer.packedType(tree, NoSymbol)
+ val manifestedRtype = reifyType(manifestedType)
+ val tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule
+ var typeTagCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType)))
+ var exprCtor = TypeApply(Select(Ident(nme.MIRROR_SHORT), ExprModule.name), List(TypeTree(manifestedType)))
+ Apply(Apply(exprCtor, List(rtree)), List(Apply(typeTagCtor, List(manifestedRtype))))
+
+ case tpe: Type =>
+ reifyTrace("reifying = ")(tpe.toString)
+ reifyTrace("prefix = ")(prefix)
+ val rtree = reify(tpe)
+
+ val manifestedType = tpe
+ var tagModule = if (definitelyConcrete) ConcreteTypeTagModule else TypeTagModule
+ var ctor = TypeApply(Select(Ident(nme.MIRROR_SHORT), tagModule.name), List(TypeTree(manifestedType)))
+ Apply(ctor, List(rtree))
+
+ 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 freedef @ FreeDef(_, _, binding, _) => binding.symbol } toSet
+ val untyped = resetAllAttrs(wrapped, leaveAlone = {
+ case ValDef(_, mr, _, _) if mr == nme.MIRROR_SHORT => true
+ case tree if freevarBindings contains 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..2fc0002838
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala
@@ -0,0 +1,177 @@
+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(origin(sym))))
+ } else {
+ locallyReify(sym, name, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(sym.tpe), value, 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))))
+ // todo. implement info reification for free types: type bounds, HK-arity, whatever else that can be useful
+ locallyReify(sym, name, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, 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.attachment
+ att match {
+ case sym: Symbol =>
+ // 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) setAttachment 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)
+ reified.attachment match {
+ case sym: Symbol => 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 {
+ val rset = Apply(Select(locallyReified(sym), nme.setTypeSignature), List(reifyType(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..5ad53c0009
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala
@@ -0,0 +1,236 @@
+package scala.reflect.reify
+package codegen
+
+trait Trees {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ // 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(_)) =>
+ 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(reifySymRef(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(reifyType(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, reifyType(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, reifyType(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..948728088e
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/Types.scala
@@ -0,0 +1,163 @@
+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 */
+ var maybeConcrete = true
+ var definitelyConcrete = true
+
+ 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 = {
+ if (tpe.isSpliceable) {
+ if (reifyDebug) println("splicing " + tpe)
+
+ if (spliceTypesEnabled) {
+ var tagClass = if (requireConcreteTypeTag) 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))
+ val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree]
+ typer.resolveTypeTag(positionBearer, prefix.tpe, tpe, requireConcreteTypeTag) match {
+ case failure if failure.isEmpty =>
+ if (reifyDebug) println("implicit search was fruitless")
+ definitelyConcrete &= false
+ maybeConcrete &= false
+ EmptyTree
+ case success =>
+ if (reifyDebug) println("implicit search has produced a result: " + success)
+ definitelyConcrete |= requireConcreteTypeTag
+ maybeConcrete |= true
+ 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")
+ }
+
+ if (requireConcreteTypeTag)
+ CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(tpe)
+ }
+
+ 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..85cf92fe2f
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/package.scala
@@ -0,0 +1,22 @@
+package scala.reflect
+
+import scala.tools.nsc.Global
+
+package object reify {
+ def mkReifier(global: Global)(typer: global.analyzer.Typer, prefix: global.Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Reifier { val mirror: global.type } = {
+ val typer1: typer.type = typer
+ val prefix1: prefix.type = prefix
+ val reifee1 = reifee
+ val dontSpliceAtTopLevel1 = dontSpliceAtTopLevel
+ val requireConcreteTypeTag1 = requireConcreteTypeTag
+
+ new {
+ val mirror: global.type = global
+ val typer = typer1
+ val prefix = prefix1
+ val reifee = reifee1
+ val dontSpliceAtTopLevel = dontSpliceAtTopLevel1
+ val requireConcreteTypeTag = requireConcreteTypeTag1
+ } with Reifier
+ }
+}
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..e4f3fce407
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala
@@ -0,0 +1,59 @@
+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") }
+ 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..bb0b8ac138
--- /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..02a96987ed
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/phases/Reify.scala
@@ -0,0 +1,46 @@
+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._
+
+ /**
+ * Reifies any supported value.
+ * For internal use only, use ``reified'' instead.
+ */
+ def reify(reifee: Any): Tree = 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..e700604612
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala
@@ -0,0 +1,296 @@
+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 Literal(const @ Constant(tpe: Type)) =>
+ // todo. implement this
+ ???
+ case Literal(const @ Constant(sym: Symbol)) =>
+ // todo. implement this
+ ???
+ 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..20024ed058 100644
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ b/src/compiler/scala/reflect/runtime/Mirror.scala
@@ -1,24 +1,24 @@
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
}
@@ -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 27e90c94bd..bbe4d60e9c 100644
--- a/src/compiler/scala/reflect/runtime/Settings.scala
+++ b/src/compiler/scala/reflect/runtime/Settings.scala
@@ -34,5 +34,5 @@ class Settings extends internal.settings.MutableSettings {
val maxClassfileName = new IntSetting(255)
val Xexperimental = new BooleanSetting(false)
val deepCloning = new BooleanSetting (false)
- val YvirtPatmat = 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/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
index 5ae4ec15ee..6fc5f7ed8a 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -14,8 +14,11 @@ 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 newFreeTerm(name: TermName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeTerm =
+ new FreeTerm(name, value, origin) with SynchronizedTermSymbol initFlags newFlags setInfo info
+
+ override def newFreeType(name: TypeName, info: Type, value: => Any, origin: String = null, newFlags: Long = 0L): FreeType =
+ new FreeType(name, value, origin) with SynchronizedTypeSymbol initFlags newFlags setInfo info
override protected def makeNoSymbol: NoSymbol = new NoSymbol with SynchronizedSymbol
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
index 28f12b378f..6d832a590f 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
@@ -1,28 +1,30 @@
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 = "") {
+ import self.{Reporter => ApiReporter}
+ import scala.tools.nsc.reporters.{Reporter => NscReporter}
- class ToolBoxGlobal(settings0: nsc.Settings, reporter0: nsc.reporters.Reporter) extends ReflectGlobal(settings0, reporter0) {
+ def mkToolBox(reporter: ApiReporter = mkSilentReporter(), options: String = "") = new ToolBox(reporter, options)
+
+ class ToolBox(val reporter: ApiReporter, val options: String) extends AbsToolBox {
+
+ class ToolBoxGlobal(settings: scala.tools.nsc.Settings, reporter: NscReporter)
+ extends ReflectGlobal(settings, reporter, ToolBox.this.classLoader) {
import definitions._
private val trace = scala.tools.nsc.util.trace when settings.debug.value
@@ -36,64 +38,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 +49,190 @@ 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))
+ 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)
+ run.compileUnits(List(unit), run.namerPhase)
if (reporter.hasErrors) {
- throw new Error("reflective compilation has failed")
+ var msg = "reflective compilation has failed: " + EOL + EOL
+ msg += ToolBox.this.reporter.infos map (_.msg) mkString EOL
+ throw new ToolBoxError(ToolBox.this, msg)
}
+ 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 = {
@@ -161,6 +252,7 @@ trait ToolBoxes extends { self: Universe =>
}
}
+ // todo. is not going to work with quoted arguments with embedded whitespaces
lazy val arguments = options.split(" ")
lazy val virtualDirectory =
@@ -170,49 +262,96 @@ 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 => reporter.log(NoPosition, msg, reporter.ERROR)
+ // [Eugene] settings shouldn't be passed via reporters, this is crazy
+// val command = reporter match {
+// case reporter: AbstractReporter => new CompilerCommand(arguments.toList, reporter.settings, errorFn)
+// case _ => new CompilerCommand(arguments.toList, errorFn)
+// }
+ val command = new CompilerCommand(arguments.toList, errorFn)
+ command.settings.outputDirs setSingleOutput virtualDirectory
+ val nscReporter = new ApiToNscReporterProxy(reporter) { val settings = command.settings }
+ val instance = new ToolBoxGlobal(command.settings, nscReporter)
+ if (nscReporter.hasErrors) {
+ var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL
+ msg += reporter.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 dca6d6041b..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,24 +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.
- type TreeAnnotation = Position
- def NoTreeAnnotation: TreeAnnotation = NoPosition
- def positionToAnnotation(pos: Position): TreeAnnotation = pos // TODO
- def annotationToPosition(annot: TreeAnnotation): Position = annot //TODO
-
// 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/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/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala
index 3792c26c34..9592e7a716 100644
--- a/src/compiler/scala/tools/cmd/FromString.scala
+++ b/src/compiler/scala/tools/cmd/FromString.scala
@@ -7,14 +7,14 @@ package scala.tools
package cmd
import nsc.io.{ Path, File, Directory }
-import scala.reflect.OptManifest
+import scala.reflect.Manifest
/** 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 PartialFunction[String, T] {
+abstract class FromString[+T](implicit m: Manifest[T]) extends PartialFunction[String, T] {
def apply(s: String): T
def isDefinedAt(s: String): Boolean = true
def zero: T = apply("")
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/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..92a0efff1e 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -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,10 @@ 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.deprecationWarnings.warn(pos, msg)
def uncheckedWarning(pos: Position, msg: String) =
- if (opt.unchecked) warning(pos, msg)
- else currentRun.uncheckedWarnings ::= ((pos, msg))
+ currentRun.uncheckedWarnings.warn(pos, msg)
def incompleteInputError(pos: Position, msg:String) =
reporter.incompleteInputError(pos, msg)
@@ -104,10 +105,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 5e0c24d304..403b5717b0 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -12,7 +12,7 @@ import compat.Platform.currentTime
import scala.tools.util.{ Profiling, PathResolver }
import scala.collection.{ mutable, immutable }
import io.{ SourceReader, AbstractFile, Path }
-import reporters.{ Reporter, ConsoleReporter }
+import reporters.{ Reporter => NscReporter, 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 }
@@ -31,25 +31,27 @@ import backend.{ ScalaPrimitives, Platform, MSILPlatform, JavaPlatform }
import backend.jvm.GenJVM
import backend.opt.{ Inliners, InlineExceptionHandlers, ClosureElimination, DeadCodeElimination }
import backend.icode.analysis._
-
-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 {
+import language.postfixOps
+
+class Global(var currentSettings: Settings, var reporter: NscReporter) extends SymbolTable
+ 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 ------------------------------------------
- def this(reporter: Reporter) =
+ def this(reporter: NscReporter) =
this(new Settings(err => reporter.error(null, err)), reporter)
def this(settings: Settings) =
@@ -61,7 +63,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 +80,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,7 +131,7 @@ 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
}
@@ -137,7 +141,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
} with TreeBrowsers
val nodeToString = nodePrinters.nodeToString
- val reifiedNodeToString = nodePrinters.reifiedNodeToString
val treeBrowser = treeBrowsers.create()
// ------------ Hooks for interactive mode-------------------------
@@ -215,7 +218,7 @@ 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))
@@ -319,7 +322,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))
@@ -344,7 +347,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.
@@ -936,6 +939,17 @@ 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))
+ }
+
/** A Run is a single execution of the compiler on a sets of units
*/
class Run {
@@ -947,9 +961,12 @@ 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
+ val deprecationWarnings = new ConditionalWarning("deprecation", settings.deprecation)
+ val uncheckedWarnings = new ConditionalWarning("unchecked", settings.unchecked)
+ val featureWarnings = new ConditionalWarning("feature", settings.feature)
+ val allConditionalWarnings = List(deprecationWarnings, uncheckedWarnings, featureWarnings)
+
+ var reportedFeature = Set[Symbol]()
/** A flag whether macro expansions failed */
var macroExpansionFailed = false
@@ -1108,7 +1125,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.
*/
@@ -1239,12 +1256,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.")
@@ -1581,7 +1594,7 @@ object Global {
* This allows the use of a custom Global subclass with the software which
* wraps Globals, such as scalac, fsc, and the repl.
*/
- def fromSettings(settings: Settings, reporter: Reporter): Global = {
+ def fromSettings(settings: Settings, reporter: NscReporter): Global = {
// !!! The classpath isn't known until the Global is created, which is too
// late, so we have to duplicate it here. Classpath is too tightly coupled,
// it is a construct external to the compiler and should be treated as such.
@@ -1589,7 +1602,7 @@ object Global {
val loader = ScalaClassLoader.fromURLs(new PathResolver(settings).result.asURLs, parentLoader)
val name = settings.globalClass.value
val clazz = Class.forName(name, true, loader)
- val cons = clazz.getConstructor(classOf[Settings], classOf[Reporter])
+ val cons = clazz.getConstructor(classOf[Settings], classOf[NscReporter])
cons.newInstance(settings, reporter).asInstanceOf[Global]
}
@@ -1597,7 +1610,7 @@ object Global {
/** A global instantiated this way honors -Yglobal-class setting, and
* falls back on calling the Global constructor directly.
*/
- def apply(settings: Settings, reporter: Reporter): Global = {
+ def apply(settings: Settings, reporter: NscReporter): Global = {
val g = (
if (settings.globalClass.isDefault) null
else try fromSettings(settings, reporter) catch { case x =>
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..1fa576afb6 100644
--- a/src/compiler/scala/tools/nsc/Phases.scala
+++ b/src/compiler/scala/tools/nsc/Phases.scala
@@ -7,6 +7,7 @@ package scala.tools.nsc
import symtab.Flags
import util.TableDef
+import language.postfixOps
object Phases {
val MaxPhases = 64
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..eb298833b8
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ToolBoxes.scala
@@ -0,0 +1,85 @@
+package scala.tools.nsc
+
+import util.ScalaClassLoader
+
+trait ToolBoxes { self: Global =>
+
+ import self.{Reporter => ApiReporter}
+
+ def mkToolBox(reporter: ApiReporter = mkSilentReporter(), options: String = "") = new ToolBox(reporter, options)
+
+ class ToolBox(val reporter: ApiReporter, 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(reporter.asInstanceOf[libraryClasspathMirror.Reporter], 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 456e7eae9e..8e7eeed3cc 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.{Reporter => NscReporter}
import util.{Position, NoPosition}
import util.DocStrings._
import scala.reflect.internal.Chars._
@@ -21,7 +21,7 @@ trait DocComments { self: Global =>
var cookedDocComments = Map[Symbol, String]()
- def reporter: Reporter
+ def reporter: NscReporter
/** The raw doc comment map */
val docComments = mutable.HashMap[Symbol, DocComment]()
@@ -252,7 +252,7 @@ trait DocComments { self: Global =>
def replaceInheritdoc(childSection: String, parentSection: => String) =
if (childSection.indexOf("@inheritdoc") == -1)
childSection
- else
+ else
childSection.replaceAllLiterally("@inheritdoc", parentSection)
def getParentSection(section: (Int, Int)): String = {
@@ -275,9 +275,9 @@ trait DocComments { self: Global =>
}
child.substring(section._1, section._1 + 7) match {
- case param@("@param "|"@tparam"|"@throws") =>
+ case param@("@param "|"@tparam"|"@throws") =>
sectionString(extractSectionParam(child, section), parentNamedParams(param.trim))
- case _ =>
+ case _ =>
sectionString(extractSectionTag(child, section), parentTagMap)
}
}
@@ -367,7 +367,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)
}
}
}
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..1bf36e8bf2
--- /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..108c8fcbfa 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
@@ -81,7 +82,7 @@ abstract class NodePrinters {
if (tpe == null || tpe == NoType) ""
else "tree.tpe=" + tpe
}
-
+
def showAttributes(tree: Tree): String = {
if (infolevel == InfoLevel.Quiet) ""
else {
@@ -90,7 +91,7 @@ abstract class NodePrinters {
}
}
}
-
+
trait PrintAST {
private val buf = new StringBuilder
private var level = 0
@@ -101,7 +102,7 @@ abstract class NodePrinters {
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)
@@ -122,8 +123,14 @@ abstract class NodePrinters {
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 +141,7 @@ abstract class NodePrinters {
}
}
def println(s: String) = printLine(s, "")
-
+
def printLine(value: String, comment: String) {
buf append " " * level
buf append value
@@ -183,7 +190,7 @@ abstract class NodePrinters {
traverseList("Nil", "argument")(args)
}
}
-
+
def printMultiline(tree: Tree)(body: => Unit) {
printMultiline(tree.printingPrefix, showAttributes(tree))(body)
}
@@ -299,7 +306,7 @@ 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
@@ -339,7 +346,7 @@ abstract class NodePrinters {
traverseList("[]", "type parameter")(tparams)
traverse(rhs)
}
-
+
case PackageDef(pid, stats) =>
printMultiline("PackageDef", "")(pid :: stats foreach traverse)
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 04468a096d..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)), Literal(Constant(sym.isClass)))
- )
- )
- }
-
- /**
- * 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 2b75925d9a..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
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index ad26ccad5e..d3e64811d3 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?
@@ -71,14 +72,6 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
Annotated(Ident(nme.synthSwitch), expr)
}
- // 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 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)
@@ -86,9 +79,11 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
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)
@@ -99,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)
}
@@ -119,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(
@@ -207,22 +177,6 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
def mkSysErrorCall(message: String): Tree =
mkMethodCall(Sys_error, List(Literal(Constant(message))))
- /** A creator for a call to a scala.reflect.Manifest or ClassManifest factory method.
- *
- * @param full full or partial manifest (target will be Manifest or ClassManifest)
- * @param constructor name of the factory method (e.g. "classType")
- * @param tparg the type argument
- * @param args value arguments
- * @return the tree
- */
- def mkManifestFactoryCall(full: Boolean, constructor: String, tparg: Type, args: List[Tree]): Tree =
- mkMethodCall(
- if (full) FullManifestModule else PartialManifestModule,
- newTermName(constructor),
- List(tparg),
- args
- )
-
/** Make a synchronized block on 'monitor'. */
def mkSynchronized(monitor: Tree, body: Tree): Tree =
Apply(Select(monitor, Object_synchronized), List(body))
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 43c231cf2d..04452c68e5 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
@@ -118,7 +88,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
// create parameters for <init> as synthetic trees.
var vparamss1 =
vparamss map (vps => vps.map { vd =>
- atPos(focusPos(vd.pos)) {
+ atPos(vd.pos.focus) {
ValDef(
Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations,
vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
@@ -130,7 +100,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
)
}
@@ -198,8 +168,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 +177,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 +190,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 +211,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 +237,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 +253,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 +266,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 +286,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 +299,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 +308,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 +364,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 e7e3eaabf5..eb4deeeee2 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)
@@ -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()
@@ -1456,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)
}
}
}
@@ -1771,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) =>
@@ -1834,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 _ =>
@@ -1852,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 =>
@@ -2421,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
* }}}
@@ -2444,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,
@@ -2463,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
@@ -2476,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)
}
@@ -2529,7 +2539,7 @@ self =>
/** {{{
* TypeDef ::= type Id [TypeParamClause] `=' Type
- * | `macro' FunSig `=' Expr
+ * | FunSig `=' Expr
* TypeDcl ::= type Id [TypeParamClause] TypeBounds
* }}}
*/
@@ -2537,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
}
}
}
@@ -2599,14 +2607,14 @@ self =>
def classDef(start: Int, mods: Modifiers): ClassDef = {
in.nextToken
val nameOffset = in.offset
+ val isBackquoted = in.token == BACKQUOTED_IDENT
val name = identForType()
-
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;
+ 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()
@@ -2640,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) {
@@ -2818,6 +2827,7 @@ self =>
* }}}
*/
def packaging(start: Int): Tree = {
+ val nameOffset = in.offset
val pkg = pkgQualId()
val stats = inBracesOrNil(topStatSeq())
makePackaging(start, pkg, stats)
@@ -3020,8 +3030,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..0f2a3e0395 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.
*
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/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index 4f3b0bf951..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 =>
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index ec303d76ee..ff58de5f12 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 ...
*
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 7ad7cadd92..f61f78ebb2 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
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 be1e466f4e..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 ...
*
@@ -651,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 =>
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..cf51a5b926 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -854,7 +854,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 f32564f097..76a8b87ba7 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -58,7 +58,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
case Right(sourceCode) =>
new compiler.Run() compileSources List(new BatchSourceFile("newSource", sourceCode))
}
-
+
if (reporter.hasErrors)
return None
@@ -80,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) =
@@ -89,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")
diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala
index 45a2ad78b4..17bfb7d21d 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,9 +127,102 @@ 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"))
+
+ /**
+ * 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/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index f059b5c0cb..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 {
@@ -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
@@ -354,7 +419,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</div>
case _ => NodeSeq.Empty
}
- }
+ }
val selfType: Seq[scala.xml.Node] = mbr match {
case dtpl: DocTemplateEntity if (isSelf && !dtpl.selfType.isEmpty && !isReduced) =>
@@ -477,7 +542,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
// end attributes block vals ---
- val attributesInfo = attributes ++ definitionClasses ++ fullSignature ++ 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
@@ -561,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",
@@ -765,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 6fb83c133e..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;
}
@@ -369,15 +396,15 @@ div.members > ol > li:last-child {
.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,
@@ -539,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
}
@@ -583,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 {
@@ -600,7 +627,7 @@ div.fullcomment dl.paramcmts > dd {
}
#textfilter > .input {
- display: block;
+ display: block;
position: absolute;
top: 0;
right: 20px;
@@ -608,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%;
}
@@ -660,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;
@@ -683,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;
}
@@ -709,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{
@@ -739,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 670c9bbb3b..124a7509e8 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 }
@@ -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) && !isPureBridge(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 }
+ 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
})
@@ -481,36 +502,36 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
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) }
}
}
@@ -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)
@@ -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)
}
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..0e44933ac6
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
@@ -0,0 +1,519 @@
+/* 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: Manifest[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 Mainfest[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)
+ 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 5b298b3761..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
*/
@@ -530,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()
@@ -957,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/core/CoreTestDefs.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala
index 40bbd3fa8e..99541ff4b4 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
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 108d4377a8..bf386d8a12 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.
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 0c64bb2901..43e01bebfd 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -13,6 +13,7 @@ import scala.sys.BooleanProp
import io.VirtualDirectory
import scala.tools.nsc.io.AbstractFile
import reporters._
+import reporters.{Reporter => NscReporter}
import symtab.Flags
import scala.reflect.internal.Names
import scala.tools.util.PathResolver
@@ -23,6 +24,7 @@ import scala.collection.{ mutable, immutable }
import scala.util.control.Exception.{ ultimately }
import IMain._
import java.util.concurrent.Future
+import language.implicitConversions
/** directory to save .class files to */
private class ReplVirtualDirectory(out: JPrintWriter) extends VirtualDirectory("(memory)", None) {
@@ -202,8 +204,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)
}
@@ -274,7 +275,7 @@ 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: NscReporter) = {
settings.outputDirs setSingleOutput virtualDirectory
settings.exposeEmptyPackage.value = true
@@ -340,7 +341,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 manifests 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
@@ -817,7 +825,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 {
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
index f9c1907696..a86462ad5f 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -287,7 +287,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..40993eb916 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
@@ -120,7 +121,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 && (vparamss.isEmpty || vparamss.head.isEmpty && vparamss.tail.isEmpty)
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..e2b1bf34d6 100644
--- a/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/NamedParam.scala
@@ -7,6 +7,7 @@ package scala.tools.nsc
package interpreter
import NamedParam._
+import language.implicitConversions
trait NamedParamCreator {
protected def freshName: () => String
@@ -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/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..ecf9dd219b 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.
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/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 ad6e8dc48d..8b891e0010 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
@@ -6,6 +6,8 @@
package scala.tools.nsc
package interpreter
+import language.implicitConversions
+
/** A class which the repl utilizes to expose predefined objects.
* The base implementation is empty; the standard repl implementation
* is StdReplVals.
@@ -58,7 +60,7 @@ object ReplVals {
* I have this forwarder which widens the type and then cast the result back
* to the dependent type.
*/
- def manifestToType(m: OptManifest[_]): Global#Type =
+ def manifestToType(m: Manifest[_]): Global#Type =
definitions.manifestToType(m)
class AppliedTypeFromManifests(sym: Symbol) {
diff --git a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala
index 5edc8fd202..59a7b9b5d2 100644
--- a/src/compiler/scala/tools/nsc/interpreter/RichClass.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/RichClass.scala
@@ -7,7 +7,7 @@ package scala.tools.nsc
package interpreter
class RichClass[T](val clazz: Class[T]) {
- def toManifest: Manifest[T] = Manifest.classType(clazz)
+ def toManifest: Manifest[T] = Manifest[T](ClassManifest[T](clazz).tpe)
def toTypeString: String = TypeStrings.fromClazz(clazz)
// Sadly isAnonymousClass does not return true for scala anonymous
diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
index 6b56d881fc..872ac00bfd 100644
--- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
@@ -10,6 +10,7 @@ import java.lang.{ reflect => r }
import r.TypeVariable
import scala.reflect.NameTransformer
import NameTransformer._
+import scala.reflect.{mirror => rm}
/** 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
@@ -72,8 +73,12 @@ 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: Manifest] : String = {
+ // [Eugene to Paul] needs review!!
+ def typeArguments: List[rm.Type] = manifest[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
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/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..86c7ca7b9a 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) }
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..249f754e8f 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)
- 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 43aad9f591..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
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/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..a52e3b8bbe 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")
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 14b3bcc8ce..d4c2ffa832 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
@@ -62,6 +63,7 @@ trait ScalaSettings extends AbsScalaSettings
val classpath = PathSetting ("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp"
val d = OutputSetting (outputDirs, ".")
val nospecialization = BooleanSetting ("-no-specialization", "Ignore @specialize annotations.")
+ val language = MultiStringSetting("-language", "feature", "Enable one or more language features.")
/**
* -X "Advanced" settings
@@ -80,6 +82,9 @@ trait ScalaSettings extends AbsScalaSettings
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.")
@@ -103,6 +108,8 @@ 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.", "")
+ 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.
*/
@@ -116,62 +123,61 @@ trait ScalaSettings extends AbsScalaSettings
/**
* -Y "Private" settings
*/
- 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 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.") 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 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 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 Ymacrocopypaste = BooleanSetting ("-Ymacro-copypaste", "Dump macro expansions 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")
@@ -180,26 +186,30 @@ trait ScalaSettings extends AbsScalaSettings
/** 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 Ymacrodebug = BooleanSetting("-Ymacro-debug", "Trace macro-related activities: generation of synthetics, 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.")
+ 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 Ymacrodebug = BooleanSetting("-Ymacro-debug", "Trace 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
+ 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.")
+ 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
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/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala
deleted file mode 100644
index 94b619de90..0000000000
--- a/src/compiler/scala/tools/nsc/symtab/Positions.scala
+++ /dev/null
@@ -1,30 +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
-
- type TreeAnnotation = scala.tools.nsc.util.TreeAnnotation
- def NoTreeAnnotation: TreeAnnotation = NoPosition
- def positionToAnnotation(pos: Position): TreeAnnotation = pos
- def annotationToPosition(annot: TreeAnnotation): Position = annot.pos
- 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)
- }
- 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/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/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 758f870d6b..52648380ec 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -149,7 +149,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 +425,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 +606,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 +1059,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 97e844f6d8..5a11926048 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -179,7 +179,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
/** If `tp` refers to a non-interface trait, return a
* reference to its implementation class. Otherwise return `tp`.
*/
- def mixinToImplClass(tp: Type): Type = erasure(implSym) {
+ 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)
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index e6f5dc5b5f..fd15d92e37 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._
@@ -542,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)) {
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index ecfc2b6084..5e61359a25 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) {
@@ -480,11 +480,10 @@ abstract class Erasure extends AddInterfaces
// 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 = afterErasure(
- member.isSynthetic
- && (member.name == nme.unapply || member.name == nme.unapplySeq)
- && !(member.tpe <:< other.tpe) // no static guarantees (TODO: is the subtype test ever true?)
- )
+ 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)
@@ -734,7 +733,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) =>
@@ -1090,7 +1089,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)
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 16c7c3c3ff..8daad8a2ac 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -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 3515c1d521..007457ef7b 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -50,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))
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index f6dc8fbfb0..6bddfe8d57 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, 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)
@@ -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 6d4dab57a3..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)
@@ -778,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))
@@ -1085,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 12d2513756..ff671088ac 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.
*
@@ -1327,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)
@@ -1341,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)
}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index f90d3d45fe..57cd51ad35 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.
@@ -240,7 +241,6 @@ abstract class UnCurry extends InfoTransform
def owner = fun.symbol.owner
def targs = fun.tpe.typeArgs
def isPartial = fun.tpe.typeSymbol == PartialFunctionClass
- assert(!(opt.virtPatmat && isPartial)) // empty-selector matches have already been translated into instantiations of anonymous (partial) functions
def parents =
if (isFunctionType(fun.tpe)) List(abstractFunctionForFunctionType(fun.tpe), SerializableClass.tpe)
@@ -281,7 +281,44 @@ abstract class UnCurry extends InfoTransform
val substParam = new TreeSymSubstituter(fun.vparams map (_.symbol), List(x))
val body = localTyper.typedPos(fun.pos) { import CODE._
- gen.mkUncheckedMatch(gen.withDefaultCase(substParam(fun.body), scrut => REF(default) APPLY (REF(x))))
+ 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)
@@ -293,30 +330,115 @@ abstract class UnCurry extends InfoTransform
methDef
}
- // duplicate before applyOrElseMethodDef is run so we start with the same symbols as applyOrElseMethodDef
+ // 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 = fun.body.duplicate
+ 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 substLabels = new TreeSymSubstituter(oldSyms, newSyms)
+
+ substLabels(duped)
+ }
+
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(resetLocalAttrs(x)) // see pos/t1761 for why `resetLocalAttrs`
+ 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._
- gen.mkUncheckedMatch(
- if (cases exists treeInfo.isDefaultCase) TRUE_typed
+ val casesNoSynthCatchAll = dropSyntheticCatchAll(cases)
+ if (casesNoSynthCatchAll exists treeInfo.isDefaultCase) TRUE_typed
else
doSubst(wrap(
- Match(selector,
- (cases map (c => deriveCaseDef(c)(x => TRUE_typed))) :+ (
+ 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)
@@ -327,11 +449,14 @@ abstract class UnCurry extends InfoTransform
if (isPartial) List(applyOrElseMethodDef, isDefinedAtMethodDef)
else List(applyMethodDef)
- localTyper.typedPos(fun.pos) {
+ // 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]) = {
@@ -358,18 +483,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.resolveClassTag(tree, 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)))
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index ff0bdf7580..e9c3bef737 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -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)
@@ -344,6 +339,11 @@ trait ContextErrors {
setError(tree)
}
+ def MacroEtaError(tree: Tree) = {
+ issueNormalTypeError(tree, "macros cannot be eta-expanded")
+ setError(tree)
+ }
+
//typedReturn
def ReturnOutsideOfDefError(tree: Tree) = {
issueNormalTypeError(tree, "return outside method definition")
@@ -453,6 +453,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))
@@ -480,7 +483,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("", ", ", ".")
)
}
@@ -501,6 +504,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")
@@ -581,9 +587,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)
}
@@ -622,7 +628,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 "" )
)
}
@@ -642,7 +647,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)
@@ -832,7 +837,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
@@ -848,6 +853,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 manifest 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 _ =>
@@ -898,10 +916,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 9b1f395ad0..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 }
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 75440a1136..4fb9362ccc 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, NoPosition)
+
+ def inferImplicit(tree: Tree, pt: Type, reportAmbiguous: Boolean, isView: Boolean, context: Context, saveAmbiguousDivergent: Boolean): SearchResult =
+ inferImplicit(tree, pt, reportAmbiguous, isView, context, saveAmbiguousDivergent, NoPosition)
/** 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) {
@@ -677,7 +710,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 +740,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 +830,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() = (eligible map (info => (info, typedImplicit(info, false)))).toMap
/** Returns the SearchResult of the best match.
*/
@@ -825,7 +859,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,111 +1119,58 @@ trait Implicits {
implicitInfoss1
}
- /** 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?
- */
- private def manifestOfType(tp: Type, full: Boolean): SearchResult = {
-
- /** Creates a tree that calls the factory method called constructor in object reflect.Manifest */
- def manifestFactoryCall(constructor: String, tparg: Type, args: Tree*): Tree =
- if (args contains EmptyTree) EmptyTree
- else typedPos(tree.pos.focus) {
- val mani = gen.mkManifestFactoryCall(full, constructor, tparg, args.toList)
- if (settings.debug.value) println("generated manifest: "+mani) // DEBUG
- mani
- }
+ // these should be lazy, otherwise we wouldn't be able to compile scala-library with starr
+ private val TagSymbols = Set(ClassTagClass, TypeTagClass, ConcreteTypeTagClass)
+ private val TagMaterializers = Map(
+ ClassTagClass -> MacroInternal_materializeClassTag,
+ TypeTagClass -> MacroInternal_materializeTypeTag,
+ ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag
+ )
- /** Creates a tree representing one of the singleton manifests.*/
- def findSingletonManifest(name: String) = typedPos(tree.pos.focus) {
- Select(gen.mkAttributedRef(FullManifestModule), name)
- }
+ 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)
+ }
- /** 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, 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 = {
- implicit def wrapResult(tree: Tree): SearchResult =
- if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to))
-
- val tp1 = tp0.normalize
- tp1 match {
- case ThisType(_) | SingleType(_, _) =>
- // can't generate a reference to a value that's abstracted over by an existential
- if (containsExistential(tp1)) EmptyTree
- else manifestFactoryCall("singleType", tp, gen.mkAttributedQualifier(tp1))
- case ConstantType(value) =>
- manifestOfType(tp1.deconst, full)
- case TypeRef(pre, sym, args) =>
- if (isPrimitiveValueClass(sym) || isPhantomClass(sym)) {
- findSingletonManifest(sym.name.toString)
- } else if (sym == ObjectClass || sym == AnyRefClass) {
- findSingletonManifest("Object")
- } else if (sym == RepeatedParamClass || sym == ByNameParamClass) {
- EmptyTree
- } else if (sym == ArrayClass && args.length == 1) {
- manifestFactoryCall("arrayType", args.head, findManifest(args.head))
- } else if (sym.isClass) {
- val classarg0 = gen.mkClassOf(tp1)
- val classarg = tp match {
- case _: ExistentialType => gen.mkCast(classarg0, ClassType(tp))
- case _ => classarg0
- }
- val suffix = classarg :: (args map findSubManifest)
- manifestFactoryCall(
- "classType", tp,
- (if ((pre eq NoPrefix) || pre.typeSymbol.isStaticOwner) suffix
- else findSubManifest(pre) :: suffix): _*)
- } else if (sym.isExistentiallyBound && full) {
- manifestFactoryCall("wildcardType", tp,
- findManifest(tp.bounds.lo), findManifest(tp.bounds.hi))
- }
- // looking for a manifest of a type parameter that hasn't been inferred by now,
- // can't do much, but let's not fail
- else if (undetParams contains sym) {
- // #3859: need to include the mapping from sym -> NothingClass.tpe in the SearchResult
- mot(NothingClass.tpe, sym :: from, NothingClass.tpe :: to)
- } else {
- // a manifest should have been found by normal searchImplicit
- EmptyTree
- }
- case RefinedType(parents, decls) => // !!! not yet: if !full || decls.isEmpty =>
- // refinement is not generated yet
- if (hasLength(parents, 1)) findManifest(parents.head)
- else if (full) manifestFactoryCall("intersectionType", tp, parents map findSubManifest: _*)
- else mot(erasure.intersectionDominator(parents), from, to)
- case ExistentialType(tparams, result) =>
- mot(tp1.skolemizeExistential, from, to)
- case _ =>
- EmptyTree
-/* !!! the following is almost right, but we have to splice nested manifest
- * !!! types into this type. This requires a substantial extension of
- * !!! reifiers.
- val reifier = new Reifier()
- val rtree = reifier.reifyTopLevel(tp1)
- manifestFactoryCall("apply", tp, rtree)
-*/
- }
+ val prefix = (tagClass, pre) match {
+ // ClassTags only exist for scala.reflect.mirror, so their materializer doesn't care about prefixes
+ case (ClassTagClass, _) =>
+ gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror)
+ // [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))
}
- mot(tp, Nil, Nil)
+ // todo. migrate hardcoded materialization in Implicits to corresponding implicit macros
+ var materializer = atPos(pos.focus)(Apply(TypeApply(Ident(TagMaterializers(tagClass)), List(TypeTree(tp))), List(prefix)))
+ if (settings.XlogImplicits.value) println("materializing requested %s.%s[%s] using %s".format(pre, tagClass.name, tp, materializer))
+ success(materializer)
}
- 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.
*/
- private def implicitManifestOrOfExpectedType(pt: Type): SearchResult = pt.dealias match {
- case TypeRef(_, sym, args) if ManifestSymbols(sym) =>
- manifestOfType(args.head, sym == FullManifestClass) match {
- case SearchFailure if sym == OptManifestClass => wrapResult(gen.mkAttributedRef(NoManifest))
- case result => result
- }
+ private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match {
+ case TypeRef(pre, sym, args) if TagSymbols(sym) =>
+ tagOfType(pre, args.head, 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
@@ -1199,7 +1180,9 @@ trait Implicits {
/** 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 manifest 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 +1202,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 +1223,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 +1251,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 +1276,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 ebf8e3fc9a..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")
@@ -267,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
@@ -310,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))
@@ -426,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{
@@ -751,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 =>
@@ -761,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)
@@ -992,6 +1007,7 @@ trait Infer {
PolymorphicExpressionInstantiationError(tree, undetparams, pt)
} else {
new TreeTypeSubstituter(undetparams, targs).traverse(tree)
+ notifyUndetparamsInferred(undetparams, targs)
}
}
@@ -1028,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
@@ -1116,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)
@@ -1171,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")
@@ -1568,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..62a0e08aad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -3,135 +3,687 @@ 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._
+/**
+ * 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 { self: Analyzer =>
import global._
import definitions._
- def macroMeth(mac: Symbol): Symbol = {
- var owner = mac.owner
- if (!owner.isModuleClass) owner = owner.companionModule.moduleClass
- owner.info.decl(nme.macroMethodName(mac.name))
- }
+ val macroDebug = settings.Ymacrodebug.value
+ val macroCopypaste = settings.Ymacrocopypaste.value
+ val macroTrace = scala.tools.nsc.util.trace when macroDebug
- 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())
- }
+ val globalMacroCache = collection.mutable.Map[Any, Any]()
+ val perRunMacroCache = perRunCaches.newMap[Symbol, collection.mutable.Map[Any, Any]]
- /**
- * The definition of the method implementing a macro. Example:
- * Say we have in a class C
+ /** A list of compatible macro implementation signatures.
*
- * def macro foo[T](xs: List[T]): T = expr
+ * In the example above:
+ * (c: scala.reflect.makro.Context)(xs: c.Expr[List[T]]): c.Expr[T]
*
- * 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
- * }
+ * @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) =>
+ vparamss.flatten.find(_.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 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 = vparamss map (_ map 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._
+ macroTrace("generating macroImplSigs for: ")(macroDef)
+ macroTrace("tparams are: ")(tparams)
+ macroTrace("vparamss are: ")(vparamss)
+ macroTrace("retTpe is: ")(retTpe)
+ macroTrace("macroImplSigs are: ")(paramsss, implRetTpe)
+ }
+
+ 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)
+ 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
+ }
+
+ /** 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
+ if (macroDebug) println("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
+ }
+ }
+
+ var hasErrors = false
+ def reportError(pos: Position, msg: String) = {
+ hasErrors = true
+ context.error(pos, msg)
+ }
+
+ 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()
+ }
+ }
+
+ loop(rhs1)
+ }
+
+ val rhs = ddef.rhs
+ validatePreTyper(rhs)
+ if (hasErrors) macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef)
+
+ // 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)
+ if (macroDebug) {
+ println("typechecked1:")
+ println(typechecked)
+ println(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)
+ }
+ }
+
+ 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) macroTrace("body of a macro def failed to typecheck: ")(ddef)
+
+ 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)
+ macroTrace("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
+ }
+
+ 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")
+
+ 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)
+
+ // 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
+ }
+
+ val ok = if (macroDebug) withTypesExplained(rparam.tpe <:< atpe) else rparam.tpe <:< atpe
+ if (!ok) {
+ compatibilityError("type mismatch for parameter "+rparam.name+": "+rparam.tpe.toString.abbreviateCoreAliases+" does not conform to "+atpe)
+ }
+ }
+ }
+ }
+ }
+ if (!hasErrors) {
+ val atpe = actres.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars)
+ val ok = if (macroDebug) withTypesExplained(atpe <:< reqres) else atpe <:< reqres
+ if (!ok) {
+ compatibilityError("type mismatch for return type : "+reqres.toString.abbreviateCoreAliases+" does not conform to "+(if (ddef.tpt.tpe != null) atpe.toString else atpe.toString.abbreviateCoreAliases))
+ }
+ }
+ 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)
+ }
+ }
+
+ errors.toList
+ }
+
+ var actparamss = macroImpl.paramss
+ actparamss = transformTypeTagEvidenceParams(actparamss, (param, tparam) => None)
+
+ val rettpe = if (ddef.tpt.tpe != null) ddef.tpt.tpe else computeMacroDefTypeFromMacroImpl(ddef, macroDef, macroImpl)
+ val (reqparamsss0, reqres0) = macroImplSigs(macroDef, ddef.tparams, ddef.vparamss, rettpe)
+ var reqparamsss = reqparamsss0
+
+ // 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")
+ macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef)
+ }
+
+ 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)
+
+ macroTrace("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name)
+ val results = reqparamsss map (checkCompatibility(_, actparamss, reqres, actres))
+ if (macroDebug) (reqparamsss zip results) foreach { case (reqparamss, result) =>
+ println("%s %s".format(if (result.isEmpty) "[ OK ]" else "[FAILED]", reqparamss))
+ result foreach (errorMsg => println(" " + errorMsg))
+ }
+
+ 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 (macroDebug) (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
+ }
+
+ rhs1
}
- 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)
+ 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 = macroDdef.vparamss map (_ map (_.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
+ }
+
+ 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
}
- 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) {}
+ /** 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.
+ */
+ private lazy val primaryMirror: Mirror = {
+ if (global.forMSIL)
+ throw new UnsupportedOperationException("Scala reflection not available on this platform")
+
+ val libraryClassLoader = {
+ if (settings.XmacroPrimaryClasspath.value != "") {
+ if (macroDebug) println("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 {
+ if (macroDebug) println("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) {}
+ }
+
+ loader
}
+ }
- 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 = {
+ if (macroDebug) println("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)
}
- override def defaultReflectiveClassLoader() = libraryClassLoader
+ new Mirror(fallbackClassLoader) { override def toString = "<fallback macro mirror>" }
}
- /** 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.
+ /** 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.
*/
- 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)
-
- try {
- val mmeth = macroMeth(mac)
- trace("found implementation at: ")(mmeth.fullNameString)
-
- 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))
+ private def macroRuntime(macroDef: Symbol): Option[List[Any] => Any] = {
+ macroTrace("looking for macro implementation: ")(macroDef)
+ macroTrace("macroDef is annotated with: ")(macroDef.annotations)
+
+ val ann = macroDef.getAnnotation(MacroImplAnnotation)
+ if (ann == None) {
+ macroTrace("@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) {
+ macroTrace("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef)
+ return None
+ }
+
+ if (macroDebug) println("resolved implementation %s at %s".format(macroImpl, macroImpl.pos))
+ if (macroImpl.isErroneous) {
+ macroTrace("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
+
+ macroTrace("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName)
+ macroTrace("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>"
}
- trace("classpath is: ")(inferClasspath(mirror.libraryClassLoader))
+ macroTrace("classpath is: ")(inferClasspath(macroMirror.classLoader))
- // @xeno.by: relies on the fact that macros can only be defined in static classes
+ // [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 =>
@@ -146,145 +698,541 @@ trait Macros { self: Analyzer =>
else recur(sym.enclClass)
}
- // @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)
+ // [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 (debug) {
- println("receiverClass is: " + receiverClass.fullNameString)
+ if (macroDebug) {
+ println("implClassSymbol is: " + implClassSymbol.fullNameString)
- 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 (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 receiverObj = receiverClass.companionModule
- trace("receiverObj is: ")(receiverObj.fullNameString)
+ val implObjSymbol = implClassSymbol.companionModule
+ macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString)
- if (receiverObj == mirror.NoSymbol) None
+ if (implObjSymbol == macroMirror.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))
+ // 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 => macroTrace("exception when loading implObj: ")(ex); null
+ case ex: NoClassDefFoundError => macroTrace("exception when loading implObj: ")(ex); null
+ case ex: ClassNotFoundException => macroTrace("exception when loading implObj: ")(ex); null
}
- if (rmeth == mirror.NoSymbol) None
+ if (implObj == null) None
else {
- Some((receiver, rmeth))
+ val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString))
+ if (macroDebug) {
+ println("implMethSymbol is: " + implMethSymbol.fullNameString)
+ println("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol))
+ }
+
+ if (implMethSymbol == macroMirror.NoSymbol) None
+ else {
+ if (macroDebug) println("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol))
+ Some((implObj, implMethSymbol))
+ }
}
}
+ } catch {
+ case ex: ClassNotFoundException =>
+ macroTrace("implementation class failed to load: ")(ex.toString)
+ None
}
- } catch {
- case ex: ClassNotFoundException =>
- trace("implementation class failed to load: ")(ex.toString)
- None
+ }
+
+ 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 != "") {
+ if (macroDebug) println("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 {
+ None
+ }
}
}
- /** 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.
+ /** 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, openMacros.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''
*/
- 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
- }
- val rawArgs: Seq[Any] = rawArgss.flatten
- trace("rawArgs: ")(rawArgs)
- val savedInfolevel = nodePrinters.infolevel
+ private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = {
+ var prefixTree: Tree = EmptyTree
+ var typeArgs = List[Tree]()
+ val exprArgs = new 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 = macroContext(typer, prefixTree, expandee)
+ var argss: List[List[Any]] = List(context) :: exprArgs.toList
+ macroTrace("argss: ")(argss)
+
+ val macroDef = expandee.symbol
+ 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
+ macroTrace("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.length != 0 && paramss_without_evidences.last.isEmpty
+ val isEmptyArglistInvocation = argss.length != 0 && argss.last.isEmpty
+ if (isEmptyParamlistDef && !isEmptyArglistInvocation) {
+ if (macroDebug) println("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.context.error(expandee.pos, "macros cannot be partially applied")
+ 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
+ paramss = transformTypeTagEvidenceParams(paramss, (param, tparam) => Some(tparam))
+ if (paramss.lastOption map (params => !params.isEmpty && params.forall(_.isType)) getOrElse false) argss = argss :+ Nil
+ val evidences = paramss.last takeWhile (_.isType) map (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
+ if (macroDebug) println("resolved tparam %s as %s".format(tparam, tpe))
+ tpe
+ }) map (tpe => {
+ val ttag = TypeTag(tpe)
+ if (ttag.isConcrete) ttag.toConcrete else ttag
+ })
+ argss = argss.dropRight(1) :+ (evidences ++ argss.last)
+
+ 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
+ macroTrace("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]()
+
+ /** 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 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.
+ *
+ * If -Ymacro-copypaste is enabled along with -Ymacro-debug, you will get macro expansions
+ * logged in the form that can be copy/pasted verbatim into REPL (useful for debugging!).
+ *
+ * @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, pt: Type): Tree =
+ macroExpand1(typer, expandee) match {
+ case Success(expanded) =>
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)
- None
+ 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 Select(_, _) => true
+ case _ => false
}
- } 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
- } else {
- realex.getMessage
- }
- typer.context.unit.error(tree.pos, "exception during macro expansion: " + msg)
- None
+ if (isNullaryInvocation) expectedTpe match {
+ case MethodType(Nil, restpe) =>
+ macroTrace("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to:")(restpe)
+ expectedTpe = restpe
+ case _ => ;
+ }
+
+ var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe))
+ if (macroDebug) {
+ println("typechecked1:")
+ println(typechecked)
+ println(showRaw(typechecked))
+ }
+
+ typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt))
+ if (macroDebug) {
+ println("typechecked2:")
+ println(typechecked)
+ println(showRaw(typechecked))
+ }
+
+ typechecked
} finally {
- nodePrinters.infolevel = savedInfolevel
+ openMacros = openMacros.tail
}
- case None =>
- def notFound() = {
- typer.context.unit.error(tree.pos, "macro implementation not found: " + macroDef.name)
- None
- }
- 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 Fallback(fallback) =>
+ typer.context.withImplicitsEnabled(typer.typed(fallback, EXPRmode, pt))
+ case Other(result) =>
+ result
+ }
+
+ 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(expandee: Tree) = Other(expandee)
+ 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) = {
+ if (macroDebug || macroCopypaste) {
+ var msg1 = if (msg contains "exception during macro expansion") msg.split(EOL).drop(1).headOption.getOrElse("?") else msg
+ if (macroDebug) msg1 = msg
+ println("macro expansion has failed: %s".format(msg1))
+ }
+ val pos = if (expandee.pos != NoPosition) expandee.pos else openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition)
+ 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 = {
+ // 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"
+ macroTrace("cancelled macro expansion because of %s: ".format(reason))(expandee)
+ return Cancel(typer.infer.setError(expandee))
+ }
+
+ if (!isDelayed(expandee)) {
+ if (macroDebug || macroCopypaste) println("typechecking macro expansion %s at %s".format(expandee, expandee.pos))
+
+ val undetparams = calculateUndetparams(expandee)
+ if (undetparams.size != 0) {
+ macroTrace("macro expansion is delayed: ")(expandee)
+ delayed += expandee -> (typer.context, undetparams)
+ Delay(expandee)
+ } else {
+ val start = startTimer(macroExpandNanos)
+ incCounter(macroExpandCount)
+ try {
+ val macroDef = expandee.symbol
+ macroRuntime(macroDef) match {
+ case Some(runtime) =>
+ val savedInfolevel = nodePrinters.infolevel
+ try {
+ // 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 args = macroArgs(typer, expandee)
+ args match {
+ case Some(args) =>
+ // adding stuff to openMacros is easy, but removing it is a nightmare
+ // it needs to be sprinkled over several different code locations
+ val (context: MacroContext) :: _ = args
+ openMacros = context :: openMacros
+ val expanded: MacroExpansionResult = try {
+ val prevNumErrors = reporter.ERROR.count
+ val expanded = runtime(args)
+ val currNumErrors = reporter.ERROR.count
+ if (currNumErrors != prevNumErrors) {
+ fail(typer, expandee) // errors have been reported by the macro itself
+ } else {
+ expanded match {
+ case expanded: Expr[_] =>
+ if (macroDebug || macroCopypaste) {
+ if (macroDebug) println("original:")
+ println(expanded.tree)
+ println(showRaw(expanded.tree))
+ }
+
+ freeTerms(expanded.tree) foreach (fte => typer.context.error(expandee.pos,
+ ("macro expansion contains free term variable %s %s. "+
+ "have you forgot to use eval when splicing this variable into a reifee? " +
+ "if you have troubles tracking free term variables, consider using -Xlog-free-terms").format(fte.name, fte.origin)))
+ freeTypes(expanded.tree) foreach (fty => typer.context.error(expandee.pos,
+ ("macro expansion contains free type variable %s %s. "+
+ "have you forgot to use c.TypeTag annotation for this type parameter? " +
+ "if you have troubles tracking free type variables, consider using -Xlog-free-types").format(fty.name, fty.origin)))
+
+ val currNumErrors = reporter.ERROR.count
+ if (currNumErrors != prevNumErrors) {
+ fail(typer, expandee)
+ } else {
+ // inherit the position from the first position-ful expandee in macro callstack
+ // this is essential for sane error messages
+ var tree = expanded.tree
+ var position = openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition)
+ tree = atPos(position.focus)(tree)
+
+ // now macro expansion gets typechecked against the macro definition return type
+ // however, this happens in macroExpand, not here in macroExpand1
+ Success(tree)
+ }
+ case expanded if expanded.isInstanceOf[Expr[_]] =>
+ val msg = "macro must return a compiler-specific expr; returned value is Expr, but it doesn't belong to this compiler's universe"
+ fail(typer, expandee, msg)
+ case expanded =>
+ val msg = "macro must return a compiler-specific expr; returned value is of class: %s".format(expanded.getClass)
+ fail(typer, expandee, msg)
+ }
+ }
+ } catch {
+ case ex: Throwable =>
+ openMacros = openMacros.tail
+ throw ex
+ }
+ if (!expanded.isInstanceOf[Success]) openMacros = openMacros.tail
+ expanded
+ case None =>
+ fail(typer, expandee) // error has been reported by macroArgs
+ }
+ } catch {
+ case ex =>
+ // [Eugene] any ideas about how to improve this one?
+ val realex = ReflectionUtils.unwrapThrowable(ex)
+ realex match {
+ case realex: reflect.makro.runtime.AbortMacroException =>
+ if (macroDebug || macroCopypaste) println("macro expansion has failed: %s".format(realex.msg))
+ fail(typer, expandee) // error has been reported by abort
+ case _ =>
+ val message = {
+ try {
+ // the most reliable way of obtaining currently executing method
+ // http://stackoverflow.com/questions/442747/getting-the-name-of-the-current-executing-method
+ val currentMethodName = new Object(){}.getClass().getEnclosingMethod().getName
+ val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == currentMethodName)
+ 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)
+ }
+ } finally {
+ nodePrinters.infolevel = savedInfolevel
}
- case Apply(fn, args) =>
- fallBackToOverridden(fn) match {
- case Some(fn1) => Some(Apply(fn1, args) setPos tree.pos)
- case _ => None
+ case None =>
+ 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
}
- case TypeApply(fn, args) =>
- fallBackToOverridden(fn) match {
- case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos)
- case _ => 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 _ =>
+ macroTrace("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
+ }
+ case TypeApply(fn, args) =>
+ fallBackToOverridden(fn) match {
+ case Some(fn1) => Some(TypeApply(fn1, args) setPos tree.pos)
+ case _ => None
+ }
+ case _ =>
+ macroTrace("unexpected tree in fallback: ")(tree)
+ notFound()
+ }
+ }
+ fallBackToOverridden(expandee) match {
+ case Some(tree1) =>
+ macroTrace("falling back to ")(tree1)
+ currentRun.macroExpansionFailed = true
+ Fallback(tree1)
+ case None =>
+ fail(typer, expandee)
}
- case _ =>
- trace("unexpected tree in fallback: ")(tree)
- notFound()
}
+ } finally {
+ stopTimer(macroExpandNanos, start)
}
- fallBackToOverridden(tree) match {
- case Some(tree1) =>
- trace("falling back to ")(tree1)
- currentRun.macroExpansionFailed = true
- Some(tree1)
- case None =>
- None
- }
+ }
+ } else {
+ val undetparams = calculateUndetparams(expandee)
+ if (undetparams.size != 0)
+ Delay(expandee)
+ else
+ Skip(macroExpandAll(typer, expandee))
}
}
+
+ /** 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, (Context, collection.mutable.Set[Int])]
+ private def isDelayed(expandee: Tree) = delayed contains expandee
+ private def calculateUndetparams(expandee: Tree): collection.mutable.Set[Int] =
+ delayed.get(expandee).map(_._2).getOrElse {
+ val calculated = collection.mutable.Set[Int]()
+ expandee foreach (sub => {
+ def traverse(sym: Symbol) = if (sym != null && (undetparams contains sym.id)) calculated += sym.id
+ if (sub.symbol != null) traverse(sub.symbol)
+ if (sub.tpe != null) sub.tpe foreach (sub => traverse(sub.typeSymbol))
+ })
+ calculated
+ }
+ private val undetparams = perRunCaches.newSet[Int]
+ def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = undetparams ++= newUndets map (_.id)
+ def notifyUndetparamsInferred(undetNoMore: List[Symbol], inferreds: List[Type]): Unit = {
+ undetparams --= undetNoMore map (_.id)
+ if (!delayed.isEmpty)
+ delayed.toList foreach {
+ case (expandee, (_, undetparams)) if !undetparams.isEmpty =>
+ undetparams --= undetNoMore map (_.id)
+ if (undetparams.isEmpty) {
+ hasPendingMacroExpansions = true
+ macroTrace("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, _) = delayed(wannabe)
+ delayed -= wannabe
+ macroExpand(newTyper(context), wannabe, 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 3d8c2ea564..9e06cbe0d3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -8,6 +8,7 @@ package typechecker
import symtab.Flags._
import scala.collection.{ mutable, immutable }
import scala.tools.util.StringOps.{ ojoin }
+import language.higherKinds
/** Logic related to method synthesis which involves cooperation between
* Namer and Typer.
@@ -28,6 +29,7 @@ trait MethodSynthesis {
else DefDef(sym, body)
def applyTypeInternal(manifests: List[M[_]]): Type = {
+ // [Eugene to Paul] needs review!!
val symbols = manifests map manifestToSymbol
val container :: args = symbols
val tparams = container.typeConstructor.typeParams
@@ -58,14 +60,32 @@ trait MethodSynthesis {
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)
+ assert(fnSymbol isSubClass FunctionClass(m.tpe.typeArguments.size - 1), (owner, m))
+ // [Eugene to Paul] needs review!!
+ // val symbols = m.typeArguments map (m => manifestToSymbol(m))
+ // val formals = symbols.init map (_.typeConstructor)
+ val formals = manifestToType(m).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) {
@@ -155,28 +175,23 @@ 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 {
self: Namer =>
import NamerErrorGen._
-
- /** TODO - synthesize method.
- */
- def enterImplicitClass(tree: ClassDef) {
- /** e.g.
- val ClassDef(mods, name, tparams, impl) = tree
- val converter = ImplicitClassConverter(tree).createAndEnterSymbol()
- ...
- */
+
+ def enterImplicitWrapper(tree: ClassDef) {
+ ImplicitClassWrapper(tree).createAndEnterSymbol()
}
def enterGetterSetter(tree: ValDef) {
@@ -203,7 +218,8 @@ trait MethodSynthesis {
enterBeans(tree)
}
- def finishGetterSetter(typer: Typer, stat: Tree): List[Tree] = stat match {
+
+ 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
@@ -211,9 +227,19 @@ trait MethodSynthesis {
map (acc => atPos(vd.pos.focus)(acc derive annotations))
filterNot (_ eq EmptyTree)
)
+ 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))
@@ -234,35 +260,59 @@ 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. */
+
+ /** 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
-
- /** The tree, symbol, and type completer for the synthetic member. */
+
+ /** 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 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 enclClass = basisSym.enclClass
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.
@@ -286,22 +336,6 @@ 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.flagString, basisSym.accurateKindString, basisSym.getterName.decode)
+ " (" + derivedSym + ")\n " + result)
@@ -310,7 +344,7 @@ trait MethodSynthesis {
}
final def derive(initial: List[AnnotationInfo]): Tree = {
validate()
- derivedSym setAnnotations deriveAnnotations(initial)
+ derivedSym setAnnotations deriveAnnotations(initial, category, keepClean)
logDerived(derivedTree)
}
}
@@ -334,15 +368,21 @@ trait MethodSynthesis {
/** A synthetic method which performs the implicit conversion implied by
* the declaration of an implicit class. Yet to be written.
*/
- case class ImplicitClassConverter(tree: ClassDef) extends DerivedFromClassDef {
- def completer(sym: Symbol): Type = ???
- def derivedSym: Symbol = ???
- def derivedTree: DefDef = ???
- def flagsExtra: Long = ???
- def flagsMask: Long = ???
- def name: TermName = ???
- }
-
+ 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
@@ -373,7 +413,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 2539091966..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
@@ -624,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) {
@@ -651,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,
@@ -666,10 +653,12 @@ trait Namers extends MethodSynthesis {
"If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead."
)
}
-
+
// Suggested location only.
- if (mods.isImplicit)
- enterImplicitClass(tree)
+ if (mods.isImplicit) {
+ log("enter implicit wrapper "+tree+", owner = "+owner)
+ enterImplicitWrapper(tree)
+ }
}
// this logic is needed in case typer was interrupted half
@@ -684,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
}
@@ -809,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)
@@ -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?)
@@ -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
@@ -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 2573678f8c..be269cf4b2 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],
@@ -47,7 +48,7 @@ trait NamesDefaults { self: Analyzer =>
/** @param pos maps indices from new to old (!) */
def reorderArgsInv[T: ClassManifest](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 */
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index aff8368f75..1fd9f6fc13 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
@@ -118,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.
@@ -130,10 +132,10 @@ 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)
+ assert(phase.id < currentRun.uncurryPhase.id, phase)
val scrutSym = freshSym(scrut.pos, pureType(scrutType)) setFlag SYNTH_CASE
// pt = Any* occurs when compiling test/files/pos/annotDepMethType.scala with -Xexperimental
@@ -157,12 +159,12 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
(caseScrutSym, propagateSubstitution(translateCase(caseScrutSym, pt)(caseDef), EmptySubstitution))
}
- for(cases <- emitTypeSwitch(bindersAndCases, pt) toList;
+ 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 = if (swatches nonEmpty) swatches else {
+ 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))}
@@ -819,13 +821,34 @@ 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))
+ // 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)
}
@@ -865,7 +888,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
@@ -873,7 +896,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
@@ -1082,22 +1105,14 @@ 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
+ // 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)
// 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)
- }
-
- def _isInstanceOf(b: Symbol, tp: Type): Tree = gen.mkIsInstanceOf(REF(b), /*repackExistential*/(tp), true, false)
- // { val tpX = /*repackExistential*/(tp)
+ 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 = {
@@ -1635,7 +1650,7 @@ class Foo(x: Other) { x._1 } // no error in this order
*/
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 SYNTH_CASE
- val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe
+ 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 SYNTH_CASE
@@ -1649,7 +1664,11 @@ class Foo(x: Other) { x._1 } // no error in this order
def catchAll = matchFailGen map { matchFailGen =>
val scrutRef = if(scrutSym ne NoSymbol) REF(scrutSym) else EmptyTree // for alternatives
- LabelDef(nextCase, Nil, matchEnd APPLY (_asInstanceOf(matchFailGen(scrutRef), restpe))) // 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
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 806ee480f0..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.
@@ -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.
@@ -356,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 {
@@ -416,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) {
@@ -1059,12 +1066,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
// equals.
def isUsingWarnableEquals = {
val m = receiver.info.member(nme.equals_)
- def n = actual.info.member(nme.equals_)
- ( (m == Object_equals)
- || (m == Any_equals)
- || (m.isSynthetic && m.owner.isCase && !n.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
@@ -1087,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)
@@ -1097,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 _ =>
}
@@ -1648,9 +1676,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
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 = false
+ inPattern = old
res
case _ =>
super.transform(result)
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index da87d38ab0..868c236ee9 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)
@@ -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/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index 8895905ca7..4319dd10c7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -14,8 +14,9 @@ import util.returning
abstract class TreeCheckers extends Analyzer {
import global._
- private val everything = ListBuffer[(Phase, Map[Tree, (Symbol, Type)])]()
+ 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 {
@@ -28,7 +29,7 @@ abstract class TreeCheckers extends Analyzer {
}
}
- private def classstr(x: AnyRef) = x.getClass.getName split """\\.|\\$""" last;
+ 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
@@ -49,12 +50,13 @@ 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 inPrev(sym: Symbol) = {
@@ -119,10 +121,8 @@ abstract class TreeCheckers extends Analyzer {
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 _ => ()
}
}
@@ -130,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 }
@@ -147,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
}
@@ -172,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) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 3233b7b07c..38c2c5f719 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -456,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 f558e0afc7..043e826d32 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -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
@@ -181,7 +182,10 @@ 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)
@@ -508,7 +512,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.
*/
@@ -671,7 +674,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
}
@@ -730,6 +733,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
@@ -769,7 +824,7 @@ 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,
@@ -813,7 +868,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)
@@ -1008,12 +1063,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 _ =>
@@ -1026,13 +1082,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 (context.macrosEnabled && // when macros are enabled
+ inExprModeButNot(mode, FUNmode) && !tree.isDef && // and typechecking application
+ tree.symbol != null && tree.symbol.isTermMacro) // of a term macro
+ macroExpand(this, tree, pt)
else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode))
adaptConstrPattern()
else if (inAllModes(mode, EXPRmode | FUNmode) &&
@@ -1169,7 +1222,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
&& !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
@@ -1653,7 +1706,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)
@@ -1906,8 +1959,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)
}
@@ -1937,6 +1992,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
}
@@ -1968,6 +2029,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
}
@@ -2111,7 +2176,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,
@@ -2147,13 +2212,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def adaptCase(cdef: CaseDef, mode: Int, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe))
- def prepareTranslateMatch(selector0: Tree, cases: List[CaseDef], mode: Int, resTp: Type) = {
+ 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)
+ val selectorTp = packCaptured(selector1.tpe.widen.withoutAnnotations)
val casesTyped = typedCases(cases, selectorTp, resTp)
val caseTypes = casesTyped map (c => packedType(c, context.owner).deconst)
@@ -2164,7 +2229,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
(selector1, selectorTp, casesAdapted, ownType, doTranslation)
}
- def translateMatch(selector1: Tree, selectorTp: Type, casesAdapted: List[CaseDef], ownType: Type, doTranslation: Boolean, matchFailGen: Option[Tree => Tree] = None) = {
+ 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
@@ -2174,10 +2239,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
Match(selector1, casesAdapted) setType ownType // setType of the Match to avoid recursing endlessly
} else {
val scrutType = repeatedToSeq(elimAnonymousClass(selectorTp))
- // we've packed the type for each case in prepareTranslateMatch so that if all cases have the same existential case, we get a clean lub
+ // 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
- MatchTranslator(this).translateMatch(selector1, casesAdapted, repeatedToSeq(ownType.skolemizeExistential(context.owner, context.tree)), scrutType, matchFailGen)
+ // 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)
}
}
@@ -2202,7 +2269,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
vparams map {p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe}
}
- def mkParams(methodSym: Symbol, formals: List[Type]/* = deriveFormals*/) = {
+ def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = {
selOverride match {
case None if targs.isEmpty => MissingParameterTypeAnonMatchError(tree, pt); (Nil, EmptyTree)
case None =>
@@ -2212,7 +2279,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
(ps, sel)
case Some((vparams, sel)) =>
val newParamSyms = (vparams, formals).zipped map {(p, tp) =>
- methodSym.newValueParameter(p.name, focusPos(p.pos), SYNTHETIC) setInfo tp
+ methodSym.newValueParameter(p.name, p.pos.focus, SYNTHETIC) setInfo tp
}
(newParamSyms, sel.duplicate)
@@ -2228,7 +2295,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// 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, FINAL)
- val (paramSyms, selector) = mkParams(methodSym, deriveFormals)
+ val (paramSyms, selector) = mkParams(methodSym)
if (selector eq EmptyTree) EmptyTree
else {
@@ -2237,7 +2304,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
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.prepareTranslateMatch(selector, cases, mode, ptRes)
+ val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, cases, mode, ptRes)
val methFormals = paramSyms map (_.tpe)
val parents = List(abstractFunctionType(methFormals, resTp), SerializableClass.tpe)
@@ -2245,7 +2312,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
anonClass setInfo ClassInfoType(parents, newScope, anonClass)
methodSym setInfoAndEnter MethodType(paramSyms, resTp)
- DefDef(methodSym, methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation))
+ DefDef(methodSym, methodBodyTyper.translatedMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation))
}
}
@@ -2267,7 +2334,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
else {
// applyOrElse's default parameter:
val B1 = methodSym newTypeParameter(newTypeName("B1")) setInfo TypeBounds.empty //lower(resTp)
- val default = methodSym newValueParameter(newTermName("default"), focusPos(tree.pos), SYNTHETIC) setInfo functionType(List(A1.tpe), B1.tpe)
+ 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))
@@ -2275,7 +2342,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
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.prepareTranslateMatch(selector, cases, mode, ptRes)
+ val (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.typedMatch(selector, cases, mode, ptRes)
anonClass setInfo ClassInfoType(parents(List(argTp, resTp)), newScope, anonClass)
B1 setInfo TypeBounds.lower(resTp)
@@ -2284,7 +2351,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// use applyOrElse's first parameter since the scrut's type has been widened
def doDefault(scrut_ignored: Tree) = REF(default) APPLY (REF(x))
- val body = methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, B1.tpe, doTranslation, Some(doDefault))
+ val body = methodBodyTyper.translatedMatch(selector1, selectorTp, casesAdapted, B1.tpe, doTranslation, Some(doDefault))
DefDef(methodSym, body)
}
@@ -2292,15 +2359,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def isDefinedAtMethod = {
val methodSym = anonClass.newMethod(nme.isDefinedAt, tree.pos, FINAL)
- val (paramSyms, selector) = mkParams(methodSym, deriveFormals)
+ 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 (selector1, selectorTp, casesAdapted, resTp, doTranslation) = methodBodyTyper.prepareTranslateMatch(selector, casesTrue, mode, BooleanClass.tpe)
- val body = methodBodyTyper.translateMatch(selector1, selectorTp, casesAdapted, resTp, doTranslation, Some(scrutinee => FALSE_typed))
+ 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))
DefDef(methodSym, body)
}
@@ -2361,29 +2428,21 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
- fun.body match {
- case Match(sel, cases) if opt.virtPatmat =>
- // 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, pt, Some((fun.vparams, sel)))
- case _ =>
- 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)
- treeCopy.Function(fun, vparams, body1).setType(funtpe)
+ 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)
+ treeCopy.Function(fun, vparams, body1).setType(funtpe)
}
}
@@ -2474,54 +2533,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.hasDefault &&
- !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)
@@ -2551,7 +2609,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 = {
@@ -2575,7 +2636,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)
}
@@ -2737,6 +2799,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
@@ -2755,8 +2822,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)
}
@@ -2764,6 +2833,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 {
@@ -2802,7 +2872,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
@@ -3111,7 +3182,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
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))
@@ -3151,7 +3222,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"+
@@ -3423,7 +3494,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
@@ -3437,7 +3609,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+")")
@@ -3451,10 +3623,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) {
@@ -3497,11 +3685,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 {
@@ -3510,7 +3698,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
}
}
@@ -3580,10 +3768,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()
}
@@ -3598,12 +3793,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) =
// 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 && thenTp =:= elseTp) (thenp1.tpe, false) // use unpacked type
+ 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))
@@ -3615,13 +3814,9 @@ 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) {
- val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = prepareTranslateMatch(selector, cases, mode, pt)
- typed(translateMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt)
- } else typedMatchAnonFun(tree, cases, mode, pt)
- } else if (selector == EmptyTree) {
+ // translation only happens when (selector != EmptyTree) && !isPastTyper && opt.virtPatmat
+ def typedTranslatedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = {
+ if (selector == EmptyTree) {
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) {
@@ -3632,7 +3827,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val selector1 = atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) }
val body = treeCopy.Match(tree, selector1, cases)
typed1(atPos(tree.pos) { Function(params, body) }, mode, pt)
- } else {
+ } else if (!((phase.id < currentRun.uncurryPhase.id) && opt.virtPatmat)) {
val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType))
var cases1 = typedCases(cases, packCaptured(selector1.tpe.widen), pt)
val (owntype, needAdapt) = ptOrLub(cases1 map (_.tpe))
@@ -3640,6 +3835,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
cases1 = cases1 map (adaptCase(_, mode, owntype))
}
treeCopy.Match(tree, selector1, cases1) setType owntype
+ } else {
+ val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt)
+ typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt)
}
}
@@ -3676,6 +3874,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
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
@@ -4030,7 +4229,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)
@@ -4038,6 +4240,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) }
@@ -4045,16 +4248,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) {
@@ -4113,7 +4310,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
@@ -4504,7 +4701,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)
@@ -4520,7 +4717,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
catches1 = catches1 map (adaptCase(_, mode, owntype))
}
- if(!isPastTyper && opt.virtPatmat) {
+ if((phase.id < currentRun.uncurryPhase.id) && opt.virtPatmat) {
catches1 = (MatchTranslator(this)).translateTry(catches1, owntype, tree.pos)
}
@@ -4534,7 +4731,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)
@@ -4608,18 +4816,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 {
+ // 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 manif = getManifestTree(tree, manifType, false)
- new ApplyToImplicitArgs(Select(manif, if (level == 1) "newArray" else "newArray"+level), args)
+ val tag = resolveClassTag(tree, tagType)
+ if (tag.isEmpty) MissingClassTagError(tree, tagType)
+ else new ApplyToImplicitArgs(Select(tag, nme.newArray), args)
}
typed(newArrayApp, mode, pt)
- }
case tree1 =>
tree1
}
@@ -4666,6 +4873,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
@@ -4679,7 +4891,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 (
@@ -4708,9 +4923,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() =>
@@ -4760,6 +4977,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
)
@@ -4863,7 +5082,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 */
@@ -4916,9 +5150,40 @@ 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 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 transformedOr(tree: Tree, op: => Tree): Tree = transformed.get(tree) match {
+ case Some(tree1) => transformed -= tree; tree1
+ case None => op
}
def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match {
@@ -4926,21 +5191,36 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case None => typed(tree, mode, pt)
}
- def findManifest(tp: Type, full: Boolean) = beforeTyper {
+ // `tree` is only necessary here for its position
+ // but that's invaluable for error reporting, so I decided to include it into this method's contract
+ // before passing EmptyTree, please, consider passing something meaningful first
+ def resolveClassTag(tree: Tree, tp: Type): Tree = beforeTyper {
inferImplicit(
EmptyTree,
- appliedType((if (full) FullManifestClass else PartialManifestClass).typeConstructor, List(tp)),
- true, false, context)
+ appliedType(ClassTagClass.typeConstructor, List(tp)),
+ /*reportAmbiguous =*/ true,
+ /*isView =*/ false,
+ /*context =*/ context,
+ /*saveAmbiguousDivergent =*/ true,
+ /*pos =*/ tree.pos
+ ).tree
}
- 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
- }
+ // `tree` is only necessary here for its position
+ // but that's invaluable for error reporting, so I decided to include it into this method's contract
+ // before passing EmptyTree, please, consider passing something meaningful first
+ def resolveTypeTag(tree: Tree, pre: Type, tp: Type, full: Boolean): Tree = beforeTyper {
+ inferImplicit(
+ EmptyTree,
+ appliedType(singleType(pre, pre member (if (full) ConcreteTypeTagClass else TypeTagClass).name), List(tp)),
+ /*reportAmbiguous =*/ true,
+ /*isView =*/ false,
+ /*context =*/ context,
+ /*saveAmbiguousDivergent =*/ true,
+ /*pos =*/ tree.pos
+ ).tree
}
+
/*
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..5dd9ce0e02 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -27,9 +27,9 @@ object ClassPath {
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](clazz: Class[T]) = new ClassAndJarInfo()(ClassManifest[T](clazz))
def info[T: ClassManifest] = new ClassAndJarInfo[T]
- def locate[T: ClassManifest] = info[T] rootClasspath
+ 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)
@@ -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 bc74717366..208cd5703a 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -33,62 +33,32 @@ object Position {
}
}
-/**
- * A tree does not directly store a Position. It stores a TreeAnnotation, which /typically/ is a Position.
- *
- * A TreeAnnotion may encompass more than just a Position, though, depending on the exact subclass of TreeAnnotation.
- */
-trait TreeAnnotation {
- def pos: 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
-/** 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 TreeAnnotation {
- def pos: Position = this
+ /** 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.
@@ -134,74 +104,74 @@ trait Position extends TreeAnnotation {
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")
@@ -219,11 +189,11 @@ trait Position extends TreeAnnotation {
* 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+"]"
}
@@ -254,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
@@ -265,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+"]"
}
@@ -289,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 {
@@ -301,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
}
@@ -311,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..700fe0c1a6 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 {
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/package.scala b/src/compiler/scala/tools/reflect/package.scala
index 8f5e099fbf..f5c836a4e9 100644
--- a/src/compiler/scala/tools/reflect/package.scala
+++ b/src/compiler/scala/tools/reflect/package.scala
@@ -27,7 +27,7 @@ package object reflect {
}
}
- def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest.classType(clazz))
+ def zeroOfClass(clazz: Class[_]) = zeroOf(Manifest(ClassManifest(clazz).tpe))
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
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
index 67ea6e15f0..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)
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index a6737573ea..0975f16c6e 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)
@@ -412,18 +443,29 @@ 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", "}")))
+
+ if (anfStats.nonEmpty && (anfStats forall gen.hasSynthCaseSymbol)) {
+ val (prologue, rest) = (anfStats :+ anfExpr) span (s => !s.isInstanceOf[DefDef]) // find first case
+ // val (defs, calls) = rest partition (_.isInstanceOf[DefDef])
+ if (rest nonEmpty){
+ val stats = prologue ++ rest.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..2db4054ef5 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
@@ -203,12 +203,16 @@ abstract class SelectiveCPSTransform extends PluginComponent with
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) }
+ 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/library/scala/Array.scala b/src/library/scala/Array.scala
index 99c54ce58c..5b8ebde308 100644
--- a/src/library/scala/Array.scala
+++ b/src/library/scala/Array.scala
@@ -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 a ClassManifest 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..a5e1dc7fe7 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`.
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala
index dc67d32ba0..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. */
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/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 2d87ccb261..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 =>
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index b5006e7948..15e007528b 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.
@@ -99,17 +100,40 @@ object Predef extends LowPriorityImplicits {
// def AnyRef = scala.AnyRef
// Manifest types, companions, and incantations for summoning
+ @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0")
type ClassManifest[T] = scala.reflect.ClassManifest[T]
- type Manifest[T] = scala.reflect.Manifest[T]
+ @deprecated("OptManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0")
type OptManifest[T] = scala.reflect.OptManifest[T]
+ @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0")
+ type Manifest[T] = scala.reflect.Manifest[T]
+ @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0")
val ClassManifest = scala.reflect.ClassManifest
- val Manifest = scala.reflect.Manifest
- val NoManifest = scala.reflect.NoManifest
+ // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies.
+ @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0")
+ lazy val Manifest = scala.reflect.Manifest // needs to be lazy, because requires scala.reflect.mirror instance
+ @deprecated("NoManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0")
+ lazy val NoManifest = scala.reflect.NoManifest // needs to be lazy, because requires scala.reflect.mirror instance
def manifest[T](implicit m: Manifest[T]) = m
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 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 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`
@@ -325,30 +349,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/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/Tuple2.scala b/src/library/scala/Tuple2.scala
index b1befca4fa..37ab564c3c 100644
--- a/src/library/scala/Tuple2.scala
+++ b/src/library/scala/Tuple2.scala
@@ -23,7 +23,7 @@ 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.
@@ -54,6 +54,16 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s
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)
+ /**
+ * @define coll zipped
+ * @define Coll Zipped
+ * @define orderDependent
+ * @define orderDependentFold
+ * @define mayNotTerminateInf
+ * @define willNotTerminateInf
+ * @define collectExample
+ * @define undefinedorder
+ */
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)
diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala
index 0d5399308b..cd5ee23757 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],
@@ -53,6 +53,17 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3)
w3: T3 => ILike[El3, Repr3]): Zipped[Repr1, El1, Repr2, El2, Repr3, El3]
= new Zipped[Repr1, El1, Repr2, El2, Repr3, El3](_1, _2, _3)
+ /**
+ * @define coll zipped
+ * @define Coll Zipped
+ * @define orderDependent
+ * @define orderDependentFold
+ * @define mayNotTerminateInf
+ * @define willNotTerminateInf
+ * @define collectExample
+ * @define undefinedorder
+ * @define thatInfo The class of the returned collection.
+ */
class Zipped[+Repr1, +El1, +Repr2, +El2, +Repr3, +El3](coll1: TLike[El1, Repr1],
coll2: ILike[El2, Repr2],
coll3: ILike[El3, Repr3]) {
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/meta/companionClass.scala b/src/library/scala/annotation/meta/companionClass.scala
new file mode 100644
index 0000000000..8e53f6caf9
--- /dev/null
+++ b/src/library/scala/annotation/meta/companionClass.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 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/library/scala/reflect/NoManifest.scala b/src/library/scala/annotation/meta/companionObject.scala
index 191e46ae39..d329df5c42 100644
--- a/src/library/scala/reflect/NoManifest.scala
+++ b/src/library/scala/annotation/meta/companionObject.scala
@@ -1,15 +1,14 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
+package scala.annotation.meta
-package scala.reflect
-
-/** One of the branches of an [[scala.reflect.OptManifest]].
- */
-object NoManifest extends OptManifest[Nothing] with Serializable {
- override def toString = "<?>"
-}
+/**
+ * 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/library/scala/reflect/OptManifest.scala b/src/library/scala/annotation/meta/languageFeature.scala
index 2a955deb2c..23acc01b51 100644
--- a/src/library/scala/reflect/OptManifest.scala
+++ b/src/library/scala/annotation/meta/languageFeature.scala
@@ -1,17 +1,13 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
+package scala.annotation.meta
-package scala.reflect
-
-/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]].
- *
- * It is either a `Manifest` or the value `NoManifest`.
- *
- * @author Martin Odersky
+/**
+ * An annotation giving particulars for a language feature in object `scala.language`.
*/
-trait OptManifest[+T] extends Serializable
+final class languageFeature(feature: String, enableRequired: Boolean) extends annotation.StaticAnnotation
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/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/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/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..e68ef9e4de 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.
@@ -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/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/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala
index e05bfc41cd..bde13f2830 100644
--- a/src/library/scala/collection/convert/DecorateAsJava.scala
+++ b/src/library/scala/collection/convert/DecorateAsJava.scala
@@ -12,6 +12,8 @@ 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.
diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala
index 722f0b9af9..b170d8d139 100644
--- a/src/library/scala/collection/convert/DecorateAsScala.scala
+++ b/src/library/scala/collection/convert/DecorateAsScala.scala
@@ -12,6 +12,7 @@ package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import Decorators._
import WrapAsScala._
+import language.implicitConversions
trait DecorateAsScala {
/**
diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala
index cdec72b9fe..ecf91deb3a 100644
--- a/src/library/scala/collection/convert/WrapAsJava.scala
+++ b/src/library/scala/collection/convert/WrapAsJava.scala
@@ -11,6 +11,7 @@ package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import Wrappers._
+import language.implicitConversions
trait WrapAsJava {
/**
diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala
index 56e13b2105..14c64695ff 100644
--- a/src/library/scala/collection/convert/WrapAsScala.scala
+++ b/src/library/scala/collection/convert/WrapAsScala.scala
@@ -11,6 +11,7 @@ package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import Wrappers._
+import language.implicitConversions
trait WrapAsScala {
/**
diff --git a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala b/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala
index e54ce9cdbf..e418ca623f 100644
--- a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala
+++ b/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala
@@ -9,6 +9,8 @@
package scala.collection
package generic
+import language.higherKinds
+
/** A template for companion objects of `ClassManifestTraversable` and
* subclasses thereof.
*
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/GenericClassManifestCompanion.scala
index 546e82fb4a..f357091361 100644
--- a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala
+++ b/src/library/scala/collection/generic/GenericClassManifestCompanion.scala
@@ -10,6 +10,7 @@ package scala.collection
package generic
import mutable.Builder
+import language.higherKinds
/** This class represents companions of classes which require ClassManifests
* for their element types.
diff --git a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala b/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala
index 12b5a495f0..1a5db4bab2 100644
--- a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala
+++ b/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala
@@ -11,6 +11,7 @@ package generic
import mutable.Builder
import annotation.unchecked.uncheckedVariance
+import language.higherKinds
/** This trait represents collections classes which require class
* manifests for their element types.
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/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/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 fc4e7bf0a8..06f09f359f 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.
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/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala
index f0e4c79abf..e396b0695e 100644
--- a/src/library/scala/collection/mutable/ArrayBuilder.scala
+++ b/src/library/scala/collection/mutable/ArrayBuilder.scala
@@ -33,8 +33,22 @@ object ArrayBuilder {
* @tparam T type of the elements for the array builder, with a `ClassManifest` context bound.
* @return a new empty array builder.
*/
- def make[T: ClassManifest](): ArrayBuilder[T] =
- implicitly[ClassManifest[T]].newArrayBuilder()
+ def make[T: ClassManifest](): ArrayBuilder[T] = {
+ val manifest = implicitly[ClassManifest[T]]
+ val erasure = manifest.erasure
+ 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]()(manifest.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]]
+ }
+ }
/** A class for array builders for arrays of reference types.
*
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 5f7c508181..875030ade0 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -39,8 +39,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza
private def rowBuilder[U]: Builder[U, Array[U]] =
Array.newBuilder(
- ClassManifest.fromClass(
- repr.getClass.getComponentType.getComponentType.asInstanceOf[Predef.Class[U]]))
+ ClassManifest[U](
+ repr.getClass.getComponentType.getComponentType))
override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) {
var l = math.min(len, repr.length)
@@ -65,7 +65,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza
*/
def flatten[U, To](implicit asTrav: T => collection.Traversable[U], m: ClassManifest[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
@@ -87,8 +87,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza
}
}
val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(
- ClassManifest.fromClass(
- repr.getClass.getComponentType.asInstanceOf[Predef.Class[Array[U]]]))
+ ClassManifest[Array[U]](
+ repr.getClass.getComponentType))
for (b <- bs) bb += b.result
bb.result
}
@@ -110,7 +110,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))
+ ClassManifest[T](repr.getClass.getComponentType))
def length: Int = repr.length
def apply(index: Int): T = repr(index)
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/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/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala
index 4287bac249..fac4eb77bb 100644
--- a/src/library/scala/collection/mutable/WrappedArray.scala
+++ b/src/library/scala/collection/mutable/WrappedArray.scala
@@ -112,7 +112,7 @@ 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 elemManifest = ClassManifest[T](array.getClass.getComponentType)
def length: Int = array.length
def apply(index: Int): T = array(index).asInstanceOf[T]
def update(index: Int, elem: T) { array(index) = elem }
diff --git a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
index 9771a45a28..fce65468e9 100644
--- a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
+++ b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
@@ -28,7 +28,19 @@ class WrappedArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, Wrap
private var size: Int = 0
private def mkArray(size: Int): WrappedArray[A] = {
- val newelems = manifest.newWrappedArray(size)
+ val erasure = manifest.erasure
+ 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](manifest.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..5bf338f560 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]`.
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/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/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala
index 789738e6ec..fafd7fd238 100644
--- a/src/library/scala/concurrent/ConcurrentPackageObject.scala
+++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala
@@ -12,7 +12,7 @@ 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.
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index 04f56950f1..f5f0c5cdfd 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -25,6 +25,7 @@ import scala.annotation.tailrec
import scala.collection.mutable.Stack
import scala.collection.mutable.Builder
import scala.collection.generic.CanBuildFrom
+import language.higherKinds
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/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/util/Duration.scala b/src/library/scala/concurrent/util/Duration.scala
index 33d034da76..15a546de10 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))
}
@@ -351,6 +300,12 @@ class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration {
def toUnit(u: TimeUnit) = long2double(toNanos) / 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"
@@ -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..25625054ee
--- /dev/null
+++ b/src/library/scala/concurrent/util/duration/package.scala
@@ -0,0 +1,30 @@
+package scala.concurrent.util
+
+import java.util.concurrent.TimeUnit
+
+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)
+} \ No newline at end of file
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..2837187d48
--- /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 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 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 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 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 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 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 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 cb42b76b51..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
/**
@@ -292,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 dbec30b2fe..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
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..1f4e3c9865 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
*/
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/reflect/ArrayTag.scala b/src/library/scala/reflect/ArrayTag.scala
new file mode 100644
index 0000000000..8df7fe5f4e
--- /dev/null
+++ b/src/library/scala/reflect/ArrayTag.scala
@@ -0,0 +1,19 @@
+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.
+ *
+ * Scala library provides a standard implementation of this trait,
+ * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T.
+ *
+ * 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.
+ */
+@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
deleted file mode 100644
index 37be067614..0000000000
--- a/src/library/scala/reflect/ClassManifest.scala
+++ /dev/null
@@ -1,263 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-/* [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 }
-import java.lang.{ Class => jClass }
-
-/** A `ClassManifest[T]` is an opaque descriptor for type `T`.
- * It is used by the compiler to preserve information necessary
- * for instantiating `Arrays` in those cases where the element type
- * is unknown at compile time.
- *
- * The type-relation operators make an effort to present a more accurate
- * picture than can be realized with erased types, but they should not be
- * relied upon to give correct answers. In particular they are likely to
- * 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 {
- /** 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 && {
- val next = left.head
- val supers = next.getInterfaces.toSet ++ Option(next.getSuperclass)
- supers(sup) || {
- val xs = left ++ supers filterNot seen
- loop(xs - next, seen + next)
- }
- }
- }
- loop(Set(sub), Set())
- }
-
- private def subargs(args1: List[OptManifest[_]], args2: List[OptManifest[_]]) = (args1 corresponds args2) {
- // !!! [Martin] this is wrong, need to take variance into account
- case (x: ClassManifest[_], y: ClassManifest[_]) => x <:< y
- case (x, y) => (x eq NoManifest) && (y eq NoManifest)
- }
-
- /** Tests whether the type represented by this manifest is a subtype
- * of the type represented by `that` manifest, subject to the limitations
- * described in the header.
- */
- def <:<(that: ClassManifest[_]): Boolean = {
- // All types which could conform to these types will override <:<.
- def cannotMatch = {
- import Manifest._
- that.isInstanceOf[AnyValManifest[_]] || (that eq AnyVal) || (that eq Nothing) || (that eq Null)
- }
-
- // This is wrong, and I don't know how it can be made right
- // without more development of Manifests, due to arity-defying
- // relationships like:
- //
- // List[String] <: AnyRef
- // Map[Int, Int] <: Iterable[(Int, Int)]
- //
- // Given the manifest for Map[A, B] how do I determine that a
- // supertype has single type argument (A, B) ? I don't see how we
- // can say whether X <:< Y when type arguments are involved except
- // when the erasure is the same, even before considering variance.
- !cannotMatch && {
- // this part is wrong for not considering variance
- if (this.erasure == that.erasure)
- subargs(this.typeArguments, that.typeArguments)
- // this part is wrong for punting unless the rhs has no type
- // arguments, but it's better than a blindfolded pinata swing.
- else
- that.typeArguments.isEmpty && subtype(this.erasure, that.erasure)
- }
- }
-
- /** Tests whether the type represented by this manifest is a supertype
- * of the type represented by `that` manifest, subject to the limitations
- * described in the header.
- */
- def >:>(that: ClassManifest[_]): Boolean =
- that <:< this
-
- def canEqual(other: Any) = other match {
- case _: ClassManifest[_] => true
- case _ => false
- }
-
- /** Tests whether the type represented by this manifest is equal to
- * the type represented by `that` manifest, subject to the limitations
- * described in the header.
- */
- override def equals(that: Any): Boolean = that match {
- case m: ClassManifest[_] => (m canEqual this) && (this.erasure == m.erasure)
- case _ => false
- }
- override def hashCode = this.erasure.##
-
- protected def arrayClass[T](tp: jClass[_]): jClass[Array[T]] =
- java.lang.reflect.Array.newInstance(tp, 0).getClass.asInstanceOf[jClass[Array[T]]]
-
- def arrayManifest: ClassManifest[Array[T]] =
- ClassManifest.classType[Array[T]](arrayClass[T](erasure), this)
-
- def newArray(len: Int): Array[T] =
- java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]]
-
- def newArray2(len: Int): Array[Array[T]] =
- java.lang.reflect.Array.newInstance(arrayClass[T](erasure), len)
- .asInstanceOf[Array[Array[T]]]
-
- def newArray3(len: Int): Array[Array[Array[T]]] =
- java.lang.reflect.Array.newInstance(arrayClass[Array[T]](arrayClass[T](erasure)), len)
- .asInstanceOf[Array[Array[Array[T]]]]
-
- def newArray4(len: Int): Array[Array[Array[Array[T]]]] =
- java.lang.reflect.Array.newInstance(arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure))), len)
- .asInstanceOf[Array[Array[Array[Array[T]]]]]
-
- def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] =
- java.lang.reflect.Array.newInstance(arrayClass[Array[Array[Array[T]]]](arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure)))), len)
- .asInstanceOf[Array[Array[Array[Array[Array[T]]]]]]
-
- def newWrappedArray(len: Int): WrappedArray[T] =
- // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests
- new WrappedArray.ofRef[T with AnyRef](newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]]
-
- def newArrayBuilder(): ArrayBuilder[T] =
- // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests
- new ArrayBuilder.ofRef[T with AnyRef]()(this.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]]
-
- def typeArguments: List[OptManifest[_]] = List()
-
- protected def argString =
- if (typeArguments.nonEmpty) typeArguments.mkString("[", ", ", "]")
- else if (erasure.isArray) "["+ClassManifest.fromClass(erasure.getComponentType)+"]"
- else ""
-}
-
-/** The object `ClassManifest` defines factory methods for manifests.
- * It is intended for use by the compiler and should not be used in client code.
- */
-object ClassManifest {
- val Byte = Manifest.Byte
- val Short = Manifest.Short
- val Char = Manifest.Char
- val Int = Manifest.Int
- val Long = Manifest.Long
- val Float = Manifest.Float
- val Double = Manifest.Double
- val Boolean = Manifest.Boolean
- val Unit = Manifest.Unit
- val Any = Manifest.Any
- val Object = Manifest.Object
- val AnyVal = Manifest.AnyVal
- val Nothing = Manifest.Nothing
- val Null = Manifest.Null
-
- def fromClass[T](clazz: jClass[T]): ClassManifest[T] = clazz match {
- case java.lang.Byte.TYPE => Byte.asInstanceOf[ClassManifest[T]]
- case java.lang.Short.TYPE => Short.asInstanceOf[ClassManifest[T]]
- case java.lang.Character.TYPE => Char.asInstanceOf[ClassManifest[T]]
- case java.lang.Integer.TYPE => Int.asInstanceOf[ClassManifest[T]]
- case java.lang.Long.TYPE => Long.asInstanceOf[ClassManifest[T]]
- case java.lang.Float.TYPE => Float.asInstanceOf[ClassManifest[T]]
- case java.lang.Double.TYPE => Double.asInstanceOf[ClassManifest[T]]
- case java.lang.Boolean.TYPE => Boolean.asInstanceOf[ClassManifest[T]]
- case java.lang.Void.TYPE => Unit.asInstanceOf[ClassManifest[T]]
- case _ => classType[T with AnyRef](clazz).asInstanceOf[ClassManifest[T]]
- }
-
- def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = Manifest.singleType(value)
-
- /** ClassManifest for the class type `clazz`, where `clazz` is
- * a top-level or static class.
- * @note This no-prefix, no-arguments case is separate because we
- * it's called from ScalaRunTime.boxArray itself. If we
- * 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] =
- 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] =
- 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] =
- new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
-
- def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match {
- case NoManifest => Object.asInstanceOf[ClassManifest[Array[T]]]
- case m: ClassManifest[_] => m.asInstanceOf[ClassManifest[T]].arrayManifest
- }
-
- /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not
- * strictly necessary as it could be obtained by reflection. It was
- * added so that erasure can be calculated without reflection. */
- def abstractType[T](prefix: OptManifest[_], name: String, clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] =
- new ClassManifest[T] {
- def erasure = clazz
- override val typeArguments = args.toList
- override def toString = prefix.toString+"#"+name+argString
- }
-
- /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not
- * strictly necessary as it could be obtained by reflection. It was
- * added so that erasure can be calculated without reflection.
- * todo: remove after next boostrap
- */
- def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] =
- new ClassManifest[T] {
- def erasure = upperbound.erasure
- override val typeArguments = args.toList
- override def toString = prefix.toString+"#"+name+argString
- }
-}
-
-/** 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](
- prefix: Option[OptManifest[_]],
- val erasure: jClass[_],
- override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T]
-{
- override def toString =
- (if (prefix.isEmpty) "" else prefix.get.toString+"#") +
- (if (erasure.isArray) "Array" else erasure.getName) +
- argString
-}
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
new file mode 100644
index 0000000000..7138837f0d
--- /dev/null
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -0,0 +1,168 @@
+package scala.reflect
+
+import java.lang.{ Class => jClass }
+import scala.reflect.{ mirror => rm }
+import language.{implicitConversions, existentials}
+
+/** 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). */
+// 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
+@annotation.implicitNotFound(msg = "No ClassTag available for ${T}")
+abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] {
+ // quick and dirty fix to a deadlock in Predef:
+ // http://groups.google.com/group/scala-internals/browse_thread/thread/977de028a4e75d6f
+ // todo. fix that in a sane way
+ // assert(erasure != null)
+
+ /** A Scala reflection type representing T.
+ * For ClassTags this representation is lossy (in their case tpe is retrospectively constructed from erasure).
+ * For TypeTags and ConcreteTypeTags the representation is almost precise, because they use reification
+ * (information is lost only when T refers to non-locatable symbols, which are then reified as free variables). */
+ def tpe: rm.Type = rm.classToType(erasure)
+
+ /** A Scala reflection symbol representing T. */
+ def symbol: rm.Symbol = rm.classToSymbol(erasure)
+
+ /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */
+ def wrap: ClassTag[Array[T]] = {
+ val arrayClazz = java.lang.reflect.Array.newInstance(erasure, 0).getClass.asInstanceOf[jClass[Array[T]]]
+ ClassTag[Array[T]](arrayClazz)
+ }
+
+ /** 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]]
+ }
+}
+
+object ClassTag {
+ private val ObjectTYPE = classOf[java.lang.Object]
+ private val StringTYPE = classOf[java.lang.String]
+
+ val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte](java.lang.Byte.TYPE) { private def readResolve() = ClassTag.Byte }
+ val Short : ClassTag[scala.Short] = new ClassTag[scala.Short](java.lang.Short.TYPE) { private def readResolve() = ClassTag.Short }
+ val Char : ClassTag[scala.Char] = new ClassTag[scala.Char](java.lang.Character.TYPE) { private def readResolve() = ClassTag.Char }
+ val Int : ClassTag[scala.Int] = new ClassTag[scala.Int](java.lang.Integer.TYPE) { private def readResolve() = ClassTag.Int }
+ val Long : ClassTag[scala.Long] = new ClassTag[scala.Long](java.lang.Long.TYPE) { private def readResolve() = ClassTag.Long }
+ val Float : ClassTag[scala.Float] = new ClassTag[scala.Float](java.lang.Float.TYPE) { private def readResolve() = ClassTag.Float }
+ val Double : ClassTag[scala.Double] = new ClassTag[scala.Double](java.lang.Double.TYPE) { private def readResolve() = ClassTag.Double }
+ val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean](java.lang.Boolean.TYPE) { private def readResolve() = ClassTag.Boolean }
+ val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit](java.lang.Void.TYPE) { private def readResolve() = ClassTag.Unit }
+ val Any : ClassTag[scala.Any] = new ClassTag[scala.Any](ObjectTYPE) { private def readResolve() = ClassTag.Any }
+ val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object](ObjectTYPE) { private def readResolve() = ClassTag.Object }
+ val AnyVal : ClassTag[scala.AnyVal] = new ClassTag[scala.AnyVal](ObjectTYPE) { private def readResolve() = ClassTag.AnyVal }
+ val AnyRef : ClassTag[scala.AnyRef] = new ClassTag[scala.AnyRef](ObjectTYPE) { private def readResolve() = ClassTag.AnyRef }
+ val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing](ObjectTYPE) { private def readResolve() = ClassTag.Nothing }
+ val Null : ClassTag[scala.Null] = new ClassTag[scala.Null](ObjectTYPE) { private def readResolve() = ClassTag.Null }
+ val String : ClassTag[java.lang.String] = new ClassTag[java.lang.String](StringTYPE) { private def readResolve() = ClassTag.String }
+
+ def apply[T](clazz: jClass[_]): ClassTag[T] =
+ clazz 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](clazz) {}
+ }
+
+ def apply[T](tpe: rm.Type): ClassTag[T] =
+ tpe match {
+ case rm.ByteTpe => ClassTag.Byte.asInstanceOf[ClassTag[T]]
+ case rm.ShortTpe => ClassTag.Short.asInstanceOf[ClassTag[T]]
+ case rm.CharTpe => ClassTag.Char.asInstanceOf[ClassTag[T]]
+ case rm.IntTpe => ClassTag.Int.asInstanceOf[ClassTag[T]]
+ case rm.LongTpe => ClassTag.Long.asInstanceOf[ClassTag[T]]
+ case rm.FloatTpe => ClassTag.Float.asInstanceOf[ClassTag[T]]
+ case rm.DoubleTpe => ClassTag.Double.asInstanceOf[ClassTag[T]]
+ case rm.BooleanTpe => ClassTag.Boolean.asInstanceOf[ClassTag[T]]
+ case rm.UnitTpe => ClassTag.Unit.asInstanceOf[ClassTag[T]]
+ case rm.AnyTpe => ClassTag.Any.asInstanceOf[ClassTag[T]]
+ case rm.ObjectTpe => ClassTag.Object.asInstanceOf[ClassTag[T]]
+ case rm.AnyValTpe => ClassTag.AnyVal.asInstanceOf[ClassTag[T]]
+ case rm.AnyRefTpe => ClassTag.AnyRef.asInstanceOf[ClassTag[T]]
+ case rm.NothingTpe => ClassTag.Nothing.asInstanceOf[ClassTag[T]]
+ case rm.NullTpe => ClassTag.Null.asInstanceOf[ClassTag[T]]
+ case rm.StringTpe => ClassTag.String.asInstanceOf[ClassTag[T]]
+ case _ => apply[T](rm.typeToClass(tpe.erasure))
+ }
+
+ implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag)
+}
+
+// this class should not be used directly in client code
+class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) {
+ import scala.collection.mutable.{ WrappedArray, ArrayBuilder }
+
+ @deprecated("Use `tpe` to analyze the underlying type", "2.10.0")
+ def <:<(that: ClassManifest[_]): Boolean = ctag.tpe <:< that.tpe
+
+ @deprecated("Use `tpe` to analyze the underlying type", "2.10.0")
+ def >:>(that: ClassManifest[_]): Boolean = that <:< ctag
+
+ @deprecated("Use `wrap` instead", "2.10.0")
+ def arrayManifest: ClassManifest[Array[T]] = ctag.wrap
+
+ @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0")
+ def newArray2(len: Int): Array[Array[T]] = ctag.wrap.newArray(len)
+
+ @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0")
+ def newArray3(len: Int): Array[Array[Array[T]]] = ctag.wrap.wrap.newArray(len)
+
+ @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0")
+ def newArray4(len: Int): Array[Array[Array[Array[T]]]] = ctag.wrap.wrap.wrap.newArray(len)
+
+ @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0")
+ def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = ctag.wrap.wrap.wrap.wrap.newArray(len)
+
+ @deprecated("Use `@scala.collection.mutable.WrappedArray` object instead", "2.10.0")
+ def newWrappedArray(len: Int): WrappedArray[T] =
+ ctag.erasure match {
+ case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](len)).asInstanceOf[WrappedArray[T]]
+ case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](len)).asInstanceOf[WrappedArray[T]]
+ case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](len)).asInstanceOf[WrappedArray[T]]
+ case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](len)).asInstanceOf[WrappedArray[T]]
+ case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](len)).asInstanceOf[WrappedArray[T]]
+ case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](len)).asInstanceOf[WrappedArray[T]]
+ case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](len)).asInstanceOf[WrappedArray[T]]
+ case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](len)).asInstanceOf[WrappedArray[T]]
+ case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](len)).asInstanceOf[WrappedArray[T]]
+ case _ => new WrappedArray.ofRef[T with AnyRef](ctag.newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]]
+ }
+
+ @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0")
+ def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag)
+
+ @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0")
+ def typeArguments: List[OptManifest[_]] = List()
+}
diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala
new file mode 100644
index 0000000000..ffd1e7a39f
--- /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(mkConsoleReporter(),"")
+ 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, null))
+ , 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, null))
+ if( name == "" ) value
+ else AssignOrNamedArg( Ident(name), value )
+ }.toList
+ )
+ toolbox.runExpr( call )
+ }
+ }
+}
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
deleted file mode 100644
index e5df487be9..0000000000
--- a/src/library/scala/reflect/Manifest.scala
+++ /dev/null
@@ -1,302 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.reflect
-
-import scala.collection.mutable.{ ArrayBuilder, WrappedArray }
-import mirror._
-
-/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use
- * is to give access to the erasure of the type as a `Class` instance, as
- * is necessary for the creation of native `Arrays` if the class is not
- * known at compile time.
- *
- * The type-relation operators `<:<` and `=:=` should be considered
- * approximations only, as there are numerous aspects of type conformance
- * which are not yet adequately represented in manifests.
- *
- * Example usages:
-{{{
- def arr[T] = new Array[T](0) // does not compile
- def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles
- def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding
-
- // Methods manifest, classManifest, and optManifest are in [[scala.Predef]].
- def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U]
- isApproxSubType[List[String], List[AnyRef]] // true
- isApproxSubType[List[String], List[Int]] // false
-
- def methods[T: ClassManifest] = classManifest[T].erasure.getMethods
- def retType[T: ClassManifest](name: String) =
- methods[T] find (_.getName == name) map (_.getGenericReturnType)
-
- retType[Map[_, _]]("values") // Some(scala.collection.Iterable<B>)
-}}}
- *
- */
-@annotation.implicitNotFound(msg = "No Manifest available for ${T}.")
-trait Manifest[T] extends ClassManifest[T] with Equals {
- override def typeArguments: List[Manifest[_]] = Nil
-
- override def arrayManifest: Manifest[Array[T]] =
- Manifest.classType[Array[T]](arrayClass[T](erasure), this)
-
- override def canEqual(that: Any): Boolean = that match {
- case _: Manifest[_] => true
- case _ => false
- }
- /** Note: testing for erasure here is important, as it is many times
- * faster than <:< and rules out most comparisons.
- */
- override def equals(that: Any): Boolean = that match {
- case m: Manifest[_] => (m canEqual this) && (this.erasure == m.erasure) && (this <:< m) && (m <:< this)
- case _ => false
- }
- override def hashCode = this.erasure.##
-}
-
-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)
- override def canEqual(other: Any) = other match {
- case _: AnyValManifest[_] => true
- case _ => false
- }
- override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
- override val hashCode = System.identityHashCode(this)
-}
-
-/** The object `Manifest` defines factory methods for manifests.
- * It is intended for use by the compiler and should not be used
- * in client code.
- */
-object Manifest {
- import mirror.{ definitions => mdefs }
-
- def valueManifests: List[AnyValManifest[_]] =
- List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit)
-
- val Byte: AnyValManifest[Byte] = new AnyValManifest[scala.Byte]("Byte") {
- def erasure = java.lang.Byte.TYPE
- override def newArray(len: Int): Array[Byte] = new Array[Byte](len)
- override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len))
- override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte()
- private def readResolve(): Any = Manifest.Byte
- }
-
- val Short: AnyValManifest[Short] = new AnyValManifest[scala.Short]("Short") {
- def erasure = java.lang.Short.TYPE
- override def newArray(len: Int): Array[Short] = new Array[Short](len)
- override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len))
- override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort()
- private def readResolve(): Any = Manifest.Short
- }
-
- val Char: AnyValManifest[Char] = new AnyValManifest[scala.Char]("Char") {
- def erasure = java.lang.Character.TYPE
- override def newArray(len: Int): Array[Char] = new Array[Char](len)
- override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len))
- override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar()
- private def readResolve(): Any = Manifest.Char
- }
-
- val Int: AnyValManifest[Int] = new AnyValManifest[scala.Int]("Int") {
- def erasure = java.lang.Integer.TYPE
- override def newArray(len: Int): Array[Int] = new Array[Int](len)
- override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len))
- override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt()
- private def readResolve(): Any = Manifest.Int
- }
-
- val Long: AnyValManifest[Long] = new AnyValManifest[scala.Long]("Long") {
- def erasure = java.lang.Long.TYPE
- override def newArray(len: Int): Array[Long] = new Array[Long](len)
- override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len))
- override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong()
- private def readResolve(): Any = Manifest.Long
- }
-
- val Float: AnyValManifest[Float] = new AnyValManifest[scala.Float]("Float") {
- def erasure = java.lang.Float.TYPE
- override def newArray(len: Int): Array[Float] = new Array[Float](len)
- override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len))
- override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat()
- private def readResolve(): Any = Manifest.Float
- }
-
- val Double: AnyValManifest[Double] = new AnyValManifest[scala.Double]("Double") {
- def erasure = java.lang.Double.TYPE
- override def newArray(len: Int): Array[Double] = new Array[Double](len)
- override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len))
- override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble()
- private def readResolve(): Any = Manifest.Double
- }
-
- val Boolean: AnyValManifest[Boolean] = new AnyValManifest[scala.Boolean]("Boolean") {
- def erasure = java.lang.Boolean.TYPE
- override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len)
- override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len))
- override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean()
- private def readResolve(): Any = Manifest.Boolean
- }
-
- val Unit: AnyValManifest[Unit] = new AnyValManifest[scala.Unit]("Unit") {
- def erasure = java.lang.Void.TYPE
- override def newArray(len: Int): Array[Unit] = new Array[Unit](len)
- override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len))
- override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit()
- private def readResolve(): Any = Manifest.Unit
- }
-
- 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"
- }
-
- /** Manifest for the singleton type `value.type`. */
- def singleType[T <: AnyRef](value: AnyRef): Manifest[T] =
- new SingletonTypeManifest[T](value)
-
- /** Manifest for the class type `clazz[args]`, where `clazz` is
- * a top-level or static class.
- * @note This no-prefix, no-arguments case is separate because we
- * it's called from ScalaRunTime.boxArray itself. If we
- * 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: Predef.Class[_]): Manifest[T] =
- new ClassTypeManifest[T](None, clazz, Nil)
-
- /** Manifest for the class type `clazz`, where `clazz` is
- * a top-level or static class and args are its type arguments. */
- def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] =
- new ClassTypeManifest[T](None, clazz, arg1 :: args.toList)
-
- /** Manifest 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: 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 val hashCode = System.identityHashCode(this)
- }
-
- /** Manifest for the class type `clazz[args]`, where `clazz` is
- * a top-level or static class. */
- 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) +
- argString
- }
-
- def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] =
- arg.asInstanceOf[Manifest[T]].arrayManifest
-
- /** Manifest for the abstract type `prefix # name'. `upperBound` is not
- * strictly necessary as it could be obtained by reflection. It was
- * added so that erasure can be calculated without reflection. */
- 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
- }
-
- /** Manifest for the unknown type `_ >: L <: U` in an existential.
- */
- 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) +
- (if (upperBound eq Nothing) "" else " <: "+upperBound)
- }
-
- /** Manifest for the intersection type `parents_0 with ... with parents_n'. */
- 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
- }
-}
diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala
index 510f0819c6..1be46eac55 100644
--- a/src/library/scala/reflect/ReflectionUtils.scala
+++ b/src/library/scala/reflect/ReflectionUtils.scala
@@ -27,7 +27,17 @@ object ReflectionUtils {
case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex))
}
- def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): AnyRef = {
+ 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 +45,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/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala
new file mode 100644
index 0000000000..aede00020f
--- /dev/null
+++ b/src/library/scala/reflect/TagMaterialization.scala
@@ -0,0 +1,155 @@
+package scala.reflect
+
+import api.Universe
+import makro.Context
+import language.implicitConversions
+
+// todo. unfortunately, current type inferencer doesn't infer type parameters of implicit values
+// this means that during macro expansion these macros will get Nothing instead of real T
+// Oh how much I'd love to implement this now, but I have to postpone this until we have a solution for type inference
+
+/** This object is required by the compiler and <b>should not be used in client code</b>. */
+object TagMaterialization {
+ def materializeClassTag[T: c.TypeTag](c: Context): c.Expr[ClassTag[T]] = {
+ import c.mirror._
+ val tpe = implicitly[c.TypeTag[T]].tpe
+ c.materializeClassTag(tpe)
+ }
+
+ def materializeTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.TypeTag[T]] = {
+ import c.mirror._
+ val tpe = implicitly[c.TypeTag[T]].tpe
+ c.materializeTypeTag(tpe, requireConcreteTypeTag = false)
+ }
+
+ def materializeConcreteTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.ConcreteTypeTag[T]] = {
+ import c.mirror._
+ val tpe = implicitly[c.TypeTag[T]].tpe
+ c.materializeTypeTag(tpe, requireConcreteTypeTag = true)
+ }
+
+ private implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils
+
+ private 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"))
+
+ val ReflectPackage = staticModule("scala.reflect.package")
+ val Reflect_mirror = selectTerm(ReflectPackage, "mirror")
+ val ClassTagClass = staticClass("scala.reflect.ClassTag")
+ val ClassTagErasure = selectTerm(ClassTagClass, "erasure")
+ val ClassTagModule = staticModule("scala.reflect.ClassTag")
+ val TypeTagsClass = staticClass("scala.reflect.api.TypeTags")
+ val TypeTagClass = selectType(TypeTagsClass, "TypeTag")
+ val TypeTagTpe = selectTerm(TypeTagClass, "tpe")
+ val TypeTagModule = selectTerm(TypeTagsClass, "TypeTag")
+ val ConcreteTypeTagClass = selectType(TypeTagsClass, "ConcreteTypeTag")
+ val ConcreteTypeTagModule = selectTerm(TypeTagsClass, "ConcreteTypeTag")
+
+ def materializeClassTag(tpe: Type): Tree = {
+ val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror)
+ materializeClassTag(prefix, tpe)
+ }
+
+ def materializeClassTag(prefix: Tree, tpe: Type): Tree = {
+ val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe)))
+ def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule))
+ typetagInScope match {
+ case success if !success.isEmpty && !typetagIsSynthetic(success) =>
+ val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
+ Apply(factory, List(Select(typetagInScope, newTermName("tpe"))))
+ case _ =>
+ val result =
+ tpe match {
+ case coreTpe if coreTags contains coreTpe =>
+ Select(Ident(ClassTagModule), coreTags(coreTpe))
+ case _ =>
+ if (tpe.typeSymbol == ArrayClass) {
+ val componentTpe = tpe.typeArguments(0)
+ val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe)))
+ val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe)
+ Select(componentTag, newTermName("wrap"))
+ } else {
+ // [Eugene] what's the intended behavior? there's no spec on ClassManifests
+ // for example, should we ban Array[T] or should we tag them with Array[AnyRef]?
+ // if its the latter, what should be the result of tagging Array[T] where T <: Int?
+ if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type")
+ val erasure =
+ if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct?
+ else tpe.erasure.normalize // necessary to deal with erasures of HK types
+ val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
+ Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure)))))
+ }
+ }
+ try c.typeCheck(result)
+ catch { case terr @ c.TypeError(pos, msg) => fail(terr) }
+ }
+ }
+
+ def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
+ def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix
+ materializeTypeTag(prefix, tpe, requireConcreteTypeTag)
+ }
+
+ def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
+ val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule
+ val result =
+ tpe match {
+ case coreTpe if coreTags contains coreTpe =>
+ Select(Select(prefix, tagModule.name), coreTags(coreTpe))
+ case _ =>
+ try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)
+ catch {
+ case ex: Throwable =>
+ // [Eugene] cannot pattern match on an abstract type, so had to do this
+ val ex1 = ex
+ if (ex.getClass.toString.endsWith("$ReificationError")) {
+ ex match {
+ case c.ReificationError(pos, msg) =>
+ c.error(pos, msg)
+ EmptyTree
+ }
+ } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) {
+ ex match {
+ case c.UnexpectedReificationError(pos, err, cause) =>
+ if (cause != null) throw cause else throw ex
+ }
+ } else {
+ throw ex
+ }
+ }
+ }
+ try c.typeCheck(result)
+ catch { case terr @ c.TypeError(pos, msg) => fail(terr) }
+ }
+
+ private def fail(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))
+ }
+ }
+}
diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala
new file mode 100644
index 0000000000..9fa5ceb0fb
--- /dev/null
+++ b/src/library/scala/reflect/api/Attachment.scala
@@ -0,0 +1,24 @@
+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.
+ */
+// [Eugene] with the introduction of `attach` and `payload[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
+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
+}
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..ff89a1cd48
--- /dev/null
+++ b/src/library/scala/reflect/api/Exprs.scala
@@ -0,0 +1,51 @@
+/* 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+")"
+ }
+
+ // [Eugene] had to move this to the companion of Tree to make stuff compile. weirdo!
+// object Expr {
+// // would be great if in future this generated an Expr[Magic]
+// // where Magic is a magic untyped type that propagates through the entire quasiquote
+// // and turns off typechecking whenever it's involved
+// // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked
+// // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo
+// implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree)
+// implicit def expr2tree(expr: Expr[_]): Tree = expr.tree
+//
+// // [Eugene] good idea?
+// implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr
+// implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree
+// }
+
+ // [Eugene] even weirder - implicits didn't feel at home in Trees :(
+
+ // would be great if in future this generated an Expr[Magic]
+ // where Magic is a magic untyped type that propagates through the entire quasiquote
+ // and turns off typechecking whenever it's involved
+ // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked
+ // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo
+ // [Martin] I have some doubts whether it's god to have implicit conversions.
+ implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree)(TypeTag.Nothing)
+ implicit def expr2tree(expr: Expr[_]): Tree = expr.tree
+
+ // [Eugene] good idea?
+ // [Martin] probably not.
+ implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr
+ implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree
+}
+
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/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..d92d056751 100755
--- a/src/library/scala/reflect/api/Names.scala
+++ b/src/library/scala/reflect/api/Names.scala
@@ -34,12 +34,12 @@ trait Names {
def toTypeName: TypeName
/** Replaces all occurrences of $op_names in this name by corresponding operator symbols.
- * Example: `foo_+=` becomes `foo_$plus$eq`.
+ * 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_+=`
+ * 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 91f1081b4d..8f01e0ced1 100644
--- a/src/library/scala/reflect/api/Positions.scala
+++ b/src/library/scala/reflect/api/Positions.scala
@@ -1,21 +1,202 @@
package scala.reflect
package api
-trait Positions { self: Universe =>
- /** TreeAnnotation is a generalisation of Position.
- *
- * TreeAnnotation cannot be an upperbound of Position since the corresponding classes
- * must live outside of the universe for backwards compatibility (see scala.tools.nsc.util.Position).
- * Thus, represent subtyping as coercions.
- *
- * Typically, positionToAnnotation is the identity, and annotationToPosition returns annot.pos
- */
- type TreeAnnotation // <: { def pos: Position }
- def NoTreeAnnotation: TreeAnnotation
- implicit def positionToAnnotation(pos: Position): TreeAnnotation // = pos
- def annotationToPosition(annot: TreeAnnotation): Position // = annot.pos
- def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = () // check that annot may overwrite tree.annot
-
- type Position // <: TreeAnnotation, but not practical to enforce this (would require moving Position, SourceFile, Reporter,... into the universe)
+trait Positions {
+ self: Universe =>
+
+ // [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/Reporters.scala b/src/library/scala/reflect/api/Reporters.scala
new file mode 100644
index 0000000000..b7428e1599
--- /dev/null
+++ b/src/library/scala/reflect/api/Reporters.scala
@@ -0,0 +1,65 @@
+package scala.reflect
+package api
+
+trait Reporters { self: Universe =>
+
+ trait Reporter {
+ 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)
+
+ 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 SilentReporter extends Reporter {
+ def display(info: Info) {}
+ def interactive() {}
+ }
+
+ /** Creates a UI-less reporter that simply accumulates all the messages
+ */
+ def mkSilentReporter(): Reporter = new SilentReporter()
+
+ /** 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 mkConsoleReporter(minSeverity: Int = 1): Reporter
+} \ No newline at end of file
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..e457bb73e0 100755
--- a/src/library/scala/reflect/api/StandardDefinitions.scala
+++ b/src/library/scala/reflect/api/StandardDefinitions.scala
@@ -8,6 +8,23 @@ package api
trait StandardDefinitions { 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 ObjectTpe: Type
+ val AnyValTpe: Type
+ val AnyRefTpe: Type
+ val NothingTpe: Type
+ val NullTpe: Type
+ val StringTpe: Type
+
val definitions: AbsDefinitions
abstract class AbsDefinitions {
@@ -15,7 +32,11 @@ trait StandardDefinitions { self: Universe =>
def RootPackage: Symbol
def RootClass: Symbol
def EmptyPackage: Symbol
+ def EmptyPackageClass: Symbol
def ScalaPackage: Symbol
+ def ScalaPackageClass: Symbol
+ def JavaLangPackage: Symbol
+ def JavaLangPackageClass: Symbol
// top types
def AnyClass : Symbol
@@ -37,6 +58,7 @@ trait StandardDefinitions { self: Universe =>
def FloatClass : Symbol
def DoubleClass : Symbol
def BooleanClass: Symbol
+ def ScalaPrimitiveValueClasses: List[Symbol]
// fundamental reference classes
def SymbolClass : Symbol
@@ -48,13 +70,57 @@ trait StandardDefinitions { self: Universe =>
def ProductClass : Array[Symbol]
def FunctionClass : Array[Symbol]
- // fundamental modules
+ // Option classes
+ def OptionClass: Symbol
+ def SomeClass: Symbol
+ def NoneModule: Symbol
+ def SomeModule: Symbol
+
+ // collections classes
+ def ConsClass: Symbol
+ def IterableClass: Symbol
+ def IteratorClass: Symbol
+ def ListClass: Symbol
+ def SeqClass: Symbol
+ def StringBuilderClass: Symbol
+ def TraversableClass: Symbol
+
+ // collections modules
def PredefModule: Symbol
+ def ListModule: Symbol
+ def List_apply: Symbol
+ def NilModule: Symbol
+ def SeqModule: Symbol
+ def IteratorModule: Symbol
+ def Iterator_apply: Symbol
+
+ // arrays and their members
+ def ArrayModule: Symbol
+ def ArrayModule_overloadedApply: Symbol
+ def ArrayClass: Symbol
+ def Array_apply: Symbol
+ def Array_update: Symbol
+ def Array_length: Symbol
+ def Array_clone: Symbol
+
+ // special parameter types
+ def ByNameParamClass: Symbol
+ def JavaRepeatedParamClass: Symbol
+ def RepeatedParamClass: Symbol
+
+ // type tags
+ def ClassTagClass: Symbol
+ def ClassTagModule: Symbol
+ def TypeTagClass: Symbol
+ def TypeTagModule: Symbol
+ def ConcreteTypeTagClass: Symbol
+ def ConcreteTypeTagModule: Symbol
/** 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?
/** 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..d39d44dd86 100644
--- a/src/library/scala/reflect/api/StandardNames.scala
+++ b/src/library/scala/reflect/api/StandardNames.scala
@@ -8,14 +8,162 @@ package api
trait StandardNames { self: Universe =>
+ abstract class AbsNames {
+ type NameType <: Name
+
+ val EMPTY: NameType
+ val ANON_FUN_NAME: NameType
+ val ANON_CLASS_NAME: NameType
+ val EMPTY_PACKAGE_NAME: NameType
+ val IMPORT: NameType
+ val MODULE_VAR_SUFFIX: NameType
+ val ROOT: NameType
+ val PACKAGE: NameType
+ val SPECIALIZED_SUFFIX: NameType
+
+ val ERROR: NameType
+ val NO_NAME: NameType
+ val WILDCARD: NameType
+
+ def flattenedName(segments: Name*): NameType
+ }
+
val nme: AbsTermNames
- abstract class AbsTermNames {
+ abstract class AbsTermNames extends AbsNames {
+ val EXPAND_SEPARATOR_STRING: String
+
+ val ANYNAME: TermName
val CONSTRUCTOR: TermName
+ val FAKE_LOCAL_THIS: TermName
+ val INITIALIZER: TermName
+ val LAZY_LOCAL: TermName
+ val LOCAL_SUFFIX_STRING: String
+ val MIRROR_PREFIX: TermName
+ val MIRROR_SHORT: TermName
+ val MIRROR_FREE_PREFIX: TermName
+ val MIRROR_FREE_THIS_SUFFIX: TermName
+ val MIRROR_FREE_VALUE_SUFFIX: 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 INTERPRETER_IMPORT_WRAPPER: String
+ val INTERPRETER_LINE_PREFIX: String
+ val INTERPRETER_VAR_PREFIX: String
+ val INTERPRETER_WRAPPER_SUFFIX: String
+
+ 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
+
+ // [Eugene] this doesn't compile. why?!
+ val UNARY_~ : TermName
+ val UNARY_+ : TermName
+ val UNARY_- : TermName
+ val UNARY_! : TermName
+
+ // [Eugene] this doesn't compile. why?!
+ val ??? : TermName
+
+ val MODULE_SUFFIX_NAME: TermName
+ val NAME_JOIN_NAME: TermName
+ 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
+
+ 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 isProtectedAccessorName(name: Name): Boolean
+ def isSuperAccessorName(name: Name): Boolean
+ def isReplWrapperName(name: Name): Boolean
+ def isSetterName(name: Name): Boolean
+ def isTraitSetterName(name: Name): Boolean
+ def isSingletonName(name: Name): Boolean
+ def isModuleName(name: Name): Boolean
+ def isOpAssignmentName(name: Name): Boolean
+
+ def segments(name: String, assumeTerm: Boolean): List[Name]
+ def originalName(name: Name): Name
+ def stripModuleSuffix(name: Name): Name
+ def unspecializedName(name: Name): Name
+ def splitSpecializedName(name: Name): (Name, String, String)
+ def dropLocalSuffix(name: Name): Name
+
+ def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName
+ def expandedSetterName(name: TermName, base: Symbol): TermName
+ def protName(name: Name): TermName
+ def protSetterName(name: Name): TermName
+ def getterName(name: TermName): TermName
+ def getterToLocal(name: TermName): TermName
+ def getterToSetter(name: TermName): TermName
+ def localToGetter(name: TermName): TermName
+ def setterToGetter(name: TermName): TermName
+ def defaultGetterName(name: Name, pos: Int): TermName
+ def defaultGetterToMethod(name: Name): TermName
+
+ def dropSingletonName(name: Name): TypeName
+ def singletonName(name: Name): TypeName
+ def implClassName(name: Name): TypeName
+ def interfaceName(implname: Name): TypeName
+ def localDummyName(clazz: Symbol): TermName
+ def superName(name: Name): TermName
}
val tpnme: AbsTypeNames
- abstract class AbsTypeNames {
+ abstract class AbsTypeNames extends AbsNames {
+ val REFINE_CLASS_NAME: TypeName
+ val BYNAME_PARAM_CLASS_NAME: TypeName
+ val EQUALS_PATTERN_NAME: TypeName
+ val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName
+ val LOCAL_CHILD: TypeName
+ val REPEATED_PARAM_CLASS_NAME: TypeName
+ val WILDCARD_STAR: TypeName
}
}
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index ab59a4a39a..e47bc7216e 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -7,6 +7,10 @@ trait Symbols { self: Universe =>
abstract class AbsSymbol { this: Symbol =>
+ /** The position of this symbol
+ */
+ def pos: Position
+
/** The modifiers of this symbol
*/
def modifiers: Set[Modifier]
@@ -47,6 +51,10 @@ 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
+
/**
* Set when symbol has a modifier of the form private[X], NoSymbol otherwise.
*
@@ -112,6 +120,20 @@ trait Symbols { self: Universe =>
*/
def isTerm : 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 +146,17 @@ trait Symbols { self: Universe =>
*/
def isClass : 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,9 +167,33 @@ trait Symbols { self: Universe =>
*/
def isAbstractType : Boolean
- /** Is this symbol an overloaded method?
+ /** 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 an existentially bound type?
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isExistential : Boolean
+
+ /** Does this symbol represent a free type captured by reification?
*/
- def isOverloaded: Boolean
+ // needed for ones who wish to inspect reified trees
+ def isFreeType : Boolean
+
+ /** Is the type parameter represented by this symbol contravariant?
+ */
+ def isContravariant : Boolean
+
+ /** 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.
* Note if the symbol is a member of a class, one almost always is interested
@@ -192,7 +249,7 @@ trait Symbols { self: Universe =>
/** 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
+ 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
@@ -207,6 +264,9 @@ trait Symbols { self: Universe =>
/** 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
+
+ /** The kind of this symbol; used for debugging */
+ def kind: String
}
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..387ef5163b
--- /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(reporter: Reporter = mkSilentReporter(), options: String = ""): AbsToolBox
+
+ // [Eugene] what do you think about the interface? namely about the ``freeTypes'' part.
+ trait AbsToolBox {
+
+ /** UI 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 reporter: Reporter
+
+ /** 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..32d7eefa5b 100644
--- a/src/library/scala/reflect/api/TreeBuildUtil.scala
+++ b/src/library/scala/reflect/api/TreeBuildUtil.scala
@@ -1,46 +1,127 @@
-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 origin debug information that tells where this symbol comes from
*/
- def newFreeVar(name: String, info: Type, value: Any): Symbol
+ def newFreeTerm(name: String, info: Type, value: => Any, origin: String): Symbol
+
+ /** Create a fresh free 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 origin debug information that tells where this symbol comes from
+ */
+ def newFreeType(name: String, info: Type, value: => Any, origin: String): 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
+}
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 d8180fe029..7548a6bdc0 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]
@@ -80,18 +81,22 @@ trait Trees { self: Universe =>
*/
def printingPrefix = productPrefix
- def pos: Position = annotationToPosition(rawannot)
- def pos_=(pos: Position): Unit = annotation = pos
+ 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 }
- private[this] var rawannot: TreeAnnotation = NoTreeAnnotation
- def annotation: TreeAnnotation = rawannot
- def annotation_=(annot: TreeAnnotation): Unit = {
- _checkSetAnnotation(this, annot)
- rawannot = annot
+ private var rawatt: Attachment = NoPosition
+ private case class NontrivialAttachment(pos: api.Position, payload: Any) extends Attachment {
+ def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload)
+ def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload)
}
-
- def setAnnotation(annot: TreeAnnotation): this.type = { annotation = annot; this }
+ // todo. annotate T with ClassTag and make pattern matcher use it
+ // todo. support multiple attachments, and remove the assignment. only leave attach/detach
+// def attachment[T]: T = rawatt.payload.asInstanceOf[T]
+// def attachmentOpt[T]: Option[T] = try { Some(rawatt.payload.asInstanceOf[T]) } catch { case _: Throwable => None }
+ def attachment: Any = rawatt.payload
+ def attachment_=(att: Any): Unit = rawatt = NontrivialAttachment(pos, att)
+ def setAttachment(att: Any): this.type = { attachment = att; this }
private[this] var rawtpe: Type = _
@@ -143,6 +148,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)
@@ -179,6 +185,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.
*/
@@ -188,9 +201,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) && {
@@ -230,7 +246,7 @@ trait Trees { self: Universe =>
duplicateTree(this).asInstanceOf[this.type]
private[scala] def copyAttrs(tree: Tree): this.type = {
- annotation = tree.annotation
+ rawatt = tree.rawatt
tpe = tree.tpe
if (hasSymbol) symbol = tree.symbol
this
@@ -241,6 +257,34 @@ trait Trees { self: Universe =>
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
}
+ // [Eugene] uh-oh
+ // locker.comp:
+ // [mkdir] Created dir: C:\Projects\Kepler\build\locker\classes\compiler
+ // [scalacfork] Compiling 471 files to C:\Projects\Kepler\build\locker\classes\compiler
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+ // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree
+// object Tree {
+// // would be great if in future this generated an Expr[Magic]
+// // where Magic is a magic untyped type that propagates through the entire quasiquote
+// // and turns off typechecking whenever it's involved
+// // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked
+// // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo
+// implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree)
+// implicit def expr2tree(expr: Expr[_]): Tree = expr.tree
+//
+// // [Eugene] good idea?
+// implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr
+// implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree
+// }
+
/** A tree for a term. Not all terms are TermTrees; use isTerm
* to reliably identify terms.
*/
@@ -258,18 +302,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
}
@@ -319,12 +369,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 {
@@ -343,17 +404,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.
@@ -371,6 +452,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
@@ -415,12 +498,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(...))
*/
@@ -439,6 +529,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
@@ -489,10 +581,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.
*
@@ -503,14 +599,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)
@@ -545,6 +640,8 @@ trait Trees { self: Universe =>
override def symbol_=(sym: Symbol) { fun.symbol = sym }
}
+ def Apply(sym: Symbol, args: Tree*): Tree
+
class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args)
class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args)
@@ -563,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.
@@ -571,38 +670,47 @@ 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
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 {
@@ -873,6 +981,8 @@ trait Trees { self: Universe =>
traverse(qualifier)
case Ident(_) =>
;
+ case ReferenceToBoxed(idt) =>
+ traverse(idt)
case Literal(_) =>
;
case TypeTree() =>
@@ -958,6 +1068,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
@@ -1040,6 +1151,8 @@ trait Trees { self: Universe =>
new Select(qualifier, selector).copyAttrs(tree)
def Ident(tree: Tree, name: Name) =
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) =
@@ -1228,6 +1341,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
@@ -1372,6 +1490,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() =>
@@ -1413,7 +1533,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)
@@ -1443,6 +1563,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) {
@@ -1535,7 +1663,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) =>
@@ -1544,6 +1672,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..59a7c87f44
--- /dev/null
+++ b/src/library/scala/reflect/api/TypeTags.scala
@@ -0,0 +1,194 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package api
+
+import scala.reflect.{ mirror => rm }
+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.
+ *
+ * Type tags are organized in a hierarchy of two classes:
+ * [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#ConcreteTypeTag]].
+ * 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 type tag that is guaranteed not to contain any references to type parameters or abstract types.
+ *
+ * It is also possible to capture Java classes by using a different kind of tag.
+ * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method.
+ *
+ * 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]].
+ *
+ * Implicit in the contract for all Tag classes is that the reified type tpe represents the type parameter T.
+ * Tags are typically created by the compiler, which makes sure that this contract is kept.
+ *
+ * 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.
+ */
+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}")
+ abstract case class TypeTag[T](tpe: Type) {
+ // it's unsafe to use assert here, because we might run into deadlocks with Predef
+ // also see comments in ClassTags.scala
+ // assert(tpe != null)
+
+ def sym = tpe.typeSymbol
+ def isConcrete = tpe.isConcrete
+ def notConcrete = !isConcrete
+ def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe)
+
+ override def toString = {
+ var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag"
+ if (prefix != this.productPrefix) prefix = "*" + prefix
+ prefix + "[" + tpe + "]"
+ }
+ }
+
+ 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
+
+ def apply[T](tpe: Type): TypeTag[T] =
+ tpe 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](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}")
+ class ConcreteTypeTag[T](tpe: Type) extends TypeTag[T](tpe) {
+ // it's unsafe to use assert here, because we might run into deadlocks with Predef
+ // also see comments in ClassTags.scala
+ //assert(isConcrete, tpe)
+ if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind))
+ override def productPrefix = "ConcreteTypeTag"
+ }
+
+ object ConcreteTypeTag {
+ val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe) { private def readResolve() = ConcreteTypeTag.Byte }
+ val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe) { private def readResolve() = ConcreteTypeTag.Short }
+ val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe) { private def readResolve() = ConcreteTypeTag.Char }
+ val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe) { private def readResolve() = ConcreteTypeTag.Int }
+ val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe) { private def readResolve() = ConcreteTypeTag.Long }
+ val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe) { private def readResolve() = ConcreteTypeTag.Float }
+ val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe) { private def readResolve() = ConcreteTypeTag.Double }
+ val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = ConcreteTypeTag.Boolean }
+ val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe) { private def readResolve() = ConcreteTypeTag.Unit }
+ val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe) { private def readResolve() = ConcreteTypeTag.Any }
+ val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = ConcreteTypeTag.Object }
+ val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = ConcreteTypeTag.AnyVal }
+ val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = ConcreteTypeTag.AnyRef }
+ val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = ConcreteTypeTag.Nothing }
+ val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe) { private def readResolve() = ConcreteTypeTag.Null }
+ val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe) { private def readResolve() = ConcreteTypeTag.String }
+
+ def apply[T](tpe: Type): ConcreteTypeTag[T] =
+ tpe 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](tpe) {}
+ }
+
+ def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None
+
+ implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure))
+
+ implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag)
+
+ // this class should not be used directly in client code
+ class DeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) {
+ @deprecated("Use `tpe` to analyze the underlying type", "2.10.0")
+ def <:<(that: Manifest[_]): Boolean = ttag.tpe <:< that.tpe
+
+ @deprecated("Use `tpe` to analyze the underlying type", "2.10.0")
+ def >:>(that: Manifest[_]): Boolean = that <:< ttag
+
+ @deprecated("Use `tpe` to analyze the type arguments", "2.10.0")
+ override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.ConcreteTypeTag(targ))
+ }
+ }
+
+ // 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..5e1c1af2fe 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -57,6 +57,10 @@ trait Types { self: Universe =>
*/
def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no?
+ /** Does this type refer to abstract types or is an abstract type?
+ */
+ def isConcrete: Boolean
+
/**
* Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
* Functions on types are also implemented as PolyTypes.
@@ -105,7 +109,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 +151,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.
@@ -424,5 +456,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..d1f546608e 100755
--- a/src/library/scala/reflect/api/Universe.scala
+++ b/src/library/scala/reflect/api/Universe.scala
@@ -1,19 +1,89 @@
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 Reporters
+ 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 cc.mirror._
+ try cc.reifyTree(cc.prefix, expr)
+ catch {
+ case ex: Throwable =>
+ // [Eugene] cannot pattern match on an abstract type, so had to do this
+ val ex1 = ex
+ if (ex.getClass.toString.endsWith("$ReificationError")) {
+ ex match {
+ case cc.ReificationError(pos, msg) =>
+ cc.error(pos, msg)
+ EmptyTree
+ }
+ } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) {
+ ex match {
+ case cc.UnexpectedReificationError(pos, err, cause) =>
+ if (cause != null) throw cause else throw ex
+ }
+ } else {
+ throw ex
+ }
+ }
+ }
+}
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..5ce801e2e6
--- /dev/null
+++ b/src/library/scala/reflect/makro/Context.scala
@@ -0,0 +1,61 @@
+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 Reporters
+ 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._
+ // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure?
+ val prefix: Tree = Select(cc.prefix, newTermName("mirror"))
+ val prefixTpe = cc.typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe
+ prefix setType prefixTpe
+ try cc.reifyTree(prefix, expr)
+ catch {
+ case ex: Throwable =>
+ // [Eugene] cannot pattern match on an abstract type, so had to do this
+ if (ex.getClass.toString.endsWith("$ReificationError")) {
+ ex match {
+ case cc.ReificationError(pos, msg) =>
+ cc.error(pos, msg)
+ EmptyTree
+ }
+ } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) {
+ ex match {
+ case cc.UnexpectedReificationError(pos, err, cause) =>
+ if (cause != null) throw cause else throw ex
+ }
+ } else {
+ throw ex
+ }
+ }
+ }
+}
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/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..d690df6aee
--- /dev/null
+++ b/src/library/scala/reflect/makro/Reifiers.scala
@@ -0,0 +1,82 @@
+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, requireConcreteTypeTag: Boolean = false): 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
+
+ /** Represents an error during reification
+ */
+ type ReificationError <: Throwable
+ val ReificationError: ReificationErrorExtractor
+ abstract class ReificationErrorExtractor {
+ def unapply(error: ReificationError): Option[(Position, String)]
+ }
+
+ /** Wraps an unexpected error during reification
+ */
+ type UnexpectedReificationError <: Throwable
+ val UnexpectedReificationError: UnexpectedReificationErrorExtractor
+ abstract class UnexpectedReificationErrorExtractor {
+ def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)]
+ }
+}
diff --git a/src/library/scala/reflect/makro/Reporters.scala b/src/library/scala/reflect/makro/Reporters.scala
new file mode 100644
index 0000000000..7341b0e0b7
--- /dev/null
+++ b/src/library/scala/reflect/makro/Reporters.scala
@@ -0,0 +1,39 @@
+package scala.reflect.makro
+
+trait Reporters {
+ self: Context =>
+
+ import mirror._
+
+ /** Exposes means to control the compiler UI */
+ def reporter: Reporter
+ def setReporter(reporter: Reporter): this.type
+ def withReporter[T](reporter: Reporter)(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/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..91a5f6d8a5
--- /dev/null
+++ b/src/library/scala/reflect/makro/Symbols.scala
@@ -0,0 +1,17 @@
+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
+} \ 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..1ced2daccd
--- /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.
+ * 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..db658fd637
--- /dev/null
+++ b/src/library/scala/reflect/makro/internal/Utils.scala
@@ -0,0 +1,135 @@
+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 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, requireConcreteTypeTag = 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, requireConcreteTypeTag = 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"))
+
+ def materializeClassTag(prefix: Tree, tpe: Type): Tree = {
+ val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe)))
+ def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule))
+ typetagInScope match {
+ case success if !success.isEmpty && !typetagIsSynthetic(success) =>
+ val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
+ Apply(factory, List(Select(typetagInScope, newTermName("tpe"))))
+ case _ =>
+ val result =
+ tpe match {
+ case coreTpe if coreTags contains coreTpe =>
+ Select(Ident(ClassTagModule), coreTags(coreTpe))
+ case _ =>
+ if (tpe.typeSymbol == ArrayClass) {
+ val componentTpe = tpe.typeArguments(0)
+ val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe)))
+ val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe)
+ Select(componentTag, newTermName("wrap"))
+ } else {
+ // [Eugene] what's the intended behavior? there's no spec on ClassManifests
+ // for example, should we ban Array[T] or should we tag them with Array[AnyRef]?
+ // if its the latter, what should be the result of tagging Array[T] where T <: Int?
+ if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type")
+ val erasure =
+ if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct?
+ else tpe.erasure.normalize // necessary to deal with erasures of HK types
+ val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
+ Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure)))))
+ }
+ }
+ try c.typeCheck(result)
+ catch { case terr @ c.TypeError(pos, msg) => fail(terr) }
+ }
+ }
+
+ def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
+ val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule
+ val result =
+ tpe match {
+ case coreTpe if coreTags contains coreTpe =>
+ Select(Select(prefix, tagModule.name), coreTags(coreTpe))
+ case _ =>
+ try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)
+ catch {
+ case ex: Throwable =>
+ // [Eugene] cannot pattern match on an abstract type, so had to do this
+ val ex1 = ex
+ if (ex.getClass.toString.endsWith("$ReificationError")) {
+ ex match {
+ case c.ReificationError(pos, msg) =>
+ c.error(pos, msg)
+ EmptyTree
+ }
+ } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) {
+ ex match {
+ case c.UnexpectedReificationError(pos, err, cause) =>
+ if (cause != null) throw cause else throw ex
+ }
+ } else {
+ throw ex
+ }
+ }
+ }
+ try c.typeCheck(result)
+ catch { case terr @ c.TypeError(pos, msg) => fail(terr) }
+ }
+
+ private def fail(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))
+ }
+ }
+}
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..1738642932 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -2,21 +2,28 @@ package scala
package object reflect {
+ import ReflectionUtils._
+
// !!! 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 = {
+
+ // 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 = mkMirror(defaultReflectionClassLoader)
+
+ def mkMirror(classLoader: ClassLoader): 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")
+ // note that we must instantiate the mirror with current classloader, otherwise we won't be able to cast it to api.Mirror
+ // that's not a problem, though, because mirror can service classes from arbitrary classloaders
+ val instance = invokeFactoryOpt(getClass.getClassLoader, "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")
+ case None => throw new UnsupportedOperationException("Scala reflection not available on this platform")
}
}
- type Symbol = mirror.Symbol
- type Type = mirror.Type
- type Tree = mirror.Tree
-
@deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0")
type BeanDescription = scala.beans.BeanDescription
@deprecated("Use `@scala.beans.BeanDisplayName` instead", "2.10.0")
@@ -31,4 +38,26 @@ package object reflect {
type BooleanBeanProperty = scala.beans.BooleanBeanProperty
@deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0")
type ScalaBeanInfo = scala.beans.ScalaBeanInfo
+
+ @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0")
+ type ClassManifest[T] = ClassTag[T]
+ @deprecated("OptManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0")
+ type OptManifest[T] = TypeTag[T]
+ @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0")
+ type Manifest[T] = ConcreteTypeTag[T]
+
+ @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0")
+ val ClassManifest = ClassTag
+ @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0")
+ lazy val Manifest = ConcreteTypeTag
+ @deprecated("NoManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0")
+ object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable
+
+ // 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
}
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 8bc63ae3a0..7a932c21bc 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
@@ -329,14 +329,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/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 7570bf705c..5ab46b8985 100644
--- a/src/library/scala/testing/Show.scala
+++ b/src/library/scala/testing/Show.scala
@@ -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..c2269cde45 100644
--- a/src/library/scala/util/Marshal.scala
+++ b/src/library/scala/util/Marshal.scala
@@ -35,7 +35,8 @@ object Marshal {
def load[A](buffer: Array[Byte])(implicit expected: ClassManifest[A]): A = {
val in = new ObjectInputStream(new ByteArrayInputStream(buffer))
val found = in.readObject.asInstanceOf[ClassManifest[_]]
- if (found <:< expected) {
+ // todo. [Eugene] needs review, since ClassManifests no longer capture typeArguments
+ if (found.tpe <:< expected.tpe) {
val o = in.readObject.asInstanceOf[A]
in.close()
o
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/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 20a179a884..1cae8088f5 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:
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 abf8f97f03..45ba9530e1 100644
--- a/src/library/scala/xml/factory/LoggedNodeFactory.scala
+++ b/src/library/scala/xml/factory/LoggedNodeFactory.scala
@@ -12,7 +12,7 @@ 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
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/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala
index 2eb026ceee..142f2baea5 100644
--- a/src/partest/scala/tools/partest/ScaladocModelTest.scala
+++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala
@@ -21,10 +21,10 @@ import scala.tools.nsc.reporters.ConsoleReporter
import scala.tools.nsc.doc.model._
import scala.tools.partest.ScaladocModelTest
- object Test extends ScaladocModelTest {
+ object Test extends ScaladocModelTest {
- def code = """ ... """
- def scaladocSettings = ""
+ 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._
@@ -39,10 +39,22 @@ 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"
@@ -50,15 +62,15 @@ abstract class ScaladocModelTest extends DirectTest {
// 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 args = scaladocSettings.split(" ")
- val universe = model(args:_*).getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")})
+ 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 =>
+ case e =>
println(e)
e.printStackTrace
}
@@ -66,51 +78,46 @@ abstract class ScaladocModelTest extends DirectTest {
System.setErr(prevErr)
}
+ private[this] var settings: Settings = null
+
// create a new scaladoc compiler
- def newDocFactory(args: String*): DocFactory = {
- val settings = new Settings(_ => ())
- val command = new ScalaDoc.Command((CommandLineParser tokenize extraSettings) ++ args.toList, settings)
+ 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(args: String*): Option[Universe] = newDocFactory(args: _*).makeUniverse(Right(code))
+ def model: Option[Universe] = newDocFactory.makeUniverse(Right(code))
// so we don't get the newSettings warning
- override def isDebug = false
+ override def isDebug = false
// finally, enable easy navigation inside the entities
object access {
- // Make it easy to access things
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).flatMap({ case c: Class => List(c)})
+ 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).flatMap({ case t: Trait => List(t)})
+ 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).flatMap({ case o: Object => List(o)})
+ 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 getTheFirst[T](list: List[T], expl: String): T = {
- if (list.length == 1)
- list.head
- else if (list.length == 0)
- sys.error("Error getting " + expl + ": No such element. All elements in list: [" + list.mkString(", ") + "]")
- else
- sys.error("Error getting " + expl + ": " + list.length + " elements with this name. " +
- "All elements in list: [" + list.mkString(", ") + "]")
- }
+ 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) {
@@ -118,7 +125,22 @@ abstract class ScaladocModelTest extends DirectTest {
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/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/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/test/files/jvm/concurrent-future.check b/test/disabled/jvm/concurrent-future.check
index 715ac90ce7..715ac90ce7 100644
--- a/test/files/jvm/concurrent-future.check
+++ b/test/disabled/jvm/concurrent-future.check
diff --git a/test/files/jvm/concurrent-future.scala b/test/disabled/jvm/concurrent-future.scala
index eda05428c8..eda05428c8 100644
--- a/test/files/jvm/concurrent-future.scala
+++ b/test/disabled/jvm/concurrent-future.scala
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 cef9d2a5ed..cef9d2a5ed 100644
--- a/test/files/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala
+++ b/test/disabled/presentation/shutdown-deadlock/ShutdownDeadlockTest.scala
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/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/jvm/interpreter.check b/test/files/jvm/interpreter.check
index 243c9aa3be..b9ff6afa2b 100755..100644
--- a/test/files/jvm/interpreter.check
+++ b/test/files/jvm/interpreter.check
@@ -73,7 +73,7 @@ fish: S = fish
scala> // Test that arrays pretty print nicely.
-scala> val arr = Array("What's", "up", "doc?")
+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
@@ -97,6 +97,7 @@ 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)
@@ -270,6 +271,8 @@ scala> xs map (x => x)
res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(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>
@@ -338,10 +341,10 @@ You typed two blank lines. Starting a new command.
scala> // defining and using quoted names should work (ticket #323)
-scala> def `match` = 1
+scala> def `match` = 1
match: Int
-scala> val x = `match`
+scala> val x = `match`
x: Int = 1
scala>
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.check b/test/files/jvm/manifests.check
index 54f504b929..be8ec2bb5b 100644
--- a/test/files/jvm/manifests.check
+++ b/test/files/jvm/manifests.check
@@ -1,55 +1,56 @@
-x=(), m=Unit
-x=true, m=Boolean
-x=a, m=Char
-x=1, m=Int
-x=abc, m=java.lang.String
-x='abc, m=scala.Symbol
-
-x=List(()), m=scala.collection.immutable.List[Unit]
-x=List(true), m=scala.collection.immutable.List[Boolean]
-x=List(1), m=scala.collection.immutable.List[Int]
-x=List(abc), m=scala.collection.immutable.List[java.lang.String]
-x=List('abc), m=scala.collection.immutable.List[scala.Symbol]
-
-x=[Z, m=Array[Boolean]
-x=[C, m=Array[Char]
-x=[I, m=Array[Int]
-x=[Ljava.lang.String;, m=Array[java.lang.String]
-x=[Lscala.Symbol;, m=Array[scala.Symbol]
-
-x=((),()), m=scala.Tuple2[Unit, Unit]
-x=(true,false), m=scala.Tuple2[Boolean, Boolean]
-x=(1,2), m=scala.Tuple2[Int, Int]
-x=(abc,xyz), m=scala.Tuple2[java.lang.String, java.lang.String]
-x=('abc,'xyz), m=scala.Tuple2[scala.Symbol, scala.Symbol]
-
-
-x=Foo, m=Foo[Int]
-x=Foo, m=Foo[scala.collection.immutable.List[Int]]
-x=Foo, m=Foo[Foo[Int]]
-x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]]
-
-x=Test1$$anon$1, m=Object with Bar[java.lang.String]
-
-()=()
-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))
-
+x=(), m=ConcreteTypeTag[Unit], k=TypeRef, s=class Unit
+x=true, m=ConcreteTypeTag[Boolean], k=TypeRef, s=class Boolean
+x=a, m=ConcreteTypeTag[Char], k=TypeRef, s=class Char
+x=1, m=ConcreteTypeTag[Int], k=TypeRef, s=class Int
+x=abc, m=ConcreteTypeTag[String], k=TypeRef, s=class String
+x='abc, m=ConcreteTypeTag[Symbol], k=TypeRef, s=class Symbol
+
+x=List(()), m=ConcreteTypeTag[List[Unit]], k=TypeRef, s=class List
+x=List(true), m=ConcreteTypeTag[List[Boolean]], k=TypeRef, s=class List
+x=List(1), m=ConcreteTypeTag[List[Int]], k=TypeRef, s=class List
+x=List(abc), m=ConcreteTypeTag[List[String]], k=TypeRef, s=class List
+x=List('abc), m=ConcreteTypeTag[List[Symbol]], k=TypeRef, s=class List
+
+x=[Z, m=ConcreteTypeTag[Array[Boolean]], k=TypeRef, s=class Array
+x=[C, m=ConcreteTypeTag[Array[Char]], k=TypeRef, s=class Array
+x=[I, m=ConcreteTypeTag[Array[Int]], k=TypeRef, s=class Array
+x=[Ljava.lang.String;, m=ConcreteTypeTag[Array[String]], k=TypeRef, s=class Array
+x=[Lscala.Symbol;, m=ConcreteTypeTag[Array[Symbol]], k=TypeRef, s=class Array
+
+x=((),()), m=ConcreteTypeTag[(Unit, Unit)], k=TypeRef, s=class Tuple2
+x=(true,false), m=ConcreteTypeTag[(Boolean, Boolean)], k=TypeRef, s=class Tuple2
+x=(1,2), m=ConcreteTypeTag[(Int, Int)], k=TypeRef, s=class Tuple2
+x=(abc,xyz), m=ConcreteTypeTag[(String, String)], k=TypeRef, s=class Tuple2
+x=('abc,'xyz), m=ConcreteTypeTag[(Symbol, Symbol)], k=TypeRef, s=class Tuple2
+
+
+x=Foo, m=ConcreteTypeTag[Foo[Int]], k=TypeRef, s=class Foo
+x=Foo, m=ConcreteTypeTag[Foo[List[Int]]], k=TypeRef, s=class Foo
+x=Foo, m=ConcreteTypeTag[Foo[Foo[Int]]], k=TypeRef, s=class Foo
+x=Foo, m=ConcreteTypeTag[Foo[List[Foo[Int]]]], k=TypeRef, s=class Foo
+
+x=Test1$$anon$1, m=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1>
+x=Test1$$anon$2, m=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.scala b/test/files/jvm/manifests.scala
index 6bbea4d052..935427f5d4 100644
--- a/test/files/jvm/manifests.scala
+++ b/test/files/jvm/manifests.scala
@@ -1,7 +1,6 @@
object Test extends App {
Test1
Test2
- //Test3 // Java 1.5+ only
}
class Foo[T](x: T)
@@ -51,7 +50,8 @@ object Test1 extends TestUtil {
print(new Foo(List(new Foo(2))))
println()
- print(new Bar[String] { def f = "abc" })
+ print(new Bar[String] { def f = "abc" });
+ {print(new Bar[String] { def f = "abc" })}
println()
}
@@ -88,15 +88,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] = {
@@ -112,8 +103,10 @@ trait TestUtil {
}
import scala.reflect._
def print[T](x: T)(implicit m: Manifest[T]) {
- val m1: Manifest[T] = read(write(m))
+ // manifests are no longer serializable
+// val m1: Manifest[T] = read(write(m))
+ val m1: Manifest[T] = m
val x1 = x.toString.replaceAll("@[0-9a-z]+$", "")
- println("x="+x1+", m="+m1)
+ println("x="+x1+", m="+m1+", k="+m1.tpe.kind+", s="+m1.sym.toString)
}
}
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..f4b6ff5af1
--- /dev/null
+++ b/test/files/neg/classtags_contextbound_a.check
@@ -0,0 +1,4 @@
+classtags_contextbound_a.scala:2: error: No ClassTag 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..54f630862a
--- /dev/null
+++ b/test/files/neg/classtags_contextbound_c.check
@@ -0,0 +1,4 @@
+classtags_contextbound_c.scala:2: error: No ClassTag 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/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/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..7fcc396463
--- /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 : c.Expr[Any] does not conform to Int
+ 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..a97d6daaa9
--- /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 : c.Expr[Any] does not conform to reflect.mirror.Literal
+ 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..7bc46ff876
--- /dev/null
+++ b/test/files/neg/macro-invalidsig-tparams-notparams-b/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)
+ Literal(Constant(()))
+ }
+}
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..7bc46ff876
--- /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)
+ Literal(Constant(()))
+ }
+}
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..01daf12b1a
--- /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._
+ 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._
+ 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._
+ 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..01daf12b1a
--- /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._
+ 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._
+ 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._
+ 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/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/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
index 1a01696a9a..f70f12535f 100644
--- a/test/files/neg/t2386.check
+++ b/test/files/neg/t2386.check
@@ -1,4 +1,4 @@
-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
+t2386.scala:2: error: No ClassTag available for Array[_ >: String with Int]
+ val a = Array(Array(1, 2), Array("a","b"))
+ ^
+one error found
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.check
deleted file mode 100644
index 8e538e4a8b..0000000000
--- a/test/files/neg/t3507.check
+++ /dev/null
@@ -1,4 +0,0 @@
-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
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.check
index 96ddd2a461..d83abd31e2 100644
--- a/test/files/neg/t3692.check
+++ b/test/files/neg/t3692.check
@@ -1,4 +1,11 @@
-t3692.scala:15: error: unreachable code
- case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
- ^
-one error found
+t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.ConcreteTypeTag` instead
+ private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = {
+ ^
+t3692.scala:11: warning: type Manifest in object Predef is deprecated: Use `@scala.reflect.ConcreteTypeTag` instead
+ private final def toJavaMap[T, V](map: Map[T, V])(implicit m1: Manifest[T], m2: Manifest[V]): java.util.Map[_, _] = {
+ ^
+t3692.scala:15: error: unreachable code
+ case m2: Map[T, Int] => new java.util.HashMap[T, Integer]
+ ^
+two warnings found
+one error found
diff --git a/test/files/neg/t3692.flags b/test/files/neg/t3692.flags
new file mode 100644
index 0000000000..82becdfbfd
--- /dev/null
+++ b/test/files/neg/t3692.flags
@@ -0,0 +1 @@
+ -Xoldpatmat \ No newline at end of file
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/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/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/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..cc31390dc7
--- /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: trait 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/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/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/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/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/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/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/Runner.scala b/test/files/presentation/callcc-interpreter/Runner.scala
index 1ef3cf9025..61b6efd50d 100644
--- a/test/files/presentation/callcc-interpreter/Runner.scala
+++ b/test/files/presentation/callcc-interpreter/Runner.scala
@@ -1,3 +1,5 @@
import scala.tools.nsc.interactive.tests._
-object Test extends InteractiveTest \ No newline at end of file
+object Test extends InteractiveTest {
+ settings.XoldPatmat.value = true // TODO: could this be running into some kind of race condition? sometimes the match has been translated, sometimes it hasn't
+} \ No newline at end of file
diff --git a/test/files/presentation/random.check b/test/files/presentation/random.check
index fce4b69fb3..1b73720312 100644
--- a/test/files/presentation/random.check
+++ b/test/files/presentation/random.check
@@ -4,7 +4,8 @@ askType at Random.scala(18,14)
================================================================================
[response] askTypeAt at (18,14)
val filter: Int => Boolean = try {
- java.this.lang.Integer.parseInt(args.apply(0)) match {
+ case <synthetic> val x1: Int = java.this.lang.Integer.parseInt(args.apply(0));
+ x1 match {
case 1 => ((x: Int) => x.%(2).!=(0))
case 2 => ((x: Int) => x.%(2).==(0))
case _ => ((x: Int) => x.!=(0))
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/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..ce5a893b08
--- /dev/null
+++ b/test/files/run/classtags_core.check
@@ -0,0 +1,30 @@
+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 java.lang.Object)
+true
+ClassTag(class java.lang.Object)
diff --git a/test/files/run/classtags_core.scala b/test/files/run/classtags_core.scala
new file mode 100644
index 0000000000..45c54b1fe0
--- /dev/null
+++ b/test/files/run/classtags_core.scala
@@ -0,0 +1,32 @@
+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]])
+} \ No newline at end of file
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/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/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.check b/test/files/run/existentials3.check
index 36a458dacc..8227d77909 100644
--- a/test/files/run/existentials3.check
+++ b/test/files/run/existentials3.check
@@ -1,22 +1,24 @@
-_ <: 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]]
+ConcreteTypeTag[Bar.type], t=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton
+ConcreteTypeTag[Bar], t=TypeRef, 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=TypeRef, s= <: B with Test.ToS
+ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS
+ConcreteTypeTag[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=TypeRef, s= <: scala.runtime.AbstractFunction0[Bar] with Serializable{case def unapply(x$0: Bar): Boolean} with Singleton
+ConcreteTypeTag[Bar], t=TypeRef, 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=TypeRef, s= <: B with Test.ToS
+ConcreteTypeTag[$anon], t=TypeRef, s= <: B with A with Test.ToS
+ConcreteTypeTag[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.scala b/test/files/run/existentials3.scala
index bb80d366cc..d6d5612687 100644
--- a/test/files/run/existentials3.scala
+++ b/test/files/run/existentials3.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,10 +30,16 @@ 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])
-
+
+ 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])
+
// manifests don't work for f10/g10
+ // oh, they do now :)
def main(args: Array[String]): Unit = {
m(f1)
m(f2)
@@ -44,7 +50,7 @@ object Test {
m(f7)
m(f8)
m(f9)
- // m(f10)
+ m2(f10)
m(f11)
m(f12)
m(g1)
@@ -56,7 +62,7 @@ object Test {
m(g7)
m(g8)
m(g9)
- // m(g10)
+ m2(g10)
m(g11)
m(g12)
}
diff --git a/test/files/run/groundtypetags_core.check b/test/files/run/groundtypetags_core.check
new file mode 100644
index 0000000000..62fcb481ae
--- /dev/null
+++ b/test/files/run/groundtypetags_core.check
@@ -0,0 +1,30 @@
+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]
diff --git a/test/files/run/groundtypetags_core.scala b/test/files/run/groundtypetags_core.scala
new file mode 100644
index 0000000000..8b81a0c795
--- /dev/null
+++ b/test/files/run/groundtypetags_core.scala
@@ -0,0 +1,32 @@
+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]])
+} \ No newline at end of file
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..708fcc6985 100644
--- a/test/files/run/inline-ex-handlers.check
+++ b/test/files/run/inline-ex-handlers.check
@@ -1,40 +1,44 @@
172c172
-< locals: value x$1, value temp1
+< locals: value x$1, value x1
---
-> locals: value x$1, value temp1, variable boxed1
+> locals: value x$1, value x1, variable boxed1
174c174
< blocks: [1,2,3,4]
---
-> blocks: [1,2,3]
-187,189d186
-< 92 JUMP 4
-<
-< 4:
-195a193,194
+> blocks: [1,3,4]
+186a187,188
> 92 STORE_LOCAL(variable boxed1)
> 92 LOAD_LOCAL(variable boxed1)
-386c385
-< blocks: [1,2,3,4,5,7,8,10]
+195,197d196
+< 92 JUMP 2
+<
+< 2:
+385c384
+< 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]
+409c408,417
< 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
+422,424d429
+< 101 JUMP 4
+<
+< 4:
+512c517
< 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
+541c546,551
< 306 THROW(MyException)
---
> ? JUMP 11
@@ -43,7 +47,7 @@
> ? LOAD_LOCAL(variable monitor4)
> 305 MONITOR_EXIT
> ? JUMP 12
-536c549,555
+547c557,563
< ? THROW(Throwable)
---
> ? JUMP 12
@@ -53,7 +57,7 @@
> 304 MONITOR_EXIT
> ? STORE_LOCAL(value t)
> ? JUMP 13
-542c561,574
+553c569,582
< ? THROW(Throwable)
---
> ? STORE_LOCAL(value t)
@@ -70,19 +74,19 @@
> 310 CALL_PRIMITIVE(EndConcat)
> 310 CALL_METHOD scala.Predef.println (dynamic)
> 310 JUMP 2
-566c598
+577c606
< catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6
---
> catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6
-569c601
+580c609
< 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
+612c641
< blocks: [1,2,3,4,5,6,7,9,10]
---
> blocks: [1,2,3,4,5,6,7,9,10,11,12]
-625c657,663
+636c665,671
< 78 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
@@ -92,7 +96,7 @@
> 81 LOAD_LOCAL(value e)
> ? STORE_LOCAL(variable exc1)
> ? JUMP 12
-654c692,706
+665c700,714
< 81 THROW(Exception)
---
> ? STORE_LOCAL(variable exc1)
@@ -110,57 +114,53 @@
> 84 STORE_LOCAL(variable result)
> 84 LOAD_LOCAL(variable exc1)
> 84 THROW(Throwable)
-676c728
+687c736
< 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]
+713c762
+< 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]
+737c786,793
< 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
+793c849,850
< 177 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$5)
-> ? JUMP 21
-784c846,855
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 33
+797c854,861
< 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
+830c894,895
< 182 THROW(MyException)
---
> ? STORE_LOCAL(variable exc2)
-> ? JUMP 22
-819c891,905
+> ? JUMP 34
+834c899,900
< 169 THROW(Throwable)
---
> ? STORE_LOCAL(variable exc2)
-> ? JUMP 22
->
-> 22:
+> ? JUMP 34
+835a902,914
+> 34:
> 184 LOAD_MODULE object Predef
> 184 CONSTANT("finally")
> 184 CALL_METHOD scala.Predef.println (dynamic)
@@ -172,57 +172,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
+>
+856c935
+< 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
+859c938
+< 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
+885c964
+< 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]
+909c988,995
< 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
+969c1055
+< 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
+995c1081
+< blocks: [1,2,3,4,5,8,11,15,16,17,19]
+---
+> blocks: [1,2,3,5,8,11,15,16,17,19,20]
+1019c1105,1114
< 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
+1040,1042d1134
+< 145 JUMP 4
+<
+< 4:
+1275c1367
< blocks: [1,2,3,4,5,7]
---
> blocks: [1,2,3,4,5,7,8]
-1260c1364,1371
+1299c1391,1398
< 38 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
@@ -233,33 +236,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]
+1348c1447
+< 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]
+1372c1471,1472
< 203 THROW(MyException)
---
-> ? STORE_LOCAL(value ex$6)
-> ? JUMP 14
-1353c1465,1474
+> ? STORE_LOCAL(value ex5)
+> ? JUMP 20
+1392c1492,1501
< 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
+1405,1407d1513
+< 200 JUMP 4
+<
+< 4:
+1467c1573
< blocks: [1,2,3,4,5,7]
---
> blocks: [1,2,3,4,5,7,8]
-1440c1561,1568
+1491c1597,1604
< 58 THROW(IllegalArgumentException)
---
> ? STORE_LOCAL(value e)
@@ -270,11 +277,11 @@
> 62 CONSTANT("RuntimeException")
> 62 CALL_METHOD scala.Predef.println (dynamic)
> 62 JUMP 2
-1489c1617
+1540c1653
< blocks: [1,2,3,4]
---
> blocks: [1,2,3,4,5]
-1509c1637,1642
+1560c1673,1678
< 229 THROW(MyException)
---
> ? JUMP 5
@@ -283,19 +290,19 @@
> ? LOAD_LOCAL(variable monitor1)
> 228 MONITOR_EXIT
> 228 THROW(Throwable)
-1515c1648
+1566c1684
< ? THROW(Throwable)
---
> 228 THROW(Throwable)
-1543c1676
+1594c1712
< locals: value args, variable result, variable monitor2, variable monitorResult1
---
> locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1
-1545c1678
+1596c1714
< blocks: [1,2,3,4]
---
> blocks: [1,2,3,4,5]
-1568c1701,1709
+1619c1737,1745
< 245 THROW(MyException)
---
> ? STORE_LOCAL(value exception$1)
@@ -307,7 +314,7 @@
> ? LOAD_LOCAL(variable monitor2)
> 244 MONITOR_EXIT
> 244 THROW(Throwable)
-1574c1715
+1625c1751
< ? THROW(Throwable)
---
> 244 THROW(Throwable)
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..f389231ca6
--- /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 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..eadb63fa8e
--- /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._
+ Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1))))
+ }
+
+ def bar(c: Ctx)(x: c.Expr[Int]): c.Expr[Int] = {
+ import c.mirror._
+ 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..8ff4494750
--- /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 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/reify_classfileann_b.check b/test/files/run/macro-expand-tparams-bounds-a.check
index e69de29bb2..e69de29bb2 100644
--- a/test/pending/run/reify_classfileann_b.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..4cd98c5838
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala
@@ -0,0 +1,8 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U <: String](c: Ctx): c.Expr[Unit] = {
+ import c.mirror._
+ Literal(Constant(()))
+ }
+}
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..9103ddb08a
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.makro.{Context => Ctx}
+
+class C
+
+object Impls {
+ def foo[U <: C](c: Ctx): c.Expr[Unit] = {
+ import c.mirror._
+ Literal(Constant(()))
+ }
+}
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..4cd98c5838
--- /dev/null
+++ b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala
@@ -0,0 +1,8 @@
+import scala.reflect.makro.{Context => Ctx}
+
+object Impls {
+ def foo[U <: String](c: Ctx): c.Expr[Unit] = {
+ import c.mirror._
+ Literal(Constant(()))
+ }
+}
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..bc880fdf77
--- /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._
+ 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..c83e401afb
--- /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._
+ 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..bc880fdf77
--- /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._
+ 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..523c6b0645
--- /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 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..882867fcab
--- /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._
+ 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..f389231ca6
--- /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 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..f389231ca6
--- /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 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..e171c9d05a
--- /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 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..63371a4a82
--- /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 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..7a093b74ee
--- /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)"
+ 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, 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, Ident(newTypeName("RangeDefault"))),
+ newTermName("foreach")),
+ List(f))
+ }
+ }
+}
+
+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..3c594aed75
--- /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(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..3c594aed75
--- /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(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..02a6a7436b
--- /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 forgot 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..55c677155a
--- /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 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..b58cff19bc
--- /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 forgot 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..d996da1570
--- /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 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..af4877e205
--- /dev/null
+++ b/test/files/run/macro-reify-typetag-typeparams-notags.check
@@ -0,0 +1,2 @@
+ConcreteTypeTag[T]
+ConcreteTypeTag[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..d75b3c72b2
--- /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..d75b3c72b2
--- /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..8225eb0b39
--- /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(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..b432a539fc
--- /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))))
+}
+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..c253f0b1fb
--- /dev/null
+++ b/test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala
@@ -0,0 +1,36 @@
+import scala.reflect.makro.Context
+
+object Macros {
+ def impl_with_macros_enabled(c: Context) = {
+ import c.mirror._
+
+ // todo. doesn't work. why?
+ //val mrPkg = staticModule("scala.reflect.package")
+ //val mrSym = selectTerm(mrPkg, "mirror")
+ //val NullaryMethodType(mrTpe) = mrSym.typeSignature
+ //val mr = newFreeTerm("mr", mrTpe, scala.reflect.mirror, null)
+ //val tree1 = Apply(Select(Ident(mr), newTermName("reify")), List(Literal(Constant(2))))
+
+ 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, null)
+
+ 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-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.scala b/test/files/run/manifests.scala
index 6b6ea80b34..2d64bf18a9 100644
--- a/test/files/run/manifests.scala
+++ b/test/files/run/manifests.scala
@@ -4,29 +4,29 @@ 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)
+
+ 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)
@@ -36,64 +36,57 @@ 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 {
+ def typeCompare[T, U](implicit ev1: Manifest[T], ev2: Manifest[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: Manifest] = List(
- manifest[T] <:< manifest[Any],
- manifest[T] <:< manifest[AnyRef],
- !(manifest[T] <:< manifest[AnyVal])
+ manifest[T].tpe <:< manifest[Any].tpe,
+ manifest[T].tpe <:< manifest[AnyRef].tpe,
+ !(manifest[T].tpe <:< manifest[AnyVal].tpe)
) foreach (assert(_, "assertAnyRef"))
-
+
def assertAnyVal[T: Manifest] = List(
- manifest[T] <:< manifest[Any],
- !(manifest[T] <:< manifest[AnyRef]),
- manifest[T] <:< manifest[AnyVal]
+ manifest[T].tpe <:< manifest[Any].tpe,
+ !(manifest[T].tpe <:< manifest[AnyRef].tpe),
+ manifest[T].tpe <:< manifest[AnyVal].tpe
) 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 +96,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 +104,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 +117,7 @@ object Test
assertSubType[Nothing, List[String]]
assertSubType[Nothing, Null]
assertSameType[Nothing, Nothing]
-
+
// Null
assertSubType[Null, Any]
assertNoRelationship[Null, AnyVal]
@@ -133,7 +126,7 @@ object Test
assertSubType[Null, List[String]]
assertSameType[Null, Null]
assertSuperType[Null, Nothing]
-
+
// Any
assertSameType[Any, Any]
assertSuperType[Any, AnyVal]
@@ -142,7 +135,7 @@ object Test
assertSuperType[Any, List[String]]
assertSuperType[Any, Null]
assertSuperType[Any, Nothing]
-
+
// Misc unrelated types
assertNoRelationship[Unit, AnyRef]
assertNoRelationship[Unit, Int]
diff --git a/test/files/run/patmat_unapp_abstype.check b/test/files/run/patmat_unapp_abstype.check
index ac28ccdb95..72239d16cd 100644
--- a/test/files/run/patmat_unapp_abstype.check
+++ b/test/files/run/patmat_unapp_abstype.check
@@ -1,2 +1,4 @@
TypeRef
none of the above
+Bar
+Foo
diff --git a/test/files/run/patmat_unapp_abstype.flags b/test/files/run/patmat_unapp_abstype.flags
new file mode 100644
index 0000000000..ba80cad69b
--- /dev/null
+++ b/test/files/run/patmat_unapp_abstype.flags
@@ -0,0 +1 @@
+-Xoldpatmat
diff --git a/test/files/run/patmat_unapp_abstype.scala b/test/files/run/patmat_unapp_abstype.scala
index e5adec5c16..45496f08a2 100644
--- a/test/files/run/patmat_unapp_abstype.scala
+++ b/test/files/run/patmat_unapp_abstype.scala
@@ -19,6 +19,11 @@ 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")
}
@@ -32,8 +37,47 @@ trait TypesImpl extends TypesAPI {
//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
+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/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check
index feb0619525..1b6e24ed20 100644
--- a/test/files/run/primitive-sigs-2.check
+++ b/test/files/run/primitive-sigs-2.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.api.TypeTags.scala.reflect.api.TypeTags$ConcreteTypeTag<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/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.scala b/test/files/run/reify_implicits.scala
index 953eabe6c2..60971c3cfb 100644
--- a/test/files/run/reify_implicits.scala
+++ b/test/files/run/reify_implicits.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..bfbf1d653d
--- /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]
+ConcreteTypeTag[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..241b7d4bc3
--- /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))
+ 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/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-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..e439a2a7f4 100644
--- a/test/files/run/repl-power.check
+++ b/test/files/run/repl-power.check
@@ -14,6 +14,7 @@ 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
+warning: there were 2 feature warnings; re-run with -feature for details
tp: $r.global.Type = Array[scala.util.Random]
scala> tp.memberType(Array_apply) // evidence
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/t1195.check b/test/files/run/t1195.check
index d023bc91f7..554e3fd03d 100644
--- a/test/files/run/t1195.check
+++ b/test/files/run/t1195.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
+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.scala b/test/files/run/t1195.scala
index 81ef5bdb0e..93b1dcbd07 100644
--- a/test/files/run/t1195.scala
+++ b/test/files/run/t1195.scala
@@ -6,8 +6,8 @@ object Test {
val f1 = f()
val g1 = g()
val h1 = h()
-
- def m[T: Manifest](x: T) = println(manifest[T])
+
+ def m[T: Manifest](x: T) = println(manifest[T] + ", underlying = " + manifest[T].sym.typeSignature)
def main(args: Array[String]): Unit = {
m(f)
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.check b/test/files/run/t3507.check
new file mode 100644
index 0000000000..50ab029592
--- /dev/null
+++ b/test/files/run/t3507.check
@@ -0,0 +1 @@
+ConcreteTypeTag[_1.type#b.c.type]
diff --git a/test/files/neg/t3507.scala b/test/files/run/t3507.scala
index 32688d3934..3cdd40a881 100644
--- a/test/files/neg/t3507.scala
+++ b/test/files/run/t3507.scala
@@ -5,11 +5,11 @@ class A {
def m = b.c
}
-object Test {
+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: Manifest](x: T) = ()
+
+ def mani[T: Manifest](x: T) = println(manifest[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/t3758.check b/test/files/run/t3758.check
new file mode 100644
index 0000000000..9c6ab655a3
--- /dev/null
+++ b/test/files/run/t3758.check
@@ -0,0 +1,6 @@
+List(String)
+List(Int)
+List(Float)
+List(String)
+List(Int)
+List(Float)
diff --git a/test/files/run/t3758.scala b/test/files/run/t3758.scala
index 18750b0a9c..10bfb5724b 100644
--- a/test/files/run/t3758.scala
+++ b/test/files/run/t3758.scala
@@ -1,10 +1,10 @@
object Test {
def main(args: Array[String]): Unit = {
- assert(classManifest[Array[String]].typeArguments contains classManifest[String])
- assert(classManifest[Array[Int]].typeArguments contains classManifest[Int])
- assert(classManifest[Array[Float]].typeArguments contains classManifest[Float])
- assert(manifest[Array[String]].typeArguments contains manifest[String])
- assert(manifest[Array[Int]].typeArguments contains manifest[Int])
- assert(manifest[Array[Float]].typeArguments contains manifest[Float])
+ println(classManifest[Array[String]].tpe.typeArguments)
+ println(classManifest[Array[Int]].tpe.typeArguments)
+ println(classManifest[Array[Float]].tpe.typeArguments)
+ println(manifest[Array[String]].tpe.typeArguments)
+ println(manifest[Array[Int]].tpe.typeArguments)
+ println(manifest[Array[Float]].tpe.typeArguments)
}
}
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.check b/test/files/run/t4110.check
index 8b005989de..28f220e1fe 100644
--- a/test/files/run/t4110.check
+++ b/test/files/run/t4110.check
@@ -1,2 +1,2 @@
-Object with Test$A with Test$B
-Object with Test$A with Test$B
+ConcreteTypeTag[Test.A with Test.B]
+ConcreteTypeTag[Test.A with Test.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/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..7a728e5164 100644
--- a/test/files/run/t5271_1.check
+++ b/test/files/run/t5271_1.check
@@ -1,11 +1,11 @@
-{
- 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..5baa57c290 100644
--- a/test/files/run/t5271_1.scala
+++ b/test/files/run/t5271_1.scala
@@ -1,13 +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{
+ 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)
}
diff --git a/test/files/run/t5271_2.check b/test/files/run/t5271_2.check
index 27297febb6..d8d6edeffc 100644
--- a/test/files/run/t5271_2.check
+++ b/test/files/run/t5271_2.check
@@ -1,12 +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>();
- ()
- }
- };
- 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))
+}
diff --git a/test/files/run/t5271_2.scala b/test/files/run/t5271_2.scala
index 4bfc574e00..9820ebe692 100644
--- a/test/files/run/t5271_2.scala
+++ b/test/files/run/t5271_2.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 {
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)
}
diff --git a/test/files/run/t5271_3.check b/test/files/run/t5271_3.check
index 9331c78959..1d4f47c5df 100644
--- a/test/files/run/t5271_3.check
+++ b/test/files/run/t5271_3.check
@@ -1,19 +1,19 @@
-{
- 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))
+}
diff --git a/test/files/run/t5271_3.scala b/test/files/run/t5271_3.scala
index a085bdca4c..5fd94f4a2b 100644
--- a/test/files/run/t5271_3.scala
+++ b/test/files/run/t5271_3.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 {
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)
}
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.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.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/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..fd244b40ec
--- /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 ConsoleReporter grabs Console.out too early
+ // todo. and isn't affected by Console.setOut employed by partest to intercept output
+
+ //val toolbox = mkToolBox(reporter = mkConsoleReporter(), 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..78606e2abc
--- /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
+ })
+}
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..7e9259946b
--- /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
+ })
+ println("============compiler messages============")
+ toolbox.reporter.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..cf2420bc17
--- /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))))
+}
+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..7d2707d5e1
--- /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, null)
+
+ 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/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/typetags_core.check b/test/files/run/typetags_core.check
new file mode 100644
index 0000000000..62fcb481ae
--- /dev/null
+++ b/test/files/run/typetags_core.check
@@ -0,0 +1,30 @@
+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]
diff --git a/test/files/run/typetags_core.scala b/test/files/run/typetags_core.scala
new file mode 100644
index 0000000000..883c54b9a8
--- /dev/null
+++ b/test/files/run/typetags_core.scala
@@ -0,0 +1,32 @@
+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]])
+} \ No newline at end of file
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_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/run/virtpatmat_stringinterp.flags b/test/files/run/virtpatmat_stringinterp.flags
new file mode 100644
index 0000000000..e1b37447c9
--- /dev/null
+++ b/test/files/run/virtpatmat_stringinterp.flags
@@ -0,0 +1 @@
+-Xexperimental \ No newline at end of file
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.flags b/test/files/run/virtpatmat_tailcalls_verifyerror.flags
index 9769db9257..3f5a3100e4 100644
--- a/test/files/run/virtpatmat_tailcalls_verifyerror.flags
+++ b/test/files/run/virtpatmat_tailcalls_verifyerror.flags
@@ -1 +1 @@
- -Yvirtpatmat -Xexperimental
+ -Xexperimental
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/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/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/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-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..755d135468
--- /dev/null
+++ b/test/pending/run/t5258a.scala
@@ -0,0 +1,5 @@
+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..8ad1ff114e 100644
--- a/test/pending/run/t5258b.scala
+++ b/test/pending/run/t5258b.scala
@@ -1,14 +1,6 @@
-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{
+ 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..1f76391162 100644
--- a/test/pending/run/t5258c.scala
+++ b/test/pending/run/t5258c.scala
@@ -1,14 +1,6 @@
-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{
+ 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
index afbd8fe465..fae64350e3 100644
--- a/test/pending/run/t5271_1.scala
+++ b/test/pending/run/t5271_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 {
case class C(foo: Int, bar: Int)
- };
-
- val reporter = new ConsoleReporter(new Settings)
- val toolbox = new ToolBox(reporter)
- toolbox.runExpr(code.tree)
+ }.eval
}
diff --git a/test/pending/run/t5271_2.scala b/test/pending/run/t5271_2.scala
index d85d945973..d25e1fe804 100644
--- a/test/pending/run/t5271_2.scala
+++ b/test/pending/run/t5271_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 {
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)
+ }.eval
}
diff --git a/test/pending/run/t5271_3.scala b/test/pending/run/t5271_3.scala
index 5a624de903..65a03ae323 100644
--- a/test/pending/run/t5271_3.scala
+++ b/test/pending/run/t5271_3.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 {
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)
+ }.eval
}
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/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala
new file mode 100644
index 0000000000..3e3d0f01a6
--- /dev/null
+++ b/test/scaladoc/resources/implicits-base-res.scala
@@ -0,0 +1,147 @@
+/**
+ * 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")
+}
+
+/** 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
index c55eb001cf..619c56180b 100644
--- a/test/scaladoc/run/SI-5373.check
+++ b/test/scaladoc/run/SI-5373.check
@@ -1 +1 @@
-model contains 6 documentable templates
+Done.
diff --git a/test/scaladoc/run/SI-5373.scala b/test/scaladoc/run/SI-5373.scala
index af433a1844..0062abbb2a 100644
--- a/test/scaladoc/run/SI-5373.scala
+++ b/test/scaladoc/run/SI-5373.scala
@@ -1,9 +1,9 @@
import scala.tools.nsc.doc.model._
import scala.tools.partest.ScaladocModelTest
-object Test extends ScaladocModelTest {
+object Test extends ScaladocModelTest {
- def code = """
+ override def code = """
import scala.annotation.bridge
package scala.test {
@@ -23,7 +23,7 @@ object Test extends ScaladocModelTest {
// 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._
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/scalacheck/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala
index 69c314a64c..68ca68efdd 100644
--- a/test/scaladoc/scalacheck/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/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