summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/ant/FastScalac.scala1
-rw-r--r--src/compiler/scala/tools/ant/Same.scala1
-rw-r--r--src/compiler/scala/tools/ant/ScalaBazaar.scala1
-rw-r--r--src/compiler/scala/tools/ant/ScalaTool.scala1
-rw-r--r--src/compiler/scala/tools/ant/Scalac.scala1
-rw-r--r--src/compiler/scala/tools/ant/Scaladoc.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Break.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Compiler.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Compilers.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Make.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/ScalacFork.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Settings.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/TaskArgs.scala1
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Use.scala1
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala6
-rw-r--r--src/compiler/scala/tools/nsc/CompileClient.scala1
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala1
-rw-r--r--src/compiler/scala/tools/nsc/CompileSocket.scala1
-rw-r--r--src/compiler/scala/tools/nsc/CompilerCommand.scala1
-rw-r--r--src/compiler/scala/tools/nsc/CompilerRun.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ConsoleWriter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/EvalLoop.scala1
-rw-r--r--src/compiler/scala/tools/nsc/FatalError.scala1
-rw-r--r--src/compiler/scala/tools/nsc/GenericRunnerCommand.scala1
-rw-r--r--src/compiler/scala/tools/nsc/GenericRunnerSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala26
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala113
-rw-r--r--src/compiler/scala/tools/nsc/InterpreterCommand.scala1
-rw-r--r--src/compiler/scala/tools/nsc/InterpreterLoop.scala80
-rw-r--r--src/compiler/scala/tools/nsc/InterpreterResults.scala1
-rw-r--r--src/compiler/scala/tools/nsc/InterpreterSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/Main.scala1
-rw-r--r--src/compiler/scala/tools/nsc/MainGenericRunner.scala19
-rw-r--r--src/compiler/scala/tools/nsc/MainInterpreter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/MainTokenMetric.scala1
-rw-r--r--src/compiler/scala/tools/nsc/NewLinePrintWriter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/NoPhase.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ObjectRunner.scala1
-rw-r--r--src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala1
-rw-r--r--src/compiler/scala/tools/nsc/Phase.scala1
-rw-r--r--src/compiler/scala/tools/nsc/PhaseAssembly.scala1
-rw-r--r--src/compiler/scala/tools/nsc/Properties.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ScalaDoc.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala78
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/SubComponent.scala1
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala9
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala79
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Tokens.scala1
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/WorklistAlgorithm.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/CheckerException.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Checkers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ICodes.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Primitives.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Printers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Repository.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/LubException.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/ProgramPoint.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala14
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala10
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocFactory.scala1
-rw-r--r--src/compiler/scala/tools/nsc/doc/Settings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala17
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css60
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/Body.scala1
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala150
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Completion.scala15
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Parsed.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/package.scala11
-rw-r--r--src/compiler/scala/tools/nsc/io/AbstractFile.scala5
-rw-r--r--src/compiler/scala/tools/nsc/io/File.scala1
-rw-r--r--src/compiler/scala/tools/nsc/io/FileOperationException.scala1
-rw-r--r--src/compiler/scala/tools/nsc/io/PlainFile.scala4
-rw-r--r--src/compiler/scala/tools/nsc/io/SourceReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/io/VirtualFile.scala3
-rw-r--r--src/compiler/scala/tools/nsc/io/ZipArchive.scala1
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaTokens.scala1
-rw-r--r--src/compiler/scala/tools/nsc/matching/Matrix.scala4
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala207
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternBindings.scala5
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala167
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugin.scala1
-rw-r--r--src/compiler/scala/tools/nsc/plugins/PluginComponent.scala1
-rw-r--r--src/compiler/scala/tools/nsc/plugins/PluginDescription.scala1
-rw-r--r--src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala1
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugins.scala1
-rw-r--r--src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/reporters/Reporter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala1
-rw-r--r--src/compiler/scala/tools/nsc/reporters/StoreReporter.scala1
-rw-r--r--src/compiler/scala/tools/nsc/settings/AbsSettings.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Flags.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/InfoTransformers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Names.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Scopes.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTable.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala16
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala20
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala16
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/InfoTransform.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala19
-rw-r--r--src/compiler/scala/tools/nsc/transform/OverridingPairs.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/SampleTransform.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala307
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/Transform.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/TypingTransformers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Analyzer.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala24
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Variances.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/CharArrayReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala6
-rwxr-xr-xsrc/compiler/scala/tools/nsc/util/DocStrings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/FreshNameCreator.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/HashSet.scala9
-rw-r--r--src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/RegexCache.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/Set.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/ShowPickled.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/SourceFile.scala181
-rw-r--r--src/compiler/scala/tools/nsc/util/Statistics.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/TreeSet.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/package.scala29
-rw-r--r--src/compiler/scala/tools/util/AbstractTimer.scala1
-rw-r--r--src/compiler/scala/tools/util/SocketConnection.scala1
-rw-r--r--src/compiler/scala/tools/util/SocketServer.scala1
-rw-r--r--src/compiler/scala/tools/util/StringOps.scala1
206 files changed, 960 insertions, 990 deletions
diff --git a/src/compiler/scala/tools/ant/FastScalac.scala b/src/compiler/scala/tools/ant/FastScalac.scala
index 1badd3047b..8c8363a321 100644
--- a/src/compiler/scala/tools/ant/FastScalac.scala
+++ b/src/compiler/scala/tools/ant/FastScalac.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant
diff --git a/src/compiler/scala/tools/ant/Same.scala b/src/compiler/scala/tools/ant/Same.scala
index d5cba4a0bf..4f7173e68b 100644
--- a/src/compiler/scala/tools/ant/Same.scala
+++ b/src/compiler/scala/tools/ant/Same.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant
diff --git a/src/compiler/scala/tools/ant/ScalaBazaar.scala b/src/compiler/scala/tools/ant/ScalaBazaar.scala
index f560883a2d..1c1b0ccb46 100644
--- a/src/compiler/scala/tools/ant/ScalaBazaar.scala
+++ b/src/compiler/scala/tools/ant/ScalaBazaar.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant {
diff --git a/src/compiler/scala/tools/ant/ScalaTool.scala b/src/compiler/scala/tools/ant/ScalaTool.scala
index 90f1fcaeda..db53224b4f 100644
--- a/src/compiler/scala/tools/ant/ScalaTool.scala
+++ b/src/compiler/scala/tools/ant/ScalaTool.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala
index 4ecfc3dc85..6cda588419 100644
--- a/src/compiler/scala/tools/ant/Scalac.scala
+++ b/src/compiler/scala/tools/ant/Scalac.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant
diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala
index 03dc99be68..3d96b959f5 100644
--- a/src/compiler/scala/tools/ant/Scaladoc.scala
+++ b/src/compiler/scala/tools/ant/Scaladoc.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant
diff --git a/src/compiler/scala/tools/ant/sabbus/Break.scala b/src/compiler/scala/tools/ant/sabbus/Break.scala
index e6c89dccf7..95bc5cc14e 100644
--- a/src/compiler/scala/tools/ant/sabbus/Break.scala
+++ b/src/compiler/scala/tools/ant/sabbus/Break.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala b/src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala
index 618350d91f..94e2ceffd2 100644
--- a/src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala
+++ b/src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/Compiler.scala b/src/compiler/scala/tools/ant/sabbus/Compiler.scala
index 2daf664b2e..6d8473ef7d 100644
--- a/src/compiler/scala/tools/ant/sabbus/Compiler.scala
+++ b/src/compiler/scala/tools/ant/sabbus/Compiler.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/Compilers.scala b/src/compiler/scala/tools/ant/sabbus/Compilers.scala
index 6f6986a118..91a8580475 100644
--- a/src/compiler/scala/tools/ant/sabbus/Compilers.scala
+++ b/src/compiler/scala/tools/ant/sabbus/Compilers.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala b/src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala
index 2263196af4..697ec44bd0 100644
--- a/src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala
+++ b/src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/Make.scala b/src/compiler/scala/tools/ant/sabbus/Make.scala
index d1579670ac..9173745472 100644
--- a/src/compiler/scala/tools/ant/sabbus/Make.scala
+++ b/src/compiler/scala/tools/ant/sabbus/Make.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala b/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
index 353499ddb3..689df48a88 100644
--- a/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
+++ b/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant
package sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/Settings.scala b/src/compiler/scala/tools/ant/sabbus/Settings.scala
index 2719196095..2304c31a0b 100644
--- a/src/compiler/scala/tools/ant/sabbus/Settings.scala
+++ b/src/compiler/scala/tools/ant/sabbus/Settings.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/TaskArgs.scala b/src/compiler/scala/tools/ant/sabbus/TaskArgs.scala
index 20a6791648..977bfee3d4 100644
--- a/src/compiler/scala/tools/ant/sabbus/TaskArgs.scala
+++ b/src/compiler/scala/tools/ant/sabbus/TaskArgs.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/ant/sabbus/Use.scala b/src/compiler/scala/tools/ant/sabbus/Use.scala
index fa17c48b63..a466d7b18a 100644
--- a/src/compiler/scala/tools/ant/sabbus/Use.scala
+++ b/src/compiler/scala/tools/ant/sabbus/Use.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.ant.sabbus
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index fb62c7d46c..a9300ff304 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -2,13 +2,11 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
-import scala.tools.nsc.util.{FreshNameCreator,OffsetPosition,Position,NoPosition,SourceFile}
-import scala.tools.nsc.io.AbstractFile
-import scala.collection.mutable.{LinkedHashSet, HashSet, HashMap, ListBuffer}
+import util.{ FreshNameCreator,Position,NoPosition,SourceFile }
+import scala.collection.mutable.{ LinkedHashSet, HashSet, HashMap, ListBuffer }
trait CompilationUnits { self: Global =>
diff --git a/src/compiler/scala/tools/nsc/CompileClient.scala b/src/compiler/scala/tools/nsc/CompileClient.scala
index b672a616c3..c3307cba77 100644
--- a/src/compiler/scala/tools/nsc/CompileClient.scala
+++ b/src/compiler/scala/tools/nsc/CompileClient.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala
index c4f9b1d9f1..832f1e5aef 100644
--- a/src/compiler/scala/tools/nsc/CompileServer.scala
+++ b/src/compiler/scala/tools/nsc/CompileServer.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala
index d4697b69e6..d57016c4e9 100644
--- a/src/compiler/scala/tools/nsc/CompileSocket.scala
+++ b/src/compiler/scala/tools/nsc/CompileSocket.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala
index c8c7482811..54ef6bb8be 100644
--- a/src/compiler/scala/tools/nsc/CompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/CompilerRun.scala b/src/compiler/scala/tools/nsc/CompilerRun.scala
index 63ed4382af..9cac12d896 100644
--- a/src/compiler/scala/tools/nsc/CompilerRun.scala
+++ b/src/compiler/scala/tools/nsc/CompilerRun.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/ConsoleWriter.scala b/src/compiler/scala/tools/nsc/ConsoleWriter.scala
index 95adc47fb8..3c7d10767c 100644
--- a/src/compiler/scala/tools/nsc/ConsoleWriter.scala
+++ b/src/compiler/scala/tools/nsc/ConsoleWriter.scala
@@ -2,7 +2,6 @@
* Copyright 2006-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/EvalLoop.scala b/src/compiler/scala/tools/nsc/EvalLoop.scala
index 388bcf8ccc..d8aa7799cb 100644
--- a/src/compiler/scala/tools/nsc/EvalLoop.scala
+++ b/src/compiler/scala/tools/nsc/EvalLoop.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/FatalError.scala b/src/compiler/scala/tools/nsc/FatalError.scala
index f9a801e611..145eb4c9ee 100644
--- a/src/compiler/scala/tools/nsc/FatalError.scala
+++ b/src/compiler/scala/tools/nsc/FatalError.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
index f3ac556d4f..c088bb9303 100644
--- a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
+++ b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
@@ -3,7 +3,6 @@
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
index 6697146a5a..5d272b06ae 100644
--- a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
+++ b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
@@ -3,7 +3,6 @@
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 0ec36cf9ab..7efd8ad2a0 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
@@ -12,7 +11,7 @@ import compat.Platform.currentTime
import io.{ SourceReader, AbstractFile, Path }
import reporters.{ Reporter, ConsoleReporter }
-import util.{ ClassPath, SourceFile, Statistics, BatchSourceFile }
+import util.{ ClassPath, SourceFile, Statistics, BatchSourceFile, ScriptSourceFile, returning }
import collection.mutable.{ HashSet, HashMap, ListBuffer }
import reflect.generic.{ PickleBuffer }
@@ -220,8 +219,13 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
if (settings.verbose.value || settings.Ylogcp.value)
inform("[Classpath = " + classPath.asClasspathString + "]")
+ /** True if -Xscript has been set, indicating a script run.
+ */
+ def isScriptRun = settings.script.value != ""
+
def getSourceFile(f: AbstractFile): BatchSourceFile =
- new BatchSourceFile(f, reader.read(f))
+ if (isScriptRun) ScriptSourceFile(f, reader read f)
+ else new BatchSourceFile(f, reader read f)
def getSourceFile(name: String): SourceFile = {
val f = AbstractFile.getFile(name)
@@ -796,21 +800,15 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
/** Compile list of abstract files */
def compileFiles(files: List[AbstractFile]) {
- try {
- compileSources(files map getSourceFile)
- } catch {
- case ex: IOException => error(ex.getMessage())
- }
+ try compileSources(files map getSourceFile)
+ catch { case ex: IOException => error(ex.getMessage()) }
}
/** Compile list of files given by their names */
def compile(filenames: List[String]) {
- val scriptMain = settings.script.value
- def sources: List[SourceFile] = scriptMain match {
- case "" => filenames map getSourceFile
- case main if filenames.length == 1 => List(ScriptRunner.wrappedScript(main, filenames.head, getSourceFile))
- case _ => error("can only compile one script at a time") ; Nil
- }
+ val sources: List[SourceFile] =
+ if (isScriptRun && filenames.size > 1) returning(Nil)(_ => error("can only compile one script at a time"))
+ else filenames map getSourceFile
try compileSources(sources)
catch { case ex: IOException => error(ex.getMessage()) }
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index 556a3107cd..128c378e23 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
@@ -27,7 +26,7 @@ import scala.util.control.Exception.{ Catcher, catching, ultimately, unwrapping
import io.{ PlainFile, VirtualDirectory }
import reporters.{ ConsoleReporter, Reporter }
import symtab.{ Flags, Names }
-import util.{ SourceFile, BatchSourceFile, ClassPath, Chars }
+import util.{ SourceFile, BatchSourceFile, ScriptSourceFile, ClassPath, Chars, stringFromWriter }
import scala.reflect.NameTransformer
import scala.tools.nsc.{ InterpreterResults => IR }
import interpreter._
@@ -76,6 +75,11 @@ import Interpreter._
class Interpreter(val settings: Settings, out: PrintWriter) {
repl =>
+ def println(x: Any) = {
+ out.println(x)
+ out.flush()
+ }
+
/** construct an interpreter that reports to Console */
def this(settings: Settings) = this(settings, new NewLinePrintWriter(new ConsoleWriter, true))
def this() = this(new Settings())
@@ -109,28 +113,37 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
|}
|""".stripMargin
- val run = new _compiler.Run()
- run compileSources List(new BatchSourceFile("<init>", source))
- if (settings.debug.value) {
- out println "Repl compiler initialized."
- out.flush()
+ try {
+ new _compiler.Run() compileSources List(new BatchSourceFile("<init>", source))
+ if (isReplDebug || settings.debug.value)
+ println("Repl compiler initialized.")
+ true
+ }
+ catch {
+ case MissingRequirementError(msg) => println("""
+ |Failed to initialize compiler: %s not found.
+ |** Note that as of 2.8 scala does not assume use of the java classpath.
+ |** For the old behavior pass -usejavacp to scala, or if using a Settings
+ |** object programatically, settings.usejavacp.value = true.""".stripMargin.format(msg)
+ )
+ false
}
- true
}
// set up initialization future
- private var _isInitialized: () => Boolean = () => false
+ private var _isInitialized: () => Boolean = null
def initialize() = synchronized {
- if (!_isInitialized())
+ if (_isInitialized == null)
_isInitialized = scala.concurrent.ops future _initialize()
}
/** the public, go through the future compiler */
lazy val compiler: Global = {
initialize()
- _isInitialized() // blocks until it is
- _compiler
+ // blocks until it is ; false means catastrophic failure
+ if (_isInitialized()) _compiler
+ else null
}
import compiler.{ Traverser, CompilationUnit, Symbol, Name, Type }
@@ -174,16 +187,6 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
/** interpreter settings */
lazy val isettings = new InterpreterSettings(this)
- /** Heuristically strip interpreter wrapper prefixes
- * from an interpreter output string.
- */
- def stripWrapperGunk(str: String): String =
- if (isettings.unwrapStrings) {
- val wrapregex = """(line[0-9]+\$object[$.])?(\$iw[$.])*"""
- str.replaceAll(wrapregex, "")
- }
- else str
-
/** Instantiate a compiler. Subclasses can override this to
* change the compiler class used by this interpreter. */
protected def newCompiler(settings: Settings, reporter: Reporter) = {
@@ -237,6 +240,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
private val usedNameMap = new HashMap[Name, Request]()
private val boundNameMap = new HashMap[Name, Request]()
private def allHandlers = prevRequests.toList flatMap (_.handlers)
+ private def allReqAndHandlers = prevRequests.toList flatMap (req => req.handlers map (req -> _))
def printAllTypeOf = {
prevRequests foreach { req =>
@@ -322,15 +326,6 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
def getVarName = varNameCreator()
def getSynthVarName = synthVarNameCreator()
- /** generate a string using a routine that wants to write on a stream */
- private def stringFrom(writer: PrintWriter => Unit): String = {
- val stringWriter = new StringWriter()
- val stream = new NewLinePrintWriter(stringWriter)
- writer(stream)
- stream.close
- stringWriter.toString
- }
-
/** Truncate a string if it is longer than isettings.maxPrintString */
private def truncPrintString(str: String): String = {
val maxpr = isettings.maxPrintString
@@ -341,7 +336,10 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
/** Clean up a string for output */
- private def clean(str: String) = truncPrintString(stripWrapperGunk(str))
+ private def clean(str: String) = truncPrintString(
+ if (isettings.unwrapStrings) stripWrapperGunk(str)
+ else str
+ )
/** Indent some code by the width of the scala> prompt.
* This way, compiler error messages read better.
@@ -350,7 +348,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
def indentCode(code: String) = {
/** Heuristic to avoid indenting and thereby corrupting """-strings and XML literals. */
val noIndent = (code contains "\n") && (List("\"\"\"", "</", "/>") exists (code contains _))
- stringFrom(str =>
+ stringFromWriter(str =>
for (line <- code.lines) {
if (!noIndent)
str.print(spaces)
@@ -419,10 +417,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
/** Flatten the handlers out and pair each with the original request */
- val rhpairs = prevRequests.reverse.toList flatMap { req =>
- req.handlers map (ReqAndHandler(req, _))
- }
- select(rhpairs, wanted).reverse
+ select(allReqAndHandlers reverseMap { case (r, h) => ReqAndHandler(r, h) }, wanted).reverse
}
val code, trailingBraces, accessPath = new StringBuffer
@@ -579,26 +574,28 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
*/
def interpret(line: String): IR.Result = interpret(line, false)
def interpret(line: String, synthetic: Boolean): IR.Result = {
- val req = requestFromLine(line, synthetic) match {
- case Left(result) => return result
- case Right(req) => req
- }
- // null indicates a disallowed statement type; otherwise compile and
- // fail if false (implying e.g. a type error)
- if (req == null || !req.compile)
- return IR.Error
+ def loadAndRunReq(req: Request) = {
+ val (result, succeeded) = req.loadAndRun
+ if (printResults || !succeeded)
+ out print clean(result)
- val (result, succeeded) = req.loadAndRun
- if (printResults || !succeeded)
- out print clean(result)
+ // book-keeping
+ if (succeeded && !synthetic)
+ recordRequest(req)
- if (succeeded) {
- if (!synthetic)
- recordRequest(req) // book-keeping
+ if (succeeded) IR.Success
+ else IR.Error
+ }
- IR.Success
+ if (compiler == null) IR.Error
+ else requestFromLine(line, synthetic) match {
+ case Left(result) => result
+ case Right(req) =>
+ // null indicates a disallowed statement type; otherwise compile and
+ // fail if false (implying e.g. a type error)
+ if (req == null || !req.compile) IR.Error
+ else loadAndRunReq(req)
}
- else IR.Error
}
/** A name creator used for objects created by <code>bind()</code>. */
@@ -682,7 +679,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
def extraCodeToEvaluate(req: Request, code: PrintWriter) { }
def resultExtractionCode(req: Request, code: PrintWriter) { }
- override def toString = "%s(usedNames = %s)".format(this.getClass, usedNames)
+ override def toString = "%s(used = %s)".format(this.getClass.toString split '.' last, usedNames)
}
private class GenericHandler(member: Tree) extends MemberHandler(member)
@@ -840,7 +837,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
def toCompute = line
/** generate the source code for the object that computes this request */
- def objectSourceCode: String = stringFrom { code =>
+ def objectSourceCode: String = stringFromWriter { code =>
val preamble = """
|object %s {
| %s%s
@@ -854,7 +851,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
/** generate source code for the object that retrieves the result
from objectSourceCode */
- def resultObjectSourceCode: String = stringFrom { code =>
+ def resultObjectSourceCode: String = stringFromWriter { code =>
/** We only want to generate this code when the result
* is a value which can be referred to as-is.
*/
@@ -975,7 +972,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
case t: Throwable if bindLastException =>
withoutBindingLastException {
quietBind("lastException", "java.lang.Throwable", t)
- (stringFrom(t.printStackTrace(_)), false)
+ (stringFromWriter(t.printStackTrace(_)), false)
}
}
@@ -985,6 +982,8 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
}
}
+
+ override def toString = "Request(line=%s, %s trees)".format(line, trees.size)
}
/** A container class for methods to be injected into the repl
diff --git a/src/compiler/scala/tools/nsc/InterpreterCommand.scala b/src/compiler/scala/tools/nsc/InterpreterCommand.scala
index 45e139194e..0ac2ef9617 100644
--- a/src/compiler/scala/tools/nsc/InterpreterCommand.scala
+++ b/src/compiler/scala/tools/nsc/InterpreterCommand.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
index 4e8a04de44..f68ce4a5b4 100644
--- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala
+++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Alexander Spoon
*/
-// $Id$
package scala.tools.nsc
@@ -246,31 +245,18 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite
case _ => true
}
- // this is about the illusion of snappiness. We call initialize()
- // which spins off a separate thread, then print the prompt and try
- // our best to look ready. Ideally the user will spend a
- // couple seconds saying "wow, it starts so fast!" and by the time
- // they type a command the compiler is ready to roll.
- interpreter.initialize()
-
while (processLine(readOneLine)) { }
}
/** interpret all lines from a specified file */
- def interpretAllFrom(filename: String) {
- val fileIn = File(filename)
- if (!fileIn.exists)
- return out.println("Error opening file: " + filename)
-
+ def interpretAllFrom(file: File) {
val oldIn = in
val oldReplay = replayCommandStack
- try {
- fileIn applyReader { reader =>
- in = new SimpleReader(reader, out, false)
- plushln("Loading " + filename + "...")
- repl
- }
+ try file applyReader { reader =>
+ in = new SimpleReader(reader, out, false)
+ plushln("Loading " + file + "...")
+ repl()
}
finally {
in = oldIn
@@ -303,8 +289,10 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite
List(("stdout", p.stdout), ("stderr", p.stderr)) foreach (add _).tupled
}
- def withFile(filename: String)(action: String => Unit) {
- if (File(filename).exists) action(filename)
+ def withFile(filename: String)(action: File => Unit) {
+ val f = File(filename)
+
+ if (f.exists) action(f)
else out.println("That file does not exist")
}
@@ -367,10 +355,13 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite
def ambiguous(cmds: List[Command]) = "Ambiguous: did you mean " + cmds.map(":" + _.name).mkString(" or ") + "?"
// not a command
- if (!line.startsWith(":"))
- return Result(true, interpretStartingWith(line))
+ if (!line.startsWith(":")) {
+ // Notice failure to create compiler
+ if (interpreter.compiler == null) return Result(false, None)
+ else return Result(true, interpretStartingWith(line))
+ }
- val tokens = line.substring(1).split("""\s+""").toList
+ val tokens = (line drop 1 split """\s+""").toList
if (tokens.isEmpty)
return withError(ambiguous(commands))
@@ -477,20 +468,25 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite
// signal completion non-completion input has been received
in.completion foreach (_.resetVerbosity())
- def reallyInterpret = {
- interpreter.interpret(code) match {
- case IR.Error => None
- case IR.Success => Some(code)
- case IR.Incomplete =>
- if (in.interactive && code.endsWith("\n\n")) {
- out.println("You typed two blank lines. Starting a new command.")
+ def reallyInterpret = interpreter.interpret(code) match {
+ case IR.Error => None
+ case IR.Success => Some(code)
+ case IR.Incomplete =>
+ if (in.interactive && code.endsWith("\n\n")) {
+ out.println("You typed two blank lines. Starting a new command.")
+ None
+ }
+ else in.readLine(CONTINUATION_STRING) match {
+ case null =>
+ // we know compilation is going to fail since we're at EOF and the
+ // parser thinks the input is still incomplete, but since this is
+ // a file being read non-interactively we want to fail. So we send
+ // it straight to the compiler for the nice error message.
+ interpreter.compileString(code)
None
- }
- else in.readLine(CONTINUATION_STRING) match {
- case null => None // end of file
- case line => interpretStartingWith(code + "\n" + line)
- }
- }
+
+ case line => interpretStartingWith(code + "\n" + line)
+ }
}
/** Here we place ourselves between the user and the interpreter and examine
@@ -552,8 +548,16 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite
if (interpreter.reporter.hasErrors) return
printWelcome()
+
+ // this is about the illusion of snappiness. We call initialize()
+ // which spins off a separate thread, then print the prompt and try
+ // our best to look ready. Ideally the user will spend a
+ // couple seconds saying "wow, it starts so fast!" and by the time
+ // they type a command the compiler is ready to roll.
+ interpreter.initialize()
repl()
- } finally closeInterpreter()
+ }
+ finally closeInterpreter()
}
private def objClass(x: Any) = x.asInstanceOf[AnyRef].getClass
diff --git a/src/compiler/scala/tools/nsc/InterpreterResults.scala b/src/compiler/scala/tools/nsc/InterpreterResults.scala
index 76657a2125..fad3fb653f 100644
--- a/src/compiler/scala/tools/nsc/InterpreterResults.scala
+++ b/src/compiler/scala/tools/nsc/InterpreterResults.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/InterpreterSettings.scala b/src/compiler/scala/tools/nsc/InterpreterSettings.scala
index a5e1c1e729..b53a6f6955 100644
--- a/src/compiler/scala/tools/nsc/InterpreterSettings.scala
+++ b/src/compiler/scala/tools/nsc/InterpreterSettings.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Alexander Spoon
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala
index eaa2970dda..948c5f6fb8 100644
--- a/src/compiler/scala/tools/nsc/Main.scala
+++ b/src/compiler/scala/tools/nsc/Main.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/MainGenericRunner.scala b/src/compiler/scala/tools/nsc/MainGenericRunner.scala
index fdc5fe82dd..936ee3c1db 100644
--- a/src/compiler/scala/tools/nsc/MainGenericRunner.scala
+++ b/src/compiler/scala/tools/nsc/MainGenericRunner.scala
@@ -3,7 +3,6 @@
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
@@ -39,14 +38,23 @@ object MainGenericRunner {
else if (settings.version.value) return errorFn("Scala code runner %s -- %s".format(versionString, copyrightString))
else if (command.shouldStopWithInfo) return errorFn(command getInfoMessage sampleCompiler)
+ def isE = !settings.execute.isDefault
def dashe = settings.execute.value
+
+ def isI = !settings.loadfiles.isDefault
def dashi = settings.loadfiles.value
- def slurp = dashi map (file => File(file).slurp()) mkString "\n"
+
+ def combinedCode = {
+ val files = if (isI) dashi map (file => File(file).slurp()) else Nil
+ val str = if (isE) List(dashe) else Nil
+
+ files ++ str mkString "\n\n"
+ }
val classpath: List[URL] = new PathResolver(settings) asURLs
/** Was code given in a -e argument? */
- if (!settings.execute.isDefault) {
+ if (isE) {
/** If a -i argument was also given, we want to execute the code after the
* files have been included, so they are read into strings and prepended to
* the code given in -e. The -i option is documented to only make sense
@@ -55,11 +63,8 @@ object MainGenericRunner {
* This all needs a rewrite though.
*/
val fullArgs = command.thingToRun.toList ::: command.arguments
- val code =
- if (settings.loadfiles.isDefault) dashe
- else slurp + "\n" + dashe
- exitCond(ScriptRunner.runCommand(settings, code, fullArgs))
+ exitCond(ScriptRunner.runCommand(settings, combinedCode, fullArgs))
}
else command.thingToRun match {
case None =>
diff --git a/src/compiler/scala/tools/nsc/MainInterpreter.scala b/src/compiler/scala/tools/nsc/MainInterpreter.scala
index 568705aff1..0a0d1e4a33 100644
--- a/src/compiler/scala/tools/nsc/MainInterpreter.scala
+++ b/src/compiler/scala/tools/nsc/MainInterpreter.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/MainTokenMetric.scala b/src/compiler/scala/tools/nsc/MainTokenMetric.scala
index 9c123922d6..fc0ea67051 100644
--- a/src/compiler/scala/tools/nsc/MainTokenMetric.scala
+++ b/src/compiler/scala/tools/nsc/MainTokenMetric.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/NewLinePrintWriter.scala b/src/compiler/scala/tools/nsc/NewLinePrintWriter.scala
index ecb436d8a9..4ced491a8d 100644
--- a/src/compiler/scala/tools/nsc/NewLinePrintWriter.scala
+++ b/src/compiler/scala/tools/nsc/NewLinePrintWriter.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
import java.io.{Writer, PrintWriter}
diff --git a/src/compiler/scala/tools/nsc/NoPhase.scala b/src/compiler/scala/tools/nsc/NoPhase.scala
index a6907ddf58..8f5e3e440c 100644
--- a/src/compiler/scala/tools/nsc/NoPhase.scala
+++ b/src/compiler/scala/tools/nsc/NoPhase.scala
@@ -2,7 +2,6 @@
* Copyright 2007-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/ObjectRunner.scala b/src/compiler/scala/tools/nsc/ObjectRunner.scala
index 210f9a1785..f2ddc84445 100644
--- a/src/compiler/scala/tools/nsc/ObjectRunner.scala
+++ b/src/compiler/scala/tools/nsc/ObjectRunner.scala
@@ -3,7 +3,6 @@
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala
index b011f88f2b..ae56941633 100644
--- a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/Phase.scala b/src/compiler/scala/tools/nsc/Phase.scala
index 98f0f840ff..882b96d84d 100644
--- a/src/compiler/scala/tools/nsc/Phase.scala
+++ b/src/compiler/scala/tools/nsc/Phase.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/PhaseAssembly.scala b/src/compiler/scala/tools/nsc/PhaseAssembly.scala
index b3300a1ff9..e0cc91cb80 100644
--- a/src/compiler/scala/tools/nsc/PhaseAssembly.scala
+++ b/src/compiler/scala/tools/nsc/PhaseAssembly.scala
@@ -3,7 +3,6 @@
* @author Anders Bach Nielsen
* @version 1.0
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/Properties.scala b/src/compiler/scala/tools/nsc/Properties.scala
index 4601a1ca64..4d488e65cf 100644
--- a/src/compiler/scala/tools/nsc/Properties.scala
+++ b/src/compiler/scala/tools/nsc/Properties.scala
@@ -3,7 +3,6 @@
* @author Stephane Micheloud
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/ScalaDoc.scala b/src/compiler/scala/tools/nsc/ScalaDoc.scala
index b7e416e121..b539b800b3 100644
--- a/src/compiler/scala/tools/nsc/ScalaDoc.scala
+++ b/src/compiler/scala/tools/nsc/ScalaDoc.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
* @author Geoffrey Washburn
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index a096efb749..a7d67a3af9 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
@@ -17,11 +16,9 @@ import io.{ Directory, File, Path, PlainFile }
import java.lang.reflect.InvocationTargetException
import java.net.URL
import java.util.jar.{ JarEntry, JarOutputStream }
-import java.util.regex.Pattern
import scala.tools.util.PathResolver
import scala.tools.nsc.reporters.{Reporter,ConsoleReporter}
-import scala.tools.nsc.util.{ClassPath, CompoundSourceFile, BatchSourceFile, SourceFile, SourceFileFragment}
/** An object that runs Scala code in script files.
*
@@ -49,8 +46,7 @@ import scala.tools.nsc.util.{ClassPath, CompoundSourceFile, BatchSourceFile, Sou
* @todo It would be better if error output went to stderr instead
* of stdout...
*/
-object ScriptRunner
-{
+object ScriptRunner {
/* While I'm chasing down the fsc and script bugs. */
def DBG(msg: Any) {
System.err.println(msg.toString)
@@ -69,6 +65,8 @@ object ScriptRunner
case x => x
}
+ def isScript(settings: Settings) = settings.script.value != ""
+
/** Choose a jar filename to hold the compiled version of a script. */
private def jarFileFor(scriptFile: String): File = {
val name =
@@ -119,22 +117,6 @@ object ScriptRunner
/** Read the entire contents of a file as a String. */
private def contentsOfFile(filename: String) = File(filename).slurp()
- /** Find the length of the header in the specified file, if
- * there is one. The header part starts with "#!" or "::#!"
- * and ends with a line that begins with "!#" or "::!#".
- */
- private def headerLength(filename: String): Int = {
- val headerPattern = Pattern.compile("""^(::)?!#.*(\r|\n|\r\n)""", Pattern.MULTILINE)
- val fileContents = contentsOfFile(filename)
- def isValid = List("#!", "::#!") exists (fileContents startsWith _)
-
- if (!isValid) 0 else {
- val matcher = headerPattern matcher fileContents
- if (matcher.find) matcher.end
- else throw new IOException("script file does not close its header with !# or ::!#")
- }
- }
-
/** Split a fully qualified object name into a
* package and an unqualified object name */
private def splitObjectName(fullname: String): (Option[String], String) =
@@ -143,48 +125,6 @@ object ScriptRunner
case idx => (Some(fullname take idx), fullname drop (idx + 1))
}
- /** Code that is added to the beginning of a script file to make
- * it a complete Scala compilation unit.
- */
- protected def preambleCode(objectName: String): String = {
- val (maybePack, objName) = splitObjectName(objectName)
- val packageDecl = maybePack map ("package %s\n" format _) getOrElse ("")
-
- return """|
- | object %s {
- | def main(argv: Array[String]): Unit = {
- | val args = argv
- | new AnyRef {
- |""".stripMargin.format(objName)
- }
-
- /** Code that is added to the end of a script file to make
- * it a complete Scala compilation unit.
- */
- val endCode = """
- | }
- | }
- | }
- |""".stripMargin
-
- /** Wrap a script file into a runnable object named
- * <code>scala.scripting.Main</code>.
- */
- def wrappedScript(
- objectName: String,
- filename: String,
- getSourceFile: PlainFile => BatchSourceFile): SourceFile =
- {
- val preamble = new BatchSourceFile("<script preamble>", preambleCode(objectName).toCharArray)
- val middle = {
- val bsf = getSourceFile(PlainFile fromPath filename)
- new SourceFileFragment(bsf, headerLength(filename), bsf.length)
- }
- val end = new BatchSourceFile("<script trailer>", endCode.toCharArray)
-
- new CompoundSourceFile(preamble, middle, end)
- }
-
/** Compile a script using the fsc compilation daemon.
*
* @param settings ...
@@ -243,12 +183,15 @@ object ScriptRunner
settings.outdir.value = compiledPath.path
if (settings.nocompdaemon.value) {
+ /** Setting settings.script.value informs the compiler this is not a
+ * self contained compilation unit.
+ */
+ settings.script.value = scriptMain(settings)
val reporter = new ConsoleReporter(settings)
val compiler = newGlobal(settings, reporter)
val cr = new compiler.Run
- val wrapped = wrappedScript(scriptMain(settings), scriptFile, compiler getSourceFile _)
- cr compileSources List(wrapped)
+ cr compile List(scriptFile)
if (reporter.hasErrors) None else Some(compiledPath)
}
else if (compileWithDaemon(settings, scriptFile)) Some(compiledPath)
@@ -295,10 +238,7 @@ object ScriptRunner
val classpath = pr.asURLs :+ File(compiledLocation).toURL
try {
- ObjectRunner.run(
- classpath,
- scriptMain(settings),
- scriptArgs)
+ ObjectRunner.run(classpath, scriptMain(settings), scriptArgs)
true
}
catch {
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index cd4626c0c6..8765ad3686 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/SubComponent.scala b/src/compiler/scala/tools/nsc/SubComponent.scala
index 425f5e4aff..445021f22a 100644
--- a/src/compiler/scala/tools/nsc/SubComponent.scala
+++ b/src/compiler/scala/tools/nsc/SubComponent.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index ddf4fb0a23..48c2536324 100755
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id: Unapplies.scala 19206 2009-10-21 20:57:27Z extempore $
package scala.tools.nsc
package ast
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
index ccab6423cf..111bf48a45 100644
--- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index e5a49f8358..0555f6c035 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index fd13958053..34d3423401 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -7,6 +7,8 @@
package scala.tools.nsc
package ast
+import PartialFunction._
+
/** A DSL for generating scala code. The goal is that the
* code generating code should look a lot like the code it
* generates.
@@ -18,22 +20,20 @@ trait TreeDSL {
import global._
import definitions._
import gen.{ scalaDot }
- import PartialFunction._
object CODE {
// Add a null check to a Tree => Tree function
def nullSafe[T](f: Tree => Tree, ifNull: Tree): Tree => Tree =
tree => IF (tree MEMBER_== NULL) THEN ifNull ELSE f(tree)
- // Applies a function to a value and then returns the value.
- def returning[T](f: T => Unit)(x: T): T = { f(x) ; x }
-
// strip bindings to find what lies beneath
final def unbind(x: Tree): Tree = x match {
case Bind(_, y) => unbind(y)
case y => y
}
+ def returning[T](x: T)(f: T => Unit): T = util.returning(x)(f)
+
object LIT extends (Any => Literal) {
def apply(x: Any) = Literal(Constant(x))
def unapply(x: Any) = condOpt(x) { case Literal(Constant(value)) => value }
@@ -93,6 +93,7 @@ trait TreeDSL {
def INT_| (other: Tree) = fn(target, getMember(IntClass, nme.OR), other)
def INT_& (other: Tree) = fn(target, getMember(IntClass, nme.AND), other)
+ def INT_>= (other: Tree) = fn(target, getMember(IntClass, nme.GE), other)
def INT_== (other: Tree) = fn(target, getMember(IntClass, nme.EQ), other)
def INT_!= (other: Tree) = fn(target, getMember(IntClass, nme.NE), other)
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index cc3581c3f8..1327781d31 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
index 430967298c..f21b1b20ff 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index cb899a2560..ddc1c3169a 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index b40f286680..8db6958d07 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
index e918489446..60df523d92 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Burak Emir
*/
-// $Id$
package scala.tools.nsc
package ast.parser
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 43e515d31e..182ae6c21c 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
//todo: allow infix type patterns
@@ -10,7 +9,7 @@ package scala.tools.nsc
package ast.parser
import scala.collection.mutable.ListBuffer
-import scala.tools.nsc.util.{OffsetPosition, BatchSourceFile}
+import util.{ OffsetPosition, BatchSourceFile }
import symtab.Flags
import Tokens._
@@ -64,6 +63,13 @@ self =>
def this(unit: global.CompilationUnit) = this(unit, List())
+ /** The parse starting point depends on whether the source file is self-contained:
+ * if not, the AST will be supplemented.
+ */
+ def parseStartRule =
+ if (unit.source.isSelfContained) () => compilationUnit()
+ else () => scriptBody()
+
val in = new UnitScanner(unit, patches)
in.init()
@@ -170,14 +176,66 @@ self =>
*/
var classContextBounds: List[Tree] = Nil
- /** this is the general parse method
+ def parseStartRule: () => Tree
+
+ /** This is the general parse entry point.
*/
def parse(): Tree = {
- val t = compilationUnit()
+ val t = parseStartRule()
accept(EOF)
t
}
+ /** This is the parse entry point for code which is not self-contained, e.g.
+ * a script which is a series of template statements. They will be
+ * swaddled in Trees until the AST is equivalent to the one returned
+ * by compilationUnit().
+ */
+ def scriptBody(): Tree = {
+ val stmts = templateStatSeq(false)._2
+ accept(EOF)
+
+ /** Here we are building an AST representing the following source fiction,
+ * where <moduleName> is from -Xscript (defaults to "Main") and <stmts> are
+ * the result of parsing the script file.
+ *
+ * object <moduleName> {
+ * def main(argv: Array[String]): Unit = {
+ * val args = argv
+ * new AnyRef {
+ * <stmts>
+ * }
+ * }
+ * }
+ */
+ import definitions._
+
+ def emptyPkg = atPos(0, 0, 0) { Ident(nme.EMPTY_PACKAGE_NAME) }
+ def emptyInit = DefDef(
+ NoMods,
+ nme.CONSTRUCTOR,
+ Nil,
+ List(Nil),
+ TypeTree(),
+ Block(List(Apply(Select(Super("", ""), nme.CONSTRUCTOR), Nil)), Literal(Constant(())))
+ )
+
+ // def main
+ def mainParamType = AppliedTypeTree(Ident("Array".toTypeName), List(Ident("String".toTypeName)))
+ def mainParameter = List(ValDef(Modifiers(Flags.PARAM), "argv", mainParamType, EmptyTree))
+ def mainSetArgv = List(ValDef(NoMods, "args", TypeTree(), Ident("argv")))
+ def mainNew = makeNew(Nil, emptyValDef, stmts, List(Nil), NoPosition, NoPosition)
+ def mainDef = DefDef(NoMods, "main", Nil, List(mainParameter), scalaDot(nme.Unit.toTypeName), Block(mainSetArgv, mainNew))
+
+ // object Main
+ def moduleName = ScriptRunner scriptMain settings
+ def moduleBody = Template(List(scalaScalaObjectConstr), emptyValDef, List(emptyInit, mainDef))
+ def moduleDef = ModuleDef(NoMods, moduleName, moduleBody)
+
+ // package <empty> { ... }
+ makePackaging(0, emptyPkg, List(moduleDef))
+ }
+
/* --------------- PLACEHOLDERS ------------------------------------------- */
/** The implicit parameters introduced by `_' in the current expression.
@@ -1407,7 +1465,7 @@ self =>
else accept(LARROW)
val rhs = expr()
enums += makeGenerator(r2p(start, point, in.lastOffset), pat, tok == EQUALS, rhs)
- if (in.token == IF) enums += makeFilter(in.offset, guard())
+ while (in.token == IF) enums += makeFilter(in.offset, guard())
}
def makeFilter(start: Int, tree: Tree) = Filter(r2p(start, tree.pos.point, tree.pos.endOrPoint), tree)
@@ -1487,7 +1545,9 @@ self =>
def pattern3(seqOK: Boolean): Tree = {
val base = opstack
var top = simplePattern(seqOK)
- if (seqOK && isIdent && in.name == STAR)
+ // See ticket #3189 for the motivation for the null check.
+ // TODO: dredge out the remnants of regexp patterns.
+ if (seqOK && isIdent && in.name == STAR && in.prev.name != null)
return atPos(top.pos.startOrPoint, in.skipToken())(Star(stripParens(top)))
while (isIdent && in.name != BAR) {
@@ -1727,8 +1787,11 @@ self =>
mods = mods withPosition (in.token, tokenRange(in))
mods |= Flags.MUTABLE
in.nextToken()
- } else if (!caseParam) {
- mods |= Flags.PRIVATE | Flags.LOCAL
+ } else {
+ if (mods.flags != Flags.PARAMACCESSOR) accept(VAL)
+ if (!caseParam) {
+ mods |= Flags.PRIVATE | Flags.LOCAL
+ }
}
if (caseParam) {
mods |= Flags.CASEACCESSOR
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index eeb3fb6e7a..5e9cc3f46e 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast.parser
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index 049c8aa2ff..86c79eb733 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Burak Emir
*/
-// $Id$
package scala.tools.nsc
package ast.parser
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
index fb97587ec4..b3c3c7dfe9 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast.parser
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
index 2146fa0fe6..00347c3a9e 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast.parser
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index bea52b1153..9f20a70de5 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package ast.parser
diff --git a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
index b95e3335ba..0af482912d 100644
--- a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
+++ b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/WorklistAlgorithm.scala b/src/compiler/scala/tools/nsc/backend/WorklistAlgorithm.scala
index 1cb5cfb051..27f5b27303 100644
--- a/src/compiler/scala/tools/nsc/backend/WorklistAlgorithm.scala
+++ b/src/compiler/scala/tools/nsc/backend/WorklistAlgorithm.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index e5afa84c82..bab3652f69 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/CheckerException.scala b/src/compiler/scala/tools/nsc/backend/icode/CheckerException.scala
index 9d102eef28..a2ba0554da 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/CheckerException.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/CheckerException.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala
index c34cefdc12..6067dc6e42 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
index 8168cc2c6e..e5b94076e8 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index b357dff25a..9136bffcda 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
index 0810a64f5d..dc90a438b9 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
@@ -7,7 +7,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
index d090454129..701e5d3815 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
index 82e99d50ac..95cd15711b 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
index c0255cda65..ed76e66aa0 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala b/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala
index 826ecc18ec..8624bb5aff 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Primitives.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
index 0c81759c18..9aaeeb2e8b 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Repository.scala b/src/compiler/scala/tools/nsc/backend/icode/Repository.scala
index 5d08b40557..78a47e129c 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Repository.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Repository.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index 4b53a5e2ae..65a5291f36 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala
index 6872f56c39..d334af525f 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala
index 95f4418759..4efefe89f9 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend.icode.analysis
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
index 1fbbc10c3d..289fae6fe3 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend.icode.analysis
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala
index df3dd1a060..39405cd84e 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend.icode.analysis
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
index 46771feeee..101bb81503 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend.icode.analysis
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/LubException.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/LubException.scala
index 0474d12a8b..6cdee7ef4b 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/LubException.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/LubException.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend.icode.analysis
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/ProgramPoint.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/ProgramPoint.scala
index e875ced036..a9a09a71a0 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/ProgramPoint.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/ProgramPoint.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend.icode.analysis
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala
index 3aa0ddfdbf..f3dd6dd93b 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend.icode.analysis
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
index 858512c9b1..9b145c9fbc 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package backend.icode.analysis
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 2b4878a93b..21d1246cc4 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -3,7 +3,6 @@
* @author Iulian Dragos
*/
-// $Id$
package scala.tools.nsc
package backend.jvm
@@ -815,7 +814,10 @@ abstract class GenJVM extends SubComponent {
import JAccessFlags._
val moduleName = javaName(module) // + "$"
val mirrorName = moduleName.substring(0, moduleName.length() - 1)
- val paramJavaTypes = m.info.paramTypes map toTypeKind
+
+ val methodInfo = module.thisType.memberInfo(m)
+
+ val paramJavaTypes = methodInfo.paramTypes map toTypeKind
val paramNames: Array[String] = new Array[String](paramJavaTypes.length);
for (i <- 0 until paramJavaTypes.length)
@@ -823,7 +825,7 @@ abstract class GenJVM extends SubComponent {
val mirrorMethod = jclass.addNewMethod(ACC_PUBLIC | ACC_FINAL | ACC_STATIC,
javaName(m),
- javaType(m.info.resultType),
+ javaType(methodInfo.resultType),
javaTypes(paramJavaTypes),
paramNames);
val mirrorCode = mirrorMethod.getCode().asInstanceOf[JExtendedCode];
@@ -839,7 +841,7 @@ abstract class GenJVM extends SubComponent {
i += 1
}
- mirrorCode.emitINVOKEVIRTUAL(moduleName, mirrorMethod.getName(), mirrorMethod.getType().asInstanceOf[JMethodType])
+ mirrorCode.emitINVOKEVIRTUAL(moduleName, mirrorMethod.getName(), javaType(m).asInstanceOf[JMethodType])
mirrorCode.emitRETURN(mirrorMethod.getReturnType())
addRemoteException(mirrorMethod, m)
@@ -1701,7 +1703,7 @@ abstract class GenJVM extends SubComponent {
def indexOf(local: Local): Int = {
assert(local.index >= 0,
- "Invalid index for: " + local + "{" + local.hashCode + "}: ")
+ "Invalid index for: " + local + "{" + local.## + "}: ")
local.index
}
@@ -1716,7 +1718,7 @@ abstract class GenJVM extends SubComponent {
for (l <- m.locals) {
if (settings.debug.value)
- log("Index value for " + l + "{" + l.hashCode + "}: " + idx)
+ log("Index value for " + l + "{" + l.## + "}: " + idx)
l.index = idx
idx += sizeOf(l.kind)
}
diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
index 554dcd4e6d..92ba50e88e 100644
--- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
+++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
@@ -3,7 +3,6 @@
* @author Nikolay Mihaylov
*/
-// $Id$
package scala.tools.nsc
package backend.msil
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
index fedf0d4143..9470078507 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
@@ -3,7 +3,6 @@
* @author Iulian Dragos
*/
-// $Id$
package scala.tools.nsc
package backend.opt;
diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
index 29d0c37c84..e365b3bc08 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
@@ -3,7 +3,6 @@
* @author Iulian Dragos
*/
-// $Id$
package scala.tools.nsc
package backend.opt
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index dc1ac8e844..9c1489a637 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -3,7 +3,6 @@
* @author Iulian Dragos
*/
-// $Id$
package scala.tools.nsc
package backend.opt
@@ -444,6 +443,15 @@ abstract class Inliners extends SubComponent {
case Some(b) =>
callsNonPublic = b
case None =>
+ // Avoiding crashing the compiler if there are open blocks.
+ callee.code.blocks filterNot (_.closed) foreach { b =>
+ currentIClazz.cunit.warning(callee.symbol.pos,
+ "Encountered open block in isSafeToInline: this indicates a bug in the optimizer!\n" +
+ " caller = " + caller + ", callee = " + callee
+ )
+ return false
+ }
+
breakable {
for (b <- callee.code.blocks; i <- b)
i match {
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
index 7fd6538566..42aab918f7 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -1,6 +1,5 @@
/* NSC -- new Scala compiler -- Copyright 2007-2010 LAMP/EPFL */
-// $Id$
package scala.tools.nsc
package doc
diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala
index 4897d78488..f3fe8c384b 100644
--- a/src/compiler/scala/tools/nsc/doc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/doc/Settings.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package doc
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index 31b932ac53..66e2ba2260 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -10,7 +10,7 @@ package html
import model._
import comment._
-import xml.{Unparsed, XML, NodeSeq}
+import xml.{XML, NodeSeq}
import xml.dtd.{DocType, PublicID}
import scala.collection._
import scala.reflect.NameTransformer
@@ -128,12 +128,12 @@ abstract class HtmlPage { thisPage =>
body.blocks flatMap (blockToHtml(_))
def blockToHtml(block: Block): NodeSeq = block match {
- case Title(in, 1) => <h1>{ inlineToHtml(in) }</h1>
- case Title(in, 2) => <h2>{ inlineToHtml(in) }</h2>
- case Title(in, 3) => <h3>{ inlineToHtml(in) }</h3>
- case Title(in, _) => <h4>{ inlineToHtml(in) }</h4>
+ case Title(in, 1) => <h3>{ inlineToHtml(in) }</h3>
+ case Title(in, 2) => <h4>{ inlineToHtml(in) }</h4>
+ case Title(in, 3) => <h5>{ inlineToHtml(in) }</h5>
+ case Title(in, _) => <h6>{ inlineToHtml(in) }</h6>
case Paragraph(in) => <p>{ inlineToHtml(in) }</p>
- case Code(data) => <pre>{ Unparsed(data) }</pre>
+ case Code(data) => <pre>{ xml.Text(data) }</pre>
case UnorderedList(items) =>
<ul>{ listItemsToHtml(items) }</ul>
case OrderedList(items, listStyle) =>
@@ -165,9 +165,10 @@ abstract class HtmlPage { thisPage =>
case Subscript(in) => <sub>{ inlineToHtml(in) }</sub>
case Link(raw, title) => <a href={ raw }>{ inlineToHtml(title) }</a>
case EntityLink(entity) => templateToHtml(entity)
- case Monospace(text) => <code>{ Unparsed(text) }</code>
- case Text(text) => Unparsed(text)
+ case Monospace(text) => <code>{ xml.Text(text) }</code>
+ case Text(text) => xml.Text(text)
case Summary(in) => inlineToHtml(in)
+ case HtmlTag(tag) => xml.Unparsed(tag)
}
def typeToHtml(tpe: model.TypeEntity, hasLinks: Boolean): NodeSeq = {
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
index 92de97f619..0c17d9fa2a 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
@@ -81,6 +81,7 @@ a:hover {
}
#comment {
+ padding-right: 8px;
padding-left: 8px;
}
@@ -193,17 +194,56 @@ div.members > ol > li {
.cmt {}
.cmt p {
- margin: 2px 0 2px 0;
+ margin-bottom: 0.4em;
+ margin-top: 0.4em;
}
-.cmt code {
- font-family: monospace;
+.cmt h3 {
+ margin-bottom: 1em;
+ margin-top: 1em;
+ display: block;
+ text-align: left;
+ font-weight: bold;
+ font-size: x-large;
+}
+
+.cmt h4 {
+ margin-bottom: 0.6em;
+ margin-top: 0.6em;
+ display: block;
+ text-align: left;
+ font-weight: bold;
+ font-size: large;
+}
+
+.cmt h5 {
+ margin-bottom: 0.4em;
+ margin-top: 0.4em;
+ display: block;
+ text-align: left;
+ font-weight: bold;
+}
+
+.cmt h6 {
+ margin-bottom: 0.4em;
+ margin-top: 0.4em;
+ display: block;
+ text-align: left;
+ font-style: italic;
}
.cmt pre {
+ padding: 0.4em;
+ border-color: #ddd;
+ border-style: solid;
+ border-width: 1px;
+ margin-left: 0;
+ margin-bottom: 0.4em;
+ margin-right: 0;
+ margin-top: 0.4em;
+ background-color: #eee;
display: block;
font-family: monospace;
- margin: 2px 0 2px 0;
}
.cmt ul {
@@ -241,20 +281,24 @@ div.members > ol > li {
display:list-item;
}
+.cmt code {
+ font-family: monospace;
+}
+
.cmt a {
- text-decoration: underline;
+ font-style: bold;
}
/* Comments structured layout */
p.comment {
display: block;
- margin-left: 8.7em;
+ margin-left: 8.7em;
}
p.shortcomment {
display: block;
- margin-left: 8.7em;
+ margin-left: 8.7em;
cursor: help;
}
@@ -264,7 +308,7 @@ div.fullcomment {
}
#template div.fullcomment {
- margin: 6px 0 6px 8.7em;
+ margin: 6px 0 6px 8.7em;
}
div.fullcomment .block {
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala b/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
index 29e47fa578..255c61095e 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
@@ -67,6 +67,7 @@ final case class Link(target: String, title: Inline) extends Inline
final case class EntityLink(target: TemplateEntity) extends Inline
final case class Monospace(text: String) extends Inline
final case class Text(text: String) extends Inline
+final case class HtmlTag(data: String) extends Inline
/** The summary of a comment, usually its first sentence. There must be exactly one summary per body. */
final case class Summary(text: Inline) extends Inline
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index f067555cc3..475fbf584e 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -57,21 +57,31 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
new Regex("""(?:\s*\*\s?)?(.*)""")
/** Dangerous HTML tags that should be replaced by something safer, such as wiki syntax, or that should be dropped. */
- protected val DangerousHtml =
- new Regex("""<(/?(?:p|div|pre|ol|ul|li|h[1-6]|code))[^>]*>""")
+ protected val DangerousTags =
+ new Regex("""<(/?(div|ol|ul|li|h[1-6]|p))( [^>]*)?/?>|<!--.*-->""")
/** Maps a dangerous HTML tag to a safe wiki replacement, or an empty string if it cannot be salvaged. */
- protected def htmlReplacement(mtch: Regex.Match): String = mtch.matched match {
+ protected def htmlReplacement(mtch: Regex.Match): String = mtch.group(1) match {
case "p" | "div" => "\n\n"
- case "h1" | "h2" | "h3" | "h4" | "h5" | "h6" => "\n= "
- case "/h1" | "/h2" | "/h3" | "/h4" | "/h5" | "/h6" => " =\n"
- case "pre" => "{{{"
- case "/pre" => "}}}"
+ case "h1" => "\n= "
+ case "/h1" => " =\n"
+ case "h2" => "\n== "
+ case "/h2" => " ==\n"
+ case "h3" => "\n=== "
+ case "/h3" => " ===\n"
+ case "h4" | "h5" | "h6" => "\n==== "
+ case "/h4" | "/h5" | "/h6" => " ====\n"
case "code" | "/code" => "`"
- case "li" => "\n - "
+ case "li" => "\n * - "
case _ => ""
}
+ /** Safe HTML tags that can be kept. */
+ protected val SafeTags =
+ new Regex("""(</?(abbr|acronym|address|area|a|bdo|big|blockquote|br|button|b|caption|code|cite|col|colgroup|dd|del|dfn|em|fieldset|form|hr|img|input|ins|i|kbd|label|legend|link|map|object|optgroup|option|param|pre|q|samp|select|small|span|strong|sub|sup|table|tbody|td|textarea|tfoot|th|thead|tr|tt|var)( [^>]*)?/?>)""")
+
+ protected val safeTagMarker = '\u000E'
+
/** A Scaladoc tag not linked to a symbol. Returns the name of the tag, and the rest of the line. */
protected val SimpleTag =
new Regex("""\s*@(\S+)\s+(.*)""")
@@ -114,8 +124,12 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
}
}
val strippedComment = comment.trim.stripPrefix("/*").stripSuffix("*/")
- val safeComment = DangerousHtml.replaceAllIn(strippedComment, { htmlReplacement(_) })
- safeComment.lines.toList map (cleanLine(_))
+ val safeComment = DangerousTags.replaceAllIn(strippedComment, { htmlReplacement(_) })
+ val markedTagComment =
+ SafeTags.replaceAllIn(safeComment, { mtch =>
+ java.util.regex.Matcher.quoteReplacement(safeTagMarker + mtch.matched + safeTagMarker)
+ })
+ markedTagComment.lines.toList map (cleanLine(_))
}
/** Parses a comment (in the form of a list of lines) to a Comment instance, recursively on lines. To do so, it
@@ -251,17 +265,6 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
var summaryParsed = false
- /** listStyle ::= '-' spc | '1.' spc | 'I.' spc | 'i.' spc | 'A.' spc | 'a.' spc
- * Characters used to build lists and their constructors */
- protected val listStyles = Map[String, (Seq[Block] => Block)]( // TODO Should this be defined at some list companion?
- "- " -> ( UnorderedList(_) ),
- "1. " -> ( OrderedList(_,"decimal") ),
- "I. " -> ( OrderedList(_,"upperRoman") ),
- "i. " -> ( OrderedList(_,"lowerRoman") ),
- "A. " -> ( OrderedList(_,"upperAlpha") ),
- "a. " -> ( OrderedList(_,"lowerAlpha") )
- )
-
def document(): Body = {
nextChar()
val blocks = new mutable.ListBuffer[Block]
@@ -287,9 +290,20 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
}
}
+ /** listStyle ::= '-' spc | '1.' spc | 'I.' spc | 'i.' spc | 'A.' spc | 'a.' spc
+ * Characters used to build lists and their constructors */
+ protected val listStyles = Map[String, (Seq[Block] => Block)]( // TODO Should this be defined at some list companion?
+ "- " -> ( UnorderedList(_) ),
+ "1. " -> ( OrderedList(_,"decimal") ),
+ "I. " -> ( OrderedList(_,"upperRoman") ),
+ "i. " -> ( OrderedList(_,"lowerRoman") ),
+ "A. " -> ( OrderedList(_,"upperAlpha") ),
+ "a. " -> ( OrderedList(_,"lowerAlpha") )
+ )
+
/** Checks if the current line is formed with more than one space and one the listStyles */
def checkList =
- countWhitespace > 0 && listStyles.keysIterator.indexWhere(checkSkipInitWhitespace(_)) >= 0
+ (countWhitespace > 0) && (listStyles.keys exists { checkSkipInitWhitespace(_) })
/** {{{
* nListBlock ::= nLine { mListBlock }
@@ -297,42 +311,39 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
* }}}
* Where n and m stand for the number of spaces. When m > n, a new list is nested. */
def listBlock: Block = {
- /** consumes one line of a list block */
- def listLine(indentedListStyle: String): Block = {
- // deals with mixed lists in the same nesting level by skipping it
- if(!jump(indentedListStyle)) { // TODO show warning when jump is false
- nextChar();
- nextChar()
- }
- val p = Paragraph(inline(check(Array(endOfLine))))
- blockEnded("end of list line ")
- p
- }
- def listLevel(leftSide: String, listStyle: String, constructor: (Seq[Block] => Block)): Block = {
- val blocks = mutable.ListBuffer.empty[Block]
- val length = leftSide.length
- val indentedListStyle = leftSide + listStyle
-
- var index = 1
- var line = listLine(indentedListStyle)
-
- while (index > -1) {
- blocks += line
- if (countWhitespace > length) { // nesting-in
- blocks += listBlock // TODO is tailrec really needed here?
- }
- index = listStyles.keysIterator.indexWhere(x => check(leftSide))
- if (index > -1) { line = listLine(indentedListStyle) }
+
+ /** Consumes one list item block and returns it, or None if the block is not a list or a different list. */
+ def listLine(indent: Int, style: String): Option[Block] =
+ if (countWhitespace > indent && checkList)
+ Some(listBlock)
+ else if (countWhitespace != indent || !checkSkipInitWhitespace(style))
+ None
+ else {
+ jumpWhitespace()
+ jump(style)
+ val p = Paragraph(inline(false))
+ blockEnded("end of list line ")
+ Some(p)
}
- constructor(blocks)
+ /** Consumes all list item blocks (possibly with nested lists) of the same list and returns the list block. */
+ def listLevel(indent: Int, style: String): Block = {
+ val lines = mutable.ListBuffer.empty[Block]
+ var line: Option[Block] = listLine(indent, style)
+ while (line.isDefined) {
+ lines += line.get
+ line = listLine(indent, style)
+ }
+ val constructor = listStyles(style)
+ constructor(lines)
}
- val indentation = countWhitespace
- val indentStr = " " * indentation
- val style = listStyles.keysIterator.find( x => check(indentStr + x) ).getOrElse(listStyles.keysIterator.next)
- val constructor = listStyles(style)
- listLevel(indentStr, style, constructor)
+
+ val indent = countWhitespace
+ val style = (listStyles.keys find { checkSkipInitWhitespace(_) }).getOrElse(listStyles.keys.head)
+ listLevel(indent, style)
+
}
+
def code(): Block = {
jumpWhitespace()
jump("{{{")
@@ -387,7 +398,8 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
def inline(isInlineEnd: => Boolean): Inline = {
def inline0(): Inline = {
- if (check("'''")) bold()
+ if (char == safeTagMarker) htmlTag()
+ else if (check("'''")) bold()
else if (check("''")) italic()
else if (check("`")) monospace()
else if (check("__")) underline()
@@ -395,7 +407,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
else if (check(",,")) subscript()
else if (check("[[")) link()
else {
- readUntil { check("''") || char == '`' || check("__") || char == '^' || check(",,") || check("[[") || isInlineEnd || checkParaEnded || char == endOfLine }
+ readUntil { char == safeTagMarker || check("''") || char == '`' || check("__") || char == '^' || check(",,") || check("[[") || isInlineEnd || checkParaEnded || char == endOfLine }
Text(getRead())
}
}
@@ -423,6 +435,14 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
}
+ def htmlTag(): Inline = {
+ jump(safeTagMarker)
+ readUntil(safeTagMarker)
+ if (char != endOfText) jump(safeTagMarker)
+ var read = getRead
+ HtmlTag(read)
+ }
+
def bold(): Inline = {
jump("'''")
val i = inline(check("'''"))
@@ -530,7 +550,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
checkSkipInitWhitespace(Array(endOfLine)) ||
checkSkipInitWhitespace(Array('=')) ||
checkSkipInitWhitespace(Array('{', '{', '{')) ||
- checkSkipInitWhitespace(Array(' ', '-', ' ')) ||
+ checkList ||
checkSkipInitWhitespace(Array('\u003D'))
}
offset = poff
@@ -606,10 +626,18 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
/* JUMPERS */
- /** jumps all the characters in chars
- * @return true only if the correct characters have been jumped
- * consumes any matching characters
- */
+ /** jumps a character and consumes it
+ * @return true only if the correct character has been jumped */
+ final def jump(ch: Char): Boolean = {
+ if (char == ch) {
+ nextChar()
+ true
+ }
+ else false
+ }
+
+ /** jumps all the characters in chars, consuming them in the process.
+ * @return true only if the correct characters have been jumped */
final def jump(chars: Array[Char]): Boolean = {
var index = 0
while (index < chars.length && char == chars(index) && char != endOfText) {
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 03fd92235d..2c174860e4 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -7,7 +7,7 @@ import scala.collection.mutable.{LinkedHashMap, SynchronizedMap}
import scala.concurrent.SyncVar
import scala.util.control.ControlThrowable
import scala.tools.nsc.io.AbstractFile
-import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, WorkScheduler}
+import scala.tools.nsc.util.{SourceFile, Position, RangePosition, NoPosition, WorkScheduler}
import scala.tools.nsc.reporters._
import scala.tools.nsc.symtab._
import scala.tools.nsc.ast._
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 337f306664..6ef85b2f59 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -3,7 +3,7 @@ package interactive
import ast.Trees
import symtab.Positions
-import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, WorkScheduler}
+import scala.tools.nsc.util.{SourceFile, Position, RangePosition, NoPosition, WorkScheduler}
import scala.collection.mutable.ListBuffer
/** Handling range positions
diff --git a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
index 7c977c6e60..bde90bc347 100644
--- a/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RefinedBuildManager.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package interactive
diff --git a/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala b/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala
index c821b9ed80..0c3d24d46f 100644
--- a/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala
@@ -1,7 +1,6 @@
/* NSC -- new Scala compiler
* Copyright 2005-2010 LAMP/EPFL
*/
-// $Id$
package scala.tools.nsc
package interpreter
diff --git a/src/compiler/scala/tools/nsc/interpreter/Completion.scala b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
index fddb1ee928..58ce85f1f6 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Completion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
@@ -9,6 +9,7 @@ package interpreter
import jline._
import java.util.{ List => JList }
+import util.returning
object Completion {
def looksLikeInvocation(code: String) = (
@@ -166,7 +167,19 @@ class Completion(val repl: Interpreter) extends CompletionOutput {
override def follow(id: String) =
if (completions(0) contains id) {
for (clazz <- repl clazzForIdent id) yield {
- (typeOf(clazz.getName) map TypeMemberCompletion.apply) getOrElse new InstanceCompletion(clazz)
+ // XXX The isMemberClass check is a workaround for the crasher described
+ // in the comments of #3431. The issue as described by iulian is:
+ //
+ // Inner classes exist as symbols
+ // inside their enclosing class, but also inside their package, with a mangled
+ // name (A$B). The mangled names should never be loaded, and exist only for the
+ // optimizer, which sometimes cannot get the right symbol, but it doesn't care
+ // and loads the bytecode anyway.
+ //
+ // So this solution is incorrect, but in the short term the simple fix is
+ // to skip the compiler any time completion is requested on a nested class.
+ if (clazz.isMemberClass) new InstanceCompletion(clazz)
+ else (typeOf(clazz.getName) map TypeMemberCompletion.apply) getOrElse new InstanceCompletion(clazz)
}
}
else None
diff --git a/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala b/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
index b3957e1062..92df6a8736 100644
--- a/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Stepan Koltsov
*/
-// $Id$
package scala.tools.nsc
package interpreter
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
index 34367eacea..ab11a53d43 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Stepan Koltsov
*/
-// $Id$
package scala.tools.nsc
package interpreter
diff --git a/src/compiler/scala/tools/nsc/interpreter/Parsed.scala b/src/compiler/scala/tools/nsc/interpreter/Parsed.scala
index 0b92608d88..84f5477c21 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Parsed.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Parsed.scala
@@ -7,6 +7,7 @@ package scala.tools.nsc
package interpreter
import jline.ArgumentCompletor.{ ArgumentDelimiter, ArgumentList }
+import util.returning
/** One instance of a command buffer.
*/
diff --git a/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala b/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
index 9d604ab8b3..c350468c3b 100644
--- a/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Stepan Koltsov
*/
-// $Id$
package scala.tools.nsc
package interpreter
diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala
index 2ded3a7900..eaf736c5b7 100644
--- a/src/compiler/scala/tools/nsc/interpreter/package.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/package.scala
@@ -6,9 +6,6 @@
package scala.tools.nsc
package object interpreter {
- /** Apply a function and return the passed value */
- def returning[T](x: T)(f: T => Unit): T = { f(x) ; x }
-
/** Tracing */
def tracing[T](msg: String)(x: T): T = { println("(" + msg + ") " + x) ; x }
@@ -18,6 +15,14 @@ package object interpreter {
/** null becomes "", otherwise identity */
def onull(s: String) = if (s == null) "" else s
+ /** Heuristically strip interpreter wrapper prefixes
+ * from an interpreter output string.
+ */
+ def stripWrapperGunk(str: String): String = {
+ val wrapregex = """(line[0-9]+\$object[$.])?(\$iw[$.])*"""
+ str.replaceAll(wrapregex, "")
+ }
+
/** Class objects */
def classForName(name: String): Option[Class[_]] =
try Some(Class forName name)
diff --git a/src/compiler/scala/tools/nsc/io/AbstractFile.scala b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
index 079b33c2a2..5d4f7b8464 100644
--- a/src/compiler/scala/tools/nsc/io/AbstractFile.scala
+++ b/src/compiler/scala/tools/nsc/io/AbstractFile.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
@@ -231,7 +230,7 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
* creating an empty file if it does not already existing.
*/
def fileNamed(name: String): AbstractFile = {
- assert(isDirectory)
+ assert(isDirectory, "Tried to find '%s' in '%s' but it is not a directory".format(name, path))
Option(lookupName(name, false)) getOrElse new PlainFile((sfile.get / name).createFile())
}
@@ -240,7 +239,7 @@ abstract class AbstractFile extends AnyRef with Iterable[AbstractFile] {
* does not already exist.
*/
def subdirectoryNamed(name: String): AbstractFile = {
- assert (isDirectory)
+ assert (isDirectory, "Tried to find '%s' in '%s' but it is not a directory".format(name, path))
Option(lookupName(name, true)) getOrElse new PlainFile((sfile.get / name).createDirectory())
}
diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala
index 66a0da3a0f..fb7170b3b3 100644
--- a/src/compiler/scala/tools/nsc/io/File.scala
+++ b/src/compiler/scala/tools/nsc/io/File.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.nsc
package io
diff --git a/src/compiler/scala/tools/nsc/io/FileOperationException.scala b/src/compiler/scala/tools/nsc/io/FileOperationException.scala
index a94b2c2ef2..2863a485df 100644
--- a/src/compiler/scala/tools/nsc/io/FileOperationException.scala
+++ b/src/compiler/scala/tools/nsc/io/FileOperationException.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.nsc
package io
diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala
index a40d01d1f5..9346e88bb2 100644
--- a/src/compiler/scala/tools/nsc/io/PlainFile.scala
+++ b/src/compiler/scala/tools/nsc/io/PlainFile.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
@@ -11,8 +10,7 @@ package io
import java.io.{ File => JFile, FileInputStream, FileOutputStream, IOException }
import PartialFunction._
-object PlainFile
-{
+object PlainFile {
/**
* If the specified File exists, returns an abstract file backed
* by it. Otherwise, returns null.
diff --git a/src/compiler/scala/tools/nsc/io/SourceReader.scala b/src/compiler/scala/tools/nsc/io/SourceReader.scala
index ccd946d0b6..cc69c238b3 100644
--- a/src/compiler/scala/tools/nsc/io/SourceReader.scala
+++ b/src/compiler/scala/tools/nsc/io/SourceReader.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/io/VirtualFile.scala b/src/compiler/scala/tools/nsc/io/VirtualFile.scala
index 6e3ad7ead6..421e39195d 100644
--- a/src/compiler/scala/tools/nsc/io/VirtualFile.scala
+++ b/src/compiler/scala/tools/nsc/io/VirtualFile.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
@@ -32,7 +31,7 @@ class VirtualFile(val name: String, _path: String) extends AbstractFile
*/
def this(name: String) = this(name, name)
- override def hashCode = name.hashCode
+ override def hashCode = name.##
override def equals(that: Any) = cond(that) { case x: VirtualFile => x.name == name }
//########################################################################
diff --git a/src/compiler/scala/tools/nsc/io/ZipArchive.scala b/src/compiler/scala/tools/nsc/io/ZipArchive.scala
index 4ee3a29671..4be11fc9a8 100644
--- a/src/compiler/scala/tools/nsc/io/ZipArchive.scala
+++ b/src/compiler/scala/tools/nsc/io/ZipArchive.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index fe46e22654..0388df7005 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
//todo: allow infix type patterns
diff --git a/src/compiler/scala/tools/nsc/javac/JavaTokens.scala b/src/compiler/scala/tools/nsc/javac/JavaTokens.scala
index c91ecc95c2..eb64ffe062 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaTokens.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaTokens.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package javac
diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala
index de3204318f..2c9d974d61 100644
--- a/src/compiler/scala/tools/nsc/matching/Matrix.scala
+++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala
@@ -16,7 +16,7 @@ trait Matrix extends MatrixAdditions {
import analyzer.Typer
import CODE._
import Debug._
- import Flags.{ TRANS_FLAG }
+ import Flags.{ TRANS_FLAG, SYNTHETIC }
/** Translation of match expressions.
*
@@ -201,7 +201,7 @@ trait Matrix extends MatrixAdditions {
{
val n: Name = if (name == null) newName(pos, "temp") else name
// careful: pos has special meaning
- owner.newVariable(pos, n) setInfo tpe setFlag (0L /: flags)(_|_)
+ owner.newVariable(pos, n) setInfo tpe setFlag (SYNTHETIC.toLong /: flags)(_|_)
}
def typedValDef(x: Symbol, rhs: Tree) =
diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
index d3dddbfaaf..fbfe00d2c1 100644
--- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
@@ -135,7 +135,7 @@ trait MatrixAdditions extends ast.TreeDSL
}
}
- returning[Tree](resetTraverser traverse _)(lxtt transform tree)
+ returning(lxtt transform tree)(resetTraverser traverse _)
}
}
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index d4a920008f..f33f637a46 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -3,12 +3,10 @@
* Copyright 2007 Google Inc. All Rights Reserved.
* Author: bqe@google.com (Burak Emir)
*/
-// $Id$
package scala.tools.nsc
package matching
-import util.Position
import transform.ExplicitOuter
import symtab.Flags
import collection._
@@ -172,11 +170,7 @@ trait ParallelMatching extends ast.TreeDSL
def tail = ps.tail
def size = ps.length
- def headType = head.necessaryType
- def isCaseHead = head.isCaseClass
- private val dummyCount = if (isCaseHead) headType.typeSymbol.caseFieldAccessors.length else 0
- def dummies = emptyPatterns(dummyCount)
- // def dummies = head.dummies
+ def dummies = head.dummies
def apply(i: Int): Pattern = ps(i)
def pzip() = ps.zipWithIndex
@@ -193,9 +187,10 @@ trait ParallelMatching extends ast.TreeDSL
}
}
- object TypedUnapply {
- def unapply(x: Tree): Option[Boolean] = condOpt(x) {
- case Typed(UnapplyParamType(tpe), tpt) => !(tpt.tpe <:< tpe)
+ if (settings.Xmigration28.value) {
+ for (p <- ps ; if isArraySeqTest(scrut.tpe, p.tpe)) {
+ val reportPos = if (p.tree.pos.isDefined) p.tree.pos else scrut.pos
+ cunit.warning(reportPos, "An Array will no longer match as Seq[_].")
}
}
@@ -203,7 +198,7 @@ trait ParallelMatching extends ast.TreeDSL
tracing("Rule", head match {
case x if isEquals(x.tree.tpe) => new MixEquals(this, rest)
case x: SequencePattern => new MixSequence(this, rest, x)
- case AnyUnapply(false) => new MixUnapply(this, rest, false)
+ case AnyUnapply(false) => new MixUnapply(this, rest)
case _ =>
isPatternSwitch(scrut, ps) match {
case Some(x) => new MixLiteralInts(x, rest)
@@ -359,7 +354,7 @@ trait ParallelMatching extends ast.TreeDSL
/** mixture rule for unapply pattern
*/
- class MixUnapply(val pmatch: PatternMatch, val rest: Rep, typeTest: Boolean) extends RuleApplication {
+ class MixUnapply(val pmatch: PatternMatch, val rest: Rep) extends RuleApplication {
val uapattern = head match { case x: UnapplyPattern => x ; case _ => abort("XXX") }
val ua @ UnApply(app, args) = head.tree
@@ -444,32 +439,92 @@ trait ParallelMatching extends ast.TreeDSL
* Note: pivot == head, just better typed.
*/
sealed class MixSequence(val pmatch: PatternMatch, val rest: Rep, pivot: SequencePattern) extends RuleApplication {
+ require(scrut.tpe <:< head.tpe)
+
def hasStar = pivot.hasStar
- private def pivotLen = pivot.nonStarLength
+ private def pivotLen = pivot.nonStarLength
+ private def seqDummies = emptyPatterns(pivot.elems.length + 1)
// one pattern var per sequence element up to elemCount, and one more for the rest of the sequence
lazy val pvs = scrut createSequenceVars pivotLen
- // divide the remaining rows into success/failure branches, expanding subsequences of patterns
- private lazy val rowsplit = {
- require(scrut.tpe <:< head.tpe)
+ // Should the given pattern join the expanded pivot in the success matrix? If so,
+ // this partial function will be defined for the pattern, and the result of the apply
+ // is the expanded sequence of new patterns.
+ lazy val successMatrixFn = new PartialFunction[Pattern, List[Pattern]] {
+ private def seqIsDefinedAt(x: SequenceLikePattern) = (hasStar, x.hasStar) match {
+ case (true, true) => true
+ case (true, false) => pivotLen <= x.nonStarLength
+ case (false, true) => pivotLen >= x.nonStarLength
+ case (false, false) => pivotLen == x.nonStarLength
+ }
- val res = for ((c, rows) <- pmatch pzip rest.rows) yield {
- def canSkip = pivot canSkipSubsequences c
- def passthrough(skip: Boolean) = if (skip) None else Some(rows insert c)
+ def isDefinedAt(pat: Pattern) = pat match {
+ case x: SequenceLikePattern => seqIsDefinedAt(x)
+ case WildcardPattern() => true
+ case _ => false
+ }
- pivot.subsequences(c, scrut.seqType) match {
- case Some(ps) => (Some(rows insert ps), passthrough(canSkip))
- case None => (None, passthrough(false))
- }
+ def apply(pat: Pattern): List[Pattern] = pat match {
+ case x: SequenceLikePattern =>
+ def isSameLength = pivotLen == x.nonStarLength
+ def rebound = x.nonStarPatterns :+ (x.elemPatterns.last rebindTo WILD(scrut.seqType))
+
+ (pivot.hasStar, x.hasStar, isSameLength) match {
+ case (true, true, true) => rebound :+ NoPattern
+ case (true, true, false) => (seqDummies drop 1) :+ x
+ case (true, false, true) => x.elemPatterns ++ List(NilPattern, NoPattern)
+ case (false, true, true) => rebound
+ case (false, false, true) => x.elemPatterns :+ NoPattern
+ case _ => seqDummies
+ }
+
+ case _ => seqDummies
}
+ }
+
+ // Should the given pattern be in the fail matrix? This is true of any sequences
+ // as long as the result of the length test on the pivot doesn't make it impossible:
+ // for instance if neither sequence is right ignoring and they are of different
+ // lengths, the later one cannot match since its length must be wrong.
+ def failureMatrixFn(c: Pattern) = (pivot ne c) && (c match {
+ case x: SequenceLikePattern =>
+ (hasStar, x.hasStar) match {
+ case (_, true) => true
+ case (true, false) => pivotLen > x.nonStarLength
+ case (false, false) => pivotLen != x.nonStarLength
+ }
+ case WildcardPattern() => true
+ case _ => false
+ })
- res.unzip match { case (l1, l2) => (l1.flatten, l2.flatten) }
+ // divide the remaining rows into success/failure branches, expanding subsequences of patterns
+ val successRows = pmatch pzip rest.rows collect {
+ case (c, row) if successMatrixFn isDefinedAt c => row insert successMatrixFn(c)
}
+ val failRows = pmatch pzip rest.rows collect {
+ case (c, row) if failureMatrixFn(c) => row insert c
+ }
+
+ // the discrimination test for sequences is a call to lengthCompare. Note that
+ // this logic must be fully consistent wiith successMatrixFn and failureMatrixFn above:
+ // any inconsistency will (and frequently has) manifested as pattern matcher crashes.
+ lazy val cond = {
+ // the method call symbol
+ val methodOp: Symbol = head.tpe member nme.lengthCompare
+
+ // the comparison to perform. If the pivot is right ignoring, then a scrutinee sequence
+ // of >= pivot length could match it; otherwise it must be exactly equal.
+ val compareOp: (Tree, Tree) => Tree = if (hasStar) _ INT_>= _ else _ INT_== _
- lazy val cond = (pivot precondition pmatch).get // length check
- lazy val success = squeezedBlockPVs(pvs, remake(rowsplit._1, pvs, hasStar).toTree)
- lazy val failure = remake(rowsplit._2).toTree
+ // scrutinee.lengthCompare(pivotLength) [== | >=] 0
+ val compareFn: Tree => Tree = (t: Tree) => compareOp((t DOT methodOp)(LIT(pivotLen)), ZERO)
+
+ // wrapping in a null check on the scrutinee
+ nullSafe(compareFn, FALSE)(scrut.id)
+ }
+ lazy val success = squeezedBlockPVs(pvs, remake(successRows, pvs, hasStar).toTree)
+ lazy val failure = remake(failRows).toTree
final def tree(): Tree = codegen
}
@@ -508,53 +563,38 @@ trait ParallelMatching extends ast.TreeDSL
* remaining: remaining, rows index and pattern
*/
class MixTypes(val pmatch: PatternMatch, val rest: Rep) extends RuleApplication {
- case class Yes(bx: Int, moreSpecific: Pattern, subsumed: List[Pattern])
- case class No(bx: Int, remaining: Pattern)
-
- val (yeses, noes) = {
- val _ys = new ListBuffer[Yes]
- val _ns = new ListBuffer[No]
-
- for ((pattern, j) <- pmatch.pzip()) {
- // scrutinee, head of pattern group
- val (s, p) = (pattern.tpe, head.necessaryType)
-
- def isEquivalent = head.necessaryType =:= pattern.tpe
- def isObjectTest = pattern.isObject && (p =:= pattern.necessaryType)
-
- def sMatchesP = matches(s, p)
- def pMatchesS = matches(p, s)
-
- def ifEquiv(yes: Pattern): Pattern = if (isEquivalent) yes else pattern
-
- def passl(p: Pattern = NoPattern, ps: List[Pattern] = pmatch.dummies) = Some(Yes(j, p, ps))
- def passr() = Some( No(j, pattern))
-
- def typed(pp: Tree) = passl(ifEquiv(Pattern(pp)))
- def subs() = passl(ifEquiv(NoPattern), pattern subpatterns pmatch)
-
- val (oneY, oneN) = pattern match {
- case Pattern(LIT(null), _) if !(p =:= s) => (None, passr) // (1)
- case x if isObjectTest => (passl(), None) // (2)
- case Pattern(Typed(pp, _), _) if sMatchesP => (typed(pp), None) // (4)
- // The next line used to be this which "fixed" 1697 but introduced
- // numerous regressions including #3136.
- // case Pattern(_: UnApply, _) => (passl(), passr)
- case Pattern(_: UnApply, _) => (None, passr)
- case x if !x.isDefault && sMatchesP => (subs(), None)
- case x if x.isDefault || pMatchesS => (passl(), passr)
- case _ => (None, passr)
- }
- oneY map (_ys +=)
- oneN map (_ns +=)
+ val succRows = new ListBuffer[(Int, List[Pattern])]
+ val failRows = new ListBuffer[(Int, Pattern)]
+
+ for ((pattern, j) <- pmatch.pzip()) {
+ def isMoreSpecific = matches(pattern.tpe, head.tpe)
+ def isLessSpecific = matches(head.tpe, pattern.tpe)
+ def isEquivalent = head.tpe =:= pattern.tpe
+ def isObjectTest = pattern.isObject && (head.tpe =:= pattern.tpe)
+
+ def whichSubs = if (head.isCaseClass) (pattern expandToArity head.arity) else Nil
+
+ def ifElsePattern(yes: Pattern) = if (isEquivalent) yes else pattern
+
+ def succDummy = succRows += ((j, NoPattern :: pmatch.dummies))
+ def succTyped(pp: Pattern) = succRows += ((j, ifElsePattern(pp) :: pmatch.dummies))
+ def succSubs = succRows += ((j, ifElsePattern(NoPattern) :: whichSubs))
+ def failOnly = failRows += ((j, pattern))
+
+ pattern match {
+ case Pattern(LIT(null), _) if !isEquivalent => failOnly
+ case x if isObjectTest => succDummy
+ // Note: bugs 1697/2337/etc have their origins right here because they
+ // have a type test which when passed doesn't guarantee a match: the
+ // unapply can still fail.
+ case Pattern(Typed(pp, _), _) if isMoreSpecific => succTyped(Pattern(pp))
+ case Pattern(UnApply(_, _), _) => failOnly
+ case x if !x.isDefault && isMoreSpecific => succSubs
+ case x if x.isDefault || isLessSpecific => succDummy ; failOnly
+ case _ => failOnly
}
- (_ys.toList, _ns.toList)
}
- val moreSpecific = yeses map (_.moreSpecific)
- val subsumed = yeses map (x => (x.bx, x.subsumed))
- val remaining = noes map (x => (x.bx, x.remaining))
-
// temporary checks so we're less crashy while we determine what to implement.
def checkErroneous(scrut: Scrutinee): Type = {
scrut.tpe match {
@@ -565,29 +605,20 @@ trait ParallelMatching extends ast.TreeDSL
}
}
- private def mkZipped =
- for (Yes(j, moreSpecific, subsumed) <- yeses) yield
- j -> (moreSpecific :: subsumed)
-
- lazy val casted = scrut castedTo pmatch.headType
+ lazy val casted = scrut castedTo head.tpe
lazy val cond = condition(checkErroneous(casted), scrut, head.boundVariables.nonEmpty)
- private def isAnyMoreSpecific = yeses exists (x => !x.moreSpecific.isEmpty)
- lazy val (subtests, subtestVars) =
- if (isAnyMoreSpecific) (mkZipped, List(casted.pv))
- else (subsumed, Nil)
-
- lazy val newRows =
- for ((j, ps) <- subtests) yield
- (rest rows j).insert2(ps, pmatch(j).boundVariables, casted.sym)
-
lazy val success = {
- val srep = remake(newRows, subtestVars ::: casted.accessorPatternVars, includeScrut = false)
+ val newRows =
+ for ((j, ps) <- succRows.toList) yield
+ (rest rows j).insert2(ps, pmatch(j).boundVariables, casted.sym)
+
+ val newRoots = casted.pv :: casted.accessorPatternVars
+ val srep = remake(newRows, newRoots, false)
squeezedBlock(casted.allValDefs, srep.toTree)
}
- lazy val failure =
- mkFail(remaining map { case (p1, p2) => rest rows p1 insert p2 })
+ lazy val failure = mkFail(failRows.toList map { case (p1, p2) => rest rows p1 insert p2 })
final def tree(): Tree = codegen
}
diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
index 83fd3a9608..82bddb2013 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
@@ -104,10 +104,7 @@ trait PatternBindings extends ast.TreeDSL
// Like rebindToEqualsCheck, but subtly different. Not trying to be
// mysterious -- I haven't sorted it all out yet.
- def rebindToObjectCheck(): Pattern = {
- val sType = sufficientType
- rebindToType(mkEqualsRef(sType), sType)
- }
+ def rebindToObjectCheck(): Pattern = rebindToType(mkEqualsRef(atomicTpe), atomicTpe)
/** Helpers **/
private def wrapBindings(vs: List[Symbol], pat: Tree): Tree = vs match {
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index a21a9c7d9f..7621c1c2f3 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -85,10 +85,11 @@ trait Patterns extends ast.TreeDSL {
// 8.1.4 (a)
case class ApplyIdentPattern(tree: Apply) extends ApplyPattern with NamePattern {
- require (!isVarPattern(fn) && args.isEmpty)
+ // XXX - see bug 3411 for code which violates this assumption
+ // require (!isVarPattern(fn) && args.isEmpty)
val ident @ Ident(name) = fn
- override def sufficientType = Pattern(ident).equalsCheck
+ override def atomicTpe = Pattern(ident).equalsCheck
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
override def description = "Id(%s)".format(name)
}
@@ -97,7 +98,7 @@ trait Patterns extends ast.TreeDSL {
require (args.isEmpty)
val Apply(select: Select, _) = tree
- override def sufficientType = mkSingletonFromQualifier
+ override def atomicTpe = mkSingletonFromQualifier
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
override def description = backticked match {
case Some(s) => "this." + s
@@ -116,7 +117,7 @@ trait Patterns extends ast.TreeDSL {
case class ObjectPattern(tree: Apply) extends ApplyPattern { // NamePattern?
require(!fn.isType && isModule)
- override def sufficientType = tpe.narrow
+ override def atomicTpe = tpe.narrow
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
override def description = "Obj(%s)".format(fn)
}
@@ -138,9 +139,7 @@ trait Patterns extends ast.TreeDSL {
private def isColonColon = cleanName == "::"
- override def subpatterns(pm: MatchMatrix#PatternMatch) =
- if (pm.head.isCaseClass) toPats(args)
- else super.subpatterns(pm)
+ override def expandToArity(newArity: Int): List[Pattern] = toPats(args)
override def simplify(pv: PatternVar) =
if (args.isEmpty) this rebindToEmpty tree.tpe
@@ -167,19 +166,20 @@ trait Patterns extends ast.TreeDSL {
private val MethodType(List(arg, _*), _) = fn.tpe
private def uaTyped = Typed(tree, TypeTree(arg.tpe)) setType arg.tpe
- override def necessaryType = arg.tpe
+ // to match an extractor, the arg type must be matched.
+ override def tpe = arg.tpe
override def simplify(pv: PatternVar) =
if (pv.sym.tpe <:< arg.tpe) this
else this rebindTo uaTyped
- override def description = "UnApp(%s => %s)".format(necessaryType, resTypesString)
+ override def description = "UnApp(%s => %s)".format(tpe, resTypesString)
}
// 8.1.8 (unapplySeq calls)
- case class SequenceExtractorPattern(tree: UnApply) extends UnapplyPattern {
+ case class SequenceExtractorPattern(tree: UnApply) extends UnapplyPattern with SequenceLikePattern {
- private val UnApply(
+ lazy val UnApply(
Apply(TypeApply(Select(_, nme.unapplySeq), List(tptArg)), _),
List(ArrayValue(_, elems))
) = tree
@@ -211,90 +211,24 @@ trait Patterns extends ast.TreeDSL {
override def description = "UnSeq(%s => %s)".format(tptArg, resTypesString)
}
- abstract class SequencePattern extends Pattern {
- val tree: ArrayValue
- def nonStarPatterns: List[Pattern]
- def subsequences(other: Pattern, seqType: Type): Option[List[Pattern]]
- def canSkipSubsequences(second: Pattern): Boolean
-
- lazy val ArrayValue(elemtpt, elems) = tree
- lazy val elemPatterns = toPats(elems)
-
- override def dummies = emptyPatterns(elems.length + 1)
- override def subpatternsForVars: List[Pattern] = elemPatterns
+ trait SequenceLikePattern extends Pattern {
+ def elems: List[Tree]
+ def elemPatterns = toPats(elems)
+ def nonStarPatterns: List[Pattern] = if (hasStar) elemPatterns.init else elemPatterns
def nonStarLength = nonStarPatterns.length
def isAllDefaults = nonStarPatterns forall (_.isDefault)
- def isShorter(other: SequencePattern) = nonStarLength < other.nonStarLength
- def isSameLength(other: SequencePattern) = nonStarLength == other.nonStarLength
-
- protected def lengthCheckOp: (Tree, Tree) => Tree =
- if (hasStar) _ ANY_>= _
- else _ MEMBER_== _
-
- // optimization to avoid trying to match if length makes it impossible
- override def precondition(pm: PatternMatch) = {
- import pm.{ scrut, head }
- val len = nonStarLength
- val compareOp = head.tpe member nme.lengthCompare
-
- def cmpFunction(t1: Tree) = lengthCheckOp((t1 DOT compareOp)(LIT(len)), ZERO)
-
- Some(nullSafe(cmpFunction _, FALSE)(scrut.id))
- }
-
- /** True if 'next' must be checked even if 'first' failed to match after passing its length test
- * (the conditional supplied by getPrecondition.) This is an optimization to avoid checking sequences
- * which cannot match due to a length incompatibility.
- */
- override def description = "Seq(%s)".format(elemPatterns)
+ def isShorter(other: SequenceLikePattern) = nonStarLength < other.nonStarLength
+ def isSameLength(other: SequenceLikePattern) = nonStarLength == other.nonStarLength
}
// 8.1.8 (b) (literal ArrayValues)
- case class SequenceNoStarPattern(tree: ArrayValue) extends SequencePattern {
- require(!hasStar)
- lazy val nonStarPatterns = elemPatterns
-
- // no star
- def subsequences(other: Pattern, seqType: Type): Option[List[Pattern]] =
- condOpt(other) {
- case next: SequenceStarPattern if isSameLength(next) => next rebindStar seqType
- case next: SequenceNoStarPattern if isSameLength(next) => next.elemPatterns ::: List(NoPattern)
- case WildcardPattern() | (_: SequencePattern) => dummies
- }
-
- def canSkipSubsequences(second: Pattern): Boolean =
- (tree eq second.tree) || (cond(second) {
- case x: SequenceNoStarPattern => (x isShorter this) && this.isAllDefaults
- })
- }
-
- // 8.1.8 (b)
- case class SequenceStarPattern(tree: ArrayValue) extends SequencePattern {
- require(hasStar)
- lazy val nonStarPatterns = elemPatterns.init
-
- // yes star
- private def nilPats = List(NilPattern, NoPattern)
- def subsequences(other: Pattern, seqType: Type): Option[List[Pattern]] =
- condOpt(other) {
- case next: SequenceStarPattern if isSameLength(next) => (next rebindStar seqType) ::: List(NoPattern)
- case next: SequenceStarPattern if (next isShorter this) => (dummies drop 1) ::: List(next)
- case next: SequenceNoStarPattern if isSameLength(next) => next.elemPatterns ::: nilPats
- case WildcardPattern() | (_: SequencePattern) => dummies
- }
-
- def rebindStar(seqType: Type): List[Pattern] =
- nonStarPatterns ::: List(elemPatterns.last rebindTo WILD(seqType))
-
- def canSkipSubsequences(second: Pattern): Boolean =
- (tree eq second.tree) || (cond(second) {
- case x: SequenceStarPattern => this isShorter x
- case x: SequenceNoStarPattern => !(x isShorter this)
- })
+ case class SequencePattern(tree: ArrayValue) extends Pattern with SequenceLikePattern {
+ lazy val ArrayValue(elemtpt, elems) = tree
- override def description = "Seq*(%s)".format(elemPatterns)
+ override def subpatternsForVars: List[Pattern] = elemPatterns
+ override def description = "Seq(%s)".format(elemPatterns mkString ", ")
}
// 8.1.8 (c)
@@ -353,7 +287,7 @@ trait Patterns extends ast.TreeDSL {
case x: Literal => LiteralPattern(x)
case x: UnApply => UnapplyPattern(x)
case x: Ident => if (isVarPattern(x)) VariablePattern(x) else SimpleIdPattern(x)
- case x: ArrayValue => if (isRightIgnoring(x)) SequenceStarPattern(x) else SequenceNoStarPattern(x)
+ case x: ArrayValue => SequencePattern(x)
case x: Select => StableIdPattern(x)
case x: Star => StarPattern(x)
case x: This => ThisPattern(x) // XXX ?
@@ -377,13 +311,20 @@ trait Patterns extends ast.TreeDSL {
object UnapplyPattern {
private object UnapplySeq {
+ /** This is as far as I can tell an elaborate attempt to spot case List(...) and
+ * avoid the extractor penalty. It has led to some bugs (e.g. 2800, 3050) which
+ * I attempt to address below.
+ */
private object TypeApp {
def unapply(x: Any) = condOpt(x) {
case TypeApply(sel @ Select(stor, nme.unapplySeq), List(tpe)) if stor.symbol eq ListModule => tpe
}
}
def unapply(x: UnApply) = condOpt(x) {
- case UnApply(Apply(TypeApp(tptArg), _), List(ArrayValue(_, xs))) => (tptArg, xs)
+ case UnApply(Apply(TypeApp(tptArg), _), List(ArrayValue(_, xs)))
+ // make sure it's not only _*, as otherwise the rewrite
+ // also removes the instance check.
+ if (xs.isEmpty || xs.size > 1 || !isStar(xs.head)) => (tptArg, xs)
}
}
@@ -449,7 +390,7 @@ trait Patterns extends ast.TreeDSL {
protected def mkSingletonFromQualifier = {
def pType = qualifier match {
case _: Apply => PseudoType(tree)
- case _ => singleType(Pattern(qualifier).necessaryType, sym)
+ case _ => singleType(Pattern(qualifier).tpe, sym)
}
qualifier.tpe match {
case t: ThisType => singleType(t, sym) // this.X
@@ -460,7 +401,7 @@ trait Patterns extends ast.TreeDSL {
sealed trait NamePattern extends Pattern {
def name: Name
- override def sufficientType = tpe.narrow
+ override def atomicTpe = tpe.narrow
override def simplify(pv: PatternVar) = this.rebindToEqualsCheck()
override def description = name.toString()
}
@@ -487,26 +428,31 @@ trait Patterns extends ast.TreeDSL {
protected lazy val Apply(fn, args) = tree
override def subpatternsForVars: List[Pattern] = toPats(args)
- override def dummies =
- if (!this.isCaseClass) Nil
- else emptyPatterns(sufficientType.typeSymbol.caseFieldAccessors.size)
-
def isConstructorPattern = fn.isType
}
sealed abstract class Pattern extends PatternBindingLogic {
val tree: Tree
+ // The type of a pattern says: in order for something to match this
+ // pattern, it must conform to this type. It does NOT say that if
+ // something does conform to this type, it definitely matches the pattern:
+ // see atomic type for that.
+ def tpe = tree.tpe
+
+ // The atomic type of a pattern says: if something matches this, it
+ // definitely matches the pattern (but this is independent of nullness
+ // and guards, which are checked independently.)
+ def atomicTpe = tpe
+
// returns either a simplification of this pattern or identity.
def simplify(pv: PatternVar): Pattern = this
- def simplify(): Pattern = this simplify null
- // the right number of dummies for this pattern
- def dummies: List[Pattern] = Nil
+ // the arity of this pattern
+ def arity = if (isCaseClass) caseAccessors.length else 0
- // given this scrutinee, what if any condition must be satisfied before
- // we even try to match?
- def precondition(scrut: PatternMatch): Option[Tree] = None
+ // the right number of dummies for this pattern
+ def dummies: List[Pattern] = emptyPatterns(arity)
// 8.1.13
// A pattern p is irrefutable for type T if any of the following applies:
@@ -517,33 +463,26 @@ trait Patterns extends ast.TreeDSL {
// pi is irrefutable for Ti.
def irrefutableFor(tpe: Type) = false
- // does this pattern completely cover that pattern (i.e. latter cannot be matched)
- def completelyCovers(second: Pattern) = false
-
// Is this a default pattern (untyped "_" or an EmptyTree inserted by the matcher)
def isDefault = false
- // what type must a scrutinee have to have any chance of matching this pattern?
- def necessaryType = tpe
-
- // what type could a scrutinee have which would automatically indicate a match?
- // (nullness and guards will still be checked.)
- def sufficientType = tpe
-
// XXX have to determine if this can be made useful beyond an extractor barrier.
// Default sufficient type might be NothingClass.tpe, tpe.narrow, ...
// the subpatterns for this pattern (at the moment, that means constructor arguments)
- def subpatterns(pm: MatchMatrix#PatternMatch): List[Pattern] = pm.dummies
+ def expandToArity(newArity: Int): List[Pattern] =
+ if (isDefault) emptyPatterns(newArity)
+ else if (newArity == 0) Nil
+ else Predef.error("expandToArity(" + newArity + ") in " + this)
def sym = tree.symbol
- def tpe = tree.tpe
def prefix = tpe.prefix
def isEmpty = tree.isEmpty
def isSymValid = (sym != null) && (sym != NoSymbol)
def isModule = sym.isModule || tpe.termSymbol.isModule
def isCaseClass = tpe.typeSymbol hasFlag Flags.CASE
+ def caseAccessors = tpe.typeSymbol.caseFieldAccessors
def isObject = isSymValid && prefix.isStable // XXX not entire logic
def unadorn(t: Tree): Tree = Pattern unadorn t
@@ -585,7 +524,7 @@ trait Patterns extends ast.TreeDSL {
if (boundVariables.isEmpty) description
else "%s%s".format(bindingsDescription, description)
}
- def toTypeString() = "%s <: x <: %s".format(necessaryType, sufficientType)
+ def toTypeString() = "%s <: x <: %s".format(tpe, atomicTpe)
}
/*** Extractors ***/
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
index f527441c68..1b7e208334 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
@@ -2,7 +2,6 @@
* Copyright 2007-2010 LAMP/EPFL
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
package plugins
diff --git a/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala b/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala
index 1da08cc4ee..4234d49545 100644
--- a/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala
+++ b/src/compiler/scala/tools/nsc/plugins/PluginComponent.scala
@@ -3,7 +3,6 @@
* @author Lex Spoon
* Updated by Anders Bach Nielsen
*/
-// $Id$
package scala.tools.nsc
package plugins
diff --git a/src/compiler/scala/tools/nsc/plugins/PluginDescription.scala b/src/compiler/scala/tools/nsc/plugins/PluginDescription.scala
index 2345fcc32c..2498d84338 100644
--- a/src/compiler/scala/tools/nsc/plugins/PluginDescription.scala
+++ b/src/compiler/scala/tools/nsc/plugins/PluginDescription.scala
@@ -2,7 +2,6 @@
* Copyright 2007-2010 LAMP/EPFL
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
package plugins
diff --git a/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala b/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala
index 42780d7a05..f0402809d7 100644
--- a/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala
+++ b/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala
@@ -2,7 +2,6 @@
* Copyright 2007-2010 LAMP/EPFL
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
package plugins
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugins.scala b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
index e800e0f904..5823a09995 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugins.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
@@ -3,7 +3,6 @@
* @author Lex Spoon
* Updated by Anders Bach Nielsen
*/
-// $Id$
package scala.tools.nsc
package plugins
diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
index e35843fc9c..11ef7ffb68 100644
--- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
@@ -2,7 +2,6 @@
* Copyright 2002-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package reporters
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index f7d380c975..1f01087dad 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -2,7 +2,6 @@
* Copyright 2002-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package reporters
diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
index bdb6c6ae6f..8dcb5183bb 100644
--- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
@@ -2,7 +2,6 @@
* Copyright 2002-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package reporters
diff --git a/src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala b/src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala
index 4c2f6a4a69..56f904a8bc 100644
--- a/src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala
@@ -2,7 +2,6 @@
* Copyright 2002-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package reporters
diff --git a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala
index b94639bb5c..e4736297e9 100644
--- a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala
@@ -2,7 +2,6 @@
* Copyright 2002-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package reporters
diff --git a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala
index 75e2c5ce11..21608f7f05 100644
--- a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala
@@ -69,9 +69,12 @@ trait AbsSettings {
* In immutable, of course they will return a new object, which means
* we can't use "this.type", at least not in a non-casty manner, which
* is unfortunate because we lose type information without it.
+ *
+ * ...but now they're this.type because of #3462. The immutable
+ * side doesn't exist yet anyway.
*/
- def withAbbreviation(name: String): Setting
- def withHelpSyntax(help: String): Setting
+ def withAbbreviation(name: String): this.type
+ def withHelpSyntax(help: String): this.type
def helpSyntax: String = name
def abbreviations: List[String] = Nil
diff --git a/src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala b/src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala
index 945d9aa2fe..388e68497e 100644
--- a/src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala
+++ b/src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala
@@ -2,7 +2,6 @@
* Copyright 2007-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala b/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala
index f2e62856d5..40177fad10 100644
--- a/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala
+++ b/src/compiler/scala/tools/nsc/symtab/AnnotationInfos.scala
@@ -2,7 +2,6 @@
* Copyright 2007-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 3511565326..597a34c773 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -2,14 +2,14 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
import scala.collection.mutable.{HashMap, HashSet}
-import scala.tools.nsc.util.{Position, NoPosition}
+import scala.tools.nsc.util.NoPosition
import Flags._
+import PartialFunction._
trait Definitions extends reflect.generic.StandardDefinitions {
self: SymbolTable =>
@@ -17,12 +17,6 @@ trait Definitions extends reflect.generic.StandardDefinitions {
object definitions extends AbsDefinitions {
def isDefinitionsInitialized = isInitialized
- // Working around bug #2133
- private object definitionHelpers {
- def cond[T](x: T)(f: PartialFunction[T, Boolean]) = (f isDefinedAt x) && f(x)
- }
- import definitionHelpers._
-
// symbols related to packages
var emptypackagescope: Scope = null //debug
diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala
index b0cc3a5340..de8f92fdf4 100644
--- a/src/compiler/scala/tools/nsc/symtab/Flags.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/InfoTransformers.scala b/src/compiler/scala/tools/nsc/symtab/InfoTransformers.scala
index 54bd35e5b3..95dcb07c7c 100644
--- a/src/compiler/scala/tools/nsc/symtab/InfoTransformers.scala
+++ b/src/compiler/scala/tools/nsc/symtab/InfoTransformers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/Names.scala b/src/compiler/scala/tools/nsc/symtab/Names.scala
index b0e6c5250a..e6222a7a94 100644
--- a/src/compiler/scala/tools/nsc/symtab/Names.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Names.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/Scopes.scala b/src/compiler/scala/tools/nsc/symtab/Scopes.scala
index f305f20d2a..bc8b93ac2c 100644
--- a/src/compiler/scala/tools/nsc/symtab/Scopes.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Scopes.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 9133228768..ed72fc16fa 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
@@ -330,7 +329,7 @@ trait StdNames extends reflect.generic.StdNames { self: SymbolTable =>
val print = newTermName("print")
val productArity = newTermName("productArity")
val productElement = newTermName("productElement")
- val productElementName = newTermName("productElementName")
+ // val productElementName = newTermName("productElementName")
val productPrefix = newTermName("productPrefix")
val readResolve = newTermName("readResolve")
val sameElements = newTermName("sameElements")
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 947f5a8f88..a95c8ada8f 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
index 75902568fa..0fdbeae98f 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index ebab5d9be7..3157e5cc20 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
@@ -928,7 +927,20 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
* type parameters later.
*/
def typeParams: List[Symbol] =
- if (isMonomorphicType) List() else { rawInfo.load(this); rawInfo.typeParams }
+ if (isMonomorphicType)
+ List()
+ else {
+ if (validTo == NoPeriod) {
+ val current = phase
+ try {
+ phase = phaseOf(infos.validFrom)
+ rawInfo.load(this)
+ } finally {
+ phase = current
+ }
+ }
+ rawInfo.typeParams
+ }
/** The value parameter sections of this symbol.
*/
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index dc59587c4a..e0987c2d8b 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -2301,7 +2301,7 @@ A type's typeSymbol should never be inspected directly.
origin+
(if(typeArgs.isEmpty) "" else (typeArgs map (_.safeToString)).mkString("[ ", ", ", " ]")) // +"#"+tid //DEBUG
if (constr.inst eq null) "<null " + origin + ">"
- else if (settings.debug.value) varString+"(@"+constr.hashCode+")"+constr.toString
+ else if (settings.debug.value) varString+"(@"+constr.## +")"+constr.toString
else if (constr.inst eq NoType) varString
else constr.inst.toString
}
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala
index b32646e3cb..106318a47d 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/AbstractFileReader.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
index a139f605b0..a3917cf2d2 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 7cd32ff81e..9c382439bc 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 23f45e0d13..624b3635bf 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Iulian Dragos
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
index 0ae2d5b015..d1f9280872 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 68d314bfe9..91141ce4d6 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala
index 4022258746..a94838e163 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
index 20dbb4d917..f62a42375a 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
@@ -2,7 +2,6 @@
* Copyright 2004-2010 LAMP/EPFL
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index 4d9c0ffc92..a90fb8b66c 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -2,7 +2,6 @@
* Copyright 2004-2010 LAMP/EPFL
*/
-// $Id$
package scala.tools.nsc
package symtab
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 92f117428a..f1ed9f43a0 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
@@ -162,7 +161,8 @@ abstract class AddInterfaces extends InfoTransform {
case ClassInfoType(parents, decls, _) =>
assert(phase == implClassPhase)
ClassInfoType(
- ObjectClass.tpe :: (parents.tail map mixinToImplClass) ::: List(iface.tpe),
+ ObjectClass.tpe :: (parents.tail map mixinToImplClass filter (_.typeSymbol != ObjectClass))
+ ::: List(iface.tpe),
implDecls(sym, decls),
sym)
case PolyType(tparams, restpe) =>
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index e6811cf497..c3c60253b9 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -2,7 +2,6 @@
* Copyrights 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index ad88b783b4..c9049d9ab1 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author
*/
-// $Id$
package scala.tools.nsc
package transform
@@ -28,6 +27,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
import collection.mutable
private val guardedCtorStats: mutable.Map[Symbol, List[Tree]] = new mutable.HashMap[Symbol, List[Tree]]
+ private val ctorParams: mutable.Map[Symbol, List[Symbol]] = new mutable.HashMap[Symbol, List[Symbol]]
def transformClassTemplate(impl: Template): Template = {
val clazz = impl.symbol.owner // the transformed class
@@ -78,18 +78,22 @@ abstract class Constructors extends Transform with ast.TreeDSL {
// A transformer for expressions that go into the constructor
val intoConstructorTransformer = new Transformer {
+ def isParamRef(sym: Symbol) =
+ (sym hasFlag PARAMACCESSOR) &&
+ sym.owner == clazz &&
+ !(sym.isGetter && sym.accessed.isVariable) &&
+ !sym.isSetter
override def transform(tree: Tree): Tree = tree match {
case Apply(Select(This(_), _), List()) =>
// references to parameter accessor methods of own class become references to parameters
// outer accessors become references to $outer parameter
- if ((tree.symbol hasFlag PARAMACCESSOR) && tree.symbol.owner == clazz)
+ if (isParamRef(tree.symbol))
gen.mkAttributedIdent(parameter(tree.symbol.accessed)) setPos tree.pos
else if (tree.symbol.outerSource == clazz && !clazz.isImplClass)
gen.mkAttributedIdent(parameterNamed(nme.OUTER)) setPos tree.pos
else
super.transform(tree)
- case Select(This(_), _)
- if ((tree.symbol hasFlag PARAMACCESSOR) && !tree.symbol.isSetter && tree.symbol.owner == clazz) =>
+ case Select(This(_), _) if (isParamRef(tree.symbol)) =>
// references to parameter accessor field of own class become references to parameters
gen.mkAttributedIdent(parameter(tree.symbol)) setPos tree.pos
case Select(_, _) =>
@@ -301,7 +305,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
case _ => false
}
- log("merging: " + originalStats.mkString("\n") + " : " + specializedStats.mkString("\n"))
+ log("merging: " + originalStats.mkString("\n") + "\nwith\n" + specializedStats.mkString("\n"))
val res = for (s <- originalStats; val stat = s.duplicate) yield {
log("merge: looking at " + stat)
val stat1 = stat match {
@@ -315,8 +319,13 @@ abstract class Constructors extends Transform with ast.TreeDSL {
}
if (stat1 eq stat) {
+ assert(ctorParams(genericClazz).length == constrParams.length)
+ // this is just to make private fields public
+ (new specializeTypes.ImplementationAdapter(ctorParams(genericClazz), constrParams, null, true))(stat1)
+
// statements coming from the original class need retyping in the current context
if (settings.debug.value) log("retyping " + stat1)
+
val d = new specializeTypes.Duplicator
d.retyped(localTyper.context1.asInstanceOf[d.Context],
stat1,
@@ -351,6 +360,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
if (usesSpecializedField && shouldGuard && postfix.nonEmpty) {
// save them for duplication in the specialized subclass
guardedCtorStats(clazz) = postfix
+ ctorParams(clazz) = constrParams
val tree =
If(
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 88a7e13d80..4c000ce3f7 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
@@ -336,9 +335,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
def erasedTypeRef(sym: Symbol): Type =
typeRef(erasure(sym.owner.tpe), sym, List())
- /** Remove duplicate references to class Object in a list of parent classes
- * todo: needed?
- */
+ /** Remove duplicate references to class Object in a list of parent classes */
private def removeDoubleObject(tps: List[Type]): List[Type] = tps match {
case List() => List()
case tp :: tps1 =>
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index ee5bc040f5..f78022bdaa 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
@@ -62,6 +61,12 @@ abstract class ExplicitOuter extends InfoTransform
result
}
+ /** Issue a migration warning for instance checks which might be on an Array and
+ * for which the type parameter conforms to Seq, because these answers changed in 2.8.
+ */
+ def isArraySeqTest(lhs: Type, rhs: Type) =
+ ArrayClass.tpe <:< lhs.widen && rhs.widen.matchesPattern(SeqClass.tpe)
+
def outerAccessor(clazz: Symbol): Symbol = {
val firstTry = clazz.info.decl(nme.expandedName(nme.OUTER, clazz))
if (firstTry != NoSymbol && firstTry.outerSource == clazz) firstTry
@@ -295,7 +300,6 @@ abstract class ExplicitOuter extends InfoTransform
* </p>
*/
class ExplicitOuterTransformer(unit: CompilationUnit) extends OuterPathTransformer(unit) {
-
/** The definition tree of the outer accessor of current class
*/
def outerFieldDef: Tree = VAL(outerField(currentClass)) === EmptyTree
@@ -484,8 +488,14 @@ abstract class ExplicitOuter extends InfoTransform
matchTranslation(mch)
case _ =>
- val x = super.transform(tree)
+ if (settings.Xmigration28.value) tree match {
+ case TypeApply(fn @ Select(qual, _), args) if fn.symbol == Object_isInstanceOf || fn.symbol == Any_isInstanceOf =>
+ if (isArraySeqTest(qual.tpe, args.head.tpe))
+ unit.warning(tree.pos, "An Array will no longer match as Seq[_].")
+ case _ => ()
+ }
+ val x = super.transform(tree)
if (x.tpe eq null) x
else x setType transformInfo(currentOwner, x.tpe)
}
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index 7fc826cdbb..1bee37bfe6 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala
index 9872705dfc..fa93a9b534 100644
--- a/src/compiler/scala/tools/nsc/transform/InfoTransform.scala
+++ b/src/compiler/scala/tools/nsc/transform/InfoTransform.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 6ed0bfcccb..33fa14033e 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index 951fa53041..a6a4a8d22c 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Gilles Dubochet
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 18c4a74950..a9810b2217 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
@@ -568,7 +567,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
val newSyms = newDefs map (_.symbol)
def isNotDuplicate(tree: Tree) = tree match {
case DefDef(_, _, _, _, _, _) =>
- val sym = tree.symbol;
+ val sym = tree.symbol
!(sym.isDeferred &&
(newSyms exists (nsym => nsym.name == sym.name && (nsym.tpe matches sym.tpe))))
case _ =>
@@ -742,14 +741,14 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
&& !sym.accessed.hasFlag(PRESUPER)
&& !sym.isOuterAccessor)
- if (settings.debug.value) {
- log("needsInitFlag(" + sym.fullName + "): " + res)
- log("\tsym.isGetter: " + sym.isGetter)
- log("\t!isInitializedToDefault: " + !sym.isInitializedToDefault + sym.hasFlag(DEFAULTINIT) + sym.hasFlag(ACCESSOR) + sym.isTerm)
- log("\t!sym.hasFlag(PARAMACCESSOR): " + !sym.hasFlag(PARAMACCESSOR))
- //println("\t!sym.accessed.hasFlag(PRESUPER): " + !sym.accessed.hasFlag(PRESUPER))
- log("\t!sym.isOuterAccessor: " + !sym.isOuterAccessor)
- }
+// if (settings.debug.value) {
+// log("needsInitFlag(" + sym.fullName + "): " + res)
+// log("\tsym.isGetter: " + sym.isGetter)
+// log("\t!isInitializedToDefault: " + !sym.isInitializedToDefault + sym.hasFlag(DEFAULTINIT) + sym.hasFlag(ACCESSOR) + sym.isTerm)
+// log("\t!sym.hasFlag(PARAMACCESSOR): " + !sym.hasFlag(PARAMACCESSOR))
+// //println("\t!sym.accessed.hasFlag(PRESUPER): " + !sym.accessed.hasFlag(PRESUPER))
+// log("\t!sym.isOuterAccessor: " + !sym.isOuterAccessor)
+// }
res
}
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
index 305f9218ec..1500759b30 100644
--- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
+++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
index 02e73035be..6661543d89 100644
--- a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
+++ b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index c2e5e474a9..c4ce7fe6e2 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Iulian Dragos
*/
-// $Id$
package scala.tools.nsc
package transform
@@ -11,6 +10,7 @@ import scala.tools.nsc.symtab.Flags
import scala.tools.nsc.util.FreshNameCreator
import scala.collection.{mutable, immutable}
+import immutable.Set
/** Specialize code on types.
*/
@@ -55,7 +55,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
/** Reduce the given environment to contain mappings only for type variables in tps. */
- def reduce(env: TypeEnv, tps: immutable.Set[Symbol]): TypeEnv = {
+ def restrict(env: TypeEnv, tps: immutable.Set[Symbol]): TypeEnv = {
env filter { kv => tps.contains(kv._1)}
}
@@ -314,11 +314,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
def specializedTypeVars(sym: Symbol): immutable.Set[Symbol] =
- specializedTypeVars(atPhase(currentRun.typerPhase)(sym.info))
+ atPhase(currentRun.typerPhase)(specializedTypeVars(sym.info))
/** Return the set of @specialized type variables mentioned by the given type.
- * It only counts type variables that appear naked or as arguments to Java
- * arrays (the only places where it makes sense to specialize).
+ * It only counts type variables that appear:
+ * - naked
+ * - as arguments to type constructors in @specialized positions
+ * (arrays ar considered as Array[@specialized T]
*/
def specializedTypeVars(tpe: Type): immutable.Set[Symbol] = tpe match {
case TypeRef(pre, sym, args) =>
@@ -327,7 +329,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
immutable.ListSet.empty + sym
else if (sym == definitions.ArrayClass)
specializedTypeVars(args)
- else immutable.ListSet.empty[Symbol]
+ else {
+ val extra = for ((tp, arg) <- sym.typeParams.zip(args) if tp.hasAnnotation(SpecializedClass))
+ yield specializedTypeVars(arg).toList
+ immutable.ListSet.empty[Symbol] ++ extra.flatten
+ }
case PolyType(tparams, resTpe) =>
specializedTypeVars(tparams map (_.info)) ++ specializedTypeVars(resTpe)
@@ -565,6 +571,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
normalizeMember(m.owner, m, outerEnv) flatMap { normalizedMember =>
val ms = specializeMember(m.owner, normalizedMember, outerEnv, clazz.info.typeParams)
// atPhase(currentRun.typerPhase)(println("normalizedMember.info: " + normalizedMember.info)) // bring the info to the typer phase
+ // interface traits have concrete members now
+ if (ms.nonEmpty && clazz.isTrait && clazz.isInterface)
+ clazz.resetFlag(INTERFACE)
+
if (normalizedMember.isMethod) {
val newTpe = subst(outerEnv, normalizedMember.info)
if (newTpe != normalizedMember.info) // only do it when necessary, otherwise the method type might be at a later phase already
@@ -599,7 +609,15 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private def normalizeMember(owner: Symbol, sym: Symbol, outerEnv: TypeEnv): List[Symbol] = {
if (settings.debug.value) log("normalizeMember: " + sym.fullName)
if (sym.isMethod && !atPhase(currentRun.typerPhase)(sym.typeParams.isEmpty)) {
- val (stps, tps) = splitParams(sym.info.typeParams)
+ var (stps, tps) = splitParams(sym.info.typeParams)
+ val unusedStvars = stps -- specializedTypeVars(sym.info).toList
+ if (unusedStvars.nonEmpty && currentRun.compiles(sym) && !sym.isSynthetic) {
+ reporter.warning(sym.pos, "%s %s unused or used in non-specializable positions."
+ .format(unusedStvars.mkString("", ", ", ""), if (unusedStvars.length == 1) "is" else "are"))
+ unusedStvars foreach (_.removeAnnotation(SpecializedClass))
+ stps = stps -- unusedStvars
+ tps = tps ::: unusedStvars
+ }
val res = sym :: (for (env <- specializations(stps) if needsSpecialization(env, sym)) yield {
val keys = env.keysIterator.toList;
val vals = env.valuesIterator.toList
@@ -636,7 +654,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
for (spec <- specializations(tparams)) yield {
if (sym.hasFlag(PRIVATE)) sym.resetFlag(PRIVATE).setFlag(PROTECTED)
val specMember = subst(outerEnv)(specializedOverload(owner, sym, spec))
- typeEnv(specMember) = outerEnv ++ spec
+ typeEnv(specMember) = typeEnv(sym) ++ outerEnv ++ spec
overloads(sym) = Overload(specMember, spec) :: overloads(sym)
specMember
}
@@ -674,54 +692,83 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
private def specialOverrides(clazz: Symbol): List[Symbol] = {
log("specialOverrides(" + clazz + ")")
+
+ /** Return the overridden symbol in syms that needs a specialized overriding symbol,
+ * together with its specialization environment. The overridden symbol may not be
+ * the closest to 'overriding', in a given hierarchy.
+ *
+ * An method m needs a special override if
+ * * m overrides a method whose type contains specialized type variables
+ * * there is a valid specialization environment that maps the overridden method type to m's type.
+ */
+ def needsSpecialOverride(overriding: Symbol, syms: List[Symbol]): (Symbol, TypeEnv) = {
+ def missingSpecializations(baseTvar: Symbol, derivedTvar: Symbol): Set[Type] = {
+ val baseSet = concreteTypes(baseTvar).toSet
+ val derivedSet = concreteTypes(derivedTvar).toSet
+ baseSet diff derivedSet
+ }
+
+ def checkOverriddenTParams(overridden: Symbol) {
+ if (currentRun.compiles(overriding))
+ for (val (baseTvar, derivedTvar) <- overridden.info.typeParams.zip(overriding.info.typeParams);
+ val missing = missingSpecializations(baseTvar, derivedTvar)
+ if missing.nonEmpty)
+ reporter.error(derivedTvar.pos,
+ "Type parameter has to be specialized at least for the same types as in the overridden method. Missing " +
+ "types: " + missing.mkString("", ", ", ""))
+ }
+
+ for (overridden <- syms) {
+ if (settings.debug.value)
+ log("Overridden: " + overridden.fullName + ": " + overridden.info
+ + "\n by " + overriding.fullName + ": " + overriding.info)
+ val stvars = specializedTypeVars(overridden.info)
+ if (!stvars.isEmpty) {
+ if (settings.debug.value) log("\t\tspecializedTVars: " + stvars)
+ checkOverriddenTParams(overridden)
+
+ val env = unify(overridden.info, overriding.info, emptyEnv)
+ if (settings.debug.value)
+ log("\t\tenv: " + env + "isValid: " + TypeEnv.isValid(env, overridden)
+ + "found: " + atPhase(phase.next)(overridden.owner.info.decl(specializedName(overridden, env))))
+ if (!TypeEnv.restrict(env, stvars).isEmpty
+ && TypeEnv.isValid(env, overridden)
+ && atPhase(phase.next)(overridden.owner.info.decl(specializedName(overridden, env))) != NoSymbol)
+ return (overridden, env)
+ }
+ }
+ (NoSymbol, emptyEnv)
+ }
+
val oms = new mutable.ListBuffer[Symbol]
for (overriding <- clazz.info.decls;
- val allOverridden = overriding.allOverriddenSymbols
- if !allOverridden.isEmpty;
- val overridden = allOverridden.head) {
- if (settings.debug.value)
- log("\toverriding pairs: " + overridden.fullName + ": " + overridden.info
- + " overriden by " + overriding.fullName + ": " + overriding.info)
- if (overriding.owner == clazz && !specializedTypeVars(overridden.info).isEmpty) {
- if (settings.debug.value) log("\t\tspecializedTVars: " + specializedTypeVars(overridden.info))
- val env = unify(overridden.info, overriding.info, emptyEnv)
- if (settings.debug.value)
- log("\t\tenv: " + env + "isValid: "
- + TypeEnv.isValid(env, overridden)
- + " looking for: " + specializedName(overridden, env) + " in:\n"
- + atPhase(phase.next)(overridden.owner.info.decls)
- + "found: " + atPhase(phase.next)(overridden.owner.info.decl(specializedName(overridden, env))))
- if (!env.isEmpty
- && TypeEnv.isValid(env, overridden)
- && atPhase(phase.next)(overridden.owner.info.decl(specializedName(overridden, env))) != NoSymbol) {
- log("Added specialized overload for " + overriding.fullName + " in env: " + env)
- val om = specializedOverload(clazz, overridden, env)
- typeEnv(om) = env
- concreteSpecMethods += overriding
- if (!overriding.isDeferred) {
- // if the override is a normalized member, 'om' gets the implementation from
- // its original target, and adds the environment of the normalized member (that is,
- // any specialized /method/ type parameter bindings)
- info(om) = info.get(overriding) match {
- case Some(NormalizedMember(target)) =>
- typeEnv(om) = env ++ typeEnv(overriding)
- SpecialOverride(target)
- case _ => SpecialOverride(overriding)
- }
- info(overriding) = Forward(om)
- om setPos overriding.pos // set the position of the concrete, overriding member
- } else {
- // abstract override
- if (settings.debug.value) log("abstract override " + overriding.fullName + " with specialized " + om.fullName)
- info(om) = Forward(overriding)
- }
- overloads(overriding) = Overload(om, env) :: overloads(overriding)
- oms += om
- atPhase(phase.next)(
- assert(overridden.owner.info.decl(om.name) != NoSymbol,
- "Could not find " + om.name + " in " + overridden.owner.info.decls))
+ val (overridden, env) = needsSpecialOverride(overriding, overriding.allOverriddenSymbols)
+ if overridden != NoSymbol) {
+ log("Added specialized overload for " + overriding.fullName + " in env: " + env)
+ val om = specializedOverload(clazz, overridden, env)
+ typeEnv(om) = env
+ concreteSpecMethods += overriding
+ if (!overriding.isDeferred) { // concrete method
+ // if the override is a normalized member, 'om' gets the implementation from
+ // its original target, and adds the environment of the normalized member (that is,
+ // any specialized /method/ type parameter bindings)
+ info(om) = info.get(overriding) match {
+ case Some(NormalizedMember(target)) =>
+ typeEnv(om) = env ++ typeEnv(overriding)
+ SpecialOverride(target)
+ case _ => SpecialOverride(overriding)
}
+ info(overriding) = Forward(om)
+ om setPos overriding.pos
+ } else { // abstract override
+ if (settings.debug.value) log("abstract override " + overriding.fullName + " with specialized " + om.fullName)
+ info(om) = Forward(overriding)
}
+ overloads(overriding) = Overload(om, env) :: overloads(overriding)
+ oms += om
+ atPhase(phase.next)(
+ assert(overridden.owner.info.decl(om.name) != NoSymbol,
+ "Could not find " + om.name + " in " + overridden.owner.info.decls))
}
oms.toList
}
@@ -824,7 +871,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
override def transformInfo(sym: Symbol, tpe: Type): Type = {
val res = tpe match {
- case PolyType(targs, ClassInfoType(base, decls, clazz)) =>
+ case PolyType(targs, ClassInfoType(base, decls, clazz)) if clazz != definitions.RepeatedParamClass && clazz != definitions.JavaRepeatedParamClass =>
val parents = base map specializedType
if (settings.debug.value) log("transformInfo (poly) " + clazz + " with parents1: " + parents + " ph: " + phase)
// if (clazz.name.toString == "$colon$colon")
@@ -905,6 +952,52 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val global: SpecializeTypes.this.global.type = SpecializeTypes.this.global
} with typechecker.Duplicators
+ /** A tree symbol substituter that substitutes on type skolems.
+ * If a type parameter is a skolem, it looks for the original
+ * symbol in the 'from' and maps it to the corresponding new
+ * symbol. The new symbol should probably be a type skolem as
+ * well (not enforced).
+ *
+ * All private members are made protected in order to be accessible from
+ * specialized classes.
+ */
+ class ImplementationAdapter(from: List[Symbol],
+ to: List[Symbol],
+ targetClass: Symbol,
+ addressFields: Boolean) extends TreeSymSubstituter(from, to) {
+ override val symSubst = new SubstSymMap(from, to) {
+ override def matches(sym1: Symbol, sym2: Symbol) =
+ if (sym2.isTypeSkolem) sym2.deSkolemize eq sym1
+ else sym1 eq sym2
+ }
+
+ private def isAccessible(sym: Symbol): Boolean =
+ (currentClass == sym.owner.enclClass) && (currentClass != targetClass)
+
+ private def shouldMakePublic(sym: Symbol): Boolean =
+ sym.hasFlag(PRIVATE | PROTECTED) && (addressFields || !nme.isLocalName(sym.name))
+
+ /** All private members that are referenced are made protected,
+ * in order to be accessible from specialized subclasses.
+ */
+ override def transform(tree: Tree): Tree = tree match {
+ case Select(qual, name) =>
+ val sym = tree.symbol
+ if (sym.hasFlag(PRIVATE))
+ if (settings.debug.value)
+ log("seeing private member %s, currentClass: %s, owner: %s, isAccessible: %b, isLocalName: %b"
+ .format(sym, currentClass, sym.owner.enclClass, isAccessible(sym), nme.isLocalName(sym.name)))
+ if (shouldMakePublic(sym) && !isAccessible(sym)) {
+ if (settings.debug.value) log("changing private flag of " + sym)
+ sym.makeNotPrivate(sym.owner)
+ }
+ super.transform(tree)
+
+ case _ =>
+ super.transform(tree)
+ }
+ }
+
def specializeCalls(unit: CompilationUnit) = new TypingTransformer(unit) {
/** Map a specializable method to it's rhs, when not deferred. */
val body: mutable.Map[Symbol, Tree] = new mutable.HashMap
@@ -938,20 +1031,22 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** The specialized symbol of 'tree.symbol' for tree.tpe, if there is one */
def specSym(qual: Tree): Option[Symbol] = {
val env = unify(symbol.tpe, tree.tpe, emptyEnv)
- log("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env)
+ log("[specSym] checking for rerouting: %s with \n\tsym.tpe: %s, \n\ttree.tpe: %s \n\tenv: %s \n\tname: %s"
+ .format(tree, symbol.tpe, tree.tpe, env, specializedName(symbol, env)))
if (!env.isEmpty) { // a method?
- val specMember = overload(symbol, env)
- if (specMember.isDefined) Some(specMember.get.sym)
- else { // a field?
- val specMember = qual.tpe.member(specializedName(symbol, env))
- if (specMember ne NoSymbol) Some(specMember)
- else None
- }
+ val specMember = qual.tpe.member(specializedName(symbol, env))
+ if (specMember ne NoSymbol)
+ if (typeEnv(specMember) == env) Some(specMember)
+ else {
+ log("wrong environments for specialized member: \n\ttypeEnv(%s) = %s\n\tenv = %s".format(specMember, typeEnv(specMember), env))
+ None
+ }
+ else None
} else None
}
def maybeTypeApply(fun: Tree, targs: List[Tree]) =
- if (targs.isEmpty)fun else TypeApply(fun, targs)
+ if (targs.isEmpty) fun else TypeApply(fun, targs)
curTree = tree
tree match {
@@ -971,13 +1066,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val qual1 = transform(qual)
specSym(qual1) match {
case Some(specMember) =>
- if (settings.debug.value) log("found " + specMember)
+ if (settings.debug.value) log("found " + specMember.fullName)
assert(symbol.info.typeParams.length == targs.length)
val env = typeEnv(specMember)
val residualTargs =
- for ((tvar, targ) <-symbol.info.typeParams.zip(targs) if !env.isDefinedAt(tvar))
+ for ((tvar, targ) <- symbol.info.typeParams.zip(targs) if !env.isDefinedAt(tvar))
yield targ
- assert(residualTargs.length == specMember.info.typeParams.length)
+ assert(residualTargs.length == specMember.info.typeParams.length,
+ "residual: %s, tparams: %s, env: %s".format(residualTargs, symbol.info.typeParams, env))
val tree1 = maybeTypeApply(Select(qual1, specMember), residualTargs)
log("rewrote " + tree + " to " + tree1)
localTyper.typedOperator(atPos(tree.pos)(tree1)) // being polymorphic, it must be a method
@@ -988,10 +1084,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case Select(qual, name) =>
if (settings.debug.value)
log("looking at Select: " + tree + " sym: " + symbol + ": " + symbol.info + "[tree.tpe: " + tree.tpe + "]")
- //if (settings.debug.value) log("\toverloads: " + overloads.mkString("", "\n", ""))
+
if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) {
- if (settings.debug.value)
- log("checking for unification at " + tree + " with sym.tpe: " + symbol.tpe + " and tree.tpe: " + tree.tpe + " at " + tree.pos.line)
val env = unify(symbol.tpe, tree.tpe, emptyEnv)
if (settings.debug.value) log("checking for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe + " env: " + env)
if (!env.isEmpty) {
@@ -1048,8 +1142,12 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val superRef: Tree = Select(Super(nme.EMPTY.toTypeName, nme.EMPTY.toTypeName), nme.CONSTRUCTOR)
forwardCall(tree.pos, superRef, vparamss)
}
- val tree1 = atPos(symbol.pos)(treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, Block(List(t), Literal(()))))
- localTyper.typed(tree1)
+ if (symbol.isPrimaryConstructor) localTyper typed {
+ atPos(symbol.pos)(treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, Block(List(t), Literal(()))))
+ } else {
+ // duplicate the original constructor
+ duplicateBody(ddef, info(symbol).target)
+ }
} else info(symbol) match {
case Implementation(target) =>
@@ -1177,7 +1275,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val symbol = tree.symbol
if (settings.debug.value) log("specializing body of" + symbol.fullName + ": " + symbol.info)
val DefDef(mods, name, tparams, vparamss, tpt, _) = tree
- val (_, origtparams) = splitParams(source.typeParams)
+// val (_, origtparams) = splitParams(source.typeParams)
+ val boundTvars = typeEnv(symbol).keySet
+ val origtparams = source.typeParams.filter(!boundTvars(_))
if (settings.debug.value) log("substituting " + origtparams + " for " + symbol.typeParams)
// skolemize type parameters
@@ -1192,54 +1292,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val symSubstituter = new ImplementationAdapter(
parameters(source).flatten ::: origtparams,
vparamss1.flatten.map(_.symbol) ::: newtparams,
- source.enclClass)
+ source.enclClass,
+ false) // don't make private fields public
val tmp = symSubstituter(body(source).duplicate)
tpt.tpe = tpt.tpe.substSym(oldtparams, newtparams)
treeCopy.DefDef(tree, mods, name, tparams, vparamss1, tpt, tmp)
}
- /** A tree symbol substituter that substitutes on type skolems.
- * If a type parameter is a skolem, it looks for the original
- * symbol in the 'from' and maps it to the corresponding new
- * symbol. The new symbol should probably be a type skolem as
- * well (not enforced).
- *
- * All private members are made protected in order to be accessible from
- * specialized classes.
- */
- class ImplementationAdapter(from: List[Symbol], to: List[Symbol], targetClass: Symbol) extends TreeSymSubstituter(from, to) {
- override val symSubst = new SubstSymMap(from, to) {
- override def matches(sym1: Symbol, sym2: Symbol) =
- if (sym2.isTypeSkolem) sym2.deSkolemize eq sym1
- else sym1 eq sym2
- }
-
- private def isAccessible(sym: Symbol): Boolean =
- (currentClass == sym.owner.enclClass) && (currentClass != targetClass)
-
- /** All private members that are referenced are made protected,
- * in order to be accessible from specialized subclasses.
- */
- override def transform(tree: Tree): Tree = tree match {
- case Select(qual, name) =>
- val sym = tree.symbol
- if (sym.hasFlag(PRIVATE))
- if (settings.debug.value) log("seeing private member " + sym + " targetClass: " + currentClass + " owner: " + sym.owner.enclClass)
- if (sym.hasFlag(PRIVATE | PROTECTED) && !nme.isLocalName(sym.name) && !isAccessible(sym)) {
- if (settings.debug.value) log("changing private flag of " + sym)
-// tree.symbol.resetFlag(PRIVATE).setFlag(PROTECTED)
- sym.makeNotPrivate(sym.owner)
-// tree.symbol.resetFlag(PRIVATE | PROTECTED)
-// tree.symbol.privateWithin = NoSymbol
- }
- super.transform(tree)
-
- case _ =>
- super.transform(tree)
- }
- }
-
def warn(clazz: Symbol)(pos: Position, err: String) =
if (!clazz.hasFlag(SPECIALIZED))
unit.warning(pos, err)
@@ -1263,19 +1323,21 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
if (info(m).target.isGetterOrSetter) hasSpecializedFields = true
if (m.isClassConstructor) {
val origParamss = parameters(info(m).target)
- assert(origParamss.length == 1) // we are after uncurry
val vparams =
for ((tp, sym) <- m.info.paramTypes zip origParamss(0))
yield m.newValue(sym.pos, specializedName(sym, typeEnv(cls)))
.setInfo(tp)
.setFlag(sym.flags)
+
// param accessors for private members (the others are inherited from the generic class)
- for (param <- vparams if cls.info.nonPrivateMember(param.name) == NoSymbol;
- val acc = param.cloneSymbol(cls).setFlag(PARAMACCESSOR | PRIVATE)) {
- cls.info.decls.enter(acc)
- mbrs += ValDef(acc, EmptyTree).setType(NoType).setPos(m.pos)
- }
+ if (m.isPrimaryConstructor)
+ for (param <- vparams if cls.info.nonPrivateMember(param.name) == NoSymbol;
+ val acc = param.cloneSymbol(cls).setFlag(PARAMACCESSOR | PRIVATE)) {
+ cls.info.decls.enter(acc)
+ mbrs += ValDef(acc, EmptyTree).setType(NoType).setPos(m.pos)
+ }
+
// ctor
mbrs += atPos(m.pos)(DefDef(m, Modifiers(m.flags), List(vparams) map (_ map ValDef), EmptyTree))
} else {
@@ -1291,11 +1353,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
}
if (hasSpecializedFields) {
+ import definitions.BooleanClass
+
+ val isSpecializedInstance = cls.hasFlag(SPECIALIZED) || cls.info.parents.exists(_.typeSymbol.hasFlag(SPECIALIZED))
val sym = cls.newMethod(nme.SPECIALIZED_INSTANCE, cls.pos)
- .setInfo(MethodType(Nil, definitions.BooleanClass.tpe))
+ .setInfo(MethodType(Nil, BooleanClass.tpe))
cls.info.decls.enter(sym)
mbrs += atPos(sym.pos) {
- DefDef(sym, Literal(cls.hasFlag(SPECIALIZED)).setType(sym.tpe.finalResultType)).setType(NoType)
+ DefDef(sym, Literal(isSpecializedInstance).setType(BooleanClass.tpe)).setType(NoType)
}
}
mbrs.toList
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 9fff8534d3..9b54dd9428 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Iulian Dragos
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/Transform.scala b/src/compiler/scala/tools/nsc/transform/Transform.scala
index 9fb6d5cdc1..2fc3eee59c 100644
--- a/src/compiler/scala/tools/nsc/transform/Transform.scala
+++ b/src/compiler/scala/tools/nsc/transform/Transform.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala b/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala
index 65f3caf642..8efbb356e8 100644
--- a/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala
+++ b/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package transform
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index bad98193b0..0270323133 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author
*/
-// $Id$
package scala.tools.nsc
package transform
@@ -404,8 +403,15 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
Select(predef, "wrap"+elemtp.typeSymbol.name+"Array")
else
TypeApply(Select(predef, "genericWrapArray"), List(TypeTree(elemtp)))
- val adaptedTree = // need to cast to Array[elemtp], as arrays are not covariant
- gen.mkCast(tree, arrayType(elemtp))
+ val pt = arrayType(elemtp)
+ val adaptedTree = // might need to cast to Array[elemtp], as arrays are not covariant
+ if (tree.tpe <:< pt) tree
+ else gen.mkCast(
+ if (elemtp.typeSymbol == AnyClass && isValueClass(tree.tpe.typeArgs.head.typeSymbol))
+ gen.mkRuntimeCall("toObjectArray", List(tree))
+ else
+ tree,
+ arrayType(elemtp))
Apply(meth, List(adaptedTree))
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
index 70bf55e661..63e5a9fb25 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
index f1e88fe6e8..ac1853cbe0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 82c4c01b79..7469388a08 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
@@ -317,7 +316,7 @@ trait Contexts { self: Analyzer =>
override def toString(): String = {
if (this == NoContext) "NoContext"
else owner.toString() + " @ " + tree.getClass() +
- " " + tree.toString() + ", scope = " + scope.hashCode() +
+ " " + tree.toString() + ", scope = " + scope.## +
" " + scope.toList + "\n:: " + outer.toString()
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala
index a2e9f10a5a..43ac9182c3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index 78f43296b4..dbc3ffbe17 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -189,6 +189,7 @@ abstract class Duplicators extends Analyzer {
if (tree.hasSymbol && tree.symbol != NoSymbol
&& !tree.symbol.isLabel // labels cannot be retyped by the type checker as LabelDef has no ValDef/return type trees
&& invalidSyms.isDefinedAt(tree.symbol)) {
+ if (settings.debug.value) log("removed symbol " + tree.symbol)
tree.symbol = NoSymbol
}
@@ -240,7 +241,9 @@ abstract class Duplicators extends Analyzer {
case Select(th @ This(_), sel) if (oldClassOwner ne null) && (th.symbol == oldClassOwner) =>
log("selection on this, no type ascription required")
- super.typed(atPos(tree.pos)(Select(This(newClassOwner), sel)), mode, pt)
+ // we use the symbol name instead of the tree name because the symbol may have been
+ // name mangled, rendering the tree name obsolete
+ super.typed(atPos(tree.pos)(Select(This(newClassOwner), tree.symbol.name)), mode, pt)
case This(_) if (oldClassOwner ne null) && (tree.symbol == oldClassOwner) =>
// val tree1 = Typed(This(newClassOwner), TypeTree(fixType(tree.tpe.widen)))
diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
index 5b79662014..7cfc4733d3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index e503d721f9..3abaf4f337 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
//todo: rewrite or disllow new T where T is a mixin (currently: <init> not a member of T)
//todo: use inherited type info also for vars and values
@@ -127,8 +126,7 @@ self: Analyzer =>
case _ => false
}
- override def hashCode =
- name.hashCode + pre.hashCode + sym.hashCode
+ override def hashCode = name.## + pre.## + sym.##
override def toString = "ImplicitInfo(" + name + "," + pre + "," + sym + ")"
}
@@ -573,6 +571,19 @@ self: Analyzer =>
/** A set containing names that are shadowed by implicit infos */
lazy val shadowed = new HashSet[Name]("shadowed", 512)
+ // #3453
+ // in addition to the implicit symbols that may shadow the implicit with name `name`,
+ // this method tests whether there's a non-implicit symbol with name `name` in scope
+ // inspired by logic in typedIdent
+ def nonImplicitSynonymInScope(name: Name) = {
+ val defEntry = context.scope.lookupEntry(name)
+ (defEntry ne null) &&
+ reallyExists(defEntry.sym) &&
+ !defEntry.sym.isImplicit // the implicit ones are handled by the `shadowed` set above
+ // also, subsumes the test that defEntry.sym ne info.sym
+ // (the `info` that's in scope at the call to nonImplicitSynonymInScope in tryImplicit)
+ }
+
/** Is `sym' the standard conforms method in Predef?
* Note: DON't replace this by sym == Predef_conforms, as Predef_conforms is a `def'
* which does a member lookup (it can't be a lazy val because we might reload Predef
@@ -594,7 +605,7 @@ self: Analyzer =>
def tryImplicit(info: ImplicitInfo): SearchResult = {
incCounter(triedImplicits)
if (info.isCyclicOrErroneous ||
- (isLocal && shadowed.contains(info.name)) ||
+ (isLocal && (shadowed.contains(info.name) || nonImplicitSynonymInScope(info.name))) ||
(isView && isConformsMethod(info.sym)) ||
//@M this condition prevents no-op conversions, which are a problem (besides efficiency),
// one example is removeNames in NamesDefaults, which relies on the type checker failing in case of ambiguity between an assignment/named arg
@@ -617,6 +628,11 @@ self: Analyzer =>
applicable
}
+ // #3453 -- alternative fix, seems not to be faster than encoding the set as the boolean predicate nonImplicitSynonymInScope
+ // in addition to the *implicit* symbols that may shadow the implicit with name `name` (added to shadowed by addAppInfos)
+ // add names of non-implicit symbols that are in scope (accessible without prefix)
+ // for(sym <- context.scope; if !sym.isImplicit) shadowed addEntry sym.name
+
var applicable = Map[ImplicitInfo, SearchResult]()
for (is <- iss) applicable = addAppInfos(is, applicable)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 1ee1604319..31bb86994e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 37f8a21bf8..d56b8ed944 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
@@ -298,7 +297,7 @@ trait Namers { self: Analyzer =>
private def enterSymFinishWith(tree: Tree, tparams: List[TypeDef]) {
val sym = tree.symbol
- if (settings.debug.value) log("entered " + sym + " in " + context.owner + ", scope-id = " + context.scope.hashCode());
+ if (settings.debug.value) log("entered " + sym + " in " + context.owner + ", scope-id = " + context.scope.## )
var ltype = namerOf(sym).typeCompleter(tree)
if (!tparams.isEmpty) {
//@M! TypeDef's type params are handled differently
@@ -876,6 +875,7 @@ trait Namers { self: Analyzer =>
if (vparam.tpt.isEmpty) vparam.symbol setInfo WildcardType
val overridden = overriddenSymbol
if (overridden != NoSymbol && !(overridden hasFlag OVERLOADED)) {
+ overridden.cookJavaRawInfo() // #3404 xform java rawtypes into existentials
resultPt = site.memberType(overridden) match {
case PolyType(tparams, rt) => rt.substSym(tparams, tparamSyms)
case mt => mt
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index ef2c3c3071..f1d0537f46 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 72f6f1ae39..4b5de16a31 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 8a7f4b0958..fabf2ed063 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 1e8b89cb6f..f33e3506fd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
@@ -88,7 +87,7 @@ trait SyntheticMethods extends ast.TreeDSL {
typer typed { DEF(method) === LIT(nargs) }
}
- /** Common code for productElement and productElementName
+ /** Common code for productElement and (currently disabled) productElementName
*/
def perElementMethod(accs: List[Symbol], methodName: Name, resType: Type, caseFn: Symbol => Tree): Tree = {
val symToTpe = makeTypeConstructor(List(IntClass.tpe), resType)
@@ -108,8 +107,8 @@ trait SyntheticMethods extends ast.TreeDSL {
def productElementMethod(accs: List[Symbol]): Tree =
perElementMethod(accs, nme.productElement, AnyClass.tpe, x => Ident(x))
- def productElementNameMethod(accs: List[Symbol]): Tree =
- perElementMethod(accs, nme.productElementName, StringClass.tpe, x => Literal(x.name.toString))
+ // def productElementNameMethod(accs: List[Symbol]): Tree =
+ // perElementMethod(accs, nme.productElementName, StringClass.tpe, x => Literal(x.name.toString))
def moduleToStringMethod: Tree = {
val method = syntheticMethod(nme.toString_, FINAL, makeNoArgConstructor(StringClass.tpe))
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index c2b6e7adf2..de9da9d814 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index f503a797bb..aad80c1d8c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
//todo: rewrite or disllow new T where T is a mixin (currently: <init> not a member of T)
//todo: use inherited type info also for vars and values
@@ -2619,6 +2618,7 @@ trait Typers { self: Analyzer =>
(nme.ERROR, None)
} else {
names -= sym
+ if(isJava) sym.cookJavaRawInfo() // #3429
val annArg = tree2ConstArg(rhs, sym.tpe.resultType)
(sym.name, annArg)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 6f432cc3c4..5bbda13acd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
@@ -100,13 +99,13 @@ trait Unapplies extends ast.TreeDSL
}
def copyUntyped[T <: Tree](tree: T): T =
- returning[T](UnTyper traverse _)(tree.duplicate)
+ returning[T](tree.duplicate)(UnTyper traverse _)
- def copyUntypedInvariant(td: TypeDef): TypeDef =
- returning[TypeDef](UnTyper traverse _)(
- treeCopy.TypeDef(td, td.mods &~ (COVARIANT | CONTRAVARIANT), td.name,
- td.tparams, td.rhs).duplicate
- )
+ def copyUntypedInvariant(td: TypeDef): TypeDef = {
+ val copy = treeCopy.TypeDef(td, td.mods &~ (COVARIANT | CONTRAVARIANT), td.name, td.tparams, td.rhs)
+
+ returning[TypeDef](copy.duplicate)(UnTyper traverse _)
+ }
private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = {
val tycon = REF(cdef.symbol)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Variances.scala b/src/compiler/scala/tools/nsc/typechecker/Variances.scala
index feaf57a541..7d0500d598 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Variances.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Variances.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package typechecker
diff --git a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala
index 39a104fb14..907622e31f 100644
--- a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala
+++ b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index c35b7139c6..4994542fdb 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
@@ -247,7 +246,7 @@ abstract class ClassPath[T] {
/** Filters for assessing validity of various entities.
*/
def validClassFile(name: String) = (name endsWith ".class") && context.isValidName(name)
- def validPackage(name: String) = (name != "META-INF") && (name != "") && (name.head != '.')
+ def validPackage(name: String) = (name != "META-INF") && (name != "") && (name(0) != '.')
def validSourceFile(name: String) = validSourceExtensions exists (name endsWith _)
def validSourceExtensions = List(".scala", ".java")
@@ -321,8 +320,7 @@ class DirectoryClassPath(val dir: AbstractFile, val context: ClassPathContext[Ab
case f if f.isDirectory && validPackage(f.name) => new DirectoryClassPath(f, context)
} toList
-
- override def toString() = "directory classpath: "+ dir.toString()
+ override def toString() = "directory classpath: "+ dir
}
/**
diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala
index 7ca2722a54..06045daf3b 100755
--- a/src/compiler/scala/tools/nsc/util/DocStrings.scala
+++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id: ClassPath.scala 20028 2009-12-07 11:49:19Z cunei $
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala b/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala
index 0c9fa6db72..714e731891 100644
--- a/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala
+++ b/src/compiler/scala/tools/nsc/util/FreshNameCreator.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/HashSet.scala b/src/compiler/scala/tools/nsc/util/HashSet.scala
index dc9ec73040..aa6e19538c 100644
--- a/src/compiler/scala/tools/nsc/util/HashSet.scala
+++ b/src/compiler/scala/tools/nsc/util/HashSet.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
@@ -27,7 +26,7 @@ class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) exte
private def index(x: Int): Int = math.abs(x % capacity)
def findEntryOrUpdate(x: T): T = {
- var h = index(x.hashCode())
+ var h = index(x.##)
var entry = table(h)
while (entry ne null) {
if (x == entry)
@@ -43,7 +42,7 @@ class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) exte
}
def findEntry(x: T): T = {
- var h = index(x.hashCode())
+ var h = index(x.##)
var entry = table(h)
while ((entry ne null) && entry != x) {
h = index(h + 1)
@@ -53,7 +52,7 @@ class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) exte
}
def addEntry(x: T) {
- var h = index(x.hashCode())
+ var h = index(x.##)
var entry = table(h)
while (entry ne null) {
if (entry == x) return
@@ -77,7 +76,7 @@ class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) exte
}
private def addOldEntry(x: T) {
- var h = index(x.hashCode())
+ var h = index(x.##)
var entry = table(h)
while (entry ne null) {
h = index(h + 1)
diff --git a/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala b/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala
index ddefcc04ee..fa377a294d 100644
--- a/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala
+++ b/src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index 806c885291..8d0ff37c44 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*
*/
-// $Id$
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/RegexCache.scala b/src/compiler/scala/tools/nsc/util/RegexCache.scala
index 5227b8ea4d..5c3197afa5 100644
--- a/src/compiler/scala/tools/nsc/util/RegexCache.scala
+++ b/src/compiler/scala/tools/nsc/util/RegexCache.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Lex Spoon
*/
-// $Id$
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/Set.scala b/src/compiler/scala/tools/nsc/util/Set.scala
index 8896ee02a5..c8ba3d27c9 100644
--- a/src/compiler/scala/tools/nsc/util/Set.scala
+++ b/src/compiler/scala/tools/nsc/util/Set.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala
index b87d603570..82911892d9 100644
--- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala
+++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools
package nsc
diff --git a/src/compiler/scala/tools/nsc/util/SourceFile.scala b/src/compiler/scala/tools/nsc/util/SourceFile.scala
index f9f3c5e5fe..8c1d308209 100644
--- a/src/compiler/scala/tools/nsc/util/SourceFile.scala
+++ b/src/compiler/scala/tools/nsc/util/SourceFile.scala
@@ -3,14 +3,15 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
-import scala.tools.nsc.io.{AbstractFile, VirtualFile}
+import io.{ AbstractFile, VirtualFile }
import scala.collection.mutable.ArrayBuffer
-import annotation.{ tailrec, switch }
+import annotation.tailrec
+import java.util.regex.Pattern
+import java.io.IOException
import Chars._
/** abstract base class of a source file used in the compiler */
@@ -18,6 +19,7 @@ abstract class SourceFile {
def content : Array[Char] // normalized, must end in SU
def file : AbstractFile
def isLineBreak(idx : Int) : Boolean
+ def isSelfContained: Boolean
def length : Int
def position(offset: Int) : Position = {
assert(offset < length)
@@ -47,6 +49,42 @@ abstract class SourceFile {
def identifier(pos: Position, compiler: Global): Option[String] = None
}
+object ScriptSourceFile {
+ /** Length of the script header from the given content, if there is one.
+ * The header begins with "#!" or "::#!" and ends with a line starting
+ * with "!#" or "::!#".
+ */
+ def headerLength(cs: Array[Char]): Int = {
+ val headerPattern = Pattern.compile("""^(::)?!#.*(\r|\n|\r\n)""", Pattern.MULTILINE)
+ val headerStarts = List("#!", "::#!")
+
+ if (headerStarts exists (cs startsWith _)) {
+ val matcher = headerPattern matcher cs.mkString
+ if (matcher.find) matcher.end
+ else throw new IOException("script file does not close its header with !# or ::!#")
+ }
+ else 0
+ }
+ def stripHeader(cs: Array[Char]): Array[Char] = cs drop headerLength(cs)
+
+ def apply(file: AbstractFile, content: Array[Char]) = {
+ val underlying = new BatchSourceFile(file, content)
+ val headerLen = headerLength(content)
+ val stripped = new ScriptSourceFile(underlying, content drop headerLen, headerLen)
+
+ stripped
+ }
+}
+import ScriptSourceFile._
+
+class ScriptSourceFile(underlying: BatchSourceFile, content: Array[Char], override val start: Int) extends BatchSourceFile(underlying.file, content) {
+ override def isSelfContained = false
+
+ override def positionInUltimateSource(pos: Position) =
+ if (!pos.isDefined) super.positionInUltimateSource(pos)
+ else new OffsetPosition(underlying, pos.point + start)
+}
+
/** a file whose contents do not change over time */
class BatchSourceFile(val file : AbstractFile, val content: Array[Char]) extends SourceFile {
@@ -55,16 +93,13 @@ class BatchSourceFile(val file : AbstractFile, val content: Array[Char]) extends
def this(file: AbstractFile, cs: Seq[Char]) = this(file, cs.toArray)
override def equals(that : Any) = that match {
- case that : BatchSourceFile => file.path == that.file.path
+ case that : BatchSourceFile => file.path == that.file.path && start == that.start
case _ => false
}
- override def hashCode = file.path.hashCode
+ override def hashCode = file.path.## + start.##
val length = content.length
-
- // in SourceFileFragments, these are overridden to compensate during offset calculation
- // Invariant: length + start = underlyingLength
- def underlyingLength = length
def start = 0
+ def isSelfContained = true
override def identifier(pos: Position, compiler: Global) =
if (pos.isDefined && pos.source == this && pos.point != -1) {
@@ -82,13 +117,14 @@ class BatchSourceFile(val file : AbstractFile, val content: Array[Char]) extends
else isLineBreakChar(ch)
}
- private lazy val lineIndices: Array[Int] = {
+ def calculateLineIndices(cs: Array[Char]) = {
val buf = new ArrayBuffer[Int]
buf += 0
- for (i <- 0 until content.length) if (isLineBreak(i)) buf += i + 1
- buf += content.length // sentinel, so that findLine below works smoother
+ for (i <- 0 until cs.length) if (isLineBreak(i)) buf += i + 1
+ buf += cs.length // sentinel, so that findLine below works smoother
buf.toArray
}
+ private lazy val lineIndices: Array[Int] = calculateLineIndices(content)
def lineToOffset(index : Int): Int = lineIndices(index)
@@ -106,125 +142,4 @@ class BatchSourceFile(val file : AbstractFile, val content: Array[Char]) extends
lastLine = findLine(0, lines.length, lastLine)
lastLine
}
-
-/**
-
- // An array which maps line numbers (counting from 0) to char offset into content
- private lazy val lineIndices: Array[Int] = {
-
- val xs = content.indices filter isLineBreak map (_ + 1) toArray
- val arr = new Array[Int](xs.length + 1)
- arr(0) = 0
- System.arraycopy(xs, 0, arr, 1, xs.length)
-
- arr
- }
- // A reverse map which also hunts down the right answer on non-exact lookups
- private class SparseReverser() {
- val revMap = Map(lineIndices.zipWithIndex: _*)
-
- def apply(x: Int): Int = revMap.get(x) match {
- case Some(res) => res
- case _ =>
- var candidate = x - 1
- while (!revMap.contains(candidate))
- candidate -= 1
-
- revMap(candidate)
- }
- }
- private lazy val lineIndicesRev = new SparseReverser()
-
- def lineToOffset(index : Int): Int = lineIndices(index)
- def offsetToLine(offset: Int): Int = lineIndicesRev(offset)
-
- */
-}
-
-/** A source file composed of multiple other source files.
- *
- * @version 1.0
- */
-class CompoundSourceFile(
- name: String,
- components: List[BatchSourceFile],
- contents: Array[Char])
-extends BatchSourceFile(name, contents)
-{
- /** The usual constructor. Specify a name for the compound file and
- * a list of component sources.
- */
- def this(name: String, components: BatchSourceFile*) =
- this(name, components.toList, components flatMap (CompoundSourceFile stripSU _.content) toArray)
-
- /** Create an instance with the specified components and a generic name. */
- def this(components: BatchSourceFile*) = this("(virtual file)", components: _*)
-
- override def positionInUltimateSource(position: Position) = {
- if (!position.isDefined) super.positionInUltimateSource(position)
- else {
- var off = position.point
- var compsLeft = components
- // the search here has to be against the length of the files underlying the
- // components, not their advertised length (which in the case of a fragment is
- // less than the underlying length.) Otherwise we can and will overshoot the
- // correct component and return a garbage position.
- while (compsLeft.head.underlyingLength-1 <= off && !compsLeft.tail.isEmpty) {
- off = off - compsLeft.head.underlyingLength + 1
- compsLeft = compsLeft.tail
- }
- // now that we've identified the correct component, we have to adjust the
- // position we report since it is expected relative to the fragment, not the
- // underlying file. Thus, off - comp.start.
- val comp = compsLeft.head
- comp.positionInUltimateSource(new OffsetPosition(this, off - comp.start))
- }
- }
-}
-
-object CompoundSourceFile {
- private[util] def stripSU(chars: Array[Char]) =
- if (chars.length > 0 && chars.last == SU)
- chars dropRight 1
- else
- chars
-}
-
-
-/** One portion of an underlying file. The fragment includes
- * the indices from the specified start (inclusively) to stop
- * (not inclusively).
- */
-class SourceFileFragment private (
- name: String,
- underlyingFile: BatchSourceFile,
- override val start: Int,
- stop: Int,
- contents: Array[Char])
-extends BatchSourceFile(name, contents) {
- override def underlyingLength = underlyingFile.length
- def this(name: String, underlyingFile: BatchSourceFile, start: Int, stop: Int) =
- this(
- name,
- underlyingFile,
- start,
- stop,
- { assert(start >= 0)
- assert(start <= stop)
- assert(start <= underlyingFile.length)
- assert(stop <= underlyingFile.length)
- underlyingFile.content.slice(start, stop).toArray })
-
- def this(underlyingFile: BatchSourceFile, start: Int, stop: Int) =
- this(
- "(fragment of " + underlyingFile.file.name + ")",
- underlyingFile,
- start,
- stop)
-
- override def positionInUltimateSource(position: Position) =
- super.positionInUltimateSource(
- if (position.isDefined) new OffsetPosition(this, position.point)
- else position
- )
}
diff --git a/src/compiler/scala/tools/nsc/util/Statistics.scala b/src/compiler/scala/tools/nsc/util/Statistics.scala
index 5aee76d946..de51c2778c 100644
--- a/src/compiler/scala/tools/nsc/util/Statistics.scala
+++ b/src/compiler/scala/tools/nsc/util/Statistics.scala
@@ -3,7 +3,6 @@
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/TreeSet.scala b/src/compiler/scala/tools/nsc/util/TreeSet.scala
index 86e44df684..522c99c4e0 100644
--- a/src/compiler/scala/tools/nsc/util/TreeSet.scala
+++ b/src/compiler/scala/tools/nsc/util/TreeSet.scala
@@ -2,7 +2,6 @@
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
package scala.tools.nsc
package util
diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala
new file mode 100644
index 0000000000..92d4eab54f
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/util/package.scala
@@ -0,0 +1,29 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2010 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+
+import java.io.{ OutputStream, PrintStream, ByteArrayOutputStream, PrintWriter, StringWriter }
+
+package object util {
+ /** Apply a function and return the passed value */
+ def returning[T](x: T)(f: T => Unit): T = { f(x) ; x }
+
+ /** Generate a string using a routine that wants to write on a stream. */
+ def stringFromWriter(writer: PrintWriter => Unit): String = {
+ val stringWriter = new StringWriter()
+ val stream = new NewLinePrintWriter(stringWriter)
+ writer(stream)
+ stream.close()
+ stringWriter.toString
+ }
+ def stringFromStream(stream: OutputStream => Unit): String = {
+ val bs = new ByteArrayOutputStream()
+ val ps = new PrintStream(bs)
+ stream(ps)
+ ps.close()
+ bs.toString()
+ }
+}
diff --git a/src/compiler/scala/tools/util/AbstractTimer.scala b/src/compiler/scala/tools/util/AbstractTimer.scala
index f91c964d26..b0ea663c47 100644
--- a/src/compiler/scala/tools/util/AbstractTimer.scala
+++ b/src/compiler/scala/tools/util/AbstractTimer.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.util
diff --git a/src/compiler/scala/tools/util/SocketConnection.scala b/src/compiler/scala/tools/util/SocketConnection.scala
index 085d754300..040f2b2392 100644
--- a/src/compiler/scala/tools/util/SocketConnection.scala
+++ b/src/compiler/scala/tools/util/SocketConnection.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.util
diff --git a/src/compiler/scala/tools/util/SocketServer.scala b/src/compiler/scala/tools/util/SocketServer.scala
index 7dcfd7efce..88d7013f36 100644
--- a/src/compiler/scala/tools/util/SocketServer.scala
+++ b/src/compiler/scala/tools/util/SocketServer.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools.util
diff --git a/src/compiler/scala/tools/util/StringOps.scala b/src/compiler/scala/tools/util/StringOps.scala
index 6e5b3e54d3..1a42c32fc8 100644
--- a/src/compiler/scala/tools/util/StringOps.scala
+++ b/src/compiler/scala/tools/util/StringOps.scala
@@ -6,7 +6,6 @@
** |/ **
\* */
-// $Id$
package scala.tools
package util