From 814cf34fb00f9ccb001249f4b3445ebc4f9942c9 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 12 Apr 2012 01:59:46 +0200 Subject: Next generation of macros Implements SIP 16: Self-cleaning macros: http://bit.ly/wjjXTZ Features: * Macro defs * Reification * Type tags * Manifests aliased to type tags * Extended reflection API * Several hundred tests * 1111 changed files Not yet implemented: * Reification of refined types * Expr.value splicing * Named and default macro expansions * Intricacies of interaction between macros and implicits * Emission of debug information for macros (compliant with JSR-45) Dedicated to Yuri Alekseyevich Gagarin --- build.xml | 2 +- lib/scala-compiler.jar.desired.sha1 | 2 +- lib/scala-library.jar.desired.sha1 | 2 +- .../scala/reflect/internal/AnnotationInfos.scala | 17 +- .../scala/reflect/internal/CapturedVariables.scala | 36 + .../scala/reflect/internal/Constants.scala | 10 +- .../scala/reflect/internal/Definitions.scala | 96 +- src/compiler/scala/reflect/internal/FreeVars.scala | 60 + .../scala/reflect/internal/Importers.scala | 39 +- .../scala/reflect/internal/NameManglers.scala | 7 +- .../scala/reflect/internal/Positions.scala | 38 +- .../scala/reflect/internal/Reporters.scala | 74 ++ src/compiler/scala/reflect/internal/Required.scala | 2 - src/compiler/scala/reflect/internal/StdNames.scala | 126 +- .../scala/reflect/internal/SymbolTable.scala | 6 +- src/compiler/scala/reflect/internal/Symbols.scala | 89 +- .../scala/reflect/internal/TreeBuildUtil.scala | 62 + src/compiler/scala/reflect/internal/TreeGen.scala | 2 +- src/compiler/scala/reflect/internal/TreeInfo.scala | 194 +++ .../scala/reflect/internal/TreePrinters.scala | 5 +- src/compiler/scala/reflect/internal/Trees.scala | 77 +- src/compiler/scala/reflect/internal/Types.scala | 53 +- .../scala/reflect/makro/runtime/Aliases.scala | 21 + .../reflect/makro/runtime/CapturedVariables.scala | 14 + .../scala/reflect/makro/runtime/Context.scala | 26 + .../scala/reflect/makro/runtime/Enclosures.scala | 36 + .../scala/reflect/makro/runtime/Errors.scala | 6 + .../reflect/makro/runtime/Infrastructure.scala | 34 + .../scala/reflect/makro/runtime/Names.scala | 20 + .../scala/reflect/makro/runtime/Reifiers.scala | 69 + .../scala/reflect/makro/runtime/Reporters.scala | 44 + .../scala/reflect/makro/runtime/Settings.scala | 36 + .../scala/reflect/makro/runtime/Symbols.scala | 8 + .../scala/reflect/makro/runtime/Typers.scala | 78 ++ .../scala/reflect/makro/runtime/Util.scala | 34 + src/compiler/scala/reflect/reify/Errors.scala | 63 + .../scala/reflect/reify/NodePrinters.scala | 111 ++ src/compiler/scala/reflect/reify/Phases.scala | 42 + src/compiler/scala/reflect/reify/Reifiers.scala | 154 +++ .../scala/reflect/reify/codegen/Names.scala | 15 + .../scala/reflect/reify/codegen/Positions.scala | 18 + .../scala/reflect/reify/codegen/Symbols.scala | 111 ++ .../scala/reflect/reify/codegen/Trees.scala | 220 ++++ .../scala/reflect/reify/codegen/Types.scala | 226 ++++ .../scala/reflect/reify/codegen/Util.scala | 112 ++ src/compiler/scala/reflect/reify/package.scala | 22 + .../scala/reflect/reify/phases/Calculate.scala | 61 + .../scala/reflect/reify/phases/Metalevels.scala | 148 +++ .../scala/reflect/reify/phases/Reify.scala | 42 + .../scala/reflect/reify/phases/Reshape.scala | 296 +++++ .../scala/reflect/runtime/ClassLoaders.scala | 25 + .../scala/reflect/runtime/ConversionUtil.scala | 1 + .../scala/reflect/runtime/JavaToScala.scala | 209 ++- src/compiler/scala/reflect/runtime/Loaders.scala | 130 -- src/compiler/scala/reflect/runtime/Memoizer.scala | 15 - src/compiler/scala/reflect/runtime/Mirror.scala | 36 +- .../scala/reflect/runtime/RuntimeTypes.scala | 27 - .../scala/reflect/runtime/SymbolLoaders.scala | 135 ++ .../scala/reflect/runtime/SymbolTable.scala | 23 +- .../reflect/runtime/SynchronizedSymbols.scala | 7 +- src/compiler/scala/reflect/runtime/ToolBoxes.scala | 363 ++++-- .../scala/reflect/runtime/TreeBuildUtil.scala | 49 - src/compiler/scala/reflect/runtime/Universe.scala | 20 +- src/compiler/scala/reflect/runtime/package.scala | 5 + src/compiler/scala/tools/cmd/FromString.scala | 4 +- src/compiler/scala/tools/nsc/ClassLoaders.scala | 64 + src/compiler/scala/tools/nsc/Global.scala | 46 +- src/compiler/scala/tools/nsc/MacroContext.scala | 10 - src/compiler/scala/tools/nsc/ReflectGlobal.scala | 7 +- src/compiler/scala/tools/nsc/ReflectMain.scala | 11 +- src/compiler/scala/tools/nsc/ToolBoxes.scala | 85 ++ src/compiler/scala/tools/nsc/ast/DocComments.scala | 4 +- src/compiler/scala/tools/nsc/ast/FreeVars.scala | 26 + .../scala/tools/nsc/ast/NodePrinters.scala | 32 +- src/compiler/scala/tools/nsc/ast/Positions.scala | 44 + src/compiler/scala/tools/nsc/ast/Reifiers.scala | 761 ----------- .../scala/tools/nsc/ast/ReifyPrinters.scala | 75 -- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 16 - src/compiler/scala/tools/nsc/ast/Trees.scala | 124 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 129 +- .../scala/tools/nsc/ast/parser/Scanners.scala | 3 +- .../scala/tools/nsc/ast/parser/Tokens.scala | 1 + .../scala/tools/nsc/backend/jvm/GenJVM.scala | 2 +- .../scala/tools/nsc/backend/jvm/GenJVMUtil.scala | 2 +- .../scala/tools/nsc/backend/msil/GenMSIL.scala | 6 +- .../scala/tools/nsc/interactive/Global.scala | 2 +- .../tools/nsc/interactive/RangePositions.scala | 2 +- .../scala/tools/nsc/interpreter/IMain.scala | 12 +- .../scala/tools/nsc/interpreter/Power.scala | 1 - .../scala/tools/nsc/interpreter/ReplVals.scala | 2 +- .../scala/tools/nsc/interpreter/RichClass.scala | 2 +- .../scala/tools/nsc/interpreter/TypeStrings.scala | 9 +- .../tools/nsc/reporters/AbstractReporter.scala | 11 +- .../tools/nsc/reporters/ConsoleReporter.scala | 1 - .../scala/tools/nsc/scratchpad/Executor.scala | 2 +- .../scala/tools/nsc/settings/MutableSettings.scala | 2 +- .../scala/tools/nsc/settings/ScalaSettings.scala | 149 ++- .../scala/tools/nsc/symtab/Positions.scala | 30 - .../scala/tools/nsc/symtab/classfile/Pickler.scala | 6 +- .../scala/tools/nsc/transform/AddInterfaces.scala | 2 +- .../scala/tools/nsc/transform/CleanUp.scala | 2 +- .../scala/tools/nsc/transform/Erasure.scala | 4 +- .../scala/tools/nsc/transform/LambdaLift.scala | 18 +- src/compiler/scala/tools/nsc/transform/Mixin.scala | 2 +- .../scala/tools/nsc/transform/UnCurry.scala | 14 +- .../tools/nsc/typechecker/ContextErrors.scala | 33 +- .../scala/tools/nsc/typechecker/Contexts.scala | 31 +- .../scala/tools/nsc/typechecker/Implicits.scala | 190 ++- .../scala/tools/nsc/typechecker/Infer.scala | 24 +- .../scala/tools/nsc/typechecker/Macros.scala | 1361 +++++++++++++++++--- .../tools/nsc/typechecker/MethodSynthesis.scala | 14 +- .../scala/tools/nsc/typechecker/Namers.scala | 31 +- .../scala/tools/nsc/typechecker/RefChecks.scala | 6 + .../tools/nsc/typechecker/TypeDiagnostics.scala | 20 +- .../scala/tools/nsc/typechecker/Typers.scala | 180 ++- src/compiler/scala/tools/nsc/util/ClassPath.scala | 2 +- src/compiler/scala/tools/nsc/util/Position.scala | 126 +- src/compiler/scala/tools/reflect/package.scala | 2 +- src/library/scala/Predef.scala | 29 +- .../scala/collection/mutable/ArrayBuilder.scala | 18 +- .../scala/collection/mutable/ArrayOps.scala | 10 +- .../scala/collection/mutable/WrappedArray.scala | 2 +- .../collection/mutable/WrappedArrayBuilder.scala | 14 +- src/library/scala/reflect/ArrayTags.scala | 19 + src/library/scala/reflect/ClassManifest.scala | 263 ---- src/library/scala/reflect/ClassTags.scala | 158 +++ src/library/scala/reflect/Manifest.scala | 302 ----- src/library/scala/reflect/NoManifest.scala | 15 - src/library/scala/reflect/OptManifest.scala | 17 - src/library/scala/reflect/ReflectionUtils.scala | 26 +- src/library/scala/reflect/TagMaterialization.scala | 154 +++ src/library/scala/reflect/api/Attachments.scala | 16 + src/library/scala/reflect/api/ClassLoaders.scala | 16 + src/library/scala/reflect/api/Exprs.scala | 48 + src/library/scala/reflect/api/FreeVars.scala | 42 + src/library/scala/reflect/api/Importers.scala | 19 + src/library/scala/reflect/api/Mirror.scala | 17 +- src/library/scala/reflect/api/Positions.scala | 215 +++- src/library/scala/reflect/api/Reporters.scala | 65 + src/library/scala/reflect/api/RuntimeTypes.scala | 20 - src/library/scala/reflect/api/Scopes.scala | 9 +- .../scala/reflect/api/StandardDefinitions.scala | 68 +- src/library/scala/reflect/api/StandardNames.scala | 156 ++- src/library/scala/reflect/api/Symbols.scala | 61 +- src/library/scala/reflect/api/ToolBoxes.scala | 90 ++ src/library/scala/reflect/api/TreeBuildUtil.scala | 111 +- src/library/scala/reflect/api/TreePrinters.scala | 6 +- src/library/scala/reflect/api/Trees.scala | 178 ++- src/library/scala/reflect/api/TypeTags.scala | 193 +++ src/library/scala/reflect/api/Types.scala | 91 +- src/library/scala/reflect/api/Universe.scala | 79 +- src/library/scala/reflect/macro/Context.scala | 36 - src/library/scala/reflect/makro/Aliases.scala | 26 + .../scala/reflect/makro/CapturedVariables.scala | 20 + src/library/scala/reflect/makro/Context.scala | 59 + src/library/scala/reflect/makro/Enclosures.scala | 53 + .../scala/reflect/makro/Infrastructure.scala | 73 ++ src/library/scala/reflect/makro/Names.scala | 14 + src/library/scala/reflect/makro/Reifiers.scala | 82 ++ src/library/scala/reflect/makro/Reporters.scala | 39 + src/library/scala/reflect/makro/Settings.scala | 38 + src/library/scala/reflect/makro/Symbols.scala | 17 + src/library/scala/reflect/makro/Typers.scala | 85 ++ src/library/scala/reflect/makro/Util.scala | 31 + .../scala/reflect/makro/internal/macroImpl.scala | 5 + .../scala/reflect/makro/internal/typeTagImpl.scala | 133 ++ src/library/scala/reflect/package.scala | 43 +- src/library/scala/runtime/ScalaRunTime.scala | 2 +- src/library/scala/util/Marshal.scala | 3 +- .../tools/partest/nest/ConsoleFileManager.scala | 1 + .../scala/tools/partest/nest/TestFile.scala | 4 +- src/partest/scala/tools/partest/nest/Worker.scala | 16 +- test/files/codelib/code.jar.desired.sha1 | 2 +- test/files/jvm/interpreter.check | 738 +++++------ test/files/jvm/interpreter.scala | 9 +- test/files/jvm/manifests.check | 55 - .../files/jvm/manifests.check.temporarily.disabled | 55 + test/files/jvm/manifests.scala | 119 -- .../files/jvm/manifests.scala.temporarily.disabled | 109 ++ test/files/macros/Printf.scala | 39 - test/files/macros/Test.scala | 8 - test/files/macros/macros_v0001.bat | 40 - test/files/macros/macros_v0001.sh | 30 - test/files/neg/checksensible.check | 200 +-- test/files/neg/classtags_contextbound_a.check | 4 + test/files/neg/classtags_contextbound_a.scala | 4 + test/files/neg/classtags_contextbound_b.check | 4 + test/files/neg/classtags_contextbound_b.scala | 5 + test/files/neg/classtags_contextbound_c.check | 4 + test/files/neg/classtags_contextbound_c.scala | 5 + .../neg/macro-argtype-mismatch/Macros_1.scala | 3 - test/files/neg/macro-argtype-mismatch/Test_2.scala | 4 - test/files/neg/macro-basic-mamdmi.check | 5 + test/files/neg/macro-basic-mamdmi.flags | 1 + .../macro-basic-mamdmi/Impls_Macros_Test_1.scala | 37 + test/files/neg/macro-cyclic.check | 4 + test/files/neg/macro-cyclic.flags | 1 + test/files/neg/macro-cyclic/Impls_Macros_1.scala | 25 + ...cro-deprecate-dont-touch-backquotedidents.check | 14 + .../Macros_Bind_12.scala | 6 + .../Macros_Class_4.scala | 3 + .../Macros_Class_5.scala | 3 + .../Macros_Def_13.scala | 3 + .../Macros_Object_6.scala | 3 + .../Macros_Object_7.scala | 3 + .../Macros_Package_10.scala | 3 + .../Macros_Package_11.scala | 3 + .../Macros_Trait_8.scala | 3 + .../Macros_Trait_9.scala | 3 + .../Macros_Type_3.scala | 3 + .../Macros_Val_1.scala | 3 + .../Macros_Var_2.scala | 3 + .../Main.scala | 2 + test/files/neg/macro-deprecate-idents.check | 50 + .../macro-deprecate-idents/Macros_Bind_12.scala | 6 + .../macro-deprecate-idents/Macros_Class_4.scala | 3 + .../macro-deprecate-idents/Macros_Class_5.scala | 3 + .../neg/macro-deprecate-idents/Macros_Def_13.scala | 3 + .../macro-deprecate-idents/Macros_Object_6.scala | 3 + .../macro-deprecate-idents/Macros_Object_7.scala | 3 + .../macro-deprecate-idents/Macros_Package_10.scala | 3 + .../macro-deprecate-idents/Macros_Package_11.scala | 3 + .../macro-deprecate-idents/Macros_Trait_8.scala | 3 + .../macro-deprecate-idents/Macros_Trait_9.scala | 3 + .../neg/macro-deprecate-idents/Macros_Type_3.scala | 3 + .../neg/macro-deprecate-idents/Macros_Val_1.scala | 3 + .../neg/macro-deprecate-idents/Macros_Var_2.scala | 3 + test/files/neg/macro-deprecate-idents/Main.scala | 2 + test/files/neg/macro-invalidimpl-a.check | 4 + test/files/neg/macro-invalidimpl-a.flags | 1 + test/files/neg/macro-invalidimpl-a/Impls_1.scala | 5 + .../neg/macro-invalidimpl-a/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-b.check | 4 + test/files/neg/macro-invalidimpl-b.flags | 1 + test/files/neg/macro-invalidimpl-b/Impls_1.scala | 5 + .../neg/macro-invalidimpl-b/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-c.check | 4 + test/files/neg/macro-invalidimpl-c.flags | 1 + .../neg/macro-invalidimpl-c/Impls_Macros_1.scala | 9 + test/files/neg/macro-invalidimpl-c/Test_2.scala | 3 + test/files/neg/macro-invalidimpl-d.check | 4 + test/files/neg/macro-invalidimpl-d.flags | 1 + test/files/neg/macro-invalidimpl-d/Impls_1.scala | 7 + .../neg/macro-invalidimpl-d/Macros_Test_2.scala | 7 + test/files/neg/macro-invalidimpl-e.check | 13 + test/files/neg/macro-invalidimpl-e.flags | 1 + test/files/neg/macro-invalidimpl-e/Impls_1.scala | 6 + .../neg/macro-invalidimpl-e/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-f.check | 7 + test/files/neg/macro-invalidimpl-f.flags | 1 + test/files/neg/macro-invalidimpl-f/Impls_1.scala | 11 + .../neg/macro-invalidimpl-f/Macros_Test_2.scala | 9 + test/files/neg/macro-invalidimpl-g.check | 7 + test/files/neg/macro-invalidimpl-g.flags | 1 + test/files/neg/macro-invalidimpl-g/Impls_1.scala | 11 + .../neg/macro-invalidimpl-g/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidimpl-h.check | 4 + test/files/neg/macro-invalidimpl-h.flags | 1 + test/files/neg/macro-invalidimpl-h/Impls_1.scala | 5 + .../neg/macro-invalidimpl-h/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidret-nontree.check | 7 + test/files/neg/macro-invalidret-nontree.flags | 1 + .../neg/macro-invalidret-nontree/Impls_1.scala | 5 + .../macro-invalidret-nontree/Macros_Test_2.scala | 8 + .../neg/macro-invalidret-nonuniversetree.check | 7 + .../neg/macro-invalidret-nonuniversetree.flags | 1 + .../macro-invalidret-nonuniversetree/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-a.check | 6 + test/files/neg/macro-invalidshape-a.flags | 1 + test/files/neg/macro-invalidshape-a/Impls_1.scala | 5 + .../neg/macro-invalidshape-a/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-b.check | 6 + test/files/neg/macro-invalidshape-b.flags | 1 + test/files/neg/macro-invalidshape-b/Impls_1.scala | 5 + .../neg/macro-invalidshape-b/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-c.check | 6 + test/files/neg/macro-invalidshape-c.flags | 1 + test/files/neg/macro-invalidshape-c/Impls_1.scala | 5 + .../neg/macro-invalidshape-c/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidshape-d.check | 4 + test/files/neg/macro-invalidshape-d.flags | 1 + test/files/neg/macro-invalidshape-d/Impls_1.scala | 5 + .../neg/macro-invalidshape-d/Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-context-bounds.check | 4 + .../neg/macro-invalidsig-context-bounds.flags | 1 + .../macro-invalidsig-context-bounds/Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-badargc.check | 7 + test/files/neg/macro-invalidsig-ctx-badargc.flags | 1 + .../neg/macro-invalidsig-ctx-badargc/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-badtype.check | 7 + test/files/neg/macro-invalidsig-ctx-badtype.flags | 1 + .../neg/macro-invalidsig-ctx-badtype/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-ctx-badvarargs.check | 7 + .../neg/macro-invalidsig-ctx-badvarargs.flags | 1 + .../macro-invalidsig-ctx-badvarargs/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidsig-ctx-noctx.check | 7 + test/files/neg/macro-invalidsig-ctx-noctx.flags | 1 + .../neg/macro-invalidsig-ctx-noctx/Impls_1.scala | 5 + .../macro-invalidsig-ctx-noctx/Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-implicit-params.check | 4 + .../neg/macro-invalidsig-implicit-params.flags | 1 + .../Impls_Macros_1.scala | 18 + .../macro-invalidsig-implicit-params/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badargc.check | 7 + .../neg/macro-invalidsig-params-badargc.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-invalidsig-params-badargc/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badtype.check | 7 + .../neg/macro-invalidsig-params-badtype.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-invalidsig-params-badtype/Test_2.scala | 4 + .../neg/macro-invalidsig-params-badvarargs.check | 7 + .../neg/macro-invalidsig-params-badvarargs.flags | 1 + .../Impls_Macros_1.scala | 9 + .../Test_2.scala | 4 + .../neg/macro-invalidsig-params-namemismatch.check | 7 + .../neg/macro-invalidsig-params-namemismatch.flags | 1 + .../Impls_Macros_1.scala | 9 + .../Test_2.scala | 4 + .../neg/macro-invalidsig-tparams-badtype.check | 7 + .../neg/macro-invalidsig-tparams-badtype.flags | 1 + .../macro-invalidsig-tparams-badtype/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-bounds-a.check | 4 + .../neg/macro-invalidsig-tparams-bounds-a.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-bounds-b.check | 4 + .../neg/macro-invalidsig-tparams-bounds-b.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-notparams-a.check | 4 + .../neg/macro-invalidsig-tparams-notparams-a.flags | 1 + .../Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidsig-tparams-notparams-b.check | 4 + .../neg/macro-invalidsig-tparams-notparams-b.flags | 1 + .../Impls_1.scala | 11 + .../Macros_Test_2.scala | 11 + .../neg/macro-invalidsig-tparams-notparams-c.check | 4 + .../neg/macro-invalidsig-tparams-notparams-c.flags | 1 + .../Impls_1.scala | 11 + .../Macros_Test_2.scala | 11 + test/files/neg/macro-invalidusage-badargs.check | 6 + test/files/neg/macro-invalidusage-badargs.flags | 1 + .../neg/macro-invalidusage-badargs/Impls_1.scala | 5 + .../macro-invalidusage-badargs/Macros_Test_2.scala | 8 + test/files/neg/macro-invalidusage-badbounds.check | 4 + test/files/neg/macro-invalidusage-badbounds.flags | 1 + .../neg/macro-invalidusage-badbounds/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-invalidusage-badtargs.check | 4 + test/files/neg/macro-invalidusage-badtargs.flags | 1 + .../neg/macro-invalidusage-badtargs/Impls_1.scala | 5 + .../Macros_Test_2.scala | 8 + .../neg/macro-invalidusage-methodvaluesyntax.check | 4 + .../neg/macro-invalidusage-methodvaluesyntax.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 8 + test/files/neg/macro-keyword.check | 49 + test/files/neg/macro-keyword.flags | 1 + test/files/neg/macro-keyword/Macros_Bind_12.scala | 6 + test/files/neg/macro-keyword/Macros_Class_4.scala | 3 + test/files/neg/macro-keyword/Macros_Class_5.scala | 3 + test/files/neg/macro-keyword/Macros_Def_13.scala | 3 + test/files/neg/macro-keyword/Macros_Object_6.scala | 3 + test/files/neg/macro-keyword/Macros_Object_7.scala | 3 + .../neg/macro-keyword/Macros_Package_10.scala | 3 + .../neg/macro-keyword/Macros_Package_11.scala | 3 + test/files/neg/macro-keyword/Macros_Trait_8.scala | 3 + test/files/neg/macro-keyword/Macros_Trait_9.scala | 3 + test/files/neg/macro-keyword/Macros_Type_3.scala | 3 + test/files/neg/macro-keyword/Macros_Val_1.scala | 3 + test/files/neg/macro-keyword/Macros_Var_2.scala | 3 + test/files/neg/macro-noexpand.check | 2 +- test/files/neg/macro-noexpand/Impls_1.scala | 5 + test/files/neg/macro-noexpand/Macros_1.scala | 3 - test/files/neg/macro-noexpand/Macros_Test_2.scala | 8 + test/files/neg/macro-noexpand/Test_2.scala | 4 - .../files/neg/macro-noncompilertree/Macros_1.scala | 3 - test/files/neg/macro-nontree/Macros_1.scala | 3 - test/files/neg/macro-nontypeablebody.check | 4 + test/files/neg/macro-nontypeablebody.flags | 1 + test/files/neg/macro-nontypeablebody/Impls_1.scala | 5 + .../neg/macro-nontypeablebody/Macros_Test_2.scala | 8 + ...verride-macro-overrides-abstract-method-a.check | 5 + ...verride-macro-overrides-abstract-method-a.flags | 1 + .../Impls_Macros_1.scala | 13 + .../Test_2.scala | 4 + ...verride-macro-overrides-abstract-method-b.check | 5 + ...verride-macro-overrides-abstract-method-b.flags | 1 + .../Impls_Macros_1.scala | 13 + .../Test_2.scala | 4 + .../macro-override-method-overrides-macro.check | 5 + .../macro-override-method-overrides-macro.flags | 1 + .../Impls_1.scala | 15 + .../Macros_Test_2.scala | 15 + ...o-reify-groundtypetag-hktypeparams-notags.check | 7 + .../Test.scala | 9 + ...cro-reify-groundtypetag-typeparams-notags.check | 7 + .../Test.scala | 9 + .../neg/macro-reify-groundtypetag-usetypetag.check | 7 + .../Test.scala | 9 + test/files/neg/macro-without-xmacros-a.check | 10 + .../neg/macro-without-xmacros-a/Impls_1.scala | 18 + .../neg/macro-without-xmacros-a/Macros_2.scala | 12 + .../files/neg/macro-without-xmacros-a/Test_3.scala | 4 + test/files/neg/macro-without-xmacros-b.check | 10 + .../neg/macro-without-xmacros-b/Impls_1.scala | 18 + .../neg/macro-without-xmacros-b/Macros_2.scala | 10 + .../files/neg/macro-without-xmacros-b/Test_3.scala | 4 + test/files/neg/reify_ann2a.check | 4 - test/files/neg/reify_ann2a.scala | 30 - test/files/neg/reify_ann2b.check | 11 +- test/files/neg/reify_ann2b.scala | 11 +- test/files/neg/t2386.check | 8 +- test/files/neg/t2775.check | 8 +- test/files/neg/t3507.check | 8 +- test/files/neg/t3692.check | 15 +- test/files/neg/t5334_1.check | 4 + test/files/neg/t5334_1.scala | 8 + test/files/neg/t5334_2.check | 4 + test/files/neg/t5334_2.scala | 8 + test/files/pos/implicits.scala | 89 -- .../files/pos/implicits.scala.temporarily.disabled | 89 ++ test/files/pos/liftcode_polymorphic.scala | 4 +- test/files/pos/macros.flags | 1 - test/files/pos/macros.scala | 8 - test/files/pos/manifest1.scala | 21 - .../files/pos/manifest1.scala.temporarily.disabled | 21 + test/files/pos/t5223.scala | 6 +- test/files/pos/t531.scala | 5 +- test/files/pos/t532.scala | 5 +- test/files/run/classtags_contextbound.check | 1 + test/files/run/classtags_contextbound.scala | 5 + test/files/run/classtags_core.check | 30 + test/files/run/classtags_core.scala | 32 + test/files/run/existentials3.check | 22 - .../run/existentials3.check.temporarily.disabled | 22 + test/files/run/existentials3.scala | 73 -- .../run/existentials3.scala.temporarily.disabled | 73 ++ test/files/run/groundtypetags_core.check | 30 + test/files/run/groundtypetags_core.scala | 32 + test/files/run/macro-abort-fresh.check | 6 + test/files/run/macro-abort-fresh.flags | 1 + test/files/run/macro-abort-fresh/Macros_1.scala | 15 + test/files/run/macro-abort-fresh/Test_2.scala | 6 + test/files/run/macro-basic-ma-md-mi.check | 1 + test/files/run/macro-basic-ma-md-mi.flags | 1 + test/files/run/macro-basic-ma-md-mi/Impls_1.scala | 21 + test/files/run/macro-basic-ma-md-mi/Macros_2.scala | 10 + test/files/run/macro-basic-ma-md-mi/Test_3.scala | 4 + test/files/run/macro-basic-ma-mdmi.check | 1 + test/files/run/macro-basic-ma-mdmi.flags | 1 + .../run/macro-basic-ma-mdmi/Impls_Macros_1.scala | 32 + test/files/run/macro-basic-ma-mdmi/Test_2.scala | 4 + test/files/run/macro-basic-mamd-mi.check | 1 + test/files/run/macro-basic-mamd-mi.flags | 1 + test/files/run/macro-basic-mamd-mi/Impls_1.scala | 19 + .../run/macro-basic-mamd-mi/Macros_Test_2.scala | 15 + test/files/run/macro-basic.check | 1 - test/files/run/macro-basic.flags | 1 - test/files/run/macro-basic/Macros_1.scala | 10 - test/files/run/macro-basic/Test_2.scala | 4 - test/files/run/macro-bodyexpandstoimpl.check | 1 + test/files/run/macro-bodyexpandstoimpl.flags | 1 + .../run/macro-bodyexpandstoimpl/Impls_1.scala | 12 + .../macro-bodyexpandstoimpl/Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-annotation.check | 1 + test/files/run/macro-declared-in-annotation.flags | 1 + .../run/macro-declared-in-annotation/Impls_1.scala | 11 + .../macro-declared-in-annotation/Macros_2.scala | 8 + .../run/macro-declared-in-annotation/Test_3.scala | 3 + test/files/run/macro-declared-in-anonymous.check | 2 + test/files/run/macro-declared-in-anonymous.flags | 1 + .../run/macro-declared-in-anonymous/Impls_1.scala | 11 + .../Macros_Test_2.scala | 4 + test/files/run/macro-declared-in-block.check | 2 + test/files/run/macro-declared-in-block.flags | 1 + .../run/macro-declared-in-block/Impls_1.scala | 11 + .../macro-declared-in-block/Macros_Test_2.scala | 6 + test/files/run/macro-declared-in-class-class.check | 2 + test/files/run/macro-declared-in-class-class.flags | 1 + .../macro-declared-in-class-class/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../files/run/macro-declared-in-class-object.check | 2 + .../files/run/macro-declared-in-class-object.flags | 1 + .../macro-declared-in-class-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-class.check | 2 + test/files/run/macro-declared-in-class.flags | 1 + .../run/macro-declared-in-class/Impls_1.scala | 11 + .../macro-declared-in-class/Macros_Test_2.scala | 7 + .../run/macro-declared-in-default-param.check | 5 + .../run/macro-declared-in-default-param.flags | 1 + .../macro-declared-in-default-param/Impls_1.scala | 11 + .../Macros_Test_2.scala | 7 + .../run/macro-declared-in-implicit-class.check | 2 + .../run/macro-declared-in-implicit-class.flags | 1 + .../Impls_Macros_1.scala | 19 + .../macro-declared-in-implicit-class/Test_2.scala | 4 + test/files/run/macro-declared-in-method.check | 2 + test/files/run/macro-declared-in-method.flags | 1 + .../run/macro-declared-in-method/Impls_1.scala | 11 + .../macro-declared-in-method/Macros_Test_2.scala | 8 + .../files/run/macro-declared-in-object-class.check | 2 + .../files/run/macro-declared-in-object-class.flags | 1 + .../macro-declared-in-object-class/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../run/macro-declared-in-object-object.check | 2 + .../run/macro-declared-in-object-object.flags | 1 + .../macro-declared-in-object-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + test/files/run/macro-declared-in-object.check | 2 + test/files/run/macro-declared-in-object.flags | 1 + .../run/macro-declared-in-object/Impls_1.scala | 11 + .../macro-declared-in-object/Macros_Test_2.scala | 7 + .../run/macro-declared-in-package-object.check | 2 + .../run/macro-declared-in-package-object.flags | 1 + .../macro-declared-in-package-object/Impls_1.scala | 11 + .../Macros_Test_2.scala | 8 + test/files/run/macro-declared-in-refinement.check | 2 + test/files/run/macro-declared-in-refinement.flags | 1 + .../run/macro-declared-in-refinement/Impls_1.scala | 11 + .../Macros_Test_2.scala | 6 + test/files/run/macro-declared-in-trait.check | 15 + test/files/run/macro-declared-in-trait.flags | 1 + .../run/macro-declared-in-trait/Impls_1.scala | 11 + .../macro-declared-in-trait/Macros_Test_2.scala | 13 + test/files/run/macro-def-infer-return-type-a.check | 1 + test/files/run/macro-def-infer-return-type-a.flags | 1 + .../macro-def-infer-return-type-a/Impls_1.scala | 5 + .../Macros_Test_2.scala | 4 + test/files/run/macro-def-infer-return-type-b.check | 6 + test/files/run/macro-def-infer-return-type-b.flags | 1 + .../Impls_Macros_1.scala | 10 + .../run/macro-def-infer-return-type-b/Test_2.scala | 6 + test/files/run/macro-def-infer-return-type-c.check | 1 + test/files/run/macro-def-infer-return-type-c.flags | 1 + .../macro-def-infer-return-type-c/Impls_1.scala | 5 + .../Macros_Test_2.scala | 4 + test/files/run/macro-def-path-dependent-a.check | 1 + test/files/run/macro-def-path-dependent-a.flags | 1 + .../Impls_Macros_1.scala | 21 + .../run/macro-def-path-dependent-a/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-b.check | 1 + test/files/run/macro-def-path-dependent-b.flags | 1 + .../Impls_Macros_1.scala | 20 + .../run/macro-def-path-dependent-b/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-c.check | 1 + test/files/run/macro-def-path-dependent-c.flags | 1 + .../Impls_Macros_1.scala | 20 + .../run/macro-def-path-dependent-c/Test_2.scala | 3 + test/files/run/macro-def-path-dependent-d.check | 1 + test/files/run/macro-def-path-dependent-d.flags | 1 + .../Impls_Macros_1.scala | 8 + .../run/macro-def-path-dependent-d/Test_2.scala | 3 + .../macro-expand-implicit-macro-has-implicit.check | 1 + .../macro-expand-implicit-macro-has-implicit.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 5 + .../macro-expand-implicit-macro-is-implicit.check | 2 + .../macro-expand-implicit-macro-is-implicit.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 10 + .../run/macro-expand-implicit-macro-is-val.check | 1 + .../run/macro-expand-implicit-macro-is-val.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 5 + .../run/macro-expand-implicit-macro-is-view.check | 1 + .../run/macro-expand-implicit-macro-is-view.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 9 + .../files/run/macro-expand-multiple-arglists.check | 1 + .../files/run/macro-expand-multiple-arglists.flags | 1 + .../macro-expand-multiple-arglists/Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-nullary-generic.check | 6 + test/files/run/macro-expand-nullary-generic.flags | 1 + .../run/macro-expand-nullary-generic/Impls_1.scala | 14 + .../Macros_Test_2.scala | 15 + .../run/macro-expand-nullary-nongeneric.check | 6 + .../run/macro-expand-nullary-nongeneric.flags | 1 + .../macro-expand-nullary-nongeneric/Impls_1.scala | 14 + .../Macros_Test_2.scala | 15 + test/files/run/macro-expand-overload.check | 6 + test/files/run/macro-expand-overload.flags | 1 + test/files/run/macro-expand-overload/Impls_1.scala | 15 + .../run/macro-expand-overload/Macros_Test_2.scala | 20 + test/files/run/macro-expand-override.check | 15 + test/files/run/macro-expand-override.flags | 1 + test/files/run/macro-expand-override/Impls_1.scala | 15 + .../run/macro-expand-override/Macros_Test_2.scala | 43 + test/files/run/macro-expand-recursive.check | 1 + test/files/run/macro-expand-recursive.flags | 1 + .../files/run/macro-expand-recursive/Impls_1.scala | 15 + .../run/macro-expand-recursive/Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-bounds-a.check | 0 test/files/run/macro-expand-tparams-bounds-a.flags | 1 + .../macro-expand-tparams-bounds-a/Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-bounds-b.check | 0 test/files/run/macro-expand-tparams-bounds-b.flags | 1 + .../macro-expand-tparams-bounds-b/Impls_1.scala | 10 + .../Macros_Test_2.scala | 10 + test/files/run/macro-expand-tparams-explicit.check | 1 + test/files/run/macro-expand-tparams-explicit.flags | 1 + .../macro-expand-tparams-explicit/Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-tparams-implicit.check | 2 + test/files/run/macro-expand-tparams-implicit.flags | 1 + .../macro-expand-tparams-implicit/Impls_1.scala | 10 + .../Macros_Test_2.scala | 5 + .../run/macro-expand-tparams-only-in-impl.flags | 1 + .../Impls_1.scala | 8 + .../Macros_Test_2.scala | 8 + test/files/run/macro-expand-tparams-optional.check | 1 + test/files/run/macro-expand-tparams-optional.flags | 1 + .../macro-expand-tparams-optional/Impls_1.scala | 9 + .../Macros_Test_2.scala | 4 + test/files/run/macro-expand-tparams-prefix-a.check | 4 + test/files/run/macro-expand-tparams-prefix-a.flags | 1 + .../macro-expand-tparams-prefix-a/Impls_1.scala | 10 + .../Macros_Test_2.scala | 10 + test/files/run/macro-expand-tparams-prefix-b.check | 2 + test/files/run/macro-expand-tparams-prefix-b.flags | 1 + .../macro-expand-tparams-prefix-b/Impls_1.scala | 11 + .../Macros_Test_2.scala | 10 + .../files/run/macro-expand-tparams-prefix-c1.check | 3 + .../files/run/macro-expand-tparams-prefix-c1.flags | 1 + .../macro-expand-tparams-prefix-c1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 11 + .../files/run/macro-expand-tparams-prefix-c2.check | 3 + .../files/run/macro-expand-tparams-prefix-c2.flags | 1 + .../Impls_Macros_1.scala | 18 + .../macro-expand-tparams-prefix-c2/Test_2.scala | 5 + .../files/run/macro-expand-tparams-prefix-d1.check | 3 + .../files/run/macro-expand-tparams-prefix-d1.flags | 1 + .../macro-expand-tparams-prefix-d1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 11 + ...pand-varargs-explicit-over-nonvarargs-bad.check | 4 + ...pand-varargs-explicit-over-nonvarargs-bad.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 10 + ...and-varargs-explicit-over-nonvarargs-good.check | 1 + ...and-varargs-explicit-over-nonvarargs-good.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 8 + ...acro-expand-varargs-explicit-over-varargs.check | 1 + ...acro-expand-varargs-explicit-over-varargs.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 8 + ...o-expand-varargs-implicit-over-nonvarargs.check | 1 + ...o-expand-varargs-implicit-over-nonvarargs.flags | 1 + .../Impls_1.scala | 9 + .../Macros_Test_2.scala | 7 + ...acro-expand-varargs-implicit-over-varargs.check | 1 + ...acro-expand-varargs-implicit-over-varargs.flags | 1 + .../Impls_1.scala | 13 + .../Macros_Test_2.scala | 7 + test/files/run/macro-impl-default-params.check | 5 + test/files/run/macro-impl-default-params.flags | 1 + .../macro-impl-default-params/Impls_Macros_1.scala | 20 + .../run/macro-impl-default-params/Test_2.scala | 4 + test/files/run/macro-impl-rename-context.check | 2 + test/files/run/macro-impl-rename-context.flags | 1 + .../macro-impl-rename-context/Impls_Macros_1.scala | 15 + .../run/macro-impl-rename-context/Test_2.scala | 4 + ...-invalidret-doesnt-conform-to-def-rettype.check | 5 + ...-invalidret-doesnt-conform-to-def-rettype.flags | 1 + .../Impls_Macros_1.scala | 12 + .../Test_2.scala | 6 + ...invalidret-doesnt-conform-to-impl-rettype.check | 0 ...invalidret-doesnt-conform-to-impl-rettype.flags | 1 + test/files/run/macro-invalidret-nontypeable.check | 3 + test/files/run/macro-invalidret-nontypeable.flags | 1 + .../Impls_Macros_1.scala | 13 + .../run/macro-invalidret-nontypeable/Test_2.scala | 6 + test/files/run/macro-invalidusage-badret.check | 5 + test/files/run/macro-invalidusage-badret.flags | 1 + .../macro-invalidusage-badret/Impls_Macros_1.scala | 9 + .../run/macro-invalidusage-badret/Test_2.scala | 6 + .../macro-invalidusage-partialapplication.check | 3 + .../macro-invalidusage-partialapplication.flags | 1 + .../Impls_Macros_1.scala | 14 + .../Test_2.scala | 6 + test/files/run/macro-openmacros.check | 3 + test/files/run/macro-openmacros.flags | 1 + .../run/macro-openmacros/Impls_Macros_1.scala | 26 + test/files/run/macro-openmacros/Test_2.scala | 3 + test/files/run/macro-quasiinvalidbody-c.check | 1 + test/files/run/macro-quasiinvalidbody-c.flags | 1 + .../macro-quasiinvalidbody-c/Impls_Macros_1.scala | 9 + .../run/macro-quasiinvalidbody-c/Test_2.scala | 4 + test/files/run/macro-range/Common_1.scala | 48 + .../run/macro-range/Expansion_Impossible_2.scala | 53 + .../run/macro-range/Expansion_Possible_3.scala | 7 + test/files/run/macro-range/macro_range_1.scala | 99 -- test/files/run/macro-range/macro_range_2.scala | 99 -- .../run/macro-reflective-ma-normal-mdmi.check | 1 + .../run/macro-reflective-ma-normal-mdmi.flags | 1 + .../Impls_Macros_1.scala | 13 + .../macro-reflective-ma-normal-mdmi/Test_2.scala | 5 + .../run/macro-reflective-mamd-normal-mi.check | 1 + .../run/macro-reflective-mamd-normal-mi.flags | 0 .../macro-reflective-mamd-normal-mi/Impls_1.scala | 9 + .../Macros_Test_2.scala | 16 + test/files/run/macro-reify-basic.check | 1 + test/files/run/macro-reify-basic.flags | 1 + test/files/run/macro-reify-basic/Macros_1.scala | 11 + test/files/run/macro-reify-basic/Test_2.scala | 3 + test/files/run/macro-reify-eval-eval.check | 1 + test/files/run/macro-reify-eval-eval.flags | 1 + .../files/run/macro-reify-eval-eval/Macros_1.scala | 12 + test/files/run/macro-reify-eval-eval/Test_2.scala | 3 + .../files/run/macro-reify-eval-outside-reify.check | 1 + .../files/run/macro-reify-eval-outside-reify.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-reify-eval-outside-reify/Test_2.scala | 5 + test/files/run/macro-reify-freevars.check | 3 + test/files/run/macro-reify-freevars.flags | 1 + test/files/run/macro-reify-freevars/Macros_1.scala | 19 + test/files/run/macro-reify-freevars/Test_2.scala | 9 + .../macro-reify-groundtypetag-notypeparams.check | 2 + .../Test.scala | 6 + ...macro-reify-groundtypetag-typeparams-tags.check | 2 + .../Test.scala | 9 + test/files/run/macro-reify-nested-a.check | 0 test/files/run/macro-reify-nested-a.flags | 1 + .../run/macro-reify-nested-a/Impls_Macros_1.scala | 43 + test/files/run/macro-reify-nested-a/Test_2.scala | 4 + test/files/run/macro-reify-nested-b.check | 0 test/files/run/macro-reify-nested-b.flags | 1 + .../run/macro-reify-nested-b/Impls_Macros_1.scala | 43 + test/files/run/macro-reify-nested-b/Test_2.scala | 4 + .../files/run/macro-reify-ref-to-packageless.check | 1 + .../files/run/macro-reify-ref-to-packageless.flags | 1 + .../macro-reify-ref-to-packageless/Impls_1.scala | 6 + .../macro-reify-ref-to-packageless/Test_2.scala | 4 + test/files/run/macro-reify-tagful-a.check | 1 + test/files/run/macro-reify-tagful-a.flags | 1 + test/files/run/macro-reify-tagful-a/Macros_1.scala | 11 + test/files/run/macro-reify-tagful-a/Test_2.scala | 4 + test/files/run/macro-reify-tagless-a.check | 3 + test/files/run/macro-reify-tagless-a.flags | 1 + .../run/macro-reify-tagless-a/Impls_Macros_1.scala | 11 + test/files/run/macro-reify-tagless-a/Test_2.scala | 12 + .../run/macro-reify-typetag-notypeparams.check | 2 + .../macro-reify-typetag-notypeparams/Test.scala | 6 + .../macro-reify-typetag-typeparams-notags.check | 2 + .../Test.scala | 9 + .../run/macro-reify-typetag-typeparams-tags.check | 2 + .../macro-reify-typetag-typeparams-tags/Test.scala | 9 + .../run/macro-reify-typetag-usegroundtypetag.check | 2 + .../Test.scala | 9 + test/files/run/macro-reify-unreify.check | 1 + test/files/run/macro-reify-unreify.flags | 1 + test/files/run/macro-reify-unreify/Macros_1.scala | 19 + test/files/run/macro-reify-unreify/Test_2.scala | 3 + .../run/macro-reify-value-outside-reify.check | 1 + .../run/macro-reify-value-outside-reify.flags | 1 + .../Impls_Macros_1.scala | 9 + .../macro-reify-value-outside-reify/Test_2.scala | 6 + test/files/run/macro-repl-basic.check | 34 +- test/files/run/macro-repl-basic.scala | 27 +- test/files/run/macro-repl-dontexpand.check | 5 +- test/files/run/macro-repl-dontexpand.scala | 3 +- .../run/macro-rettype-mismatch/Macros_1.scala | 3 - test/files/run/macro-rettype-mismatch/Test_2.scala | 16 - test/files/run/macro-settings.check | 1 + test/files/run/macro-settings.flags | 1 + test/files/run/macro-settings/Impls_Macros_1.scala | 11 + test/files/run/macro-settings/Test_2.scala | 3 + test/files/run/macro-sip19-revised.check | 5 + test/files/run/macro-sip19-revised.flags | 1 + .../run/macro-sip19-revised/Impls_Macros_1.scala | 34 + test/files/run/macro-sip19-revised/Test_2.scala | 12 + test/files/run/macro-sip19.check | 5 + test/files/run/macro-sip19.flags | 1 + test/files/run/macro-sip19/Impls_Macros_1.scala | 25 + test/files/run/macro-sip19/Test_2.scala | 16 + .../run/macro-typecheck-implicitsdisabled.check | 2 + .../run/macro-typecheck-implicitsdisabled.flags | 1 + .../Impls_Macros_1.scala | 28 + .../macro-typecheck-implicitsdisabled/Test_2.scala | 4 + .../files/run/macro-typecheck-macrosdisabled.check | 5 + .../files/run/macro-typecheck-macrosdisabled.flags | 1 + .../Impls_Macros_1.scala | 36 + .../macro-typecheck-macrosdisabled/Test_2.scala | 4 + test/files/run/macro-undetparams-consfromsls.check | 5 + test/files/run/macro-undetparams-consfromsls.flags | 1 + .../Impls_Macros_1.scala | 17 + .../run/macro-undetparams-consfromsls/Test_2.scala | 7 + test/files/run/macro-undetparams-implicitval.check | 1 + test/files/run/macro-undetparams-implicitval.flags | 1 + .../run/macro-undetparams-implicitval/Test.scala | 4 + test/files/run/macro-undetparams-macroitself.check | 2 + test/files/run/macro-undetparams-macroitself.flags | 1 + .../Impls_Macros_1.scala | 7 + .../run/macro-undetparams-macroitself/Test_2.scala | 4 + test/files/run/manifests.scala | 71 +- test/files/run/primitive-sigs-2.check | 14 +- test/files/run/reify_ann1a.check | 60 +- test/files/run/reify_ann1a.scala | 11 +- test/files/run/reify_ann1b.check | 60 +- test/files/run/reify_ann1b.scala | 11 +- test/files/run/reify_ann2a.check | 44 + test/files/run/reify_ann2a.scala | 25 + test/files/run/reify_ann3.check | 21 + test/files/run/reify_ann3.scala | 19 + test/files/run/reify_ann4.check | 32 + test/files/run/reify_ann4.scala | 23 + test/files/run/reify_ann5.check | 22 + test/files/run/reify_ann5.scala | 20 + test/files/run/reify_anonymous.scala | 12 +- test/files/run/reify_classfileann_a.check | 36 +- test/files/run/reify_classfileann_a.scala | 11 +- test/files/run/reify_classfileann_b.check | 20 + test/files/run/reify_classfileann_b.scala | 23 + test/files/run/reify_closure1.scala | 9 +- test/files/run/reify_closure2a.scala | 9 +- test/files/run/reify_closure3a.scala | 9 +- test/files/run/reify_closure4a.scala | 9 +- test/files/run/reify_closure5a.scala | 17 +- test/files/run/reify_closure6.scala | 17 +- test/files/run/reify_closure7.scala | 17 +- test/files/run/reify_closure8a.scala | 10 +- test/files/run/reify_closure8b.check | 3 + test/files/run/reify_closure8b.scala | 18 + test/files/run/reify_closures10.scala | 10 +- test/files/run/reify_complex.scala | 12 +- test/files/run/reify_extendbuiltins.scala | 12 +- test/files/run/reify_for1.scala | 12 +- test/files/run/reify_fors.scala | 12 +- test/files/run/reify_generic.scala | 12 +- test/files/run/reify_generic2.scala | 12 +- test/files/run/reify_getter.scala | 11 +- test/files/run/reify_implicits.scala | 12 +- test/files/run/reify_inheritance.scala | 12 +- test/files/run/reify_inner1.scala | 12 +- test/files/run/reify_inner2.scala | 12 +- test/files/run/reify_inner3.scala | 12 +- test/files/run/reify_inner4.scala | 12 +- test/files/run/reify_maps.scala | 12 +- .../reify_metalevel_breach_+0_refers_to_1.check | 1 + .../reify_metalevel_breach_+0_refers_to_1.scala | 13 + .../reify_metalevel_breach_-1_refers_to_0_a.check | 1 + .../reify_metalevel_breach_-1_refers_to_0_a.scala | 11 + .../reify_metalevel_breach_-1_refers_to_0_b.check | 1 + .../reify_metalevel_breach_-1_refers_to_0_b.scala | 15 + .../reify_metalevel_breach_-1_refers_to_1.check | 1 + .../reify_metalevel_breach_-1_refers_to_1.scala | 13 + .../run/reify_nested_inner_refers_to_global.check | 1 + .../run/reify_nested_inner_refers_to_global.scala | 14 + .../run/reify_nested_inner_refers_to_local.check | 1 + .../run/reify_nested_inner_refers_to_local.scala | 12 + .../run/reify_nested_outer_refers_to_global.check | 1 + .../run/reify_nested_outer_refers_to_global.scala | 16 + .../run/reify_nested_outer_refers_to_local.check | 1 + .../run/reify_nested_outer_refers_to_local.scala | 16 + test/files/run/reify_newimpl_01.check | 1 + test/files/run/reify_newimpl_01.scala | 11 + test/files/run/reify_newimpl_02.check | 1 + test/files/run/reify_newimpl_02.scala | 11 + test/files/run/reify_newimpl_03.check | 1 + test/files/run/reify_newimpl_03.scala | 11 + test/files/run/reify_newimpl_04.check | 1 + test/files/run/reify_newimpl_04.scala | 11 + test/files/run/reify_newimpl_05.check | 1 + test/files/run/reify_newimpl_05.scala | 12 + test/files/run/reify_newimpl_06.check | 1 + test/files/run/reify_newimpl_06.scala | 11 + test/files/run/reify_newimpl_09.check | 1 + test/files/run/reify_newimpl_09.scala | 11 + test/files/run/reify_newimpl_10.check | 1 + test/files/run/reify_newimpl_10.scala | 12 + test/files/run/reify_newimpl_11.check | 2 + test/files/run/reify_newimpl_11.scala | 17 + test/files/run/reify_newimpl_12.check | 1 + test/files/run/reify_newimpl_12.scala | 12 + test/files/run/reify_newimpl_13.check | 2 + test/files/run/reify_newimpl_13.scala | 19 + test/files/run/reify_newimpl_14.check | 1 + test/files/run/reify_newimpl_14.scala | 14 + test/files/run/reify_newimpl_15.check | 1 + test/files/run/reify_newimpl_15.scala | 13 + test/files/run/reify_newimpl_16.check | 1 + test/files/run/reify_newimpl_16.scala | 15 + test/files/run/reify_newimpl_17.check | 2 + test/files/run/reify_newimpl_17.scala | 18 + test/files/run/reify_newimpl_18.check | 1 + test/files/run/reify_newimpl_18.scala | 13 + test/files/run/reify_newimpl_19.check | 2 + test/files/run/reify_newimpl_19.scala | 18 + test/files/run/reify_newimpl_20.check | 1 + test/files/run/reify_newimpl_20.scala | 14 + test/files/run/reify_newimpl_21.check | 1 + test/files/run/reify_newimpl_21.scala | 18 + test/files/run/reify_newimpl_22.check | 23 + test/files/run/reify_newimpl_22.scala | 15 + test/files/run/reify_newimpl_23.check | 22 + test/files/run/reify_newimpl_23.scala | 14 + test/files/run/reify_newimpl_24.check | 24 + test/files/run/reify_newimpl_24.scala | 16 + test/files/run/reify_newimpl_25.check | 21 + test/files/run/reify_newimpl_25.scala | 13 + test/files/run/reify_newimpl_26.check | 23 + test/files/run/reify_newimpl_26.scala | 13 + test/files/run/reify_newimpl_27.check | 1 + test/files/run/reify_newimpl_27.scala | 13 + test/files/run/reify_newimpl_28.check | 1 + test/files/run/reify_newimpl_28.scala | 15 + test/files/run/reify_newimpl_29.check | 1 + test/files/run/reify_newimpl_29.scala | 13 + test/files/run/reify_newimpl_30.check | 1 + test/files/run/reify_newimpl_30.scala | 15 + test/files/run/reify_newimpl_31.check | 1 + test/files/run/reify_newimpl_31.scala | 13 + test/files/run/reify_newimpl_32.check | 1 + test/files/run/reify_newimpl_32.scala | 15 + test/files/run/reify_newimpl_33.check | 1 + test/files/run/reify_newimpl_33.scala | 14 + test/files/run/reify_newimpl_34.check | 1 + test/files/run/reify_newimpl_34.scala | 16 + test/files/run/reify_newimpl_36.check | 1 + test/files/run/reify_newimpl_36.scala | 14 + test/files/run/reify_newimpl_37.check | 1 + test/files/run/reify_newimpl_37.scala | 15 + test/files/run/reify_newimpl_38.check | 1 + test/files/run/reify_newimpl_38.scala | 14 + test/files/run/reify_newimpl_39.check | 1 + test/files/run/reify_newimpl_39.scala | 15 + test/files/run/reify_newimpl_40.check | 1 + test/files/run/reify_newimpl_40.scala | 15 + test/files/run/reify_newimpl_41.check | 3 + test/files/run/reify_newimpl_41.scala | 17 + test/files/run/reify_newimpl_42.check | 3 + test/files/run/reify_newimpl_42.scala | 16 + test/files/run/reify_newimpl_43.check | 2 + test/files/run/reify_newimpl_43.scala | 15 + test/files/run/reify_newimpl_44.check | 2 + test/files/run/reify_newimpl_44.scala | 15 + test/files/run/reify_newimpl_45.check | 2 + test/files/run/reify_newimpl_45.scala | 12 + test/files/run/reify_newimpl_47.check | 1 + test/files/run/reify_newimpl_47.scala | 15 + test/files/run/reify_newimpl_48.check | 1 + test/files/run/reify_newimpl_48.scala | 20 + test/files/run/reify_newimpl_49.check | 3 + test/files/run/reify_newimpl_49.scala | 15 + test/files/run/reify_newimpl_50.check | 3 + test/files/run/reify_newimpl_50.scala | 14 + test/files/run/reify_newimpl_51.check | 3 + test/files/run/reify_newimpl_51.scala | 17 + test/files/run/reify_newimpl_52.check | 3 + test/files/run/reify_newimpl_52.scala | 17 + test/files/run/reify_printf.scala | 11 +- test/files/run/reify_sort.scala | 12 +- test/files/run/reify_sort1.scala | 12 +- test/files/run/reify_this.scala | 25 +- test/files/run/reify_timeofday.scala | 12 +- test/files/run/reify_typerefs_1a.check | 1 + test/files/run/reify_typerefs_1a.scala | 15 + test/files/run/reify_typerefs_1b.check | 1 + test/files/run/reify_typerefs_1b.scala | 15 + test/files/run/reify_typerefs_2a.check | 1 + test/files/run/reify_typerefs_2a.scala | 17 + test/files/run/reify_typerefs_2b.check | 1 + test/files/run/reify_typerefs_2b.scala | 17 + test/files/run/reify_typerefs_3a.check | 1 + test/files/run/reify_typerefs_3a.scala | 17 + test/files/run/reify_typerefs_3b.check | 1 + test/files/run/reify_typerefs_3b.scala | 17 + test/files/run/reify_varargs.scala | 12 +- test/files/run/repl-power.check | 64 +- test/files/run/t1195.check | 6 - test/files/run/t1195.check.temporarily.disabled | 6 + test/files/run/t1195.scala | 26 - test/files/run/t1195.scala.temporarily.disabled | 26 + test/files/run/t3758.check | 6 + test/files/run/t3758.scala | 12 +- test/files/run/t4110.check | 2 - test/files/run/t4110.check.temporarily.disabled | 2 + test/files/run/t4110.scala | 11 - test/files/run/t4110.scala.temporarily.disabled | 11 + test/files/run/t5224.check | 18 +- test/files/run/t5224.scala | 5 +- test/files/run/t5225_1.check | 8 +- test/files/run/t5225_1.scala | 5 +- test/files/run/t5225_2.check | 8 +- test/files/run/t5225_2.scala | 5 +- test/files/run/t5229_1.scala | 12 +- test/files/run/t5229_2.scala | 9 +- test/files/run/t5230.scala | 9 +- test/files/run/t5258a.check | 1 - test/files/run/t5258a.scala | 13 - test/files/run/t5266_1.scala | 9 +- test/files/run/t5266_2.scala | 9 +- test/files/run/t5269.scala | 12 +- test/files/run/t5270.scala | 12 +- test/files/run/t5271_1.check | 22 +- test/files/run/t5271_1.scala | 9 +- test/files/run/t5271_2.check | 24 +- test/files/run/t5271_2.scala | 9 +- test/files/run/t5271_3.check | 38 +- test/files/run/t5271_3.scala | 9 +- test/files/run/t5271_4.scala | 12 +- test/files/run/t5272_1.scala | 12 +- test/files/run/t5272_2.scala | 12 +- test/files/run/t5273_1.scala | 12 +- test/files/run/t5273_2a.scala | 12 +- test/files/run/t5273_2b.scala | 12 +- test/files/run/t5274_1.scala | 12 +- test/files/run/t5274_2.scala | 12 +- test/files/run/t5275.scala | 12 +- test/files/run/t5276_1a.scala | 12 +- test/files/run/t5276_1b.scala | 12 +- test/files/run/t5276_2a.scala | 12 +- test/files/run/t5276_2b.scala | 12 +- test/files/run/t5277_1.scala | 12 +- test/files/run/t5277_2.scala | 12 +- test/files/run/t5279.scala | 12 +- test/files/run/t5334_1.scala | 12 +- test/files/run/t5334_2.scala | 12 +- test/files/run/t5335.scala | 12 +- test/files/run/t5415.scala | 10 +- test/files/run/t5419.check | 2 +- test/files/run/t5419.scala | 5 +- test/files/run/t5423.scala | 3 - test/files/run/toolbox_console_reporter.check | 0 test/files/run/toolbox_console_reporter.scala | 16 + .../run/toolbox_default_reporter_is_silent.check | 1 + .../run/toolbox_default_reporter_is_silent.scala | 13 + test/files/run/toolbox_silent_reporter.check | 4 + test/files/run/toolbox_silent_reporter.scala | 16 + .../run/toolbox_typecheck_implicitsdisabled.check | 5 + .../run/toolbox_typecheck_implicitsdisabled.scala | 24 + .../run/toolbox_typecheck_macrosdisabled.check | 5 + .../run/toolbox_typecheck_macrosdisabled.scala | 17 + test/files/run/treePrint.check | 5 - .../files/run/treePrint.check.temporarily.disabled | 5 + test/files/run/treePrint.scala | 42 - .../files/run/treePrint.scala.temporarily.disabled | 42 + test/files/run/typetags_core.check | 30 + test/files/run/typetags_core.scala | 32 + test/pending/neg/reify_packed.check | 4 + test/pending/neg/reify_packed.scala | 10 + test/pending/run/macro-expand-default.flags | 1 + .../pending/run/macro-expand-default/Impls_1.scala | 10 + .../run/macro-expand-default/Macros_Test_2.scala | 8 + ...o-expand-implicit-macro-has-context-bound.check | 1 + ...o-expand-implicit-macro-has-context-bound.flags | 1 + .../Impls_1.scala | 10 + .../Macros_Test_2.scala | 4 + test/pending/run/macro-expand-named.flags | 1 + test/pending/run/macro-expand-named/Impls_1.scala | 10 + .../run/macro-expand-named/Macros_Test_2.scala | 5 + .../run/macro-expand-tparams-prefix-e1.check | 3 + .../run/macro-expand-tparams-prefix-e1.flags | 1 + .../macro-expand-tparams-prefix-e1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 13 + .../run/macro-expand-tparams-prefix-f1.check | 3 + .../run/macro-expand-tparams-prefix-f1.flags | 1 + .../macro-expand-tparams-prefix-f1/Impls_1.scala | 12 + .../Macros_Test_2.scala | 13 + test/pending/run/macro-overload.check | 4 - test/pending/run/macro-overload.flags | 1 - test/pending/run/macro-overload/Macros_1.scala | 9 - test/pending/run/macro-overload/Test_2.scala | 6 - test/pending/run/macro-quasiinvalidbody-a.check | 1 + test/pending/run/macro-quasiinvalidbody-a.flags | 1 + .../run/macro-quasiinvalidbody-a/Impls_1.scala | 5 + .../macro-quasiinvalidbody-a/Macros_Test_2.scala | 10 + test/pending/run/macro-quasiinvalidbody-b.check | 1 + test/pending/run/macro-quasiinvalidbody-b.flags | 1 + .../run/macro-quasiinvalidbody-b/Impls_1.scala | 7 + .../macro-quasiinvalidbody-b/Macros_Test_2.scala | 10 + test/pending/run/macro-reify-array.flags | 1 + test/pending/run/macro-reify-array/Macros_1.scala | 11 + test/pending/run/macro-reify-array/Test_2.scala | 4 + test/pending/run/macro-reify-eval-vs-value.flags | 1 + .../run/macro-reify-eval-vs-value/Macros_1.scala | 25 + .../run/macro-reify-eval-vs-value/Test_2.scala | 5 + ...cro-reify-groundtypetag-hktypeparams-tags.check | 2 + .../Test.scala | 9 + test/pending/run/macro-reify-tagful-b.check | 1 + test/pending/run/macro-reify-tagful-b.flags | 1 + .../run/macro-reify-tagful-b/Macros_1.scala | 11 + test/pending/run/macro-reify-tagful-b/Test_2.scala | 4 + test/pending/run/macro-reify-tagless-b.check | 3 + test/pending/run/macro-reify-tagless-b.flags | 1 + .../run/macro-reify-tagless-b/Impls_Macros_1.scala | 11 + .../pending/run/macro-reify-tagless-b/Test_2.scala | 11 + .../macro-reify-typetag-hktypeparams-notags.check | 2 + .../Test.scala | 9 + .../macro-reify-typetag-hktypeparams-tags.check | 2 + .../Test.scala | 9 + test/pending/run/reify_addressbook.scala | 12 +- test/pending/run/reify_brainf_ck.scala | 12 +- test/pending/run/reify_callccinterpreter.scala | 12 +- test/pending/run/reify_classfileann_b.check | 0 test/pending/run/reify_classfileann_b.scala | 24 - test/pending/run/reify_closure2b.scala | 9 +- test/pending/run/reify_closure3b.scala | 9 +- test/pending/run/reify_closure4b.scala | 9 +- test/pending/run/reify_closure5b.scala | 9 +- test/pending/run/reify_closure8b.check | 1 - test/pending/run/reify_closure8b.scala | 16 - test/pending/run/reify_closure9a.scala | 11 +- test/pending/run/reify_closure9b.scala | 11 +- test/pending/run/reify_closures11.scala | 11 +- test/pending/run/reify_csv.scala | 12 +- test/pending/run/reify_gadts.scala | 12 +- test/pending/run/reify_lazyevaluation.scala | 12 +- test/pending/run/reify_newimpl_07.scala | 13 + test/pending/run/reify_newimpl_08.scala | 15 + test/pending/run/reify_newimpl_35.scala | 10 + test/pending/run/reify_newimpl_46.scala | 12 + test/pending/run/reify_newimpl_53.scala | 15 + test/pending/run/reify_properties.scala | 12 +- test/pending/run/reify_simpleinterpreter.scala | 12 +- test/pending/run/t5258a.check | 1 + test/pending/run/t5258a.scala | 5 + test/pending/run/t5258b.scala | 12 +- test/pending/run/t5258c.scala | 12 +- test/pending/run/t5271_1.scala | 12 +- test/pending/run/t5271_2.scala | 12 +- test/pending/run/t5271_3.scala | 12 +- test/pending/run/t5418.scala | 12 +- 1134 files changed, 15211 insertions(+), 5479 deletions(-) create mode 100644 src/compiler/scala/reflect/internal/CapturedVariables.scala create mode 100644 src/compiler/scala/reflect/internal/FreeVars.scala create mode 100644 src/compiler/scala/reflect/internal/Reporters.scala create mode 100644 src/compiler/scala/reflect/internal/TreeBuildUtil.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Aliases.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Context.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Enclosures.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Errors.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Infrastructure.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Names.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Reifiers.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Reporters.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Settings.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Symbols.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Typers.scala create mode 100644 src/compiler/scala/reflect/makro/runtime/Util.scala create mode 100644 src/compiler/scala/reflect/reify/Errors.scala create mode 100644 src/compiler/scala/reflect/reify/NodePrinters.scala create mode 100644 src/compiler/scala/reflect/reify/Phases.scala create mode 100644 src/compiler/scala/reflect/reify/Reifiers.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Names.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Positions.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Symbols.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Trees.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Types.scala create mode 100644 src/compiler/scala/reflect/reify/codegen/Util.scala create mode 100644 src/compiler/scala/reflect/reify/package.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Calculate.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Metalevels.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Reify.scala create mode 100644 src/compiler/scala/reflect/reify/phases/Reshape.scala create mode 100644 src/compiler/scala/reflect/runtime/ClassLoaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/Loaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/Memoizer.scala delete mode 100644 src/compiler/scala/reflect/runtime/RuntimeTypes.scala create mode 100644 src/compiler/scala/reflect/runtime/SymbolLoaders.scala delete mode 100644 src/compiler/scala/reflect/runtime/TreeBuildUtil.scala create mode 100644 src/compiler/scala/reflect/runtime/package.scala create mode 100644 src/compiler/scala/tools/nsc/ClassLoaders.scala delete mode 100644 src/compiler/scala/tools/nsc/MacroContext.scala create mode 100644 src/compiler/scala/tools/nsc/ToolBoxes.scala create mode 100644 src/compiler/scala/tools/nsc/ast/FreeVars.scala create mode 100644 src/compiler/scala/tools/nsc/ast/Positions.scala delete mode 100644 src/compiler/scala/tools/nsc/ast/Reifiers.scala delete mode 100644 src/compiler/scala/tools/nsc/ast/ReifyPrinters.scala delete mode 100644 src/compiler/scala/tools/nsc/symtab/Positions.scala create mode 100644 src/library/scala/reflect/ArrayTags.scala delete mode 100644 src/library/scala/reflect/ClassManifest.scala create mode 100644 src/library/scala/reflect/ClassTags.scala delete mode 100644 src/library/scala/reflect/Manifest.scala delete mode 100644 src/library/scala/reflect/NoManifest.scala delete mode 100644 src/library/scala/reflect/OptManifest.scala create mode 100644 src/library/scala/reflect/TagMaterialization.scala create mode 100644 src/library/scala/reflect/api/Attachments.scala create mode 100644 src/library/scala/reflect/api/ClassLoaders.scala create mode 100644 src/library/scala/reflect/api/Exprs.scala create mode 100644 src/library/scala/reflect/api/FreeVars.scala create mode 100644 src/library/scala/reflect/api/Importers.scala create mode 100644 src/library/scala/reflect/api/Reporters.scala delete mode 100644 src/library/scala/reflect/api/RuntimeTypes.scala create mode 100644 src/library/scala/reflect/api/ToolBoxes.scala create mode 100644 src/library/scala/reflect/api/TypeTags.scala delete mode 100644 src/library/scala/reflect/macro/Context.scala create mode 100644 src/library/scala/reflect/makro/Aliases.scala create mode 100644 src/library/scala/reflect/makro/CapturedVariables.scala create mode 100644 src/library/scala/reflect/makro/Context.scala create mode 100644 src/library/scala/reflect/makro/Enclosures.scala create mode 100644 src/library/scala/reflect/makro/Infrastructure.scala create mode 100644 src/library/scala/reflect/makro/Names.scala create mode 100644 src/library/scala/reflect/makro/Reifiers.scala create mode 100644 src/library/scala/reflect/makro/Reporters.scala create mode 100644 src/library/scala/reflect/makro/Settings.scala create mode 100644 src/library/scala/reflect/makro/Symbols.scala create mode 100644 src/library/scala/reflect/makro/Typers.scala create mode 100644 src/library/scala/reflect/makro/Util.scala create mode 100644 src/library/scala/reflect/makro/internal/macroImpl.scala create mode 100644 src/library/scala/reflect/makro/internal/typeTagImpl.scala delete mode 100644 test/files/jvm/manifests.check create mode 100644 test/files/jvm/manifests.check.temporarily.disabled delete mode 100644 test/files/jvm/manifests.scala create mode 100644 test/files/jvm/manifests.scala.temporarily.disabled delete mode 100644 test/files/macros/Printf.scala delete mode 100644 test/files/macros/Test.scala delete mode 100644 test/files/macros/macros_v0001.bat delete mode 100644 test/files/macros/macros_v0001.sh create mode 100644 test/files/neg/classtags_contextbound_a.check create mode 100644 test/files/neg/classtags_contextbound_a.scala create mode 100644 test/files/neg/classtags_contextbound_b.check create mode 100644 test/files/neg/classtags_contextbound_b.scala create mode 100644 test/files/neg/classtags_contextbound_c.check create mode 100644 test/files/neg/classtags_contextbound_c.scala delete mode 100644 test/files/neg/macro-argtype-mismatch/Macros_1.scala delete mode 100644 test/files/neg/macro-argtype-mismatch/Test_2.scala create mode 100644 test/files/neg/macro-basic-mamdmi.check create mode 100644 test/files/neg/macro-basic-mamdmi.flags create mode 100644 test/files/neg/macro-basic-mamdmi/Impls_Macros_Test_1.scala create mode 100644 test/files/neg/macro-cyclic.check create mode 100644 test/files/neg/macro-cyclic.flags create mode 100644 test/files/neg/macro-cyclic/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents.check create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala create mode 100644 test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala create mode 100644 test/files/neg/macro-deprecate-idents.check create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Class_4.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Class_5.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Def_13.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Object_6.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Object_7.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Package_10.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Package_11.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Type_3.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Val_1.scala create mode 100644 test/files/neg/macro-deprecate-idents/Macros_Var_2.scala create mode 100644 test/files/neg/macro-deprecate-idents/Main.scala create mode 100644 test/files/neg/macro-invalidimpl-a.check create mode 100644 test/files/neg/macro-invalidimpl-a.flags create mode 100644 test/files/neg/macro-invalidimpl-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-b.check create mode 100644 test/files/neg/macro-invalidimpl-b.flags create mode 100644 test/files/neg/macro-invalidimpl-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-c.check create mode 100644 test/files/neg/macro-invalidimpl-c.flags create mode 100644 test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidimpl-c/Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-d.check create mode 100644 test/files/neg/macro-invalidimpl-d.flags create mode 100644 test/files/neg/macro-invalidimpl-d/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-e.check create mode 100644 test/files/neg/macro-invalidimpl-e.flags create mode 100644 test/files/neg/macro-invalidimpl-e/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-f.check create mode 100644 test/files/neg/macro-invalidimpl-f.flags create mode 100644 test/files/neg/macro-invalidimpl-f/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-g.check create mode 100644 test/files/neg/macro-invalidimpl-g.flags create mode 100644 test/files/neg/macro-invalidimpl-g/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidimpl-h.check create mode 100644 test/files/neg/macro-invalidimpl-h.flags create mode 100644 test/files/neg/macro-invalidimpl-h/Impls_1.scala create mode 100644 test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidret-nontree.check create mode 100644 test/files/neg/macro-invalidret-nontree.flags create mode 100644 test/files/neg/macro-invalidret-nontree/Impls_1.scala create mode 100644 test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidret-nonuniversetree.check create mode 100644 test/files/neg/macro-invalidret-nonuniversetree.flags create mode 100644 test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala create mode 100644 test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-a.check create mode 100644 test/files/neg/macro-invalidshape-a.flags create mode 100644 test/files/neg/macro-invalidshape-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-b.check create mode 100644 test/files/neg/macro-invalidshape-b.flags create mode 100644 test/files/neg/macro-invalidshape-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-c.check create mode 100644 test/files/neg/macro-invalidshape-c.flags create mode 100644 test/files/neg/macro-invalidshape-c/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-c/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidshape-d.check create mode 100644 test/files/neg/macro-invalidshape-d.flags create mode 100644 test/files/neg/macro-invalidshape-d/Impls_1.scala create mode 100644 test/files/neg/macro-invalidshape-d/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-context-bounds.check create mode 100644 test/files/neg/macro-invalidsig-context-bounds.flags create mode 100644 test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-context-bounds/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs.check create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx.check create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx.flags create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-implicit-params.check create mode 100644 test/files/neg/macro-invalidsig-implicit-params.flags create mode 100644 test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-implicit-params/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badargc.check create mode 100644 test/files/neg/macro-invalidsig-params-badargc.flags create mode 100644 test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badargc/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badtype.check create mode 100644 test/files/neg/macro-invalidsig-params-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badtype/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs.check create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs.flags create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch.check create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch.flags create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype.check create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a.check create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b.check create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c.check create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c.flags create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala create mode 100644 test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badargs.check create mode 100644 test/files/neg/macro-invalidusage-badargs.flags create mode 100644 test/files/neg/macro-invalidusage-badargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badbounds.check create mode 100644 test/files/neg/macro-invalidusage-badbounds.flags create mode 100644 test/files/neg/macro-invalidusage-badbounds/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-badtargs.check create mode 100644 test/files/neg/macro-invalidusage-badtargs.flags create mode 100644 test/files/neg/macro-invalidusage-badtargs/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax.check create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax.flags create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax/Impls_1.scala create mode 100644 test/files/neg/macro-invalidusage-methodvaluesyntax/Macros_Test_2.scala create mode 100644 test/files/neg/macro-keyword.check create mode 100644 test/files/neg/macro-keyword.flags create mode 100644 test/files/neg/macro-keyword/Macros_Bind_12.scala create mode 100644 test/files/neg/macro-keyword/Macros_Class_4.scala create mode 100644 test/files/neg/macro-keyword/Macros_Class_5.scala create mode 100644 test/files/neg/macro-keyword/Macros_Def_13.scala create mode 100644 test/files/neg/macro-keyword/Macros_Object_6.scala create mode 100644 test/files/neg/macro-keyword/Macros_Object_7.scala create mode 100644 test/files/neg/macro-keyword/Macros_Package_10.scala create mode 100644 test/files/neg/macro-keyword/Macros_Package_11.scala create mode 100644 test/files/neg/macro-keyword/Macros_Trait_8.scala create mode 100644 test/files/neg/macro-keyword/Macros_Trait_9.scala create mode 100644 test/files/neg/macro-keyword/Macros_Type_3.scala create mode 100644 test/files/neg/macro-keyword/Macros_Val_1.scala create mode 100644 test/files/neg/macro-keyword/Macros_Var_2.scala create mode 100644 test/files/neg/macro-noexpand/Impls_1.scala delete mode 100644 test/files/neg/macro-noexpand/Macros_1.scala create mode 100644 test/files/neg/macro-noexpand/Macros_Test_2.scala delete mode 100644 test/files/neg/macro-noexpand/Test_2.scala delete mode 100644 test/files/neg/macro-noncompilertree/Macros_1.scala delete mode 100644 test/files/neg/macro-nontree/Macros_1.scala create mode 100644 test/files/neg/macro-nontypeablebody.check create mode 100644 test/files/neg/macro-nontypeablebody.flags create mode 100644 test/files/neg/macro-nontypeablebody/Impls_1.scala create mode 100644 test/files/neg/macro-nontypeablebody/Macros_Test_2.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a.check create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a.flags create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-a/Test_2.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b.check create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b.flags create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala create mode 100644 test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala create mode 100644 test/files/neg/macro-override-method-overrides-macro.check create mode 100644 test/files/neg/macro-override-method-overrides-macro.flags create mode 100644 test/files/neg/macro-override-method-overrides-macro/Impls_1.scala create mode 100644 test/files/neg/macro-override-method-overrides-macro/Macros_Test_2.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check create mode 100644 test/files/neg/macro-reify-groundtypetag-hktypeparams-notags/Test.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-typeparams-notags.check create mode 100644 test/files/neg/macro-reify-groundtypetag-typeparams-notags/Test.scala create mode 100644 test/files/neg/macro-reify-groundtypetag-usetypetag.check create mode 100644 test/files/neg/macro-reify-groundtypetag-usetypetag/Test.scala create mode 100644 test/files/neg/macro-without-xmacros-a.check create mode 100644 test/files/neg/macro-without-xmacros-a/Impls_1.scala create mode 100644 test/files/neg/macro-without-xmacros-a/Macros_2.scala create mode 100644 test/files/neg/macro-without-xmacros-a/Test_3.scala create mode 100644 test/files/neg/macro-without-xmacros-b.check create mode 100644 test/files/neg/macro-without-xmacros-b/Impls_1.scala create mode 100644 test/files/neg/macro-without-xmacros-b/Macros_2.scala create mode 100644 test/files/neg/macro-without-xmacros-b/Test_3.scala delete mode 100644 test/files/neg/reify_ann2a.check delete mode 100644 test/files/neg/reify_ann2a.scala create mode 100644 test/files/neg/t5334_1.check create mode 100644 test/files/neg/t5334_1.scala create mode 100644 test/files/neg/t5334_2.check create mode 100644 test/files/neg/t5334_2.scala delete mode 100644 test/files/pos/implicits.scala create mode 100644 test/files/pos/implicits.scala.temporarily.disabled delete mode 100644 test/files/pos/macros.flags delete mode 100644 test/files/pos/macros.scala delete mode 100644 test/files/pos/manifest1.scala create mode 100644 test/files/pos/manifest1.scala.temporarily.disabled create mode 100644 test/files/run/classtags_contextbound.check create mode 100644 test/files/run/classtags_contextbound.scala create mode 100644 test/files/run/classtags_core.check create mode 100644 test/files/run/classtags_core.scala delete mode 100644 test/files/run/existentials3.check create mode 100644 test/files/run/existentials3.check.temporarily.disabled delete mode 100644 test/files/run/existentials3.scala create mode 100644 test/files/run/existentials3.scala.temporarily.disabled create mode 100644 test/files/run/groundtypetags_core.check create mode 100644 test/files/run/groundtypetags_core.scala create mode 100644 test/files/run/macro-abort-fresh.check create mode 100644 test/files/run/macro-abort-fresh.flags create mode 100644 test/files/run/macro-abort-fresh/Macros_1.scala create mode 100644 test/files/run/macro-abort-fresh/Test_2.scala create mode 100644 test/files/run/macro-basic-ma-md-mi.check create mode 100644 test/files/run/macro-basic-ma-md-mi.flags create mode 100644 test/files/run/macro-basic-ma-md-mi/Impls_1.scala create mode 100644 test/files/run/macro-basic-ma-md-mi/Macros_2.scala create mode 100644 test/files/run/macro-basic-ma-md-mi/Test_3.scala create mode 100644 test/files/run/macro-basic-ma-mdmi.check create mode 100644 test/files/run/macro-basic-ma-mdmi.flags create mode 100644 test/files/run/macro-basic-ma-mdmi/Impls_Macros_1.scala create mode 100644 test/files/run/macro-basic-ma-mdmi/Test_2.scala create mode 100644 test/files/run/macro-basic-mamd-mi.check create mode 100644 test/files/run/macro-basic-mamd-mi.flags create mode 100644 test/files/run/macro-basic-mamd-mi/Impls_1.scala create mode 100644 test/files/run/macro-basic-mamd-mi/Macros_Test_2.scala delete mode 100644 test/files/run/macro-basic.check delete mode 100644 test/files/run/macro-basic.flags delete mode 100644 test/files/run/macro-basic/Macros_1.scala delete mode 100644 test/files/run/macro-basic/Test_2.scala create mode 100644 test/files/run/macro-bodyexpandstoimpl.check create mode 100644 test/files/run/macro-bodyexpandstoimpl.flags create mode 100644 test/files/run/macro-bodyexpandstoimpl/Impls_1.scala create mode 100644 test/files/run/macro-bodyexpandstoimpl/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-annotation.check create mode 100644 test/files/run/macro-declared-in-annotation.flags create mode 100644 test/files/run/macro-declared-in-annotation/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-annotation/Macros_2.scala create mode 100644 test/files/run/macro-declared-in-annotation/Test_3.scala create mode 100644 test/files/run/macro-declared-in-anonymous.check create mode 100644 test/files/run/macro-declared-in-anonymous.flags create mode 100644 test/files/run/macro-declared-in-anonymous/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-block.check create mode 100644 test/files/run/macro-declared-in-block.flags create mode 100644 test/files/run/macro-declared-in-block/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-block/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class-class.check create mode 100644 test/files/run/macro-declared-in-class-class.flags create mode 100644 test/files/run/macro-declared-in-class-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class-object.check create mode 100644 test/files/run/macro-declared-in-class-object.flags create mode 100644 test/files/run/macro-declared-in-class-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-class.check create mode 100644 test/files/run/macro-declared-in-class.flags create mode 100644 test/files/run/macro-declared-in-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-default-param.check create mode 100644 test/files/run/macro-declared-in-default-param.flags create mode 100644 test/files/run/macro-declared-in-default-param/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-default-param/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-implicit-class.check create mode 100644 test/files/run/macro-declared-in-implicit-class.flags create mode 100644 test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala create mode 100644 test/files/run/macro-declared-in-implicit-class/Test_2.scala create mode 100644 test/files/run/macro-declared-in-method.check create mode 100644 test/files/run/macro-declared-in-method.flags create mode 100644 test/files/run/macro-declared-in-method/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-method/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object-class.check create mode 100644 test/files/run/macro-declared-in-object-class.flags create mode 100644 test/files/run/macro-declared-in-object-class/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object-class/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object-object.check create mode 100644 test/files/run/macro-declared-in-object-object.flags create mode 100644 test/files/run/macro-declared-in-object-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-object.check create mode 100644 test/files/run/macro-declared-in-object.flags create mode 100644 test/files/run/macro-declared-in-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-package-object.check create mode 100644 test/files/run/macro-declared-in-package-object.flags create mode 100644 test/files/run/macro-declared-in-package-object/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-package-object/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-refinement.check create mode 100644 test/files/run/macro-declared-in-refinement.flags create mode 100644 test/files/run/macro-declared-in-refinement/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-refinement/Macros_Test_2.scala create mode 100644 test/files/run/macro-declared-in-trait.check create mode 100644 test/files/run/macro-declared-in-trait.flags create mode 100644 test/files/run/macro-declared-in-trait/Impls_1.scala create mode 100644 test/files/run/macro-declared-in-trait/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-a.check create mode 100644 test/files/run/macro-def-infer-return-type-a.flags create mode 100644 test/files/run/macro-def-infer-return-type-a/Impls_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-b.check create mode 100644 test/files/run/macro-def-infer-return-type-b.flags create mode 100644 test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-b/Test_2.scala create mode 100644 test/files/run/macro-def-infer-return-type-c.check create mode 100644 test/files/run/macro-def-infer-return-type-c.flags create mode 100644 test/files/run/macro-def-infer-return-type-c/Impls_1.scala create mode 100644 test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-a.check create mode 100644 test/files/run/macro-def-path-dependent-a.flags create mode 100644 test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-a/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-b.check create mode 100644 test/files/run/macro-def-path-dependent-b.flags create mode 100644 test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-b/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-c.check create mode 100644 test/files/run/macro-def-path-dependent-c.flags create mode 100644 test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-c/Test_2.scala create mode 100644 test/files/run/macro-def-path-dependent-d.check create mode 100644 test/files/run/macro-def-path-dependent-d.flags create mode 100644 test/files/run/macro-def-path-dependent-d/Impls_Macros_1.scala create mode 100644 test/files/run/macro-def-path-dependent-d/Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit.check create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit.flags create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-has-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-val.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-val.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-val/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-val/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-view.check create mode 100644 test/files/run/macro-expand-implicit-macro-is-view.flags create mode 100644 test/files/run/macro-expand-implicit-macro-is-view/Impls_1.scala create mode 100644 test/files/run/macro-expand-implicit-macro-is-view/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-multiple-arglists.check create mode 100644 test/files/run/macro-expand-multiple-arglists.flags create mode 100644 test/files/run/macro-expand-multiple-arglists/Impls_1.scala create mode 100644 test/files/run/macro-expand-multiple-arglists/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-nullary-generic.check create mode 100644 test/files/run/macro-expand-nullary-generic.flags create mode 100644 test/files/run/macro-expand-nullary-generic/Impls_1.scala create mode 100644 test/files/run/macro-expand-nullary-generic/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-nullary-nongeneric.check create mode 100644 test/files/run/macro-expand-nullary-nongeneric.flags create mode 100644 test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala create mode 100644 test/files/run/macro-expand-nullary-nongeneric/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-overload.check create mode 100644 test/files/run/macro-expand-overload.flags create mode 100644 test/files/run/macro-expand-overload/Impls_1.scala create mode 100644 test/files/run/macro-expand-overload/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-override.check create mode 100644 test/files/run/macro-expand-override.flags create mode 100644 test/files/run/macro-expand-override/Impls_1.scala create mode 100644 test/files/run/macro-expand-override/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-recursive.check create mode 100644 test/files/run/macro-expand-recursive.flags create mode 100644 test/files/run/macro-expand-recursive/Impls_1.scala create mode 100644 test/files/run/macro-expand-recursive/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-a.check create mode 100644 test/files/run/macro-expand-tparams-bounds-a.flags create mode 100644 test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-b.check create mode 100644 test/files/run/macro-expand-tparams-bounds-b.flags create mode 100644 test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-explicit.check create mode 100644 test/files/run/macro-expand-tparams-explicit.flags create mode 100644 test/files/run/macro-expand-tparams-explicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-explicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-implicit.check create mode 100644 test/files/run/macro-expand-tparams-implicit.flags create mode 100644 test/files/run/macro-expand-tparams-implicit/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-implicit/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-only-in-impl.flags create mode 100644 test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-optional.check create mode 100644 test/files/run/macro-expand-tparams-optional.flags create mode 100644 test/files/run/macro-expand-tparams-optional/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-a.check create mode 100644 test/files/run/macro-expand-tparams-prefix-a.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-b.check create mode 100644 test/files/run/macro-expand-tparams-prefix-b.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c1.check create mode 100644 test/files/run/macro-expand-tparams-prefix-c1.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c2.check create mode 100644 test/files/run/macro-expand-tparams-prefix-c2.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-d1.check create mode 100644 test/files/run/macro-expand-tparams-prefix-d1.flags create mode 100644 test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala create mode 100644 test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs.check create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs.flags create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-explicit-over-varargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs.check create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-nonvarargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs.check create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs.flags create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs/Impls_1.scala create mode 100644 test/files/run/macro-expand-varargs-implicit-over-varargs/Macros_Test_2.scala create mode 100644 test/files/run/macro-impl-default-params.check create mode 100644 test/files/run/macro-impl-default-params.flags create mode 100644 test/files/run/macro-impl-default-params/Impls_Macros_1.scala create mode 100644 test/files/run/macro-impl-default-params/Test_2.scala create mode 100644 test/files/run/macro-impl-rename-context.check create mode 100644 test/files/run/macro-impl-rename-context.flags create mode 100644 test/files/run/macro-impl-rename-context/Impls_Macros_1.scala create mode 100644 test/files/run/macro-impl-rename-context/Test_2.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.check create mode 100644 test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags create mode 100644 test/files/run/macro-invalidret-nontypeable.check create mode 100644 test/files/run/macro-invalidret-nontypeable.flags create mode 100644 test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidret-nontypeable/Test_2.scala create mode 100644 test/files/run/macro-invalidusage-badret.check create mode 100644 test/files/run/macro-invalidusage-badret.flags create mode 100644 test/files/run/macro-invalidusage-badret/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidusage-badret/Test_2.scala create mode 100644 test/files/run/macro-invalidusage-partialapplication.check create mode 100644 test/files/run/macro-invalidusage-partialapplication.flags create mode 100644 test/files/run/macro-invalidusage-partialapplication/Impls_Macros_1.scala create mode 100644 test/files/run/macro-invalidusage-partialapplication/Test_2.scala create mode 100644 test/files/run/macro-openmacros.check create mode 100644 test/files/run/macro-openmacros.flags create mode 100644 test/files/run/macro-openmacros/Impls_Macros_1.scala create mode 100644 test/files/run/macro-openmacros/Test_2.scala create mode 100644 test/files/run/macro-quasiinvalidbody-c.check create mode 100644 test/files/run/macro-quasiinvalidbody-c.flags create mode 100644 test/files/run/macro-quasiinvalidbody-c/Impls_Macros_1.scala create mode 100644 test/files/run/macro-quasiinvalidbody-c/Test_2.scala create mode 100644 test/files/run/macro-range/Common_1.scala create mode 100644 test/files/run/macro-range/Expansion_Impossible_2.scala create mode 100644 test/files/run/macro-range/Expansion_Possible_3.scala delete mode 100644 test/files/run/macro-range/macro_range_1.scala delete mode 100644 test/files/run/macro-range/macro_range_2.scala create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi.check create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi.flags create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala create mode 100644 test/files/run/macro-reflective-mamd-normal-mi.check create mode 100644 test/files/run/macro-reflective-mamd-normal-mi.flags create mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Impls_1.scala create mode 100644 test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala create mode 100644 test/files/run/macro-reify-basic.check create mode 100644 test/files/run/macro-reify-basic.flags create mode 100644 test/files/run/macro-reify-basic/Macros_1.scala create mode 100644 test/files/run/macro-reify-basic/Test_2.scala create mode 100644 test/files/run/macro-reify-eval-eval.check create mode 100644 test/files/run/macro-reify-eval-eval.flags create mode 100644 test/files/run/macro-reify-eval-eval/Macros_1.scala create mode 100644 test/files/run/macro-reify-eval-eval/Test_2.scala create mode 100644 test/files/run/macro-reify-eval-outside-reify.check create mode 100644 test/files/run/macro-reify-eval-outside-reify.flags create mode 100644 test/files/run/macro-reify-eval-outside-reify/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-eval-outside-reify/Test_2.scala create mode 100644 test/files/run/macro-reify-freevars.check create mode 100644 test/files/run/macro-reify-freevars.flags create mode 100644 test/files/run/macro-reify-freevars/Macros_1.scala create mode 100644 test/files/run/macro-reify-freevars/Test_2.scala create mode 100644 test/files/run/macro-reify-groundtypetag-notypeparams.check create mode 100644 test/files/run/macro-reify-groundtypetag-notypeparams/Test.scala create mode 100644 test/files/run/macro-reify-groundtypetag-typeparams-tags.check create mode 100644 test/files/run/macro-reify-groundtypetag-typeparams-tags/Test.scala create mode 100644 test/files/run/macro-reify-nested-a.check create mode 100644 test/files/run/macro-reify-nested-a.flags create mode 100644 test/files/run/macro-reify-nested-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-nested-a/Test_2.scala create mode 100644 test/files/run/macro-reify-nested-b.check create mode 100644 test/files/run/macro-reify-nested-b.flags create mode 100644 test/files/run/macro-reify-nested-b/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-nested-b/Test_2.scala create mode 100644 test/files/run/macro-reify-ref-to-packageless.check create mode 100644 test/files/run/macro-reify-ref-to-packageless.flags create mode 100644 test/files/run/macro-reify-ref-to-packageless/Impls_1.scala create mode 100644 test/files/run/macro-reify-ref-to-packageless/Test_2.scala create mode 100644 test/files/run/macro-reify-tagful-a.check create mode 100644 test/files/run/macro-reify-tagful-a.flags create mode 100644 test/files/run/macro-reify-tagful-a/Macros_1.scala create mode 100644 test/files/run/macro-reify-tagful-a/Test_2.scala create mode 100644 test/files/run/macro-reify-tagless-a.check create mode 100644 test/files/run/macro-reify-tagless-a.flags create mode 100644 test/files/run/macro-reify-tagless-a/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-tagless-a/Test_2.scala create mode 100644 test/files/run/macro-reify-typetag-notypeparams.check create mode 100644 test/files/run/macro-reify-typetag-notypeparams/Test.scala create mode 100644 test/files/run/macro-reify-typetag-typeparams-notags.check create mode 100644 test/files/run/macro-reify-typetag-typeparams-notags/Test.scala create mode 100644 test/files/run/macro-reify-typetag-typeparams-tags.check create mode 100644 test/files/run/macro-reify-typetag-typeparams-tags/Test.scala create mode 100644 test/files/run/macro-reify-typetag-usegroundtypetag.check create mode 100644 test/files/run/macro-reify-typetag-usegroundtypetag/Test.scala create mode 100644 test/files/run/macro-reify-unreify.check create mode 100644 test/files/run/macro-reify-unreify.flags create mode 100644 test/files/run/macro-reify-unreify/Macros_1.scala create mode 100644 test/files/run/macro-reify-unreify/Test_2.scala create mode 100644 test/files/run/macro-reify-value-outside-reify.check create mode 100644 test/files/run/macro-reify-value-outside-reify.flags create mode 100644 test/files/run/macro-reify-value-outside-reify/Impls_Macros_1.scala create mode 100644 test/files/run/macro-reify-value-outside-reify/Test_2.scala delete mode 100644 test/files/run/macro-rettype-mismatch/Macros_1.scala delete mode 100644 test/files/run/macro-rettype-mismatch/Test_2.scala create mode 100644 test/files/run/macro-settings.check create mode 100644 test/files/run/macro-settings.flags create mode 100644 test/files/run/macro-settings/Impls_Macros_1.scala create mode 100644 test/files/run/macro-settings/Test_2.scala create mode 100644 test/files/run/macro-sip19-revised.check create mode 100644 test/files/run/macro-sip19-revised.flags create mode 100644 test/files/run/macro-sip19-revised/Impls_Macros_1.scala create mode 100644 test/files/run/macro-sip19-revised/Test_2.scala create mode 100644 test/files/run/macro-sip19.check create mode 100644 test/files/run/macro-sip19.flags create mode 100644 test/files/run/macro-sip19/Impls_Macros_1.scala create mode 100644 test/files/run/macro-sip19/Test_2.scala create mode 100644 test/files/run/macro-typecheck-implicitsdisabled.check create mode 100644 test/files/run/macro-typecheck-implicitsdisabled.flags create mode 100644 test/files/run/macro-typecheck-implicitsdisabled/Impls_Macros_1.scala create mode 100644 test/files/run/macro-typecheck-implicitsdisabled/Test_2.scala create mode 100644 test/files/run/macro-typecheck-macrosdisabled.check create mode 100644 test/files/run/macro-typecheck-macrosdisabled.flags create mode 100644 test/files/run/macro-typecheck-macrosdisabled/Impls_Macros_1.scala create mode 100644 test/files/run/macro-typecheck-macrosdisabled/Test_2.scala create mode 100644 test/files/run/macro-undetparams-consfromsls.check create mode 100644 test/files/run/macro-undetparams-consfromsls.flags create mode 100644 test/files/run/macro-undetparams-consfromsls/Impls_Macros_1.scala create mode 100644 test/files/run/macro-undetparams-consfromsls/Test_2.scala create mode 100644 test/files/run/macro-undetparams-implicitval.check create mode 100644 test/files/run/macro-undetparams-implicitval.flags create mode 100644 test/files/run/macro-undetparams-implicitval/Test.scala create mode 100644 test/files/run/macro-undetparams-macroitself.check create mode 100644 test/files/run/macro-undetparams-macroitself.flags create mode 100644 test/files/run/macro-undetparams-macroitself/Impls_Macros_1.scala create mode 100644 test/files/run/macro-undetparams-macroitself/Test_2.scala create mode 100644 test/files/run/reify_ann2a.check create mode 100644 test/files/run/reify_ann2a.scala create mode 100644 test/files/run/reify_ann3.check create mode 100644 test/files/run/reify_ann3.scala create mode 100644 test/files/run/reify_ann4.check create mode 100644 test/files/run/reify_ann4.scala create mode 100644 test/files/run/reify_ann5.check create mode 100644 test/files/run/reify_ann5.scala create mode 100644 test/files/run/reify_classfileann_b.check create mode 100644 test/files/run/reify_classfileann_b.scala create mode 100644 test/files/run/reify_closure8b.check create mode 100644 test/files/run/reify_closure8b.scala create mode 100644 test/files/run/reify_metalevel_breach_+0_refers_to_1.check create mode 100644 test/files/run/reify_metalevel_breach_+0_refers_to_1.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_a.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_a.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_b.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_0_b.scala create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_1.check create mode 100644 test/files/run/reify_metalevel_breach_-1_refers_to_1.scala create mode 100644 test/files/run/reify_nested_inner_refers_to_global.check create mode 100644 test/files/run/reify_nested_inner_refers_to_global.scala create mode 100644 test/files/run/reify_nested_inner_refers_to_local.check create mode 100644 test/files/run/reify_nested_inner_refers_to_local.scala create mode 100644 test/files/run/reify_nested_outer_refers_to_global.check create mode 100644 test/files/run/reify_nested_outer_refers_to_global.scala create mode 100644 test/files/run/reify_nested_outer_refers_to_local.check create mode 100644 test/files/run/reify_nested_outer_refers_to_local.scala create mode 100644 test/files/run/reify_newimpl_01.check create mode 100644 test/files/run/reify_newimpl_01.scala create mode 100644 test/files/run/reify_newimpl_02.check create mode 100644 test/files/run/reify_newimpl_02.scala create mode 100644 test/files/run/reify_newimpl_03.check create mode 100644 test/files/run/reify_newimpl_03.scala create mode 100644 test/files/run/reify_newimpl_04.check create mode 100644 test/files/run/reify_newimpl_04.scala create mode 100644 test/files/run/reify_newimpl_05.check create mode 100644 test/files/run/reify_newimpl_05.scala create mode 100644 test/files/run/reify_newimpl_06.check create mode 100644 test/files/run/reify_newimpl_06.scala create mode 100644 test/files/run/reify_newimpl_09.check create mode 100644 test/files/run/reify_newimpl_09.scala create mode 100644 test/files/run/reify_newimpl_10.check create mode 100644 test/files/run/reify_newimpl_10.scala create mode 100644 test/files/run/reify_newimpl_11.check create mode 100644 test/files/run/reify_newimpl_11.scala create mode 100644 test/files/run/reify_newimpl_12.check create mode 100644 test/files/run/reify_newimpl_12.scala create mode 100644 test/files/run/reify_newimpl_13.check create mode 100644 test/files/run/reify_newimpl_13.scala create mode 100644 test/files/run/reify_newimpl_14.check create mode 100644 test/files/run/reify_newimpl_14.scala create mode 100644 test/files/run/reify_newimpl_15.check create mode 100644 test/files/run/reify_newimpl_15.scala create mode 100644 test/files/run/reify_newimpl_16.check create mode 100644 test/files/run/reify_newimpl_16.scala create mode 100644 test/files/run/reify_newimpl_17.check create mode 100644 test/files/run/reify_newimpl_17.scala create mode 100644 test/files/run/reify_newimpl_18.check create mode 100644 test/files/run/reify_newimpl_18.scala create mode 100644 test/files/run/reify_newimpl_19.check create mode 100644 test/files/run/reify_newimpl_19.scala create mode 100644 test/files/run/reify_newimpl_20.check create mode 100644 test/files/run/reify_newimpl_20.scala create mode 100644 test/files/run/reify_newimpl_21.check create mode 100644 test/files/run/reify_newimpl_21.scala create mode 100644 test/files/run/reify_newimpl_22.check create mode 100644 test/files/run/reify_newimpl_22.scala create mode 100644 test/files/run/reify_newimpl_23.check create mode 100644 test/files/run/reify_newimpl_23.scala create mode 100644 test/files/run/reify_newimpl_24.check create mode 100644 test/files/run/reify_newimpl_24.scala create mode 100644 test/files/run/reify_newimpl_25.check create mode 100644 test/files/run/reify_newimpl_25.scala create mode 100644 test/files/run/reify_newimpl_26.check create mode 100644 test/files/run/reify_newimpl_26.scala create mode 100644 test/files/run/reify_newimpl_27.check create mode 100644 test/files/run/reify_newimpl_27.scala create mode 100644 test/files/run/reify_newimpl_28.check create mode 100644 test/files/run/reify_newimpl_28.scala create mode 100644 test/files/run/reify_newimpl_29.check create mode 100644 test/files/run/reify_newimpl_29.scala create mode 100644 test/files/run/reify_newimpl_30.check create mode 100644 test/files/run/reify_newimpl_30.scala create mode 100644 test/files/run/reify_newimpl_31.check create mode 100644 test/files/run/reify_newimpl_31.scala create mode 100644 test/files/run/reify_newimpl_32.check create mode 100644 test/files/run/reify_newimpl_32.scala create mode 100644 test/files/run/reify_newimpl_33.check create mode 100644 test/files/run/reify_newimpl_33.scala create mode 100644 test/files/run/reify_newimpl_34.check create mode 100644 test/files/run/reify_newimpl_34.scala create mode 100644 test/files/run/reify_newimpl_36.check create mode 100644 test/files/run/reify_newimpl_36.scala create mode 100644 test/files/run/reify_newimpl_37.check create mode 100644 test/files/run/reify_newimpl_37.scala create mode 100644 test/files/run/reify_newimpl_38.check create mode 100644 test/files/run/reify_newimpl_38.scala create mode 100644 test/files/run/reify_newimpl_39.check create mode 100644 test/files/run/reify_newimpl_39.scala create mode 100644 test/files/run/reify_newimpl_40.check create mode 100644 test/files/run/reify_newimpl_40.scala create mode 100644 test/files/run/reify_newimpl_41.check create mode 100644 test/files/run/reify_newimpl_41.scala create mode 100644 test/files/run/reify_newimpl_42.check create mode 100644 test/files/run/reify_newimpl_42.scala create mode 100644 test/files/run/reify_newimpl_43.check create mode 100644 test/files/run/reify_newimpl_43.scala create mode 100644 test/files/run/reify_newimpl_44.check create mode 100644 test/files/run/reify_newimpl_44.scala create mode 100644 test/files/run/reify_newimpl_45.check create mode 100644 test/files/run/reify_newimpl_45.scala create mode 100644 test/files/run/reify_newimpl_47.check create mode 100644 test/files/run/reify_newimpl_47.scala create mode 100644 test/files/run/reify_newimpl_48.check create mode 100644 test/files/run/reify_newimpl_48.scala create mode 100644 test/files/run/reify_newimpl_49.check create mode 100644 test/files/run/reify_newimpl_49.scala create mode 100644 test/files/run/reify_newimpl_50.check create mode 100644 test/files/run/reify_newimpl_50.scala create mode 100644 test/files/run/reify_newimpl_51.check create mode 100644 test/files/run/reify_newimpl_51.scala create mode 100644 test/files/run/reify_newimpl_52.check create mode 100644 test/files/run/reify_newimpl_52.scala create mode 100644 test/files/run/reify_typerefs_1a.check create mode 100644 test/files/run/reify_typerefs_1a.scala create mode 100644 test/files/run/reify_typerefs_1b.check create mode 100644 test/files/run/reify_typerefs_1b.scala create mode 100644 test/files/run/reify_typerefs_2a.check create mode 100644 test/files/run/reify_typerefs_2a.scala create mode 100644 test/files/run/reify_typerefs_2b.check create mode 100644 test/files/run/reify_typerefs_2b.scala create mode 100644 test/files/run/reify_typerefs_3a.check create mode 100644 test/files/run/reify_typerefs_3a.scala create mode 100644 test/files/run/reify_typerefs_3b.check create mode 100644 test/files/run/reify_typerefs_3b.scala delete mode 100644 test/files/run/t1195.check create mode 100644 test/files/run/t1195.check.temporarily.disabled delete mode 100644 test/files/run/t1195.scala create mode 100644 test/files/run/t1195.scala.temporarily.disabled create mode 100644 test/files/run/t3758.check delete mode 100644 test/files/run/t4110.check create mode 100644 test/files/run/t4110.check.temporarily.disabled delete mode 100644 test/files/run/t4110.scala create mode 100644 test/files/run/t4110.scala.temporarily.disabled delete mode 100644 test/files/run/t5258a.check delete mode 100644 test/files/run/t5258a.scala create mode 100644 test/files/run/toolbox_console_reporter.check create mode 100644 test/files/run/toolbox_console_reporter.scala create mode 100644 test/files/run/toolbox_default_reporter_is_silent.check create mode 100644 test/files/run/toolbox_default_reporter_is_silent.scala create mode 100644 test/files/run/toolbox_silent_reporter.check create mode 100644 test/files/run/toolbox_silent_reporter.scala create mode 100644 test/files/run/toolbox_typecheck_implicitsdisabled.check create mode 100644 test/files/run/toolbox_typecheck_implicitsdisabled.scala create mode 100644 test/files/run/toolbox_typecheck_macrosdisabled.check create mode 100644 test/files/run/toolbox_typecheck_macrosdisabled.scala delete mode 100644 test/files/run/treePrint.check create mode 100644 test/files/run/treePrint.check.temporarily.disabled delete mode 100644 test/files/run/treePrint.scala create mode 100644 test/files/run/treePrint.scala.temporarily.disabled create mode 100644 test/files/run/typetags_core.check create mode 100644 test/files/run/typetags_core.scala create mode 100644 test/pending/neg/reify_packed.check create mode 100644 test/pending/neg/reify_packed.scala create mode 100644 test/pending/run/macro-expand-default.flags create mode 100644 test/pending/run/macro-expand-default/Impls_1.scala create mode 100644 test/pending/run/macro-expand-default/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound.check create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound.flags create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound/Impls_1.scala create mode 100644 test/pending/run/macro-expand-implicit-macro-has-context-bound/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-named.flags create mode 100644 test/pending/run/macro-expand-named/Impls_1.scala create mode 100644 test/pending/run/macro-expand-named/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1.check create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1.flags create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1/Impls_1.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-e1/Macros_Test_2.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1.check create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1.flags create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1/Impls_1.scala create mode 100644 test/pending/run/macro-expand-tparams-prefix-f1/Macros_Test_2.scala delete mode 100644 test/pending/run/macro-overload.check delete mode 100644 test/pending/run/macro-overload.flags delete mode 100644 test/pending/run/macro-overload/Macros_1.scala delete mode 100644 test/pending/run/macro-overload/Test_2.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-a.check create mode 100644 test/pending/run/macro-quasiinvalidbody-a.flags create mode 100644 test/pending/run/macro-quasiinvalidbody-a/Impls_1.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-a/Macros_Test_2.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-b.check create mode 100644 test/pending/run/macro-quasiinvalidbody-b.flags create mode 100644 test/pending/run/macro-quasiinvalidbody-b/Impls_1.scala create mode 100644 test/pending/run/macro-quasiinvalidbody-b/Macros_Test_2.scala create mode 100644 test/pending/run/macro-reify-array.flags create mode 100644 test/pending/run/macro-reify-array/Macros_1.scala create mode 100644 test/pending/run/macro-reify-array/Test_2.scala create mode 100644 test/pending/run/macro-reify-eval-vs-value.flags create mode 100644 test/pending/run/macro-reify-eval-vs-value/Macros_1.scala create mode 100644 test/pending/run/macro-reify-eval-vs-value/Test_2.scala create mode 100644 test/pending/run/macro-reify-groundtypetag-hktypeparams-tags.check create mode 100644 test/pending/run/macro-reify-groundtypetag-hktypeparams-tags/Test.scala create mode 100644 test/pending/run/macro-reify-tagful-b.check create mode 100644 test/pending/run/macro-reify-tagful-b.flags create mode 100644 test/pending/run/macro-reify-tagful-b/Macros_1.scala create mode 100644 test/pending/run/macro-reify-tagful-b/Test_2.scala create mode 100644 test/pending/run/macro-reify-tagless-b.check create mode 100644 test/pending/run/macro-reify-tagless-b.flags create mode 100644 test/pending/run/macro-reify-tagless-b/Impls_Macros_1.scala create mode 100644 test/pending/run/macro-reify-tagless-b/Test_2.scala create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-notags.check create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-notags/Test.scala create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-tags.check create mode 100644 test/pending/run/macro-reify-typetag-hktypeparams-tags/Test.scala delete mode 100644 test/pending/run/reify_classfileann_b.check delete mode 100644 test/pending/run/reify_classfileann_b.scala delete mode 100644 test/pending/run/reify_closure8b.check delete mode 100644 test/pending/run/reify_closure8b.scala create mode 100644 test/pending/run/reify_newimpl_07.scala create mode 100644 test/pending/run/reify_newimpl_08.scala create mode 100644 test/pending/run/reify_newimpl_35.scala create mode 100644 test/pending/run/reify_newimpl_46.scala create mode 100644 test/pending/run/reify_newimpl_53.scala create mode 100644 test/pending/run/t5258a.check create mode 100644 test/pending/run/t5258a.scala diff --git a/build.xml b/build.xml index 6a3bc1d4c7..29c84cd610 100644 --- a/build.xml +++ b/build.xml @@ -170,7 +170,7 @@ PROPERTIES - + diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index 0bbbea1e7b..d74b6353d9 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -f9fcb59f3dbe1b060f8c57d4463dde5e0796951f ?scala-compiler.jar +d2808836aef2cbee506f9b0b0e346c749cac9ad8 ?scala-compiler.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 703eb006da..78e9f0b593 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -1d53671b52f2052c0690fcef9c9989150d8a4704 ?scala-library.jar +752baeeb4a01c7c50ac0dc6e0f59f5598696a223 ?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..b1c822ed97 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 GroundTypeTagClass = getMember(TypeTagsClass, tpnme.GroundTypeTag) + lazy val GroundTypeTagModule = getMember(TypeTagsClass, nme.GroundTypeTag) + + 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_materializeGroundTypeTag = getMember(MacroInternalPackage, nme.materializeGroundTypeTag) 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) @@ -993,7 +1009,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/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..b72610f1e0 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -44,6 +44,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") @@ -123,6 +124,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 GroundTypeTag: NameType = "GroundTypeTag" // fictions we use as both types and terms final val ERROR: NameType = "" @@ -140,10 +144,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 +191,34 @@ trait StdNames extends NameManglers { self: SymbolTable => trait TermNames extends Keywords with CommonNames { // Compiler internal names - val EXPAND_SEPARATOR_STRING = "$$" - - val ANYNAME: NameType = "" - val CONSTRUCTOR: NameType = "" - 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 = "" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter - val SELECTOR_DUMMY: NameType = "" - 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 = "" + val CONSTRUCTOR: NameType = "" + 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 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 = "" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter + val SELECTOR_DUMMY: NameType = "" + 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" @@ -260,6 +268,8 @@ trait StdNames extends NameManglers { self: SymbolTable => case _ => newTermName("x$" + i) } + // [Eugene to Paul] see comments in StandardNames.scala to find out why's this here + val QQQ = ??? val ??? = encode("???") val wrapRefArray: NameType = "wrapRefArray" @@ -275,12 +285,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" @@ -311,6 +347,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 +359,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 +369,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 +377,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 +389,54 @@ 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 materializeGroundTypeTag: NameType = "materializeGroundTypeTag" 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 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,6 +447,8 @@ 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" @@ -582,9 +641,14 @@ trait StdNames extends NameManglers { self: SymbolTable => val ZOR = encode("||") // unary operators + // [Eugene to Paul] see comments in StandardNames.scala to find out why's this here + val UNARY_TILDE = UNARY_~ val UNARY_~ = encode("unary_~") + val UNARY_PLUS = UNARY_+ val UNARY_+ = encode("unary_+") + val UNARY_MINUS = UNARY_- val UNARY_- = encode("unary_-") + val UNARY_NOT = UNARY_! val UNARY_! = encode("unary_!") // Grouped here so Cleanup knows what tests to perform. diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 83a24dce68..ffc8178528 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 @@ -158,7 +162,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. diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 04bdb0f4ad..fc94e96acd 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,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => abstract class AbsSymbolImpl extends AbsSymbol { this: Symbol => + def kind: String = kindString + 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 +331,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 +550,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 +572,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 +623,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 . Subclasses * of Symbol refine. @@ -632,7 +642,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 +790,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? */ @@ -865,6 +879,23 @@ 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 (isType && isNonClassType) 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 +1323,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 @@ -1946,7 +1977,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 +2063,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 +2087,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 +2250,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 +2441,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 +2472,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 +2504,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 => "" // DEFAULTPARAM case EXISTENTIAL => "" // MIXEDIN @@ -2877,7 +2913,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 +2949,15 @@ 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 + } + + // [Eugene] the NoSymbol origin works for type parameters. what about existential free types? + 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 */ @@ -3068,7 +3107,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..ed22cad730 100644 --- a/src/compiler/scala/reflect/internal/TreeInfo.scala +++ b/src/compiler/scala/reflect/internal/TreeInfo.scala @@ -531,4 +531,198 @@ abstract class TreeInfo { case _ => None } } + + // 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[ValDef], 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[ValDef], 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 map (_.asInstanceOf[ValDef]), tree, tpe) + case _ => + None + } + } + + object InlineableTreeSplice { + def unapply(tree: Tree): Option[(Tree, List[ValDef], 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[ValDef], 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[ValDef], Tree)] = tree match { + case reifee @ Block((mrDef @ ValDef(_, _, _, _)) :: symbolTable, Apply(_, List(tpe))) if mrDef.name == nme.MIRROR_SHORT => + Some(reifee, symbolTable map (_.asInstanceOf[ValDef]), tpe) + case _ => + None + } + } + + object InlinedTypeSplice { + def unapply(tree: Tree): Option[(Tree, List[ValDef], 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..9b4c18ce86 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() diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index c0d6f54b1a..0d7e68aee3 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -184,7 +184,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 +203,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 +235,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 +250,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).(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 +296,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 +304,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 +361,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 +428,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..73a8f5c55c 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -254,7 +254,9 @@ trait Types extends api.Types { self: SymbolTable => case object UnmappableTree extends TermTree { override def toString = "" super.tpe_=(NoType) - override def tpe_=(t: Type) = if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for ") + override def tpe_=(t: Type) = if (t != NoType) { + throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for ") + } } abstract class AbsTypeImpl extends AbsType { this: Type => @@ -262,7 +264,7 @@ 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) } @@ -723,6 +725,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)) @@ -1194,6 +1199,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 @@ -1822,7 +1829,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] } } @@ -3751,6 +3786,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 +4600,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) 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/Errors.scala b/src/compiler/scala/reflect/makro/runtime/Errors.scala new file mode 100644 index 0000000000..d78eae9237 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Errors.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/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..826fa7153f --- /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, noTypeVariablesInResult: Boolean = false): Tree = + reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, noTypeVariablesInResult) + + def unreifyTree(tree: Tree): Tree = + Select(tree, definitions.ExprEval) + + def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireGroundTypeTag: 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, requireGroundTypeTag) + + 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..8bfe64621b --- /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 CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe: Type) = { + val msg = "cannot reify GroundTypeTag 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) "" 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/Reifiers.scala b/src/compiler/scala/reflect/reify/Reifiers.scala new file mode 100644 index 0000000000..6854710949 --- /dev/null +++ b/src/compiler/scala/reflect/reify/Reifiers.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 requireGroundTypeTag: 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 (definitelyGround) GroundTypeTagModule 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 (definitelyGround) GroundTypeTagModule 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/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..3328f5e402 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Symbols.scala @@ -0,0 +1,111 @@ +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) { + if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym) + reifyFreeTerm(sym, Ident(sym)) + } else { + if (reifyDebug) println("Free type: " + sym) + reifyFreeType(sym, Ident(sym)) + } + } + } + + def reifyFreeTerm(sym: Symbol, value: Tree): Tree = + locallyReified get sym match { + case Some(reified) => + reified + case None => + if (sym.isCapturedVariable) { + assert(value.isInstanceOf[Ident], showRaw(value)) + val capturedTpe = capturedVariableType(sym) + val capturedValue = referenceCapturedVariable(sym) + locallyReify(sym, mirrorCall(nme.newFreeTerm, reify(sym.name.toString), reify(capturedTpe), capturedValue, reify(origin(sym)))) + } else { + locallyReify(sym, 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 => + 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, mirrorCall(nme.newFreeType, reify(sym.name.toString), reify(sym.info), phantomTypeTag, reify(origin(sym)))) + } + + import scala.collection.mutable._ + private val localReifications = ArrayBuffer[ValDef]() + private val locallyReified = Map[Symbol, Tree]() + def symbolTable: List[ValDef] = localReifications.toList + def symbolTable_=(newSymbolTable: List[ValDef]): Unit = { + localReifications.clear() + locallyReified.clear() + newSymbolTable foreach { + case freedef @ FreeDef(_, name, binding, _) => + if (!(locallyReified contains binding.symbol)) { + localReifications += freedef + locallyReified(binding.symbol) = Ident(name) + } + } + } + + private def locallyReify(sym: Symbol, reificode: => Tree): Tree = { + val reified = reificode + val Apply(Select(_, flavor), _) = reified + // [Eugene] name clashes are impossible, right? + var name = newTermName(nme.MIRROR_FREE_PREFIX + sym.name) + if (flavor == nme.newFreeTerm && sym.isType) name = name.append(nme.MIRROR_FREE_THIS_SUFFIX); + // todo. also reify annotations for free vars + localReifications += ValDef(NoMods, name, TypeTree(), reified) + locallyReified(sym) = Ident(name) + locallyReified(sym) + } +} \ 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..22f42aea49 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Trees.scala @@ -0,0 +1,220 @@ +package scala.reflect.reify +package codegen + +trait Trees { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + /** + * 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) + } + + 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 foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, 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 (eligibleForSplicing(tpe)) { + 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..6f3a60a076 --- /dev/null +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -0,0 +1,226 @@ +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) + CannotReifyType(tpe) + case _ => +// reifyToughType(tpe) + CannotReifyType(tpe) + } + } + + /** An obscure flag necessary for implicit TypeTag generation */ + private var spliceTypesEnabled = !dontSpliceAtTopLevel + + /** Keeps track of whether this reification contains abstract type parameters */ + var maybeGround = true + var definitelyGround = true + + def eligibleForSplicing(tpe: Type): Boolean = { + // [Eugene] is this comprehensive? + // the only thingies that we want to splice are: 1) type parameters, 2) type members + // this check seems to cover them all, right? + tpe.isInstanceOf[TypeRef] && tpe.typeSymbol.isAbstractType + } + + 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 (eligibleForSplicing(tpe)) { + if (reifyDebug) println("splicing " + tpe) + + if (spliceTypesEnabled) { + var tagClass = if (requireGroundTypeTag) GroundTypeTagClass 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, requireGroundTypeTag) match { + case failure if failure.isEmpty => + if (reifyDebug) println("implicit search was fruitless") + definitelyGround &= false + maybeGround &= false + EmptyTree + case success => + if (reifyDebug) println("implicit search has produced a result: " + success) + definitelyGround |= requireGroundTypeTag + maybeGround |= 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 foreach { case freedef @ FreeDef(_, _, binding, _) => assert(!binding.symbol.isLocalToReifee, 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 (requireGroundTypeTag) + CannotReifyGroundTypeTagHavingUnresolvedTypeParameters(tpe) + } + + spliceTypesEnabled = true + EmptyTree + } + + // yet another thingie disabled for simplicity + // in principle, we could retain and reify AnnotatedTypes + // but that'd require reifying every type and symbol inside ann.args + // however, since we've given up on tough types for the moment, the former would be problematic +// private def reifyAnnotatedType(tpe: AnnotatedType): Tree = { +// // ``Reshaper'' transforms annotation infos from symbols back into Modifier.annotations, which are trees +// // so the only place on Earth that can lead to reification of AnnotationInfos is the Ay Tee Land +// // therefore this function is as local as possible, don't move it out of this scope +// 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)) +// } +// +// val AnnotatedType(anns, underlying, selfsym) = tpe +// mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying), reify(selfsym)) +// } + + // previous solution to reifying tough types involved creating dummy symbols (see ``registerReifiableSymbol'' calls below) + // however such symbols lost all the connections with their origins and became almost useless, except for typechecking + // hence this approach was replaced by less powerful, but more principled one based on ``reifyFreeType'' + // it's possible that later on we will revise and revive ``reifyToughType'', but for now it's disabled under an implementation restriction +// /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */ +// // This is the uncharted territory in the reifier +// private def reifyToughType(tpe: Type): Tree = { +// if (reifyDebug) println("tough type: %s (%s)".format(tpe, tpe.kind)) +// +// def reifyScope(scope: Scope): Tree = { +// scope foreach registerReifiableSymbol +// mirrorCall(nme.newScopeWith, scope.toList map reify: _*) +// } +// +// tpe match { +// case tpe @ RefinedType(parents, decls) => +// registerReifiableSymbol(tpe.typeSymbol) +// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) +// case tpe @ ExistentialType(tparams, underlying) => +// tparams foreach registerReifiableSymbol +// mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) +// case tpe @ ClassInfoType(parents, decls, clazz) => +// registerReifiableSymbol(clazz) +// mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) +// case tpe @ MethodType(params, restpe) => +// params foreach registerReifiableSymbol +// mirrorFactoryCall(tpe, reify(params), reify(restpe)) +// case tpe @ PolyType(tparams, underlying) => +// tparams foreach registerReifiableSymbol +// 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..7041fbf6ed --- /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, requireGroundTypeTag: Boolean = false): Reifier { val mirror: global.type } = { + val typer1: typer.type = typer + val prefix1: prefix.type = prefix + val reifee1 = reifee + val dontSpliceAtTopLevel1 = dontSpliceAtTopLevel + val requireGroundTypeTag1 = requireGroundTypeTag + + new { + val mirror: global.type = global + val typer = typer1 + val prefix = prefix1 + val reifee = reifee1 + val dontSpliceAtTopLevel = dontSpliceAtTopLevel1 + val requireGroundTypeTag = requireGroundTypeTag1 + } 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..59a36f0ba4 --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala @@ -0,0 +1,61 @@ +package scala.reflect.reify +package phases + +trait Calculate { + self: Reifier => + + import mirror._ + import definitions._ + import treeInfo._ + + implicit def sym2richSym(sym: Symbol): RichSymbol = new RichSymbol(sym) + 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 def tpe2richTpe(tpe: Type): RichType = new RichType(tpe) + 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) + } + } +} \ No newline at end of file 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..a329a1043d --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Metalevels.scala @@ -0,0 +1,148 @@ +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 + 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..f6d6423605 --- /dev/null +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -0,0 +1,42 @@ +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 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) + 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 + * ., 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 _ => "" + } + 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 _ => "" + } + 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/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala deleted file mode 100644 index 4b35a5b37e..0000000000 --- a/src/compiler/scala/reflect/runtime/Loaders.scala +++ /dev/null @@ -1,130 +0,0 @@ -package scala.reflect -package runtime - -import internal.Flags -import java.lang.{Class => jClass, Package => jPackage} -import collection.mutable - -trait Loaders { self: SymbolTable => - - /** The lazy type for root. - */ - override val rootLoader = new LazyType { - override def complete(sym: Symbol) = sym setInfo new LazyPackageType - } - - /** The standard completer for top-level classes - * @param clazz The top-level class - * @param module The companion object of `clazz` - * Calling `complete` on this type will assign the infos of `clazz` and `module` - * by unpickling information from the corresponding Java class. If no Java class - * is found, a package is created instead. - */ - class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader { -// def makePackage() { -// println("wrong guess; making package "+clazz) -// val ptpe = newPackageType(module.moduleClass) -// for (sym <- List(clazz, module, module.moduleClass)) { -// sym setFlag Flags.PACKAGE -// sym setInfo ptpe -// } -// } - - override def complete(sym: Symbol) = { - debugInfo("completing "+sym+"/"+clazz.fullName) - assert(sym == clazz || sym == module || sym == module.moduleClass) -// try { - atPhaseNotLaterThan(picklerPhase) { - unpickleClass(clazz, module, javaClass(clazz.javaClassName)) -// } catch { -// case ex: ClassNotFoundException => makePackage() -// case ex: NoClassDefFoundError => makePackage() - // Note: We catch NoClassDefFoundError because there are situations - // where a package and a class have the same name except for capitalization. - // It seems in this case the class is loaded even if capitalization differs - // but then a NoClassDefFound error is issued with a ("wrong name: ...") - // reason. (I guess this is a concession to Windows). - // The present behavior is a bit too forgiving, in that it masks - // all class load errors, not just wrong name errors. We should try - // to be more discriminating. To get on the right track simply delete - // the clause above and load a collection class such as collection.Iterable. - // You'll see an error that class `parallel` has the wrong name. -// } - } - } - override def load(sym: Symbol) = complete(sym) - } - - /** Create a class and a companion object, enter in enclosing scope, - * and initialize with a lazy type completer. - * @param owner The owner of the newly created class and object - * @param name The simple name of the newly created class - * @param completer The completer to be used to set the info of the class and the module - */ - protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { - assert(!(name.toString endsWith "[]"), name) - val clazz = owner.newClass(name) - val module = owner.newModule(name.toTermName) - owner.info.decls enter clazz - owner.info.decls enter module - initClassModule(clazz, module, completer(clazz, module)) - (clazz, module) - } - - protected def setAllInfos(clazz: Symbol, module: Symbol, info: Type) = { - List(clazz, module, module.moduleClass) foreach (_ setInfo info) - } - - protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = - setAllInfos(clazz, module, completer) - - /** The type completer for packages. - */ - class LazyPackageType extends LazyType { - override def complete(sym: Symbol) { - assert(sym.isPackageClass) - sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym) - // override def safeToString = pkgClass.toString - openPackageModule(sym) - } - } - - /** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because - * these are nested classes or anonymous classes, - */ - def invalidClassName(name: Name) = { - val dp = name pos '$' - 0 < dp && dp < (name.length - 1) - } - - class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope { - assert(pkgClass.isType) - private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. - override def lookupEntry(name: Name): ScopeEntry = { - val e = super.lookupEntry(name) - if (e != null) - e - else if (invalidClassName(name) || (negatives contains name)) - null - else { - val path = - if (pkgClass.isEmptyPackageClass) name.toString - else pkgClass.fullName + "." + name - if (isJavaClass(path)) { - val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) - debugInfo("created "+module+"/"+module.moduleClass+" in "+pkgClass) - lookupEntry(name) - } else { - debugInfo("*** not found : "+path) - negatives += name - null - } - } - } - } - - override def newPackageScope(pkgClass: Symbol) = new PackageScope(pkgClass) - - override def scopeTransform(owner: Symbol)(op: => Scope): Scope = - if (owner.isPackageClass) owner.info.decls else op -} 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/SymbolLoaders.scala b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala new file mode 100644 index 0000000000..7c1cc16152 --- /dev/null +++ b/src/compiler/scala/reflect/runtime/SymbolLoaders.scala @@ -0,0 +1,135 @@ +package scala.reflect +package runtime + +import internal.Flags +import java.lang.{Class => jClass, Package => jPackage} +import collection.mutable + +trait SymbolLoaders { self: SymbolTable => + + /** The lazy type for root. + */ + override val rootLoader = new LazyType { + override def complete(sym: Symbol) = sym setInfo new LazyPackageType + } + + /** The standard completer for top-level classes + * @param clazz The top-level class + * @param module The companion object of `clazz` + * Calling `complete` on this type will assign the infos of `clazz` and `module` + * by unpickling information from the corresponding Java class. If no Java class + * is found, a package is created instead. + */ + class TopClassCompleter(clazz: Symbol, module: Symbol) extends SymLoader { +// def makePackage() { +// println("wrong guess; making package "+clazz) +// val ptpe = newPackageType(module.moduleClass) +// for (sym <- List(clazz, module, module.moduleClass)) { +// sym setFlag Flags.PACKAGE +// sym setInfo ptpe +// } +// } + + override def complete(sym: Symbol) = { + debugInfo("completing "+sym+"/"+clazz.fullName) + assert(sym == clazz || sym == module || sym == module.moduleClass) +// try { + atPhaseNotLaterThan(picklerPhase) { + unpickleClass(clazz, module, javaClass(clazz.javaClassName)) +// } catch { +// case ex: ClassNotFoundException => makePackage() +// case ex: NoClassDefFoundError => makePackage() + // Note: We catch NoClassDefFoundError because there are situations + // where a package and a class have the same name except for capitalization. + // It seems in this case the class is loaded even if capitalization differs + // but then a NoClassDefFound error is issued with a ("wrong name: ...") + // reason. (I guess this is a concession to Windows). + // The present behavior is a bit too forgiving, in that it masks + // all class load errors, not just wrong name errors. We should try + // to be more discriminating. To get on the right track simply delete + // the clause above and load a collection class such as collection.Iterable. + // You'll see an error that class `parallel` has the wrong name. +// } + } + } + override def load(sym: Symbol) = complete(sym) + } + + /** Create a class and a companion object, enter in enclosing scope, + * and initialize with a lazy type completer. + * @param owner The owner of the newly created class and object + * @param name The simple name of the newly created class + * @param completer The completer to be used to set the info of the class and the module + */ + protected def createClassModule(owner: Symbol, name: TypeName, completer: (Symbol, Symbol) => LazyType) = { + assert(!(name.toString endsWith "[]"), name) + val clazz = owner.newClass(name) + val module = owner.newModule(name.toTermName) + owner.info.decls enter clazz + owner.info.decls enter module + initClassModule(clazz, module, completer(clazz, module)) + (clazz, module) + } + + protected def setAllInfos(clazz: Symbol, module: Symbol, info: Type) = { + List(clazz, module, module.moduleClass) foreach (_ setInfo info) + } + + protected def initClassModule(clazz: Symbol, module: Symbol, completer: LazyType) = + setAllInfos(clazz, module, completer) + + /** The type completer for packages. + */ + class LazyPackageType extends LazyType { + override def complete(sym: Symbol) { + assert(sym.isPackageClass) + sym setInfo new ClassInfoType(List(), new PackageScope(sym), sym) + // override def safeToString = pkgClass.toString + openPackageModule(sym) + } + } + + /** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because + * these are nested classes or anonymous classes, + */ + def invalidClassName(name: Name) = { + val dp = name pos '$' + 0 < dp && dp < (name.length - 1) + } + + class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope { + assert(pkgClass.isType) + private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected. + override def lookupEntry(name: Name): ScopeEntry = { + val e = super.lookupEntry(name) + if (e != null) + e + else if (invalidClassName(name) || (negatives contains name)) + null + else { + val path = + if (pkgClass.isEmptyPackageClass) name.toString + else pkgClass.fullName + "." + name + if (isJavaClass(path)) { + val (clazz, module) = createClassModule(pkgClass, name.toTypeName, new TopClassCompleter(_, _)) + debugInfo("created "+module+"/"+module.moduleClass+" in "+pkgClass) + lookupEntry(name) + } else { + debugInfo("*** not found : "+path) + negatives += name + null + } + } + } + } + + /** 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 = + if (owner.isPackageClass) owner.info.decls else op +} 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 - * ., 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(""), 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(""), 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) = "" - - 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/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/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/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 5e0c24d304..b7d7f5d16f 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 } @@ -32,24 +32,25 @@ 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 { +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 +62,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 +79,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 +130,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 +140,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 +217,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 +321,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)) @@ -1108,7 +1110,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. */ @@ -1581,7 +1583,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 +1591,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 +1599,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/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..ff4e2f3fb5 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]() 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..c79ca1206e 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -27,24 +27,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 +81,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 +90,7 @@ abstract class NodePrinters { } } } - + trait PrintAST { private val buf = new StringBuilder private var level = 0 @@ -101,7 +101,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 +122,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 +140,7 @@ abstract class NodePrinters { } } def println(s: String) = printLine(s, "") - + def printLine(value: String, comment: String) { buf append " " * level buf append value @@ -183,7 +189,7 @@ abstract class NodePrinters { traverseList("Nil", "argument")(args) } } - + def printMultiline(tree: Tree)(body: => Unit) { printMultiline(tree.printingPrefix, showAttributes(tree))(body) } @@ -299,7 +305,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 +345,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/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index ad26ccad5e..19d1e0a51a 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -207,22 +207,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..66704680ae 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 @@ -84,15 +61,6 @@ trait Trees extends reflect.internal.Trees { self: Global => /** 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 +86,7 @@ trait Trees extends reflect.internal.Trees { self: Global => // create parameters for 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 +98,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 +166,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 +175,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 +188,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 +209,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 +235,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 +251,8 @@ 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) /** A transformer which resets symbol and tpe fields of all nodes in a given tree, * with special treatment of: @@ -308,7 +263,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) { val debug = settings.debug.value val trace = scala.tools.nsc.util.trace when debug @@ -328,6 +283,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 +296,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 +305,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))) + 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 = { - new MarkLocals().traverse(x) + 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] } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index e7e3eaabf5..daabfae6b3 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1771,7 +1771,23 @@ self => * }}} */ def pattern2(): Tree = { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case _ => + ; + } + } + val p = pattern3() + warnIfMacro(p) + if (in.token != AT) p else p match { case Ident(nme.WILDCARD) => @@ -2421,10 +2437,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 +2460,16 @@ 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) + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different 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 +2477,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()) - val rhs = - if (isMacro) - equalsExpr() - else if (isStatSep || in.token == RBRACE) { + newLineOptWhenFollowedBy(LBRACE) + var restype = fromWithinReturnType(typedOpt()) + val rhs = + if (isStatSep || in.token == RBRACE) { if (restype.isEmpty) restype = scalaUnitConstr newmods |= Flags.DEFERRED EmptyTree @@ -2476,10 +2488,12 @@ 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?") + accept(EQUALS) + if (settings.Xmacros.value && in.token == MACRO) { + in.nextToken() + newmods |= Flags.MACRO } - equalsExpr() + expr() } DefDef(newmods, name, tparams, vparamss, restype, rhs) } @@ -2529,7 +2543,7 @@ self => /** {{{ * TypeDef ::= type Id [TypeParamClause] `=' Type - * | `macro' FunSig `=' Expr + * | FunSig `=' Expr * TypeDcl ::= type Id [TypeParamClause] TypeBounds * }}} */ @@ -2537,22 +2551,22 @@ 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 - } + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + // @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,7 +2613,10 @@ self => def classDef(start: Int, mods: Modifiers): ClassDef = { in.nextToken val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = identForType() + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") atPos(start, if (name == tpnme.ERROR) start else nameOffset) { savingClassContextBounds { @@ -2640,7 +2657,10 @@ self => def objectDef(start: Int, mods: Modifiers): ModuleDef = { in.nextToken val nameOffset = in.offset + val isBackquoted = in.token == BACKQUOTED_IDENT val name = ident() + if (name.toString == nme.MACROkw.toString && !isBackquoted) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") val tstart = in.offset atPos(start, if (name == nme.ERROR) start else nameOffset) { val mods1 = if (in.token == SUBTYPE) mods | Flags.DEFERRED else mods @@ -2818,7 +2838,25 @@ self => * }}} */ def packaging(start: Int): Tree = { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case Select(qual, name) => + warnIfMacro(qual) + check(name) + case _ => + ; + } + } + val pkg = pkgQualId() + warnIfMacro(pkg) val stats = inBracesOrNil(topStatSeq()) makePackaging(start, pkg, stats) } @@ -3020,8 +3058,29 @@ self => ts ++= topStatSeq() } } else { + val nameOffset = in.offset + def warnIfMacro(tree: Tree): Unit = { + def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString) + warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.") + tree match { + // [Eugene] pkgQualId never returns BackQuotedIdents + // this means that we'll get spurious warnings even if we wrap macro package name in backquotes + case _: BackQuotedIdent => + ; + case Ident(name) => + check(name) + case Select(qual, name) => + warnIfMacro(qual) + check(name) + case _ => + ; + } + } + in.flushDoc val pkg = pkgQualId() + warnIfMacro(pkg) + 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..81d81a4fb7 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -1125,7 +1125,8 @@ trait Scanners extends ScannersCommon { nme.SUPERTYPEkw -> SUPERTYPE, nme.HASHkw -> HASH, nme.ATkw -> AT - ) + ) ++ + (if (settings.Xmacros.value) List(nme.MACROkw -> MACRO) else List()) private var kwOffset: Int = -1 private val kwArray: Array[Int] = { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index fb4daefd57..e17bbf5e46 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -110,6 +110,7 @@ object Tokens extends Tokens { final val MATCH = 58 final val FORSOME = 59 final val LAZY = 61 + final val MACRO = 62 def isKeyword(code: Int) = code >= IF && code <= LAZY diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index be1e466f4e..c04be1721e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -651,7 +651,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..98c1fc2f63 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -365,7 +365,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 +388,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 +968,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/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 5b298b3761..12a3c4b3c6 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -957,7 +957,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/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 0c64bb2901..c0f7d8412a 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 @@ -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 diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index 14876425f4..cc06100f5f 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 } diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala index ad6e8dc48d..e293c0fed9 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala @@ -58,7 +58,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/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/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index e7959f36b2..ea12300785 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 => diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 14b3bcc8ce..e9a7e3dab4 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -80,6 +80,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.") @@ -116,62 +119,62 @@ 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 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 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 +183,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.") + 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/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/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 758f870d6b..edbe6df472 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -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/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..eea87c8ba6 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -542,7 +542,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..e2ce3b62b4 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -734,7 +734,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 +1090,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/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..0e4975c04c 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -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/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index f90d3d45fe..11f06a0541 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -358,18 +358,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..b400743469 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)) @@ -581,9 +584,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 +625,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 "" ) ) } @@ -848,6 +850,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 _ => diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 9b1f395ad0..fe1c90fe67 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -105,8 +105,8 @@ 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 - // are currently searched + 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 var prefix: Type = NoPrefix @@ -119,6 +119,7 @@ trait Contexts { self: Analyzer => var diagnostic: List[String] = Nil // these messages are printed when issuing an error var implicitsEnabled = false + var macrosEnabled = true var checking = false var retyping = false @@ -181,6 +182,13 @@ 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 @@ -188,6 +196,20 @@ trait Contexts { self: Analyzer => finally implicitsEnabled = saved } + 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, scope: Scope, imports: List[ImportInfo]): Context = { val c = new Context @@ -223,6 +245,7 @@ trait Contexts { self: Analyzer => c.diagnostic = this.diagnostic c.typingIndentLevel = typingIndentLevel c.implicitsEnabled = this.implicitsEnabled + c.macrosEnabled = this.macrosEnabled c.checking = this.checking c.retyping = this.retyping c.openImplicits = this.openImplicits @@ -237,6 +260,7 @@ trait Contexts { self: Analyzer => val c = make(unit, EmptyTree, owner, scope, imports) c.setReportErrors() c.implicitsEnabled = true + c.macrosEnabled = true c } @@ -312,6 +336,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 +344,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 +354,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..8aa257983a 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 @@ -100,8 +108,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`, @@ -251,8 +257,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 +273,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,13 +367,13 @@ 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 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 { @@ -515,7 +531,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 +539,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) { @@ -707,6 +719,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. @@ -825,7 +838,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 +1098,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, GroundTypeTagClass) + private val TagMaterializers = Map( + ClassTagClass -> MacroInternal_materializeClassTag, + TypeTagClass -> MacroInternal_materializeTypeTag, + GroundTypeTagClass -> MacroInternal_materializeGroundTypeTag + ) - /** 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 +1159,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 +1181,7 @@ trait Implicits { val failstart = startTimer(oftypeFailNanos) val succstart = startTimer(oftypeSucceedNanos) - result = implicitManifestOrOfExpectedType(pt) + result = implicitTagOrOfExpectedType(pt) if (result == SearchFailure) { context.updateBuffer(previousErrs) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index ebf8e3fc9a..98b8d7673e 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() } @@ -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,6 +438,9 @@ 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]] @@ -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) @@ -1568,9 +1586,9 @@ trait Infer { else infer } - /** Assign tree the type of unique polymorphic alternative + /** Assign tree the type of all polymorphic alternatives * with nparams 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..3b270a92ad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -3,135 +3,682 @@ 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 +/** + * 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) + def typedMacroBody(typer: Typer, ddef: DefDef): Tree = { + import typer.context + if (macroDebug) println("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) + + implicit def augmentString(s: String) = new AugmentedString(s) + 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 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)) + + 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 ." + + "\n or : macro ") + 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 ., 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 } + } + + new Mirror(libraryClassLoader) { override def toString = "" } + } - loader + /** 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 = "" } } - /** 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 _ => "" } - 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 +693,535 @@ 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.isGround) ttag.toGround 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 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 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 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 + } + 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 _ => - trace("macro is not overridden: ")(tree) + macroTrace("unexpected tree in fallback: ")(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 _ => - trace("unexpected tree in fallback: ")(tree) - notFound() - } - } - fallBackToOverridden(tree) match { - case Some(tree1) => - trace("falling back to ")(tree1) - currentRun.macroExpansionFailed = true - Some(tree1) - case None => - None + } + fallBackToOverridden(expandee) match { + case Some(tree1) => + macroTrace("falling back to ")(tree1) + currentRun.macroExpansionFailed = true + Fallback(tree1) + case None => + fail(typer, expandee) + } } + } + } 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..6382e5a847 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -28,6 +28,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,12 +59,13 @@ 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) } } import synthesisUtil._ @@ -373,7 +375,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..696952fe6a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -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, @@ -809,7 +796,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 +860,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 +1016,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?) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 806ee480f0..ad727d4082 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -227,6 +227,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. @@ -416,6 +418,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) { 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..1b508a96fe 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) @@ -813,7 +817,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 +1012,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 +1031,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) && @@ -1906,8 +1908,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) } @@ -2212,7 +2216,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) @@ -2267,7 +2271,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)) @@ -2489,7 +2493,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { 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)) + (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.hasDefault && @@ -2575,7 +2579,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 +2742,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) != NoSymbol) + duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun)) + } + if (mt.isErroneous) duplErrTree else if (inPatternMode(mode)) { // #2064 @@ -2755,8 +2765,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 +2776,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 { @@ -3111,7 +3124,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 +3164,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"+ @@ -3437,7 +3450,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 +3464,27 @@ 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 + original setPos tree.pos.focus + 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 +3527,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 +3540,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.focus setType atype } } @@ -3676,6 +3706,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 @@ -4534,7 +4565,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.isTermMacro => + MacroEtaError(expr1) + case _ => + typedEta(checkDead(expr1)) + } case Typed(expr0, tpt @ Ident(tpnme.WILDCARD_STAR)) => val expr = typed(expr0, onlyStickyModes(mode), WildcardType) @@ -4608,18 +4650,17 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { tpt.tpe.typeSymbol == ArrayClass && args.length == 1 && erasure.GenericArray.unapply(tpt.tpe).isDefined) => // !!! todo simplify by using extractor - // convert new Array[T](len) to evidence[ClassManifest[T]].newArray(len) - // convert new Array^N[T](len) for N > 1 to evidence[ClassManifest[T]].newArrayN(len) - val Some((level, manifType)) = erasure.GenericArray.unapply(tpt.tpe) - if (level > MaxArrayDims) - MultiDimensionalArrayError(tree) - else { - val newArrayApp = atPos(tree.pos) { - val manif = getManifestTree(tree, manifType, false) - new ApplyToImplicitArgs(Select(manif, if (level == 1) "newArray" else "newArray"+level), args) - } - typed(newArrayApp, mode, pt) + // convert new Array[T](len) to evidence[ClassTag[T]].newArray(len) + // convert new Array^N[T](len) for N > 1 to evidence[ClassTag[Array[...Array[T]...]]].newArray(len), where Array HK gets applied (N-1) times + // [Eugene] no more MaxArrayDims. ClassTags are flexible enough to allow creation of arrays of arbitrary dimensionality (w.r.t JVM restrictions) + val Some((level, componentType)) = erasure.GenericArray.unapply(tpt.tpe) + val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.asType, List(tpe))).last + val newArrayApp = atPos(tree.pos) { + val tag = resolveClassTag(tree, tagType) + if (tag.isEmpty) MissingClassTagError(tree, tagType) + else new ApplyToImplicitArgs(Select(tag, nme.newArray), args) } + typed(newArrayApp, mode, pt) case tree1 => tree1 } @@ -4679,7 +4720,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 ( @@ -4916,31 +4960,75 @@ 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) } + 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 { case Some(tree1) => transformed -= tree; tree1 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) GroundTypeTagClass 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/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index ce10ee34a2..11d7db5180 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -27,7 +27,7 @@ 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 locateJar[T: ClassManifest] = info[T].rootPossibles find (x => isJarOrZip(x)) map (x => File(x)) diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala index bc74717366..573f7bc7b2 100644 --- a/src/compiler/scala/tools/nsc/util/Position.scala +++ b/src/compiler/scala/tools/nsc/util/Position.scala @@ -33,62 +33,24 @@ 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(pos: scala.reflect.api.Position) = pos -/** 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 + /** 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 +96,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 +181,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 +216,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 +229,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 +253,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 +265,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 +275,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/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/library/scala/Predef.scala b/src/library/scala/Predef.scala index b5006e7948..d241d2ddc0 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -99,17 +99,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.GroundTypeTag` 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.GroundTypeTag` 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 GroundTypeTag[T] = scala.reflect.GroundTypeTag[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 GroundTypeTag = scala.reflect.GroundTypeTag + + // [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 groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag + // 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` 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..3e7b8071be 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) @@ -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/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/reflect/ArrayTags.scala b/src/library/scala/reflect/ArrayTags.scala new file mode 100644 index 0000000000..8df7fe5f4e --- /dev/null +++ b/src/library/scala/reflect/ArrayTags.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/ClassTags.scala b/src/library/scala/reflect/ClassTags.scala new file mode 100644 index 0000000000..2833e7cc8e --- /dev/null +++ b/src/library/scala/reflect/ClassTags.scala @@ -0,0 +1,158 @@ +package scala.reflect + +import java.lang.{ Class => jClass } +import scala.reflect.{ mirror => rm } + +/** 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. + */ +// 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 GroundTypeTags the representation is almost precise, because it uses 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.GroundTypeTag` to capture and analyze type arguments", "2.10.0") + def typeArguments: List[OptManifest[_]] = List() +} \ No newline at end of file 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) -}}} - * - */ -@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/NoManifest.scala b/src/library/scala/reflect/NoManifest.scala deleted file mode 100644 index 191e46ae39..0000000000 --- a/src/library/scala/reflect/NoManifest.scala +++ /dev/null @@ -1,15 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -/** One of the branches of an [[scala.reflect.OptManifest]]. - */ -object NoManifest extends OptManifest[Nothing] with Serializable { - override def toString = "" -} diff --git a/src/library/scala/reflect/OptManifest.scala b/src/library/scala/reflect/OptManifest.scala deleted file mode 100644 index 2a955deb2c..0000000000 --- a/src/library/scala/reflect/OptManifest.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]]. - * - * It is either a `Manifest` or the value `NoManifest`. - * - * @author Martin Odersky - */ -trait OptManifest[+T] extends Serializable 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..991feb3bac --- /dev/null +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -0,0 +1,154 @@ +package scala.reflect + +import api.Universe +import makro.Context + +// 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 should not be used in client code. */ +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, requireGroundTypeTag = false) + } + + def materializeGroundTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.GroundTypeTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeTypeTag(tpe, requireGroundTypeTag = 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 GroundTypeTagClass = selectType(TypeTagsClass, "GroundTypeTag") + val GroundTypeTagModule = selectTerm(TypeTagsClass, "GroundTypeTag") + + 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, TypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + 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, requireGroundTypeTag: Boolean): Tree = { + def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix + materializeTypeTag(prefix, tpe, requireGroundTypeTag) + } + + def materializeTypeTag(prefix: Tree, tpe: Type, requireGroundTypeTag: Boolean): Tree = { + val tagModule = if (requireGroundTypeTag) GroundTypeTagModule 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, requireGroundTypeTag = requireGroundTypeTag) + 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)) + } + } +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Attachments.scala b/src/library/scala/reflect/api/Attachments.scala new file mode 100644 index 0000000000..dfd362ebe0 --- /dev/null +++ b/src/library/scala/reflect/api/Attachments.scala @@ -0,0 +1,16 @@ +package scala.reflect +package api + +/** Attachment is a generalisation of Position. + * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads. + * + * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree + * imposing an unnecessary memory tax because of something that will not be used in most cases. + */ +trait Attachment { + /** Gets the underlying position */ + def pos: Position + + /** Creates a copy of this attachment with its position updated */ + def withPos(pos: Position): 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..8c3f12783b --- /dev/null +++ b/src/library/scala/reflect/api/Exprs.scala @@ -0,0 +1,48 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package api + +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 + implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree)(TypeTag.Nothing) + 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 +} + 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/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 _ => "" + } + } + 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..b4fedbe055 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 GroundTypeTagClass: Symbol + def GroundTypeTagModule: 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..bfc165f613 100644 --- a/src/library/scala/reflect/api/StandardNames.scala +++ b/src/library/scala/reflect/api/StandardNames.scala @@ -8,14 +8,166 @@ 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 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 + val UNARY_TILDE: TermName + val UNARY_PLUS: TermName + val UNARY_MINUS: TermName + val UNARY_NOT: TermName + + // [Eugene] this doesn't compile. why?! +// val ???: TermName + val QQQ: 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..a154e5f7a0 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,28 @@ 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 isOverloaded: Boolean + def isSkolem : Boolean + + /** Does this symbol represent a free type captured by reification? + */ + // needed for ones who wish to inspect reified trees + def isFreeType : Boolean + + /** 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 +244,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 +259,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..01f948809c 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,14 @@ 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 - } - - def setAnnotation(annot: TreeAnnotation): this.type = { annotation = annot; this } + private[this] var rawatt: Attachment = NoPosition + def attachment: Attachment = rawatt + def attachment_=(att: Attachment): Unit = rawatt = att + def setAttachment(att: Attachment): this.type = { rawatt = att; this } private[this] var rawtpe: Type = _ @@ -143,6 +140,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 +177,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 +193,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 +238,7 @@ trait Trees { self: Universe => duplicateTree(this).asInstanceOf[this.type] private[scala] def copyAttrs(tree: Tree): this.type = { - annotation = tree.annotation + attachment = tree.attachment tpe = tree.tpe if (hasSymbol) symbol = tree.symbol this @@ -241,6 +249,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. */ @@ -319,12 +355,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 +390,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 +438,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 +484,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 +515,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 +567,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 +585,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).(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 +626,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 +646,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 +656,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 . */ 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 */ 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 +967,8 @@ trait Trees { self: Universe => traverse(qualifier) case Ident(_) => ; + case ReferenceToBoxed(idt) => + traverse(idt) case Literal(_) => ; case TypeTree() => @@ -958,6 +1054,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 +1137,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 +1327,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 +1476,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() => @@ -1443,6 +1549,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 +1649,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 +1658,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..a38c21a9d4 --- /dev/null +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -0,0 +1,193 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package api + +import scala.reflect.{ mirror => rm } + +/** + * 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.ClassTag]], [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#GroundTypeTag]]. + * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method. + * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field. + * A [[scala.reflect.api.Universe#GroundTypeTag]] value is a type tag that is guaranteed not to contain any references to type parameters or abstract types. + * + * 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.GroundTypeTag, + * 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 isGround = !isNotGround + def isNotGround = tpe exists (_.typeSymbol.isAbstractType) + + def toGround: GroundTypeTag[T] = { + assert(isGround, tpe) + GroundTypeTag[T](tpe) + } + + override def toString = { + var prefix = if (isGround) "GroundTypeTag" else "TypeTag" + if (prefix != this.productPrefix) prefix = "*" + prefix + prefix + "[" + tpe + "]" + } + } + + object TypeTag { + val Byte : TypeTag[scala.Byte] = GroundTypeTag.Byte + val Short : TypeTag[scala.Short] = GroundTypeTag.Short + val Char : TypeTag[scala.Char] = GroundTypeTag.Char + val Int : TypeTag[scala.Int] = GroundTypeTag.Int + val Long : TypeTag[scala.Long] = GroundTypeTag.Long + val Float : TypeTag[scala.Float] = GroundTypeTag.Float + val Double : TypeTag[scala.Double] = GroundTypeTag.Double + val Boolean : TypeTag[scala.Boolean] = GroundTypeTag.Boolean + val Unit : TypeTag[scala.Unit] = GroundTypeTag.Unit + val Any : TypeTag[scala.Any] = GroundTypeTag.Any + val Object : TypeTag[java.lang.Object] = GroundTypeTag.Object + val AnyVal : TypeTag[scala.AnyVal] = GroundTypeTag.AnyVal + val AnyRef : TypeTag[scala.AnyRef] = GroundTypeTag.AnyRef + val Nothing : TypeTag[scala.Nothing] = GroundTypeTag.Nothing + val Null : TypeTag[scala.Null] = GroundTypeTag.Null + val String : TypeTag[java.lang.String] = GroundTypeTag.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.GroundTypeTag[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 GroundTypeTag available for ${T}") + class GroundTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { + assert(isGround, tpe) + override def productPrefix = "GroundTypeTag" + } + + object GroundTypeTag { + val Byte : GroundTypeTag[scala.Byte] = new GroundTypeTag[scala.Byte](ByteTpe) { private def readResolve() = GroundTypeTag.Byte } + val Short : GroundTypeTag[scala.Short] = new GroundTypeTag[scala.Short](ShortTpe) { private def readResolve() = GroundTypeTag.Short } + val Char : GroundTypeTag[scala.Char] = new GroundTypeTag[scala.Char](CharTpe) { private def readResolve() = GroundTypeTag.Char } + val Int : GroundTypeTag[scala.Int] = new GroundTypeTag[scala.Int](IntTpe) { private def readResolve() = GroundTypeTag.Int } + val Long : GroundTypeTag[scala.Long] = new GroundTypeTag[scala.Long](LongTpe) { private def readResolve() = GroundTypeTag.Long } + val Float : GroundTypeTag[scala.Float] = new GroundTypeTag[scala.Float](FloatTpe) { private def readResolve() = GroundTypeTag.Float } + val Double : GroundTypeTag[scala.Double] = new GroundTypeTag[scala.Double](DoubleTpe) { private def readResolve() = GroundTypeTag.Double } + val Boolean : GroundTypeTag[scala.Boolean] = new GroundTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = GroundTypeTag.Boolean } + val Unit : GroundTypeTag[scala.Unit] = new GroundTypeTag[scala.Unit](UnitTpe) { private def readResolve() = GroundTypeTag.Unit } + val Any : GroundTypeTag[scala.Any] = new GroundTypeTag[scala.Any](AnyTpe) { private def readResolve() = GroundTypeTag.Any } + val Object : GroundTypeTag[java.lang.Object] = new GroundTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = GroundTypeTag.Object } + val AnyVal : GroundTypeTag[scala.AnyVal] = new GroundTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = GroundTypeTag.AnyVal } + val AnyRef : GroundTypeTag[scala.AnyRef] = new GroundTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = GroundTypeTag.AnyRef } + val Nothing : GroundTypeTag[scala.Nothing] = new GroundTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = GroundTypeTag.Nothing } + val Null : GroundTypeTag[scala.Null] = new GroundTypeTag[scala.Null](NullTpe) { private def readResolve() = GroundTypeTag.Null } + val String : GroundTypeTag[java.lang.String] = new GroundTypeTag[java.lang.String](StringTpe) { private def readResolve() = GroundTypeTag.String } + + def apply[T](tpe: Type): GroundTypeTag[T] = + tpe match { + case ByteTpe => GroundTypeTag.Byte.asInstanceOf[GroundTypeTag[T]] + case ShortTpe => GroundTypeTag.Short.asInstanceOf[GroundTypeTag[T]] + case CharTpe => GroundTypeTag.Char.asInstanceOf[GroundTypeTag[T]] + case IntTpe => GroundTypeTag.Int.asInstanceOf[GroundTypeTag[T]] + case LongTpe => GroundTypeTag.Long.asInstanceOf[GroundTypeTag[T]] + case FloatTpe => GroundTypeTag.Float.asInstanceOf[GroundTypeTag[T]] + case DoubleTpe => GroundTypeTag.Double.asInstanceOf[GroundTypeTag[T]] + case BooleanTpe => GroundTypeTag.Boolean.asInstanceOf[GroundTypeTag[T]] + case UnitTpe => GroundTypeTag.Unit.asInstanceOf[GroundTypeTag[T]] + case AnyTpe => GroundTypeTag.Any.asInstanceOf[GroundTypeTag[T]] + case ObjectTpe => GroundTypeTag.Object.asInstanceOf[GroundTypeTag[T]] + case AnyValTpe => GroundTypeTag.AnyVal.asInstanceOf[GroundTypeTag[T]] + case AnyRefTpe => GroundTypeTag.AnyRef.asInstanceOf[GroundTypeTag[T]] + case NothingTpe => GroundTypeTag.Nothing.asInstanceOf[GroundTypeTag[T]] + case NullTpe => GroundTypeTag.Null.asInstanceOf[GroundTypeTag[T]] + case StringTpe => GroundTypeTag.String.asInstanceOf[GroundTypeTag[T]] + case _ => new GroundTypeTag[T](tpe) {} + } + + def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isGround) Some(ttag.tpe) else None + + implicit def toClassTag[T](ttag: rm.GroundTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) + + implicit def toDeprecatedManifestApis[T](ttag: rm.GroundTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) + + // this class should not be used directly in client code + class DeprecatedManifestApis[T](ttag: rm.GroundTypeTag[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.GroundTypeTag(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 groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag +// def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag +} \ No newline at end of file diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 0371e2c5df..12aad453b1 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -105,7 +105,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 +147,33 @@ trait Types { self: Universe => * .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 +452,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..60abd267cb 100755 --- a/src/library/scala/reflect/api/Universe.scala +++ b/src/library/scala/reflect/api/Universe.scala @@ -2,18 +2,87 @@ package scala.reflect package api 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 = + * $mr.Expr[Int]($mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", , 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", , 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..e8b847600c --- /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 groundTag[T](implicit gttag: GroundTypeTag[T]) = gttag + def groundTypeTag[T](implicit gttag: GroundTypeTag[T]) = gttag +} 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..96a41377b3 --- /dev/null +++ b/src/library/scala/reflect/makro/Context.scala @@ -0,0 +1,59 @@ +package scala.reflect.makro + +// 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..9bd25cf0f8 --- /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, requireGroundTypeTag: 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/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 should not be used in client code. */ +class macroImpl(val referenceToMacroImpl: Any) extends StaticAnnotation diff --git a/src/library/scala/reflect/makro/internal/typeTagImpl.scala b/src/library/scala/reflect/makro/internal/typeTagImpl.scala new file mode 100644 index 0000000000..6c49ef45de --- /dev/null +++ b/src/library/scala/reflect/makro/internal/typeTagImpl.scala @@ -0,0 +1,133 @@ +package scala.reflect.makro + +import scala.reflect.api.Universe + +/** This package is required by the compiler and should not be used in client code. */ +package object internal { + /** This method is required by the compiler and should not be used in client code. */ + def materializeClassTag[T](u: Universe): ClassTag[T] = macro materializeClassTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + 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 should not be used in client code. */ + def materializeTypeTag[T](u: Universe): u.TypeTag[T] = macro materializeTypeTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + 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, requireGroundTypeTag = false))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + def materializeGroundTypeTag[T](u: Universe): u.GroundTypeTag[T] = macro materializeGroundTypeTag_impl[T] + + /** This method is required by the compiler and should not be used in client code. */ + def materializeGroundTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.GroundTypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireGroundTypeTag = true))(c.TypeTag.Nothing) + + /** This method is required by the compiler and should not be used in client code. */ + 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, TypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == GroundTypeTagModule)) + 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, requireGroundTypeTag: Boolean): Tree = { + val tagModule = if (requireGroundTypeTag) GroundTypeTagModule 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, requireGroundTypeTag = requireGroundTypeTag) + 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/package.scala b/src/library/scala/reflect/package.scala index 1c3e618520..7a8267e689 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.GroundTypeTag` instead", "2.10.0") + type Manifest[T] = GroundTypeTag[T] + + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") + val ClassManifest = ClassTag + @deprecated("Use `@scala.reflect.GroundTypeTag` instead", "2.10.0") + lazy val Manifest = GroundTypeTag + @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 GroundTypeTag[T] = scala.reflect.mirror.GroundTypeTag[T] + + // ClassTag object is defined separately from the mirror + lazy val TypeTag = scala.reflect.mirror.TypeTag + lazy val GroundTypeTag = scala.reflect.mirror.GroundTypeTag } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 8bc63ae3a0..d06eba8f7d 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 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/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/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/jvm/interpreter.check b/test/files/jvm/interpreter.check index 243c9aa3be..d93e314d8e 100755 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -1,372 +1,372 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> - -scala> // basics - -scala> 3+4 -res0: Int = 7 - -scala> def gcd(x: Int, y: Int): Int = { - if (x == 0) y - else if (y == 0) x - else gcd(y%x, x) -} -gcd: (x: Int, y: Int)Int - -scala> val five = gcd(15,35) -five: Int = 5 - -scala> var x = 1 -x: Int = 1 - -scala> x = 2 -x: Int = 2 - -scala> val three = x+1 -three: Int = 3 - -scala> type anotherint = Int -defined type alias anotherint - -scala> val four: anotherint = 4 -four: anotherint = 4 - -scala> val bogus: anotherint = "hello" -:8: error: type mismatch; - found : String("hello") - required: anotherint - (which expands to) Int - val bogus: anotherint = "hello" - ^ - -scala> trait PointlessTrait -defined trait PointlessTrait - -scala> val (x,y) = (2,3) -x: Int = 2 -y: Int = 3 - -scala> println("hello") -hello - -scala> - -scala> // ticket #1513 - -scala> val t1513 = Array(null) -t1513: Array[Null] = Array(null) - -scala> // ambiguous toString problem from #547 - -scala> val atom = new scala.xml.Atom() -atom: scala.xml.Atom[Unit] = () - -scala> // overriding toString problem from #1404 - -scala> class S(override val toString : String) -defined class S - -scala> val fish = new S("fish") -fish: S = fish - -scala> // Test that arrays pretty print nicely. - -scala> val arr = Array("What's", "up", "doc?") -arr: Array[String] = Array(What's, up, doc?) - -scala> // Test that arrays pretty print nicely, even when we give them type Any - -scala> val arrInt : Any = Array(1,2,3) -arrInt: Any = Array(1, 2, 3) - -scala> // Test that nested arrays are pretty-printed correctly - -scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) -arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) - -scala> - -scala> // implicit conversions - -scala> case class Foo(n: Int) -defined class Foo - -scala> case class Bar(n: Int) -defined class Bar - -scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) -foo2bar: (foo: Foo)Bar - -scala> val bar: Bar = Foo(3) -bar: Bar = Bar(3) - -scala> - -scala> // importing from a previous result - -scala> import bar._ -import bar._ - -scala> val m = n -m: Int = 3 - -scala> - -scala> // stressing the imports mechanism - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> val one = 1 -one: Int = 1 - -scala> - -scala> - -scala> val x1 = 1 -x1: Int = 1 - -scala> val x2 = 1 -x2: Int = 1 - -scala> val x3 = 1 -x3: Int = 1 - -scala> val x4 = 1 -x4: Int = 1 - -scala> val x5 = 1 -x5: Int = 1 - -scala> val x6 = 1 -x6: Int = 1 - -scala> val x7 = 1 -x7: Int = 1 - -scala> val x8 = 1 -x8: Int = 1 - -scala> val x9 = 1 -x9: Int = 1 - -scala> val x10 = 1 -x10: Int = 1 - -scala> val x11 = 1 -x11: Int = 1 - -scala> val x12 = 1 -x12: Int = 1 - -scala> val x13 = 1 -x13: Int = 1 - -scala> val x14 = 1 -x14: Int = 1 - -scala> val x15 = 1 -x15: Int = 1 - -scala> val x16 = 1 -x16: Int = 1 - -scala> val x17 = 1 -x17: Int = 1 - -scala> val x18 = 1 -x18: Int = 1 - -scala> val x19 = 1 -x19: Int = 1 - -scala> val x20 = 1 -x20: Int = 1 - -scala> - -scala> val two = one + x5 -two: Int = 2 - -scala> - -scala> // handling generic wildcard arrays (#2386) - -scala> // It's put here because type feedback is an important part of it. - -scala> val xs: Array[_] = Array(1, 2) -xs: Array[_] = Array(1, 2) - -scala> xs.size -res2: Int = 2 - -scala> xs.head -res3: Any = 1 - -scala> xs filter (_ == 2) -res4: Array[_] = Array(2) - -scala> xs map (_ => "abc") -res5: Array[String] = Array(abc, abc) - -scala> xs map (x => x) -res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) - -scala> xs map (x => (x, x)) -res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) - -scala> - -scala> // interior syntax errors should *not* go into multi-line input mode. - -scala> // both of the following should abort immediately: - -scala> def x => y => z -:1: error: '=' expected but '=>' found. - def x => y => z - ^ - -scala> [1,2,3] -:1: error: illegal start of definition - [1,2,3] - ^ - -scala> - -scala> - -scala> // multi-line XML - -scala> - -res8: scala.xml.Elem = - - - -scala> - -scala> - -scala> /* - /* - multi-line comment - */ -*/ - -scala> - -scala> - -scala> // multi-line string - -scala> """ -hello -there -""" -res9: String = -" -hello -there -" - -scala> - -scala> (1 + // give up early by typing two blank lines - - -You typed two blank lines. Starting a new command. - -scala> // defining and using quoted names should work (ticket #323) - -scala> def `match` = 1 -match: Int - -scala> val x = `match` -x: Int = 1 - -scala> - -scala> // multiple classes defined on one line - -scala> sealed class Exp; class Fact extends Exp; class Term extends Exp -defined class Exp -defined class Fact -defined class Term - -scala> def f(e: Exp) = e match { // non-exhaustive warning here - case _:Fact => 3 -} -:18: warning: match is not exhaustive! -missing combination Exp -missing combination Term - - def f(e: Exp) = e match { // non-exhaustive warning here - ^ -f: (e: Exp)Int - -scala> - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> // basics + +scala> 3+4 +res0: Int = 7 + +scala> def gcd(x: Int, y: Int): Int = { + if (x == 0) y + else if (y == 0) x + else gcd(y%x, x) +} +gcd: (x: Int, y: Int)Int + +scala> val five = gcd(15,35) +five: Int = 5 + +scala> var x = 1 +x: Int = 1 + +scala> x = 2 +x: Int = 2 + +scala> val three = x+1 +three: Int = 3 + +scala> type anotherint = Int +defined type alias anotherint + +scala> val four: anotherint = 4 +four: anotherint = 4 + +scala> val bogus: anotherint = "hello" +:8: error: type mismatch; + found : String("hello") + required: anotherint + (which expands to) Int + val bogus: anotherint = "hello" + ^ + +scala> trait PointlessTrait +defined trait PointlessTrait + +scala> val (x,y) = (2,3) +x: Int = 2 +y: Int = 3 + +scala> println("hello") +hello + +scala> + +scala> // ticket #1513 + +scala> val t1513 = Array(null) +t1513: Array[Null] = Array(null) + +scala> // ambiguous toString problem from #547 + +scala> val atom = new scala.xml.Atom() +atom: scala.xml.Atom[Unit] = () + +scala> // overriding toString problem from #1404 + +scala> class S(override val toString : String) +defined class S + +scala> val fish = new S("fish") +fish: S = fish + +scala> // Test that arrays pretty print nicely. + +scala> val arr = Array("What's", "up", "doc?") +arr: Array[String] = Array(What's, up, doc?) + +scala> // Test that arrays pretty print nicely, even when we give them type Any + +scala> val arrInt : Any = Array(1,2,3) +arrInt: Any = Array(1, 2, 3) + +scala> // Test that nested arrays are pretty-printed correctly + +scala> val arrArrInt : Any = Array(Array(1, 2), Array(3, 4)) +arrArrInt: Any = Array(Array(1, 2), Array(3, 4)) + +scala> + +scala> // implicit conversions + +scala> case class Foo(n: Int) +defined class Foo + +scala> case class Bar(n: Int) +defined class Bar + +scala> implicit def foo2bar(foo: Foo) = Bar(foo.n) +foo2bar: (foo: Foo)Bar + +scala> val bar: Bar = Foo(3) +bar: Bar = Bar(3) + +scala> + +scala> // importing from a previous result + +scala> import bar._ +import bar._ + +scala> val m = n +m: Int = 3 + +scala> + +scala> // stressing the imports mechanism + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> val one = 1 +one: Int = 1 + +scala> + +scala> + +scala> val x1 = 1 +x1: Int = 1 + +scala> val x2 = 1 +x2: Int = 1 + +scala> val x3 = 1 +x3: Int = 1 + +scala> val x4 = 1 +x4: Int = 1 + +scala> val x5 = 1 +x5: Int = 1 + +scala> val x6 = 1 +x6: Int = 1 + +scala> val x7 = 1 +x7: Int = 1 + +scala> val x8 = 1 +x8: Int = 1 + +scala> val x9 = 1 +x9: Int = 1 + +scala> val x10 = 1 +x10: Int = 1 + +scala> val x11 = 1 +x11: Int = 1 + +scala> val x12 = 1 +x12: Int = 1 + +scala> val x13 = 1 +x13: Int = 1 + +scala> val x14 = 1 +x14: Int = 1 + +scala> val x15 = 1 +x15: Int = 1 + +scala> val x16 = 1 +x16: Int = 1 + +scala> val x17 = 1 +x17: Int = 1 + +scala> val x18 = 1 +x18: Int = 1 + +scala> val x19 = 1 +x19: Int = 1 + +scala> val x20 = 1 +x20: Int = 1 + +scala> + +scala> val two = one + x5 +two: Int = 2 + +scala> + +scala> // handling generic wildcard arrays (#2386) + +scala> // It's put here because type feedback is an important part of it. + +scala> val xs: Array[_] = Array(1, 2) +xs: Array[_] = Array(1, 2) + +scala> xs.size +res2: Int = 2 + +scala> xs.head +res3: Any = 1 + +scala> xs filter (_ == 2) +res4: Array[_] = Array(2) + +scala> xs map (_ => "abc") +res5: Array[String] = Array(abc, abc) + +scala> xs map (x => x) +res6: scala.collection.mutable.ArraySeq[_] = ArraySeq(1, 2) + +scala> xs map (x => (x, x)) +res7: Array[(_$1, _$1)] forSome { type _$1 } = Array((1,1), (2,2)) + +scala> + +scala> // interior syntax errors should *not* go into multi-line input mode. + +scala> // both of the following should abort immediately: + +scala> def x => y => z +:1: error: '=' expected but '=>' found. + def x => y => z + ^ + +scala> [1,2,3] +:1: error: illegal start of definition + [1,2,3] + ^ + +scala> + +scala> + +scala> // multi-line XML + +scala> + +res8: scala.xml.Elem = + + + +scala> + +scala> + +scala> /* + /* + multi-line comment + */ +*/ + +scala> + +scala> + +scala> // multi-line string + +scala> """ +hello +there +""" +res9: String = +" +hello +there +" + +scala> + +scala> (1 + // give up early by typing two blank lines + + +You typed two blank lines. Starting a new command. + +scala> // defining and using quoted names should work (ticket #323) + +scala> def `match` = 1 +match: Int + +scala> val x = `match` +x: Int = 1 + +scala> + +scala> // multiple classes defined on one line + +scala> sealed class Exp; class Fact extends Exp; class Term extends Exp +defined class Exp +defined class Fact +defined class Term + +scala> def f(e: Exp) = e match { // non-exhaustive warning here + case _:Fact => 3 +} +:18: warning: match is not exhaustive! +missing combination Exp +missing combination Term + + def f(e: Exp) = e match { // non-exhaustive warning here + ^ +f: (e: Exp)Int + +scala> + +scala> plusOne: (x: Int)Int res0: Int = 6 res0: String = after reset diff --git a/test/files/jvm/interpreter.scala b/test/files/jvm/interpreter.scala index f0bc8b5818..1f289d9335 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" def 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 deleted file mode 100644 index 54f504b929..0000000000 --- a/test/files/jvm/manifests.check +++ /dev/null @@ -1,55 +0,0 @@ -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)) - diff --git a/test/files/jvm/manifests.check.temporarily.disabled b/test/files/jvm/manifests.check.temporarily.disabled new file mode 100644 index 0000000000..54f504b929 --- /dev/null +++ b/test/files/jvm/manifests.check.temporarily.disabled @@ -0,0 +1,55 @@ +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)) + diff --git a/test/files/jvm/manifests.scala b/test/files/jvm/manifests.scala deleted file mode 100644 index 6bbea4d052..0000000000 --- a/test/files/jvm/manifests.scala +++ /dev/null @@ -1,119 +0,0 @@ -object Test extends App { - Test1 - Test2 - //Test3 // Java 1.5+ only -} - -class Foo[T](x: T) -trait Bar[T] { def f: T } - -object Test1 extends TestUtil { - print(()) - print(true) - print('a') - print(1) - print("abc") - print('abc) - println() - - print(List(())) - print(List(true)) - print(List(1)) - print(List("abc")) - print(List('abc)) - println() - - //print(Array(())) //Illegal class name "[V" in class file Test$ - print(Array(true)) - print(Array('a')) - print(Array(1)) - print(Array("abc")) - print(Array('abc)) - println() - - print(((), ())) - print((true, false)) - print((1, 2)) - print(("abc", "xyz")) - print(('abc, 'xyz)) - println() - - // Disabled: should these work? changing the inference for objects from - // "object Test" to "Test.type" drags in a singleton manifest which for - // some reason leads to serialization failure. - // print(Test) - // print(List) - println() - - print(new Foo(2)) - print(new Foo(List(2))) - print(new Foo(new Foo(2))) - print(new Foo(List(new Foo(2)))) - println() - - print(new Bar[String] { def f = "abc" }) - println() -} - -object Test2 { - import scala.util.Marshal._ - println("()="+load[Unit](dump(()))) - println("true="+load[Boolean](dump(true))) - println("a="+load[Char](dump('a'))) - println("1="+load[Int](dump(1))) - println("'abc="+load[Symbol](dump('abc))) - println() - - println("List(())="+load[List[Unit]](dump(List(())))) - println("List(true)="+load[List[Boolean]](dump(List(true)))) - println("List('abc)="+load[List[Symbol]](dump(List('abc)))) - println() - - def loadArray[T](x: Array[Byte])(implicit m: reflect.Manifest[Array[T]]) = - load[Array[T]](x)(m).deep.toString - println("Array()="+loadArray[Int](dump(Array(): Array[Int]))) - println("Array(true)="+loadArray[Boolean](dump(Array(true)))) - println("Array(a)="+loadArray[Char](dump(Array('a')))) - println("Array(1)="+loadArray[Int](dump(Array(1)))) - println() - - println("((),())="+load[(Unit, Unit)](dump(((), ())))) - println("(true,false)="+load[(Boolean, Boolean)](dump((true, false)))) - println() - - println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2))))) - println() - - println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2))))) - println() -} - -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] = { - val ba = new ByteArrayOutputStream(512) - val out = new ObjectOutputStream(ba) - out.writeObject(o) - out.close() - ba.toByteArray() - } - def read[A](buffer: Array[Byte]): A = { - val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) - in.readObject().asInstanceOf[A] - } - import scala.reflect._ - def print[T](x: T)(implicit m: Manifest[T]) { - val m1: Manifest[T] = read(write(m)) - val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") - println("x="+x1+", m="+m1) - } -} diff --git a/test/files/jvm/manifests.scala.temporarily.disabled b/test/files/jvm/manifests.scala.temporarily.disabled new file mode 100644 index 0000000000..241966fd9d --- /dev/null +++ b/test/files/jvm/manifests.scala.temporarily.disabled @@ -0,0 +1,109 @@ +object Test extends App { + Test1 + Test2 +} + +class Foo[T](x: T) +trait Bar[T] { def f: T } + +object Test1 extends TestUtil { + print(()) + print(true) + print('a') + print(1) + print("abc") + print('abc) + println() + + print(List(())) + print(List(true)) + print(List(1)) + print(List("abc")) + print(List('abc)) + println() + + //print(Array(())) //Illegal class name "[V" in class file Test$ + print(Array(true)) + print(Array('a')) + print(Array(1)) + print(Array("abc")) + print(Array('abc)) + println() + + print(((), ())) + print((true, false)) + print((1, 2)) + print(("abc", "xyz")) + print(('abc, 'xyz)) + println() + + // Disabled: should these work? changing the inference for objects from + // "object Test" to "Test.type" drags in a singleton manifest which for + // some reason leads to serialization failure. + // print(Test) + // print(List) + println() + + print(new Foo(2)) + print(new Foo(List(2))) + print(new Foo(new Foo(2))) + print(new Foo(List(new Foo(2)))) + println() + + print(new Bar[String] { def f = "abc" }) + println() +} + +object Test2 { + import scala.util.Marshal._ + println("()="+load[Unit](dump(()))) + println("true="+load[Boolean](dump(true))) + println("a="+load[Char](dump('a'))) + println("1="+load[Int](dump(1))) + println("'abc="+load[Symbol](dump('abc))) + println() + + println("List(())="+load[List[Unit]](dump(List(())))) + println("List(true)="+load[List[Boolean]](dump(List(true)))) + println("List('abc)="+load[List[Symbol]](dump(List('abc)))) + println() + + def loadArray[T](x: Array[Byte])(implicit m: reflect.Manifest[Array[T]]) = + load[Array[T]](x)(m).deep.toString + println("Array()="+loadArray[Int](dump(Array(): Array[Int]))) + println("Array(true)="+loadArray[Boolean](dump(Array(true)))) + println("Array(a)="+loadArray[Char](dump(Array('a')))) + println("Array(1)="+loadArray[Int](dump(Array(1)))) + println() + + println("((),())="+load[(Unit, Unit)](dump(((), ())))) + println("(true,false)="+load[(Boolean, Boolean)](dump((true, false)))) + println() + + println("List(List(1), List(2))="+load[List[List[Int]]](dump(List(List(1), List(2))))) + println() + + println("Array(Array(1), Array(2))="+loadArray[Array[Int]](dump(Array(Array(1), Array(2))))) + println() +} + +trait TestUtil { + import java.io._ + def write[A](o: A): Array[Byte] = { + val ba = new ByteArrayOutputStream(512) + val out = new ObjectOutputStream(ba) + out.writeObject(o) + out.close() + ba.toByteArray() + } + def read[A](buffer: Array[Byte]): A = { + val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) + in.readObject().asInstanceOf[A] + } + import scala.reflect._ + def print[T](x: T)(implicit m: Manifest[T]) { + val m1: Manifest[T] = read(write(m)) + val x1 = x.toString.replaceAll("@[0-9a-z]+$", "") + println("x="+x1+", m="+m1) + } +} 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 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 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/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/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-argtype-mismatch/Test_2.scala b/test/files/neg/macro-argtype-mismatch/Test_2.scala deleted file mode 100644 index 18feb69425..0000000000 --- a/test/files/neg/macro-argtype-mismatch/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo("2") -} \ 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..06a7b31f11 --- /dev/null +++ b/test/files/neg/macro-basic-mamdmi.flags @@ -0,0 +1 @@ +-Xmacros 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-cyclic.flags @@ -0,0 +1 @@ +-Xmacros \ 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-dont-touch-backquotedidents.check b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check new file mode 100644 index 0000000000..c97be5d9f6 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents.check @@ -0,0 +1,14 @@ +Macros_Package_10.scala:1: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro` + ^ +Macros_Package_10.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro`.bar + ^ +Macros_Package_11.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package `macro`.foo + ^ +Main.scala:2: error: Unmatched closing brace '}' ignored here +} +^ +three warnings found +one error found diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala new file mode 100644 index 0000000000..97c07b04a0 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(`macro`) = Some(42) + `macro` match { + case `macro` => println(`macro`) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala new file mode 100644 index 0000000000..f0037b5f82 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala new file mode 100644 index 0000000000..a6d0903cbb --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala new file mode 100644 index 0000000000..6af8e1d65e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def `macro` = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala new file mode 100644 index 0000000000..29dab017d2 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala new file mode 100644 index 0000000000..6cbcac55ca --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala new file mode 100644 index 0000000000..4985d6691e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package `macro` + +package `macro`.bar \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala new file mode 100644 index 0000000000..35ed610637 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package `macro`.foo diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala new file mode 100644 index 0000000000..7895cf9a43 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait `macro` diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala new file mode 100644 index 0000000000..90ba2207b7 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait `macro` +} diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala new file mode 100644 index 0000000000..7a2196c9cd --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type `macro` = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala new file mode 100644 index 0000000000..9ad08b8ba0 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val `macro` = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala new file mode 100644 index 0000000000..4fbe152e76 --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var `macro` = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala new file mode 100644 index 0000000000..f5278d9e7e --- /dev/null +++ b/test/files/neg/macro-deprecate-dont-touch-backquotedidents/Main.scala @@ -0,0 +1,2 @@ +object Test extends App +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents.check b/test/files/neg/macro-deprecate-idents.check new file mode 100644 index 0000000000..5fa1dc84d0 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents.check @@ -0,0 +1,50 @@ +Macros_Bind_12.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + val Some(macro) = Some(42) + ^ +Macros_Bind_12.scala:4: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + case macro => println(macro) + ^ +Macros_Class_4.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +class macro + ^ +Macros_Class_5.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + class macro + ^ +Macros_Def_13.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + def macro = 2 + ^ +Macros_Object_6.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +object macro + ^ +Macros_Object_7.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + object macro + ^ +Macros_Package_10.scala:1: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro + ^ +Macros_Package_10.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro.bar + ^ +Macros_Package_11.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +package macro.foo + ^ +Macros_Trait_8.scala:3: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. +trait macro + ^ +Macros_Trait_9.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + trait macro + ^ +Macros_Type_3.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + type macro = Int + ^ +Macros_Val_1.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + val macro = ??? + ^ +Macros_Var_2.scala:2: warning: in future versions of Scala "macro" will be a keyword. consider using a different name. + var macro = ??? + ^ +Main.scala:2: error: Unmatched closing brace '}' ignored here +} +^ +15 warnings found +one error found diff --git a/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala b/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala new file mode 100644 index 0000000000..a3b1553348 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala b/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala new file mode 100644 index 0000000000..8635d1f4f6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala b/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala new file mode 100644 index 0000000000..af24a489d0 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala b/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala new file mode 100644 index 0000000000..f4e25bfdfc --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala b/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala new file mode 100644 index 0000000000..66eb494e6b --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala b/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala new file mode 100644 index 0000000000..6f5b9ceacd --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala b/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala new file mode 100644 index 0000000000..52d3fbabf6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package macro + +package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala b/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala new file mode 100644 index 0000000000..a68ebd935f --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package macro.foo diff --git a/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala b/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala new file mode 100644 index 0000000000..e32d4c1385 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait macro diff --git a/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala b/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala new file mode 100644 index 0000000000..243a54abe6 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait macro +} diff --git a/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala b/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala new file mode 100644 index 0000000000..30e523bcaf --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type macro = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala b/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala new file mode 100644 index 0000000000..96f57acb30 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala b/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala new file mode 100644 index 0000000000..a79dda6dc2 --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-deprecate-idents/Main.scala b/test/files/neg/macro-deprecate-idents/Main.scala new file mode 100644 index 0000000000..f5278d9e7e --- /dev/null +++ b/test/files/neg/macro-deprecate-idents/Main.scala @@ -0,0 +1,2 @@ +object Test extends App +} \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-c.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-d.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-e.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-f.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-g.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidimpl-h.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidret-nontree.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidret-nonuniversetree.flags @@ -0,0 +1 @@ +-Xmacros \ 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 . + or : macro + 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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 . + or : macro + 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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 . + or : macro + 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-c.flags @@ -0,0 +1 @@ +-Xmacros \ 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..031aa653ab --- /dev/null +++ b/test/files/neg/macro-invalidshape-d.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:2: error: illegal start of statement + def foo(x: Any) = {2; macro Impls.foo} + ^ +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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidshape-d.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-context-bounds.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badargc.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-badvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-ctx-noctx.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-implicit-params.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc.flags @@ -0,0 +1 @@ +-Xmacros \ 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-invalidsig-params-badargc/Test_2.scala b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ 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-invalidsig-params-badtype/Test_2.scala b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala new file mode 100644 index 0000000000..cbd6232073 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-badvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ 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..cbd6232073 --- /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) +} \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-params-namemismatch.flags @@ -0,0 +1 @@ +-Xmacros \ 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..cbd6232073 --- /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) +} \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-badtype.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-bounds-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidsig-tparams-notparams-c.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badargs.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badbounds.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-invalidusage-methodvaluesyntax.flags @@ -0,0 +1 @@ +-Xmacros \ 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-keyword.check b/test/files/neg/macro-keyword.check new file mode 100644 index 0000000000..fd63db951c --- /dev/null +++ b/test/files/neg/macro-keyword.check @@ -0,0 +1,49 @@ +Macros_Bind_12.scala:2: error: illegal start of simple pattern + val Some(macro) = Some(42) + ^ +Macros_Bind_12.scala:6: error: ')' expected but '}' found. +} +^ +Macros_Class_4.scala:3: error: identifier expected but 'macro' found. +class macro + ^ +Macros_Class_5.scala:2: error: identifier expected but 'macro' found. + class macro + ^ +Macros_Def_13.scala:2: error: identifier expected but 'macro' found. + def macro = 2 + ^ +Macros_Object_6.scala:3: error: identifier expected but 'macro' found. +object macro + ^ +Macros_Object_7.scala:2: error: identifier expected but 'macro' found. + object macro + ^ +Macros_Package_10.scala:1: error: identifier expected but 'macro' found. +package macro + ^ +Macros_Package_11.scala:3: error: identifier expected but 'macro' found. +package macro.foo + ^ +Macros_Trait_8.scala:3: error: identifier expected but 'macro' found. +trait macro + ^ +Macros_Trait_9.scala:2: error: identifier expected but 'macro' found. + trait macro + ^ +Macros_Type_3.scala:2: error: identifier expected but 'macro' found. + type macro = Int + ^ +Macros_Val_1.scala:2: error: illegal start of simple pattern + val macro = ??? + ^ +Macros_Val_1.scala:3: error: '=' expected but '}' found. +} +^ +Macros_Var_2.scala:2: error: illegal start of simple pattern + var macro = ??? + ^ +Macros_Var_2.scala:3: error: '=' expected but '}' found. +} +^ +16 errors found diff --git a/test/files/neg/macro-keyword.flags b/test/files/neg/macro-keyword.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-keyword.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Bind_12.scala b/test/files/neg/macro-keyword/Macros_Bind_12.scala new file mode 100644 index 0000000000..a3b1553348 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Bind_12.scala @@ -0,0 +1,6 @@ +object Test12 { + val Some(macro) = Some(42) + macro match { + case macro => println(macro) + } +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Class_4.scala b/test/files/neg/macro-keyword/Macros_Class_4.scala new file mode 100644 index 0000000000..8635d1f4f6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Class_4.scala @@ -0,0 +1,3 @@ +package test4 + +class macro diff --git a/test/files/neg/macro-keyword/Macros_Class_5.scala b/test/files/neg/macro-keyword/Macros_Class_5.scala new file mode 100644 index 0000000000..af24a489d0 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Class_5.scala @@ -0,0 +1,3 @@ +object Test5 { + class macro +} diff --git a/test/files/neg/macro-keyword/Macros_Def_13.scala b/test/files/neg/macro-keyword/Macros_Def_13.scala new file mode 100644 index 0000000000..f4e25bfdfc --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Def_13.scala @@ -0,0 +1,3 @@ +object Test13 { + def macro = 2 +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Object_6.scala b/test/files/neg/macro-keyword/Macros_Object_6.scala new file mode 100644 index 0000000000..66eb494e6b --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Object_6.scala @@ -0,0 +1,3 @@ +package test6 + +object macro diff --git a/test/files/neg/macro-keyword/Macros_Object_7.scala b/test/files/neg/macro-keyword/Macros_Object_7.scala new file mode 100644 index 0000000000..6f5b9ceacd --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Object_7.scala @@ -0,0 +1,3 @@ +object Test7 { + object macro +} diff --git a/test/files/neg/macro-keyword/Macros_Package_10.scala b/test/files/neg/macro-keyword/Macros_Package_10.scala new file mode 100644 index 0000000000..52d3fbabf6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Package_10.scala @@ -0,0 +1,3 @@ +package macro + +package macro.bar \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Package_11.scala b/test/files/neg/macro-keyword/Macros_Package_11.scala new file mode 100644 index 0000000000..a68ebd935f --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Package_11.scala @@ -0,0 +1,3 @@ +package foo + +package macro.foo diff --git a/test/files/neg/macro-keyword/Macros_Trait_8.scala b/test/files/neg/macro-keyword/Macros_Trait_8.scala new file mode 100644 index 0000000000..e32d4c1385 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Trait_8.scala @@ -0,0 +1,3 @@ +package test8 + +trait macro diff --git a/test/files/neg/macro-keyword/Macros_Trait_9.scala b/test/files/neg/macro-keyword/Macros_Trait_9.scala new file mode 100644 index 0000000000..243a54abe6 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Trait_9.scala @@ -0,0 +1,3 @@ +object Test9 { + trait macro +} diff --git a/test/files/neg/macro-keyword/Macros_Type_3.scala b/test/files/neg/macro-keyword/Macros_Type_3.scala new file mode 100644 index 0000000000..30e523bcaf --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Type_3.scala @@ -0,0 +1,3 @@ +object Test3 { + type macro = Int +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Val_1.scala b/test/files/neg/macro-keyword/Macros_Val_1.scala new file mode 100644 index 0000000000..96f57acb30 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Val_1.scala @@ -0,0 +1,3 @@ +object Test1 { + val macro = ??? +} \ No newline at end of file diff --git a/test/files/neg/macro-keyword/Macros_Var_2.scala b/test/files/neg/macro-keyword/Macros_Var_2.scala new file mode 100644 index 0000000000..a79dda6dc2 --- /dev/null +++ b/test/files/neg/macro-keyword/Macros_Var_2.scala @@ -0,0 +1,3 @@ +object Test2 { + var macro = ??? +} \ 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/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-noexpand/Test_2.scala b/test/files/neg/macro-noexpand/Test_2.scala deleted file mode 100644 index 0bed592883..0000000000 --- a/test/files/neg/macro-noexpand/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(x) -} \ 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/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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-nontypeablebody.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/neg/macro-override-method-overrides-macro.flags @@ -0,0 +1 @@ +-Xmacros \ 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..d9c390ba25 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-hktypeparams-notags.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for C[T] + println(implicitly[GroundTypeTag[C[T]]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[C[T]] + println(implicitly[GroundTypeTag[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..d5ee61b91d --- /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[GroundTypeTag[C[T]]]) + println(implicitly[GroundTypeTag[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..c678a2a313 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-typeparams-notags.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for T + println(implicitly[GroundTypeTag[T]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[T] + println(implicitly[GroundTypeTag[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..98bdf6d67f --- /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[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[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..c678a2a313 --- /dev/null +++ b/test/files/neg/macro-reify-groundtypetag-usetypetag.check @@ -0,0 +1,7 @@ +Test.scala:5: error: No GroundTypeTag available for T + println(implicitly[GroundTypeTag[T]]) + ^ +Test.scala:6: error: No GroundTypeTag available for List[T] + println(implicitly[GroundTypeTag[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..507d03a390 --- /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[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[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..a3ca081f04 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a.check @@ -0,0 +1,10 @@ +Macros_2.scala:5: error: not found: value macro + def foo(x: Int): Int = macro foo_impl + ^ +Macros_2.scala:7: error: not found: value macro + def bar(x: Int): Int = macro bar_impl + ^ +Macros_2.scala:11: error: not found: value macro + 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..2493c81c95 --- /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.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + 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/neg/macro-without-xmacros-a/Test_3.scala b/test/files/neg/macro-without-xmacros-a/Test_3.scala new file mode 100644 index 0000000000..e9a10e20c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-a/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/macro-without-xmacros-b.check b/test/files/neg/macro-without-xmacros-b.check new file mode 100644 index 0000000000..dce4a084c9 --- /dev/null +++ b/test/files/neg/macro-without-xmacros-b.check @@ -0,0 +1,10 @@ +Macros_2.scala:3: error: ';' expected but '.' found. + def foo(x: Int): Int = macro Impls.foo_impl + ^ +Macros_2.scala:5: error: ';' expected but '.' found. + def bar(x: Int): Int = macro Impls.bar_impl + ^ +Macros_2.scala:9: error: ';' expected but '.' found. + 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..2493c81c95 --- /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.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(1)))) + } + + def bar_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + import c.mirror._ + Apply(Select(x.tree, newTermName("$plus")), List(Literal(Constant(2)))) + } + + def quux_impl(c: Ctx)(x: c.Expr[Int]): c.mirror.Tree = { + 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/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_ann2a.scala b/test/files/neg/reify_ann2a.scala deleted file mode 100644 index 8de0984074..0000000000 --- a/test/files/neg/reify_ann2a.scala +++ /dev/null @@ -1,30 +0,0 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - // test 1: reify - val tree = scala.reflect.Code.lift{ - 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"))) { - @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")) - val s = 4: Int @ann(bar=List("9a")) @ann(bar=List("9b")) - r + s - } - } - }.tree - println(tree.toString) - - // test 2: import and typecheck - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - 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/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/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/t3507.check b/test/files/neg/t3507.check index 8e538e4a8b..6b6df6ba76 100644 --- a/test/files/neg/t3507.check +++ b/test/files/neg/t3507.check @@ -1,4 +1,4 @@ -t3507.scala:13: error: No Manifest available for _1.b.c.type. - mani/*[object _1.b.c]*/(c) // kaboom in manifestOfType / TreeGen.mkAttributedQualifier - ^ -one error found +t3507.scala:13: error: No GroundTypeTag 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/t3692.check b/test/files/neg/t3692.check index 96ddd2a461..ec67e76bb4 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.GroundTypeTag` 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.GroundTypeTag` 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/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/pos/implicits.scala b/test/files/pos/implicits.scala deleted file mode 100644 index 2c01dd0ba8..0000000000 --- a/test/files/pos/implicits.scala +++ /dev/null @@ -1,89 +0,0 @@ -// #1435 -object t1435 { - implicit def a(s:String):String = error("") - implicit def a(i:Int):String = error("") - implicit def b(i:Int):String = error("") -} - -class C1435 { - val v:String = { - import t1435.a - 2 - } -} - -// #1492 -class C1492 { - - class X - - def foo(x: X => X) {} - - foo ( implicit x => implicitly[X] ) - foo { implicit x => implicitly[X] } -} - -// #1579 -object Test1579 { - class Column - class Query[E](val value: E) - class Invoker(q: Any) { val foo = null } - - implicit def unwrap[C](q: Query[C]) = q.value - implicit def invoker(q: Query[Column]) = new Invoker(q) - - val q = new Query(new Column) - q.foo -} -// #1625 -object Test1625 { - - class Wrapped(x:Any) { - def unwrap() = x - } - - implicit def byName[A](x: =>A) = new Wrapped(x) - - implicit def byVal[A](x: A) = x - - def main(args: Array[String]) = { - -// val res:Wrapped = 7 // works - - val res = 7.unwrap() // doesn't work - - println("=> result: " + res) - } -} - -object Test2188 { - implicit def toJavaList[A: ClassManifest](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*) - - val x: java.util.List[String] = List("foo") -} - -object TestNumericWidening { - val y = 1 - val x: java.lang.Long = y -} - -// #2709 -package foo2709 { - class A - class B - - package object bar { - implicit def a2b(a: A): B = new B - } - - package bar { - object test { - new A: B - } - } -} - -// Problem with specs -object specsProblem { - println(implicitly[Manifest[Class[_]]]) -} diff --git a/test/files/pos/implicits.scala.temporarily.disabled b/test/files/pos/implicits.scala.temporarily.disabled new file mode 100644 index 0000000000..2c01dd0ba8 --- /dev/null +++ b/test/files/pos/implicits.scala.temporarily.disabled @@ -0,0 +1,89 @@ +// #1435 +object t1435 { + implicit def a(s:String):String = error("") + implicit def a(i:Int):String = error("") + implicit def b(i:Int):String = error("") +} + +class C1435 { + val v:String = { + import t1435.a + 2 + } +} + +// #1492 +class C1492 { + + class X + + def foo(x: X => X) {} + + foo ( implicit x => implicitly[X] ) + foo { implicit x => implicitly[X] } +} + +// #1579 +object Test1579 { + class Column + class Query[E](val value: E) + class Invoker(q: Any) { val foo = null } + + implicit def unwrap[C](q: Query[C]) = q.value + implicit def invoker(q: Query[Column]) = new Invoker(q) + + val q = new Query(new Column) + q.foo +} +// #1625 +object Test1625 { + + class Wrapped(x:Any) { + def unwrap() = x + } + + implicit def byName[A](x: =>A) = new Wrapped(x) + + implicit def byVal[A](x: A) = x + + def main(args: Array[String]) = { + +// val res:Wrapped = 7 // works + + val res = 7.unwrap() // doesn't work + + println("=> result: " + res) + } +} + +object Test2188 { + implicit def toJavaList[A: ClassManifest](t:collection.Seq[A]):java.util.List[A] = java.util.Arrays.asList(t.toArray:_*) + + val x: java.util.List[String] = List("foo") +} + +object TestNumericWidening { + val y = 1 + val x: java.lang.Long = y +} + +// #2709 +package foo2709 { + class A + class B + + package object bar { + implicit def a2b(a: A): B = new B + } + + package bar { + object test { + new A: B + } + } +} + +// Problem with specs +object specsProblem { + println(implicitly[Manifest[Class[_]]]) +} 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/macros.flags b/test/files/pos/macros.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/files/pos/macros.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ No newline at end of file diff --git a/test/files/pos/macros.scala b/test/files/pos/macros.scala deleted file mode 100644 index 303610d464..0000000000 --- a/test/files/pos/macros.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test { - - class C { - def macro foo[T](xs: List[T]): T = (T, xs) match { - case (t1: Type, t2: Tree) => t2 - } - } -} diff --git a/test/files/pos/manifest1.scala b/test/files/pos/manifest1.scala deleted file mode 100644 index 8901aa7437..0000000000 --- a/test/files/pos/manifest1.scala +++ /dev/null @@ -1,21 +0,0 @@ -import scala.reflect.Manifest - -object Test { - def foo[T](x: T)(implicit m: Manifest[T]) { - foo(List(x)) - } - foo(1) - foo("abc") - foo(List(1, 2, 3)) - val x: List[Int] with Ordered[List[Int]] = null - foo(x) - foo[x.type](x) - abstract class C { type T = String; val x: T } - val c = new C { val x = "abc" } - foo(c.x) - abstract class D { type T; implicit val m: Manifest[T]; val x: T } - val stringm = implicitly[Manifest[String]] - val d: D = new D { type T = String; val m = stringm; val x = "x" } - import d.m - foo(d.x) -} diff --git a/test/files/pos/manifest1.scala.temporarily.disabled b/test/files/pos/manifest1.scala.temporarily.disabled new file mode 100644 index 0000000000..8901aa7437 --- /dev/null +++ b/test/files/pos/manifest1.scala.temporarily.disabled @@ -0,0 +1,21 @@ +import scala.reflect.Manifest + +object Test { + def foo[T](x: T)(implicit m: Manifest[T]) { + foo(List(x)) + } + foo(1) + foo("abc") + foo(List(1, 2, 3)) + val x: List[Int] with Ordered[List[Int]] = null + foo(x) + foo[x.type](x) + abstract class C { type T = String; val x: T } + val c = new C { val x = "abc" } + foo(c.x) + abstract class D { type T; implicit val m: Manifest[T]; val x: T } + val stringm = implicitly[Manifest[String]] + val d: D = new D { type T = String; val m = stringm; val x = "x" } + import d.m + foo(d.x) +} diff --git a/test/files/pos/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/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/existentials3.check b/test/files/run/existentials3.check deleted file mode 100644 index 36a458dacc..0000000000 --- a/test/files/run/existentials3.check +++ /dev/null @@ -1,22 +0,0 @@ -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.Product with scala.Serializable -Object with Test$ToS -Object with Test$ToS -Object with Test$ToS -scala.Function0[Object with Test$ToS] -scala.Function0[Object with Test$ToS] -_ <: Object with _ <: Object with Object with Test$ToS -_ <: Object with _ <: Object with _ <: Object with Test$ToS -scala.collection.immutable.List[Object with scala.collection.Seq[Int]] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] -_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with Test$ToS with scala.Product with scala.Serializable -Object with Test$ToS -Object with Test$ToS -Object with Test$ToS -scala.Function0[Object with Test$ToS] -scala.Function0[Object with Test$ToS] -_ <: Object with _ <: Object with Object with Test$ToS -_ <: Object with _ <: Object with _ <: Object with Test$ToS -scala.collection.immutable.List[Object with scala.collection.Seq[Int]] -scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] diff --git a/test/files/run/existentials3.check.temporarily.disabled b/test/files/run/existentials3.check.temporarily.disabled new file mode 100644 index 0000000000..36a458dacc --- /dev/null +++ b/test/files/run/existentials3.check.temporarily.disabled @@ -0,0 +1,22 @@ +_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with Test$ToS with scala.Product with scala.Serializable +Object with Test$ToS +Object with Test$ToS +Object with Test$ToS +scala.Function0[Object with Test$ToS] +scala.Function0[Object with Test$ToS] +_ <: Object with _ <: Object with Object with Test$ToS +_ <: Object with _ <: Object with _ <: Object with Test$ToS +scala.collection.immutable.List[Object with scala.collection.Seq[Int]] +scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] +_ <: scala.runtime.AbstractFunction0[_ <: Object with Test$ToS with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object +_ <: Object with Test$ToS with scala.Product with scala.Serializable +Object with Test$ToS +Object with Test$ToS +Object with Test$ToS +scala.Function0[Object with Test$ToS] +scala.Function0[Object with Test$ToS] +_ <: Object with _ <: Object with Object with Test$ToS +_ <: Object with _ <: Object with _ <: Object with Test$ToS +scala.collection.immutable.List[Object with scala.collection.Seq[Int]] +scala.collection.immutable.List[Object with scala.collection.Seq[_ <: Int]] diff --git a/test/files/run/existentials3.scala b/test/files/run/existentials3.scala deleted file mode 100644 index bb80d366cc..0000000000 --- a/test/files/run/existentials3.scala +++ /dev/null @@ -1,73 +0,0 @@ -object Test { - trait ToS { final override def toString = getClass.getName } - - def f1 = { case class Bar() extends ToS; Bar } - def f2 = { case class Bar() extends ToS; Bar() } - def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar } - def f4 = { class Bar() extends ToS; new Bar() } - def f5 = { object Bar extends ToS; Bar } - def f6 = { () => { object Bar extends ToS ; Bar } } - def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } - - def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } - def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } - - def f10 = { class A { type T1 } ; List[A#T1]() } - def f11 = { abstract class A extends Seq[Int] ; List[A]() } - def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } - - val g1 = { case class Bar() extends ToS; Bar } - val g2 = { case class Bar() extends ToS; Bar() } - val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar } - val g4 = { class Bar() extends ToS; new Bar() } - val g5 = { object Bar extends ToS; Bar } - val g6 = { () => { object Bar extends ToS ; Bar } } - val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } - - val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } - val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } - - val g10 = { class A { type T1 } ; List[A#T1]() } - val g11 = { abstract class A extends Seq[Int] ; List[A]() } - val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } - - def m[T: Manifest](x: T) = println(manifest[T]) - - // manifests don't work for f10/g10 - def main(args: Array[String]): Unit = { - m(f1) - m(f2) - m(f3) - m(f4) - m(f5) - m(f6) - m(f7) - m(f8) - m(f9) - // m(f10) - m(f11) - m(f12) - m(g1) - m(g2) - m(g3) - m(g4) - m(g5) - m(g6) - m(g7) - m(g8) - m(g9) - // m(g10) - m(g11) - m(g12) - } -} - -object Misc { - trait Bippy { def bippy = "I'm Bippy!" } - object o1 { - def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) } - def f2 = f1.head.bippy - } - def g1 = o1.f1 _ - def g2 = o1.f2 _ -} diff --git a/test/files/run/existentials3.scala.temporarily.disabled b/test/files/run/existentials3.scala.temporarily.disabled new file mode 100644 index 0000000000..bb80d366cc --- /dev/null +++ b/test/files/run/existentials3.scala.temporarily.disabled @@ -0,0 +1,73 @@ +object Test { + trait ToS { final override def toString = getClass.getName } + + def f1 = { case class Bar() extends ToS; Bar } + def f2 = { case class Bar() extends ToS; Bar() } + def f3 = { class Bar() extends ToS; object Bar extends ToS; Bar } + def f4 = { class Bar() extends ToS; new Bar() } + def f5 = { object Bar extends ToS; Bar } + def f6 = { () => { object Bar extends ToS ; Bar } } + def f7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } + + def f8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } + def f9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } + + def f10 = { class A { type T1 } ; List[A#T1]() } + def f11 = { abstract class A extends Seq[Int] ; List[A]() } + def f12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } + + val g1 = { case class Bar() extends ToS; Bar } + val g2 = { case class Bar() extends ToS; Bar() } + val g3 = { class Bar() extends ToS; object Bar extends ToS; Bar } + val g4 = { class Bar() extends ToS; new Bar() } + val g5 = { object Bar extends ToS; Bar } + val g6 = { () => { object Bar extends ToS ; Bar } } + val g7 = { val f = { () => { object Bar extends ToS ; Bar } } ; f } + + val g8 = { trait A ; trait B extends A ; class C extends B with ToS; new C { } } + val g9 = { trait A ; trait B ; class C extends B with A with ToS; new C { } } + + val g10 = { class A { type T1 } ; List[A#T1]() } + val g11 = { abstract class A extends Seq[Int] ; List[A]() } + val g12 = { abstract class A extends Seq[U forSome { type U <: Int }] ; List[A]() } + + def m[T: Manifest](x: T) = println(manifest[T]) + + // manifests don't work for f10/g10 + def main(args: Array[String]): Unit = { + m(f1) + m(f2) + m(f3) + m(f4) + m(f5) + m(f6) + m(f7) + m(f8) + m(f9) + // m(f10) + m(f11) + m(f12) + m(g1) + m(g2) + m(g3) + m(g4) + m(g5) + m(g6) + m(g7) + m(g8) + m(g9) + // m(g10) + m(g11) + m(g12) + } +} + +object Misc { + trait Bippy { def bippy = "I'm Bippy!" } + object o1 { + def f1 = { trait A extends Seq[U forSome { type U <: Bippy }] ; abstract class B extends A ; trait C extends B ; (null: C) } + def f2 = f1.head.bippy + } + def g1 = o1.f1 _ + def g2 = o1.f2 _ +} diff --git a/test/files/run/groundtypetags_core.check b/test/files/run/groundtypetags_core.check new file mode 100644 index 0000000000..d1b71f0926 --- /dev/null +++ b/test/files/run/groundtypetags_core.check @@ -0,0 +1,30 @@ +true +GroundTypeTag[Byte] +true +GroundTypeTag[Short] +true +GroundTypeTag[Char] +true +GroundTypeTag[Int] +true +GroundTypeTag[Long] +true +GroundTypeTag[Float] +true +GroundTypeTag[Double] +true +GroundTypeTag[Boolean] +true +GroundTypeTag[Unit] +true +GroundTypeTag[Any] +true +GroundTypeTag[Object] +true +GroundTypeTag[AnyVal] +true +GroundTypeTag[AnyRef] +true +GroundTypeTag[Null] +true +GroundTypeTag[Nothing] diff --git a/test/files/run/groundtypetags_core.scala b/test/files/run/groundtypetags_core.scala new file mode 100644 index 0000000000..d779e3fc7e --- /dev/null +++ b/test/files/run/groundtypetags_core.scala @@ -0,0 +1,32 @@ +object Test extends App { + println(implicitly[GroundTypeTag[Byte]] eq GroundTypeTag.Byte) + println(implicitly[GroundTypeTag[Byte]]) + println(implicitly[GroundTypeTag[Short]] eq GroundTypeTag.Short) + println(implicitly[GroundTypeTag[Short]]) + println(implicitly[GroundTypeTag[Char]] eq GroundTypeTag.Char) + println(implicitly[GroundTypeTag[Char]]) + println(implicitly[GroundTypeTag[Int]] eq GroundTypeTag.Int) + println(implicitly[GroundTypeTag[Int]]) + println(implicitly[GroundTypeTag[Long]] eq GroundTypeTag.Long) + println(implicitly[GroundTypeTag[Long]]) + println(implicitly[GroundTypeTag[Float]] eq GroundTypeTag.Float) + println(implicitly[GroundTypeTag[Float]]) + println(implicitly[GroundTypeTag[Double]] eq GroundTypeTag.Double) + println(implicitly[GroundTypeTag[Double]]) + println(implicitly[GroundTypeTag[Boolean]] eq GroundTypeTag.Boolean) + println(implicitly[GroundTypeTag[Boolean]]) + println(implicitly[GroundTypeTag[Unit]] eq GroundTypeTag.Unit) + println(implicitly[GroundTypeTag[Unit]]) + println(implicitly[GroundTypeTag[Any]] eq GroundTypeTag.Any) + println(implicitly[GroundTypeTag[Any]]) + println(implicitly[GroundTypeTag[Object]] eq GroundTypeTag.Object) + println(implicitly[GroundTypeTag[Object]]) + println(implicitly[GroundTypeTag[AnyVal]] eq GroundTypeTag.AnyVal) + println(implicitly[GroundTypeTag[AnyVal]]) + println(implicitly[GroundTypeTag[AnyRef]] eq GroundTypeTag.AnyRef) + println(implicitly[GroundTypeTag[AnyRef]]) + println(implicitly[GroundTypeTag[Null]] eq GroundTypeTag.Null) + println(implicitly[GroundTypeTag[Null]]) + println(implicitly[GroundTypeTag[Nothing]] eq GroundTypeTag.Nothing) + println(implicitly[GroundTypeTag[Nothing]]) +} \ No newline at end of file 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-abort-fresh.flags @@ -0,0 +1 @@ +-Xmacros \ 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..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-ma-md-mi.flags @@ -0,0 +1 @@ +-Xmacros 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..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-ma-mdmi.flags @@ -0,0 +1 @@ +-Xmacros 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..06a7b31f11 --- /dev/null +++ b/test/files/run/macro-basic-mamd-mi.flags @@ -0,0 +1 @@ +-Xmacros 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-basic/Test_2.scala b/test/files/run/macro-basic/Test_2.scala deleted file mode 100644 index e9a10e20c9..0000000000 --- a/test/files/run/macro-basic/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -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-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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-bodyexpandstoimpl.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-annotation.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-anonymous.flags @@ -0,0 +1 @@ +-Xmacros \ 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]() +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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-block.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class-class.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class-object.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-class.flags @@ -0,0 +1 @@ +-Xmacros \ 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]() +it works +it works +prefix = Expr[Nothing]() +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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-default-param.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-implicit-class.flags @@ -0,0 +1 @@ +-Xmacros \ 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]() +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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-method.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object-class.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object-object.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-object.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-package-object.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-refinement.flags @@ -0,0 +1 @@ +-Xmacros \ 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 (): anonymous class $anon = { + $anon.super.(); + () + }; + + }; + 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-declared-in-trait.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type-c.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-c.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-def-path-dependent-d.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-has-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-val.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-implicit-macro-is-view.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-multiple-arglists.flags @@ -0,0 +1 @@ +-Xmacros \ 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..34a453cd3a --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic.check @@ -0,0 +1,6 @@ +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[Int] +it works GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-nullary-generic.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-nullary-nongeneric.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-overload.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-override.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-recursive.flags @@ -0,0 +1 @@ +-Xmacros \ 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/files/run/macro-expand-tparams-bounds-a.check b/test/files/run/macro-expand-tparams-bounds-a.check new file mode 100644 index 0000000000..e69de29bb2 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..54da026aa8 --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit.check @@ -0,0 +1 @@ +GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-explicit.flags @@ -0,0 +1 @@ +-Xmacros \ 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..60c021a35b --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-implicit.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-only-in-impl.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-optional.flags @@ -0,0 +1 @@ +-Xmacros \ 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..1447c2478f --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a.check @@ -0,0 +1,4 @@ +GroundTypeTag[Int] +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..c7ec594b92 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b.check @@ -0,0 +1,2 @@ +GroundTypeTag[Boolean] GroundTypeTag[Int] +GroundTypeTag[Boolean] GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..fac58e9516 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1.check @@ -0,0 +1,3 @@ +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c1.flags @@ -0,0 +1 @@ +-Xmacros \ 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..fac58e9516 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2.check @@ -0,0 +1,3 @@ +GroundTypeTag[Int] +GroundTypeTag[String] +GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-c2.flags @@ -0,0 +1 @@ +-Xmacros \ 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..f78ddea4f3 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1.check @@ -0,0 +1,3 @@ +TypeTag[T] +TypeTag[U] +GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix-d1.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-good.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-explicit-over-varargs.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-nonvarargs.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-expand-varargs-implicit-over-varargs.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-impl-default-params.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-impl-rename-context.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.flags @@ -0,0 +1 @@ +-Xmacros \ 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 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-doesnt-conform-to-impl-rettype.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidret-nontypeable.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidusage-badret.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-invalidusage-partialapplication.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-openmacros.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-quasiinvalidbody-c.flags @@ -0,0 +1 @@ +-Xmacros \ 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/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("") + // 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("") - // 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("") - // 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reflective-ma-normal-mdmi.flags @@ -0,0 +1 @@ +-Xmacros \ 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.flags b/test/files/run/macro-reflective-mamd-normal-mi.flags new file mode 100644 index 0000000000..e69de29bb2 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..7cbe425fc8 --- /dev/null +++ b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala @@ -0,0 +1,16 @@ +//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) + println(tree.eval) +} 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-basic.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-eval-eval.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-eval-outside-reify.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-freevars.flags @@ -0,0 +1 @@ +-Xmacros \ 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..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-notypeparams.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[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..3aa40251ec --- /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[GroundTypeTag[Int]]) + println(implicitly[GroundTypeTag[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..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-groundtypetag-typeparams-tags.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[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..21735c10d5 --- /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: GroundTypeTag] = { + println(implicitly[GroundTypeTag[T]]) + println(implicitly[GroundTypeTag[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 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-nested-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-nested-b.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-ref-to-packageless.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-tagful-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-tagless-a.flags @@ -0,0 +1 @@ +-Xmacros \ 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..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-notypeparams.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[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..3da30c71ba --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-notags.check @@ -0,0 +1,2 @@ +GroundTypeTag[T] +GroundTypeTag[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..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-typeparams-tags.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[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..24612cd4b7 --- /dev/null +++ b/test/files/run/macro-reify-typetag-usegroundtypetag.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[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..c9b210f35a --- /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: GroundTypeTag] = { + 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-unreify.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-reify-value-outside-reify.flags @@ -0,0 +1 @@ +-Xmacros \ 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..3bc899f49b 100644 --- a/test/files/run/macro-repl-basic.check +++ b/test/files/run/macro-repl-basic.check @@ -3,13 +3,39 @@ Type :help for more information. scala> +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 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 } defined module Macros defined class Macros @@ -20,6 +46,6 @@ scala> import Macros.Shmacros._ import Macros.Shmacros._ scala> println(foo(2) + Macros.bar(2) * new Macros().quux(4)) -10 +31 scala> diff --git a/test/files/run/macro-repl-basic.scala b/test/files/run/macro-repl-basic.scala index 9b1a53343b..a21eb7815f 100644 --- a/test/files/run/macro-repl-basic.scala +++ b/test/files/run/macro-repl-basic.scala @@ -3,13 +3,34 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { override def extraSettings = "-Xmacros" def code = """ + |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._ 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..9889a8ffdf 100644 --- a/test/files/run/macro-repl-dontexpand.scala +++ b/test/files/run/macro-repl-dontexpand.scala @@ -3,6 +3,7 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { override def extraSettings = "-Xmacros" 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/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..cdc7512197 --- /dev/null +++ b/test/files/run/macro-settings.flags @@ -0,0 +1 @@ +-Xmacros -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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-sip19-revised.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-sip19.flags @@ -0,0 +1 @@ +-Xmacros \ 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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-typecheck-implicitsdisabled.flags @@ -0,0 +1 @@ +-Xmacros \ 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..9760c117a7 --- /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.GroundTypeTag.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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-typecheck-macrosdisabled.flags @@ -0,0 +1 @@ +-Xmacros \ 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..6bf9bcca5a --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls.check @@ -0,0 +1,5 @@ +A = GroundTypeTag[Int] +B = GroundTypeTag[Nothing] +List(1) +A = GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-consfromsls.flags @@ -0,0 +1 @@ +-Xmacros \ 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..352a2e6480 --- /dev/null +++ b/test/files/run/macro-undetparams-implicitval.check @@ -0,0 +1 @@ +GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-implicitval.flags @@ -0,0 +1 @@ +-Xmacros \ 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..60c021a35b --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself.check @@ -0,0 +1,2 @@ +GroundTypeTag[Int] +GroundTypeTag[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..7fea2ff901 --- /dev/null +++ b/test/files/run/macro-undetparams-macroitself.flags @@ -0,0 +1 @@ +-Xmacros \ 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/primitive-sigs-2.check b/test/files/run/primitive-sigs-2.check index feb0619525..761aa1ca72 100644 --- a/test/files/run/primitive-sigs-2.check +++ b/test/files/run/primitive-sigs-2.check @@ -1,7 +1,7 @@ -T -List(A, char, class java.lang.Object) -a -public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.Manifest) -public float[] Arr.arr3(float[][]) -public scala.collection.immutable.List Arr.arr2(java.lang.Character[]) -public scala.collection.immutable.List Arr.arr1(int[]) +T +List(A, char, class java.lang.Object) +a +public java.lang.Object Arr.arr4(java.lang.Object[],scala.reflect.api.TypeTags.scala.reflect.api.TypeTags$GroundTypeTag) +public float[] Arr.arr3(float[][]) +public scala.collection.immutable.List Arr.arr2(java.lang.Character[]) +public scala.collection.immutable.List 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")) private[this] val x: T @ann(immutable.this.List.apply[String]("4a")) @ann(immutable.this.List.apply[String]("4b")) = _; - def (@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.(); - () - }; - @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")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; - def (@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.(); - () - }; - @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")) private[this] val x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b")) = _; + def (@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.(); + () + }; + @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")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; + def (@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.(); + () + }; + @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") private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _; - def (@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = { - super.(); - () - }; - @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") private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _; - def (@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = { - C.super.(); - () - }; - @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") private[this] val x: T @ann(bar = "4a") @ann(bar = "4b") = _; + def (@new ann(bar = "3a") @new ann(bar = "3b") x: T @ann(bar = "4a") @ann(bar = "4b")) = { + super.(); + () + }; + @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") private[this] val x: T @ann(bar = "4b") @ann(bar = "4a") = _; + def (@ann(bar = "3a") @ann(bar = "3b") x: T @ann(bar = "4b") @ann(bar = "4a")): C[T] = { + C.super.(); + () + }; + @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 { + private[this] val bar: List[String] = _; + def (bar: List[String]) = { + super.(); + () + } + }; + @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")) private[this] val x: T @ann(immutable.this.List.apply("4a")) @ann(immutable.this.List.apply("4b")) = _; + def (@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.(); + () + }; + @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 { + private[this] val bar: List[String] = _; + def (bar: List[String]): ann = { + ann.super.(); + () + } + }; + @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")) private[this] val x: T @ann(immutable.this.List.apply[String]("4b")) @ann(immutable.this.List.apply[String]("4a")) = _; + def (@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.(); + () + }; + @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_ann2a.scala b/test/files/run/reify_ann2a.scala new file mode 100644 index 0000000000..370abadba0 --- /dev/null +++ b/test/files/run/reify_ann2a.scala @@ -0,0 +1,25 @@ +import scala.reflect.mirror._ + +object Test extends App { + // test 1: reify + 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"))) { + @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")) + val s = 4: Int @ann(bar=List("9a")) @ann(bar=List("9b")) + r + s + } + } + }.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) +} \ No newline at end of file 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 val key: A = _; + def (key: A) = { + super.(); + () + } + }; + () +} +{ + class Tree[A, B] extends Object { + final private[this] val key: A = _; + @inline @scala.annotation.meta.getter final def key: A = Tree.this.key; + def (key: A): Tree[A,B] = { + Tree.super.(); + () + } + }; + () +} 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 () = { + super.(); + () + } + }; + class C extends Object { + def () = { + super.(); + () + } + }; + val c1 = new C @D(); + () +} +{ + class D extends scala.annotation.Annotation with scala.annotation.StaticAnnotation { + def (): D = { + D.super.(); + () + } + }; + class C extends Object { + def (): C = { + C.super.(); + () + } + }; + 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() val x: Int = _; + def (x: Int) = { + super.(); + () + } + }; + () +} +{ + class C extends Object { + @scala.beans.BeanProperty private[this] val x: Int = _; + def x: Int = C.this.x; + def (x: Int): C = { + C.super.(); + () + }; + @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 () = { - super.(); - () - } - }; - () -} -{ - @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends scala.AnyRef { - def (): C = { - C.super.(); - () - } - }; - () -} +{ + @new ann(bar = "1", quux = Array("2", "3"), baz = new ann(bar = "4")) class C extends Object { + def () = { + super.(); + () + } + }; + () +} +{ + @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4")) class C extends Object { + def (): C = { + C.super.(); + () + } + }; + () +} 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 () = { + super.(); + () + }; + def x: Int = 2: @ann(bar = "1",quux = Array("2", "3"),baz = new ann(bar = "4")) + }; + () +} +{ + class C extends Object { + def (): C = { + C.super.(); + () + }; + def x: Int = (2: Int(2) @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4"))) + }; + () +} diff --git a/test/files/run/reify_classfileann_b.scala b/test/files/run/reify_classfileann_b.scala new file mode 100644 index 0000000000..4e50494af3 --- /dev/null +++ b/test/files/run/reify_classfileann_b.scala @@ -0,0 +1,23 @@ +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 = reify{ + class C { + def x: Int = { + 2: @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) + } + } + }.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) +} \ 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.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.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) +} +:13: free term: Ident(newTermName("x")) defined by res0 in :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) +} +:11: free type: Ident(newTypeName("T")) defined by foo in :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) +} +: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..31ece627e1 --- /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) +} +:13: free term: Ident(newTermName("x")) defined by res0 in :12:21 + val tt = implicitly[TypeTag[x.type]] + ^ +GroundTypeTag[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..68b0ee8c99 --- /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) +} +:11: free type: Ident(newTypeName("T")) defined by foo in :10:16 + val tt = implicitly[TypeTag[List[T]]] + ^ +foo: [T]=> Unit + +scala> foo[Int] +GroundTypeTag[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-power.check b/test/files/run/repl-power.check index 1e7b6f0cd8..b811a4a8c5 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -1,32 +1,32 @@ -Type in expressions to have them evaluated. -Type :help for more information. - -scala> :power -** Power User mode enabled - BEEP WHIR GYVE ** -** :phase has been set to 'typer'. ** -** scala.tools.nsc._ has been imported ** -** global._, definitions._ also imported ** -** Try :help, :vals, power. ** - -scala> // guarding against "error: reference to global is ambiguous" - -scala> global.emptyValDef // "it is imported twice in the same scope by ..." -res0: $r.global.emptyValDef.type = private val _ = _ - -scala> val tp = ArrayClass[scala.util.Random] // magic with manifests -tp: $r.global.Type = Array[scala.util.Random] - -scala> tp.memberType(Array_apply) // evidence -res1: $r.global.Type = (i: Int)scala.util.Random - -scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl -m: $r.treedsl.global.Match = -10 match { - case 5 => false - case _ => true -} - -scala> typed(m).tpe // typed is in scope -res2: $r.treedsl.global.Type = Boolean - -scala> +Type in expressions to have them evaluated. +Type :help for more information. + +scala> :power +** Power User mode enabled - BEEP WHIR GYVE ** +** :phase has been set to 'typer'. ** +** scala.tools.nsc._ has been imported ** +** global._, definitions._ also imported ** +** Try :help, :vals, power. ** + +scala> // guarding against "error: reference to global is ambiguous" + +scala> global.emptyValDef // "it is imported twice in the same scope by ..." +res0: $r.global.emptyValDef.type = private val _ = _ + +scala> val tp = ArrayClass[scala.util.Random] // magic with manifests +tp: $r.global.Type = Array[scala.util.Random] + +scala> tp.memberType(Array_apply) // evidence +res1: $r.global.Type = (i: Int)scala.util.Random + +scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl +m: $r.treedsl.global.Match = +10 match { + case 5 => false + case _ => true +} + +scala> typed(m).tpe // typed is in scope +res2: $r.treedsl.global.Type = Boolean + +scala> diff --git a/test/files/run/t1195.check b/test/files/run/t1195.check deleted file mode 100644 index d023bc91f7..0000000000 --- a/test/files/run/t1195.check +++ /dev/null @@ -1,6 +0,0 @@ -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with scala.Product with scala.Serializable -Object with scala.Product with scala.Serializable -_ <: scala.runtime.AbstractFunction1[Int, _ <: Object with scala.Product with scala.Serializable] with scala.Serializable with java.lang.Object -_ <: Object with scala.Product with scala.Serializable -Object with scala.Product with scala.Serializable diff --git a/test/files/run/t1195.check.temporarily.disabled b/test/files/run/t1195.check.temporarily.disabled new file mode 100644 index 0000000000..d023bc91f7 --- /dev/null +++ b/test/files/run/t1195.check.temporarily.disabled @@ -0,0 +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 diff --git a/test/files/run/t1195.scala b/test/files/run/t1195.scala deleted file mode 100644 index 81ef5bdb0e..0000000000 --- a/test/files/run/t1195.scala +++ /dev/null @@ -1,26 +0,0 @@ -object Test { - def f() = { case class Bar(x: Int); Bar } - def g() = { case class Bar(x: Int); Bar(5) } - def h() = { case object Bar ; Bar } - - val f1 = f() - val g1 = g() - val h1 = h() - - def m[T: Manifest](x: T) = println(manifest[T]) - - def main(args: Array[String]): Unit = { - m(f) - m(g) - m(h) - m(f1) - m(g1) - m(h1) - } -} - -class A1[T] { - class B1[U] { - def f = { case class D(x: Int) extends A1[String] ; new D(5) } - } -} diff --git a/test/files/run/t1195.scala.temporarily.disabled b/test/files/run/t1195.scala.temporarily.disabled new file mode 100644 index 0000000000..81ef5bdb0e --- /dev/null +++ b/test/files/run/t1195.scala.temporarily.disabled @@ -0,0 +1,26 @@ +object Test { + def f() = { case class Bar(x: Int); Bar } + def g() = { case class Bar(x: Int); Bar(5) } + def h() = { case object Bar ; Bar } + + val f1 = f() + val g1 = g() + val h1 = h() + + def m[T: Manifest](x: T) = println(manifest[T]) + + def main(args: Array[String]): Unit = { + m(f) + m(g) + m(h) + m(f1) + m(g1) + m(h1) + } +} + +class A1[T] { + class B1[U] { + def f = { case class D(x: Int) extends A1[String] ; new D(5) } + } +} diff --git a/test/files/run/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/t4110.check b/test/files/run/t4110.check deleted file mode 100644 index 8b005989de..0000000000 --- a/test/files/run/t4110.check +++ /dev/null @@ -1,2 +0,0 @@ -Object with Test$A with Test$B -Object with Test$A with Test$B diff --git a/test/files/run/t4110.check.temporarily.disabled b/test/files/run/t4110.check.temporarily.disabled new file mode 100644 index 0000000000..8b005989de --- /dev/null +++ b/test/files/run/t4110.check.temporarily.disabled @@ -0,0 +1,2 @@ +Object with Test$A with Test$B +Object with Test$A with Test$B diff --git a/test/files/run/t4110.scala b/test/files/run/t4110.scala deleted file mode 100644 index 4bd377b73e..0000000000 --- a/test/files/run/t4110.scala +++ /dev/null @@ -1,11 +0,0 @@ -object Test extends App { - def inferredType[T : Manifest](v : T) = println(manifest[T]) - - trait A - trait B - - inferredType(new A with B) - - val name = new A with B - inferredType(name) -} \ No newline at end of file diff --git a/test/files/run/t4110.scala.temporarily.disabled b/test/files/run/t4110.scala.temporarily.disabled new file mode 100644 index 0000000000..4bd377b73e --- /dev/null +++ b/test/files/run/t4110.scala.temporarily.disabled @@ -0,0 +1,11 @@ +object Test extends App { + def inferredType[T : Manifest](v : T) = println(manifest[T]) + + trait A + trait B + + inferredType(new A with B) + + val name = new A with B + inferredType(name) +} \ No newline at end of file diff --git a/test/files/run/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 () = { - super.(); - () - } - }; - () -} +{ + @new Foo(bar = "qwe") class C extends Object { + def () = { + super.(); + () + } + }; + () +} 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.check b/test/files/run/t5258a.check deleted file mode 100644 index 4e0b2da04c..0000000000 --- a/test/files/run/t5258a.check +++ /dev/null @@ -1 +0,0 @@ -int \ No newline at end of file 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 { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - () -} +{ + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + () +} 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 { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - val c = C.apply(2, 2); - scala.this.Predef.println(c.foo.$times(c.bar)) -} +{ + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + 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 () = { - super.(); - () - }; - def qwe: Int = 4 - }; - case class C extends Object with Product with Serializable { - val foo : Int = _; - val bar : Int = _; - def (foo: Int, bar: Int) = { - super.(); - () - } - }; - val c = C.apply(2, 2); - scala.this.Predef.println(c.foo.$times(c.bar).$eq$eq(C.qwe)) -} +{ + object C extends Object { + def () = { + super.(); + () + }; + def qwe = 4 + }; + case class C extends Product with Serializable { + val foo: Int = _; + val bar: Int = _; + def (foo: Int, bar: Int) = { + super.(); + () + } + }; + 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.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.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.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/toolbox_console_reporter.check b/test/files/run/toolbox_console_reporter.check new file mode 100644 index 0000000000..e69de29bb2 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..fe2323ea06 --- /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.GroundTypeTag.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.check b/test/files/run/treePrint.check deleted file mode 100644 index 3360815ac1..0000000000 --- a/test/files/run/treePrint.check +++ /dev/null @@ -1,5 +0,0 @@ -def foo = { - var q: Boolean = false; - val x = 5; - ((x == 5) || (!q)) || (true) -} diff --git a/test/files/run/treePrint.check.temporarily.disabled b/test/files/run/treePrint.check.temporarily.disabled new file mode 100644 index 0000000000..3360815ac1 --- /dev/null +++ b/test/files/run/treePrint.check.temporarily.disabled @@ -0,0 +1,5 @@ +def foo = { + var q: Boolean = false; + val x = 5; + ((x == 5) || (!q)) || (true) +} diff --git a/test/files/run/treePrint.scala b/test/files/run/treePrint.scala deleted file mode 100644 index e0332a705f..0000000000 --- a/test/files/run/treePrint.scala +++ /dev/null @@ -1,42 +0,0 @@ -/** Testing compact tree printers. - */ -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 - val x = if (true) { - if (true) { - if (true) { - 5 - } - else if (true) { - 5 - } else { - 10 - } - } - else 20 - } - else 30 - - (x == 5) || !q || true - } - """ - - class NullOutputStream extends OutputStream { def write(b: Int) { } } - - def main(args: Array[String]) { - val settings = new Settings - settings.classpath.value = System.getProperty("java.class.path") - settings.Ycompacttrees.value = true - - val intp = new IMain(settings, new PrintWriter(new NullOutputStream)) - val power = new Power(intp, new ReplVals { }) - intp.interpret("""def initialize = "Have to interpret something or we get errors." """) - power trees code foreach println - } -} diff --git a/test/files/run/treePrint.scala.temporarily.disabled b/test/files/run/treePrint.scala.temporarily.disabled new file mode 100644 index 0000000000..e0332a705f --- /dev/null +++ b/test/files/run/treePrint.scala.temporarily.disabled @@ -0,0 +1,42 @@ +/** Testing compact tree printers. + */ +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 + val x = if (true) { + if (true) { + if (true) { + 5 + } + else if (true) { + 5 + } else { + 10 + } + } + else 20 + } + else 30 + + (x == 5) || !q || true + } + """ + + class NullOutputStream extends OutputStream { def write(b: Int) { } } + + def main(args: Array[String]) { + val settings = new Settings + settings.classpath.value = System.getProperty("java.class.path") + settings.Ycompacttrees.value = true + + val intp = new IMain(settings, new PrintWriter(new NullOutputStream)) + val power = new Power(intp, new ReplVals { }) + 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..d1b71f0926 --- /dev/null +++ b/test/files/run/typetags_core.check @@ -0,0 +1,30 @@ +true +GroundTypeTag[Byte] +true +GroundTypeTag[Short] +true +GroundTypeTag[Char] +true +GroundTypeTag[Int] +true +GroundTypeTag[Long] +true +GroundTypeTag[Float] +true +GroundTypeTag[Double] +true +GroundTypeTag[Boolean] +true +GroundTypeTag[Unit] +true +GroundTypeTag[Any] +true +GroundTypeTag[Object] +true +GroundTypeTag[AnyVal] +true +GroundTypeTag[AnyRef] +true +GroundTypeTag[Null] +true +GroundTypeTag[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/pending/neg/reify_packed.check b/test/pending/neg/reify_packed.check new file mode 100644 index 0000000000..adba330d56 --- /dev/null +++ b/test/pending/neg/reify_packed.check @@ -0,0 +1,4 @@ +reify_packed.scala:6: error: implementation restriction: cannot reify block of type List[_$1] that involves a type declared inside the block being reified. consider casting the return value to a suitable type. + reify { + ^ +one error found diff --git a/test/pending/neg/reify_packed.scala b/test/pending/neg/reify_packed.scala new file mode 100644 index 0000000000..0240f2a4b5 --- /dev/null +++ b/test/pending/neg/reify_packed.scala @@ -0,0 +1,10 @@ +object Test extends App { + reify { + class C { override def toString() = "C" } + val ret = List((new C, new C)) + ret.asInstanceOf[List[_]] + }; + + val toolbox = mkToolBox() + println(toolbox.runExpr(code.tree)) +} diff --git a/test/pending/run/macro-expand-default.flags b/test/pending/run/macro-expand-default.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-default.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file 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-expand-implicit-macro-has-context-bound.flags b/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags new file mode 100644 index 0000000000..7fea2ff901 --- /dev/null +++ b/test/pending/run/macro-expand-implicit-macro-has-context-bound.flags @@ -0,0 +1 @@ +-Xmacros \ No newline at end of file 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.flags b/test/pending/run/macro-overload.flags deleted file mode 100644 index 7fea2ff901..0000000000 --- a/test/pending/run/macro-overload.flags +++ /dev/null @@ -1 +0,0 @@ --Xmacros \ 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..4b264d83af --- /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[_]: GroundTypeTag, T: GroundTypeTag] = { + println(implicitly[GroundTypeTag[C[T]]]) + println(implicitly[GroundTypeTag[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 { ; 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_classfileann_b.check b/test/pending/run/reify_classfileann_b.check deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/pending/run/reify_classfileann_b.scala b/test/pending/run/reify_classfileann_b.scala deleted file mode 100644 index c31826377a..0000000000 --- a/test/pending/run/reify_classfileann_b.scala +++ /dev/null @@ -1,24 +0,0 @@ -import scala.reflect._ -import scala.reflect.api._ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -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{ - class C { - def x: Int = { - 2: @ann(bar="1", quux=Array("2", "3"), baz = new ann(bar = "4")) - } - } - }.tree - println(tree.toString) - - // test 2: import and compile - val reporter = new ConsoleReporter(new Settings) - val toolbox = new ToolBox(reporter) - toolbox.runExpr(tree) -} \ No newline at end of file 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/pending/run/t5258a.check b/test/pending/run/t5258a.check new file mode 100644 index 0000000000..4e0b2da04c --- /dev/null +++ b/test/pending/run/t5258a.check @@ -0,0 +1 @@ +int \ No newline at end of file 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 -- cgit v1.2.3