diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build/bnd/scala-compiler.bnd | 2 | ||||
-rw-r--r-- | src/build/bnd/scala-parser-combinators.bnd | 5 | ||||
-rw-r--r-- | src/build/bnd/scala-xml.bnd | 5 | ||||
-rw-r--r-- | src/build/dbuild-meta-json-gen.scala | 63 | ||||
-rw-r--r-- | src/build/maven/jline-pom.xml | 68 | ||||
-rw-r--r-- | src/build/maven/maven-deploy.xml | 320 | ||||
-rw-r--r-- | src/build/maven/plugins/continuations-pom.xml (renamed from src/build/maven/continuations-plugin-pom.xml) | 0 | ||||
-rw-r--r-- | src/build/maven/scala-compiler-pom.xml | 56 | ||||
-rw-r--r-- | src/build/maven/scala-library-pom.xml | 5 | ||||
-rw-r--r-- | src/build/maven/scala-parser-combinators-pom.xml | 59 | ||||
-rw-r--r-- | src/build/maven/scala-xml-pom.xml (renamed from src/build/maven/scala-dotnet-library-pom.xml) | 40 | ||||
-rw-r--r-- | src/build/pack.xml | 27 | ||||
-rw-r--r-- | src/compiler/scala/reflect/macros/compiler/Errors.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/reflect/reify/codegen/GenTrees.scala | 27 | ||||
-rw-r--r-- | src/compiler/scala/reflect/reify/codegen/GenUtils.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/reflect/reify/package.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/ant/templates/tool-unix.tmpl | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeGen.scala | 49 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 77 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 54 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 33 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala | 49 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/settings/MutableSettings.scala | 71 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala | 39 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Mixin.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 21 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 107 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Unapplies.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/util/CharArrayReader.scala | 31 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/FastTrack.scala | 8 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/ToolBoxFactory.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/quasiquotes/Holes.scala | 187 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala | 134 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala | 123 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala | 51 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala | 290 | ||||
-rw-r--r-- | src/eclipse/continuations-library/.classpath | 2 | ||||
-rw-r--r-- | src/eclipse/continuations-library/.project | 2 | ||||
-rw-r--r-- | src/eclipse/interactive/.classpath | 5 | ||||
-rw-r--r-- | src/eclipse/partest/.classpath | 13 | ||||
-rw-r--r-- | src/eclipse/reflect/.classpath | 2 | ||||
-rw-r--r-- | src/eclipse/repl/.classpath | 15 | ||||
-rw-r--r-- | src/eclipse/repl/.project | 64 | ||||
-rw-r--r-- | src/eclipse/scala-compiler/.classpath | 7 | ||||
-rw-r--r-- | src/eclipse/scala-library/.classpath | 2 | ||||
-rw-r--r-- | src/eclipse/scala-parser-combinators/.classpath | 7 | ||||
-rw-r--r-- | src/eclipse/scala-parser-combinators/.project | 30 | ||||
-rw-r--r-- | src/eclipse/scala-xml/.classpath | 7 | ||||
-rw-r--r-- | src/eclipse/scala-xml/.project | 30 | ||||
-rw-r--r-- | src/eclipse/scaladoc/.classpath | 11 | ||||
-rw-r--r-- | src/eclipse/scalap/.classpath | 9 | ||||
-rw-r--r-- | src/eclipse/test-junit/.classpath | 7 | ||||
-rw-r--r-- | src/interactive/scala/tools/nsc/interactive/ScratchPadMaker.scala | 2 | ||||
-rw-r--r-- | src/library/scala/Predef.scala | 9 | ||||
-rw-r--r-- | src/library/scala/collection/GenTraversableOnce.scala | 30 | ||||
-rw-r--r-- | src/library/scala/collection/TraversableOnce.scala | 28 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/ImplicitConversions.scala (renamed from src/library/scala/util/parsing/combinator/ImplicitConversions.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/JavaTokenParsers.scala (renamed from src/library/scala/util/parsing/combinator/JavaTokenParsers.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/PackratParsers.scala (renamed from src/library/scala/util/parsing/combinator/PackratParsers.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/Parsers.scala (renamed from src/library/scala/util/parsing/combinator/Parsers.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/RegexParsers.scala (renamed from src/library/scala/util/parsing/combinator/RegexParsers.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/lexical/Lexical.scala (renamed from src/library/scala/util/parsing/combinator/lexical/Lexical.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/lexical/Scanners.scala (renamed from src/library/scala/util/parsing/combinator/lexical/Scanners.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/lexical/StdLexical.scala (renamed from src/library/scala/util/parsing/combinator/lexical/StdLexical.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala (renamed from src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala (renamed from src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/syntactical/TokenParsers.scala (renamed from src/library/scala/util/parsing/combinator/syntactical/TokenParsers.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/token/StdTokens.scala (renamed from src/library/scala/util/parsing/combinator/token/StdTokens.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/combinator/token/Tokens.scala (renamed from src/library/scala/util/parsing/combinator/token/Tokens.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/CharArrayReader.scala (renamed from src/library/scala/util/parsing/input/CharArrayReader.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/CharSequenceReader.scala (renamed from src/library/scala/util/parsing/input/CharSequenceReader.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/NoPosition.scala (renamed from src/library/scala/util/parsing/input/NoPosition.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/OffsetPosition.scala (renamed from src/library/scala/util/parsing/input/OffsetPosition.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/PagedSeqReader.scala (renamed from src/library/scala/util/parsing/input/PagedSeqReader.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/Position.scala (renamed from src/library/scala/util/parsing/input/Position.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/Positional.scala (renamed from src/library/scala/util/parsing/input/Positional.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/Reader.scala (renamed from src/library/scala/util/parsing/input/Reader.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/input/StreamReader.scala (renamed from src/library/scala/util/parsing/input/StreamReader.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/json/JSON.scala (renamed from src/library/scala/util/parsing/json/JSON.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/json/Lexer.scala (renamed from src/library/scala/util/parsing/json/Lexer.scala) | 0 | ||||
-rw-r--r-- | src/parser-combinators/scala/util/parsing/json/Parser.scala (renamed from src/library/scala/util/parsing/json/Parser.scala) | 0 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/ReplTest.scala | 13 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/nest/FileManager.scala | 4 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/BuildUtils.scala | 42 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Liftable.scala | 32 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Quasiquotes.scala | 20 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/StandardLiftables.scala | 36 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Universe.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/BuildUtils.scala | 120 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 40 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/StdNames.scala | 49 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeGen.scala | 76 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/ConsoleReaderHelper.scala | 2 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/Delimited.scala | 2 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/ILoop.scala | 220 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/JLineReader.scala | 6 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/session/SimpleHistory.scala | 5 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/session/package.scala | 8 | ||||
-rw-r--r-- | src/xml/scala/xml/Atom.scala (renamed from src/library/scala/xml/Atom.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Attribute.scala (renamed from src/library/scala/xml/Attribute.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Comment.scala (renamed from src/library/scala/xml/Comment.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Document.scala (renamed from src/library/scala/xml/Document.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/Elem.scala (renamed from src/library/scala/xml/Elem.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/EntityRef.scala (renamed from src/library/scala/xml/EntityRef.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Equality.scala (renamed from src/library/scala/xml/Equality.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Group.scala (renamed from src/library/scala/xml/Group.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/MalformedAttributeException.scala (renamed from src/library/scala/xml/MalformedAttributeException.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/MetaData.scala (renamed from src/library/scala/xml/MetaData.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/NamespaceBinding.scala (renamed from src/library/scala/xml/NamespaceBinding.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/Node.scala (renamed from src/library/scala/xml/Node.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/NodeBuffer.scala (renamed from src/library/scala/xml/NodeBuffer.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/NodeSeq.scala (renamed from src/library/scala/xml/NodeSeq.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Null.scala (renamed from src/library/scala/xml/Null.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/PCData.scala (renamed from src/library/scala/xml/PCData.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/PrefixedAttribute.scala (renamed from src/library/scala/xml/PrefixedAttribute.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/PrettyPrinter.scala (renamed from src/library/scala/xml/PrettyPrinter.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/ProcInstr.scala (renamed from src/library/scala/xml/ProcInstr.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/QNode.scala (renamed from src/library/scala/xml/QNode.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/SpecialNode.scala (renamed from src/library/scala/xml/SpecialNode.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Text.scala (renamed from src/library/scala/xml/Text.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/TextBuffer.scala (renamed from src/library/scala/xml/TextBuffer.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/TopScope.scala (renamed from src/library/scala/xml/TopScope.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/TypeSymbol.scala (renamed from src/library/scala/xml/TypeSymbol.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Unparsed.scala (renamed from src/library/scala/xml/Unparsed.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/UnprefixedAttribute.scala (renamed from src/library/scala/xml/UnprefixedAttribute.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/Utility.scala (renamed from src/library/scala/xml/Utility.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/XML.scala (renamed from src/library/scala/xml/XML.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/Xhtml.scala (renamed from src/library/scala/xml/Xhtml.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/ContentModel.scala (renamed from src/library/scala/xml/dtd/ContentModel.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/ContentModelParser.scala (renamed from src/library/scala/xml/dtd/ContentModelParser.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/DTD.scala (renamed from src/library/scala/xml/dtd/DTD.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/Decl.scala (renamed from src/library/scala/xml/dtd/Decl.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/DocType.scala (renamed from src/library/scala/xml/dtd/DocType.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/ElementValidator.scala (renamed from src/library/scala/xml/dtd/ElementValidator.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/ExternalID.scala (renamed from src/library/scala/xml/dtd/ExternalID.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/Scanner.scala (renamed from src/library/scala/xml/dtd/Scanner.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/Tokens.scala (renamed from src/library/scala/xml/dtd/Tokens.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/ValidationException.scala (renamed from src/library/scala/xml/dtd/ValidationException.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/Base.scala (renamed from src/library/scala/xml/dtd/impl/Base.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/BaseBerrySethi.scala (renamed from src/library/scala/xml/dtd/impl/BaseBerrySethi.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/DetWordAutom.scala (renamed from src/library/scala/xml/dtd/impl/DetWordAutom.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/Inclusion.scala (renamed from src/library/scala/xml/dtd/impl/Inclusion.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/NondetWordAutom.scala (renamed from src/library/scala/xml/dtd/impl/NondetWordAutom.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/PointedHedgeExp.scala (renamed from src/library/scala/xml/dtd/impl/PointedHedgeExp.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/SubsetConstruction.scala (renamed from src/library/scala/xml/dtd/impl/SubsetConstruction.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/SyntaxError.scala (renamed from src/library/scala/xml/dtd/impl/SyntaxError.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/WordBerrySethi.scala (renamed from src/library/scala/xml/dtd/impl/WordBerrySethi.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/dtd/impl/WordExp.scala (renamed from src/library/scala/xml/dtd/impl/WordExp.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/factory/Binder.scala (renamed from src/library/scala/xml/factory/Binder.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/factory/LoggedNodeFactory.scala (renamed from src/library/scala/xml/factory/LoggedNodeFactory.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/factory/NodeFactory.scala (renamed from src/library/scala/xml/factory/NodeFactory.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/factory/XMLLoader.scala (renamed from src/library/scala/xml/factory/XMLLoader.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/include/CircularIncludeException.scala (renamed from src/library/scala/xml/include/CircularIncludeException.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/include/UnavailableResourceException.scala (renamed from src/library/scala/xml/include/UnavailableResourceException.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/include/XIncludeException.scala (renamed from src/library/scala/xml/include/XIncludeException.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/include/sax/EncodingHeuristics.scala (renamed from src/library/scala/xml/include/sax/EncodingHeuristics.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/include/sax/XIncludeFilter.scala (renamed from src/library/scala/xml/include/sax/XIncludeFilter.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/include/sax/XIncluder.scala (renamed from src/library/scala/xml/include/sax/XIncluder.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/package.scala (renamed from src/library/scala/xml/package.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/parsing/ConstructingHandler.scala (renamed from src/library/scala/xml/parsing/ConstructingHandler.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/ConstructingParser.scala (renamed from src/library/scala/xml/parsing/ConstructingParser.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/parsing/DefaultMarkupHandler.scala (renamed from src/library/scala/xml/parsing/DefaultMarkupHandler.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/ExternalSources.scala (renamed from src/library/scala/xml/parsing/ExternalSources.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/FactoryAdapter.scala (renamed from src/library/scala/xml/parsing/FactoryAdapter.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/FatalError.scala (renamed from src/library/scala/xml/parsing/FatalError.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/parsing/MarkupHandler.scala (renamed from src/library/scala/xml/parsing/MarkupHandler.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/parsing/MarkupParser.scala (renamed from src/library/scala/xml/parsing/MarkupParser.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/MarkupParserCommon.scala (renamed from src/library/scala/xml/parsing/MarkupParserCommon.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/NoBindingFactoryAdapter.scala (renamed from src/library/scala/xml/parsing/NoBindingFactoryAdapter.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/TokenTests.scala (renamed from src/library/scala/xml/parsing/TokenTests.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/ValidatingMarkupHandler.scala (renamed from src/library/scala/xml/parsing/ValidatingMarkupHandler.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/XhtmlEntities.scala (renamed from src/library/scala/xml/parsing/XhtmlEntities.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/parsing/XhtmlParser.scala (renamed from src/library/scala/xml/parsing/XhtmlParser.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/persistent/CachedFileStorage.scala (renamed from src/library/scala/xml/persistent/CachedFileStorage.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/persistent/Index.scala (renamed from src/library/scala/xml/persistent/Index.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/persistent/SetStorage.scala (renamed from src/library/scala/xml/persistent/SetStorage.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/pull/XMLEvent.scala (renamed from src/library/scala/xml/pull/XMLEvent.scala) | 0 | ||||
-rwxr-xr-x | src/xml/scala/xml/pull/XMLEventReader.scala (renamed from src/library/scala/xml/pull/XMLEventReader.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/pull/package.scala (renamed from src/library/scala/xml/pull/package.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/transform/BasicTransformer.scala (renamed from src/library/scala/xml/transform/BasicTransformer.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/transform/RewriteRule.scala (renamed from src/library/scala/xml/transform/RewriteRule.scala) | 0 | ||||
-rw-r--r-- | src/xml/scala/xml/transform/RuleTransformer.scala (renamed from src/library/scala/xml/transform/RuleTransformer.scala) | 0 |
187 files changed, 2260 insertions, 796 deletions
diff --git a/src/build/bnd/scala-compiler.bnd b/src/build/bnd/scala-compiler.bnd index c289843447..dc30513db4 100644 --- a/src/build/bnd/scala-compiler.bnd +++ b/src/build/bnd/scala-compiler.bnd @@ -3,6 +3,6 @@ Bundle-SymbolicName: org.scala-lang.scala-compiler ver: @VERSION@ Bundle-Version: ${ver} Export-Package: *;version=${ver} -Import-Package: scala.tools.jline.*;resolution:=optional, \ +Import-Package: jline.*;resolution:=optional, \ org.apache.tools.ant.*;resolution:=optional, \ * diff --git a/src/build/bnd/scala-parser-combinators.bnd b/src/build/bnd/scala-parser-combinators.bnd new file mode 100644 index 0000000000..d712a4ba2a --- /dev/null +++ b/src/build/bnd/scala-parser-combinators.bnd @@ -0,0 +1,5 @@ +Bundle-Name: Scala Parser Combinators Library +Bundle-SymbolicName: org.scala-lang.scala-parser-combinators +ver: @VERSION@ +Bundle-Version: ${ver} +Export-Package: *;version=${ver} diff --git a/src/build/bnd/scala-xml.bnd b/src/build/bnd/scala-xml.bnd new file mode 100644 index 0000000000..6203c57dfe --- /dev/null +++ b/src/build/bnd/scala-xml.bnd @@ -0,0 +1,5 @@ +Bundle-Name: Scala XML Library +Bundle-SymbolicName: org.scala-lang.scala-xml +ver: @VERSION@ +Bundle-Version: ${ver} +Export-Package: *;version=${ver} diff --git a/src/build/dbuild-meta-json-gen.scala b/src/build/dbuild-meta-json-gen.scala new file mode 100644 index 0000000000..42214dd191 --- /dev/null +++ b/src/build/dbuild-meta-json-gen.scala @@ -0,0 +1,63 @@ +// use this script to generate dbuild-meta.json +// make sure the version is specified correctly, +// update the dependency structura and +// check out distributed-build and run `sbt console`: +// TODO: also generate build.xml and eclipse config from a similar data-structure + +import distributed.project.model._ + +val meta = + ExtractedBuildMeta("2.11.0", Seq( + Project("scala-library", "org.scala-lang", + Seq(ProjectRef("scala-library", "org.scala-lang")), + Seq.empty), // TODO: forkjoin + Project("scala-reflect", "org.scala-lang", + Seq(ProjectRef("scala-reflect", "org.scala-lang")), + Seq(ProjectRef("scala-library", "org.scala-lang"))), + Project("scala-compiler", "org.scala-lang", + Seq(ProjectRef("scala-compiler", "org.scala-lang")), + Seq(ProjectRef("scala-reflect", "org.scala-lang"))), // asm + + // Project("scala-repl", "org.scala-lang", + // Seq(ProjectRef("scala-repl", "org.scala-lang")), + // Seq(ProjectRef("scala-compiler", "org.scala-lang"))), // jline + + // Project("scala-interactive", "org.scala-lang", + // Seq(ProjectRef("scala-interactive", "org.scala-lang")), + // Seq(ProjectRef("scala-compiler", "org.scala-lang"), ProjectRef("scaladoc", "org.scala-lang"))), + + Project("scala-swing", "org.scala-lang", + Seq(ProjectRef("scala-swing", "org.scala-lang")), + Seq(ProjectRef("scala-library", "org.scala-lang"))), + + Project("scala-actors", "org.scala-lang", + Seq(ProjectRef("scala-actors", "org.scala-lang")), + Seq(ProjectRef("scala-library", "org.scala-lang"))), + Project("scala-xml", "org.scala-lang", + Seq(ProjectRef("scala-xml", "org.scala-lang")), + Seq(ProjectRef("scala-library", "org.scala-lang"))), + Project("scala-parser-combinators", "org.scala-lang", + Seq(ProjectRef("scala-parser-combinators", "org.scala-lang")), + Seq(ProjectRef("scala-library", "org.scala-lang"))), + + Project("scalacheck", "org.scala-lang", + Seq(ProjectRef("scalacheck", "org.scala-lang")), + Seq(ProjectRef("scala-library", "org.scala-lang"), ProjectRef("scala-actors", "org.scala-lang"), ProjectRef("scala-parser-combinators", "org.scala-lang"))), + + Project("scala-partest", "org.scala-lang", + Seq(ProjectRef("scala-partest", "org.scala-lang")), + Seq(ProjectRef("scala-compiler", "org.scala-lang"), // TODO: refine to scala-repl + ProjectRef("scalap", "org.scala-lang"), ProjectRef("scala-xml", "org.scala-lang"), ProjectRef("scalacheck", "org.scala-lang"))), + + Project("scaladoc", "org.scala-lang", + Seq(ProjectRef("scaladoc", "org.scala-lang")), + Seq(ProjectRef("scala-compiler", "org.scala-lang"),ProjectRef("scala-partest", "org.scala-lang"), ProjectRef("scala-xml", "org.scala-lang"), ProjectRef("scala-parser-combinators", "org.scala-lang"))), + + Project("scalap", "org.scala-lang", + Seq(ProjectRef("scalap", "org.scala-lang")), + Seq(ProjectRef("scala-compiler", "org.scala-lang"))), + + Project("continuations", "org.scala-lang.plugins", Seq(ProjectRef("continuations", "org.scala-lang.plugins")), Seq.empty) + )) + +println(Utils.writeValue(meta)) diff --git a/src/build/maven/jline-pom.xml b/src/build/maven/jline-pom.xml deleted file mode 100644 index 0d6e801551..0000000000 --- a/src/build/maven/jline-pom.xml +++ /dev/null @@ -1,68 +0,0 @@ -<project - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.scala-lang</groupId> - <artifactId>jline</artifactId> - <packaging>jar</packaging> - <version>@VERSION@</version> - <name>jline</name> - <description>Like readline, but better</description> - <url>http://www.scala-lang.org/</url> - <inceptionYear>2011</inceptionYear> - <organization> - <name>LAMP/EPFL</name> - <url>http://lamp.epfl.ch/</url> - </organization> - <licenses> - <license> - <name>BSD-like</name> - <url>http://www.scala-lang.org/downloads/license.html - </url> - <distribution>repo</distribution> - </license> - <license> - <name>The BSD License</name> - <url>http://www.opensource.org/licenses/bsd-license.php</url> - <distribution>repo</distribution> - </license> - </licenses> - <scm> - <connection>scm:git:git://github.com/scala/scala.git</connection> - <url>https://github.com/scala/scala.git</url> - </scm> - <issueManagement> - <system>JIRA</system> - <url>https://issues.scala-lang.org/</url> - </issueManagement> - - <dependencies> - <dependency> - <groupId>org.fusesource.jansi</groupId> - <artifactId>jansi</artifactId> - <version>1.4</version> - <!--<scope>provided</scope>--> - </dependency> - </dependencies> - <distributionManagement> - <repository> - <id>scala-tools.org</id> - <url>@RELEASE_REPOSITORY@</url> - </repository> - <snapshotRepository> - <id>scala-tools.org</id> - <url>@SNAPSHOT_REPOSITORY@</url> - <uniqueVersion>false</uniqueVersion> - </snapshotRepository> - </distributionManagement> - <developers> - <developer> - <id>lamp</id> - <name>EPFL LAMP</name> - </developer> - <developer> - <id>Typesafe</id> - <name>Typesafe, Inc.</name> - </developer> - </developers> -</project> diff --git a/src/build/maven/maven-deploy.xml b/src/build/maven/maven-deploy.xml index e70173319e..84a12066f5 100644 --- a/src/build/maven/maven-deploy.xml +++ b/src/build/maven/maven-deploy.xml @@ -5,271 +5,121 @@ <description> SuperSabbus extension for deploying a distribution to Maven. THIS FILE IS MEANT TO BE RUN STANDALONE IN THE MAVEN "distpack" DIRECTORY </description> - <target name="init.properties"> + + <target name="boot"> <!-- Pull in properties from build --> <property file="build.properties" /> - <!-- Initialize specific properties --> + <property name="remote.snapshot.repository" value="https://oss.sonatype.org/content/repositories/snapshots" /> - <property name="remote.release.repository" value="https://oss.sonatype.org/service/local/staging/deploy/maven2" /> + <property name="remote.release.repository" value="https://oss.sonatype.org/service/local/staging/deploy/maven2" /> <property name="local.snapshot.repository" value="${user.home}/.m2/repository" /> - <property name="local.release.repository" value="${user.home}/.m2/repository" /> + <property name="local.release.repository" value="${user.home}/.m2/repository" /> + <property name="repository.credentials.id" value="sonatype-nexus" /> <property name="settings.file" value="${user.home}/.m2/settings.xml" /> - <condition property="version.is.snapshot"> - <contains string="${maven.version.number}" substring="-SNAPSHOT"/> - </condition> - - <echo>Using server[${repository.credentials.id}] for maven repository credentials. - Please make sure that your ~/.m2/settings.xml has the needed username/password for this server id - </echo> - - </target> - - <target name="init.maven" depends="init.properties"> + <!-- Set up Ant contrib tasks so we can use <if><then><else> instead of the clunky `unless` attribute --> + <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="ant-contrib.jar"/> <!-- Add our maven ant tasks --> <path id="maven-ant-tasks.classpath" path="maven-ant-tasks-2.1.1.jar" /> <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" /> + </target> - <!-- simplify fixing pom versions --> - <macrodef name="make-pom"> - <attribute name="name" /> - <attribute name="version" /> - <sequential> - <copy file="@{name}/@{name}-pom.xml" tofile="@{name}/@{name}-pom-fixed.xml" overwrite="true"> - <filterset> - <filter token="VERSION" value="@{version}" /> - <filter token="RELEASE_REPOSITORY" value="${remote.release.repository}" /> - <filter token="SNAPSHOT_REPOSITORY" value="${remote.snapshot.repository}" /> - </filterset> - </copy> - <artifact:pom id="@{name}.pom" file="@{name}/@{name}-pom-fixed.xml" /> - </sequential> - </macrodef> + <target name="init" depends="boot"> + <if><contains string="${maven.version.number}" substring="-SNAPSHOT"/><then> + <property name="remote.repository" value="${remote.snapshot.repository}"/> + <property name="local.repository" value="${local.snapshot.repository}"/> + </then><else> + <property name="remote.repository" value="${remote.release.repository}"/> + <property name="local.repository" value="${local.release.repository}"/> + </else></if> - <macrodef name="make-pom-plugin"> + <echo>Using server[${repository.credentials.id}] for maven repository credentials. + Please make sure that your ~/.m2/settings.xml has the needed username/password for this server id + </echo> + + <macrodef name="deploy-one"> + <attribute name="dir" default=""/> <attribute name="name" /> <attribute name="version" /> + <attribute name="local" /> + <attribute name="signed" /> + <sequential> - <copy file="plugins/@{name}/@{name}-plugin-pom.xml" tofile="plugins/@{name}/@{name}-pom-fixed.xml" overwrite="true"> + <local name="path"/> <property name="path" value="@{dir}@{name}/@{name}"/> + + <echo>Deploying ${path}-[pom.xml|src.jar|docs.jar].</echo> + + <copy file="${path}-pom.xml" tofile="${path}-pom-filtered.xml" overwrite="true"> <filterset> <filter token="VERSION" value="@{version}" /> <filter token="RELEASE_REPOSITORY" value="${remote.release.repository}" /> <filter token="SNAPSHOT_REPOSITORY" value="${remote.snapshot.repository}" /> + <filter token="JLINE_VERSION" value="${jline.version}" /> </filterset> </copy> - <artifact:pom id="plugin-@{name}.pom" file="plugins/@{name}/@{name}-pom-fixed.xml" /> - </sequential> - </macrodef> - </target> - <!-- macros for local deployment --> - <target name="deploy.local.init" depends="init.maven"> - <!-- Deploy single artifact locally --> - <macrodef name="deploy-local"> - <attribute name="name" /> - <attribute name="version" /> - <attribute name="repository" /> - <element name="extra-attachments" optional="yes" /> - <sequential> - <make-pom name="@{name}" version="@{version}" /> - <artifact:install file="@{name}/@{name}.jar"> - <artifact:pom refid="@{name}.pom" /> - <artifact:localRepository path="@{repository}" id="${repository.credentials.id}" /> - <artifact:attach type="jar" file="@{name}/@{name}-src.jar" classifier="sources" /> - <artifact:attach type="jar" file="@{name}/@{name}-docs.jar" classifier="javadoc" /> - <extra-attachments /> - </artifact:install> - </sequential> - </macrodef> - - <!-- Deploy compiler plugins --> - <macrodef name="deploy-local-plugin"> - <attribute name="name" /> - <attribute name="version" /> - <attribute name="repository" /> - <element name="extra-attachments" optional="yes" /> - <sequential> - <make-pom-plugin name="@{name}" version="@{version}" /> - <artifact:install file="plugins/@{name}/@{name}.jar"> - <artifact:pom refid="plugin-@{name}.pom" /> - <artifact:attach type="jar" file="plugins/@{name}/@{name}-src.jar" classifier="sources" /> - <artifact:attach type="jar" file="plugins/@{name}/@{name}-docs.jar" classifier="javadoc" /> - <artifact:localRepository path="@{repository}" id="${repository.credentials.id}" /> - <extra-attachments /> - </artifact:install> - </sequential> - </macrodef> - - - <!-- Deploy all artifacts locally --> - <macrodef name="deploy-local-all"> - <attribute name="repository" /> - <attribute name="version" /> - <sequential> - <deploy-local name="scala-library" version="@{version}" repository="@{repository}" /> - <deploy-local name="scala-compiler" version="@{version}" repository="@{repository}" /> - <deploy-local-plugin name="continuations" version="@{version}" repository="@{repository}"/> - <deploy-local name="scala-reflect" version="@{version}" repository="@{repository}" /> - <deploy-local name="scala-actors" version="@{version}" repository="@{repository}" /> - <deploy-local name="scala-swing" version="@{version}" repository="@{repository}"/> - <deploy-local name="scalap" version="@{version}" repository="@{repository}"/> - <deploy-local name="scala-partest" version="@{version}" repository="@{repository}"/> - <deploy-local name="jline" version="@{version}" repository="@{repository}"/> - </sequential> - </macrodef> - </target> - - <!-- macros for remote deployment --> - <target name="deploy.remote.init" depends="init.maven"> - <!-- Deploy single artifact locally --> - <macrodef name="deploy-remote"> - <attribute name="name" /> - <attribute name="repository" /> - <attribute name="version" /> - <element name="extra-attachments" optional="yes" /> - <sequential> - <make-pom name="@{name}" version="@{version}" /> - <artifact:deploy file="@{name}/@{name}.jar" settingsFile="${settings.file}"> - <artifact:pom refid="@{name}.pom" /> - <artifact:remoteRepository url="@{repository}" id="${repository.credentials.id}" /> - <artifact:attach type="jar" file="@{name}/@{name}-src.jar" classifier="sources" /> - <artifact:attach type="jar" file="@{name}/@{name}-docs.jar" classifier="javadoc" /> - <extra-attachments /> - </artifact:deploy> + <artifact:pom id="@{name}.pom" file="${path}-pom-filtered.xml" /> + + <if><equals arg1="@{signed}" arg2="false"/><then> + <if><equals arg1="@{local}" arg2="false"/><then> + <artifact:deploy file="${path}.jar" settingsFile="${settings.file}"> + <artifact:remoteRepository url="${remote.repository}" id="${repository.credentials.id}" /> + <artifact:pom refid="@{name}.pom" /> + <artifact:attach type="jar" file="${path}-src.jar" classifier="sources" /> + <artifact:attach type="jar" file="${path}-docs.jar" classifier="javadoc" /> + </artifact:deploy> + </then><else> + <artifact:install file="${path}.jar"> + <artifact:localRepository path="${local.repository}" id="${repository.credentials.id}" /> + <artifact:pom refid="@{name}.pom" /> + <artifact:attach type="jar" file="${path}-src.jar" classifier="sources" /> + <artifact:attach type="jar" file="${path}-docs.jar" classifier="javadoc" /> + </artifact:install> + </else></if> + </then><else> + <local name="repo"/> + <if><equals arg1="@{local}" arg2="false"/><then> + <property name="repo" value="${remote.repository}"/> + </then><else> + <property name="repo" value="${local.repository}"/> + </else></if> + <artifact:mvn> + <arg value="org.apache.maven.plugins:maven-gpg-plugin:1.3:sign-and-deploy-file" /> + <arg value="-Durl=${repo}" /> + <arg value="-DrepositoryId=${repository.credentials.id}" /> + <arg value="-DpomFile=${path}-pom-filtered.xml" /> + <arg value= "-Dfile=${path}.jar" /> + <arg value="-Dsources=${path}-src.jar" /> + <arg value="-Djavadoc=${path}-docs.jar" /> + <arg value="-Pgpg" /> + <arg value="-Dgpg.useagent=true" /> + </artifact:mvn> + </else></if> </sequential> </macrodef> - <!-- Deploy compiler plugins --> - <macrodef name="deploy-remote-plugin"> - <attribute name="name" /> - <attribute name="version" /> - <attribute name="repository" /> - <element name="extra-attachments" optional="yes" /> - <sequential> - <make-pom-plugin name="@{name}" version="@{version}" /> - <artifact:deploy file="plugins/@{name}/@{name}.jar" settingsFile="${settings.file}"> - <artifact:pom refid="plugin-@{name}.pom" /> - <artifact:attach type="jar" file="plugins/@{name}/@{name}-src.jar" classifier="sources" /> - <artifact:attach type="jar" file="plugins/@{name}/@{name}-docs.jar" classifier="javadoc" /> - <artifact:remoteRepository url="@{repository}" id="${repository.credentials.id}" /> - <extra-attachments /> - </artifact:deploy> - </sequential> - </macrodef> + <macrodef name="deploy"> + <attribute name="local" default="false"/> + <attribute name="signed" default="false"/> - <!-- Deploy all artifacts locally --> - <macrodef name="deploy-remote-all"> - <attribute name="repository" /> - <attribute name="version" /> <sequential> - <deploy-remote name="scala-library" version="@{version}" repository="@{repository}"/> - <deploy-remote name="jline" version="@{version}" repository="@{repository}"/> - <deploy-remote name="scala-reflect" version="@{version}" repository="@{repository}"/> - <deploy-remote name="scala-compiler" version="@{version}" repository="@{repository}" /> - <deploy-remote name="scala-swing" version="@{version}" repository="@{repository}"/> - <deploy-remote name="scala-actors" version="@{version}" repository="@{repository}"/> - <deploy-remote name="scalap" version="@{version}" repository="@{repository}"/> - <deploy-remote name="scala-partest" version="@{version}" repository="@{repository}"/> - <deploy-remote-plugin name="continuations" version="@{version}" repository="@{repository}"/> + <deploy-one name="scala-actors" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one name="scala-compiler" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one name="scala-library" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one name="scala-xml" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one name="scala-parser-combinators" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one name="scala-partest" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one name="scala-reflect" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one name="scala-swing" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one name="scalap" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> + <deploy-one dir="plugins/" name="continuations" version="${maven.version.number}" local="@{local}" signed="@{signed}"/> </sequential> </macrodef> - - <!-- PGP Signed deployment --> - <macrodef name="deploy-remote-signed-single"> - <attribute name="pom" /> - <attribute name="repository" /> - <attribute name="jar" /> - <attribute name="srcjar" /> - <attribute name="docjar" /> - <sequential> - <artifact:mvn> - <arg value="org.apache.maven.plugins:maven-gpg-plugin:1.3:sign-and-deploy-file" /> - <arg value="-Durl=@{repository}" /> - <arg value="-DrepositoryId=${repository.credentials.id}" /> - <arg value="-DpomFile=@{pom}" /> - <arg value="-Dfile=@{jar}" /> - <arg value="-Dsources=@{srcjar}" /> - <arg value="-Djavadoc=@{docjar}" /> - <arg value="-Pgpg" /> - <arg value="-Dgpg.useagent=true" /> - </artifact:mvn> - </sequential> - </macrodef> - <macrodef name="deploy-remote-signed"> - <attribute name="name" /> - <attribute name="repository" /> - <attribute name="version" /> - <element name="extra-attachments" optional="yes" /> - <sequential> - <make-pom name="@{name}" version="@{version}" /> - <deploy-remote-signed-single - pom="@{name}/@{name}-pom-fixed.xml" - repository="@{repository}" - jar="@{name}/@{name}.jar" - srcjar="@{name}/@{name}-src.jar" - docjar="@{name}/@{name}-docs.jar" /> - </sequential> - </macrodef> - <macrodef name="deploy-remote-plugin-signed"> - <attribute name="name" /> - <attribute name="repository" /> - <attribute name="version" /> - <element name="extra-attachments" optional="yes" /> - <sequential> - <make-pom-plugin name="@{name}" version="@{version}" /> - <deploy-remote-signed-single - pom="plugins/@{name}/@{name}-pom-fixed.xml" - repository="@{repository}" - jar="plugins/@{name}/@{name}.jar" - srcjar="plugins/@{name}/@{name}-src.jar" - docjar="plugins/@{name}/@{name}-docs.jar" /> - </sequential> - </macrodef> - <macrodef name="deploy-remote-signed-all"> - <attribute name="repository" /> - <attribute name="version" /> - <sequential> - <deploy-remote-plugin-signed name="continuations" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scala-library" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="jline" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scala-reflect" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scala-compiler" version="@{version}" repository="@{repository}" /> - <deploy-remote-signed name="scala-swing" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scala-actors" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scalap" version="@{version}" repository="@{repository}"/> - <deploy-remote-signed name="scala-partest" version="@{version}" repository="@{repository}"/> - </sequential> - </macrodef> - </target> - - <!-- Local Targets --> - <target name="deploy.snapshot.local" depends="deploy.local.init" if="version.is.snapshot" description="Deploys the bundled snapshot of the Scala Lanaguage to a local maven repository"> - <deploy-local-all version="${maven.version.number}" repository="${local.snapshot.repository}" /> - </target> - - <target name="deploy.release.local" depends="deploy.local.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the local Maven repository"> - <deploy-local-all version="${maven.version.number}" repository="${local.release.repository}" /> - </target> - <target name="deploy.local" depends="deploy.snapshot.local, deploy.release.local" description="Deploys the bundle files to the local maven repo."/> - - <!-- Remote Signed Targets --> - <target name="deploy.signed.snapshot" depends="deploy.remote.init" if="version.is.snapshot" description="Deploys the bundled files as a snapshot into the desired remote Maven repository"> - <deploy-remote-signed-all version="${maven.version.number}" repository="${remote.snapshot.repository}" /> </target> - <target name="deploy.signed.release" depends="deploy.remote.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the desired remote Maven repository"> - <deploy-remote-signed-all version="${maven.version.number}" repository="${remote.release.repository}" /> - </target> - <target name="deploy.signed" depends="deploy.signed.release, deploy.signed.snapshot" description="Deploys signed bundles to remote repo"/> - <!-- Remote unsigned targets --> - <target name="deploy.snapshot" depends="deploy.remote.init" if="version.is.snapshot" description="Deploys the bundled files as a snapshot into the desired remote Maven repository"> - <deploy-remote-all version="${maven.version.number}" repository="${remote.snapshot.repository}" /> - </target> - - <target name="deploy.release" depends="deploy.remote.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the desired remote Maven repository"> - <deploy-remote-all version="${maven.version.number}" repository="${remote.release.repository}" /> - </target> - <target name="deploy" depends="deploy.snapshot, deploy.release" description="Deploys unsigned artifacts to the maven repo."/> + <target name="deploy" depends="init" description="Deploys unsigned artifacts to the maven repo."> <deploy/> </target> + <target name="deploy.local" depends="init" description="Deploys unsigned artifacts to the local maven repo."> <deploy local="true"/> </target> + <target name="deploy.signed" depends="init" description="Deploys signed artifacts to the remote maven repo."> <deploy signed="true"/> </target> </project> diff --git a/src/build/maven/continuations-plugin-pom.xml b/src/build/maven/plugins/continuations-pom.xml index 9abb0a36f0..9abb0a36f0 100644 --- a/src/build/maven/continuations-plugin-pom.xml +++ b/src/build/maven/plugins/continuations-pom.xml diff --git a/src/build/maven/scala-compiler-pom.xml b/src/build/maven/scala-compiler-pom.xml index fedc34a5d5..6e7f1a0f2c 100644 --- a/src/build/maven/scala-compiler-pom.xml +++ b/src/build/maven/scala-compiler-pom.xml @@ -1,13 +1,13 @@ <project - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.scala-lang</groupId> <artifactId>scala-compiler</artifactId> <packaging>jar</packaging> <version>@VERSION@</version> - <name>Scala Compiler</name> - <description>Compiler for the Scala Programming Language</description> + <name>Scala Compiler</name> + <description>Compiler for the Scala Programming Language</description> <url>http://www.scala-lang.org/</url> <inceptionYear>2002</inceptionYear> <organization> @@ -23,12 +23,12 @@ </license> </licenses> <scm> - <connection>scm:git:git://github.com/scala/scala.git</connection> - <url>https://github.com/scala/scala.git</url> + <connection>scm:git:git://github.com/scala/scala.git</connection> + <url>https://github.com/scala/scala.git</url> </scm> <issueManagement> - <system>JIRA</system> - <url>https://issues.scala-lang.org/</url> + <system>JIRA</system> + <url>https://issues.scala-lang.org/</url> </issueManagement> <dependencies> @@ -37,17 +37,27 @@ <artifactId>scala-library</artifactId> <version>@VERSION@</version> </dependency> + <dependency> <!-- for scaladoc --> + <groupId>org.scala-lang</groupId> + <artifactId>scala-xml</artifactId> + <version>@VERSION@</version> + </dependency> + <dependency> <!-- for scaladoc --> + <groupId>org.scala-lang</groupId> + <artifactId>scala-parser-combinators</artifactId> + <version>@VERSION@</version> + </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-reflect</artifactId> <version>@VERSION@</version> </dependency> - <dependency> - <groupId>org.scala-lang</groupId> - <artifactId>jline</artifactId> - <version>@VERSION@</version> - <optional>true</optional> - </dependency> + <dependency> + <groupId>jline</groupId> + <artifactId>jline</artifactId> + <version>@JLINE_VERSION@</version> + <optional>true</optional> + </dependency> </dependencies> <distributionManagement> <repository> @@ -60,14 +70,14 @@ <uniqueVersion>false</uniqueVersion> </snapshotRepository> </distributionManagement> - <developers> - <developer> - <id>lamp</id> - <name>EPFL LAMP</name> - </developer> - <developer> - <id>Typesafe</id> - <name>Typesafe, Inc.</name> - </developer> - </developers> + <developers> + <developer> + <id>lamp</id> + <name>EPFL LAMP</name> + </developer> + <developer> + <id>Typesafe</id> + <name>Typesafe, Inc.</name> + </developer> + </developers> </project> diff --git a/src/build/maven/scala-library-pom.xml b/src/build/maven/scala-library-pom.xml index fc9964ae92..684474e79a 100644 --- a/src/build/maven/scala-library-pom.xml +++ b/src/build/maven/scala-library-pom.xml @@ -34,11 +34,6 @@ <info.apiURL>http://www.scala-lang.org/api/@VERSION@/</info.apiURL> </properties> <dependencies> - <!--<dependency> - <groupId>com.typesafe</groupId> - <artifactId>config</artifactId> - <version>0.4.0</version> - </dependency>--> </dependencies> <distributionManagement> <repository> diff --git a/src/build/maven/scala-parser-combinators-pom.xml b/src/build/maven/scala-parser-combinators-pom.xml new file mode 100644 index 0000000000..cddff269c8 --- /dev/null +++ b/src/build/maven/scala-parser-combinators-pom.xml @@ -0,0 +1,59 @@ +<project + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.scala-lang</groupId> + <artifactId>scala-parser-combinators</artifactId> + <packaging>jar</packaging> + <version>@VERSION@</version> + <name>Scala Parser Combinators</name> + <description>Parser Combinator Library for the Scala Programming Language</description> + <url>http://www.scala-lang.org/</url> + <inceptionYear>2002</inceptionYear> + <organization> + <name>LAMP/EPFL</name> + <url>http://lamp.epfl.ch/</url> + </organization> + <licenses> + <license> + <name>BSD-like</name> + <url>http://www.scala-lang.org/downloads/license.html + </url> + <distribution>repo</distribution> + </license> + </licenses> + <scm> + <connection>scm:git:git://github.com/scala/scala.git</connection> + <url>https://github.com/scala/scala.git</url> + </scm> + <issueManagement> + <system>JIRA</system> + <url>https://issues.scala-lang.org/</url> + </issueManagement> + <properties> + <info.apiURL>http://www.scala-lang.org/api/@VERSION@/</info.apiURL> + </properties> + <dependencies> + </dependencies> + <distributionManagement> + <repository> + <id>scala-tools.org</id> + <url>@RELEASE_REPOSITORY@</url> + </repository> + <snapshotRepository> + <id>scala-tools.org</id> + <url>@SNAPSHOT_REPOSITORY@</url> + <uniqueVersion>false</uniqueVersion> + </snapshotRepository> + </distributionManagement> + <developers> + <developer> + <id>lamp</id> + <name>EPFL LAMP</name> + </developer> + <developer> + <id>Typesafe</id> + <name>Typesafe, Inc.</name> + </developer> + </developers> +</project> diff --git a/src/build/maven/scala-dotnet-library-pom.xml b/src/build/maven/scala-xml-pom.xml index 007e8be173..629872c2e2 100644 --- a/src/build/maven/scala-dotnet-library-pom.xml +++ b/src/build/maven/scala-xml-pom.xml @@ -1,15 +1,14 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.scala-lang</groupId> - <artifactId>scala-dotnet-library</artifactId> - <version>@VERSION@</version> - <name>Class Library</name> - <packaging>dotnet:library</packaging> - - <url>http://www.scala-lang.org/</url> +<project + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.scala-lang</groupId> + <artifactId>scala-xml</artifactId> + <packaging>jar</packaging> + <version>@VERSION@</version> + <name>Scala XML</name> + <description>XML Library for the Scala Programming Language</description> + <url>http://www.scala-lang.org/</url> <inceptionYear>2002</inceptionYear> <organization> <name>LAMP/EPFL</name> @@ -31,6 +30,11 @@ <system>JIRA</system> <url>https://issues.scala-lang.org/</url> </issueManagement> + <properties> + <info.apiURL>http://www.scala-lang.org/api/@VERSION@/</info.apiURL> + </properties> + <dependencies> + </dependencies> <distributionManagement> <repository> <id>scala-tools.org</id> @@ -41,5 +45,15 @@ <url>@SNAPSHOT_REPOSITORY@</url> <uniqueVersion>false</uniqueVersion> </snapshotRepository> - </distributionManagement> + </distributionManagement> + <developers> + <developer> + <id>lamp</id> + <name>EPFL LAMP</name> + </developer> + <developer> + <id>Typesafe</id> + <name>Typesafe, Inc.</name> + </developer> + </developers> </project> diff --git a/src/build/pack.xml b/src/build/pack.xml index 20c4034107..6b6579ce12 100644 --- a/src/build/pack.xml +++ b/src/build/pack.xml @@ -151,8 +151,9 @@ MAIN DISTRIBUTION PACKAGING </copy> </sequential> </macrodef> - <mvn-copy-lib mvn.artifact.name="jline"/> <mvn-copy-lib mvn.artifact.name="scala-library"/> + <mvn-copy-lib mvn.artifact.name="scala-xml"/> + <mvn-copy-lib mvn.artifact.name="scala-parser-combinators"/> <mvn-copy-lib mvn.artifact.name="scala-reflect"/> <mvn-copy-lib mvn.artifact.name="scala-compiler"/> <mvn-copy-lib mvn.artifact.name="scala-swing"/> @@ -170,8 +171,8 @@ MAIN DISTRIBUTION PACKAGING <fileset dir="${dist.dir}/misc/scala-devel/plugins/"> <filename name="@{mvn.artifact.name}.jar"/> </fileset> - <fileset dir="${src.dir}/build/maven/"> - <filename name="@{mvn.artifact.name}-plugin-pom.xml"/> + <fileset dir="${src.dir}/build/maven/plugins/"> + <filename name="@{mvn.artifact.name}-pom.xml"/> </fileset> </copy> </sequential> @@ -181,12 +182,6 @@ MAIN DISTRIBUTION PACKAGING <target name="pack-maven.srcs" depends="pack-maven.libs"> <!-- Add missing src jars. --> - <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/jline/jline-src.jar" - basedir="${src.dir}/jline/src/main/java"> - <include name="**/*"/> - </jar> - - <!-- Continuations plugin --> <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/plugins/continuations/continuations-src.jar" basedir="${src.dir}/continuations/plugin"> @@ -195,14 +190,18 @@ MAIN DISTRIBUTION PACKAGING </target> <target name="pack-maven.docs" depends="pack-maven.libs, pack-maven.plugins"> - <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/jline/jline-docs.jar" - basedir="${build-docs.dir}/jline"> - <include name="**/*"/> - </jar> <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/scala-library/scala-library-docs.jar" basedir="${build-docs.dir}/library"> <include name="**/*"/> </jar> + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/scala-xml/scala-xml-docs.jar" + basedir="${build-docs.dir}/xml"> + <include name="**/*"/> + </jar> + <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/scala-parser-combinators/scala-parser-combinators-docs.jar" + basedir="${build-docs.dir}/parser-combinators"> + <include name="**/*"/> + </jar> <jar whenmanifestonly="fail" destfile="${dists.dir}/maven/${version.number}/scala-compiler/scala-compiler-docs.jar" basedir="${build-docs.dir}/compiler"> <include name="**/*"/> @@ -243,6 +242,8 @@ MAIN DISTRIBUTION PACKAGING <target name="pack-maven.scripts" depends="pack-maven.latest.unix,pack-maven.latest.win,pack-maven.srcs"> <copy todir="${dists.dir}/maven/${version.number}" + file="${lib-ant.dir}/ant-contrib.jar"/> + <copy todir="${dists.dir}/maven/${version.number}" file="${lib-ant.dir}/maven-ant-tasks-2.1.1.jar"/> <copy tofile="${dists.dir}/maven/${version.number}/build.xml" file="${src.dir}/build/maven/maven-deploy.xml"/> diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala index dd3142127e..a60a2c2306 100644 --- a/src/compiler/scala/reflect/macros/compiler/Errors.scala +++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala @@ -60,8 +60,8 @@ trait Errors extends Traces { (rtpe, atpe) match { case _ if rtpe eq atpe => success() case (TypeRef(_, RepeatedParamClass, rtpe :: Nil), TypeRef(_, RepeatedParamClass, atpe :: Nil)) => check(rtpe, atpe) - case (ExprClassOf(_), TreeType()) => success() - case (TreeType(), ExprClassOf(_)) => success() + case (ExprClassOf(_), TreeType()) if rtpe.prefix =:= atpe.prefix => success() + case (SubtreeType(), ExprClassOf(_)) if rtpe.prefix =:= atpe.prefix => success() case _ => rtpe <:< atpe } } diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala index 78bdf7e132..3507c2a173 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala @@ -42,12 +42,6 @@ trait GenTrees { // 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 global.EmptyTree => - reifyMirrorObject(EmptyTree) - case global.emptyValDef => - mirrorSelect(nme.emptyValDef) - case global.pendingSuperCall => - mirrorSelect(nme.pendingSuperCall) case FreeDef(_, _, _, _, _) => reifyNestedFreeDef(tree) case FreeRef(_, _) => @@ -56,12 +50,8 @@ trait GenTrees { reifyBoundTerm(tree) case BoundType(tree) => reifyBoundType(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) + reifyTreeSyntactically(tree) } // usually we don't reify symbols/types, because they can be re-inferred during subsequent reflective compilation @@ -78,6 +68,21 @@ trait GenTrees { rtree } + def reifyTreeSyntactically(tree: Tree) = tree match { + case global.EmptyTree => + reifyMirrorObject(EmptyTree) + case global.emptyValDef => + mirrorSelect(nme.emptyValDef) + case global.pendingSuperCall => + mirrorSelect(nme.pendingSuperCall) + 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) + } + def reifyModifiers(m: global.Modifiers) = mirrorFactoryCall(nme.Modifiers, mirrorBuildCall(nme.flagsFromBits, reify(m.flags)), reify(m.privateWithin), reify(m.annotations)) diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala index e0570d61f2..de9fec0df5 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala @@ -42,6 +42,9 @@ trait GenUtils { def mirrorBuildCall(name: TermName, args: Tree*): Tree = call("" + nme.UNIVERSE_BUILD_PREFIX + name, args: _*) + def reifyBuildCall(name: TermName, args: Any*) = + mirrorBuildCall(name, args map reify: _*) + def mirrorMirrorCall(name: TermName, args: Tree*): Tree = call("" + nme.MIRROR_PREFIX + name, args: _*) diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index d3cae3d123..30cfec8e2a 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -32,7 +32,7 @@ package object reify { // If we're in the constructor of an object or others don't have easy access to `this`, we have no good way to grab // the class of that object. Instead, we construct an anonymous class and grab his class file, assuming // this is enough to get the correct class loadeer for the class we *want* a mirror for, the object itself. - rClassTree orElse Apply(Select(treeBuilder.makeAnonymousNew(Nil), sn.GetClass), Nil) + rClassTree orElse Apply(Select(gen.mkAnonymousNew(Nil), sn.GetClass), Nil) } // JavaUniverse is defined in scala-reflect.jar, so we must be very careful in case someone reifies stuff having only scala-library.jar on the classpath val isJavaUniverse = JavaUniverseClass != NoSymbol && universe.tpe <:< JavaUniverseClass.toTypeConstructor diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl index 84ccaba749..abf9925ad9 100644 --- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl @@ -115,7 +115,7 @@ if [[ -n "$cygwin$mingw" ]]; then case "$TERM" in rxvt* | xterm*) stty -icanon min 1 -echo - WINDOWS_OPT="-Djline.terminal=scala.tools.jline.UnixTerminal" + WINDOWS_OPT="-Djline.terminal=unix" ;; esac fi diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 603f9af1b4..ea6543bb71 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -103,16 +103,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter) typer.typed(mkCast(tree, pt)) } - /** Trees fresh from the oven, mostly for use by the parser. */ - object treeBuilder extends { - val global: Global.this.type = Global.this - } with TreeBuilder { - def freshName(prefix: String): Name = freshTermName(prefix) - def freshTermName(prefix: String): TermName = currentUnit.freshTermName(prefix) - def freshTypeName(prefix: String): TypeName = currentUnit.freshTypeName(prefix) - def o2p(offset: Int): Position = new OffsetPosition(currentUnit.source, offset) - def r2p(start: Int, mid: Int, end: Int): Position = rangePos(currentUnit.source, start, mid, end) - } + /** A spare instance of TreeBuilder left for backwards compatibility. */ + lazy val treeBuilder: TreeBuilder { val global: Global.this.type } = new syntaxAnalyzer.ParserTreeBuilder /** Fold constants */ object constfold extends { diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index c28a6ba337..ad1977b9aa 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -112,7 +112,6 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { else AppliedTypeTree(Ident(clazz), targs map TypeTree) )) } - def mkSuperInitCall: Select = Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR) def wildcardStar(tree: Tree) = atPos(tree.pos) { Typed(tree, Ident(tpnme.WILDCARD_STAR)) } @@ -255,4 +254,52 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { attrThis, If(cond, Block(syncBody: _*), EmptyTree)) :: stats: _*) + + /** Creates a tree representing new Object { stats }. + * To make sure an anonymous subclass of Object is created, + * if there are no stats, a () is added. + */ + def mkAnonymousNew(stats: List[Tree]): Tree = { + val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats + mkNew(Nil, emptyValDef, stats1, NoPosition, NoPosition) + } + + /** Create positioned tree representing an object creation <new parents { stats } + * @param npos the position of the new + * @param cpos the position of the anonymous class starting with parents + */ + def mkNew(parents: List[Tree], self: ValDef, stats: List[Tree], + npos: Position, cpos: Position): Tree = + if (parents.isEmpty) + mkNew(List(scalaAnyRefConstr), self, stats, npos, cpos) + else if (parents.tail.isEmpty && stats.isEmpty) { + // `Parsers.template` no longer differentiates tpts and their argss + // e.g. `C()` will be represented as a single tree Apply(Ident(C), Nil) + // instead of parents = Ident(C), argss = Nil as before + // this change works great for things that are actually templates + // but in this degenerate case we need to perform postprocessing + val app = treeInfo.dissectApplied(parents.head) + atPos(npos union cpos) { New(app.callee, app.argss) } + } else { + val x = tpnme.ANON_CLASS_NAME + atPos(npos union cpos) { + Block( + List( + atPos(cpos) { + ClassDef( + Modifiers(FINAL), x, Nil, + mkTemplate(parents, self, NoMods, ListOfNil, stats, cpos.focus)) + }), + atPos(npos) { + New( + Ident(x) setPos npos.focus, + Nil) + } + ) + } + } + + def mkSyntheticParam(pname: TermName) = + ValDef(Modifiers(PARAM | SYNTHETIC), pname, TypeTree(), EmptyTree) + } diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 41d89aa3b4..641ab9c279 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -54,77 +54,6 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => case xs :: rest => rest.foldLeft(Apply(gen.mkSuperInitCall, xs): Tree)(Apply.apply) } - /** Generates a template with constructor corresponding to - * - * constrmods (vparams1_) ... (vparams_n) preSuper { presupers } - * extends superclass(args_1) ... (args_n) with mixins { self => body } - * - * This gets translated to - * - * extends superclass with mixins { self => - * presupers' // presupers without rhs - * vparamss // abstract fields corresponding to value parameters - * def <init>(vparamss) { - * presupers - * super.<init>(args) - * } - * body - * } - */ - def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): Template = { - /* Add constructor to template */ - - // create parameters for <init> as synthetic trees. - var vparamss1 = mmap(vparamss) { vd => - atPos(vd.pos.focus) { - val mods = Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) - ValDef(mods withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, vd.rhs.duplicate) - } - } - val (edefs, rest) = body span treeInfo.isEarlyDef - val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef - val gvdefs = evdefs map { - case vdef @ ValDef(_, _, tpt, _) => - copyValDef(vdef)( - // atPos for the new tpt is necessary, since the original tpt might have no position - // (when missing type annotation for ValDef for example), so even though setOriginal modifies the - // position of TypeTree, it would still be NoPosition. That's what the author meant. - tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus), - rhs = EmptyTree - ) - } - val lvdefs = evdefs collect { case vdef: ValDef => copyValDef(vdef)(mods = vdef.mods | PRESUPER) } - - val constrs = { - if (constrMods hasFlag TRAIT) { - if (body forall treeInfo.isInterfaceMember) List() - else List( - atPos(wrappingPos(superPos, lvdefs)) ( - DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), ListOfNil, TypeTree(), Block(lvdefs, Literal(Constant(())))))) - } else { - // convert (implicit ... ) to ()(implicit ... ) if its the only parameter section - if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit) - vparamss1 = List() :: vparamss1 - val superCall = pendingSuperCall // we can't know in advance which of the parents will end up as a superclass - // this requires knowing which of the parents is a type macro and which is not - // and that's something that cannot be found out before typer - // (the type macros aren't in the trunk yet, but there is a plan for them to land there soon) - // this means that we don't know what will be the arguments of the super call - // therefore here we emit a dummy which gets populated when the template is named and typechecked - List( - // TODO: previously this was `wrappingPos(superPos, lvdefs ::: argss.flatten)` - // is it going to be a problem that we can no longer include the `argss`? - atPos(wrappingPos(superPos, lvdefs)) ( - DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant(())))))) - } - } - constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus=false)) - // Field definitions for the class - remove defaults. - val fieldDefs = vparamss.flatten map (vd => copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree)) - - Template(parents, self, gvdefs ::: fieldDefs ::: constrs ::: etdefs ::: rest) - } - /** Construct class definition with given class symbol, value parameters, * supercall arguments and template body. * @@ -143,9 +72,9 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => ) ClassDef(sym, - Template(sym.info.parents map TypeTree, - if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym), - constrMods, vparamss, body, superPos)) + gen.mkTemplate(sym.info.parents map TypeTree, + if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym), + constrMods, vparamss, body, superPos)) } // --- subcomponents -------------------------------------------------- diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index ef5872986c..eb924a811b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -26,13 +26,22 @@ import util.FreshNameCreator * the beginnings of a campaign against this latest incursion by Cutty * McPastington and his army of very similar soldiers. */ -trait ParsersCommon extends ScannersCommon { +trait ParsersCommon extends ScannersCommon { self => val global : Global import global._ def newLiteral(const: Any) = Literal(Constant(const)) def literalUnit = newLiteral(()) + class ParserTreeBuilder extends TreeBuilder { + val global: self.global.type = self.global + def freshName(prefix: String): Name = freshTermName(prefix) + def freshTermName(prefix: String): TermName = currentUnit.freshTermName(prefix) + def freshTypeName(prefix: String): TypeName = currentUnit.freshTypeName(prefix) + def o2p(offset: Int): Position = new OffsetPosition(currentUnit.source, offset) + def r2p(start: Int, mid: Int, end: Int): Position = rangePos(currentUnit.source, start, mid, end) + } + /** This is now an abstract class, only to work around the optimizer: * methods in traits are never inlined. */ @@ -147,6 +156,17 @@ self => def newScanner(): Scanner = new SourceFileScanner(source) + /** Scoping operator used to temporarily look into the future. + * Backs up scanner data before evaluating a block and restores it after. + */ + def lookingAhead[T](body: => T): T = { + val snapshot = (new ScannerData{}).copyFrom(in) + in.nextToken() + val res = body + in copyFrom snapshot + res + } + val in = newScanner() in.init() @@ -290,6 +310,7 @@ self => /** whether a non-continuable syntax error has been seen */ private var lastErrorOffset : Int = -1 + val treeBuilder = new ParserTreeBuilder import treeBuilder.{global => _, _} /** The types of the context bounds of type parameters of the surrounding class @@ -399,7 +420,7 @@ self => def mainParamType = AppliedTypeTree(Ident(tpnme.Array), List(Ident(tpnme.String))) def mainParameter = List(ValDef(Modifiers(Flags.PARAM), nme.argv, mainParamType, EmptyTree)) def mainSetArgv = List(ValDef(NoMods, nme.args, TypeTree(), Ident(nme.argv))) - def mainDef = DefDef(NoMods, nme.main, Nil, List(mainParameter), scalaDot(tpnme.Unit), Block(mainSetArgv, makeAnonymousNew(stmts))) + def mainDef = DefDef(NoMods, nme.main, Nil, List(mainParameter), scalaDot(tpnme.Unit), Block(mainSetArgv, gen.mkAnonymousNew(stmts))) // object Main def moduleName = newTermName(ScriptRunner scriptMain settings) @@ -604,6 +625,8 @@ self => case _ => false } + def isAnnotation: Boolean = in.token == AT + def isLocalModifier: Boolean = in.token match { case ABSTRACT | FINAL | SEALED | IMPLICIT | LAZY => true case _ => false @@ -731,7 +754,7 @@ self => } @inline final def commaSeparated[T](part: => T): List[T] = tokenSeparated(COMMA, sepFirst = false, part) @inline final def caseSeparated[T](part: => T): List[T] = tokenSeparated(CASE, sepFirst = true, part) - @inline final def readAnnots[T](part: => T): List[T] = tokenSeparated(AT, sepFirst = true, part) + def readAnnots(part: => Tree): List[Tree] = tokenSeparated(AT, sepFirst = true, part) /* --------- OPERAND/OPERATOR STACK --------------------------------------- */ @@ -1365,7 +1388,7 @@ self => } else { syntaxErrorOrIncomplete("`*' expected", skipIt = true) } - } else if (in.token == AT) { + } else if (isAnnotation) { t = (t /: annotations(skipNewLines = false))(makeAnnotated) } else { t = atPos(t.pos.startOrPoint, colonPos) { @@ -1501,7 +1524,7 @@ self => val pname = freshName("x$") in.nextToken() val id = atPos(start) (Ident(pname)) - val param = atPos(id.pos.focus){ makeSyntheticParam(pname.toTermName) } + val param = atPos(id.pos.focus){ gen.mkSyntheticParam(pname.toTermName) } placeholderParams = param :: placeholderParams id case LPAREN => @@ -1516,7 +1539,7 @@ self => val tstart = in.offset val (parents, self, stats) = template() val cpos = r2p(tstart, tstart, in.lastOffset max tstart) - makeNew(parents, self, stats, npos, cpos) + gen.mkNew(parents, self, stats, npos, cpos) case _ => syntaxErrorOrIncompleteAnd("illegal start of simple expression", skipIt = true)(errorTermTree) } @@ -1602,13 +1625,16 @@ self => */ def block(): Tree = makeBlock(blockStatSeq()) + def caseClause(): CaseDef = + atPos(in.offset)(makeCaseDef(pattern(), guard(), caseBlock())) + /** {{{ * CaseClauses ::= CaseClause {CaseClause} * CaseClause ::= case Pattern [Guard] `=>' Block * }}} */ def caseClauses(): List[CaseDef] = { - val cases = caseSeparated { atPos(in.offset)(makeCaseDef(pattern(), guard(), caseBlock())) } + val cases = caseSeparated { caseClause() } if (cases.isEmpty) // trigger error if there are no cases accept(CASE) @@ -2050,6 +2076,8 @@ self => /* -------- PARAMETERS ------------------------------------------- */ + def allowTypelessParams = false + /** {{{ * ParamClauses ::= {ParamClause} [[nl] `(' implicit Params `)'] * ParamClause ::= [nl] `(' [Params] `)' @@ -2086,7 +2114,7 @@ self => val name = ident() var bynamemod = 0 val tpt = - if (settings.YmethodInfer && !owner.isTypeName && in.token != COLON) { + if (((settings.YmethodInfer && !owner.isTypeName) || allowTypelessParams) && in.token != COLON) { TypeTree() } else { // XX-METHOD-INFER accept(COLON) @@ -2804,7 +2832,7 @@ self => if (inScalaRootPackage && ScalaValueClassNames.contains(name)) Template(parents0, self, anyvalConstructor :: body) else - Template(anyrefParents(), self, constrMods, vparamss, body, o2p(tstart)) + gen.mkTemplate(anyrefParents(), self, constrMods, vparamss, body, o2p(tstart)) } } @@ -2867,7 +2895,7 @@ self => case IMPORT => in.flushDoc importClause() - case x if x == AT || isTemplateIntro || isModifier => + case x if isAnnotation || isTemplateIntro || isModifier => joinComment(topLevelTmplDef :: Nil) case _ => if (isStatSep) Nil @@ -2923,11 +2951,11 @@ self => if (in.token == IMPORT) { in.flushDoc stats ++= importClause() + } else if (isDefIntro || isModifier || isAnnotation) { + stats ++= joinComment(nonLocalDefOrDcl) } else if (isExprIntro) { in.flushDoc stats += statement(InTemplate) - } else if (isDefIntro || isModifier || in.token == AT) { - stats ++= joinComment(nonLocalDefOrDcl) } else if (!isStatSep) { syntaxErrorOrIncomplete("illegal start of definition", skipIt = true) } @@ -3007,7 +3035,7 @@ self => stats += statement(InBlock) if (in.token != RBRACE && in.token != CASE) acceptStatSep() } - else if (isDefIntro || isLocalModifier || in.token == AT) { + else if (isDefIntro || isLocalModifier || isAnnotation) { if (in.token == IMPLICIT) { val start = in.skipToken() if (isIdent) stats += implicitClosure(start, InBlock) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 2dca39f7a3..03cdead472 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -5,7 +5,7 @@ package scala.tools.nsc package ast.parser -import scala.tools.nsc.util.CharArrayReader +import scala.tools.nsc.util.{ CharArrayReader, CharArrayReaderData } import scala.reflect.internal.util._ import scala.reflect.internal.Chars._ import Tokens._ @@ -71,17 +71,37 @@ trait Scanners extends ScannersCommon { /** the base of a number */ var base: Int = 0 - def copyFrom(td: TokenData) = { + def copyFrom(td: TokenData): this.type = { this.token = td.token this.offset = td.offset this.lastOffset = td.lastOffset this.name = td.name this.strVal = td.strVal this.base = td.base + this } } - abstract class Scanner extends CharArrayReader with TokenData with ScannerCommon { + /** An interface to most of mutable data in Scanner defined in TokenData + * and CharArrayReader (+ next, prev fields) with copyFrom functionality + * to backup/restore data (used by quasiquotes' lookingAhead). + */ + trait ScannerData extends TokenData with CharArrayReaderData { + /** we need one token lookahead and one token history + */ + val next: TokenData = new TokenData{} + val prev: TokenData = new TokenData{} + + def copyFrom(sd: ScannerData): this.type = { + this.next copyFrom sd.next + this.prev copyFrom sd.prev + super[CharArrayReaderData].copyFrom(sd) + super[TokenData].copyFrom(sd) + this + } + } + + abstract class Scanner extends CharArrayReader with TokenData with ScannerData with ScannerCommon { private def isDigit(c: Char) = java.lang.Character isDigit c private var openComments = 0 @@ -194,13 +214,6 @@ trait Scanners extends ScannersCommon { cbuf.clear() } - private class TokenData0 extends TokenData - - /** we need one token lookahead and one token history - */ - val next : TokenData = new TokenData0 - val prev : TokenData = new TokenData0 - /** a stack of tokens which indicates whether line-ends can be statement separators * also used for keeping track of nesting levels. * We keep track of the closing symbol of a region. This can be diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 0ef71fa1b5..666f19851d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -190,50 +190,6 @@ abstract class TreeBuilder { } } - /** Creates a tree representing new Object { stats }. - * To make sure an anonymous subclass of Object is created, - * if there are no stats, a () is added. - */ - def makeAnonymousNew(stats: List[Tree]): Tree = { - val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats - makeNew(Nil, emptyValDef, stats1, NoPosition, NoPosition) - } - - /** Create positioned tree representing an object creation <new parents { stats } - * @param npos the position of the new - * @param cpos the position of the anonymous class starting with parents - */ - def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree], - npos: Position, cpos: Position): Tree = - if (parents.isEmpty) - makeNew(List(scalaAnyRefConstr), self, stats, npos, cpos) - else if (parents.tail.isEmpty && stats.isEmpty) { - // `Parsers.template` no longer differentiates tpts and their argss - // e.g. `C()` will be represented as a single tree Apply(Ident(C), Nil) - // instead of parents = Ident(C), argss = Nil as before - // this change works great for things that are actually templates - // but in this degenerate case we need to perform postprocessing - val app = treeInfo.dissectApplied(parents.head) - atPos(npos union cpos) { New(app.callee, app.argss) } - } else { - val x = tpnme.ANON_CLASS_NAME - atPos(npos union cpos) { - Block( - List( - atPos(cpos) { - ClassDef( - Modifiers(FINAL), x, Nil, - Template(parents, self, NoMods, ListOfNil, stats, cpos.focus)) - }), - atPos(npos) { - New( - Ident(x) setPos npos.focus, - Nil) - } - ) - } - } - /** Create a tree representing an assignment <lhs = rhs> */ def makeAssign(lhs: Tree, rhs: Tree): Tree = lhs match { case Apply(fn, args) => @@ -303,9 +259,6 @@ abstract class TreeBuilder { def makeParam(pname: TermName, tpe: Tree) = ValDef(Modifiers(PARAM), pname, tpe, EmptyTree) - def makeSyntheticParam(pname: TermName) = - ValDef(Modifiers(PARAM | SYNTHETIC), pname, TypeTree(), EmptyTree) - def makeSyntheticTypeParam(pname: TypeName, bounds: Tree) = TypeDef(Modifiers(DEFERRED | SYNTHETIC), pname, Nil, bounds) @@ -467,7 +420,7 @@ abstract class TreeBuilder { val x = freshTermName(prefix) val id = Ident(x) val sel = if (checkExhaustive) id else gen.mkUnchecked(id) - Function(List(makeSyntheticParam(x)), Match(sel, cases)) + Function(List(gen.mkSyntheticParam(x)), Match(sel, cases)) } /** Create tree for case definition <case pat if guard => rhs> */ diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index b5cc89c0c8..0536be92cf 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -9,8 +9,9 @@ package nsc package settings import io.{ AbstractFile, Jar, Path, PlainFile, VirtualDirectory } -import scala.reflect.internal.util.StringOps +import scala.collection.generic.Clearable import scala.io.Source +import scala.reflect.internal.util.StringOps import scala.reflect.{ ClassTag, classTag } /** A mutable Settings object. @@ -542,7 +543,7 @@ class MutableSettings(val errorFn: String => Unit) name: String, val arg: String, descr: String) - extends Setting(name, descr) { + extends Setting(name, descr) with Clearable { type T = List[String] protected var v: T = Nil def appendToValue(str: String) { value ++= List(str) } @@ -555,6 +556,7 @@ class MutableSettings(val errorFn: String => Unit) } override def tryToSetColon(args: List[String]) = tryToSet(args) override def tryToSetFromPropertyValue(s: String) = tryToSet(s.trim.split(',').toList) // used from ide + def clear(): Unit = (v = Nil) def unparse: List[String] = value map (name + ":" + _) withHelpSyntax(name + ":<" + arg + ">") @@ -608,44 +610,49 @@ class MutableSettings(val errorFn: String => Unit) name: String, descr: String, default: String - ) extends Setting(name, mkPhasesHelp(descr, default)) { + ) extends Setting(name, mkPhasesHelp(descr, default)) with Clearable { private[nsc] def this(name: String, descr: String) = this(name, descr, "") type T = List[String] - protected var v: T = Nil - override def value = if (v contains "all") List("all") else super.value - private lazy val (numericValues, stringValues) = - value filterNot (_ == "" ) partition (_ forall (ch => ch.isDigit || ch == '-')) - - /** A little ad-hoc parsing. If a string is not the name of a phase, it can also be: - * a phase id: 5 - * a phase id range: 5-10 (inclusive of both ends) - * a range with no start: -5 means up to and including 5 - * a range with no end: 10- means 10 until completion. - */ - private def stringToPhaseIdTest(s: String): Int => Boolean = (s indexOf '-') match { - case -1 => (_ == s.toInt) - case 0 => (_ <= s.tail.toInt) - case idx => - if (s.last == '-') (_ >= s.init.toInt) - else (s splitAt idx) match { - case (s1, s2) => (id => id >= s1.toInt && id <= s2.tail.toInt) - } - } - private lazy val phaseIdTest: Int => Boolean = - (numericValues map stringToPhaseIdTest) match { - case Nil => _ => false - case fns => fns.reduceLeft((f1, f2) => id => f1(id) || f2(id)) + private[this] var _v: T = Nil + private[this] var _numbs: List[(Int,Int)] = Nil + private[this] var _names: T = Nil + //protected var v: T = Nil + protected def v: T = _v + protected def v_=(t: T): Unit = { + // throws NumberFormat on bad range (like -5-6) + def asRange(s: String): (Int,Int) = (s indexOf '-') match { + case -1 => (s.toInt, s.toInt) + case 0 => (-1, s.tail.toInt) + case i if s.last == '-' => (s.init.toInt, Int.MaxValue) + case i => (s.take(i).toInt, s.drop(i+1).toInt) } + val numsAndStrs = t filter (_.nonEmpty) partition (_ forall (ch => ch.isDigit || ch == '-')) + _numbs = numsAndStrs._1 map asRange + _names = numsAndStrs._2 + _v = t + } + override def value = if (v contains "all") List("all") else super.value // i.e., v + private def numericValues = _numbs + private def stringValues = _names + private def phaseIdTest(i: Int): Boolean = numericValues exists (_ match { + case (min, max) => min <= i && i <= max + }) def tryToSet(args: List[String]) = if (default == "") errorAndValue("missing phase", None) - else { tryToSetColon(List(default)) ; Some(args) } + else tryToSetColon(List(default)) map (_ => args) + + override def tryToSetColon(args: List[String]) = try { + args match { + case Nil => if (default == "") errorAndValue("missing phase", None) + else tryToSetColon(List(default)) + case xs => value = (value ++ xs).distinct.sorted ; Some(Nil) + } + } catch { case _: NumberFormatException => None } + + def clear(): Unit = (v = Nil) - override def tryToSetColon(args: List[String]) = args match { - case Nil => if (default == "") errorAndValue("missing phase", None) else tryToSetColon(List(default)) - case xs => value = (value ++ xs).distinct.sorted ; Some(Nil) - } // we slightly abuse the usual meaning of "contains" here by returning // true if our phase list contains "all", regardless of the incoming argument def contains(phName: String) = doAllPhases || containsName(phName) diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 321baba562..32f0571e83 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -166,6 +166,7 @@ trait ScalaSettings extends AbsScalaSettings val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.") val Ymemberpos = StringSetting ("-Yshow-member-pos", "output style", "Show start and end positions of members", "") withPostSetHook (_ => Yrangepos.value = true) val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") + val Ymacronoexpand = BooleanSetting ("-Ymacro-no-expand", "Don't expand macros. Might be useful for scaladoc and presentation compiler, but will crash anything which uses macros and gets past typer.") val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") val Yreploutdir = StringSetting ("-Yrepl-outdir", "path", "Write repl-generated classfiles to given output directory (use \"\" to generate a temporary dir)" , "") val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") @@ -190,6 +191,7 @@ trait ScalaSettings extends AbsScalaSettings val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.") val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.") val Ypatmatdebug = BooleanSetting("-Ypatmat-debug", "Trace pattern matching translation.") + val Yquasiquotedebug = BooleanSetting("-Yquasiquote-debug", "Trace quasiquote-related activities.") /** Groups of Settings. */ diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 672d9d232a..56ec49e962 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -208,6 +208,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { companion.moduleClass.newMethod(extensionName, origMeth.pos, origMeth.flags & ~OVERRIDE & ~PROTECTED | FINAL) setAnnotations origMeth.annotations ) + origMeth.removeAnnotation(TailrecClass) // it's on the extension method, now. companion.info.decls.enter(extensionMeth) } @@ -221,15 +222,16 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { val extensionParams = allParameters(extensionMono) val extensionThis = gen.mkAttributedStableRef(thiz setPos extensionMeth.pos) - val extensionBody = ( - rhs + val extensionBody: Tree = { + val tree = rhs .substituteSymbols(origTpeParams, extensionTpeParams) .substituteSymbols(origParams, extensionParams) .substituteThis(origThis, extensionThis) .changeOwner(origMeth -> extensionMeth) - ) + new SubstututeRecursion(origMeth, extensionMeth, unit).transform(tree) + } - // Record the extension method ( FIXME: because... ? ) + // Record the extension method. Later, in `Extender#transformStats`, these will be added to the companion object. extensionDefs(companion) += atPos(tree.pos)(DefDef(extensionMeth, extensionBody)) // These three lines are assembling Foo.bar$extension[T1, T2, ...]($this) @@ -264,4 +266,33 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { stat } } + + final class SubstututeRecursion(origMeth: Symbol, extensionMeth: Symbol, + unit: CompilationUnit) extends TypingTransformer(unit) { + override def transform(tree: Tree): Tree = tree match { + // SI-6574 Rewrite recursive calls against the extension method so they can + // be tail call optimized later. The tailcalls phases comes before + // erasure, which performs this translation more generally at all call + // sites. + // + // // Source + // class C[C] { def meth[M](a: A) = { { <expr>: C[C'] }.meth[M'] } } + // + // // Translation + // class C[C] { def meth[M](a: A) = { { <expr>: C[C'] }.meth[M'](a1) } } + // object C { def meth$extension[M, C](this$: C[C], a: A) + // = { meth$extension[M', C']({ <expr>: C[C'] })(a1) } } + case treeInfo.Applied(sel @ Select(qual, _), targs, argss) if sel.symbol == origMeth => + import gen.CODE._ + localTyper.typedPos(tree.pos) { + val allArgss = List(qual) :: argss + val origThis = extensionMeth.owner.companionClass + val baseType = qual.tpe.baseType(origThis) + val allTargs = targs.map(_.tpe) ::: baseType.typeArgs + val fun = gen.mkAttributedTypeApply(THIS(extensionMeth.owner), extensionMeth, allTargs) + allArgss.foldLeft(fun)(Apply(_, _)) + } + case _ => super.transform(tree) + } + } } diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index e0b1d9ea80..1c44e86aca 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -119,7 +119,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { * @param mixinClass The mixin class that produced the superaccessor */ private def rebindSuper(base: Symbol, member: Symbol, mixinClass: Symbol): Symbol = - exitingPickler { + exitingSpecialize { var bcs = base.info.baseClasses.dropWhile(mixinClass != _).tail var sym: Symbol = NoSymbol debuglog("starting rebindsuper " + base + " " + member + ":" + member.tpe + diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index a3ab948171..81f5545695 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -697,7 +697,7 @@ trait ContextErrors { protected def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = { def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg macroLogLite("macro expansion has failed: %s".format(msgForLog)) - if (msg != null) context.error(pos, msg) // issueTypeError(PosAndMsgTypeError(..)) won't work => swallows positions + if (msg != null) context.error(if (pos.isDefined) pos else expandee.pos, msg) // issueTypeError(PosAndMsgTypeError(..)) won't work => swallows positions setError(expandee) throw MacroExpansionException } @@ -741,7 +741,7 @@ trait ContextErrors { try { // [Eugene] is there a better way? // [Paul] See Exceptional.scala and Origins.scala. - val relevancyThreshold = realex.getStackTrace().indexWhere(_.getMethodName endsWith "macroExpand1") + val relevancyThreshold = realex.getStackTrace().indexWhere(_.getMethodName endsWith "macroExpandWithRuntime") if (relevancyThreshold == -1) None else { var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1) @@ -782,13 +782,16 @@ trait ContextErrors { } def MacroExpansionHasInvalidTypeError(expandee: Tree, expanded: Any) = { + def isUnaffiliatedExpr = expanded.isInstanceOf[scala.reflect.api.Exprs#Expr[_]] + def isUnaffiliatedTree = expanded.isInstanceOf[scala.reflect.api.Trees#TreeApi] val expected = "expr or tree" - val isPathMismatch = expanded != null && expanded.isInstanceOf[scala.reflect.api.Exprs#Expr[_]] + val actual = if (isUnaffiliatedExpr) "an expr" else if (isUnaffiliatedTree) "a tree" else "unexpected" + val isPathMismatch = expanded != null && (isUnaffiliatedExpr || isUnaffiliatedTree) macroExpansionError(expandee, s"macro must return a compiler-specific $expected; returned value is " + ( if (expanded == null) "null" - else if (isPathMismatch) s" $expected, but it doesn't belong to this compiler" - else " of " + expanded.getClass + else if (isPathMismatch) s"$actual, but it doesn't belong to this compiler's universe" + else "of " + expanded.getClass )) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 1f4ff7cc2d..1f8f13ae02 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -99,22 +99,13 @@ trait Contexts { self: Analyzer => // there must be a scala.xml package when xml literals were parsed in this unit if (unit.hasXml && ScalaXmlPackage == NoSymbol) - unit.error(unit.firstXmlPos, "XML literals may only be used if the package scala.xml is present in the compilation classpath.") - - // TODO: remove the def below and drop `|| predefDefinesDollarScope` in the condition for `contextWithXML` - // as soon as 2.11.0-M4 is released and used as STARR (and $scope is no longer defined in Predef) - // Until then, to allow compiling quick with pre-2.11.0-M4 STARR, - // which relied on Predef defining `val $scope`, we've left it in place. - // Since the new scheme also imports $scope (as an alias for scala.xml.TopScope), - // we must check whether it is still there and not import the alias to avoid ambiguity. - // (All of this is only necessary to compile the full quick stage with STARR. - // if using locker, Predef.$scope is no longer needed.) - def predefDefinesDollarScope = definitions.getMemberIfDefined(PredefModule, nme.dollarScope) != NoSymbol - - // hack for the old xml library (detected by looking for scala.xml.TopScope, which needs to be in scope as $scope) - // import scala.xml.{TopScope => $scope} + unit.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see https://github.com/scala/scala/wiki/Scala-2.11#xml.") + + // scala-xml needs `scala.xml.TopScope` to be in scope globally as `$scope` + // We detect `scala-xml` by looking for `scala.xml.TopScope` and + // inject the equivalent of `import scala.xml.{TopScope => $scope}` val contextWithXML = - if (!unit.hasXml || ScalaXmlTopScope == NoSymbol || predefDefinesDollarScope) rootImportsContext + if (!unit.hasXml || ScalaXmlTopScope == NoSymbol) rootImportsContext else rootImportsContext.make(gen.mkImport(ScalaXmlPackage, nme.TopScope, nme.dollarScope)) val c = contextWithXML.make(tree, unit = unit) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 86ba3d2164..6b9537e27d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -142,7 +142,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { case Literal(Constant(s: String)) => s case Literal(Constant(d: Double)) => d case Literal(Constant(b: Boolean)) => b - case Literal(Constant(i: Int)) => new Fingerprint(i) + case Literal(Constant(i: Int)) => Fingerprint(i) } def pickle(macroImplRef: Tree): Tree = { @@ -464,9 +464,9 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { /** Describes the role that the macro expandee is performing. */ - type MacroRole = String - final def APPLY_ROLE: MacroRole = "APPLY_ROLE" - private val roleNames = Map(APPLY_ROLE -> "apply") + type MacroRole = scala.tools.nsc.typechecker.MacroRole + final def APPLY_ROLE = MacroRole.Apply + final def UNAPPLY_ROLE = MacroRole.Unapply /** Performs macro expansion: * @@ -482,9 +482,10 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { * ========= Macro expansion ========= * * First of all `macroExpandXXX`: - * 1) If necessary desugars the `expandee` to fit into `macroExpand1` + * 1) If necessary desugars the `expandee` to fit into the default expansion scheme + * that is understood by `macroExpandWithRuntime` / `macroExpandWithoutRuntime` * - * Then `macroExpand1`: + * Then `macroExpandWithRuntime`: * 2) Checks whether the expansion needs to be delayed * 3) Loads macro implementation using `macroMirror` * 4) Synthesizes invocation arguments for the macro implementation @@ -532,26 +533,41 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { def summary() = s"expander = $this, expandee = ${showDetailed(expandee)}, desugared = ${if (expandee == desugared) () else showDetailed(desugared)}" if (macroDebugVerbose) println(s"macroExpand: ${summary()}") assert(allowExpandee(expandee), summary()) + linkExpandeeAndDesugared(expandee, desugared, role) val start = if (Statistics.canEnable) Statistics.startTimer(macroExpandNanos) else null if (Statistics.canEnable) Statistics.incCounter(macroExpandCount) try { - linkExpandeeAndDesugared(expandee, desugared, role) - macroExpand1(typer, desugared) match { - case Success(expanded) => - if (allowExpanded(expanded)) { - // also see http://groups.google.com/group/scala-internals/browse_thread/thread/492560d941b315cc - val expanded1 = try onSuccess(duplicateAndKeepPositions(expanded)) finally popMacroContext() - if (!hasMacroExpansionAttachment(expanded1)) linkExpandeeAndExpanded(expandee, expanded1) - if (allowResult(expanded1)) expanded1 else onFailure(expanded) - } else { - typer.TyperErrorGen.MacroInvalidExpansionError(expandee, roleNames(role), allowedExpansions) - onFailure(expanded) + withInfoLevel(nodePrinters.InfoLevel.Quiet) { // verbose printing might cause recursive macro expansions + if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { + val reason = if (expandee.symbol.isErroneous) "not found or incompatible macro implementation" else "erroneous arguments" + macroLogVerbose(s"cancelled macro expansion because of $reason: $expandee") + onFailure(typer.infer.setError(expandee)) + } else try { + val expanded = { + val runtime = macroRuntime(expandee.symbol) + if (runtime != null) macroExpandWithRuntime(typer, expandee, runtime) + else macroExpandWithoutRuntime(typer, expandee) + } + expanded match { + case Success(expanded) => + if (allowExpanded(expanded)) { + // also see http://groups.google.com/group/scala-internals/browse_thread/thread/492560d941b315cc + val expanded1 = try onSuccess(duplicateAndKeepPositions(expanded)) finally popMacroContext() + if (!hasMacroExpansionAttachment(expanded1)) linkExpandeeAndExpanded(expandee, expanded1) + if (allowResult(expanded1)) expanded1 else onFailure(expanded) + } else { + typer.TyperErrorGen.MacroInvalidExpansionError(expandee, role.name, allowedExpansions) + onFailure(expanded) + } + case Fallback(fallback) => onFallback(fallback) + case Delayed(delayed) => onDelayed(delayed) + case Skipped(skipped) => onSkipped(skipped) + case Failure(failure) => onFailure(failure) } - case Fallback(fallback) => onFallback(fallback) - case Delayed(delayed) => onDelayed(delayed) - case Skipped(skipped) => onSkipped(skipped) - case Failure(failure) => onFailure(failure) + } catch { + case typer.TyperErrorGen.MacroExpansionException => onFailure(expandee) + } } } finally { if (Statistics.canEnable) Statistics.stopTimer(macroExpandNanos, start) @@ -622,8 +638,21 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { expander(expandee) } - /** Captures statuses of macro expansions performed by `macroExpand1'. + /** Expands a term macro used in unapply role as `u.Quasiquote(StringContext("", "")).q.unapply(x)` in `case q"$x" => ...`. + * @see MacroExpander */ + def macroExpandUnapply(typer: Typer, original: Tree, fun: Tree, unapply: Symbol, args: List[Tree], mode: Mode, pt: Type) = { + val expandee = treeCopy.Apply(original, gen.mkAttributedSelect(fun, unapply), args) + object expander extends TermMacroExpander(UNAPPLY_ROLE, typer, expandee, mode, pt) { + override def allowedExpansions: String = "unapply trees" + override def allowExpandee(expandee: Tree) = expandee.isInstanceOf[Apply] + private def unsupported(what: String) = abort("unapply macros currently don't support " + what) + override def onFallback(fallback: Tree) = unsupported("fallback") + override def onDelayed(delayed: Tree) = unsupported("advanced interaction with type inference") + } + expander(original) + } + private sealed abstract class MacroStatus(val result: Tree) private case class Success(expanded: Tree) extends MacroStatus(expanded) private case class Fallback(fallback: Tree) extends MacroStatus(fallback) { currentRun.seenMacroExpansionsFallingBack = true } @@ -632,28 +661,6 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { private case class Failure(failure: Tree) extends MacroStatus(failure) private def Delay(expanded: Tree) = Delayed(expanded) private def Skip(expanded: Tree) = Skipped(expanded) - private def Cancel(expandee: Tree) = 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): MacroStatus = { - // verbose printing might cause recursive macro expansions, so I'm shutting it down here - withInfoLevel(nodePrinters.InfoLevel.Quiet) { - if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { - val reason = if (expandee.symbol.isErroneous) "not found or incompatible macro implementation" else "erroneous arguments" - macroLogVerbose(s"cancelled macro expansion because of $reason: $expandee") - Cancel(typer.infer.setError(expandee)) - } - else try { - val runtime = macroRuntime(expandee.symbol) - if (runtime != null) macroExpandWithRuntime(typer, expandee, runtime) - else macroExpandWithoutRuntime(typer, expandee) - } catch { - case typer.TyperErrorGen.MacroExpansionException => Failure(expandee) - } - } - } /** Expands a macro when a runtime (i.e. the macro implementation) can be successfully loaded * Meant for internal use within the macro infrastructure, don't use it elsewhere. @@ -804,7 +811,7 @@ object MacrosStats { val macroExpandNanos = Statistics.newSubTimer("time spent in macroExpand", typerNanos) } -class Fingerprint(val value: Int) extends AnyVal { +class Fingerprint private[Fingerprint](val value: Int) extends AnyVal { def paramPos = { assert(isTag, this); value } def isTag = value >= 0 def isOther = this == Other @@ -819,8 +826,18 @@ class Fingerprint(val value: Int) extends AnyVal { } object Fingerprint { + def apply(value: Int) = new Fingerprint(value) def Tagged(tparamPos: Int) = new Fingerprint(tparamPos) val Other = new Fingerprint(-1) val LiftedTyped = new Fingerprint(-2) val LiftedUntyped = new Fingerprint(-3) } + +class MacroRole private[MacroRole](val name: String) extends AnyVal { + override def toString = name +} + +object MacroRole { + val Apply = new MacroRole("apply") + val Unapply = new MacroRole("unapply") +} diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index c616ded704..bbd51b5564 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -100,15 +100,17 @@ trait StdAttachments { /** Determines whether a tree should not be expanded, because someone has put SuppressMacroExpansionAttachment on it or one of its children. */ def isMacroExpansionSuppressed(tree: Tree): Boolean = - if (tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined) true - else tree match { - // we have to account for the fact that during typechecking an expandee might become wrapped, - // i.e. surrounded by an inferred implicit argument application or by an inferred type argument application. - // in that case the expandee itself will no longer be suppressed and we need to look at the core - case Apply(fn, _) => isMacroExpansionSuppressed(fn) - case TypeApply(fn, _) => isMacroExpansionSuppressed(fn) - case _ => false - } + ( settings.Ymacronoexpand.value // SI-6812 + || tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined + || (tree match { + // we have to account for the fact that during typechecking an expandee might become wrapped, + // i.e. surrounded by an inferred implicit argument application or by an inferred type argument application. + // in that case the expandee itself will no longer be suppressed and we need to look at the core + case Apply(fn, _) => isMacroExpansionSuppressed(fn) + case TypeApply(fn, _) => isMacroExpansionSuppressed(fn) + case _ => false + }) + ) /** After being synthesized by the parser, primary constructors aren't fully baked yet. * A call to super in such constructors is just a fill-me-in-later dummy resolved later @@ -154,4 +156,4 @@ trait StdAttachments { * because someone has put MacroImplRefAttachment on it. */ def isMacroImplRef(tree: Tree): Boolean = tree.attachments.get[MacroImplRefAttachment.type].isDefined -}
\ No newline at end of file +} diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 353e8e4810..1a9a30c2ad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2797,16 +2797,11 @@ trait Typers extends Adaptations with Tags { if (numVparams > definitions.MaxFunctionArity) return MaxFunctionArityError(fun) - def decompose(pt: Type): (Symbol, List[Type], Type) = - if ((isFunctionType(pt) || (pt.typeSymbol == PartialFunctionClass && numVparams == 1 && fun.body.isInstanceOf[Match])) && // see bug901 for a reason why next conditions are needed - ( pt.dealiasWiden.typeArgs.length - 1 == numVparams - || fun.vparams.exists(_.tpt.isEmpty) - )) - (pt.typeSymbol, pt.dealiasWiden.typeArgs.init, pt.dealiasWiden.typeArgs.last) - else - (FunctionClass(numVparams), fun.vparams map (x => NoType), WildcardType) - - val (clazz, argpts, respt) = decompose(pt) + val FunctionSymbol = FunctionClass(numVparams) + val (argpts, respt) = pt baseType FunctionSymbol match { + case TypeRef(_, FunctionSymbol, args :+ res) => (args, res) + case _ => (fun.vparams map (_ => NoType), WildcardType) + } if (argpts.lengthCompare(numVparams) != 0) WrongNumberOfParametersError(fun, argpts) else { @@ -2856,7 +2851,7 @@ trait Typers extends Adaptations with Tags { val formals = vparamSyms map (_.tpe) val body1 = typed(fun.body, respt) val restpe = packedType(body1, fun.symbol).deconst.resultType - val funtpe = appliedType(clazz, formals :+ restpe: _*) + val funtpe = appliedType(FunctionSymbol, formals :+ restpe: _*) treeCopy.Function(fun, vparams, body1) setType funtpe } @@ -3385,8 +3380,9 @@ trait Typers extends Adaptations with Tags { if (!tree.isErrorTyped) setError(tree) else tree // @H change to setError(treeCopy.Apply(tree, fun, args)) - case otpe if mode.inPatternMode && unapplyMember(otpe).exists => - doTypedUnapply(tree, fun0, fun, args, mode, pt) + case ExtractorType(unapply) if mode.inPatternMode => + if (unapply == QuasiquoteClass_api_unapply) macroExpandUnapply(this, tree, fun, unapply, args, mode, pt) + else doTypedUnapply(tree, fun0, fun, args, mode, pt) case _ => if (treeInfo.isMacroApplication(tree)) duplErrorTree(MacroTooManyArgumentListsError(tree, fun.symbol)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index af3f772f79..47c859bb5c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -51,6 +51,14 @@ trait Unapplies extends ast.TreeDSL case NoSymbol => tp member nme.unapplySeq case unapp => unapp } + + object ExtractorType { + def unapply(tp: Type): Option[Symbol] = { + val member = unapplyMember(tp) + if (member.exists) Some(member) else None + } + } + /** returns unapply member's parameter type. */ def unapplyParameterType(extractor: Symbol) = extractor.tpe.params match { case p :: Nil => p.tpe.typeSymbol @@ -142,7 +150,7 @@ trait Unapplies extends ast.TreeDSL ModuleDef( Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin), cdef.name.toTermName, - Template(parents, emptyValDef, NoMods, Nil, body, cdef.impl.pos.focus)) + gen.mkTemplate(parents, emptyValDef, NoMods, Nil, body, cdef.impl.pos.focus)) } private val caseMods = Modifiers(SYNTHETIC | CASE) diff --git a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala index 5c6f525c6f..f116e4af34 100644 --- a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala @@ -8,15 +8,7 @@ package util import scala.reflect.internal.Chars._ -abstract class CharArrayReader { self => - - val buf: Array[Char] - - def decodeUni: Boolean = true - - /** An error routine to call on bad unicode escapes \\uxxxx. */ - protected def error(offset: Int, msg: String): Unit - +trait CharArrayReaderData { /** the last read character */ var ch: Char = _ @@ -29,7 +21,26 @@ abstract class CharArrayReader { self => /** The start offset of the line before the current one */ var lastLineStartOffset: Int = 0 - private var lastUnicodeOffset = -1 + protected var lastUnicodeOffset = -1 + + def copyFrom(cd: CharArrayReaderData): this.type = { + this.ch = cd.ch + this.charOffset = cd.charOffset + this.lineStartOffset = cd.lineStartOffset + this.lastLineStartOffset = cd.lastLineStartOffset + this.lastUnicodeOffset = cd.lastUnicodeOffset + this + } +} + +abstract class CharArrayReader extends CharArrayReaderData { self => + + val buf: Array[Char] + + def decodeUni: Boolean = true + + /** An error routine to call on bad unicode escapes \\uxxxx. */ + protected def error(offset: Int, msg: String): Unit /** Is last character a unicode escape \\uxxxx? */ def isUnicodeEscape = charOffset == lastUnicodeOffset diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala index 5a0ff4f6db..ad1d4c896b 100644 --- a/src/compiler/scala/tools/reflect/FastTrack.scala +++ b/src/compiler/scala/tools/reflect/FastTrack.scala @@ -5,7 +5,7 @@ import scala.reflect.reify.Taggers import scala.tools.nsc.typechecker.{ Analyzer, Macros } import scala.reflect.runtime.Macros.currentMirror import scala.reflect.api.Universe -import scala.reflect.macros.compiler.DefaultMacroCompiler +import scala.tools.reflect.quasiquotes.{ Quasiquotes => QuasiquoteImpls } /** Optimizes system macro expansions by hardwiring them directly to their implementations * bypassing standard reflective load and invoke to avoid the overhead of Java/Scala reflection. @@ -22,6 +22,8 @@ trait FastTrack { new { val c: c0.type = c0 } with Taggers private implicit def context2macroimplementations(c0: MacroContext): MacroImplementations { val c: c0.type } = new { val c: c0.type = c0 } with MacroImplementations + private implicit def context2quasiquote(c0: MacroContext): QuasiquoteImpls { val c: c0.type } = + new { val c: c0.type = c0 } with QuasiquoteImpls private def make(sym: Symbol)(pf: PartialFunction[Applied, MacroContext => Tree]) = sym -> new FastTrackEntry(pf) @@ -41,6 +43,8 @@ trait FastTrack { make( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) }, make( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }, make( StringContext_f) { case Applied(Select(Apply(_, ps), _), _, args) => c => c.macro_StringInterpolation_f(ps, args.flatten, c.expandee.pos) }, - make(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree } + make(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree }, + make( QuasiquoteClass_api_apply) { case _ => _.expandQuasiquote }, + make(QuasiquoteClass_api_unapply) { case _ => _.expandQuasiquote } ) } diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index c53d10bd87..afaca3396c 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -217,7 +217,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => val moduledef = ModuleDef( obj, - Template( + gen.mkTemplate( List(TypeTree(ObjectTpe)), emptyValDef, NoMods, diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala new file mode 100644 index 0000000000..9d171d52d2 --- /dev/null +++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala @@ -0,0 +1,187 @@ +package scala.tools.reflect +package quasiquotes + +import scala.collection.{immutable, mutable} +import scala.reflect.internal.Flags._ + +class Cardinality private[Cardinality](val value: Int) extends AnyVal { + def pred = { assert(value - 1 >= 0); new Cardinality(value - 1) } + def succ = new Cardinality(value + 1) + override def toString = if (value == 0) "no dots" else "." * (value + 1) +} + +object Cardinality { + val NoDot = new Cardinality(0) + val DotDot = new Cardinality(1) + val DotDotDot = new Cardinality(2) + object Dot { def unapply(card: Cardinality) = card != NoDot } + def parseDots(part: String) = { + if (part.endsWith("...")) (part.stripSuffix("..."), DotDotDot) + else if (part.endsWith("..")) (part.stripSuffix(".."), DotDot) + else (part, NoDot) + } +} + +/** Defines abstractions that provide support for splicing into Scala syntax. + */ +trait Holes { self: Quasiquotes => + import global._ + import Cardinality._ + import definitions._ + import universeTypes._ + + /** Location characterizes a kind of a non-terminal in Scala syntax where something is going to be spliced. + * A location is typically associated with a type of the things that can be spliced there. + * Associated type might be different from an actual tpe of a splicee due to lifting. + * This is the first pillar of modularity in the quasiquote reifier. + */ + sealed abstract class Location(val tpe: Type) + case object UnknownLocation extends Location(NoType) + case class TreeLocation(override val tpe: Type) extends Location(tpe) + case object NameLocation extends Location(nameType) + case object ModsLocation extends Location(modsType) + case object FlagsLocation extends Location(flagsType) + case object SymbolLocation extends Location(symbolType) + case class IterableLocation(card: Cardinality, sublocation: TreeLocation) extends Location(NoType) { + override val tpe = { + def loop(n: Cardinality, tpe: Type): Type = + if (n == NoDot) tpe + else appliedType(IterableClass.toType, List(loop(n.pred, tpe))) + loop(card, sublocation.tpe) + } + } + + /** Hole type describes location, cardinality and a pre-reification routine associated with a hole. + * An interesting thing about HoleType is that it can be completely inferred from the type of the splicee. + * This is the second pillar of modularity in the quasiquote reifier. + */ + case class HoleType(preprocessor: Tree => Tree, location: Location, cardinality: Cardinality) { + def makeHole(tree: Tree) = Hole(preprocessor(tree), location, cardinality) + } + object HoleType { + def unapply(tpe: Type): Option[HoleType] = tpe match { + case NativeType(holeTpe) => Some(holeTpe) + case LiftableType(holeTpe) => Some(holeTpe) + case IterableTreeType(holeTpe) => Some(holeTpe) + case IterableLiftableType(holeTpe) => Some(holeTpe) + case _ => None + } + + trait HoleTypeExtractor { + def unapply(tpe: Type): Option[HoleType] = { + for { + preprocessor <- this.preprocessor(tpe) + location <- this.location(tpe) + cardinality <- Some(this.cardinality(tpe)) + } yield HoleType(preprocessor, location, cardinality) + } + def preprocessor(tpe: Type): Option[Tree => Tree] + def location(tpe: Type): Option[Location] + def cardinality(tpe: Type): Cardinality = parseCardinality(tpe)._1 + + def lifter(tpe: Type): Option[Tree => Tree] = { + val lifterTpe = appliedType(LiftableClass.toType, List(tpe)) + val lifter = c.inferImplicitValue(lifterTpe, silent = true) + if (lifter != EmptyTree) Some(tree => { + val lifted = Apply(lifter, List(u, tree)) + val targetType = Select(u, tpnme.Tree) + atPos(tree.pos)(TypeApply(Select(lifted, nme.asInstanceOf_), List(targetType))) + }) else None + } + + def iterator(tpe: Type)(elementTransform: Tree => Tree): Option[Tree => Tree] = { + def reifyIterable(tree: Tree, n: Cardinality): Tree = { + def loop(tree: Tree, n: Cardinality) = + if (n == NoDot) elementTransform(tree) + else { + val x: TermName = c.freshName() + val wrapped = reifyIterable(Ident(x), n.pred) + val xToWrapped = Function(List(ValDef(Modifiers(PARAM), x, TypeTree(), EmptyTree)), wrapped) + Select(Apply(Select(tree, nme.map), List(xToWrapped)), nme.toList) + } + if (tree.tpe != null && (tree.tpe <:< listTreeType || tree.tpe <:< listListTreeType)) tree + else atPos(tree.pos)(loop(tree, n)) + } + val (card, elementTpe) = parseCardinality(tpe) + if (card != NoDot) Some(reifyIterable(_, card)) else None + } + } + + object NativeType extends HoleTypeExtractor { + def preprocessor(tpe: Type) = Some(identity) + def location(tpe: Type) = { + if (tpe <:< treeType) Some(TreeLocation(tpe)) + else if (tpe <:< nameType) Some(NameLocation) + else if (tpe <:< modsType) Some(ModsLocation) + else if (tpe <:< flagsType) Some(FlagsLocation) + else if (tpe <:< symbolType) Some(SymbolLocation) + else None + } + } + + object LiftableType extends HoleTypeExtractor { + def preprocessor(tpe: Type) = lifter(tpe) + def location(tpe: Type) = Some(TreeLocation(treeType)) + } + + object IterableTreeType extends HoleTypeExtractor { + def preprocessor(tpe: Type) = iterator(tpe)(identity) + def location(tpe: Type) = { + val (card, elementTpe) = parseCardinality(tpe) + if (card != NoDot && elementTpe <:< treeType) Some(IterableLocation(card, TreeLocation(elementTpe))) + else None + } + } + + object IterableLiftableType extends HoleTypeExtractor { + def preprocessor(tpe: Type) = { + val (_, elementTpe) = parseCardinality(tpe) + for { + lifter <- this.lifter(elementTpe) + iterator <- this.iterator(tpe)(lifter) + } yield iterator + } + def location(tpe: Type) = Some(IterableLocation(cardinality(tpe), TreeLocation(treeType))) + } + } + + /** Hole encapsulates information about splices in quasiquotes. + * It packs together a cardinality of a splice, a splicee (possibly preprocessed) + * and the description of the location in Scala syntax where the splicee can be spliced. + * This is the third pillar of modularity in the quasiquote reifier. + */ + case class Hole(tree: Tree, location: Location, cardinality: Cardinality) + + object Hole { + def apply(splicee: Tree, holeCard: Cardinality): Hole = { + if (splicee.tpe == null) return new Hole(splicee, UnknownLocation, holeCard) + val (spliceeCard, elementTpe) = parseCardinality(splicee.tpe) + def cantSplice() = { + val holeCardMsg = if (holeCard != NoDot) s" with $holeCard" else "" + val action = "splice " + splicee.tpe + holeCardMsg + val suggestCard = holeCard != spliceeCard || holeCard != NoDot + val spliceeCardMsg = if (holeCard != spliceeCard && spliceeCard != NoDot) s"using $spliceeCard" else "omitting the dots" + val cardSuggestion = if (suggestCard) spliceeCardMsg else "" + def canBeLifted(tpe: Type) = HoleType.LiftableType.unapply(tpe).nonEmpty + val suggestLifting = (holeCard == NoDot || spliceeCard != NoDot) && !(elementTpe <:< treeType) && !canBeLifted(elementTpe) + val liftedTpe = if (holeCard != NoDot) elementTpe else splicee.tpe + val liftSuggestion = if (suggestLifting) s"providing an implicit instance of Liftable[$liftedTpe]" else "" + val advice = List(cardSuggestion, liftSuggestion).filter(_ != "").mkString(" or ") + c.abort(splicee.pos, s"Can't $action, consider $advice") + } + val holeTpe = splicee.tpe match { + case _ if holeCard != spliceeCard => cantSplice() + case HoleType(holeTpe) => holeTpe + case _ => cantSplice() + } + holeTpe.makeHole(splicee) + } + } + + def parseCardinality(tpe: Type): (Cardinality, Type) = { + if (tpe != null && isIterableType(tpe)) { + val (card, innerTpe) = parseCardinality(tpe.typeArguments.head) + (card.succ, innerTpe) + } else (NoDot, tpe) + } +}
\ No newline at end of file diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala new file mode 100644 index 0000000000..9a6ba56c18 --- /dev/null +++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala @@ -0,0 +1,134 @@ +package scala.tools.reflect +package quasiquotes + +import scala.tools.nsc.ast.parser.{Parsers => ScalaParser} +import scala.tools.nsc.ast.parser.Tokens._ +import scala.compat.Platform.EOL +import scala.reflect.internal.util.{BatchSourceFile, SourceFile} +import scala.collection.mutable.ListBuffer + +/** Builds upon the vanilla Scala parser and teams up together with Placeholders.scala to emulate holes. + * A principled solution to splicing into Scala syntax would be a parser that natively supports holes. + * Unfortunately, that's outside of our reach in Scala 2.11, so we have to emulate. + */ +trait Parsers { self: Quasiquotes => + import global._ + + abstract class Parser extends { + val global: self.global.type = self.global + } with ScalaParser { + /** Wraps given code to obtain a desired parser mode. + * This way we can just re-use standard parser entry point. + */ + def wrapCode(code: String): String = + s"object wrapper { self => $EOL $code $EOL }" + + def unwrapTree(wrappedTree: Tree): Tree = { + val PackageDef(_, List(ModuleDef(_, _, Template(_, _, _ :: parsed)))) = wrappedTree + parsed match { + case tree :: Nil => tree + case stats :+ tree => Block(stats, tree) + } + } + + def parse(code: String): Tree = { + try { + val wrapped = wrapCode(code) + debug(s"wrapped code\n=${wrapped}\n") + val file = new BatchSourceFile(nme.QUASIQUOTE_FILE, wrapped) + val tree = new QuasiquoteParser(file).parse() + unwrapTree(tree) + } catch { + case mi: MalformedInput => c.abort(c.macroApplication.pos, s"syntax error: ${mi.msg}") + } + } + + class QuasiquoteParser(source0: SourceFile) extends SourceFileParser(source0) { + override val treeBuilder = new ParserTreeBuilder { + // q"(..$xs)" + override def makeTupleTerm(trees: List[Tree], flattenUnary: Boolean): Tree = + Apply(Ident(nme.QUASIQUOTE_TUPLE), trees) + + // tq"(..$xs)" + override def makeTupleType(trees: List[Tree], flattenUnary: Boolean): Tree = + AppliedTypeTree(Ident(tpnme.QUASIQUOTE_TUPLE), trees) + + // q"{ $x }" + override def makeBlock(stats: List[Tree]): Tree = stats match { + case (head @ Ident(name)) :: Nil if holeMap.contains(name) => Block(Nil, head) + case _ => super.makeBlock(stats) + } + } + import treeBuilder.{global => _, _} + + // q"def foo($x)" + override def allowTypelessParams = true + + // q"foo match { case $x }" + override def caseClause(): CaseDef = + if (isHole && lookingAhead { in.token == CASE || in.token == RBRACE || in.token == SEMI }) { + val c = makeCaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Ident(ident()))), EmptyTree, EmptyTree) + while (in.token == SEMI) in.nextToken() + c + } else + super.caseClause() + + def isHole = isIdent && holeMap.contains(in.name) + + override def isAnnotation: Boolean = super.isAnnotation || (isHole && lookingAhead { isAnnotation }) + + override def isModifier: Boolean = super.isModifier || (isHole && lookingAhead { isModifier }) + + override def isLocalModifier: Boolean = super.isLocalModifier || (isHole && lookingAhead { isLocalModifier }) + + override def isTemplateIntro: Boolean = super.isTemplateIntro || (isHole && lookingAhead { isTemplateIntro }) + + override def isDclIntro: Boolean = super.isDclIntro || (isHole && lookingAhead { isDclIntro }) + + // $mods def foo + // $mods T + override def readAnnots(annot: => Tree): List[Tree] = in.token match { + case AT => + in.nextToken() + annot :: readAnnots(annot) + case _ if isHole && lookingAhead { in.token == AT || isModifier || isDefIntro || isIdent} => + val ann = Apply(Select(New(Ident(tpnme.QUASIQUOTE_MODS)), nme.CONSTRUCTOR), List(Literal(Constant(in.name.toString)))) + in.nextToken() + ann :: readAnnots(annot) + case _ => + Nil + } + } + } + + object TermParser extends Parser + + object CaseParser extends Parser { + override def wrapCode(code: String) = super.wrapCode("something match { case " + code + " }") + + override def unwrapTree(wrappedTree: Tree): Tree = { + val Match(_, head :: tail) = super.unwrapTree(wrappedTree) + if (tail.nonEmpty) + c.abort(c.macroApplication.pos, "Can't parse more than one casedef, consider generating a match tree instead") + head + } + } + + object PatternParser extends Parser { + override def wrapCode(code: String) = super.wrapCode("something match { case " + code + " => }") + + override def unwrapTree(wrappedTree: Tree): Tree = { + val Match(_, List(CaseDef(pat, _, _))) = super.unwrapTree(wrappedTree) + pat + } + } + + object TypeParser extends Parser { + override def wrapCode(code: String) = super.wrapCode("type T = " + code) + + override def unwrapTree(wrappedTree: Tree): Tree = { + val TypeDef(_, _, _, rhs) = super.unwrapTree(wrappedTree) + rhs + } + } +}
\ No newline at end of file diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala new file mode 100644 index 0000000000..b680c25f76 --- /dev/null +++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala @@ -0,0 +1,123 @@ +package scala.tools.reflect +package quasiquotes + +import java.util.UUID.randomUUID +import scala.collection.{immutable, mutable} + +/** Emulates hole support (see Holes.scala) in the quasiquote parser (see Parsers.scala). + * A principled solution to splicing into Scala syntax would be a parser that natively supports holes. + * Unfortunately, that's outside of our reach in Scala 2.11, so we have to emulate. + * This trait stores knowledge of how to represent the holes as something understandable by the parser + * and how to recover holes from the results of parsing the produced representation. + */ +trait Placeholders { self: Quasiquotes => + import global._ + import Cardinality._ + + // Step 1: Transform Scala source with holes into vanilla Scala source + + lazy val holeMap = new HoleMap() + lazy val code = { + val sb = new StringBuilder() + val sessionSuffix = randomUUID().toString.replace("-", "").substring(0, 8) + "$" + + foreach2(args, parts.init) { (tree, p) => + val (part, cardinality) = parseDots(p) + val placeholderName = c.freshName(TermName(nme.QUASIQUOTE_PREFIX + sessionSuffix)) + sb.append(part) + sb.append(placeholderName) + holeMap(placeholderName) = Hole(tree, cardinality) + } + sb.append(parts.last) + + sb.toString + } + + class HoleMap { + private val underlying = mutable.ListMap[String, Hole]() + private val accessed = mutable.Set[String]() + def unused: Set[Name] = (underlying.keys.toSet -- accessed).map(TermName(_)) + def contains(key: Name) = underlying.contains(key.toString) + def apply(key: Name) = { + val s = key.toString + accessed += s + underlying(s) + } + def update(key: Name, hole: Hole) = { + underlying += key.toString -> hole + } + def get(key: Name) = { + val s = key.toString + accessed += s + underlying.get(s) + } + } + + // Step 2: Transform vanilla Scala AST into an AST with holes + + trait HolePlaceholder { + def matching: PartialFunction[Any, Name] + def unapply(scrutinee: Any): Option[(Tree, Location, Cardinality)] = { + val name = matching.lift(scrutinee) + name.flatMap { holeMap.get(_).map { case Hole(repr, loc, card) => (repr, loc, card) } } + } + } + + object Placeholder extends HolePlaceholder { + def matching = { + case name: Name => name + case Ident(name) => name + case Bind(name, Ident(nme.WILDCARD)) => name + case TypeDef(_, name, List(), TypeBoundsTree(EmptyTree, EmptyTree)) => name + case ValDef(_, name, TypeTree(), EmptyTree) => name + } + } + + object ModsPlaceholder extends HolePlaceholder { + def matching = { + case Apply(Select(New(Ident(tpnme.QUASIQUOTE_MODS)), nme.CONSTRUCTOR), List(Literal(Constant(s: String)))) => TermName(s) + } + } + + object AnnotPlaceholder { + def unapply(tree: Tree): Option[(Tree, Location, Cardinality, List[Tree])] = tree match { + case Apply(Select(New(Placeholder(tree, loc, card)), nme.CONSTRUCTOR), args) => Some(tree, loc, card, args) + case _ => None + } + } + + object TuplePlaceholder { + def unapply(tree: Tree): Option[List[Tree]] = tree match { + case Apply(Ident(nme.QUASIQUOTE_TUPLE), args) => Some(args) + case _ => None + } + } + + object TupleTypePlaceholder { + def unapply(tree: Tree): Option[List[Tree]] = tree match { + case AppliedTypeTree(Ident(tpnme.QUASIQUOTE_TUPLE), args) => Some(args) + case _ => None + } + } + + object SymbolPlaceholder { + def unapply(scrutinee: Any): Option[Tree] = scrutinee match { + case Placeholder(tree, SymbolLocation, _) => Some(tree) + case _ => None + } + } + + object CasePlaceholder { + def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { + case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(tree, location, card))), EmptyTree, EmptyTree) => Some((tree, location, card)) + case _ => None + } + } + + object ClassPlaceholder { + def unapply(tree: Tree): Option[Tree] = tree match { + case ClassDef(_, _, _, _) => Some(tree) + case _ => None + } + } +}
\ No newline at end of file diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala new file mode 100644 index 0000000000..fe954e0bfd --- /dev/null +++ b/src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala @@ -0,0 +1,51 @@ +package scala.tools.reflect +package quasiquotes + +import scala.reflect.macros.runtime.Context + +abstract class Quasiquotes extends Parsers + with Holes + with Placeholders + with Reifiers { + val c: Context + val global: c.universe.type = c.universe + import c.universe._ + + def debug(msg: String): Unit = + if (settings.Yquasiquotedebug.value) println(msg) + + lazy val (universe: Tree, args, parts, parse, reify) = c.macroApplication match { + case Apply(Select(Select(Apply(Select(universe0, _), List(Apply(_, parts0))), interpolator0), method0), args0) => + val parts1 = parts0.map { + case Literal(Constant(s: String)) => s + case part => c.abort(part.pos, "Quasiquotes can only be used with literal strings") + } + val reify0 = method0 match { + case nme.apply => new ApplyReifier().reifyFillingHoles(_) + case nme.unapply => new UnapplyReifier().reifyFillingHoles(_) + case other => global.abort(s"Unknown quasiquote api method: $other") + } + val parse0 = interpolator0 match { + case nme.q => TermParser.parse(_) + case nme.tq => TypeParser.parse(_) + case nme.cq => CaseParser.parse(_) + case nme.pq => PatternParser.parse(_) + case other => global.abort(s"Unknown quasiquote flavor: $other") + } + (universe0, args0, parts1, parse0, reify0) + case _ => + global.abort(s"Couldn't parse call prefix tree ${c.macroApplication}.") + } + + lazy val u = universe // shortcut + lazy val universeTypes = new definitions.UniverseDependentTypes(universe) + + def expandQuasiquote = { + debug(s"\ncode to parse=\n$code\n") + val tree = parse(code) + debug(s"parsed tree\n=${tree}\n=${showRaw(tree)}\n") + val reified = reify(tree) + debug(s"reified tree\n=${reified}\n=${showRaw(reified)}\n") + reified + } +} diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala new file mode 100644 index 0000000000..900237b00d --- /dev/null +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -0,0 +1,290 @@ +package scala.tools.reflect +package quasiquotes + +import java.lang.UnsupportedOperationException +import scala.reflect.reify.{Reifier => ReflectReifier} +import scala.reflect.internal.Flags._ + +trait Reifiers { self: Quasiquotes => + import global._ + import global.build.SyntacticClassDef + import global.treeInfo._ + import global.definitions._ + import Cardinality._ + import universeTypes._ + + abstract class Reifier extends { + val global: self.global.type = self.global + val universe = self.universe + val reifee = EmptyTree + val mirror = EmptyTree + val concrete = false + } with ReflectReifier { + lazy val typer = throw new UnsupportedOperationException + + def isReifyingExpressions: Boolean + def isReifyingPatterns: Boolean = !isReifyingExpressions + def action = if (isReifyingExpressions) "splice" else "extract" + def holesHaveTypes = isReifyingExpressions + + def reifyFillingHoles(tree: Tree): Tree = { + val reified = reifyTree(tree) + holeMap.unused.foreach { hole => + c.abort(holeMap(hole).tree.pos, s"Don't know how to $action here") + } + reified + } + + override def reifyTree(tree: Tree): Tree = { + val reified = + reifyTreePlaceholder(tree) orElse + reifyTreeSyntactically(tree) + //println(s"reified ${showRaw(tree)} as $reified") + reified + } + + def reifyTreePlaceholder(tree: Tree): Tree = tree match { + case Placeholder(tree, TreeLocation(_), _) if isReifyingExpressions => tree + case Placeholder(tree, _, NoDot) if isReifyingPatterns => tree + case Placeholder(tree, _, card @ Dot()) => c.abort(tree.pos, s"Can't $action with $card here") + case TuplePlaceholder(args) => reifyTuple(args) + case TupleTypePlaceholder(args) => reifyTupleType(args) + case CasePlaceholder(tree, location, _) => reifyCase(tree, location) + case ClassPlaceholder(tree) => reifyClass(tree) + case _ => EmptyTree + } + + override def reifyName(name: Name): Tree = name match { + case Placeholder(tree, location, _) => + if (holesHaveTypes && !(location.tpe <:< nameType)) c.abort(tree.pos, s"$nameType expected but ${location.tpe} found") + tree + case _ => + super.reifyName(name) + } + + def reifyCase(tree: Tree, location: Location) = { + if (holesHaveTypes && !(location.tpe <:< caseDefType)) c.abort(tree.pos, s"$caseDefType expected but ${location.tpe} found") + tree + } + + def reifyTuple(args: List[Tree]) = args match { + case Nil => reify(Literal(Constant(()))) + case List(hole @ Placeholder(_, _, NoDot)) => reify(hole) + case List(Placeholder(_, _, _)) => reifyBuildCall(nme.TupleN, args) + // in a case we only have one element tuple without + // any cardinality annotations this means that this is + // just an expression wrapped in parentheses + case List(other) => reify(other) + case _ => reifyBuildCall(nme.TupleN, args) + } + + def reifyTupleType(args: List[Tree]) = args match { + case Nil => reify(Select(Ident(nme.scala_), tpnme.Unit)) + case List(hole @ Placeholder(_, _, NoDot)) => reify(hole) + case List(Placeholder(_, _, _)) => reifyBuildCall(nme.TupleTypeN, args) + case List(other) => reify(other) + case _ => reifyBuildCall(nme.TupleTypeN, args) + } + + def reifyClass(tree: Tree) = { + val SyntacticClassDef(mods, name, tparams, constrmods, argss, parents, selfval, body) = tree + reifyBuildCall(nme.SyntacticClassDef, mods, name, tparams, constrmods, argss, parents, selfval, body) + } + + /** Splits list into a list of groups where subsequent elements are considered + * similar by the corresponding function. + * + * Example: + * + * > group(List(1, 1, 0, 0, 1, 0)) { _ == _ } + * List(List(1, 1), List(0, 0), List(1), List(0)) + * + */ + def group[T](lst: List[T])(similar: (T, T) => Boolean) = lst.foldLeft[List[List[T]]](List()) { + case (Nil, el) => List(List(el)) + case (ll :+ (last @ (lastinit :+ lastel)), el) if similar(lastel, el) => ll :+ (last :+ el) + case (ll, el) => ll :+ List(el) + } + + /** Reifies list filling all the valid holeMap. + * + * Reification of non-trivial list is done in two steps: + * + * 1. split the list into groups where every placeholder is always + * put in a group of it's own and all subsquent non-holeMap are + * grouped together; element is considered to be a placeholder if it's + * in the domain of the fill function; + * + * 2. fold the groups into a sequence of lists added together with ++ using + * fill reification for holeMap and fallback reification for non-holeMap. + * + * Example: + * + * reifyMultiCardinalityList(lst) { + * // first we define patterns that extract high-cardinality holeMap (currently ..) + * case Placeholder(CorrespondsTo(tree, tpe)) if tpe <:< iterableTreeType => tree + * } { + * // in the end we define how single elements are reified, typically with default reify call + * reify(_) + * } + * + * Sample execution of previous concrete list reifier: + * + * > val lst = List(foo, bar, qq$f3948f9s$1) + * > reifyMultiCardinalityList(lst) { ... } { ... } + * q"List($foo, $bar) ++ ${holeMap(qq$f3948f9s$1).tree}" + */ + def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree): Tree + + /** Reifies arbitrary list filling ..$x and ...$y holeMap when they are put + * in the correct position. Fallbacks to regular reification for non-high cardinality + * elements. + */ + override def reifyList(xs: List[Any]): Tree = reifyMultiCardinalityList(xs) { + case Placeholder(tree, _, DotDot) => tree + case CasePlaceholder(tree, _, DotDot) => tree + case List(Placeholder(tree, _, DotDotDot)) => tree + } { + reify(_) + } + + def reifyAnnotList(annots: List[Tree]): Tree + + def ensureNoExplicitFlags(m: Modifiers, pos: Position) = + if ((m.flags & ExplicitFlags) != 0L) c.abort(pos, s"Can't $action modifiers together with flags, consider merging flags into modifiers") + + override def mirrorSelect(name: String): Tree = + Select(universe, TermName(name)) + + override def mirrorCall(name: TermName, args: Tree*): Tree = + Apply(Select(universe, name), args.toList) + + override def mirrorBuildCall(name: TermName, args: Tree*): Tree = + Apply(Select(Select(universe, nme.build), name), args.toList) + } + + class ApplyReifier extends Reifier { + def isReifyingExpressions = true + + override def reifyTreeSyntactically(tree: Tree): Tree = tree match { + case Block(stats, p @ Placeholder(_, _, _)) => reifyBuildCall(nme.Block, stats :+ p) + case Apply(f, List(Placeholder(argss, _, DotDotDot))) => reifyCallWithArgss(f, argss) + case RefTree(qual, SymbolPlaceholder(tree)) => mirrorBuildCall(nme.RefTree, reify(qual), tree) + case _ => super.reifyTreeSyntactically(tree) + } + + def reifyCallWithArgss(f: Tree, argss: Tree) = { + val f1 = reifyTree(f) + val foldLeftF1 = Apply(TypeApply(Select(argss, nme.foldLeft), List(Select(u, tpnme.Tree))), List(f1)) + val uDotApply = Function( + List(gen.mkSyntheticParam(nme.x_1), gen.mkSyntheticParam(nme.x_2)), + Apply(Select(u, nme.Apply), List(Ident(nme.x_1), Ident(nme.x_2)))) + Apply(foldLeftF1, List(uDotApply)) + } + + override def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree): Tree = xs match { + case Nil => mkList(Nil) + case _ => + def reifyGroup(group: List[T]): Tree = group match { + case List(elem) if fill.isDefinedAt(elem) => fill(elem) + case elems => mkList(elems.map(fallback)) + } + val head :: tail = group(xs) { (a, b) => !fill.isDefinedAt(a) && !fill.isDefinedAt(b) } + tail.foldLeft[Tree](reifyGroup(head)) { (tree, lst) => Apply(Select(tree, nme.PLUSPLUS), List(reifyGroup(lst))) } + } + + override def reifyAnnotList(annots: List[Tree]): Tree = reifyMultiCardinalityList(annots) { + case AnnotPlaceholder(tree, _, DotDot, args) => + val x: TermName = c.freshName() + val xToAnnotationCtor = Function( + List(ValDef(Modifiers(PARAM), x, TypeTree(), EmptyTree)), + mirrorBuildCall(nme.mkAnnotationCtor, Ident(x), reify(args))) + Apply(Select(tree, nme.map), List(xToAnnotationCtor)) + } { + case AnnotPlaceholder(tree, _: TreeLocation, _, args) => + mirrorBuildCall(nme.mkAnnotationCtor, tree, reify(args)) + case other => reify(other) + } + + override def reifyModifiers(m: Modifiers) = { + val (modsPlaceholders, annots) = m.annotations.partition { + case ModsPlaceholder(_, _, _) => true + case _ => false + } + val (mods, flags) = modsPlaceholders.map { + case ModsPlaceholder(tree, location, card) => (tree, location) + }.partition { case (tree, location) => + location match { + case ModsLocation => true + case FlagsLocation => false + case _ => c.abort(tree.pos, s"$flagsType or $modsType expected but ${tree.tpe} found") + } + } + mods match { + case (tree, _) :: Nil => + if (flags.nonEmpty) c.abort(flags(0)._1.pos, "Can't splice flags together with modifiers, consider merging flags into modifiers") + if (annots.nonEmpty) c.abort(tree.pos, "Can't splice modifiers together with annotations, consider merging annotations into modifiers") + ensureNoExplicitFlags(m, tree.pos) + tree + case _ :: (second, _) :: Nil => + c.abort(second.pos, "Can't splice multiple modifiers, consider merging them into a single modifiers instance") + case _ => + val baseFlags = reifyBuildCall(nme.flagsFromBits, m.flags) + val reifiedFlags = flags.foldLeft[Tree](baseFlags) { case (flag, (tree, _)) => Apply(Select(flag, nme.OR), List(tree)) } + mirrorFactoryCall(nme.Modifiers, reifiedFlags, reify(m.privateWithin), reifyAnnotList(annots)) + } + } + } + + class UnapplyReifier extends Reifier { + def isReifyingExpressions = false + + override def reifyTreeSyntactically(tree: Tree): Tree = tree match { + case treeInfo.Applied(fun, Nil, argss) if fun != tree && !tree.isInstanceOf[AppliedTypeTree] => + reifyBuildCall(nme.Applied, fun, argss) + case treeInfo.Applied(fun, targs, argss) if fun != tree & !tree.isInstanceOf[AppliedTypeTree] => + mirrorBuildCall(nme.Applied, reifyBuildCall(nme.TypeApplied, fun, targs), reifyList(argss)) + case _ => + super.reifyTreeSyntactically(tree) + } + + override def scalaFactoryCall(name: String, args: Tree*): Tree = + call("scala." + name, args: _*) + + override def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree) = xs match { + case init :+ last if fill.isDefinedAt(last) => + init.foldRight[Tree](fill(last)) { (el, rest) => + val cons = Select(Select(Select(Ident(nme.scala_), nme.collection), nme.immutable), nme.CONS) + Apply(cons, List(fallback(el), rest)) + } + case _ => + mkList(xs.map(fallback)) + } + + override def reifyAnnotList(annots: List[Tree]): Tree = reifyMultiCardinalityList(annots) { + case AnnotPlaceholder(tree, _, DotDot, Nil) => tree + } { + case AnnotPlaceholder(tree, _, NoDot, Nil) => tree + case AnnotPlaceholder(tree, _, NoDot, args) => + val selectCONSTRUCTOR = Apply(Select(u, nme.Select), List(Apply(Select(u, nme.New), List(tree)), Select(Select(u, nme.nmeNme), nme.nmeCONSTRUCTOR))) + Apply(Select(u, nme.Apply), List(selectCONSTRUCTOR, reify(args))) + case other => + reify(other) + } + + override def reifyModifiers(m: Modifiers) = { + val mods = m.annotations.collect { case ModsPlaceholder(tree, _, _) => tree } + mods match { + case tree :: Nil => + if (m.annotations.length != 1) c.abort(tree.pos, "Can't extract modifiers together with annotations, consider extracting just modifiers") + ensureNoExplicitFlags(m, tree.pos) + tree + case _ :: second :: rest => + c.abort(second.pos, "Can't extract multiple modifiers together, consider extracting a single modifiers instance") + case Nil => + mirrorFactoryCall(nme.Modifiers, reifyBuildCall(nme.FlagsAsBits, m.flags), + reify(m.privateWithin), reifyAnnotList(m.annotations)) + } + } + } +}
\ No newline at end of file diff --git a/src/eclipse/continuations-library/.classpath b/src/eclipse/continuations-library/.classpath index b3ca4eeb48..61cb3f060e 100644 --- a/src/eclipse/continuations-library/.classpath +++ b/src/eclipse/continuations-library/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="src" path="library"/> + <classpathentry kind="src" path="continuations-library"/> <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> diff --git a/src/eclipse/continuations-library/.project b/src/eclipse/continuations-library/.project index f3a53a3d97..33cc57d667 100644 --- a/src/eclipse/continuations-library/.project +++ b/src/eclipse/continuations-library/.project @@ -22,7 +22,7 @@ <locationURI>SCALA_BASEDIR/build/quick/classes/continuations/library</locationURI> </link> <link> - <name>library</name> + <name>continuations-library</name> <type>2</type> <locationURI>SCALA_BASEDIR/src/continuations/library</locationURI> </link> diff --git a/src/eclipse/interactive/.classpath b/src/eclipse/interactive/.classpath index 870cc67aec..73a67e45ed 100644 --- a/src/eclipse/interactive/.classpath +++ b/src/eclipse/interactive/.classpath @@ -1,10 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="interactive"/> - <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> <classpathentry combineaccessrules="false" kind="src" path="/scaladoc"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_COMPILER_CONTAINER"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> <classpathentry kind="output" path="build-quick-interactive"/> </classpath> diff --git a/src/eclipse/partest/.classpath b/src/eclipse/partest/.classpath index a990c5a1b3..462cbb9c94 100644 --- a/src/eclipse/partest/.classpath +++ b/src/eclipse/partest/.classpath @@ -1,15 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="partest"/> - <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> <classpathentry combineaccessrules="false" kind="src" path="/scalap"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="lib" path="lib/ant/ant.jar"/> - <classpathentry kind="lib" path="lib/jline.jar"/> <classpathentry combineaccessrules="false" kind="src" path="/asm"/> - <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/> <classpathentry combineaccessrules="false" kind="src" path="/repl"/> + <classpathentry kind="var" path="M2_REPO/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar"/> + <classpathentry kind="var" path="M2_REPO/org/scala-tools/testing/test-interface/0.5/test-interface-0.5.jar"/> + <classpathentry kind="var" path="SCALA_BASEDIR/lib/ant/ant.jar"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_COMPILER_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="output" path="build-quick-partest"/> </classpath> diff --git a/src/eclipse/reflect/.classpath b/src/eclipse/reflect/.classpath index 36e6b6adf1..1eb37e3f5f 100644 --- a/src/eclipse/reflect/.classpath +++ b/src/eclipse/reflect/.classpath @@ -2,7 +2,7 @@ <classpath> <classpathentry kind="src" path="reflect"/> <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="output" path="build-quick-reflect"/> </classpath> diff --git a/src/eclipse/repl/.classpath b/src/eclipse/repl/.classpath index 30744da306..748fa6c9c8 100644 --- a/src/eclipse/repl/.classpath +++ b/src/eclipse/repl/.classpath @@ -1,11 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="src" path="repl"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> - <classpathentry kind="var" path="SCALA_BASEDIR/lib/jline.jar"/> - <classpathentry combineaccessrules="false" kind="src" path="/asm"/> - <classpathentry kind="output" path="build-quick-repl"/> + <classpathentry kind="src" path="repl"/> + <classpathentry combineaccessrules="false" kind="src" path="/asm"/> + <classpathentry kind="var" path="M2_REPO/jline/jline/2.11/jline-2.11.jar"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_COMPILER_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="output" path="build-quick-repl"/> </classpath> diff --git a/src/eclipse/repl/.project b/src/eclipse/repl/.project index ea188bc262..69ad08ab1a 100644 --- a/src/eclipse/repl/.project +++ b/src/eclipse/repl/.project @@ -1,35 +1,35 @@ <?xml version="1.0" encoding="UTF-8"?> <projectDescription> - <name>repl</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.scala-ide.sdt.core.scalabuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.scala-ide.sdt.core.scalanature</nature> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> - <linkedResources> - <link> - <name>build-quick-repl</name> - <type>2</type> - <locationURI>SCALA_BASEDIR/build/quick/classes/repl</locationURI> - </link> - <link> - <name>lib</name> - <type>2</type> - <locationURI>SCALA_BASEDIR/lib</locationURI> - </link> - <link> - <name>repl</name> - <type>2</type> - <locationURI>SCALA_BASEDIR/src/repl</locationURI> - </link> - </linkedResources> + <name>repl</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.scala-ide.sdt.core.scalabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.scala-ide.sdt.core.scalanature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> + <linkedResources> + <link> + <name>build-quick-repl</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/build/quick/classes/repl</locationURI> + </link> + <link> + <name>lib</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/lib</locationURI> + </link> + <link> + <name>repl</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/src/repl</locationURI> + </link> + </linkedResources> </projectDescription> diff --git a/src/eclipse/scala-compiler/.classpath b/src/eclipse/scala-compiler/.classpath index 0488a0dc39..b6ef5f35bb 100644 --- a/src/eclipse/scala-compiler/.classpath +++ b/src/eclipse/scala-compiler/.classpath @@ -1,12 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="compiler"/> + <classpathentry combineaccessrules="false" kind="src" path="/asm"/> <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> - <classpathentry combineaccessrules="false" kind="src" path="/asm"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="lib" path="lib/ant/ant.jar"/> - <classpathentry kind="lib" path="lib/jline.jar"/> <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/> + <classpathentry kind="var" path="SCALA_BASEDIR/lib/ant/ant.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="output" path="build-quick-compiler"/> </classpath> diff --git a/src/eclipse/scala-library/.classpath b/src/eclipse/scala-library/.classpath index a3a4933d34..eff3c8e0b7 100644 --- a/src/eclipse/scala-library/.classpath +++ b/src/eclipse/scala-library/.classpath @@ -2,6 +2,6 @@ <classpath> <classpathentry kind="src" path="library"/> <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="output" path="build-quick-lib"/> </classpath> diff --git a/src/eclipse/scala-parser-combinators/.classpath b/src/eclipse/scala-parser-combinators/.classpath new file mode 100644 index 0000000000..7eab7094eb --- /dev/null +++ b/src/eclipse/scala-parser-combinators/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src-parser-combinators"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="output" path="build-quick-parser-combinators"/> +</classpath> diff --git a/src/eclipse/scala-parser-combinators/.project b/src/eclipse/scala-parser-combinators/.project new file mode 100644 index 0000000000..d94523f56d --- /dev/null +++ b/src/eclipse/scala-parser-combinators/.project @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>scala-parser-combinators</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.scala-ide.sdt.core.scalabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.scala-ide.sdt.core.scalanature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> + <linkedResources> + <link> + <name>build-quick-parser-combinators</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/build/quick/classes/parser-combinators</locationURI> + </link> + <link> + <name>src-parser-combinators</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/src/parser-combinators</locationURI> + </link> + </linkedResources> +</projectDescription> diff --git a/src/eclipse/scala-xml/.classpath b/src/eclipse/scala-xml/.classpath new file mode 100644 index 0000000000..b90d951640 --- /dev/null +++ b/src/eclipse/scala-xml/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src-xml"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="output" path="build-quick-xml"/> +</classpath> diff --git a/src/eclipse/scala-xml/.project b/src/eclipse/scala-xml/.project new file mode 100644 index 0000000000..8b0f7f6864 --- /dev/null +++ b/src/eclipse/scala-xml/.project @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>scala-xml</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.scala-ide.sdt.core.scalabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.scala-ide.sdt.core.scalanature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> + <linkedResources> + <link> + <name>build-quick-xml</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/build/quick/classes/xml</locationURI> + </link> + <link> + <name>src-xml</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/src/xml</locationURI> + </link> + </linkedResources> +</projectDescription> diff --git a/src/eclipse/scaladoc/.classpath b/src/eclipse/scaladoc/.classpath index f12ba4bb2c..caafcf33b0 100644 --- a/src/eclipse/scaladoc/.classpath +++ b/src/eclipse/scaladoc/.classpath @@ -1,13 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry combineaccessrules="false" kind="src" path="/partest"/> <classpathentry kind="src" path="scaladoc"/> - <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry combineaccessrules="false" kind="src" path="/partest"/> <classpathentry kind="var" path="SCALA_BASEDIR/lib/ant/ant.jar"/> - <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/> - <classpathentry combineaccessrules="false" kind="src" path="/asm"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_COMPILER_CONTAINER"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="output" path="build-quick-scaladoc"/> </classpath> diff --git a/src/eclipse/scalap/.classpath b/src/eclipse/scalap/.classpath index 0a55745702..3b635cf56e 100644 --- a/src/eclipse/scalap/.classpath +++ b/src/eclipse/scalap/.classpath @@ -1,12 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="scalap"/> - <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> + <classpathentry kind="var" path="SCALA_BASEDIR/lib/ant/ant.jar"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> + <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_COMPILER_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="lib" path="lib/ant/ant.jar"/> - <classpathentry kind="lib" path="lib/jline.jar"/> - <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/> <classpathentry kind="output" path="build-quick-scalap"/> </classpath> diff --git a/src/eclipse/test-junit/.classpath b/src/eclipse/test-junit/.classpath index 718f7b6ece..8e4f88e0f0 100644 --- a/src/eclipse/test-junit/.classpath +++ b/src/eclipse/test-junit/.classpath @@ -1,12 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="test-junit"/> + <classpathentry kind="var" path="SCALA_BASEDIR/lib/ant/ant.jar"/> + <classpathentry kind="var" path="M2_REPO/junit/junit/4.10/junit-4.10.jar"/> <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> + <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="lib" path="lib/ant/ant.jar"/> - <classpathentry kind="lib" path="lib/jline.jar"/> - <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> - <classpathentry kind="var" path="M2_REPO/junit/junit/4.10/junit-4.10.jar"/> <classpathentry kind="output" path="build-test-junit"/> </classpath> diff --git a/src/interactive/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/interactive/scala/tools/nsc/interactive/ScratchPadMaker.scala index ae70a74b60..2400b97d97 100644 --- a/src/interactive/scala/tools/nsc/interactive/ScratchPadMaker.scala +++ b/src/interactive/scala/tools/nsc/interactive/ScratchPadMaker.scala @@ -47,7 +47,7 @@ trait ScratchPadMaker { self: Global => toPrint.clear() } - /** The position where to insert an instrumentation statement in front of giuven statement. + /** The position where to insert an instrumentation statement in front of given statement. * This is at the latest `stat.pos.start`. But in order not to mess with column numbers * in position we try to insert it at the end of the previous token instead. * Furthermore, `(' tokens have to be skipped because they do not show up diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index a188602543..3b588e261f 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -134,15 +134,6 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { @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` @inline def locally[T](x: T): T = x // to communicate intent and avoid unmoored statements - // TODO: remove `val $scope = ...` as soon as 2.11.0-M4 is released and used as STARR - // As it has a '$' in its name, we don't have to deprecate first. - // The compiler now aliases `scala.xml.TopScope` to `$scope` (unless Predef.$scope is still there). - // This definition left in place for older compilers and to compile quick with pre-2.11.0-M4 STARR. - // In principle we don't need it to compile library/reflect/compiler (there's no xml left there), - // so a new locker can be built without this definition, and locker can build quick - // (partest, scaladoc still require xml). - val $scope = scala.xml.TopScope - // errors and asserts ------------------------------------------------- // !!! Remove this when possible - ideally for 2.11. diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala index d966c7324b..e4976d8f2c 100644 --- a/src/library/scala/collection/GenTraversableOnce.scala +++ b/src/library/scala/collection/GenTraversableOnce.scala @@ -341,7 +341,7 @@ trait GenTraversableOnce[+A] extends Any { * * @param ord An ordering to be used for comparing elements. * @tparam A1 The type over which the ordering is defined. - * @return the smallest element of this $coll with respect to the ordering `cmp`. + * @return the smallest element of this $coll with respect to the ordering `ord`. * * @usecase def min: A * @inheritdoc @@ -354,7 +354,7 @@ trait GenTraversableOnce[+A] extends Any { * * @param ord An ordering to be used for comparing elements. * @tparam A1 The type over which the ordering is defined. - * @return the largest element of this $coll with respect to the ordering `cmp`. + * @return the largest element of this $coll with respect to the ordering `ord`. * * @usecase def max: A * @inheritdoc @@ -363,8 +363,34 @@ trait GenTraversableOnce[+A] extends Any { */ def max[A1 >: A](implicit ord: Ordering[A1]): A + /** Finds the first element which yields the largest value measured by function f. + * + * @param cmp An ordering to be used for comparing elements. + * @tparam B The result type of the function f. + * @param f The measuring function. + * @return the first element of this $coll with the largest value measured by function f + * with respect to the ordering `cmp`. + * + * @usecase def maxBy[B](f: A => B): A + * @inheritdoc + * + * @return the first element of this $coll with the largest value measured by function f. + */ def maxBy[B](f: A => B)(implicit cmp: Ordering[B]): A + /** Finds the first element which yields the smallest value measured by function f. + * + * @param cmp An ordering to be used for comparing elements. + * @tparam B The result type of the function f. + * @param f The measuring function. + * @return the first element of this $coll with the smallest value measured by function f + * with respect to the ordering `cmp`. + * + * @usecase def minBy[B](f: A => B): A + * @inheritdoc + * + * @return the first element of this $coll with the smallest value measured by function f. + */ def minBy[B](f: A => B)(implicit cmp: Ordering[B]): A def forall(pred: A => Boolean): Boolean diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 526c36dda7..634807b29f 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -221,13 +221,37 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { if (isEmpty) throw new UnsupportedOperationException("empty.maxBy") - reduceLeft((x, y) => if (cmp.gteq(f(x), f(y))) x else y) + var maxF: B = null.asInstanceOf[B] + var maxElem: A = null.asInstanceOf[A] + var first = true + + for (elem <- self) { + val fx = f(elem) + if (first || cmp.gt(fx, maxF)) { + maxElem = elem + maxF = fx + first = false + } + } + maxElem } def minBy[B](f: A => B)(implicit cmp: Ordering[B]): A = { if (isEmpty) throw new UnsupportedOperationException("empty.minBy") - reduceLeft((x, y) => if (cmp.lteq(f(x), f(y))) x else y) + var minF: B = null.asInstanceOf[B] + var minElem: A = null.asInstanceOf[A] + var first = true + + for (elem <- self) { + val fx = f(elem) + if (first || cmp.lt(fx, minF)) { + minElem = elem + minF = fx + first = false + } + } + minElem } /** Copies all elements of this $coll to a buffer. diff --git a/src/library/scala/util/parsing/combinator/ImplicitConversions.scala b/src/parser-combinators/scala/util/parsing/combinator/ImplicitConversions.scala index 0683ea927d..0683ea927d 100644 --- a/src/library/scala/util/parsing/combinator/ImplicitConversions.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/ImplicitConversions.scala diff --git a/src/library/scala/util/parsing/combinator/JavaTokenParsers.scala b/src/parser-combinators/scala/util/parsing/combinator/JavaTokenParsers.scala index 01288a182e..01288a182e 100644 --- a/src/library/scala/util/parsing/combinator/JavaTokenParsers.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/JavaTokenParsers.scala diff --git a/src/library/scala/util/parsing/combinator/PackratParsers.scala b/src/parser-combinators/scala/util/parsing/combinator/PackratParsers.scala index a11dd18e62..a11dd18e62 100644 --- a/src/library/scala/util/parsing/combinator/PackratParsers.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/PackratParsers.scala diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/parser-combinators/scala/util/parsing/combinator/Parsers.scala index 16754646fd..16754646fd 100644 --- a/src/library/scala/util/parsing/combinator/Parsers.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/Parsers.scala diff --git a/src/library/scala/util/parsing/combinator/RegexParsers.scala b/src/parser-combinators/scala/util/parsing/combinator/RegexParsers.scala index 8ebbc573ad..8ebbc573ad 100644 --- a/src/library/scala/util/parsing/combinator/RegexParsers.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/RegexParsers.scala diff --git a/src/library/scala/util/parsing/combinator/lexical/Lexical.scala b/src/parser-combinators/scala/util/parsing/combinator/lexical/Lexical.scala index d8029d068f..d8029d068f 100644 --- a/src/library/scala/util/parsing/combinator/lexical/Lexical.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/lexical/Lexical.scala diff --git a/src/library/scala/util/parsing/combinator/lexical/Scanners.scala b/src/parser-combinators/scala/util/parsing/combinator/lexical/Scanners.scala index 2e12915bb8..2e12915bb8 100644 --- a/src/library/scala/util/parsing/combinator/lexical/Scanners.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/lexical/Scanners.scala diff --git a/src/library/scala/util/parsing/combinator/lexical/StdLexical.scala b/src/parser-combinators/scala/util/parsing/combinator/lexical/StdLexical.scala index 32d7502cda..32d7502cda 100644 --- a/src/library/scala/util/parsing/combinator/lexical/StdLexical.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/lexical/StdLexical.scala diff --git a/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala b/src/parser-combinators/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala index 5b9d14c9a7..5b9d14c9a7 100644 --- a/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala diff --git a/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala b/src/parser-combinators/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala index adcf85da7a..adcf85da7a 100644 --- a/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala diff --git a/src/library/scala/util/parsing/combinator/syntactical/TokenParsers.scala b/src/parser-combinators/scala/util/parsing/combinator/syntactical/TokenParsers.scala index b06babcd7e..b06babcd7e 100644 --- a/src/library/scala/util/parsing/combinator/syntactical/TokenParsers.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/syntactical/TokenParsers.scala diff --git a/src/library/scala/util/parsing/combinator/token/StdTokens.scala b/src/parser-combinators/scala/util/parsing/combinator/token/StdTokens.scala index a102d1541e..a102d1541e 100644 --- a/src/library/scala/util/parsing/combinator/token/StdTokens.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/token/StdTokens.scala diff --git a/src/library/scala/util/parsing/combinator/token/Tokens.scala b/src/parser-combinators/scala/util/parsing/combinator/token/Tokens.scala index 5c3f1f95b5..5c3f1f95b5 100644 --- a/src/library/scala/util/parsing/combinator/token/Tokens.scala +++ b/src/parser-combinators/scala/util/parsing/combinator/token/Tokens.scala diff --git a/src/library/scala/util/parsing/input/CharArrayReader.scala b/src/parser-combinators/scala/util/parsing/input/CharArrayReader.scala index 22530cb9aa..22530cb9aa 100644 --- a/src/library/scala/util/parsing/input/CharArrayReader.scala +++ b/src/parser-combinators/scala/util/parsing/input/CharArrayReader.scala diff --git a/src/library/scala/util/parsing/input/CharSequenceReader.scala b/src/parser-combinators/scala/util/parsing/input/CharSequenceReader.scala index 8e7751cc82..8e7751cc82 100644 --- a/src/library/scala/util/parsing/input/CharSequenceReader.scala +++ b/src/parser-combinators/scala/util/parsing/input/CharSequenceReader.scala diff --git a/src/library/scala/util/parsing/input/NoPosition.scala b/src/parser-combinators/scala/util/parsing/input/NoPosition.scala index 4a32264b79..4a32264b79 100644 --- a/src/library/scala/util/parsing/input/NoPosition.scala +++ b/src/parser-combinators/scala/util/parsing/input/NoPosition.scala diff --git a/src/library/scala/util/parsing/input/OffsetPosition.scala b/src/parser-combinators/scala/util/parsing/input/OffsetPosition.scala index 23f79c74d1..23f79c74d1 100644 --- a/src/library/scala/util/parsing/input/OffsetPosition.scala +++ b/src/parser-combinators/scala/util/parsing/input/OffsetPosition.scala diff --git a/src/library/scala/util/parsing/input/PagedSeqReader.scala b/src/parser-combinators/scala/util/parsing/input/PagedSeqReader.scala index 468f1f9a5f..468f1f9a5f 100644 --- a/src/library/scala/util/parsing/input/PagedSeqReader.scala +++ b/src/parser-combinators/scala/util/parsing/input/PagedSeqReader.scala diff --git a/src/library/scala/util/parsing/input/Position.scala b/src/parser-combinators/scala/util/parsing/input/Position.scala index b7995a6471..b7995a6471 100644 --- a/src/library/scala/util/parsing/input/Position.scala +++ b/src/parser-combinators/scala/util/parsing/input/Position.scala diff --git a/src/library/scala/util/parsing/input/Positional.scala b/src/parser-combinators/scala/util/parsing/input/Positional.scala index cfde67cadd..cfde67cadd 100644 --- a/src/library/scala/util/parsing/input/Positional.scala +++ b/src/parser-combinators/scala/util/parsing/input/Positional.scala diff --git a/src/library/scala/util/parsing/input/Reader.scala b/src/parser-combinators/scala/util/parsing/input/Reader.scala index 9dbf08a7ca..9dbf08a7ca 100644 --- a/src/library/scala/util/parsing/input/Reader.scala +++ b/src/parser-combinators/scala/util/parsing/input/Reader.scala diff --git a/src/library/scala/util/parsing/input/StreamReader.scala b/src/parser-combinators/scala/util/parsing/input/StreamReader.scala index 30eb097fd7..30eb097fd7 100644 --- a/src/library/scala/util/parsing/input/StreamReader.scala +++ b/src/parser-combinators/scala/util/parsing/input/StreamReader.scala diff --git a/src/library/scala/util/parsing/json/JSON.scala b/src/parser-combinators/scala/util/parsing/json/JSON.scala index b06dddf532..b06dddf532 100644 --- a/src/library/scala/util/parsing/json/JSON.scala +++ b/src/parser-combinators/scala/util/parsing/json/JSON.scala diff --git a/src/library/scala/util/parsing/json/Lexer.scala b/src/parser-combinators/scala/util/parsing/json/Lexer.scala index 7fc4e0bab6..7fc4e0bab6 100644 --- a/src/library/scala/util/parsing/json/Lexer.scala +++ b/src/parser-combinators/scala/util/parsing/json/Lexer.scala diff --git a/src/library/scala/util/parsing/json/Parser.scala b/src/parser-combinators/scala/util/parsing/json/Parser.scala index 521dfc6612..521dfc6612 100644 --- a/src/library/scala/util/parsing/json/Parser.scala +++ b/src/parser-combinators/scala/util/parsing/json/Parser.scala diff --git a/src/partest/scala/tools/partest/ReplTest.scala b/src/partest/scala/tools/partest/ReplTest.scala index edd1f705a4..7381b8af54 100644 --- a/src/partest/scala/tools/partest/ReplTest.scala +++ b/src/partest/scala/tools/partest/ReplTest.scala @@ -7,6 +7,7 @@ package scala.tools.partest import scala.tools.nsc.Settings import scala.tools.nsc.interpreter.ILoop +import scala.tools.partest.nest.FileUtil import java.lang.reflect.{ Method => JMethod, Field => JField } /** A trait for testing repl code. It drops the first line @@ -29,3 +30,15 @@ abstract class ReplTest extends DirectTest { } def show() = eval() foreach println } + +abstract class SessionTest extends ReplTest with FileUtil { + def session: String + override final def code = expected filter (_.startsWith(prompt)) map (_.drop(prompt.length)) mkString "\n" + def expected = session.stripMargin.lines.toList + final def prompt = "scala> " + override def show() = { + val out = eval().toList + if (out.size != expected.size) Console println s"Expected ${expected.size} lines, got ${out.size}" + if (out != expected) Console print compareContents(expected, out, "expected", "actual") + } +} diff --git a/src/partest/scala/tools/partest/nest/FileManager.scala b/src/partest/scala/tools/partest/nest/FileManager.scala index 230ada4803..7bfa8c6e77 100644 --- a/src/partest/scala/tools/partest/nest/FileManager.scala +++ b/src/partest/scala/tools/partest/nest/FileManager.scala @@ -68,12 +68,14 @@ trait FileManager extends FileUtil { else (SFile(LATEST_LIB).parent.parent / "classes" / what).toAbsolute.path } + def latestParserCBLib = relativeToLibrary("parser-combinators") + def latestXmlLib = relativeToLibrary("xml") def latestScaladoc = relativeToLibrary("scaladoc") def latestInteractive = relativeToLibrary("interactive") def latestScalapFile = relativeToLibrary("scalap") def latestPaths = List( LATEST_LIB, LATEST_REFLECT, LATEST_COMP, LATEST_PARTEST, LATEST_ACTORS, - latestScalapFile, latestScaladoc, latestInteractive + latestParserCBLib, latestXmlLib, latestScalapFile, latestScaladoc, latestInteractive ) def latestFiles = latestPaths map (p => new java.io.File(p)) def latestUrls = latestFiles map (_.toURI.toURL) diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala index 2e95a01176..c568cf74c0 100644 --- a/src/reflect/scala/reflect/api/BuildUtils.scala +++ b/src/reflect/scala/reflect/api/BuildUtils.scala @@ -66,6 +66,8 @@ private[reflect] trait BuildUtils { self: Universe => def Ident(sym: Symbol): Ident + def Block(stats: List[Tree]): Block + def TypeTree(tp: Type): TypeTree def thisPrefix(sym: Symbol): Type @@ -73,5 +75,45 @@ private[reflect] trait BuildUtils { self: Universe => def setType[T <: Tree](tree: T, tpe: Type): T def setSymbol[T <: Tree](tree: T, sym: Symbol): T + + def mkAnnotationCtor(tree: Tree, args: List[Tree]): Tree + + val FlagsAsBits: FlagsAsBitsExtractor + + trait FlagsAsBitsExtractor { + def unapply(flags: Long): Option[Long] + } + + val TypeApplied: TypeAppliedExtractor + + trait TypeAppliedExtractor { + def unapply(tree: Tree): Some[(Tree, List[Tree])] + } + + val Applied: AppliedExtractor + + trait AppliedExtractor { + def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] + } + + val SyntacticClassDef: SyntacticClassDefExtractor + + trait SyntacticClassDefExtractor { + def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], + constrMods: Modifiers, vparamss: List[List[ValDef]], parents: List[Tree], + selfdef: ValDef, body: List[Tree]): Tree + def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, + List[List[ValDef]], List[Tree], ValDef, List[Tree])] + } + + val TupleN: TupleNExtractor + val TupleTypeN: TupleNExtractor + + trait TupleNExtractor { + def apply(args: List[Tree]): Tree + def unapply(tree: Tree): Option[List[Tree]] + } + + def RefTree(qual: Tree, sym: Symbol): Tree } } diff --git a/src/reflect/scala/reflect/api/Liftable.scala b/src/reflect/scala/reflect/api/Liftable.scala new file mode 100644 index 0000000000..8f6fe066dd --- /dev/null +++ b/src/reflect/scala/reflect/api/Liftable.scala @@ -0,0 +1,32 @@ +package scala.reflect +package api + +trait Liftable[T] { + def apply(universe: api.Universe, value: T): universe.Tree +} + +object Liftable { + private class LiftableConstant[T] extends Liftable[T] { + def apply(universe: Universe, value: T): universe.Tree = + universe.Literal(universe.Constant(value)) + } + + implicit lazy val liftByte: Liftable[Byte] = new LiftableConstant[Byte] + implicit lazy val liftShort: Liftable[Short] = new LiftableConstant[Short] + implicit lazy val liftChar: Liftable[Char] = new LiftableConstant[Char] + implicit lazy val liftInt: Liftable[Int] = new LiftableConstant[Int] + implicit lazy val liftLong: Liftable[Long] = new LiftableConstant[Long] + implicit lazy val liftFloat: Liftable[Float] = new LiftableConstant[Float] + implicit lazy val liftDouble: Liftable[Double] = new LiftableConstant[Double] + implicit lazy val liftBoolean: Liftable[Boolean] = new LiftableConstant[Boolean] + implicit lazy val liftString: Liftable[String] = new LiftableConstant[String] + implicit lazy val liftUnit: Liftable[Unit] = new LiftableConstant[Unit] + + implicit lazy val liftScalaSymbol: Liftable[scala.Symbol] = new Liftable[scala.Symbol] { + def apply(universe: Universe, value: scala.Symbol): universe.Tree = { + import universe._ + val symbol = Select(Ident(TermName("scala")), TermName("Symbol")) + Apply(symbol, List(Literal(Constant(value.name)))) + } + } +} diff --git a/src/reflect/scala/reflect/api/Quasiquotes.scala b/src/reflect/scala/reflect/api/Quasiquotes.scala new file mode 100644 index 0000000000..3895b8b95f --- /dev/null +++ b/src/reflect/scala/reflect/api/Quasiquotes.scala @@ -0,0 +1,20 @@ +package scala.reflect +package api + +import language.experimental.macros + +trait Quasiquotes { self: Universe => + + // implementation is hardwired to `dispatch` method of `scala.tools.reflect.quasiquotes.Quasiquotes` + // using the mechanism implemented in `scala.tools.reflect.FastTrack` + implicit class Quasiquote(ctx: StringContext) { + protected trait api { + def apply(args: Any*): Any = macro ??? + def unapply(subpatterns: Any*): Option[Any] = macro ??? + } + object q extends api + object tq extends api + object cq extends api + object pq extends api + } +} diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala new file mode 100644 index 0000000000..ecea550225 --- /dev/null +++ b/src/reflect/scala/reflect/api/StandardLiftables.scala @@ -0,0 +1,36 @@ +package scala.reflect +package api + +trait StandardLiftables { self: Universe => + + private def requireSameUniverse[T](universe: Universe, tp: String, value: T) = + require(universe eq self, s"Can't lift $tp ${showRaw(value)} from universe ${showRaw(universe)} using lift$tp defined for ${showRaw(self)}.") + + implicit def liftExpr[T <: Expr[_]]: Liftable[T] = new Liftable[T] { + def apply(universe: Universe, value: T): universe.Tree = { + requireSameUniverse(universe, "Expr", value) + value.tree.asInstanceOf[universe.Tree] + } + } + + implicit def liftType[T <: Type]: Liftable[T] = new Liftable[T] { + def apply(universe: Universe, value: T): universe.Tree = { + requireSameUniverse(universe, "Type", value) + universe.TypeTree(value.asInstanceOf[universe.Type]) + } + } + + implicit def liftTypeTag[T <: WeakTypeTag[_]]: Liftable[T] = new Liftable[T] { + def apply(universe: Universe, value: T): universe.Tree = { + requireSameUniverse(universe, "TypeTag", value) + universe.TypeTree(value.asInstanceOf[universe.WeakTypeTag[_]].tpe) + } + } + + implicit def liftConstant[T <: Constant]: Liftable[T] = new Liftable[T] { + def apply(universe: Universe, value: T): universe.Tree = { + requireSameUniverse(universe, "Constant", value) + universe.Literal(value.asInstanceOf[universe.Constant]) + } + } +} diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala index cb629f9c5a..77b4827eab 100644 --- a/src/reflect/scala/reflect/api/Universe.scala +++ b/src/reflect/scala/reflect/api/Universe.scala @@ -72,10 +72,12 @@ abstract class Universe extends Symbols with ImplicitTags with StandardDefinitions with StandardNames + with StandardLiftables with BuildUtils with Mirrors with Printers with Importers + with Quasiquotes { /** Use `refiy` to produce the abstract syntax tree representing a given Scala expression. * diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index ece2d28be3..cdebfe52f8 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -2,7 +2,10 @@ package scala package reflect package internal +import Flags._ + trait BuildUtils { self: SymbolTable => + import definitions.{TupleClass, MaxTupleArity, ScalaPackage, UnitClass} class BuildImpl extends BuildApi { @@ -52,6 +55,12 @@ trait BuildUtils { self: SymbolTable => def Ident(sym: Symbol): Ident = self.Ident(sym) + def Block(stats: List[Tree]): Block = stats match { + case Nil => self.Block(Nil, Literal(Constant(()))) + case elem :: Nil => self.Block(Nil, elem) + case elems => self.Block(elems.init, elems.last) + } + def TypeTree(tp: Type): TypeTree = self.TypeTree(tp) def thisPrefix(sym: Symbol): Type = sym.thisPrefix @@ -59,6 +68,117 @@ trait BuildUtils { self: SymbolTable => def setType[T <: Tree](tree: T, tpe: Type): T = { tree.setType(tpe); tree } def setSymbol[T <: Tree](tree: T, sym: Symbol): T = { tree.setSymbol(sym); tree } + + def mkAnnotationCtor(tree: Tree, args: List[Tree]): Tree = tree match { + case ident: Ident => Apply(self.Select(New(ident), nme.CONSTRUCTOR: TermName), args) + case call @ Apply(Select(New(ident: Ident), nme.CONSTRUCTOR), _) => + if (args.nonEmpty) + throw new IllegalArgumentException("Can't splice annotation that already contains args with extra args, consider merging these lists together") + call + case _ => throw new IllegalArgumentException(s"Tree ${showRaw(tree)} isn't a correct representation of annotation, consider passing Ident as a first argument") + } + + object FlagsAsBits extends FlagsAsBitsExtractor { + def unapply(flags: Long): Some[Long] = Some(flags) + } + + object TypeApplied extends TypeAppliedExtractor { + def unapply(tree: Tree): Some[(Tree, List[Tree])] = tree match { + case TypeApply(fun, targs) => Some((fun, targs)) + case _ => Some((tree, Nil)) + } + } + + object Applied extends AppliedExtractor { + def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] = { + val treeInfo.Applied(fun, targs, argss) = tree + targs match { + case Nil => Some((fun, argss)) + case _ => Some((TypeApply(fun, targs), argss)) + } + } + } + + object SyntacticClassDef extends SyntacticClassDefExtractor { + def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], + constrMods: Modifiers, vparamss: List[List[ValDef]], parents: List[Tree], + selfdef: ValDef, body: List[Tree]): Tree = + ClassDef(mods, name, tparams, gen.mkTemplate(parents, selfdef, constrMods, vparamss, body, NoPosition)) + + def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, + List[List[ValDef]], List[Tree], ValDef, List[Tree])] = tree match { + case ClassDef(mods, name, tparams, Template(parents, selfdef, tbody)) => + // extract generated fieldDefs and constructor + val (defs, (ctor: DefDef) :: body) = tbody.splitAt(tbody.indexWhere { + case DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => true + case _ => false + }) + val (earlyDefs, fieldDefs) = defs.span(treeInfo.isEarlyDef) + + // undo conversion from (implicit ... ) to ()(implicit ... ) when its the only parameter section + val vparamssRestoredImplicits = ctor.vparamss match { + case Nil :: rest if !rest.isEmpty && !rest.head.isEmpty && rest.head.head.mods.isImplicit => rest + case other => other + } + + // undo flag modifications by mergeing flag info from constructor args and fieldDefs + val modsMap = fieldDefs.map { case ValDef(mods, name, _, _) => name -> mods }.toMap + val vparamss = mmap(vparamssRestoredImplicits) { vd => + val originalMods = modsMap(vd.name) | (vd.mods.flags & DEFAULTPARAM) + atPos(vd.pos)(ValDef(originalMods, vd.name, vd.tpt, vd.rhs)) + } + + Some((mods, name, tparams, ctor.mods, vparamss, parents, selfdef, earlyDefs ::: body)) + case _ => + None + } + } + + object TupleN extends TupleNExtractor { + def apply(args: List[Tree]): Tree = args match { + case Nil => Literal(Constant(())) + case _ => + require(args.length <= MaxTupleArity, s"Tuples with arity bigger than $MaxTupleArity aren't supported") + self.Apply(TupleClass(args.length).companionModule, args: _*) + } + + def unapply(tree: Tree): Option[List[Tree]] = tree match { + case Literal(Constant(())) => + Some(Nil) + case Apply(id: Ident, args) + if args.length <= MaxTupleArity && id.symbol == TupleClass(args.length).companionModule => + Some(args) + case Apply(Select(Ident(nme.scala_), TermName(tuple)), args) + if args.length <= MaxTupleArity && tuple == TupleClass(args.length).name => + Some(args) + case _ => + None + } + } + + object TupleTypeN extends TupleNExtractor { + def apply(args: List[Tree]): Tree = args match { + case Nil => self.Select(self.Ident(nme.scala_), tpnme.Unit) + case _ => + require(args.length <= MaxTupleArity, s"Tuples with arity bigger than $MaxTupleArity aren't supported") + AppliedTypeTree(Ident(TupleClass(args.length)), args) + } + + def unapply(tree: Tree): Option[List[Tree]] = tree match { + case Select(Ident(nme.scala_), tpnme.Unit) => + Some(Nil) + case AppliedTypeTree(id: Ident, args) + if args.length <= MaxTupleArity && id.symbol == TupleClass(args.length) => + Some(args) + case AppliedTypeTree(Select(id @ Ident(nme.scala_), TermName(tuple)), args) + if args.length <= MaxTupleArity && id.symbol == ScalaPackage && tuple == TupleClass(args.length).name => + Some(args) + case _ => + None + } + } + + def RefTree(qual: Tree, sym: Symbol) = self.RefTree(qual, sym.name) setSymbol sym } val build: BuildApi = new BuildImpl diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index bf8ef79a63..6a9fa9a884 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -442,6 +442,7 @@ trait Definitions extends api.StandardDefinitions { // collections classes lazy val ConsClass = requiredClass[scala.collection.immutable.::[_]] lazy val IteratorClass = requiredClass[scala.collection.Iterator[_]] + lazy val IterableClass = requiredClass[scala.collection.Iterable[_]] lazy val ListClass = requiredClass[scala.collection.immutable.List[_]] lazy val SeqClass = requiredClass[scala.collection.Seq[_]] lazy val StringBuilderClass = requiredClass[scala.collection.mutable.StringBuilder] @@ -491,10 +492,8 @@ trait Definitions extends api.StandardDefinitions { lazy val TreesClass = getClassIfDefined("scala.reflect.api.Trees") // defined in scala-reflect.jar, so we need to be careful lazy val TreesTreeType = TreesClass.map(sym => getTypeMember(sym, tpnme.Tree)) - object TreeType { - def unapply(tpe: Type): Boolean = unapply(tpe.typeSymbol) - def unapply(sym: Symbol): Boolean = sym.overrideChain contains TreesTreeType - } + object TreeType { def unapply(tpe: Type): Boolean = tpe.typeSymbol.overrideChain contains TreesTreeType } + object SubtreeType { def unapply(tpe: Type): Boolean = tpe.typeSymbol.overrideChain exists (_.tpe <:< TreesTreeType.tpe) } lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful lazy val ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr)) @@ -520,6 +519,7 @@ trait Definitions extends api.StandardDefinitions { lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful + lazy val LiftableClass = getClassIfDefined("scala.reflect.api.Liftable") // defined in scala-reflect.jar, so we need to be careful lazy val MacroClass = getClassIfDefined("scala.reflect.macros.Macro") // defined in scala-reflect.jar, so we need to be careful lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.Context") // defined in scala-reflect.jar, so we need to be careful @@ -534,6 +534,11 @@ trait Definitions extends api.StandardDefinitions { lazy val StringContextClass = requiredClass[scala.StringContext] def StringContext_f = getMemberMethod(StringContextClass, nme.f) + lazy val QuasiquoteClass = if (ApiUniverseClass != NoSymbol) getMember(ApiUniverseClass, tpnme.Quasiquote) else NoSymbol + lazy val QuasiquoteClass_api = if (QuasiquoteClass != NoSymbol) getMember(QuasiquoteClass, tpnme.api) else NoSymbol + lazy val QuasiquoteClass_api_apply = if (QuasiquoteClass_api != NoSymbol) getMember(QuasiquoteClass_api, nme.apply) else NoSymbol + lazy val QuasiquoteClass_api_unapply = if (QuasiquoteClass_api != NoSymbol) getMember(QuasiquoteClass_api, nme.unapply) else NoSymbol + lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature] lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature] @@ -645,6 +650,10 @@ trait Definitions extends api.StandardDefinitions { isNonTrivial && isMacroCompatible } + def isLiftableType(tp: Type) = tp <:< classExistentialType(LiftableClass) + + def isIterableType(tp: Type) = tp <:< classExistentialType(IterableClass) + lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product] def Product_productArity = getMemberMethod(ProductRootClass, nme.productArity) def Product_productElement = getMemberMethod(ProductRootClass, nme.productElement) @@ -1185,5 +1194,28 @@ trait Definitions extends api.StandardDefinitions { val _ = symbolsNotPresentInBytecode isInitialized = true } //init + + class UniverseDependentTypes(universe: Tree) { + lazy val universeType = universe.tpe + lazy val universeSym = universe.symbol + lazy val nameType = universeMemberType(tpnme.Name) + lazy val termNameType = universeMemberType(tpnme.TypeName) + lazy val typeNameType = universeMemberType(tpnme.TermName) + lazy val modsType = universeMemberType(tpnme.Modifiers) + lazy val flagsType = universeMemberType(tpnme.FlagSet) + lazy val symbolType = universeMemberType(tpnme.Symbol) + lazy val treeType0 = universeMemberType(tpnme.Tree) + lazy val treeType = universeMemberType(tpnme.Tree) + lazy val typeDefType = universeMemberType(tpnme.TypeDef) + lazy val caseDefType = universeMemberType(tpnme.CaseDef) + lazy val iterableTreeType = appliedType(IterableClass, treeType) + lazy val iterableCaseDefType = appliedType(IterableClass, caseDefType) + lazy val iterableIterableTreeType = appliedType(IterableClass, iterableTreeType) + lazy val listTreeType = appliedType(ListClass, treeType) + lazy val listListTreeType = appliedType(ListClass, listTreeType) + lazy val optionTreeType = appliedType(OptionClass, treeType) + lazy val optionNameType = appliedType(OptionClass, nameType) + def universeMemberType(name: TypeName) = universe.tpe.memberType(getTypeMember(universe.symbol, name)) + } } } diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 30aaaa1f3a..64713b8d41 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -216,23 +216,39 @@ trait StdNames { final val Any: NameType = "Any" final val AnyVal: NameType = "AnyVal" + final val FlagSet: NameType = "FlagSet" final val Mirror: NameType = "Mirror" + final val Modifiers: NameType = "Modifiers" final val Nothing: NameType = "Nothing" final val Null: NameType = "Null" final val Object: NameType = "Object" + final val Option: NameType = "Option" final val PrefixType: NameType = "PrefixType" final val Product: NameType = "Product" final val Serializable: NameType = "Serializable" final val Singleton: NameType = "Singleton" final val Throwable: NameType = "Throwable" + final val api: NameType = "api" final val Annotation: NameType = "Annotation" + final val CaseDef: NameType = "CaseDef" final val ClassfileAnnotation: NameType = "ClassfileAnnotation" final val ClassManifest: NameType = "ClassManifest" final val Enum: NameType = "Enum" final val Group: NameType = "Group" + final val Name: NameType = "Name" final val Tree: NameType = "Tree" + final val TermName: NameType = "TermName" final val Type : NameType = "Type" + final val TypeName: NameType = "TypeName" + final val TypeDef: NameType = "TypeDef" + final val Tuple: NameType = "Tuple" + final val Universe: NameType = "Universe" + final val Quasiquote: NameType = "Quasiquote" + + // quasiquote-specific names + final val QUASIQUOTE_MODS: NameType = "$quasiquote$mods$" + final val QUASIQUOTE_TUPLE: NameType = "$quasiquote$tuple$" // Annotation simple names, used in Namer final val BeanPropertyAnnot: NameType = "BeanProperty" @@ -304,6 +320,10 @@ trait StdNames { val REIFY_FREE_THIS_SUFFIX: NameType = "$this" val REIFY_FREE_VALUE_SUFFIX: NameType = "$value" val REIFY_SYMDEF_PREFIX: NameType = "symdef$" + val QUASIQUOTE_PREFIX: String = "qq$" + val QUASIQUOTE_FILE: String = "<quasiquote>" + val QUASIQUOTE_TUPLE: NameType = "$quasiquote$tuple$" + val QUASIQUOTE_CASE: NameType = "$quasiquote$case$" val MIXIN_CONSTRUCTOR: NameType = "$init$" val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$" val OUTER: NameType = "$outer" @@ -539,17 +559,23 @@ trait StdNames { val Annotation: NameType = "Annotation" val Any: NameType = "Any" val AnyVal: NameType = "AnyVal" + val Apply: NameType = "Apply" + val Applied: NameType = "Applied" val ArrayAnnotArg: NameType = "ArrayAnnotArg" + val Block: NameType = "Block" val ConstantType: NameType = "ConstantType" val EmptyPackage: NameType = "EmptyPackage" val EmptyPackageClass: NameType = "EmptyPackageClass" + val False : NameType = "False" val Flag : NameType = "Flag" + val FlagsAsBits: NameType = "FlagsAsBits" val Ident: NameType = "Ident" val Import: NameType = "Import" val Literal: NameType = "Literal" val LiteralAnnotArg: NameType = "LiteralAnnotArg" val Modifiers: NameType = "Modifiers" val NestedAnnotArg: NameType = "NestedAnnotArg" + val New: NameType = "New" val NoFlags: NameType = "NoFlags" val NoSymbol: NameType = "NoSymbol" val Nothing: NameType = "Nothing" @@ -560,10 +586,15 @@ trait StdNames { val Select: NameType = "Select" val SelectFromTypeTree: NameType = "SelectFromTypeTree" val StringContext: NameType = "StringContext" + val SyntacticClassDef: NameType = "SyntacticClassDef" val This: NameType = "This" val ThisType: NameType = "ThisType" + val True : NameType = "True" val Tuple2: NameType = "Tuple2" + val TupleN: NameType = "TupleN" + val TupleTypeN: NameType = "TupleTypeN" val TYPE_ : NameType = "TYPE" + val TypeApplied: NameType = "TypeApplied" val TypeRef: NameType = "TypeRef" val TypeTree: NameType = "TypeTree" val UNIT : NameType = "UNIT" @@ -593,6 +624,7 @@ trait StdNames { val checkInitialized: NameType = "checkInitialized" val classOf: NameType = "classOf" val clone_ : NameType = "clone" + val collection: NameType = "collection" val conforms: NameType = "conforms" val copy: NameType = "copy" val create: NameType = "create" @@ -619,10 +651,13 @@ trait StdNames { val find_ : NameType = "find" val flagsFromBits : NameType = "flagsFromBits" val flatMap: NameType = "flatMap" + val flatten: NameType = "flatten" + val foldLeft: NameType = "foldLeft" val foreach: NameType = "foreach" val get: NameType = "get" val hashCode_ : NameType = "hashCode" val hash_ : NameType = "hash" + val immutable: NameType = "immutable" val implicitly: NameType = "implicitly" val in: NameType = "in" val inlinedEquals: NameType = "inlinedEquals" @@ -644,12 +679,15 @@ trait StdNames { val materializeWeakTypeTag: NameType = "materializeWeakTypeTag" val materializeTypeTag: NameType = "materializeTypeTag" val moduleClass : NameType = "moduleClass" + val mkAnnotationCtor: NameType = "mkAnnotationCtor" 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 nmeCONSTRUCTOR: NameType = "CONSTRUCTOR" + val nmeNme: NameType = "nme" val notifyAll_ : NameType = "notifyAll" val notify_ : NameType = "notify" val null_ : NameType = "null" @@ -665,6 +703,7 @@ trait StdNames { val runtime: NameType = "runtime" val runtimeClass: NameType = "runtimeClass" val runtimeMirror: NameType = "runtimeMirror" + val RefTree: NameType = "RefTree" val scala_ : NameType = "scala" val selectDynamic: NameType = "selectDynamic" val selectOverloadedMethod: NameType = "selectOverloadedMethod" @@ -684,6 +723,7 @@ trait StdNames { val this_ : NameType = "this" val thisPrefix : NameType = "thisPrefix" val toArray: NameType = "toArray" + val toList: NameType = "toList" val toObjectArray : NameType = "toObjectArray" val TopScope: NameType = "TopScope" val toString_ : NameType = "toString" @@ -694,6 +734,7 @@ trait StdNames { val typedProductIterator: NameType = "typedProductIterator" val TypeName: NameType = "TypeName" val typeTagToManifest: NameType = "typeTagToManifest" + val unapply: NameType = "unapply" val unapplySeq: NameType = "unapplySeq" val unbox: NameType = "unbox" @@ -708,6 +749,12 @@ trait StdNames { val withFilter: NameType = "withFilter" val zero: NameType = "zero" + // quasiquote interpolators: + val q: NameType = "q" + val tq: NameType = "tq" + val cq: NameType = "cq" + val pq: NameType = "pq" + // unencoded operators object raw { final val BANG : NameType = "!" @@ -744,6 +791,7 @@ trait StdNames { val ADD = encode("+") val AND = encode("&") val ASR = encode(">>") + val CONS = encode("::") val DIV = encode("/") val EQ = encode("==") val EQL = encode("=") @@ -760,6 +808,7 @@ trait StdNames { val NE = encode("!=") val OR = encode("|") val PLUS = ADD // technically redundant, but ADD looks funny with MINUS + val PLUSPLUS = encode("++") val SUB = MINUS // ... as does SUB with PLUS val XOR = encode("^") val ZAND = encode("&&") diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index b75fd72526..1af8c225f5 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -2,6 +2,8 @@ package scala package reflect package internal +import Flags._ + abstract class TreeGen extends macros.TreeBuilder { val global: SymbolTable @@ -302,4 +304,78 @@ abstract class TreeGen extends macros.TreeBuilder { val factory = Select(gen.mkAttributedRef(SeqModule), nme.apply) Apply(factory, List(arg)) } + + def mkSuperInitCall: Select = Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR) + + /** Generates a template with constructor corresponding to + * + * constrmods (vparams1_) ... (vparams_n) preSuper { presupers } + * extends superclass(args_1) ... (args_n) with mixins { self => body } + * + * This gets translated to + * + * extends superclass with mixins { self => + * presupers' // presupers without rhs + * vparamss // abstract fields corresponding to value parameters + * def <init>(vparamss) { + * presupers + * super.<init>(args) + * } + * body + * } + */ + def mkTemplate(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): Template = { + /* Add constructor to template */ + + // create parameters for <init> as synthetic trees. + var vparamss1 = mmap(vparamss) { vd => + atPos(vd.pos.focus) { + val mods = Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) + ValDef(mods withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, vd.rhs.duplicate) + } + } + val (edefs, rest) = body span treeInfo.isEarlyDef + val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef + val gvdefs = evdefs map { + case vdef @ ValDef(_, _, tpt, _) => + copyValDef(vdef)( + // atPos for the new tpt is necessary, since the original tpt might have no position + // (when missing type annotation for ValDef for example), so even though setOriginal modifies the + // position of TypeTree, it would still be NoPosition. That's what the author meant. + tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus), + rhs = EmptyTree + ) + } + val lvdefs = evdefs collect { case vdef: ValDef => copyValDef(vdef)(mods = vdef.mods | PRESUPER) } + + val constrs = { + if (constrMods hasFlag TRAIT) { + if (body forall treeInfo.isInterfaceMember) List() + else List( + atPos(wrappingPos(superPos, lvdefs)) ( + DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(Nil), TypeTree(), Block(lvdefs, Literal(Constant()))))) + } else { + // convert (implicit ... ) to ()(implicit ... ) if its the only parameter section + if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit) + vparamss1 = List() :: vparamss1 + val superRef: Tree = atPos(superPos)(mkSuperInitCall) + val superCall = pendingSuperCall // we can't know in advance which of the parents will end up as a superclass + // this requires knowing which of the parents is a type macro and which is not + // and that's something that cannot be found out before typer + // (the type macros aren't in the trunk yet, but there is a plan for them to land there soon) + // this means that we don't know what will be the arguments of the super call + // therefore here we emit a dummy which gets populated when the template is named and typechecked + List( + // TODO: previously this was `wrappingPos(superPos, lvdefs ::: argss.flatten)` + // is it going to be a problem that we can no longer include the `argss`? + atPos(wrappingPos(superPos, lvdefs)) ( + DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant()))))) + } + } + constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus=false)) + // Field definitions for the class - remove defaults. + val fieldDefs = vparamss.flatten map (vd => copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree)) + + global.Template(parents, self, gvdefs ::: fieldDefs ::: constrs ::: etdefs ::: rest) + } } diff --git a/src/repl/scala/tools/nsc/interpreter/ConsoleReaderHelper.scala b/src/repl/scala/tools/nsc/interpreter/ConsoleReaderHelper.scala index 48af261937..cf03ecb480 100644 --- a/src/repl/scala/tools/nsc/interpreter/ConsoleReaderHelper.scala +++ b/src/repl/scala/tools/nsc/interpreter/ConsoleReaderHelper.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package interpreter -import scala.tools.jline.console.{ ConsoleReader, CursorBuffer } +import jline.console.{ ConsoleReader, CursorBuffer } trait ConsoleReaderHelper extends ConsoleReader { def terminal = getTerminal() diff --git a/src/repl/scala/tools/nsc/interpreter/Delimited.scala b/src/repl/scala/tools/nsc/interpreter/Delimited.scala index e88a044931..b7f06f1d0a 100644 --- a/src/repl/scala/tools/nsc/interpreter/Delimited.scala +++ b/src/repl/scala/tools/nsc/interpreter/Delimited.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package interpreter -import scala.tools.jline.console.completer.ArgumentCompleter.{ ArgumentDelimiter, ArgumentList } +import jline.console.completer.ArgumentCompleter.{ ArgumentDelimiter, ArgumentList } class JLineDelimiter extends ArgumentDelimiter { def toJLine(args: List[String], cursor: Int) = args match { diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala index a84d076e76..a623ee5055 100644 --- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala @@ -7,22 +7,22 @@ package scala package tools.nsc package interpreter -import Predef.{ println => _, _ } -import java.io.{ BufferedReader, FileReader } -import session._ +import scala.language.{ implicitConversions, existentials } import scala.annotation.tailrec +import Predef.{ println => _, _ } +import interpreter.session._ +import StdReplTags._ import scala.util.Properties.{ jdkHome, javaVersion, versionString, javaVmName } -import util.{ ClassPath, Exceptional, stringFromWriter, stringFromStream } -import io.{ File, Directory } -import util.ScalaClassLoader +import scala.tools.nsc.util.{ ClassPath, Exceptional, stringFromWriter, stringFromStream } +import scala.reflect.classTag +import scala.reflect.internal.util.{ BatchSourceFile, ScalaClassLoader } import ScalaClassLoader._ +import scala.reflect.io.{ File, Directory } import scala.tools.util._ -import scala.language.{implicitConversions, existentials} -import scala.reflect.classTag -import StdReplTags._ +import scala.collection.generic.Clearable import scala.concurrent.{ ExecutionContext, Await, Future, future } import ExecutionContext.Implicits._ -import scala.reflect.internal.util.BatchSourceFile +import java.io.{ BufferedReader, FileReader } /** The Scala interactive shell. It provides a read-eval-print loop * around the Interpreter class. @@ -208,19 +208,23 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) /** Standard commands **/ lazy val standardCommands = List( cmd("cp", "<path>", "add a jar or directory to the classpath", addClasspath), + cmd("edit", "<id>|<line>", "edit history", editCommand), cmd("help", "[command]", "print this summary or command-specific help", helpCommand), historyCommand, cmd("h?", "<string>", "search the history", searchHistory), cmd("imports", "[name name ...]", "show import history, identifying sources of names", importsCommand), cmd("implicits", "[-v]", "show the implicits in scope", intp.implicitsCommand), cmd("javap", "<path|class>", "disassemble a file or class name", javapCommand), - cmd("load", "<path>", "load and interpret a Scala file", loadCommand), - nullary("paste", "enter paste mode: all input up to ctrl-D compiled together", pasteCommand), + cmd("line", "<id>|<line>", "place line(s) at the end of history", lineCommand), + cmd("load", "<path>", "interpret lines in a file", loadCommand), + cmd("paste", "[-raw] [path]", "enter paste mode or paste a file", pasteCommand), nullary("power", "enable power user mode", powerCmd), nullary("quit", "exit the interpreter", () => Result(keepRunning = false, None)), nullary("replay", "reset execution and replay all previous commands", replay), nullary("reset", "reset the repl to its initial state, forgetting all session entries", resetCommand), + cmd("save", "<path>", "save replayable session to a file", saveCommand), shCommand, + cmd("settings", "[+|-]<options>", "+enable/-disable flags, set compiler options", changeSettings), nullary("silent", "disable/enable automatic printing of results", verbosity), cmd("type", "[-v] <expr>", "display the type of an expression without evaluating it", typeCommand), cmd("kind", "[-v] <expr>", "display the kind of expression's type", kindCommand), @@ -300,6 +304,49 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) intp.lastWarnings foreach { case (pos, msg) => intp.reporter.warning(pos, msg) } } + private def changeSettings(args: String): Result = { + def showSettings() = { + for (s <- settings.userSetSettings.toSeq.sorted) echo(s.toString) + } + def updateSettings() = { + // put aside +flag options + val (pluses, rest) = (args split "\\s+").toList partition (_.startsWith("+")) + val tmps = new Settings + val (ok, leftover) = tmps.processArguments(rest, processAll = true) + if (!ok) echo("Bad settings request.") + else if (leftover.nonEmpty) echo("Unprocessed settings.") + else { + // boolean flags set-by-user on tmp copy should be off, not on + val offs = tmps.userSetSettings filter (_.isInstanceOf[Settings#BooleanSetting]) + val (minuses, nonbools) = rest partition (arg => offs exists (_ respondsTo arg)) + // update non-flags + settings.processArguments(nonbools, processAll = true) + // also snag multi-value options for clearing, e.g. -Ylog: and -language: + for { + s <- settings.userSetSettings + if s.isInstanceOf[Settings#MultiStringSetting] || s.isInstanceOf[Settings#PhasesSetting] + if nonbools exists (arg => arg.head == '-' && arg.last == ':' && (s respondsTo arg.init)) + } s match { + case c: Clearable => c.clear() + case _ => + } + def update(bs: Seq[String], name: String=>String, setter: Settings#Setting=>Unit) = { + for (b <- bs) + settings.lookupSetting(name(b)) match { + case Some(s) => + if (s.isInstanceOf[Settings#BooleanSetting]) setter(s) + else echo(s"Not a boolean flag: $b") + case _ => + echo(s"Not an option: $b") + } + } + update(minuses, identity, _.tryToSetFromPropertyValue("false")) // turn off + update(pluses, "-" + _.drop(1), _.tryToSet(Nil)) // turn on + } + } + if (args.isEmpty) showSettings() else updateSettings() + } + private def javapCommand(line: String): Result = { if (javap == null) ":javap unavailable, no tools.jar at %s. Set JDK_HOME.".format(jdkHome) @@ -442,6 +489,90 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) unleashAndSetPhase() } + def lineCommand(what: String): Result = editCommand(what, None) + + // :edit id or :edit line + def editCommand(what: String): Result = editCommand(what, Properties.envOrNone("EDITOR")) + + def editCommand(what: String, editor: Option[String]): Result = { + def diagnose(code: String) = { + echo("The edited code is incomplete!\n") + val errless = intp compileSources new BatchSourceFile("<pastie>", s"object pastel {\n$code\n}") + if (errless) echo("The compiler reports no errors.") + } + def historicize(text: String) = history match { + case jlh: JLineHistory => text.lines foreach jlh.add ; jlh.moveToEnd() ; true + case _ => false + } + def edit(text: String): Result = editor match { + case Some(ed) => + val tmp = File.makeTemp() + tmp.writeAll(text) + try { + val pr = new ProcessResult(s"$ed ${tmp.path}") + pr.exitCode match { + case 0 => + tmp.safeSlurp() match { + case Some(edited) if edited.trim.isEmpty => echo("Edited text is empty.") + case Some(edited) => + echo(edited.lines map ("+" + _) mkString "\n") + val res = intp interpret edited + if (res == IR.Incomplete) diagnose(edited) + else { + historicize(edited) + Result(lineToRecord = Some(edited), keepRunning = true) + } + case None => echo("Can't read edited text. Did you delete it?") + } + case x => echo(s"Error exit from $ed ($x), ignoring") + } + } finally { + tmp.delete() + } + case None => + if (historicize(text)) echo("Placing text in recent history.") + else echo(f"No EDITOR defined and you can't change history, echoing your text:%n$text") + } + + // if what is a number, use it as a line number or range in history + def isNum = what forall (c => c.isDigit || c == '-' || c == '+') + // except that "-" means last value + def isLast = (what == "-") + if (isLast || !isNum) { + val name = if (isLast) intp.mostRecentVar else what + val sym = intp.symbolOfIdent(name) + intp.prevRequestList collectFirst { case r if r.defines contains sym => r } match { + case Some(req) => edit(req.line) + case None => echo(s"No symbol in scope: $what") + } + } else try { + val s = what + // line 123, 120+3, -3, 120-123, 120-, note -3 is not 0-3 but (cur-3,cur) + val (start, len) = + if ((s indexOf '+') > 0) { + val (a,b) = s splitAt (s indexOf '+') + (a.toInt, b.drop(1).toInt) + } else { + (s indexOf '-') match { + case -1 => (s.toInt, 1) + case 0 => val n = s.drop(1).toInt ; (history.index - n, n) + case _ if s.last == '-' => val n = s.init.toInt ; (n, history.index - n) + case i => val n = s.take(i).toInt ; (n, s.drop(i+1).toInt - n) + } + } + import scala.collection.JavaConverters._ + val index = (start - 1) max 0 + val text = history match { + case jlh: JLineHistory => jlh.entries(index).asScala.take(len) map (_.value) mkString "\n" + case _ => history.asStrings.slice(index, index + len) mkString "\n" + } + edit(text) + } catch { + case _: NumberFormatException => echo(s"Bad range '$what'") + echo("Use line 123, 120+3, -3, 120-123, 120-, note -3 is not 0-3 but (cur-3,cur)") + } + } + /** fork a shell and run a command */ lazy val shCommand = new LoopCommand("sh", "run a shell command (result is implicitly => List[String])") { override def usage = "<command line>" @@ -454,11 +585,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) } } - def withFile(filename: String)(action: File => Unit) { - val f = File(filename) - - if (f.exists) action(f) - else echo("That file does not exist") + def withFile[A](filename: String)(action: File => A): Option[A] = { + val res = Some(File(filename)) filter (_.exists) map action + if (res.isEmpty) echo("That file does not exist") // courtesy side-effect + res } def loadCommand(arg: String) = { @@ -470,6 +600,12 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) Result(keepRunning = true, shouldReplay) } + def saveCommand(filename: String): Result = ( + if (filename.isEmpty) echo("File name is required.") + else if (replayCommandStack.isEmpty) echo("No replay commands in session") + else File(filename).printlnAll(replayCommands: _*) + ) + def addClasspath(arg: String): Unit = { val f = File(arg).normalize if (f.exists) { @@ -528,13 +664,40 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) Iterator continually in.readLine("") takeWhile (x => x != null && cond(x)) } - def pasteCommand(): Result = { - echo("// Entering paste mode (ctrl-D to finish)\n") - val code = readWhile(_ => true) mkString "\n" - if (code.trim.isEmpty) { - echo("\n// Nothing pasted, nothing gained.\n") - } else { - echo("\n// Exiting paste mode, now interpreting.\n") + def pasteCommand(arg: String): Result = { + var shouldReplay: Option[String] = None + def result = Result(keepRunning = true, shouldReplay) + val (raw, file) = + if (arg.isEmpty) (false, None) + else { + val r = """(-raw)?(\s+)?([^\-]\S*)?""".r + arg match { + case r(flag, sep, name) => + if (flag != null && name != null && sep == null) + echo(s"""I assume you mean "$flag $name"?""") + (flag != null, Option(name)) + case _ => + echo("usage: :paste -raw file") + return result + } + } + val code = file match { + case Some(name) => + withFile(name)(f => { + shouldReplay = Some(s":paste $arg") + val s = f.slurp.trim + if (s.isEmpty) echo(s"File contains no code: $f") + else echo(s"Pasting file $f...") + s + }) getOrElse "" + case None => + echo("// Entering paste mode (ctrl-D to finish)\n") + val text = (readWhile(_ => true) mkString "\n").trim + if (text.isEmpty) echo("\n// Nothing pasted, nothing gained.\n") + else echo("\n// Exiting paste mode, now interpreting.\n") + text + } + def interpretCode() = { val res = intp interpret code // if input is incomplete, let the compiler try to say why if (res == IR.Incomplete) { @@ -544,7 +707,14 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) if (errless) echo("...but compilation found no error? Good luck with that.") } } - () + def compileCode() = { + val errless = intp compileSources new BatchSourceFile("<pastie>", code) + if (!errless) echo("There were compilation errors!") + } + if (code.nonEmpty) { + if (raw) compileCode() else interpretCode() + } + result } private object paste extends Pasted { diff --git a/src/repl/scala/tools/nsc/interpreter/JLineReader.scala b/src/repl/scala/tools/nsc/interpreter/JLineReader.scala index 5d41f1bbb4..d8a876feb2 100644 --- a/src/repl/scala/tools/nsc/interpreter/JLineReader.scala +++ b/src/repl/scala/tools/nsc/interpreter/JLineReader.scala @@ -6,8 +6,8 @@ package scala.tools.nsc package interpreter -import scala.tools.jline.console.ConsoleReader -import scala.tools.jline.console.completer._ +import jline.console.ConsoleReader +import jline.console.completer._ import session._ import Completion._ @@ -42,7 +42,7 @@ class JLineReader(_completion: => Completion) extends InteractiveReader { def readOneKey(prompt: String) = { this.print(prompt) this.flush() - this.readVirtualKey() + this.readCharacter() } def eraseLine() = consoleReader.resetPromptLine("", "", 0) def redrawLineAndFlush(): Unit = { flush() ; drawLine() ; flush() } diff --git a/src/repl/scala/tools/nsc/interpreter/session/SimpleHistory.scala b/src/repl/scala/tools/nsc/interpreter/session/SimpleHistory.scala index 89998e438a..7c49b91296 100644 --- a/src/repl/scala/tools/nsc/interpreter/session/SimpleHistory.scala +++ b/src/repl/scala/tools/nsc/interpreter/session/SimpleHistory.scala @@ -46,6 +46,11 @@ class SimpleHistory extends JLineHistory { def entries(): JListIterator[JEntry] = toEntries().asJava.listIterator() def iterator: JIterator[JEntry] = toEntries().iterator.asJava + def remove(idx: Int): CharSequence = buf remove idx + def removeFirst(): CharSequence = buf remove 0 + def removeLast(): CharSequence = buf remove lastIndex + def set(idx: Int, to: CharSequence): Unit = buf(idx) = to + def current() = if (index >= 0 && index < buf.size) buf(index) else fail("current()") def previous() = (index > 0) && minusOne def next() = (index <= lastIndex) && plusOne diff --git a/src/repl/scala/tools/nsc/interpreter/session/package.scala b/src/repl/scala/tools/nsc/interpreter/session/package.scala index c62cf21151..a3d7312c98 100644 --- a/src/repl/scala/tools/nsc/interpreter/session/package.scala +++ b/src/repl/scala/tools/nsc/interpreter/session/package.scala @@ -14,10 +14,10 @@ package object session { type JIterator[T] = java.util.Iterator[T] type JListIterator[T] = java.util.ListIterator[T] - type JEntry = scala.tools.jline.console.history.History.Entry - type JHistory = scala.tools.jline.console.history.History - type JMemoryHistory = scala.tools.jline.console.history.MemoryHistory - type JPersistentHistory = scala.tools.jline.console.history.PersistentHistory + type JEntry = jline.console.history.History.Entry + type JHistory = jline.console.history.History + type JMemoryHistory = jline.console.history.MemoryHistory + type JPersistentHistory = jline.console.history.PersistentHistory private[interpreter] implicit def charSequenceFix(x: CharSequence): String = x.toString } diff --git a/src/library/scala/xml/Atom.scala b/src/xml/scala/xml/Atom.scala index 33e58ba7e7..33e58ba7e7 100644 --- a/src/library/scala/xml/Atom.scala +++ b/src/xml/scala/xml/Atom.scala diff --git a/src/library/scala/xml/Attribute.scala b/src/xml/scala/xml/Attribute.scala index e4b2b69fc6..e4b2b69fc6 100644 --- a/src/library/scala/xml/Attribute.scala +++ b/src/xml/scala/xml/Attribute.scala diff --git a/src/library/scala/xml/Comment.scala b/src/xml/scala/xml/Comment.scala index b8dccdcb16..b8dccdcb16 100644 --- a/src/library/scala/xml/Comment.scala +++ b/src/xml/scala/xml/Comment.scala diff --git a/src/library/scala/xml/Document.scala b/src/xml/scala/xml/Document.scala index 9a725014fc..9a725014fc 100644 --- a/src/library/scala/xml/Document.scala +++ b/src/xml/scala/xml/Document.scala diff --git a/src/library/scala/xml/Elem.scala b/src/xml/scala/xml/Elem.scala index 484cf98744..484cf98744 100755 --- a/src/library/scala/xml/Elem.scala +++ b/src/xml/scala/xml/Elem.scala diff --git a/src/library/scala/xml/EntityRef.scala b/src/xml/scala/xml/EntityRef.scala index 7a58831075..7a58831075 100644 --- a/src/library/scala/xml/EntityRef.scala +++ b/src/xml/scala/xml/EntityRef.scala diff --git a/src/library/scala/xml/Equality.scala b/src/xml/scala/xml/Equality.scala index 021d185812..021d185812 100644 --- a/src/library/scala/xml/Equality.scala +++ b/src/xml/scala/xml/Equality.scala diff --git a/src/library/scala/xml/Group.scala b/src/xml/scala/xml/Group.scala index e3af615008..e3af615008 100644 --- a/src/library/scala/xml/Group.scala +++ b/src/xml/scala/xml/Group.scala diff --git a/src/library/scala/xml/MalformedAttributeException.scala b/src/xml/scala/xml/MalformedAttributeException.scala index d499ad3e10..d499ad3e10 100644 --- a/src/library/scala/xml/MalformedAttributeException.scala +++ b/src/xml/scala/xml/MalformedAttributeException.scala diff --git a/src/library/scala/xml/MetaData.scala b/src/xml/scala/xml/MetaData.scala index 8b5ea187cb..8b5ea187cb 100644 --- a/src/library/scala/xml/MetaData.scala +++ b/src/xml/scala/xml/MetaData.scala diff --git a/src/library/scala/xml/NamespaceBinding.scala b/src/xml/scala/xml/NamespaceBinding.scala index b320466976..b320466976 100644 --- a/src/library/scala/xml/NamespaceBinding.scala +++ b/src/xml/scala/xml/NamespaceBinding.scala diff --git a/src/library/scala/xml/Node.scala b/src/xml/scala/xml/Node.scala index e121284252..e121284252 100755 --- a/src/library/scala/xml/Node.scala +++ b/src/xml/scala/xml/Node.scala diff --git a/src/library/scala/xml/NodeBuffer.scala b/src/xml/scala/xml/NodeBuffer.scala index ae7c7b2bf8..ae7c7b2bf8 100644 --- a/src/library/scala/xml/NodeBuffer.scala +++ b/src/xml/scala/xml/NodeBuffer.scala diff --git a/src/library/scala/xml/NodeSeq.scala b/src/xml/scala/xml/NodeSeq.scala index b8022472fb..b8022472fb 100644 --- a/src/library/scala/xml/NodeSeq.scala +++ b/src/xml/scala/xml/NodeSeq.scala diff --git a/src/library/scala/xml/Null.scala b/src/xml/scala/xml/Null.scala index f763c023c4..f763c023c4 100644 --- a/src/library/scala/xml/Null.scala +++ b/src/xml/scala/xml/Null.scala diff --git a/src/library/scala/xml/PCData.scala b/src/xml/scala/xml/PCData.scala index 31eea2b6d7..31eea2b6d7 100644 --- a/src/library/scala/xml/PCData.scala +++ b/src/xml/scala/xml/PCData.scala diff --git a/src/library/scala/xml/PrefixedAttribute.scala b/src/xml/scala/xml/PrefixedAttribute.scala index 4ab79c8677..4ab79c8677 100644 --- a/src/library/scala/xml/PrefixedAttribute.scala +++ b/src/xml/scala/xml/PrefixedAttribute.scala diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/xml/scala/xml/PrettyPrinter.scala index 9e01905357..9e01905357 100755 --- a/src/library/scala/xml/PrettyPrinter.scala +++ b/src/xml/scala/xml/PrettyPrinter.scala diff --git a/src/library/scala/xml/ProcInstr.scala b/src/xml/scala/xml/ProcInstr.scala index 189c1c6878..189c1c6878 100644 --- a/src/library/scala/xml/ProcInstr.scala +++ b/src/xml/scala/xml/ProcInstr.scala diff --git a/src/library/scala/xml/QNode.scala b/src/xml/scala/xml/QNode.scala index f9e3f1854b..f9e3f1854b 100644 --- a/src/library/scala/xml/QNode.scala +++ b/src/xml/scala/xml/QNode.scala diff --git a/src/library/scala/xml/SpecialNode.scala b/src/xml/scala/xml/SpecialNode.scala index 5fef8ef66c..5fef8ef66c 100644 --- a/src/library/scala/xml/SpecialNode.scala +++ b/src/xml/scala/xml/SpecialNode.scala diff --git a/src/library/scala/xml/Text.scala b/src/xml/scala/xml/Text.scala index debea0c025..debea0c025 100644 --- a/src/library/scala/xml/Text.scala +++ b/src/xml/scala/xml/Text.scala diff --git a/src/library/scala/xml/TextBuffer.scala b/src/xml/scala/xml/TextBuffer.scala index 514b1701af..514b1701af 100644 --- a/src/library/scala/xml/TextBuffer.scala +++ b/src/xml/scala/xml/TextBuffer.scala diff --git a/src/library/scala/xml/TopScope.scala b/src/xml/scala/xml/TopScope.scala index 474fbbbdb5..474fbbbdb5 100644 --- a/src/library/scala/xml/TopScope.scala +++ b/src/xml/scala/xml/TopScope.scala diff --git a/src/library/scala/xml/TypeSymbol.scala b/src/xml/scala/xml/TypeSymbol.scala index fb371ee340..fb371ee340 100644 --- a/src/library/scala/xml/TypeSymbol.scala +++ b/src/xml/scala/xml/TypeSymbol.scala diff --git a/src/library/scala/xml/Unparsed.scala b/src/xml/scala/xml/Unparsed.scala index bc190eb724..bc190eb724 100644 --- a/src/library/scala/xml/Unparsed.scala +++ b/src/xml/scala/xml/Unparsed.scala diff --git a/src/library/scala/xml/UnprefixedAttribute.scala b/src/xml/scala/xml/UnprefixedAttribute.scala index 6fa827da5f..6fa827da5f 100644 --- a/src/library/scala/xml/UnprefixedAttribute.scala +++ b/src/xml/scala/xml/UnprefixedAttribute.scala diff --git a/src/library/scala/xml/Utility.scala b/src/xml/scala/xml/Utility.scala index 9134476401..9134476401 100755 --- a/src/library/scala/xml/Utility.scala +++ b/src/xml/scala/xml/Utility.scala diff --git a/src/library/scala/xml/XML.scala b/src/xml/scala/xml/XML.scala index 020264e509..020264e509 100755 --- a/src/library/scala/xml/XML.scala +++ b/src/xml/scala/xml/XML.scala diff --git a/src/library/scala/xml/Xhtml.scala b/src/xml/scala/xml/Xhtml.scala index 6a12c1a89a..6a12c1a89a 100644 --- a/src/library/scala/xml/Xhtml.scala +++ b/src/xml/scala/xml/Xhtml.scala diff --git a/src/library/scala/xml/dtd/ContentModel.scala b/src/xml/scala/xml/dtd/ContentModel.scala index 4007985dce..4007985dce 100644 --- a/src/library/scala/xml/dtd/ContentModel.scala +++ b/src/xml/scala/xml/dtd/ContentModel.scala diff --git a/src/library/scala/xml/dtd/ContentModelParser.scala b/src/xml/scala/xml/dtd/ContentModelParser.scala index 71b391c422..71b391c422 100644 --- a/src/library/scala/xml/dtd/ContentModelParser.scala +++ b/src/xml/scala/xml/dtd/ContentModelParser.scala diff --git a/src/library/scala/xml/dtd/DTD.scala b/src/xml/scala/xml/dtd/DTD.scala index 16a824fe2c..16a824fe2c 100644 --- a/src/library/scala/xml/dtd/DTD.scala +++ b/src/xml/scala/xml/dtd/DTD.scala diff --git a/src/library/scala/xml/dtd/Decl.scala b/src/xml/scala/xml/dtd/Decl.scala index 8bf859c460..8bf859c460 100644 --- a/src/library/scala/xml/dtd/Decl.scala +++ b/src/xml/scala/xml/dtd/Decl.scala diff --git a/src/library/scala/xml/dtd/DocType.scala b/src/xml/scala/xml/dtd/DocType.scala index 849d560cc9..849d560cc9 100644 --- a/src/library/scala/xml/dtd/DocType.scala +++ b/src/xml/scala/xml/dtd/DocType.scala diff --git a/src/library/scala/xml/dtd/ElementValidator.scala b/src/xml/scala/xml/dtd/ElementValidator.scala index 4830769a7d..4830769a7d 100644 --- a/src/library/scala/xml/dtd/ElementValidator.scala +++ b/src/xml/scala/xml/dtd/ElementValidator.scala diff --git a/src/library/scala/xml/dtd/ExternalID.scala b/src/xml/scala/xml/dtd/ExternalID.scala index 880633d860..880633d860 100644 --- a/src/library/scala/xml/dtd/ExternalID.scala +++ b/src/xml/scala/xml/dtd/ExternalID.scala diff --git a/src/library/scala/xml/dtd/Scanner.scala b/src/xml/scala/xml/dtd/Scanner.scala index 5f9d1ccaed..5f9d1ccaed 100644 --- a/src/library/scala/xml/dtd/Scanner.scala +++ b/src/xml/scala/xml/dtd/Scanner.scala diff --git a/src/library/scala/xml/dtd/Tokens.scala b/src/xml/scala/xml/dtd/Tokens.scala index 07e888e77a..07e888e77a 100644 --- a/src/library/scala/xml/dtd/Tokens.scala +++ b/src/xml/scala/xml/dtd/Tokens.scala diff --git a/src/library/scala/xml/dtd/ValidationException.scala b/src/xml/scala/xml/dtd/ValidationException.scala index 1bfae55286..1bfae55286 100644 --- a/src/library/scala/xml/dtd/ValidationException.scala +++ b/src/xml/scala/xml/dtd/ValidationException.scala diff --git a/src/library/scala/xml/dtd/impl/Base.scala b/src/xml/scala/xml/dtd/impl/Base.scala index 91ff03a93a..91ff03a93a 100644 --- a/src/library/scala/xml/dtd/impl/Base.scala +++ b/src/xml/scala/xml/dtd/impl/Base.scala diff --git a/src/library/scala/xml/dtd/impl/BaseBerrySethi.scala b/src/xml/scala/xml/dtd/impl/BaseBerrySethi.scala index f30309b037..f30309b037 100644 --- a/src/library/scala/xml/dtd/impl/BaseBerrySethi.scala +++ b/src/xml/scala/xml/dtd/impl/BaseBerrySethi.scala diff --git a/src/library/scala/xml/dtd/impl/DetWordAutom.scala b/src/xml/scala/xml/dtd/impl/DetWordAutom.scala index 6f8ba4de72..6f8ba4de72 100644 --- a/src/library/scala/xml/dtd/impl/DetWordAutom.scala +++ b/src/xml/scala/xml/dtd/impl/DetWordAutom.scala diff --git a/src/library/scala/xml/dtd/impl/Inclusion.scala b/src/xml/scala/xml/dtd/impl/Inclusion.scala index 07b6afaeba..07b6afaeba 100644 --- a/src/library/scala/xml/dtd/impl/Inclusion.scala +++ b/src/xml/scala/xml/dtd/impl/Inclusion.scala diff --git a/src/library/scala/xml/dtd/impl/NondetWordAutom.scala b/src/xml/scala/xml/dtd/impl/NondetWordAutom.scala index 0bb19a7e3e..0bb19a7e3e 100644 --- a/src/library/scala/xml/dtd/impl/NondetWordAutom.scala +++ b/src/xml/scala/xml/dtd/impl/NondetWordAutom.scala diff --git a/src/library/scala/xml/dtd/impl/PointedHedgeExp.scala b/src/xml/scala/xml/dtd/impl/PointedHedgeExp.scala index 1720604132..1720604132 100644 --- a/src/library/scala/xml/dtd/impl/PointedHedgeExp.scala +++ b/src/xml/scala/xml/dtd/impl/PointedHedgeExp.scala diff --git a/src/library/scala/xml/dtd/impl/SubsetConstruction.scala b/src/xml/scala/xml/dtd/impl/SubsetConstruction.scala index 632ca1eb18..632ca1eb18 100644 --- a/src/library/scala/xml/dtd/impl/SubsetConstruction.scala +++ b/src/xml/scala/xml/dtd/impl/SubsetConstruction.scala diff --git a/src/library/scala/xml/dtd/impl/SyntaxError.scala b/src/xml/scala/xml/dtd/impl/SyntaxError.scala index a5b8a5aba0..a5b8a5aba0 100644 --- a/src/library/scala/xml/dtd/impl/SyntaxError.scala +++ b/src/xml/scala/xml/dtd/impl/SyntaxError.scala diff --git a/src/library/scala/xml/dtd/impl/WordBerrySethi.scala b/src/xml/scala/xml/dtd/impl/WordBerrySethi.scala index 9bf3fa518b..9bf3fa518b 100644 --- a/src/library/scala/xml/dtd/impl/WordBerrySethi.scala +++ b/src/xml/scala/xml/dtd/impl/WordBerrySethi.scala diff --git a/src/library/scala/xml/dtd/impl/WordExp.scala b/src/xml/scala/xml/dtd/impl/WordExp.scala index a4bb54c1ea..a4bb54c1ea 100644 --- a/src/library/scala/xml/dtd/impl/WordExp.scala +++ b/src/xml/scala/xml/dtd/impl/WordExp.scala diff --git a/src/library/scala/xml/factory/Binder.scala b/src/xml/scala/xml/factory/Binder.scala index 947f99e6a4..947f99e6a4 100755 --- a/src/library/scala/xml/factory/Binder.scala +++ b/src/xml/scala/xml/factory/Binder.scala diff --git a/src/library/scala/xml/factory/LoggedNodeFactory.scala b/src/xml/scala/xml/factory/LoggedNodeFactory.scala index bc074bfc83..bc074bfc83 100644 --- a/src/library/scala/xml/factory/LoggedNodeFactory.scala +++ b/src/xml/scala/xml/factory/LoggedNodeFactory.scala diff --git a/src/library/scala/xml/factory/NodeFactory.scala b/src/xml/scala/xml/factory/NodeFactory.scala index 94801bb554..94801bb554 100644 --- a/src/library/scala/xml/factory/NodeFactory.scala +++ b/src/xml/scala/xml/factory/NodeFactory.scala diff --git a/src/library/scala/xml/factory/XMLLoader.scala b/src/xml/scala/xml/factory/XMLLoader.scala index b69f187039..b69f187039 100644 --- a/src/library/scala/xml/factory/XMLLoader.scala +++ b/src/xml/scala/xml/factory/XMLLoader.scala diff --git a/src/library/scala/xml/include/CircularIncludeException.scala b/src/xml/scala/xml/include/CircularIncludeException.scala index 351f403008..351f403008 100644 --- a/src/library/scala/xml/include/CircularIncludeException.scala +++ b/src/xml/scala/xml/include/CircularIncludeException.scala diff --git a/src/library/scala/xml/include/UnavailableResourceException.scala b/src/xml/scala/xml/include/UnavailableResourceException.scala index 47b176e0f3..47b176e0f3 100644 --- a/src/library/scala/xml/include/UnavailableResourceException.scala +++ b/src/xml/scala/xml/include/UnavailableResourceException.scala diff --git a/src/library/scala/xml/include/XIncludeException.scala b/src/xml/scala/xml/include/XIncludeException.scala index 11e1644d83..11e1644d83 100644 --- a/src/library/scala/xml/include/XIncludeException.scala +++ b/src/xml/scala/xml/include/XIncludeException.scala diff --git a/src/library/scala/xml/include/sax/EncodingHeuristics.scala b/src/xml/scala/xml/include/sax/EncodingHeuristics.scala index 57ab5ed91c..57ab5ed91c 100644 --- a/src/library/scala/xml/include/sax/EncodingHeuristics.scala +++ b/src/xml/scala/xml/include/sax/EncodingHeuristics.scala diff --git a/src/library/scala/xml/include/sax/XIncludeFilter.scala b/src/xml/scala/xml/include/sax/XIncludeFilter.scala index 3fa3beefb0..3fa3beefb0 100644 --- a/src/library/scala/xml/include/sax/XIncludeFilter.scala +++ b/src/xml/scala/xml/include/sax/XIncludeFilter.scala diff --git a/src/library/scala/xml/include/sax/XIncluder.scala b/src/xml/scala/xml/include/sax/XIncluder.scala index 1939fa1875..1939fa1875 100644 --- a/src/library/scala/xml/include/sax/XIncluder.scala +++ b/src/xml/scala/xml/include/sax/XIncluder.scala diff --git a/src/library/scala/xml/package.scala b/src/xml/scala/xml/package.scala index 4001cc5ffb..4001cc5ffb 100644 --- a/src/library/scala/xml/package.scala +++ b/src/xml/scala/xml/package.scala diff --git a/src/library/scala/xml/parsing/ConstructingHandler.scala b/src/xml/scala/xml/parsing/ConstructingHandler.scala index ba416e4301..ba416e4301 100755 --- a/src/library/scala/xml/parsing/ConstructingHandler.scala +++ b/src/xml/scala/xml/parsing/ConstructingHandler.scala diff --git a/src/library/scala/xml/parsing/ConstructingParser.scala b/src/xml/scala/xml/parsing/ConstructingParser.scala index 3caeddabf4..3caeddabf4 100644 --- a/src/library/scala/xml/parsing/ConstructingParser.scala +++ b/src/xml/scala/xml/parsing/ConstructingParser.scala diff --git a/src/library/scala/xml/parsing/DefaultMarkupHandler.scala b/src/xml/scala/xml/parsing/DefaultMarkupHandler.scala index 6ec7474843..6ec7474843 100755 --- a/src/library/scala/xml/parsing/DefaultMarkupHandler.scala +++ b/src/xml/scala/xml/parsing/DefaultMarkupHandler.scala diff --git a/src/library/scala/xml/parsing/ExternalSources.scala b/src/xml/scala/xml/parsing/ExternalSources.scala index bb939bca95..bb939bca95 100644 --- a/src/library/scala/xml/parsing/ExternalSources.scala +++ b/src/xml/scala/xml/parsing/ExternalSources.scala diff --git a/src/library/scala/xml/parsing/FactoryAdapter.scala b/src/xml/scala/xml/parsing/FactoryAdapter.scala index 2154bdf5ba..2154bdf5ba 100644 --- a/src/library/scala/xml/parsing/FactoryAdapter.scala +++ b/src/xml/scala/xml/parsing/FactoryAdapter.scala diff --git a/src/library/scala/xml/parsing/FatalError.scala b/src/xml/scala/xml/parsing/FatalError.scala index ab3cb2a74d..ab3cb2a74d 100644 --- a/src/library/scala/xml/parsing/FatalError.scala +++ b/src/xml/scala/xml/parsing/FatalError.scala diff --git a/src/library/scala/xml/parsing/MarkupHandler.scala b/src/xml/scala/xml/parsing/MarkupHandler.scala index 1ebffb9c90..1ebffb9c90 100755 --- a/src/library/scala/xml/parsing/MarkupHandler.scala +++ b/src/xml/scala/xml/parsing/MarkupHandler.scala diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/xml/scala/xml/parsing/MarkupParser.scala index 3bbd136b67..3bbd136b67 100755 --- a/src/library/scala/xml/parsing/MarkupParser.scala +++ b/src/xml/scala/xml/parsing/MarkupParser.scala diff --git a/src/library/scala/xml/parsing/MarkupParserCommon.scala b/src/xml/scala/xml/parsing/MarkupParserCommon.scala index 57c1651558..57c1651558 100644 --- a/src/library/scala/xml/parsing/MarkupParserCommon.scala +++ b/src/xml/scala/xml/parsing/MarkupParserCommon.scala diff --git a/src/library/scala/xml/parsing/NoBindingFactoryAdapter.scala b/src/xml/scala/xml/parsing/NoBindingFactoryAdapter.scala index 56ac185f47..56ac185f47 100644 --- a/src/library/scala/xml/parsing/NoBindingFactoryAdapter.scala +++ b/src/xml/scala/xml/parsing/NoBindingFactoryAdapter.scala diff --git a/src/library/scala/xml/parsing/TokenTests.scala b/src/xml/scala/xml/parsing/TokenTests.scala index 8dd9cdfaa3..8dd9cdfaa3 100644 --- a/src/library/scala/xml/parsing/TokenTests.scala +++ b/src/xml/scala/xml/parsing/TokenTests.scala diff --git a/src/library/scala/xml/parsing/ValidatingMarkupHandler.scala b/src/xml/scala/xml/parsing/ValidatingMarkupHandler.scala index 1b20901249..1b20901249 100644 --- a/src/library/scala/xml/parsing/ValidatingMarkupHandler.scala +++ b/src/xml/scala/xml/parsing/ValidatingMarkupHandler.scala diff --git a/src/library/scala/xml/parsing/XhtmlEntities.scala b/src/xml/scala/xml/parsing/XhtmlEntities.scala index 3683af202c..3683af202c 100644 --- a/src/library/scala/xml/parsing/XhtmlEntities.scala +++ b/src/xml/scala/xml/parsing/XhtmlEntities.scala diff --git a/src/library/scala/xml/parsing/XhtmlParser.scala b/src/xml/scala/xml/parsing/XhtmlParser.scala index 6ce5bec8d0..6ce5bec8d0 100644 --- a/src/library/scala/xml/parsing/XhtmlParser.scala +++ b/src/xml/scala/xml/parsing/XhtmlParser.scala diff --git a/src/library/scala/xml/persistent/CachedFileStorage.scala b/src/xml/scala/xml/persistent/CachedFileStorage.scala index a1489ef3f4..a1489ef3f4 100644 --- a/src/library/scala/xml/persistent/CachedFileStorage.scala +++ b/src/xml/scala/xml/persistent/CachedFileStorage.scala diff --git a/src/library/scala/xml/persistent/Index.scala b/src/xml/scala/xml/persistent/Index.scala index 9ee45e7086..9ee45e7086 100644 --- a/src/library/scala/xml/persistent/Index.scala +++ b/src/xml/scala/xml/persistent/Index.scala diff --git a/src/library/scala/xml/persistent/SetStorage.scala b/src/xml/scala/xml/persistent/SetStorage.scala index 8db56a2e71..8db56a2e71 100644 --- a/src/library/scala/xml/persistent/SetStorage.scala +++ b/src/xml/scala/xml/persistent/SetStorage.scala diff --git a/src/library/scala/xml/pull/XMLEvent.scala b/src/xml/scala/xml/pull/XMLEvent.scala index 3beb3648e7..3beb3648e7 100644 --- a/src/library/scala/xml/pull/XMLEvent.scala +++ b/src/xml/scala/xml/pull/XMLEvent.scala diff --git a/src/library/scala/xml/pull/XMLEventReader.scala b/src/xml/scala/xml/pull/XMLEventReader.scala index 76e51e17fd..76e51e17fd 100755 --- a/src/library/scala/xml/pull/XMLEventReader.scala +++ b/src/xml/scala/xml/pull/XMLEventReader.scala diff --git a/src/library/scala/xml/pull/package.scala b/src/xml/scala/xml/pull/package.scala index 0e3019446b..0e3019446b 100644 --- a/src/library/scala/xml/pull/package.scala +++ b/src/xml/scala/xml/pull/package.scala diff --git a/src/library/scala/xml/transform/BasicTransformer.scala b/src/xml/scala/xml/transform/BasicTransformer.scala index c98339fd67..c98339fd67 100644 --- a/src/library/scala/xml/transform/BasicTransformer.scala +++ b/src/xml/scala/xml/transform/BasicTransformer.scala diff --git a/src/library/scala/xml/transform/RewriteRule.scala b/src/xml/scala/xml/transform/RewriteRule.scala index 1399ee538d..1399ee538d 100644 --- a/src/library/scala/xml/transform/RewriteRule.scala +++ b/src/xml/scala/xml/transform/RewriteRule.scala diff --git a/src/library/scala/xml/transform/RuleTransformer.scala b/src/xml/scala/xml/transform/RuleTransformer.scala index 3a222ba759..3a222ba759 100644 --- a/src/library/scala/xml/transform/RuleTransformer.scala +++ b/src/xml/scala/xml/transform/RuleTransformer.scala |