diff options
157 files changed, 5821 insertions, 852 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 904e9477a2..08d972eee1 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -219,6 +219,54 @@ filter { { matchName="scala.concurrent.forkjoin.ForkJoinPool.helpJoinOnce" problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.getClassMethods" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.primitiveGetClassMethods" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments.unsuppressMacroExpansion" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments.suppressMacroExpansion" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments.isMacroExpansionSuppressed" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.JavaUniverse.isInvalidClassName" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.isInvalidClassName" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.uncheckedBounds" + problemName=MissingMethodProblem + } + { + matchName="scala.reflect.internal.Trees.scala$reflect$internal$Trees$$duplicator" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees.duplicateAndKeepPositions" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees.scala$reflect$internal$Trees$$duplicator" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.scala$reflect$internal$Trees$$duplicator" + problemName=IncompatibleResultTypeProblem } ] } diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index fd6451d3bc..7fdd4329ea 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -467,6 +467,110 @@ filter { { matchName="scala.concurrent.forkjoin.ForkJoinPool.helpJoinOnce" problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.concurrent.impl.Promise$CompletionLatch" + problemName=MissingClassProblem + }, + { + matchName="scala.concurrent.impl.Promise#DefaultPromise.linkRootOf" + problemName=MissingMethodProblem + }, + { + matchName="scala.concurrent.impl.Promise#DefaultPromise.scala$concurrent$impl$Promise$DefaultPromise$$dispatchOrAddCallback" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.getClassMethods" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.primitiveGetClassMethods" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments.unsuppressMacroExpansion" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments.suppressMacroExpansion" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.StdAttachments.isMacroExpansionSuppressed" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.unsuppressMacroExpansion" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.suppressMacroExpansion" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.isMacroExpansionSuppressed" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.JavaMirrors#JavaMirror#FromJavaClassCompleter.scala$reflect$runtime$JavaMirrors$JavaMirror$FromJavaClassCompleter$$enterEmptyCtorIfNecessary$1" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.ReflectionUtils.scalacShouldntLoadClass" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.ReflectionUtils.scalacShouldntLoadClassfile" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.ReflectionUtils.isTraitImplementation" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.runtime.SymbolLoaders.isInvalidClassName" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.uncheckedBounds" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Types.uncheckedBounds" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.UncheckedBoundsClass" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.annotations.uncheckedBounds" + problemName=MissingClassProblem + } + { + matchName="scala.reflect.internal.Trees$Duplicator" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.Trees.duplicateAndKeepPositions" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees.scala$reflect$internal$Trees$$duplicator" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Trees.scala$reflect$internal$Trees$$duplicator" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.duplicateAndKeepPositions" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.SymbolTable.scala$reflect$internal$Trees$$duplicator" + problemName=IncompatibleResultTypeProblem } ] } diff --git a/build.number b/build.number index 0b06d13468..d5dd553362 100644 --- a/build.number +++ b/build.number @@ -1,7 +1,7 @@ #Tue Sep 11 19:21:09 CEST 2007 version.major=2 version.minor=10 -version.patch=2 +version.patch=3 # This is the -N part of a version. if it's 0, it's dropped from maven versions. version.bnum=0 @@ -137,6 +137,7 @@ TODO: <property name="build-quick.dir" value="${build.dir}/quick"/> <property name="build-pack.dir" value="${build.dir}/pack"/> <property name="build-osgi.dir" value="${build.dir}/osgi"/> + <property name="build-junit.dir" value="${build.dir}/junit"/> <property name="build-strap.dir" value="${build.dir}/strap"/> <property name="build-docs.dir" value="${build.dir}/scaladoc"/> <property name="build-sbt.dir" value="${build.dir}/sbt-interface"/> @@ -144,6 +145,9 @@ TODO: <property name="test.osgi.src" value="${partest.dir}/osgi/src"/> <property name="test.osgi.classes" value="${build-osgi.dir}/classes"/> + <property name="test.junit.src" value="${partest.dir}/junit"/> + <property name="test.junit.classes" value="${build-junit.dir}/classes"/> + <property name="dists.dir" value="${basedir}/dists"/> <property name="copyright.string" value="Copyright 2002-2013, LAMP/EPFL"/> @@ -208,6 +212,12 @@ TODO: <dependency groupId="biz.aQute" artifactId="bnd" version="1.50.0"/> </artifact:dependencies> + <!-- JUnit --> + <property name="junit.version" value="4.10"/> + <artifact:dependencies pathId="junit.classpath" filesetId="junit.fileset"> + <dependency groupId="junit" artifactId="junit" version="${junit.version}"/> + </artifact:dependencies> + <!-- Pax runner --> <property name="pax.exam.version" value="2.5.0"/> <artifact:dependencies pathId="pax.exam.classpath" filesetId="pax.exam.fileset"> @@ -218,10 +228,11 @@ TODO: <dependency groupId="org.ops4j.pax.swissbox" artifactId="pax-swissbox-framework" version="1.5.1"/> <dependency groupId="ch.qos.logback" artifactId="logback-core" version="0.9.20"/> <dependency groupId="ch.qos.logback" artifactId="logback-classic" version="0.9.20"/> - <dependency groupId="junit" artifactId="junit" version="4.10"/> + <dependency groupId="junit" artifactId="junit" version="${junit.version}"/> <dependency groupId="org.apache.felix" artifactId="org.apache.felix.framework" version="3.2.2"/> </artifact:dependencies> + <artifact:dependencies pathId="partest.extras.classpath" filesetId="partest.extras.fileset" versionsId="partest.extras.versions"> <dependency groupId="com.googlecode.java-diff-utils" artifactId="diffutils" version="1.3.0"/> </artifact:dependencies> @@ -680,6 +691,12 @@ TODO: <pathelement location="${pack.dir}/lib/scala-swing.jar"/> <!-- TODO - segregate swing tests (there can't be many) --> </path> + <path id="test.junit.compiler.build.path"> + <pathelement location="${test.junit.classes}"/> + <path refid="quick.compiler.build.path"/> + <path refid="junit.classpath"/> + </path> + <path id="test.osgi.compiler.build.path"> <pathelement location="${test.osgi.classes}"/> <pathelement location="${build-osgi.dir}/org.scala-lang.scala-library.jar"/> @@ -1445,6 +1462,45 @@ TODO: <stopwatch name="quick.sbt-interface.timer" action="total"/> </target> + <target name="test.junit.init" depends="quick.done"> + <uptodate property="test.junit.available" targetfile="${build-junit.dir}/test-compile.complete"> + <srcfiles dir="${test.junit.src}"> + <include name="**/*.scala"/> + </srcfiles> + </uptodate> + </target> + + <target name="test.junit.comp" depends="test.junit.init, quick.done" unless="test.junit.available"> + <stopwatch name="test.junit.compiler.timer"/> + <mkdir dir="${test.junit.classes}"/> + <scalacfork + destdir="${test.junit.classes}" + compilerpathref="quick.compiler.path" + params="${scalac.args.quick}" + srcdir="${test.junit.src}" + jvmargs="${scalacfork.jvmargs}"> + <include name="**/*.scala"/> + <compilationpath refid="test.junit.compiler.build.path"/> + </scalacfork> + <touch file="${build-junit.dir}/test-compile.complete" verbose="no"/> + <stopwatch name="test.junit.compiler.timer" action="total"/> + </target> + + <target name="test.junit" depends="test.junit.comp"> + <stopwatch name="test.junit.timer"/> + <mkdir dir="${test.junit.classes}"/> + <junit fork="yes" haltonfailure="yes" showoutput="yes" printsummary="on"> + <classpath refid="test.junit.compiler.build.path"/> + <batchtest fork="yes" todir="${build-junit.dir}"> + <fileset dir="${test.junit.classes}"> + <include name="**/*Test.class"/> + </fileset> + </batchtest> + <formatter type="plain"/> + </junit> + <stopwatch name="test.junit.timer" action="total"/> + </target> + <property name="partest.srcdir" value="files" /> <!-- TODO: make targets for `pending` and other subdirs --> <target name="test.run" depends="pack.done"> @@ -1516,7 +1572,7 @@ TODO: <!-- for use in PR validation, where stability is rarely broken, so we're going to use starr for locker, and skip test.stability (which requires locker == quick) --> - <target name="test.core" depends="test.osgi, test.sbt, test.bc, test.interactive, test.continuations.suite, test.scaladoc, test.suite"/> + <target name="test.core" depends="test.osgi, test.sbt, test.bc, test.junit, test.interactive, test.continuations.suite, test.scaladoc, test.suite"/> <target name="test.done" depends="test.core, test.stability"/> diff --git a/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala b/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala index ee8776f397..bfd4e7ac40 100644 --- a/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala +++ b/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala @@ -42,10 +42,7 @@ private[actors] object ThreadPoolConfig { (propIsSetTo("actors.enableForkJoin", "true") || { Debug.info(this+": java.version = "+javaVersion) Debug.info(this+": java.vm.vendor = "+javaVmVendor) - - // on IBM J9 1.6 do not use ForkJoinPool - // XXX this all needs to go into Properties. - isJavaAtLeast("1.6") && ((javaVmVendor contains "Oracle") || (javaVmVendor contains "Sun") || (javaVmVendor contains "Apple")) + isJavaAtLeast("1.6") }) catch { case _: SecurityException => false diff --git a/src/build/maven/maven-deploy.xml b/src/build/maven/maven-deploy.xml index bd946bf0f3..e70173319e 100644 --- a/src/build/maven/maven-deploy.xml +++ b/src/build/maven/maven-deploy.xml @@ -164,11 +164,7 @@ <attribute name="repository" /> <attribute name="version" /> <sequential> - <deploy-remote name="scala-library" version="@{version}" repository="@{repository}"> - <extra-attachments> - <artifact:attach type="jar" file="scala-library/scala-library-docs.jar" classifier="javadoc" /> - </extra-attachments> - </deploy-remote> + <deploy-remote name="scala-library" version="@{version}" repository="@{repository}"/> <deploy-remote name="jline" version="@{version}" repository="@{repository}"/> <deploy-remote name="scala-reflect" version="@{version}" repository="@{repository}"/> <deploy-remote name="scala-compiler" version="@{version}" repository="@{repository}" /> diff --git a/src/compiler/scala/reflect/macros/runtime/Typers.scala b/src/compiler/scala/reflect/macros/runtime/Typers.scala index 4d333f180b..a51bee0fe8 100644 --- a/src/compiler/scala/reflect/macros/runtime/Typers.scala +++ b/src/compiler/scala/reflect/macros/runtime/Typers.scala @@ -22,7 +22,7 @@ trait Typers { // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time // I'd advise fixing the root cause: finding why the context is not set to report errors // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) - wrapper(callsiteTyper.silent(_.typed(tree, universe.analyzer.EXPRmode, pt)) match { + wrapper(callsiteTyper.silent(_.typed(tree, universe.analyzer.EXPRmode, pt), reportAmbiguousErrors = false) match { case universe.analyzer.SilentResultValue(result) => macroLogVerbose(result) result diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 55f8684df2..6777bb0a50 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -45,18 +45,21 @@ package object reify { def reifyType(global: Global)(typer: global.analyzer.Typer,universe: global.Tree, mirror: global.Tree, tpe: global.Type, concrete: Boolean = false): global.Tree = mkReifier(global)(typer, universe, mirror, tpe, concrete = concrete).reification.asInstanceOf[global.Tree] - def reifyRuntimeClass(global: Global)(typer0: global.analyzer.Typer, tpe: global.Type, concrete: Boolean = true): global.Tree = { + def reifyRuntimeClass(global: Global)(typer0: global.analyzer.Typer, tpe0: global.Type, concrete: Boolean = true): global.Tree = { import global._ import definitions._ import analyzer.enclosingMacroPosition + // SI-7375 + val tpe = tpe0.dealiasWiden + if (tpe.isSpliceable) { val classTagInScope = typer0.resolveClassTag(enclosingMacroPosition, tpe, allowMaterialization = false) if (!classTagInScope.isEmpty) return Select(classTagInScope, nme.runtimeClass) if (concrete) throw new ReificationException(enclosingMacroPosition, "tpe %s is an unresolved spliceable type".format(tpe)) } - tpe.normalize match { + tpe match { case TypeRef(_, ArrayClass, componentTpe :: Nil) => val componentErasure = reifyRuntimeClass(global)(typer0, componentTpe, concrete) gen.mkMethodCall(arrayClassMethod, List(componentErasure)) diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index a320718084..535a933c73 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -91,20 +91,20 @@ trait Reshape { private def undoMacroExpansion(tree: Tree): Tree = tree.attachments.get[MacroExpansionAttachment] match { case Some(MacroExpansionAttachment(original)) => + def mkImplicitly(tp: Type) = atPos(tree.pos)( + gen.mkNullaryCall(Predef_implicitly, List(tp)) + ) + val sym = original.symbol original match { // this hack is necessary until I fix implicit macros // so far tag materialization is implemented by sneaky macros hidden in scala-compiler.jar // hence we cannot reify references to them, because noone will be able to see them later // when implicit macros are fixed, these sneaky macros will move to corresponding companion objects // of, say, ClassTag or TypeTag - case Apply(TypeApply(_, List(tt)), _) if original.symbol == materializeClassTag => - gen.mkNullaryCall(Predef_implicitly, List(appliedType(ClassTagClass, tt.tpe))) - case Apply(TypeApply(_, List(tt)), List(pre)) if original.symbol == materializeWeakTypeTag => - gen.mkNullaryCall(Predef_implicitly, List(typeRef(pre.tpe, WeakTypeTagClass, List(tt.tpe)))) - case Apply(TypeApply(_, List(tt)), List(pre)) if original.symbol == materializeTypeTag => - gen.mkNullaryCall(Predef_implicitly, List(typeRef(pre.tpe, TypeTagClass, List(tt.tpe)))) - case _ => - original + case Apply(TypeApply(_, List(tt)), _) if sym == materializeClassTag => mkImplicitly(appliedType(ClassTagClass, tt.tpe)) + case Apply(TypeApply(_, List(tt)), List(pre)) if sym == materializeWeakTypeTag => mkImplicitly(typeRef(pre.tpe, WeakTypeTagClass, List(tt.tpe))) + case Apply(TypeApply(_, List(tt)), List(pre)) if sym == materializeTypeTag => mkImplicitly(typeRef(pre.tpe, TypeTagClass, List(tt.tpe))) + case _ => original } case _ => tree } diff --git a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl index bd6cf561b9..1288eb0b7c 100644 --- a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl @@ -22,13 +22,74 @@ if "%~1"=="-toolcp" ( goto another_param ) -set _LINE_PARAMS=%1 +rem We keep in _JAVA_PARAMS all -J-prefixed and -D-prefixed arguments +set _JAVA_PARAMS= + +if [%1]==[] goto param_afterloop +set _TEST_PARAM=%~1 +if not "%_TEST_PARAM:~0,1%"=="-" goto param_afterloop + +rem ignore -e "scala code" +if "%_TEST_PARAM:~0,2%"=="-e" ( + shift + shift + if [%1]==[] goto param_afterloop +) + +set _TEST_PARAM=%~1 +if "%_TEST_PARAM:~0,2%"=="-J" ( + set _JAVA_PARAMS=%_TEST_PARAM:~2% +) + +if "%_TEST_PARAM:~0,2%"=="-D" ( + rem test if this was double-quoted property "-Dprop=42" + for /F "delims== tokens=1-2" %%G in ("%_TEST_PARAM%") DO ( + if not "%%G" == "%_TEST_PARAM%" ( + rem double quoted: "-Dprop=42" -> -Dprop="42" + set _JAVA_PARAMS=%%G="%%H" + ) else if [%2] neq [] ( + rem it was a normal property: -Dprop=42 or -Drop="42" + set _JAVA_PARAMS=%_TEST_PARAM%=%2 + shift + ) + ) +) + :param_loop shift + if [%1]==[] goto param_afterloop -set _LINE_PARAMS=%_LINE_PARAMS% %1 +set _TEST_PARAM=%~1 +if not "%_TEST_PARAM:~0,1%"=="-" goto param_afterloop + +rem ignore -e "scala code" +if "%_TEST_PARAM:~0,2%"=="-e" ( + shift + shift + if [%1]==[] goto param_afterloop +) + +set _TEST_PARAM=%~1 +if "%_TEST_PARAM:~0,2%"=="-J" ( + set _JAVA_PARAMS=%_JAVA_PARAMS% %_TEST_PARAM:~2% +) + +if "%_TEST_PARAM:~0,2%"=="-D" ( + rem test if this was double-quoted property "-Dprop=42" + for /F "delims== tokens=1-2" %%G in ("%_TEST_PARAM%") DO ( + if not "%%G" == "%_TEST_PARAM%" ( + rem double quoted: "-Dprop=42" -> -Dprop="42" + set _JAVA_PARAMS=%_JAVA_PARAMS% %%G="%%H" + ) else if [%2] neq [] ( + rem it was a normal property: -Dprop=42 or -Drop="42" + set _JAVA_PARAMS=%_JAVA_PARAMS% %_TEST_PARAM%=%2 + shift + ) + ) +) goto param_loop :param_afterloop + if "%OS%" NEQ "Windows_NT" ( echo "Warning, your version of Windows is not supported. Attempting to start scala anyway." ) @@ -51,6 +112,9 @@ rem We use the value of the JAVA_OPTS environment variable if defined set _JAVA_OPTS=%JAVA_OPTS% if not defined _JAVA_OPTS set _JAVA_OPTS=@javaflags@ +rem We append _JAVA_PARAMS java arguments to JAVA_OPTS if necessary +if defined _JAVA_PARAMS set _JAVA_OPTS=%_JAVA_OPTS% %_JAVA_PARAMS% + set _TOOL_CLASSPATH=@classpath@ if "%_TOOL_CLASSPATH%"=="" ( for %%f in ("!_SCALA_HOME!\lib\*") do call :add_cpath "%%f" @@ -89,4 +153,4 @@ goto :eof @@endlocal REM exit code fix, see http://stackoverflow.com/questions/4632891/exiting-batch-with-exit-b-x-where-x-1-acts-as-if-command-completed-successfu -@@%COMSPEC% /C exit %errorlevel% >nul +@@"%COMSPEC%" /C exit %errorlevel% >nul diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index b8791c15dc..50398824e1 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1474,8 +1474,9 @@ self => * }}} */ def postfixExpr(): Tree = { - val base = opstack - var top = prefixExpr() + val start = in.offset + val base = opstack + var top = prefixExpr() while (isIdent) { top = reduceStack(isExpr = true, base, top, precedence(in.name), leftAssoc = treeInfo.isLeftAssoc(in.name)) @@ -1493,9 +1494,7 @@ self => val topinfo = opstack.head opstack = opstack.tail val od = stripParens(reduceStack(isExpr = true, base, topinfo.operand, 0, leftAssoc = true)) - return atPos(od.pos.startOrPoint, topinfo.offset) { - new PostfixSelect(od, topinfo.operator.encode) - } + return makePostfixSelect(start, topinfo.offset, od, topinfo.operator) } } reduceStack(isExpr = true, base, top, 0, leftAssoc = true) diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index b5771454f8..1412bff0ab 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -245,6 +245,12 @@ abstract class TreeBuilder { Assign(lhs, rhs) } + /** Tree for `od op`, start is start0 if od.pos is borked. */ + def makePostfixSelect(start0: Int, end: Int, od: Tree, op: Name): Tree = { + val start = if (od.pos.isDefined) od.pos.startOrPoint else start0 + atPos(r2p(start, end, end + op.length)) { new PostfixSelect(od, op.encode) } + } + /** A type tree corresponding to (possibly unary) intersection type */ def makeIntersectionTypeTree(tps: List[Tree]): Tree = if (tps.tail.isEmpty) tps.head diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 47a8b1f947..2955986a7e 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -626,7 +626,7 @@ abstract class ClassfileParser { sawPrivateConstructor = true in.skip(2); skipAttributes() } else { - if ((sflags & PRIVATE) != 0L && global.settings.optimise.value) { + if ((sflags & PRIVATE) != 0L && global.settings.optimise.value) { // TODO this should be !optimize, no? See c4181f656d. in.skip(4); skipAttributes() } else { val name = pool.getName(in.nextChar) @@ -636,7 +636,7 @@ abstract class ClassfileParser { info match { case MethodType(params, restpe) => // if this is a non-static inner class, remove the explicit outer parameter - val newParams = innerClasses getEntry currentClass match { + val paramsNoOuter = innerClasses getEntry currentClass match { case Some(entry) if !isScalaRaw && !isStatic(entry.jflags) => /* About `clazz.owner.isPackage` below: SI-5957 * For every nested java class A$B, there are two symbols in the scala compiler. @@ -650,6 +650,15 @@ abstract class ClassfileParser { case _ => params } + val newParams = paramsNoOuter match { + case (init :+ tail) if (jflags & JAVA_ACC_SYNTHETIC) != 0L => + // SI-7455 strip trailing dummy argument ("access constructor tag") from synthetic constructors which + // are added when an inner class needs to access a private constructor. + init + case _ => + paramsNoOuter + } + info = MethodType(newParams, clazz.tpe) } sym.setInfo(info) @@ -943,9 +952,14 @@ abstract class ClassfileParser { case ENUM_TAG => val t = pool.getType(index) val n = pool.getName(in.nextChar) - val s = t.typeSymbol.companionModule.info.decls.lookup(n) - assert(s != NoSymbol, t) - Some(LiteralAnnotArg(Constant(s))) + val module = t.typeSymbol.companionModule + val s = module.info.decls.lookup(n) + if (s != NoSymbol) Some(LiteralAnnotArg(Constant(s))) + else { + warning(s"""While parsing annotations in ${in.file}, could not find $n in enum $module.\nThis is likely due to an implementation restriction: an annotation argument cannot refer to a member of the annotated class (SI-7014).""") + None + } + case ARRAY_TAG => val arr = new ArrayBuffer[ClassfileAnnotArg]() var hasError = false diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 4891ef2fd1..1a1137f402 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -523,7 +523,10 @@ abstract class Constructors extends Transform with ast.TreeDSL { /** Return a pair consisting of (all statements up to and including superclass and trait constr calls, rest) */ def splitAtSuper(stats: List[Tree]) = { - def isConstr(tree: Tree) = (tree.symbol ne null) && tree.symbol.isConstructor + def isConstr(tree: Tree): Boolean = tree match { + case Block(_, expr) => isConstr(expr) // SI-6481 account for named argument blocks + case _ => (tree.symbol ne null) && tree.symbol.isConstructor + } val (pre, rest0) = stats span (!isConstr(_)) val (supercalls, rest) = rest0 span (isConstr(_)) (pre ::: supercalls, rest) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ead6ef288c..76249974ac 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -341,11 +341,6 @@ abstract class Erasure extends AddInterfaces } } - // Each primitive value class has its own getClass for ultra-precise class object typing. - private lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ ( - ScalaValueClasses map (_.tpe member nme.getClass_) - ) - // ## requires a little translation private lazy val poundPoundMethods = Set[Symbol](Any_##, Object_##) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index c9c68d080d..e92450c9c0 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -119,7 +119,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { * @param mixinClass The mixin class that produced the superaccessor */ private def rebindSuper(base: Symbol, member: Symbol, mixinClass: Symbol): Symbol = - afterPickler { + afterSpecialize { var bcs = base.info.baseClasses.dropWhile(mixinClass != _).tail var sym: Symbol = NoSymbol debuglog("starting rebindsuper " + base + " " + member + ":" + member.tpe + diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 39716d4ed0..7e85647592 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -844,7 +844,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { debuglog("%s expands to %s in %s".format(sym, specMember.name.decode, pp(env))) info(specMember) = NormalizedMember(sym) newOverload(sym, specMember, env) - owner.info.decls.enter(specMember) + // if this is a class, we insert the normalized member in scope, + // if this is a method, there's no attached scope for it (EmptyScope) + val decls = owner.info.decls + if (decls != EmptyScope) + decls.enter(specMember) specMember } } @@ -1264,7 +1268,35 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } protected override def newBodyDuplicator(context: Context) = new BodyDuplicator(context) + } + /** Introduced to fix SI-7343: Phase ordering problem between Duplicators and Specialization. + * brief explanation: specialization rewires class parents during info transformation, and + * the new info then guides the tree changes. But if a symbol is created during duplication, + * which runs after specialization, its info is not visited and thus the corresponding tree + * is not specialized. One manifestation is the following: + * ``` + * object Test { + * class Parent[@specialized(Int) T] + * + * def spec_method[@specialized(Int) T](t: T, expectedXSuper: String) = { + * class X extends Parent[T]() + * // even in the specialized variant, the local X class + * // doesn't extend Parent$mcI$sp, since its symbol has + * // been created after specialization and was not seen + * // by specialzation's info transformer. + * ... + * } + * } + * ``` + * We fix this by forcing duplication to take place before specialization. + * + * Note: The constructors phase (which also uses duplication) comes after erasure and uses the + * post-erasure typer => we must protect it from the beforeSpecialization phase shifting. + */ + class SpecializationDuplicator(casts: Map[Symbol, Type]) extends Duplicator(casts) { + override def retyped(context: Context, tree: Tree, oldThis: Symbol, newThis: Symbol, env: scala.collection.Map[Symbol, Type]): Tree = + beforeSpecialize(super.retyped(context, tree, oldThis, newThis, env)) } /** A tree symbol substituter that substitutes on type skolems. @@ -1392,7 +1424,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val env = unify(symbol.tpe, tree.tpe, emptyEnv, false) debuglog("[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? + if (env.nonEmpty) { // a method? val specCandidates = qual.tpe.member(specializedName(symbol, env)) val specMember = specCandidates suchThat { s => doesConform(symbol, tree.tpe, qual.tpe.memberType(s), env) @@ -1410,6 +1442,34 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } else None } + /** Computes residual type parameters after rewiring, like "String" in the following example: + * ``` + * def specMe[@specialized T, U](t: T, u: U) = ??? + * specMe[Int, String](1, "2") => specMe$mIc$sp[String](1, "2") + * ``` + */ + def computeResidualTypeVars(baseTree: Tree, specTree: Tree, baseTargs: List[Tree], env: TypeEnv) = { + val baseSym: Symbol = baseTree.symbol + val specSym: Symbol = specTree.symbol + val residualTargs = baseSym.info.typeParams zip baseTargs collect { + case (tvar, targ) if !env.contains(tvar) || !isPrimitiveValueClass(env(tvar).typeSymbol) => targ + } + + if (specSym.info.typeParams.isEmpty && residualTargs.nonEmpty) { + log("!!! Type args to be applied, but symbol says no parameters: " + ((specSym.defString, residualTargs))) + baseTree + } + else { + ifDebug(assert(residualTargs.length == specSym.info.typeParams.length, + "residual: %s, tparams: %s, env: %s".format(residualTargs, specSym.info.typeParams, env)) + ) + + val tree1 = gen.mkTypeApply(specTree, residualTargs) + debuglog("rewrote " + tree + " to " + tree1) + localTyper.typedOperator(atPos(tree.pos)(tree1)) + } + } + curTree = tree tree match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => @@ -1442,43 +1502,44 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } transformSuperApply + // This rewires calls to specialized methods defined in a class (which have a receiver) + // class C { + // def foo[@specialized T](t: T): T = t + // C.this.foo(3) // TypeApply(Select(This(C), foo), List(Int)) => C.this.foo$mIc$sp(3) + // } case TypeApply(sel @ Select(qual, name), targs) - if (!specializedTypeVars(symbol.info).isEmpty && name != nme.CONSTRUCTOR) => - def transformTypeApply = { + if (specializedTypeVars(symbol.info).nonEmpty && name != nme.CONSTRUCTOR) => debuglog("checking typeapp for rerouting: " + tree + " with sym.tpe: " + symbol.tpe + " tree.tpe: " + tree.tpe) val qual1 = transform(qual) - // log(">>> TypeApply: " + tree + ", qual1: " + qual1) + log(">>> TypeApply: " + tree + ", qual1: " + qual1) specSym(qual1) match { case Some(specMember) => debuglog("found " + specMember.fullName) ifDebug(assert(symbol.info.typeParams.length == targs.length, symbol.info.typeParams + " / " + targs)) val env = typeEnv(specMember) - val residualTargs = symbol.info.typeParams zip targs collect { - case (tvar, targ) if !env.contains(tvar) || !isPrimitiveValueClass(env(tvar).typeSymbol) => targ - } - // See SI-5583. Don't know why it happens now if it didn't before. - if (specMember.info.typeParams.isEmpty && residualTargs.nonEmpty) { - log("!!! Type args to be applied, but symbol says no parameters: " + ((specMember.defString, residualTargs))) - localTyper.typed(sel) - } - else { - ifDebug(assert(residualTargs.length == specMember.info.typeParams.length, - "residual: %s, tparams: %s, env: %s".format(residualTargs, specMember.info.typeParams, env)) - ) - - val tree1 = gen.mkTypeApply(Select(qual1, specMember), residualTargs) - debuglog("rewrote " + tree + " to " + tree1) - localTyper.typedOperator(atPos(tree.pos)(tree1)) // being polymorphic, it must be a method - } + computeResidualTypeVars(tree, gen.mkAttributedSelect(qual1, specMember), targs, env) case None => treeCopy.TypeApply(tree, treeCopy.Select(sel, qual1, name), super.transformTrees(targs)) // See pos/exponential-spec.scala - can't call transform on the whole tree again. // super.transform(tree) } + + // This rewires calls to specialized methods defined in the local scope. For example: + // def outerMethod = { + // def foo[@specialized T](t: T): T = t + // foo(3) // TypeApply(Ident(foo), List(Int)) => foo$mIc$sp(3) + // } + case TypeApply(sel @ Ident(name), targs) if name != nme.CONSTRUCTOR => + val env = unify(symbol.tpe, tree.tpe, emptyEnv, false) + if (env.isEmpty) super.transform(tree) + else { + overloads(symbol) find (_ matchesEnv env) match { + case Some(Overload(specMember, _)) => computeResidualTypeVars(tree, Ident(specMember), targs, env) + case _ => super.transform(tree) + } } - transformTypeApply case Select(Super(_, _), _) if illegalSpecializedInheritance(currentClass) => val pos = tree.pos @@ -1629,7 +1690,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { localTyper.typed(deriveDefDef(tree)(rhs => rhs)) } } - transformDefDef + expandInnerNormalizedMembers(transformDefDef) + + case ddef @ DefDef(_, _, _, _, _, _) => + val tree1 = expandInnerNormalizedMembers(tree) + super.transform(tree1) case ValDef(_, _, _, _) if symbol.hasFlag(SPECIALIZED) && !symbol.isParamAccessor => def transformValDef = { @@ -1637,7 +1702,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val tree1 = deriveValDef(tree)(_ => body(symbol.alias).duplicate) debuglog("now typing: " + tree1 + " in " + tree.symbol.owner.fullName) - val d = new Duplicator(emptyEnv) + val d = new SpecializationDuplicator(emptyEnv) val newValDef = d.retyped( localTyper.context1.asInstanceOf[d.Context], tree1, @@ -1654,6 +1719,39 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } + /** + * This performs method specialization inside a scope other than a {class, trait, object}: could be another method + * or a value. This specialization is much simpler, since there is no need to record the new members in the class + * signature, their signatures are only visible locally. It works according to the usual logic: + * - we use normalizeMember to create the specialized symbols + * - we leave DefDef stubs in the tree that are later filled in by tree duplication and adaptation + * @see duplicateBody + */ + private def expandInnerNormalizedMembers(tree: Tree) = tree match { + case ddef @ DefDef(_, _, _, vparams :: Nil, _, rhs) + if ddef.symbol.owner.isMethod && + specializedTypeVars(ddef.symbol.info).nonEmpty && + !ddef.symbol.hasFlag(SPECIALIZED) => + + val sym = ddef.symbol + val owner = sym.owner + val norm = normalizeMember(owner, sym, emptyEnv) + + if (norm.length > 1) { + // record the body for duplication + body(sym) = rhs + parameters(sym) = vparams.map(_.symbol) + // to avoid revisiting the member, we can set the SPECIALIZED + // flag. nobody has to see this anyway :) + sym.setFlag(SPECIALIZED) + // create empty bodies for specializations + localTyper.typed(Block(norm.tail.map(sym => DefDef(sym, { vparamss => EmptyTree })), ddef)) + } else + tree + case _ => + tree + } + /** Duplicate the body of the given method `tree` to the new symbol `source`. * * Knowing that the method can be invoked only in the `castmap` type environment, @@ -1664,7 +1762,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val symbol = tree.symbol val meth = addBody(tree, source) - val d = new Duplicator(castmap) + val d = new SpecializationDuplicator(castmap) debuglog("-->d DUPLICATING: " + meth) d.retyped( localTyper.context1.asInstanceOf[d.Context], diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala index 843f831ea1..ec66bf6f20 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Solving.scala @@ -208,15 +208,16 @@ trait Solving extends Logic { withLit(findModelFor(dropUnit(f, unitLit)), unitLit) case _ => // partition symbols according to whether they appear in positive and/or negative literals - val pos = new mutable.HashSet[Sym]() - val neg = new mutable.HashSet[Sym]() + // SI-7020 Linked- for deterministic counter examples. + val pos = new mutable.LinkedHashSet[Sym]() + val neg = new mutable.LinkedHashSet[Sym]() f.foreach{_.foreach{ lit => if (lit.pos) pos += lit.sym else neg += lit.sym }} // appearing in both positive and negative - val impures = pos intersect neg + val impures: mutable.LinkedHashSet[Sym] = pos intersect neg // appearing only in either positive/negative positions - val pures = (pos ++ neg) -- impures + val pures: mutable.LinkedHashSet[Sym] = (pos ++ neg) -- impures if (pures nonEmpty) { val pureSym = pures.head diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index b9cff5b2d3..5d6d094b44 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -697,7 +697,7 @@ trait ContextErrors { def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg macroLogLite("macro expansion has failed: %s".format(msgForLog)) val errorPos = if (pos != NoPosition) pos else (if (expandee.pos != NoPosition) expandee.pos else enclosingMacroPosition) - if (msg != null) context.error(pos, msg) // issueTypeError(PosAndMsgTypeError(..)) won't work => swallows positions + if (msg != null) context.error(errorPos, msg) // issueTypeError(PosAndMsgTypeError(..)) won't work => swallows positions setError(expandee) throw MacroExpansionException } diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index f6142a81be..25a1228bf6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -37,14 +37,12 @@ abstract class Duplicators extends Analyzer { envSubstitution = new SubstSkolemsTypeMap(env.keysIterator.toList, env.valuesIterator.toList) debuglog("retyped with env: " + env) + newBodyDuplicator(context).typed(tree) } protected def newBodyDuplicator(context: Context) = new BodyDuplicator(context) - def retypedMethod(context: Context, tree: Tree, oldThis: Symbol, newThis: Symbol): Tree = - (newBodyDuplicator(context)).retypedMethod(tree.asInstanceOf[DefDef], oldThis, newThis) - /** Return the special typer for duplicate method bodies. */ override def newTyper(context: Context): Typer = newBodyDuplicator(context) @@ -186,20 +184,6 @@ abstract class Duplicators extends Analyzer { stats.foreach(invalidate(_, owner)) } - def retypedMethod(ddef: DefDef, oldThis: Symbol, newThis: Symbol): Tree = { - oldClassOwner = oldThis - newClassOwner = newThis - invalidateAll(ddef.tparams) - mforeach(ddef.vparamss) { vdef => - invalidate(vdef) - vdef.tpe = null - } - ddef.symbol = NoSymbol - enterSym(context, ddef) - debuglog("remapping this of " + oldClassOwner + " to " + newClassOwner) - typed(ddef) - } - private def inspectTpe(tpe: Type) = { tpe match { case MethodType(_, res) => @@ -401,7 +385,8 @@ abstract class Duplicators extends Analyzer { tree.symbol = NoSymbol // maybe we can find a more specific member in a subclass of Any (see AnyVal members, like ==) } val ntree = castType(tree, pt) - super.typed(ntree, mode, pt) + val res = super.typed(ntree, mode, pt) + res } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 816f977890..d6ec5f2cb0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -713,9 +713,11 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { var expectedTpe = expandee.tpe if (isNullaryInvocation(expandee)) expectedTpe = expectedTpe.finalResultType - var typechecked = typecheck("macro def return type", expanded, expectedTpe) - typechecked = typecheck("expected type", typechecked, pt) - typechecked + // also see http://groups.google.com/group/scala-internals/browse_thread/thread/492560d941b315cc + val expanded0 = duplicateAndKeepPositions(expanded) + val expanded1 = typecheck("macro def return type", expanded0, expectedTpe) + val expanded2 = typecheck("expected type", expanded1, pt) + expanded2 } finally { popMacroContext() } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 379f56521b..bb938074cb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1420,11 +1420,12 @@ trait Namers extends MethodSynthesis { if (!annotated.isInitialized) tree match { case defn: MemberDef => val ainfos = defn.mods.annotations filterNot (_ eq null) map { ann => + val ctx = typer.context + val annCtx = ctx.make(ann) + annCtx.setReportErrors() // need to be lazy, #1782. beforeTyper to allow inferView in annotation args, SI-5892. AnnotationInfo lazily { - val context1 = typer.context.make(ann) - context1.setReportErrors() - beforeTyper(newTyper(context1) typedAnnotation ann) + beforeTyper(newTyper(annCtx) typedAnnotation ann) } } if (ainfos.nonEmpty) { diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index d54f894c62..aafff8a48e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -164,7 +164,7 @@ trait NamesDefaults { self: Analyzer => // never used for constructor calls, they always have a stable qualifier def blockWithQualifier(qual: Tree, selected: Name) = { - val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos) setInfo qual.tpe + val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos) setInfo uncheckedBounds(qual.tpe) blockTyper.context.scope enter sym val vd = atPos(sym.pos)(ValDef(sym, qual) setType NoType) // it stays in Vegas: SI-5720, SI-5727 @@ -291,9 +291,10 @@ trait NamesDefaults { self: Analyzer => arg.tpe } ).widen // have to widen or types inferred from literal defaults will be singletons - val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos) setInfo ( - if (byName) functionType(Nil, argTpe) else argTpe - ) + val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos) setInfo { + val tp = if (byName) functionType(Nil, argTpe) else argTpe + uncheckedBounds(tp) + } Some((context.scope.enter(s), byName, repeated)) }) map2(symPs, args) { diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 03ce710700..09c4878b2f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -225,7 +225,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans * 1.8.1 M's type is a subtype of O's type, or * 1.8.2 M is of type []S, O is of type ()T and S <: T, or * 1.8.3 M is of type ()S, O is of type []T and S <: T, or - * 1.9. If M is a macro def, O cannot be deferred. + * 1.9. If M is a macro def, O cannot be deferred unless there's a concrete method overriding O. * 1.10. If M is not a macro def, O cannot be a macro def. * 2. Check that only abstract classes have deferred members * 3. Check that concrete classes do not have deferred definitions @@ -417,7 +417,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } else if (other.isValue && other.isLazy && !other.isSourceMethod && !other.isDeferred && member.isValue && !member.isLazy) { overrideError("must be declared lazy to override a concrete lazy value") - } else if (other.isDeferred && member.isTermMacro) { // (1.9) + } else if (other.isDeferred && member.isTermMacro && member.extendedOverriddenSymbols.forall(_.isDeferred)) { // (1.9) overrideError("cannot override an abstract method") } else if (other.isTermMacro && !member.isTermMacro) { // (1.10) overrideError("cannot override a macro") @@ -1513,17 +1513,35 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans false } - private def checkTypeRef(tp: Type, tree: Tree) = tp match { + private def checkTypeRef(tp: Type, tree: Tree, skipBounds: Boolean) = tp match { case TypeRef(pre, sym, args) => checkDeprecated(sym, tree.pos) if(sym.isJavaDefined) sym.typeParams foreach (_.cookJavaRawInfo()) - if (!tp.isHigherKinded) + if (!tp.isHigherKinded && !skipBounds) checkBounds(tree, pre, sym.owner, sym.typeParams, args) case _ => } - private def checkAnnotations(tpes: List[Type], tree: Tree) = tpes foreach (tp => checkTypeRef(tp, tree)) + private def checkTypeRefBounds(tp: Type, tree: Tree) = { + var skipBounds = false + tp match { + case AnnotatedType(ann :: Nil, underlying, selfSym) if ann.symbol == UncheckedBoundsClass => + skipBounds = true + underlying + case TypeRef(pre, sym, args) => + if (!tp.isHigherKinded && !skipBounds) + checkBounds(tree, pre, sym.owner, sym.typeParams, args) + tp + case _ => + tp + } + } + + private def checkAnnotations(tpes: List[Type], tree: Tree) = tpes foreach { tp => + checkTypeRef(tp, tree, skipBounds = false) + checkTypeRefBounds(tp, tree) + } private def doTypeTraversal(tree: Tree)(f: Type => Unit) = if (!inPattern) tree.tpe foreach f private def applyRefchecksToAnnotations(tree: Tree): Unit = { @@ -1551,8 +1569,9 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } doTypeTraversal(tree) { - case AnnotatedType(annots, _, _) => applyChecks(annots) - case _ => + case tp @ AnnotatedType(annots, _, _) => + applyChecks(annots) + case tp => } case _ => } @@ -1735,13 +1754,27 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } val existentialParams = new ListBuffer[Symbol] - doTypeTraversal(tree) { // check all bounds, except those that are existential type parameters - case ExistentialType(tparams, tpe) => + var skipBounds = false + // check all bounds, except those that are existential type parameters + // or those within typed annotated with @uncheckedBounds + doTypeTraversal(tree) { + case tp @ ExistentialType(tparams, tpe) => existentialParams ++= tparams - case t: TypeRef => - checkTypeRef(deriveTypeWithWildcards(existentialParams.toList)(t), tree) + case ann: AnnotatedType if ann.hasAnnotation(UncheckedBoundsClass) => + // SI-7694 Allow code synthetizers to disable checking of bounds for TypeTrees based on inferred LUBs + // which might not conform to the constraints. + skipBounds = true + case tp: TypeRef => + val tpWithWildcards = deriveTypeWithWildcards(existentialParams.toList)(tp) + checkTypeRef(tpWithWildcards, tree, skipBounds) case _ => } + if (skipBounds) { + tree.tpe = tree.tpe.map { + _.filterAnnotations(_.symbol != UncheckedBoundsClass) + } + } + tree case TypeApply(fn, args) => @@ -1793,9 +1826,11 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans case LabelDef(_, _, _) if treeInfo.hasSynthCaseSymbol(result) => val old = inPattern inPattern = true - val res = deriveLabelDef(result)(transform) + val res = deriveLabelDef(result)(transform) // TODO SI-7756 Too broad! The code from the original case body should be fully refchecked! inPattern = old res + case ValDef(_, _, _, _) if treeInfo.hasSynthCaseSymbol(result) => + deriveValDef(result)(transform) // SI-7716 Don't refcheck the tpt of the synthetic val that holds the selector. case _ => super.transform(result) } diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 4950a7efef..2270e812eb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -366,11 +366,14 @@ trait TypeDiagnostics { val strings = mutable.Map[String, Set[TypeDiag]]() withDefaultValue Set() val names = mutable.Map[Name, Set[TypeDiag]]() withDefaultValue Set() - def record(t: Type, sym: Symbol) = { - val diag = TypeDiag(t, sym) + val localsSet = locals.toSet - strings("" + t) += diag - names(sym.name) += diag + def record(t: Type, sym: Symbol) = { + if (!localsSet(sym)) { + val diag = TypeDiag(t, sym) + strings("" + t) += diag + names(sym.name) += diag + } } for (tpe <- types ; t <- tpe) { t match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c59ef4ebda..bf2170310f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -656,8 +656,7 @@ trait Typers extends Modes with Adaptations with Tags { // To fully benefit from special casing the return type of // getClass, we have to catch it immediately so expressions // like x.getClass().newInstance() are typed with the type of x. - else if ( tree.symbol.name == nme.getClass_ - && tree.tpe.params.isEmpty + else if ( isGetClass(tree.symbol) // TODO: If the type of the qualifier is inaccessible, we can cause private types // to escape scope here, e.g. pos/t1107. I'm not sure how to properly handle this // so for now it requires the type symbol be public. @@ -1148,7 +1147,7 @@ trait Typers extends Modes with Adaptations with Tags { else if ( inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application tree.symbol != null && tree.symbol.isTermMacro && // of a macro - !tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined) + !isMacroExpansionSuppressed(tree)) macroExpand(this, tree, mode, pt) else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode)) adaptConstrPattern() @@ -1456,8 +1455,8 @@ trait Typers extends Modes with Adaptations with Tags { implRestriction(tree, "nested object") //see https://issues.scala-lang.org/browse/SI-6444 //see https://issues.scala-lang.org/browse/SI-6463 - case _: ClassDef => - implRestriction(tree, "nested class") + case cd: ClassDef if !cd.symbol.isAnonymousClass => // Don't warn about partial functions, etc. SI-7571 + implRestriction(tree, "nested class") // avoiding Type Tests that might check the $outer pointer. case Select(sup @ Super(qual, mix), selector) if selector != nme.CONSTRUCTOR && qual.symbol == clazz && mix != tpnme.EMPTY => //see https://issues.scala-lang.org/browse/SI-6483 implRestriction(sup, "qualified super reference") @@ -2011,6 +2010,8 @@ trait Typers extends Modes with Adaptations with Tags { // !!! This method is redundant with other, less buggy ones. def decompose(call: Tree): (Tree, List[Tree]) = call match { + case _ if call.isErrorTyped => // e.g. SI-7636 + (call, Nil) case Apply(fn, args) => // an object cannot be allowed to pass a reference to itself to a superconstructor // because of initialization issues; SI-473, SI-3913, SI-6928. @@ -4058,6 +4059,7 @@ trait Typers extends Modes with Adaptations with Tags { findSelection(cxTree) match { case Some((opName, treeInfo.Applied(_, targs, _))) => val fun = gen.mkTypeApply(Select(qual, opName), targs) + if (opName == nme.updateDynamic) suppressMacroExpansion(fun) // SI-7617 atPos(qual.pos)(Apply(fun, Literal(Constant(name.decode)) :: Nil)) case _ => setError(tree) @@ -4230,7 +4232,9 @@ trait Typers extends Modes with Adaptations with Tags { } def typedAssign(lhs: Tree, rhs: Tree): Tree = { - val lhs1 = typed(lhs, EXPRmode | LHSmode, WildcardType) + // see SI-7617 for an explanation of why macro expansion is suppressed + def typedLhs(lhs: Tree) = typed(lhs, EXPRmode | LHSmode, WildcardType) + val lhs1 = unsuppressMacroExpansion(typedLhs(suppressMacroExpansion(lhs))) val varsym = lhs1.symbol // see #2494 for double error message example @@ -5353,7 +5357,7 @@ trait Typers extends Modes with Adaptations with Tags { // that typecheck must not trigger macro expansions, so we explicitly prohibit them // however we cannot do `context.withMacrosDisabled` // because `expr` might contain nested macro calls (see SI-6673) - val exprTyped = typed1(expr updateAttachment SuppressMacroExpansionAttachment, mode, pt) + val exprTyped = typed1(suppressMacroExpansion(expr), mode, pt) exprTyped match { case macroDef if macroDef.symbol != null && macroDef.symbol.isTermMacro && !macroDef.symbol.isErroneous => MacroEtaError(exprTyped) diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 471e2653cf..a62c87e713 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -16,6 +16,7 @@ import Jar.isJarOrZip import File.pathSeparator import java.net.MalformedURLException import java.util.regex.PatternSyntaxException +import scala.reflect.runtime.ReflectionUtils /** <p> * This module provides star expansion of '-classpath' option arguments, behaves the same as @@ -100,7 +101,7 @@ object ClassPath { } /** A useful name filter. */ - def isTraitImplementation(name: String) = name endsWith "$class.class" + def isTraitImplementation(name: String) = ReflectionUtils.isTraitImplementation(name) def specToURL(spec: String): Option[URL] = try Some(new URL(spec)) @@ -161,7 +162,7 @@ object ClassPath { } object DefaultJavaContext extends JavaContext { - override def isValidName(name: String) = !isTraitImplementation(name) + override def isValidName(name: String) = !ReflectionUtils.scalacShouldntLoadClassfile(name) } private def endsClass(s: String) = s.length > 6 && s.substring(s.length - 6) == ".class" diff --git a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala index aa3b7c286d..77a19d3ead 100644 --- a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala @@ -15,7 +15,8 @@ import scala.util.Sorting import scala.collection.mutable import scala.tools.nsc.io.{ AbstractFile, MsilFile } import ch.epfl.lamp.compiler.msil.{ Type => MSILType, Assembly } -import ClassPath.{ ClassPathContext, isTraitImplementation } +import ClassPath.ClassPathContext +import scala.reflect.runtime.ReflectionUtils.isTraitImplementation /** Keeping the MSIL classpath code in its own file is important to make sure * we don't accidentally introduce a dependency on msil.jar in the jvm. diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 4b5dcadfa2..b9541ece5d 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -8,12 +8,14 @@ import scala.tools.nsc.typechecker.Modes import scala.tools.nsc.io.VirtualDirectory import scala.tools.nsc.interpreter.AbstractFileClassLoader import scala.tools.nsc.util.FreshNameCreator +import scala.tools.nsc.ast.parser.Tokens.EOF import scala.reflect.internal.Flags._ import scala.reflect.internal.util.{BatchSourceFile, NoSourceFile, NoFile} import java.lang.{Class => jClass} import scala.compat.Platform.EOL import scala.reflect.NameTransformer import scala.reflect.api.JavaUniverse +import scala.reflect.io.NoAbstractFile abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => @@ -137,7 +139,9 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => val wrapper2 = if (!withMacrosDisabled) (currentTyper.context.withMacrosEnabled[Tree] _) else (currentTyper.context.withMacrosDisabled[Tree] _) def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) - phase = (new Run).typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled + val run = new Run + run.symSource(ownerClass) = NoAbstractFile // need to set file to something different from null, so that currentRun.defines works + phase = run.typerPhase // need to set a phase to something <= typerPhase, otherwise implicits in typedSelect will be disabled currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions reporter.reset() @@ -166,7 +170,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)( (currentTyper, expr) => { trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value)) - currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match { + currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt), reportAmbiguousErrors = false) match { case analyzer.SilentResultValue(result) => trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) result @@ -273,14 +277,13 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => def parse(code: String): Tree = { val run = new Run reporter.reset() - val wrappedCode = "object wrapper {" + EOL + code + EOL + "}" - val file = new BatchSourceFile("<toolbox>", wrappedCode) + val file = new BatchSourceFile("<toolbox>", code) val unit = new CompilationUnit(file) phase = run.parserPhase val parser = new syntaxAnalyzer.UnitParser(unit) - val wrappedTree = parser.parse() + val parsed = parser.templateStats() + parser.accept(EOF) throwIfErrors() - val PackageDef(_, List(ModuleDef(_, _, Template(_, _, _ :: parsed)))) = wrappedTree parsed match { case expr :: Nil => expr case stats :+ expr => Block(stats, expr) @@ -402,7 +405,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => def compile(tree: u.Tree): () => Any = { if (compiler.settings.verbose.value) println("importing "+tree) - var ctree: compiler.Tree = importer.importTree(tree) + val ctree: compiler.Tree = importer.importTree(tree) if (compiler.settings.verbose.value) println("compiling "+ctree) compiler.compile(ctree) diff --git a/src/eclipse/README.md b/src/eclipse/README.md index 39a3f457a0..44dd3d83ea 100644 --- a/src/eclipse/README.md +++ b/src/eclipse/README.md @@ -11,6 +11,9 @@ IMPORTANT Preferences/General/Workspace/Linked Resources. The value should be the absolute path to your scala checkout. All paths in project files are relative to this one, so nothing will work before you do so. +Additionally, we start using Maven dependencies (e.g. junit) so you need to define +`classpath variable` inside Eclipse. Define `M2_REPO` in Java/Build Path/Classpath Variables +to point to your local Maven repository (e.g. $HOME/.m2/repository). 2. The Eclipse Java compiler does not allow certain calls to restricted APIs in the JDK. The Scala library uses such APIs, so you'd see this error: diff --git a/src/eclipse/test-junit/.classpath b/src/eclipse/test-junit/.classpath new file mode 100644 index 0000000000..718f7b6ece --- /dev/null +++ b/src/eclipse/test-junit/.classpath @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="test-junit"/> + <classpathentry combineaccessrules="false" kind="src" path="/reflect"/> + <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="lib" path="lib/ant/ant.jar"/> + <classpathentry kind="lib" path="lib/jline.jar"/> + <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/> + <classpathentry kind="var" path="M2_REPO/junit/junit/4.10/junit-4.10.jar"/> + <classpathentry kind="output" path="build-test-junit"/> +</classpath> diff --git a/src/eclipse/test-junit/.project b/src/eclipse/test-junit/.project new file mode 100644 index 0000000000..052b6c1b6f --- /dev/null +++ b/src/eclipse/test-junit/.project @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>test-junit</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.scala-ide.sdt.core.scalabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.scala-ide.sdt.core.scalanature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> + <linkedResources> + <link> + <name>build-test-junit</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/build/junit/classes</locationURI> + </link> + <link> + <name>lib</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/lib</locationURI> + </link> + <link> + <name>test-junit</name> + <type>2</type> + <locationURI>SCALA_BASEDIR/test/junit</locationURI> + </link> + </linkedResources> +</projectDescription> diff --git a/src/library/scala/collection/concurrent/TrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala index 6c11c5bcb5..714260fa8a 100644 --- a/src/library/scala/collection/concurrent/TrieMap.scala +++ b/src/library/scala/collection/concurrent/TrieMap.scala @@ -1011,8 +1011,11 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct: */ protected def subdivide(): Seq[Iterator[(K, V)]] = if (subiter ne null) { // the case where an LNode is being iterated - val it = subiter - subiter = null + val it = newIterator(level + 1, ct, _mustInit = false) + it.depth = -1 + it.subiter = this.subiter + it.current = null + this.subiter = null advance() this.level += 1 Seq(it, this) diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 6b6ad29074..caf91fbb0f 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -14,7 +14,7 @@ import java.util.concurrent.{ ConcurrentLinkedQueue, TimeUnit, Callable } import java.util.concurrent.TimeUnit.{ NANOSECONDS => NANOS, MILLISECONDS ⇒ MILLIS } import java.lang.{ Iterable => JIterable } import java.util.{ LinkedList => JLinkedList } -import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, AtomicBoolean } +import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, AtomicLong, AtomicBoolean } import scala.util.control.NonFatal import scala.Option @@ -101,7 +101,7 @@ trait Future[+T] extends Awaitable[T] { // that also have an executor parameter, which // keeps us from accidentally forgetting to use // the executor parameter. - private implicit def internalExecutor: ExecutionContext = Future.InternalCallbackExecutor + private def internalExecutor = Future.InternalCallbackExecutor /* Callbacks */ @@ -116,9 +116,10 @@ trait Future[+T] extends Awaitable[T] { * $callbackInContext */ def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit = onComplete { - case Success(v) if pf isDefinedAt v => pf(v) + case Success(v) => + pf.applyOrElse[T, Any](v, Predef.conforms[T]) // Exploiting the cached function to avoid MatchError case _ => - }(executor) + } /** When this future is completed with a failure (i.e. with a throwable), * apply the provided callback to the throwable. @@ -134,9 +135,10 @@ trait Future[+T] extends Awaitable[T] { * $callbackInContext */ def onFailure[U](callback: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = onComplete { - case Failure(t) if NonFatal(t) && callback.isDefinedAt(t) => callback(t) + case Failure(t) => + callback.applyOrElse[Throwable, Any](t, Predef.conforms[Throwable]) // Exploiting the cached function to avoid MatchError case _ => - }(executor) + } /** When this future is completed, either through an exception, or a value, * apply the provided function. @@ -186,13 +188,12 @@ trait Future[+T] extends Awaitable[T] { * and throws a corresponding exception if the original future fails. */ def failed: Future[Throwable] = { + implicit val ec = internalExecutor val p = Promise[Throwable]() - onComplete { case Failure(t) => p success t case Success(v) => p failure (new NoSuchElementException("Future.failed not completed with a throwable.")) } - p.future } @@ -203,10 +204,7 @@ trait Future[+T] extends Awaitable[T] { * * Will not be called if the future fails. */ - def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit = onComplete { - case Success(r) => f(r) - case _ => // do nothing - }(executor) + def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit = onComplete { _ foreach f } /** Creates a new future by applying the 's' function to the successful result of * this future, or the 'f' function to the failed result. If there is any non-fatal @@ -221,19 +219,11 @@ trait Future[+T] extends Awaitable[T] { */ def transform[S](s: T => S, f: Throwable => Throwable)(implicit executor: ExecutionContext): Future[S] = { val p = Promise[S]() - + // transform on Try has the wrong shape for us here onComplete { - case result => - try { - result match { - case Failure(t) => p failure f(t) - case Success(r) => p success s(r) - } - } catch { - case NonFatal(t) => p failure t - } - }(executor) - + case Success(r) => p complete Try(s(r)) + case Failure(t) => p complete Try(throw f(t)) // will throw fatal errors! + } p.future } @@ -245,19 +235,7 @@ trait Future[+T] extends Awaitable[T] { */ def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity) val p = Promise[S]() - - onComplete { - case result => - try { - result match { - case Success(r) => p success f(r) - case f: Failure[_] => p complete f.asInstanceOf[Failure[S]] - } - } catch { - case NonFatal(t) => p failure t - } - }(executor) - + onComplete { v => p complete (v map f) } p.future } @@ -269,21 +247,16 @@ trait Future[+T] extends Awaitable[T] { * $forComprehensionExamples */ def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = { - val p = Promise[S]() - + import impl.Promise.DefaultPromise + val p = new DefaultPromise[S]() onComplete { case f: Failure[_] => p complete f.asInstanceOf[Failure[S]] - case Success(v) => - try { - f(v).onComplete({ - case f: Failure[_] => p complete f.asInstanceOf[Failure[S]] - case Success(v) => p success v - })(internalExecutor) - } catch { - case NonFatal(t) => p failure t - } - }(executor) - + case Success(v) => try f(v) match { + // If possible, link DefaultPromises to avoid space leaks + case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p) + case fut => fut onComplete p.complete + } catch { case NonFatal(t) => p failure t } + } p.future } @@ -303,34 +276,14 @@ trait Future[+T] extends Awaitable[T] { * Await.result(h, Duration.Zero) // throw a NoSuchElementException * }}} */ - def filter(pred: T => Boolean)(implicit executor: ExecutionContext): Future[T] = { - val p = Promise[T]() - - onComplete { - case f: Failure[_] => p complete f.asInstanceOf[Failure[T]] - case Success(v) => - try { - if (pred(v)) p success v - else p failure new NoSuchElementException("Future.filter predicate is not satisfied") - } catch { - case NonFatal(t) => p failure t - } - }(executor) - - p.future - } + def filter(pred: T => Boolean)(implicit executor: ExecutionContext): Future[T] = + map { + r => if (pred(r)) r else throw new NoSuchElementException("Future.filter predicate is not satisfied") + } /** Used by for-comprehensions. */ final def withFilter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T] = filter(p)(executor) - // final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p) - - // final class FutureWithFilter[+S](self: Future[S], p: S => Boolean) { - // def foreach(f: S => Unit): Unit = self filter p foreach f - // def map[R](f: S => R) = self filter p map f - // def flatMap[R](f: S => Future[R]) = self filter p flatMap f - // def withFilter(q: S => Boolean): FutureWithFilter[S] = new FutureWithFilter[S](self, x => p(x) && q(x)) - // } /** Creates a new future by mapping the value of the current future, if the given partial function is defined at that value. * @@ -352,22 +305,10 @@ trait Future[+T] extends Awaitable[T] { * Await.result(h, Duration.Zero) // throw a NoSuchElementException * }}} */ - def collect[S](pf: PartialFunction[T, S])(implicit executor: ExecutionContext): Future[S] = { - val p = Promise[S]() - - onComplete { - case f: Failure[_] => p complete f.asInstanceOf[Failure[S]] - case Success(v) => - try { - if (pf.isDefinedAt(v)) p success pf(v) - else p failure new NoSuchElementException("Future.collect partial function is not defined at: " + v) - } catch { - case NonFatal(t) => p failure t - } - }(executor) - - p.future - } + def collect[S](pf: PartialFunction[T, S])(implicit executor: ExecutionContext): Future[S] = + map { + r => pf.applyOrElse(r, (t: T) => throw new NoSuchElementException("Future.collect partial function is not defined at: " + t)) + } /** Creates a new future that will handle any matching throwable that this * future might contain. If there is no match, or if this future contains @@ -383,9 +324,7 @@ trait Future[+T] extends Awaitable[T] { */ def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = { val p = Promise[U]() - - onComplete { case tr => p.complete(tr recover pf) }(executor) - + onComplete { v => p complete (v recover pf) } p.future } @@ -404,17 +343,10 @@ trait Future[+T] extends Awaitable[T] { */ def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = { val p = Promise[U]() - onComplete { - case Failure(t) if pf isDefinedAt t => - try { - p completeWith pf(t) - } catch { - case NonFatal(t) => p failure t - } - case otherwise => p complete otherwise - }(executor) - + case Failure(t) => try pf.applyOrElse(t, (_: Throwable) => this) onComplete p.complete catch { case NonFatal(t) => p failure t } + case other => p complete other + } p.future } @@ -427,19 +359,12 @@ trait Future[+T] extends Awaitable[T] { * with the throwable stored in `that`. */ def zip[U](that: Future[U]): Future[(T, U)] = { + implicit val ec = internalExecutor val p = Promise[(T, U)]() - - this onComplete { + onComplete { case f: Failure[_] => p complete f.asInstanceOf[Failure[(T, U)]] - case Success(r) => - that onSuccess { - case r2 => p success ((r, r2)) - } - that onFailure { - case f => p failure f - } + case Success(s) => that onComplete { c => p.complete(c map { s2 => (s, s2) }) } } - p.future } @@ -458,6 +383,7 @@ trait Future[+T] extends Awaitable[T] { * }}} */ def fallbackTo[U >: T](that: Future[U]): Future[U] = { + implicit val ec = internalExecutor val p = Promise[U]() onComplete { case s @ Success(_) => p complete s @@ -470,23 +396,13 @@ trait Future[+T] extends Awaitable[T] { * that conforms to `S`'s erased type or a `ClassCastException` otherwise. */ def mapTo[S](implicit tag: ClassTag[S]): Future[S] = { - def boxedType(c: Class[_]): Class[_] = { + implicit val ec = internalExecutor + val boxedClass = { + val c = tag.runtimeClass if (c.isPrimitive) Future.toBoxed(c) else c } - - val p = Promise[S]() - - onComplete { - case f: Failure[_] => p complete f.asInstanceOf[Failure[S]] - case Success(t) => - p complete (try { - Success(boxedType(tag.runtimeClass).cast(t).asInstanceOf[S]) - } catch { - case e: ClassCastException => Failure(e) - }) - } - - p.future + require(boxedClass ne null) + map(s => boxedClass.cast(s).asInstanceOf[S]) } /** Applies the side-effecting function to the result of this future, and returns @@ -514,11 +430,9 @@ trait Future[+T] extends Awaitable[T] { */ def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T] = { val p = Promise[T]() - onComplete { - case r => try if (pf isDefinedAt r) pf(r) finally p complete r - }(executor) - + case r => try pf.applyOrElse[Try[T], Any](r, Predef.conforms[Try[T]]) finally p complete r + } p.future } @@ -579,14 +493,12 @@ object Future { } map (_.result) } - /** Returns a `Future` to the result of the first future in the list that is completed. + /** Returns a new `Future` to the result of the first future in the list that is completed. */ def firstCompletedOf[T](futures: TraversableOnce[Future[T]])(implicit executor: ExecutionContext): Future[T] = { val p = Promise[T]() - val completeFirst: Try[T] => Unit = p tryComplete _ - futures.foreach(_ onComplete completeFirst) - + futures foreach { _ onComplete completeFirst } p.future } @@ -626,7 +538,7 @@ object Future { * }}} */ def fold[T, R](futures: TraversableOnce[Future[T]])(zero: R)(foldFun: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = { - if (futures.isEmpty) Promise.successful(zero).future + if (futures.isEmpty) Future.successful(zero) else sequence(futures).map(_.foldLeft(zero)(foldFun)) } @@ -638,7 +550,7 @@ object Future { * }}} */ def reduce[T, R >: T](futures: TraversableOnce[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = { - if (futures.isEmpty) Promise[R].failure(new NoSuchElementException("reduce attempted on empty collection")).future + if (futures.isEmpty) Future.failed(new NoSuchElementException("reduce attempted on empty collection")) else sequence(futures).map(_ reduceLeft op) } diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index 52f1075137..c9b2a15f2f 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -8,11 +8,14 @@ package scala.concurrent.impl -import scala.concurrent.{ ExecutionContext, CanAwait, OnCompleteRunnable, TimeoutException, ExecutionException } +import scala.concurrent.{ ExecutionContext, CanAwait, OnCompleteRunnable, TimeoutException, ExecutionException, blocking } +import scala.concurrent.Future.InternalCallbackExecutor import scala.concurrent.duration.{ Duration, Deadline, FiniteDuration, NANOSECONDS } import scala.annotation.tailrec import scala.util.control.NonFatal import scala.util.{ Try, Success, Failure } +import java.io.ObjectInputStream +import java.util.concurrent.locks.AbstractQueuedSynchronizer private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] { def future: this.type = this @@ -53,98 +56,262 @@ private[concurrent] object Promise { case t => Failure(t) } + /** + * Latch used to implement waiting on a DefaultPromise's result. + * + * Inspired by: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/locks/AbstractQueuedSynchronizer.java + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + private final class CompletionLatch[T] extends AbstractQueuedSynchronizer with (Try[T] => Unit) { + override protected def tryAcquireShared(ignored: Int): Int = if (getState != 0) 1 else -1 + override protected def tryReleaseShared(ignore: Int): Boolean = { + setState(1) + true + } + override def apply(ignored: Try[T]): Unit = releaseShared(1) + } + + /** Default promise implementation. + * + * A DefaultPromise has three possible states. It can be: + * + * 1. Incomplete, with an associated list of callbacks waiting on completion. + * 2. Complete, with a result. + * 3. Linked to another DefaultPromise. + * + * If a DefaultPromise is linked it another DefaultPromise then it will + * delegate all its operations to that other promise. This means that two + * DefaultPromises that are linked will appear, to external callers, to have + * exactly the same state and behaviour. E.g. they will both appear to be + * either complete or incomplete, and with the same values. + * + * A DefaultPromise stores its state entirely in the AnyRef cell exposed by + * AbstractPromise. The type of object stored in the cell fully describes the + * current state of the promise. + * + * 1. List[CallbackRunnable] - The promise is incomplete and has zero or more callbacks + * to call when it is eventually completed. + * 2. Try[T] - The promise is complete and now contains its value. + * 3. DefaultPromise[T] - The promise is linked to another promise. + * + * The ability to link DefaultPromises is needed to prevent memory leaks when + * using Future.flatMap. The previous implementation of Future.flatMap used + * onComplete handlers to propagate the ultimate value of a flatMap operation + * to its promise. Recursive calls to flatMap built a chain of onComplete + * handlers and promises. Unfortunately none of the handlers or promises in + * the chain could be collected until the handlers had been called and + * detached, which only happened when the final flatMap future was completed. + * (In some situations, such as infinite streams, this would never actually + * happen.) Because of the fact that the promise implementation internally + * created references between promises, and these references were invisible to + * user code, it was easy for user code to accidentally build large chains of + * promises and thereby leak memory. + * + * The problem of leaks is solved by automatically breaking these chains of + * promises, so that promises don't refer to each other in a long chain. This + * allows each promise to be individually collected. The idea is to "flatten" + * the chain of promises, so that instead of each promise pointing to its + * neighbour, they instead point directly the promise at the root of the + * chain. This means that only the root promise is referenced, and all the + * other promises are available for garbage collection as soon as they're no + * longer referenced by user code. + * + * To make the chains flattenable, the concept of linking promises together + * needed to become an explicit feature of the DefaultPromise implementation, + * so that the implementation to navigate and rewire links as needed. The idea + * of linking promises is based on the [[Twitter promise implementation + * https://github.com/twitter/util/blob/master/util-core/src/main/scala/com/twitter/util/Promise.scala]]. + * + * In practice, flattening the chain cannot always be done perfectly. When a + * promise is added to the end of the chain, it scans the chain and links + * directly to the root promise. This prevents the chain from growing forwards + * But the root promise for a chain can change, causing the chain to grow + * backwards, and leaving all previously-linked promise pointing at a promise + * which is no longer the root promise. + * + * To mitigate the problem of the root promise changing, whenever a promise's + * methods are called, and it needs a reference to its root promise it calls + * the `compressedRoot()` method. This method re-scans the promise chain to + * get the root promise, and also compresses its links so that it links + * directly to whatever the current root promise is. This ensures that the + * chain is flattened whenever `compressedRoot()` is called. And since + * `compressedRoot()` is called at every possible opportunity (when getting a + * promise's value, when adding an onComplete handler, etc), this will happen + * frequently. Unfortunately, even this eager relinking doesn't absolutely + * guarantee that the chain will be flattened and that leaks cannot occur. + * However eager relinking does greatly reduce the chance that leaks will + * occur. + * + * Future.flatMap links DefaultPromises together by calling the `linkRootOf` + * method. This is the only externally visible interface to linked + * DefaultPromises, and `linkedRootOf` is currently only designed to be called + * by Future.flatMap. */ class DefaultPromise[T] extends AbstractPromise with Promise[T] { self => - updateState(null, Nil) // Start at "No callbacks" + updateState(null, Nil) // The promise is incomplete and has no callbacks - protected final def tryAwait(atMost: Duration): Boolean = { - @tailrec - def awaitUnsafe(deadline: Deadline, nextWait: FiniteDuration): Boolean = { - if (!isCompleted && nextWait > Duration.Zero) { - val ms = nextWait.toMillis - val ns = (nextWait.toNanos % 1000000l).toInt // as per object.wait spec - - synchronized { if (!isCompleted) wait(ms, ns) } - - awaitUnsafe(deadline, deadline.timeLeft) - } else - isCompleted + /** Get the root promise for this promise, compressing the link chain to that + * promise if necessary. + * + * For promises that are not linked, the result of calling + * `compressedRoot()` will the promise itself. However for linked promises, + * this method will traverse each link until it locates the root promise at + * the base of the link chain. + * + * As a side effect of calling this method, the link from this promise back + * to the root promise will be updated ("compressed") to point directly to + * the root promise. This allows intermediate promises in the link chain to + * be garbage collected. Also, subsequent calls to this method should be + * faster as the link chain will be shorter. + */ + @tailrec + private def compressedRoot(): DefaultPromise[T] = { + getState match { + case linked: DefaultPromise[_] => + val target = linked.asInstanceOf[DefaultPromise[T]].root + if (linked eq target) target else if (updateState(linked, target)) target else compressedRoot() + case _ => this } - @tailrec - def awaitUnbounded(): Boolean = { - if (isCompleted) true - else { - synchronized { if (!isCompleted) wait() } - awaitUnbounded() - } + } + + /** Get the promise at the root of the chain of linked promises. Used by `compressedRoot()`. + * The `compressedRoot()` method should be called instead of this method, as it is important + * to compress the link chain whenever possible. + */ + @tailrec + private def root: DefaultPromise[T] = { + getState match { + case linked: DefaultPromise[_] => linked.asInstanceOf[DefaultPromise[T]].root + case _ => this } + } + /** Try waiting for this promise to be completed. + */ + protected final def tryAwait(atMost: Duration): Boolean = if (!isCompleted) { import Duration.Undefined + import scala.concurrent.Future.InternalCallbackExecutor atMost match { - case u if u eq Undefined => throw new IllegalArgumentException("cannot wait for Undefined period") - case Duration.Inf => awaitUnbounded - case Duration.MinusInf => isCompleted - case f: FiniteDuration => if (f > Duration.Zero) awaitUnsafe(f.fromNow, f) else isCompleted + case e if e eq Undefined => throw new IllegalArgumentException("cannot wait for Undefined period") + case Duration.Inf => + val l = new CompletionLatch[T]() + onComplete(l)(InternalCallbackExecutor) + l.acquireSharedInterruptibly(1) + case Duration.MinusInf => // Drop out + case f: FiniteDuration => + if (f > Duration.Zero) { + val l = new CompletionLatch[T]() + onComplete(l)(InternalCallbackExecutor) + l.tryAcquireSharedNanos(1, f.toNanos) + } } - } + + isCompleted + } else true // Already completed @throws(classOf[TimeoutException]) @throws(classOf[InterruptedException]) def ready(atMost: Duration)(implicit permit: CanAwait): this.type = - if (isCompleted || tryAwait(atMost)) this + if (tryAwait(atMost)) this else throw new TimeoutException("Futures timed out after [" + atMost + "]") @throws(classOf[Exception]) def result(atMost: Duration)(implicit permit: CanAwait): T = - ready(atMost).value.get match { - case Failure(e) => throw e - case Success(r) => r - } + ready(atMost).value.get.get // ready throws TimeoutException if timeout so value.get is safe here - def value: Option[Try[T]] = getState match { + def value: Option[Try[T]] = value0 + + @tailrec + private def value0: Option[Try[T]] = getState match { case c: Try[_] => Some(c.asInstanceOf[Try[T]]) + case _: DefaultPromise[_] => compressedRoot().value0 case _ => None } - override def isCompleted: Boolean = getState match { // Cheaper than boxing result into Option due to "def value" + override def isCompleted: Boolean = isCompleted0 + + @tailrec + private def isCompleted0: Boolean = getState match { case _: Try[_] => true + case _: DefaultPromise[_] => compressedRoot().isCompleted0 case _ => false } def tryComplete(value: Try[T]): Boolean = { val resolved = resolveTry(value) - (try { - @tailrec - def tryComplete(v: Try[T]): List[CallbackRunnable[T]] = { - getState match { - case raw: List[_] => - val cur = raw.asInstanceOf[List[CallbackRunnable[T]]] - if (updateState(cur, v)) cur else tryComplete(v) - case _ => null - } - } - tryComplete(resolved) - } finally { - synchronized { notifyAll() } //Notify any evil blockers - }) match { + tryCompleteAndGetListeners(resolved) match { case null => false case rs if rs.isEmpty => true case rs => rs.foreach(r => r.executeWithValue(resolved)); true } } + /** Called by `tryComplete` to store the resolved value and get the list of + * listeners, or `null` if it is already completed. + */ + @tailrec + private def tryCompleteAndGetListeners(v: Try[T]): List[CallbackRunnable[T]] = { + getState match { + case raw: List[_] => + val cur = raw.asInstanceOf[List[CallbackRunnable[T]]] + if (updateState(cur, v)) cur else tryCompleteAndGetListeners(v) + case _: DefaultPromise[_] => + compressedRoot().tryCompleteAndGetListeners(v) + case _ => null + } + } + def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit = { val preparedEC = executor.prepare val runnable = new CallbackRunnable[T](preparedEC, func) + dispatchOrAddCallback(runnable) + } - @tailrec //Tries to add the callback, if already completed, it dispatches the callback to be executed - def dispatchOrAddCallback(): Unit = - getState match { - case r: Try[_] => runnable.executeWithValue(r.asInstanceOf[Try[T]]) - case listeners: List[_] => if (updateState(listeners, runnable :: listeners)) () else dispatchOrAddCallback() - } - dispatchOrAddCallback() + /** Tries to add the callback, if already completed, it dispatches the callback to be executed. + * Used by `onComplete()` to add callbacks to a promise and by `link()` to transfer callbacks + * to the root promise when linking two promises togehter. + */ + @tailrec + private def dispatchOrAddCallback(runnable: CallbackRunnable[T]): Unit = { + getState match { + case r: Try[_] => runnable.executeWithValue(r.asInstanceOf[Try[T]]) + case _: DefaultPromise[_] => compressedRoot().dispatchOrAddCallback(runnable) + case listeners: List[_] => if (updateState(listeners, runnable :: listeners)) () else dispatchOrAddCallback(runnable) + } + } + + /** Link this promise to the root of another promise using `link()`. Should only be + * be called by Future.flatMap. + */ + protected[concurrent] final def linkRootOf(target: DefaultPromise[T]): Unit = link(target.compressedRoot()) + + /** Link this promise to another promise so that both promises share the same + * externally-visible state. Depending on the current state of this promise, this + * may involve different things. For example, any onComplete listeners will need + * to be transferred. + * + * If this promise is already completed, then the same effect as linking - + * sharing the same completed value - is achieved by simply sending this + * promise's result to the target promise. + */ + @tailrec + private def link(target: DefaultPromise[T]): Unit = if (this ne target) { + getState match { + case r: Try[_] => + if (!target.tryComplete(r.asInstanceOf[Try[T]])) { + // Currently linking is done from Future.flatMap, which should ensure only + // one promise can be completed. Therefore this situation is unexpected. + throw new IllegalStateException("Cannot link completed promises together") + } + case _: DefaultPromise[_] => + compressedRoot().link(target) + case listeners: List[_] => if (updateState(listeners, target)) { + if (!listeners.isEmpty) listeners.asInstanceOf[List[CallbackRunnable[T]]].foreach(target.dispatchOrAddCallback(_)) + } else link(target) + } } } diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index 7c14ed3a9e..62528e15fa 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -159,7 +159,7 @@ object BigDecimal { * @author Stephane Micheloud * @version 1.0 */ -@deprecatedInheritance("This class will me made final.", "2.10.0") +@deprecatedInheritance("This class will be made final.", "2.10.0") class BigDecimal( val bigDecimal: BigDec, val mc: MathContext) diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index fdba0ec716..58838f13a7 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -114,7 +114,7 @@ object BigInt { * @author Martin Odersky * @version 1.0, 15/07/2003 */ -@deprecatedInheritance("This class will me made final.", "2.10.0") +@deprecatedInheritance("This class will be made final.", "2.10.0") class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericConversions with Serializable { /** Returns the hash code for this BigInt. */ override def hashCode(): Int = diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index cc145134c4..d04e5e48fe 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -72,7 +72,7 @@ private[scala] trait PropertiesTrait { * it is an RC, Beta, etc. or was built from source, or if the version * cannot be read. */ - val releaseVersion = + val releaseVersion = for { v <- scalaPropOrNone("maven.version.number") if !(v endsWith "-SNAPSHOT") @@ -86,7 +86,7 @@ private[scala] trait PropertiesTrait { * @return Some(version) if this is a non-final version, None if this * is a final release or the version cannot be read. */ - val developmentVersion = + val developmentVersion = for { v <- scalaPropOrNone("maven.version.number") if v endsWith "-SNAPSHOT" @@ -119,8 +119,7 @@ private[scala] trait PropertiesTrait { */ def lineSeparator = propOrElse("line.separator", "\n") - /** Various well-known properties. - */ + /* Various well-known properties. */ def javaClassPath = propOrEmpty("java.class.path") def javaHome = propOrEmpty("java.home") def javaVendor = propOrEmpty("java.vendor") @@ -129,6 +128,10 @@ private[scala] trait PropertiesTrait { def javaVmName = propOrEmpty("java.vm.name") def javaVmVendor = propOrEmpty("java.vm.vendor") def javaVmVersion = propOrEmpty("java.vm.version") + // this property must remain less-well-known until 2.11 + private def javaSpecVersion = propOrEmpty("java.specification.version") + //private def javaSpecVendor = propOrEmpty("java.specification.vendor") + //private def javaSpecName = propOrEmpty("java.specification.name") def osName = propOrEmpty("os.name") def scalaHome = propOrEmpty("scala.home") def tmpDir = propOrEmpty("java.io.tmpdir") @@ -136,10 +139,13 @@ private[scala] trait PropertiesTrait { def userHome = propOrEmpty("user.home") def userName = propOrEmpty("user.name") - /** Some derived values. - */ + /* Some derived values. */ + /** Returns `true` iff the underlying operating system is a version of Microsoft Windows. */ def isWin = osName startsWith "Windows" - def isMac = javaVendor startsWith "Apple" + // See http://mail.openjdk.java.net/pipermail/macosx-port-dev/2012-November/005148.html for + // the reason why we don't follow developer.apple.com/library/mac/#technotes/tn2002/tn2110. + /** Returns `true` iff the underlying operating system is a version of Apple Mac OSX. */ + def isMac = osName startsWith "Mac OS X" // This is looking for javac, tools.jar, etc. // Tries JDK_HOME first, then the more common but likely jre JAVA_HOME, @@ -150,18 +156,29 @@ private[scala] trait PropertiesTrait { def scalaCmd = if (isWin) "scala.bat" else "scala" def scalacCmd = if (isWin) "scalac.bat" else "scalac" - /** Can the java version be determined to be at least as high as the argument? - * Hard to properly future proof this but at the rate 1.7 is going we can leave - * the issue for our cyborg grandchildren to solve. + /** Compares the given specification version to the specification version of the platform. + * + * @param version a specification version of the form "major.minor" + * @return `true` iff the specification version of the current runtime + * is equal to or higher than the version denoted by the given string. + * @throws NumberFormatException if the given string is not a version string + * + * @example {{{ + * // In this example, the runtime's Java specification is assumed to be at version 1.7. + * isJavaAtLeast("1.6") // true + * isJavaAtLeast("1.7") // true + * isJavaAtLeast("1.8") // false + * }} */ - def isJavaAtLeast(version: String) = { - val okVersions = version match { - case "1.5" => List("1.5", "1.6", "1.7") - case "1.6" => List("1.6", "1.7") - case "1.7" => List("1.7") - case _ => Nil + def isJavaAtLeast(version: String): Boolean = { + def parts(x: String) = { + val i = x.indexOf('.') + if (i < 0) throw new NumberFormatException("Not a version: " + x) + (x.substring(0, i), x.substring(i+1, x.length)) } - okVersions exists (javaVersion startsWith _) + val (v, _v) = parts(version) + val (s, _s) = parts(javaSpecVersion) + s.toInt >= v.toInt && _s.toInt >= _v.toInt } // provide a main method so version info can be obtained by running this diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala index e2dac2fd55..8fcaa6423c 100644 --- a/src/partest/scala/tools/partest/DirectTest.scala +++ b/src/partest/scala/tools/partest/DirectTest.scala @@ -6,6 +6,7 @@ package scala.tools.partest import scala.tools.nsc._ +import settings.ScalaVersion import io.Directory import util.{ SourceFile, BatchSourceFile, CommandLineParser } import reporters.{Reporter, ConsoleReporter} @@ -101,4 +102,30 @@ abstract class DirectTest extends App { final def log(msg: => Any) { if (isDebug) Console.err println msg } + + /** + * Run a test only if the current java version is at least the version specified. + */ + def testUnderJavaAtLeast[A](version: String)(yesRun: =>A) = new TestUnderJavaAtLeast(version, { yesRun }) + + class TestUnderJavaAtLeast[A](version: String, yesRun: => A) { + val javaVersion = System.getProperty("java.specification.version") + + // the "ScalaVersion" class parses Java specification versions just fine + val requiredJavaVersion = ScalaVersion(version) + val executingJavaVersion = ScalaVersion(javaVersion) + val shouldRun = executingJavaVersion >= requiredJavaVersion + val preamble = if (shouldRun) "Attempting" else "Doing fallback for" + + def logInfo() = log(s"$preamble java $version specific test under java version $javaVersion") + + /* + * If the current java version is at least 'version' then 'yesRun' is evaluated + * otherwise 'fallback' is + */ + def otherwise(fallback: =>A): A = { + logInfo() + if (shouldRun) yesRun else fallback + } + } } diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala index 0199400ada..dc40f9f81b 100644 --- a/src/partest/scala/tools/partest/PartestTask.scala +++ b/src/partest/scala/tools/partest/PartestTask.scala @@ -19,6 +19,7 @@ import java.lang.reflect.Method import org.apache.tools.ant.Task import org.apache.tools.ant.types.{Path, Reference, FileSet} import org.apache.tools.ant.types.Commandline.Argument +import scala.tools.ant.ScalaTask /** An Ant task to execute the Scala test suite (NSC). * @@ -54,7 +55,7 @@ import org.apache.tools.ant.types.Commandline.Argument * * @author Philippe Haller */ -class PartestTask extends Task with CompilationPathProperty { +class PartestTask extends Task with CompilationPathProperty with ScalaTask { def addConfiguredPosTests(input: FileSet) { posFiles = Some(input) @@ -406,7 +407,7 @@ class PartestTask extends Task with CompilationPathProperty { val allFailures = _results map (_._2) sum val allFailedPaths = _results flatMap (_._3) - def f = if (errorOnFailed && allFailures > 0) (sys error _) else log(_: String) + def f = if (errorOnFailed && allFailures > 0) buildError(_: String) else log(_: String) def s = if (allFailures > 1) "s" else "" val msg = if (allFailures > 0) diff --git a/src/reflect/scala/reflect/internal/CapturedVariables.scala b/src/reflect/scala/reflect/internal/CapturedVariables.scala index 77909d9157..a3d2a8bd94 100644 --- a/src/reflect/scala/reflect/internal/CapturedVariables.scala +++ b/src/reflect/scala/reflect/internal/CapturedVariables.scala @@ -29,7 +29,7 @@ trait CapturedVariables { self: SymbolTable => def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) = if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe else if (erasedTypes) objectRefClass.tpe - else appliedType(objectRefClass, tpe) + else appliedType(objectRefClass, tpe1) if (vble.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass) else refType(refClass, ObjectRefClass) } diff --git a/src/reflect/scala/reflect/internal/ClassfileConstants.scala b/src/reflect/scala/reflect/internal/ClassfileConstants.scala index c198271fb1..eb70ff3f17 100644 --- a/src/reflect/scala/reflect/internal/ClassfileConstants.scala +++ b/src/reflect/scala/reflect/internal/ClassfileConstants.scala @@ -335,13 +335,8 @@ object ClassfileConstants { abstract class FlagTranslation { import Flags._ - private var isAnnotation = false - private var isClass = false - private def initFields(flags: Int) = { - isAnnotation = (flags & JAVA_ACC_ANNOTATION) != 0 - isClass = false - } - private def translateFlag(jflag: Int): Long = (jflag: @switch) match { + private def isAnnotation(flags: Int): Boolean = (flags & JAVA_ACC_ANNOTATION) != 0 + private def translateFlag(jflag: Int, isAnnotation: Boolean, isClass: Boolean): Long = (jflag: @switch) match { case JAVA_ACC_PRIVATE => PRIVATE case JAVA_ACC_PROTECTED => PROTECTED case JAVA_ACC_FINAL => FINAL @@ -351,31 +346,28 @@ object ClassfileConstants { case JAVA_ACC_INTERFACE => if (isAnnotation) 0L else TRAIT | INTERFACE | ABSTRACT case _ => 0L } - private def translateFlags(jflags: Int, baseFlags: Long): Long = { + private def translateFlags(jflags: Int, baseFlags: Long, isAnnotation: Boolean, isClass: Boolean): Long = { + def translateFlag0(jflags: Int): Long = translateFlag(jflags, isAnnotation, isClass) var res: Long = JAVA | baseFlags /** fast, elegant, maintainable, pick any two... */ - res |= translateFlag(jflags & JAVA_ACC_PRIVATE) - res |= translateFlag(jflags & JAVA_ACC_PROTECTED) - res |= translateFlag(jflags & JAVA_ACC_FINAL) - res |= translateFlag(jflags & JAVA_ACC_SYNTHETIC) - res |= translateFlag(jflags & JAVA_ACC_STATIC) - res |= translateFlag(jflags & JAVA_ACC_ABSTRACT) - res |= translateFlag(jflags & JAVA_ACC_INTERFACE) + res |= translateFlag0(jflags & JAVA_ACC_PRIVATE) + res |= translateFlag0(jflags & JAVA_ACC_PROTECTED) + res |= translateFlag0(jflags & JAVA_ACC_FINAL) + res |= translateFlag0(jflags & JAVA_ACC_SYNTHETIC) + res |= translateFlag0(jflags & JAVA_ACC_STATIC) + res |= translateFlag0(jflags & JAVA_ACC_ABSTRACT) + res |= translateFlag0(jflags & JAVA_ACC_INTERFACE) res } def classFlags(jflags: Int): Long = { - initFields(jflags) - isClass = true - translateFlags(jflags, 0) + translateFlags(jflags, 0, isAnnotation(jflags), isClass = true) } def fieldFlags(jflags: Int): Long = { - initFields(jflags) - translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0) + translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) MUTABLE else 0 , isAnnotation(jflags), isClass = false) } def methodFlags(jflags: Int): Long = { - initFields(jflags) - translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE else 0) + translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) BRIDGE else 0, isAnnotation(jflags), isClass = false) } } object FlagTranslation extends FlagTranslation { } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index e5d9e54a16..09d7af82d1 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -110,8 +110,10 @@ trait Definitions extends api.StandardDefinitions { /** Is symbol a numeric value class? */ def isNumericValueClass(sym: Symbol) = ScalaNumericValueClasses contains sym - def isGetClass(sym: Symbol) = - (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss) + def isGetClass(sym: Symbol) = ( + sym.name == nme.getClass_ // this condition is for performance only, this is called from `Typer#stabliize`. + && getClassMethods(sym) + ) lazy val UnitClass = valueClassSymbol(tpnme.Unit) lazy val ByteClass = valueClassSymbol(tpnme.Byte) @@ -805,6 +807,12 @@ trait Definitions extends api.StandardDefinitions { lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype) lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor) + lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ ( + ScalaValueClasses map (_.tpe member nme.getClass_) + ) + + lazy val getClassMethods: Set[Symbol] = primitiveGetClassMethods + Object_getClass + // A type function from T => Class[U], used to determine the return // type of getClass calls. The returned type is: // @@ -975,6 +983,7 @@ trait Definitions extends api.StandardDefinitions { lazy val ThrowsClass = requiredClass[scala.throws[_]] lazy val TransientAttr = requiredClass[scala.transient] lazy val UncheckedClass = requiredClass[scala.unchecked] + lazy val UncheckedBoundsClass = getClassIfDefined("scala.reflect.internal.annotations.uncheckedBounds") lazy val UnspecializedClass = requiredClass[scala.annotation.unspecialized] lazy val VolatileAttr = requiredClass[scala.volatile] diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index 43902c1930..9a8dee1f15 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -443,7 +443,12 @@ trait Importers extends api.Importers { self: SymbolTable => } }) tryFixup() - mytree + // we have to be careful with position import as some shared trees + // like EmptyTree, emptyValDef don't support position assignment + if (tree.pos != NoPosition) + mytree.setPos(importPosition(tree.pos)) + else + mytree } def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef] diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index 80d247c0ea..35cb749ede 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -564,6 +564,8 @@ trait Printers extends api.Printers { self: SymbolTable => case refTree: RefTree => if (tree.symbol.name != refTree.name) print("[", tree.symbol, " aka ", refTree.name, "]") else print(tree.symbol) + case defTree: DefTree => + print(tree.symbol) case _ => print(tree.symbol.name) } diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index b782353ed3..539d19140c 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -42,4 +42,35 @@ trait StdAttachments { * (but think thrice before using that API - see the discussion at https://github.com/scala/scala/pull/1639). */ case object SuppressMacroExpansionAttachment + + /** Suppresses macro expansion of the tree by putting SuppressMacroExpansionAttachment on it. + */ + def suppressMacroExpansion(tree: Tree) = tree.updateAttachment(SuppressMacroExpansionAttachment) + + /** Unsuppresses macro expansion of the tree by removing SuppressMacroExpansionAttachment from it and its children. + */ + def unsuppressMacroExpansion(tree: Tree): Tree = { + tree.removeAttachment[SuppressMacroExpansionAttachment.type] + tree match { + // see the comment to `isMacroExpansionSuppressed` to learn why we need + // a special traversal strategy here + case Apply(fn, _) => unsuppressMacroExpansion(fn) + case TypeApply(fn, _) => unsuppressMacroExpansion(fn) + case _ => // do nothing + } + tree + } + + /** Determines whether a tree should not be expanded, because someone has put SuppressMacroExpansionAttachment on it or one of its children. + */ + def isMacroExpansionSuppressed(tree: Tree): Boolean = + if (tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined) true + else tree match { + // we have to account for the fact that during typechecking an expandee might become wrapped, + // i.e. surrounded by an inferred implicit argument application or by an inferred type argument application. + // in that case the expandee itself will no longer be suppressed and we need to look at the core + case Apply(fn, _) => isMacroExpansionSuppressed(fn) + case TypeApply(fn, _) => isMacroExpansionSuppressed(fn) + case _ => false + } } diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 2585b541ed..53b9b1d88e 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1526,15 +1526,18 @@ trait Trees extends api.Trees { self: SymbolTable => } } - private lazy val duplicator = new Transformer { + private lazy val duplicator = new Duplicator(focusPositions = true) + private class Duplicator(focusPositions: Boolean) extends Transformer { override val treeCopy = newStrictTreeCopier override def transform(t: Tree) = { val t1 = super.transform(t) - if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus + if ((t1 ne t) && t1.pos.isRange && focusPositions) t1 setPos t.pos.focus t1 } } + def duplicateAndKeepPositions(tree: Tree) = new Duplicator(focusPositions = false) transform tree + // ------ copiers ------------------------------------------- def copyDefDef(tree: Tree)( diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 0cc2b91a44..cd9f3d23c9 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1172,6 +1172,14 @@ trait Types extends api.Types { self: SymbolTable => continue = false val bcs0 = baseClasses var bcs = bcs0 + // omit PRIVATE LOCALS unless selector class is contained in class owning the def. + def admitPrivateLocal(owner: Symbol): Boolean = { + val selectorClass = this match { + case tt: ThisType => tt.sym // SI-7507 the first base class is not necessarily the selector class. + case _ => bcs0.head + } + selectorClass.hasTransOwner(owner) + } while (!bcs.isEmpty) { val decls = bcs.head.info.decls var entry = decls.lookupEntry(name) @@ -1181,10 +1189,10 @@ trait Types extends api.Types { self: SymbolTable => if ((flags & required) == required) { val excl = flags & excluded if (excl == 0L && - (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. + ( (bcs eq bcs0) || (flags & PrivateLocal) != PrivateLocal || - (bcs0.head.hasTransOwner(bcs.head)))) { + admitPrivateLocal(bcs.head))) { if (name.isTypeName || stableOnly && sym.isStable) { if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start) if (suspension ne null) suspension foreach (_.suspended = false) @@ -7305,6 +7313,12 @@ trait Types extends api.Types { self: SymbolTable => else (ps :+ SerializableClass.tpe).toList ) + /** Adds the @uncheckedBound annotation if the given `tp` has type arguments */ + final def uncheckedBounds(tp: Type): Type = { + if (tp.typeArgs.isEmpty || UncheckedBoundsClass == NoSymbol) tp // second condition for backwards compatibilty with older scala-reflect.jar + else tp.withAnnotation(AnnotationInfo marker UncheckedBoundsClass.tpe) + } + /** Members of the given class, other than those inherited * from Any or AnyRef. */ diff --git a/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala b/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala new file mode 100644 index 0000000000..a44bb54734 --- /dev/null +++ b/src/reflect/scala/reflect/internal/annotations/uncheckedBounds.scala @@ -0,0 +1,13 @@ +package scala.reflect +package internal +package annotations + +/** + * An annotation that designates the annotated type should not be checked for violations of + * type parameter bounds in the `refchecks` phase of the compiler. This can be used by synthesized + * code the uses an inferred type of an expression as the type of an artifict val/def (for example, + * a temporary value introduced by an ANF transform). See [[https://issues.scala-lang.org/browse/SI-7694]]. + * + * @since 2.10.3 + */ +final class uncheckedBounds extends scala.annotation.StaticAnnotation diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index ccc727451c..22fe7f098c 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -19,7 +19,7 @@ import scala.collection.mutable.{ HashMap, ListBuffer } import internal.Flags._ //import scala.tools.nsc.util.ScalaClassLoader //import scala.tools.nsc.util.ScalaClassLoader._ -import ReflectionUtils.{staticSingletonInstance, innerSingletonInstance} +import ReflectionUtils.{staticSingletonInstance, innerSingletonInstance, scalacShouldntLoadClass} import scala.language.existentials import scala.runtime.{ScalaRunTime, BoxesRunTime} import scala.reflect.internal.util.Collections._ @@ -567,15 +567,10 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni loadBytes[Array[String]]("scala.reflect.ScalaLongSignature") match { case Some(slsig) => info(s"unpickling Scala $clazz and $module with long Scala signature") - val byteSegments = slsig map (_.getBytes) - val lens = byteSegments map ByteCodecs.decode - val bytes = Array.ofDim[Byte](lens.sum) - var len = 0 - for ((bs, l) <- byteSegments zip lens) { - bs.copyToArray(bytes, len, l) - len += l - } - unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName) + val encoded = slsig flatMap (_.getBytes) + val len = ByteCodecs.decode(encoded) + val decoded = encoded.take(len) + unpickler.unpickle(decoded, 0, clazz, module, jclazz.getName) case None => // class does not have a Scala signature; it's a Java class info("translating reflection info for Java " + jclazz) //debug @@ -678,8 +673,10 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni val parents = try { parentsLevel += 1 val jsuperclazz = jclazz.getGenericSuperclass - val superclazz = if (jsuperclazz == null) AnyClass.tpe else typeToScala(jsuperclazz) - superclazz :: (jclazz.getGenericInterfaces.toList map typeToScala) + val ifaces = jclazz.getGenericInterfaces.toList map typeToScala + val isAnnotation = (jclazz.getModifiers & JAVA_ACC_ANNOTATION) != 0 + if (isAnnotation) AnnotationClass.tpe :: ClassfileAnnotationClass.tpe :: ifaces + else (if (jsuperclazz == null) AnyClass.tpe else typeToScala(jsuperclazz)) :: ifaces } finally { parentsLevel -= 1 } @@ -691,6 +688,11 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni def enter(sym: Symbol, mods: Int) = (if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym + def enterEmptyCtorIfNecessary(): Unit = { + if (jclazz.getConstructors.isEmpty) + clazz.info.decls.enter(clazz.newClassConstructor(NoPosition)) + } + for (jinner <- jclazz.getDeclaredClasses) { jclassAsScala(jinner) // inner class is entered as a side-effect // no need to call enter explicitly @@ -707,6 +709,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni for (jconstr <- jclazz.getConstructors) enter(jconstrAsScala(jconstr), jconstr.getModifiers) + enterEmptyCtorIfNecessary() + } :: pendingLoadActions if (parentsLevel == 0) { @@ -952,7 +956,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni val cls = if (jclazz.isMemberClass && !nme.isImplClassName(jname)) lookupClass - else if (jclazz.isLocalClass0 || isInvalidClassName(jname)) + else if (jclazz.isLocalClass0 || scalacShouldntLoadClass(jname)) // local classes and implementation classes not preserved by unpickling - treat as Java // // upd. but only if they cannot be loaded as top-level classes diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala index 33ad6d2430..ffed3cc38e 100644 --- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala +++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala @@ -76,4 +76,10 @@ private[scala] object ReflectionUtils { accessor setAccessible true accessor invoke outer } + + def isTraitImplementation(fileName: String) = fileName endsWith "$class.class" + + def scalacShouldntLoadClassfile(fileName: String) = isTraitImplementation(fileName) + + def scalacShouldntLoadClass(name: scala.reflect.internal.SymbolTable#Name) = scalacShouldntLoadClassfile(name + ".class") } diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala index 61663f6181..b895092639 100644 --- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala +++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala @@ -4,6 +4,7 @@ package runtime import internal.Flags import java.lang.{Class => jClass, Package => jPackage} import scala.collection.mutable +import scala.reflect.runtime.ReflectionUtils.scalacShouldntLoadClass private[reflect] trait SymbolLoaders { self: SymbolTable => @@ -89,14 +90,6 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => } } - /** Is the given name valid for a top-level class? We exclude names with embedded $-signs, because - * these are nested classes or anonymous classes, - */ - def isInvalidClassName(name: Name) = { - val dp = name pos '$' - 0 < dp && dp < (name.length - 1) - } - class PackageScope(pkgClass: Symbol) extends Scope(initFingerPrints = -1L) // disable fingerprinting as we do not know entries beforehand with SynchronizedScope { assert(pkgClass.isType) @@ -106,7 +99,7 @@ private[reflect] trait SymbolLoaders { self: SymbolTable => val e = super.lookupEntry(name) if (e != null) e - else if (isInvalidClassName(name) || (negatives contains name)) + else if (scalacShouldntLoadClass(name) || (negatives contains name)) null else { val path = diff --git a/test/files/jvm/duration-tck.scala b/test/files/jvm/duration-tck.scala index d0f13816a6..b2573448c7 100644 --- a/test/files/jvm/duration-tck.scala +++ b/test/files/jvm/duration-tck.scala @@ -176,8 +176,9 @@ object Test extends App { Thread.sleep(1.second.toMillis) - { val l = dead.timeLeft; assert(l <= 1.second, s"$l > 1.second") } - { val l = dead2.timeLeft; assert(l <= 1.second, s"$l > 1.second") } + // unfortunately it can happen that the sleep() returns early without throwing + { val l = dead.timeLeft; assert(l <= 1100.millis, s"$l > 1100.millis") } + { val l = dead2.timeLeft; assert(l <= 1100.millis, s"$l > 1100.millis") } // test integer mul/div diff --git a/test/files/jvm/scala-concurrent-tck.scala b/test/files/jvm/scala-concurrent-tck.scala index b2b4183564..6e2b8ca033 100644 --- a/test/files/jvm/scala-concurrent-tck.scala +++ b/test/files/jvm/scala-concurrent-tck.scala @@ -15,21 +15,17 @@ import scala.reflect.{ classTag, ClassTag } import scala.tools.partest.TestUtil.intercept trait TestBase { - - def once(body: (() => Unit) => Unit) { - val sv = new SyncVar[Boolean] - body(() => sv put true) - sv.take(2000) + trait Done { def apply(proof: => Boolean): Unit } + def once(body: Done => Unit) { + import java.util.concurrent.{ LinkedBlockingQueue, TimeUnit } + val q = new LinkedBlockingQueue[Try[Boolean]] + body(new Done { + def apply(proof: => Boolean): Unit = q offer Try(proof) + }) + assert(q.poll(2000, TimeUnit.MILLISECONDS).get) + // Check that we don't get more than one completion + assert(q.poll(50, TimeUnit.MILLISECONDS) eq null) } - - // def assert(cond: => Boolean) { - // try { - // Predef.assert(cond) - // } catch { - // case e => e.printStackTrace() - // } - // } - } @@ -39,99 +35,52 @@ trait FutureCallbacks extends TestBase { def testOnSuccess(): Unit = once { done => var x = 0 - val f = future { - x = 1 - } - f onSuccess { - case _ => - done() - assert(x == 1) - } + val f = future { x = 1 } + f onSuccess { case _ => done(x == 1) } } def testOnSuccessWhenCompleted(): Unit = once { done => var x = 0 - val f = future { - x = 1 - } + val f = future { x = 1 } f onSuccess { - case _ => - assert(x == 1) + case _ if x == 1 => x = 2 - f onSuccess { - case _ => - assert(x == 2) - done() - } + f onSuccess { case _ => done(x == 2) } } } def testOnSuccessWhenFailed(): Unit = once { done => - val f = future[Unit] { - done() - throw new Exception - } - f onSuccess { - case _ => assert(false) - } + val f = future[Unit] { throw new Exception } + f onSuccess { case _ => done(false) } + f onFailure { case _ => done(true) } } def testOnFailure(): Unit = once { done => - var x = 0 - val f = future[Unit] { - x = 1 - throw new Exception - } - f onSuccess { - case _ => - done() - assert(false) - } - f onFailure { - case _ => - done() - assert(x == 1) - } + val f = future[Unit] { throw new Exception } + f onSuccess { case _ => done(false) } + f onFailure { case _ => done(true) } } def testOnFailureWhenSpecialThrowable(num: Int, cause: Throwable): Unit = once { done => - val f = future[Unit] { - throw cause - } - f onSuccess { - case _ => - done() - assert(false) - } + val f = future[Unit] { throw cause } + f onSuccess { case _ => done(false) } f onFailure { - case e: ExecutionException if (e.getCause == cause) => - done() - case _ => - done() - assert(false) + case e: ExecutionException if e.getCause == cause => done(true) + case _ => done(false) } } def testOnFailureWhenTimeoutException(): Unit = once { done => - val f = future[Unit] { - throw new TimeoutException() - } - f onSuccess { - case _ => - done() - assert(false) - } + val f = future[Unit] { throw new TimeoutException() } + f onSuccess { case _ => done(false) } f onFailure { - case e: TimeoutException => - done() - case other => - done() - assert(false) + case e: TimeoutException => done(true) + case _ => done(false) } } @@ -151,7 +100,6 @@ trait FutureCallbacks extends TestBase { //testOnFailureWhenSpecialThrowable(7, new InterruptedException) testThatNestedCallbacksDoNotYieldStackOverflow() testOnFailureWhenTimeoutException() - } @@ -162,207 +110,120 @@ trait FutureCombinators extends TestBase { done => val f = future { 5 } val g = f map { x => "result: " + x } - g onSuccess { - case s => - done() - assert(s == "result: 5") - } - g onFailure { - case _ => - done() - assert(false) - } + g onSuccess { case s => done(s == "result: 5") } + g onFailure { case _ => done(false) } } def testMapFailure(): Unit = once { done => - val f = future { - throw new Exception("exception message") - } + val f = future[Unit] { throw new Exception("exception message") } val g = f map { x => "result: " + x } - g onSuccess { - case _ => - done() - assert(false) - } - g onFailure { - case t => - done() - assert(t.getMessage() == "exception message") - } + g onSuccess { case _ => done(false) } + g onFailure { case t => done(t.getMessage() == "exception message") } } def testMapSuccessPF(): Unit = once { done => val f = future { 5 } val g = f map { case r => "result: " + r } - g onSuccess { - case s => - done() - assert(s == "result: 5") - } - g onFailure { - case _ => - done() - assert(false) - } + g onSuccess { case s => done(s == "result: 5") } + g onFailure { case _ => done(false) } } def testTransformSuccess(): Unit = once { done => val f = future { 5 } val g = f.transform(r => "result: " + r, identity) - g onSuccess { - case s => - done() - assert(s == "result: 5") - } - g onFailure { - case _ => - done() - assert(false) - } + g onSuccess { case s => done(s == "result: 5") } + g onFailure { case _ => done(false) } } def testTransformSuccessPF(): Unit = once { done => val f = future { 5 } val g = f.transform( { case r => "result: " + r }, identity) - g onSuccess { - case s => - done() - assert(s == "result: 5") - } - g onFailure { - case _ => - done() - assert(false) - } + g onSuccess { case s => done(s == "result: 5") } + g onFailure { case _ => done(false) } + } + +def testTransformFailure(): Unit = once { + done => + val transformed = new Exception("transformed") + val f = future { throw new Exception("expected") } + val g = f.transform(identity, _ => transformed) + g onSuccess { case _ => done(false) } + g onFailure { case e => done(e eq transformed) } + } + + def testTransformFailurePF(): Unit = once { + done => + val e = new Exception("expected") + val transformed = new Exception("transformed") + val f = future[Unit] { throw e } + val g = f.transform(identity, { case `e` => transformed }) + g onSuccess { case _ => done(false) } + g onFailure { case e => done(e eq transformed) } } def testFoldFailure(): Unit = once { done => - val f = future { - throw new Exception("exception message") - } + val f = future[Unit] { throw new Exception("expected") } val g = f.transform(r => "result: " + r, identity) - g onSuccess { - case _ => - done() - assert(false) - } - g onFailure { - case t => - done() - assert(t.getMessage() == "exception message") - } + g onSuccess { case _ => done(false) } + g onFailure { case t => done(t.getMessage() == "expected") } } def testFlatMapSuccess(): Unit = once { done => val f = future { 5 } val g = f flatMap { _ => future { 10 } } - g onSuccess { - case x => - done() - assert(x == 10) - } - g onFailure { - case _ => - done() - assert(false) - } + g onSuccess { case x => done(x == 10) } + g onFailure { case _ => done(false) } } def testFlatMapFailure(): Unit = once { done => - val f = future { - throw new Exception("exception message") - } + val f = future[Unit] { throw new Exception("expected") } val g = f flatMap { _ => future { 10 } } - g onSuccess { - case _ => - done() - assert(false) - } - g onFailure { - case t => - done() - assert(t.getMessage() == "exception message") - } + g onSuccess { case _ => done(false) } + g onFailure { case t => done(t.getMessage() == "expected") } } def testFilterSuccess(): Unit = once { done => val f = future { 4 } val g = f filter { _ % 2 == 0 } - g onSuccess { - case x: Int => - done() - assert(x == 4) - } - g onFailure { - case _ => - done() - assert(false) - } + g onSuccess { case x: Int => done(x == 4) } + g onFailure { case _ => done(false) } } def testFilterFailure(): Unit = once { done => val f = future { 4 } val g = f filter { _ % 2 == 1 } - g onSuccess { - case x: Int => - done() - assert(false) - } + g onSuccess { case x: Int => done(false) } g onFailure { - case e: NoSuchElementException => - done() - assert(true) - case _ => - done() - assert(false) + case e: NoSuchElementException => done(true) + case _ => done(false) } } def testCollectSuccess(): Unit = once { done => val f = future { -5 } - val g = f collect { - case x if x < 0 => -x - } - g onSuccess { - case x: Int => - done() - assert(x == 5) - } - g onFailure { - case _ => - done() - assert(false) - } + val g = f collect { case x if x < 0 => -x } + g onSuccess { case x: Int => done(x == 5) } + g onFailure { case _ => done(false) } } def testCollectFailure(): Unit = once { done => val f = future { -5 } - val g = f collect { - case x if x > 0 => x * 2 - } - g onSuccess { - case _ => - done() - assert(false) - } + val g = f collect { case x if x > 0 => x * 2 } + g onSuccess { case _ => done(false) } g onFailure { - case e: NoSuchElementException => - done() - assert(true) - case _ => - done() - assert(false) + case e: NoSuchElementException => done(true) + case _ => done(false) } } @@ -376,16 +237,8 @@ trait FutureCombinators extends TestBase { f foreach { x => p.success(x * 2) } val g = p.future - g.onSuccess { - case res: Int => - done() - assert(res == 10) - } - g.onFailure { - case _ => - done() - assert(false) - } + g.onSuccess { case res: Int => done(res == 10) } + g.onFailure { case _ => done(false) } } def testForeachFailure(): Unit = once { @@ -396,16 +249,8 @@ trait FutureCombinators extends TestBase { f onFailure { case _ => p.failure(new Exception) } val g = p.future - g.onSuccess { - case _ => - done() - assert(false) - } - g.onFailure { - case _ => - done() - assert(true) - } + g.onSuccess { case _ => done(false) } + g.onFailure { case _ => done(true) } } def testRecoverSuccess(): Unit = once { @@ -415,18 +260,9 @@ trait FutureCombinators extends TestBase { throw cause } recover { case re: RuntimeException => - "recovered" - } - f onSuccess { - case x => - done() - assert(x == "recovered") - } - f onFailure { case any => - done() - assert(false) - } - f + "recovered" } + f onSuccess { case x => done(x == "recovered") } + f onFailure { case any => done(false) } } def testRecoverFailure(): Unit = once { @@ -437,15 +273,8 @@ trait FutureCombinators extends TestBase { } recover { case te: TimeoutException => "timeout" } - f onSuccess { - case x => - done() - assert(false) - } - f onFailure { case any => - done() - assert(any == cause) - } + f onSuccess { case _ => done(false) } + f onFailure { case any => done(any == cause) } } def testRecoverWithSuccess(): Unit = once { @@ -457,15 +286,8 @@ trait FutureCombinators extends TestBase { case re: RuntimeException => future { "recovered" } } - f onSuccess { - case x => - done() - assert(x == "recovered") - } - f onFailure { case any => - done() - assert(false) - } + f onSuccess { case x => done(x == "recovered") } + f onFailure { case any => done(false) } } def testRecoverWithFailure(): Unit = once { @@ -477,15 +299,8 @@ trait FutureCombinators extends TestBase { case te: TimeoutException => future { "timeout" } } - f onSuccess { - case x => - done() - assert(false) - } - f onFailure { case any => - done() - assert(any == cause) - } + f onSuccess { case x => done(false) } + f onFailure { case any => done(any == cause) } } def testZipSuccess(): Unit = once { @@ -493,52 +308,28 @@ trait FutureCombinators extends TestBase { val f = future { 5 } val g = future { 6 } val h = f zip g - h onSuccess { - case (l: Int, r: Int) => - done() - assert(l+r == 11) - } - h onFailure { - case _ => - done() - assert(false) - } + h onSuccess { case (l: Int, r: Int) => done(l+r == 11) } + h onFailure { case _ => done(false) } } def testZipFailureLeft(): Unit = once { done => - val cause = new Exception("exception message") + val cause = new Exception("expected") val f = future { throw cause } val g = future { 6 } val h = f zip g - h onSuccess { - case _ => - done() - assert(false) - } - h onFailure { - case e: Exception => - done() - assert(e.getMessage == "exception message") - } + h onSuccess { case _ => done(false) } + h onFailure { case e: Exception => done(e.getMessage == "expected") } } def testZipFailureRight(): Unit = once { done => - val cause = new Exception("exception message") + val cause = new Exception("expected") val f = future { 5 } val g = future { throw cause } val h = f zip g - h onSuccess { - case _ => - done() - assert(false) - } - h onFailure { - case e: Exception => - done() - assert(e.getMessage == "exception message") - } + h onSuccess { case _ => done(false) } + h onFailure { case e: Exception => done(e.getMessage == "expected") } } def testFallbackTo(): Unit = once { @@ -546,17 +337,8 @@ trait FutureCombinators extends TestBase { val f = future { sys.error("failed") } val g = future { 5 } val h = f fallbackTo g - - h onSuccess { - case x: Int => - done() - assert(x == 5) - } - h onFailure { - case _ => - done() - assert(false) - } + h onSuccess { case x: Int => done(x == 5) } + h onFailure { case _ => done(false) } } def testFallbackToFailure(): Unit = once { @@ -566,16 +348,8 @@ trait FutureCombinators extends TestBase { val g = future { throw cause } val h = f fallbackTo g - h onSuccess { - case _ => - done() - assert(false) - } - h onFailure { - case e: Exception => - done() - assert(e == cause) - } + h onSuccess { case _ => done(false) } + h onFailure { case e => done(e eq cause) } } testMapSuccess() @@ -597,6 +371,8 @@ trait FutureCombinators extends TestBase { testZipFailureRight() testFallbackTo() testFallbackToFailure() + testTransformSuccess() + testTransformSuccessPF() } @@ -606,40 +382,26 @@ trait FutureProjections extends TestBase { def testFailedFailureOnComplete(): Unit = once { done => val cause = new RuntimeException - val f = future { - throw cause - } + val f = future { throw cause } f.failed onComplete { - case Success(t) => - assert(t == cause) - done() - case Failure(t) => - assert(false) + case Success(t) => done(t == cause) + case Failure(t) => done(false) } } def testFailedFailureOnSuccess(): Unit = once { done => val cause = new RuntimeException - val f = future { - throw cause - } - f.failed onSuccess { - case t => - assert(t == cause) - done() - } + val f = future { throw cause } + f.failed onSuccess { case t => done(t == cause) } } def testFailedSuccessOnComplete(): Unit = once { done => val f = future { 0 } f.failed onComplete { - case Success(t) => - assert(false) - case Failure(t) => - assert(t.isInstanceOf[NoSuchElementException]) - done() + case Failure(_: NoSuchElementException) => done(true) + case _ => done(false) } } @@ -647,19 +409,17 @@ trait FutureProjections extends TestBase { done => val f = future { 0 } f.failed onFailure { - case nsee: NoSuchElementException => - done() + case e: NoSuchElementException => done(true) + case _ => done(false) } + f.failed onSuccess { case _ => done(false) } } def testFailedFailureAwait(): Unit = once { done => val cause = new RuntimeException - val f = future { - throw cause - } - assert(Await.result(f.failed, Duration(500, "ms")) == cause) - done() + val f = future { throw cause } + done(Await.result(f.failed, Duration(500, "ms")) == cause) } def testFailedSuccessAwait(): Unit = once { @@ -667,9 +427,10 @@ trait FutureProjections extends TestBase { val f = future { 0 } try { Await.result(f.failed, Duration(500, "ms")) - assert(false) + done(false) } catch { - case nsee: NoSuchElementException => done() + case nsee: NoSuchElementException => done(true) + case _: Throwable => done(false) } } @@ -682,8 +443,8 @@ trait FutureProjections extends TestBase { Await.ready(f, Duration.Zero) Await.ready(f, Duration(500, "ms")) Await.ready(f, Duration.Inf) - done() - } onFailure { case x => throw x } + done(true) + } onFailure { case x => done(throw x) } } def testAwaitNegativeDuration(): Unit = once { done => @@ -692,8 +453,8 @@ trait FutureProjections extends TestBase { intercept[TimeoutException] { Await.ready(f, Duration.Zero) } intercept[TimeoutException] { Await.ready(f, Duration.MinusInf) } intercept[TimeoutException] { Await.ready(f, Duration(-500, "ms")) } - done() - } onFailure { case x => throw x } + done(true) + } onFailure { case x => done(throw x) } } testFailedFailureOnComplete() @@ -704,7 +465,6 @@ trait FutureProjections extends TestBase { testFailedSuccessAwait() testAwaitPositiveDuration() testAwaitNegativeDuration() - } @@ -714,33 +474,25 @@ trait Blocking extends TestBase { def testAwaitSuccess(): Unit = once { done => val f = future { 0 } - Await.result(f, Duration(500, "ms")) - done() + done(Await.result(f, Duration(500, "ms")) == 0) } def testAwaitFailure(): Unit = once { done => val cause = new RuntimeException - val f = future { - throw cause - } + val f = future { throw cause } try { Await.result(f, Duration(500, "ms")) - assert(false) + done(false) } catch { - case t => - assert(t == cause) - done() + case t: Throwable => done(t == cause) } } def testFQCNForAwaitAPI(): Unit = once { done => - - assert(classOf[CanAwait].getName == "scala.concurrent.CanAwait") - assert(Await.getClass.getName == "scala.concurrent.Await") - - done() + done(classOf[CanAwait].getName == "scala.concurrent.CanAwait" && + Await.getClass.getName == "scala.concurrent.Await") } testAwaitSuccess() @@ -813,22 +565,26 @@ trait Promises extends TestBase { val p = promise[Int]() val f = p.future - f onSuccess { - case x => - done() - assert(x == 5) - } - f onFailure { - case any => - done() - assert(false) - } + f onSuccess { case x => done(x == 5) } + f onFailure { case any => done(false) } p.success(5) } - testSuccess() + def testFailure(): Unit = once { + done => + val e = new Exception("expected") + val p = promise[Int]() + val f = p.future + + f onSuccess { case x => done(false) } + f onFailure { case any => done(any eq e) } + + p.failure(e) + } + testSuccess() + testFailure() } @@ -888,11 +644,11 @@ trait CustomExecutionContext extends TestBase { val count = countExecs { implicit ec => blocking { once { done => - val f = future({ assertNoEC() })(defaultEC) + val f = future(assertNoEC())(defaultEC) f onSuccess { case _ => assertEC() - done() + done(true) } assertNoEC() } @@ -911,7 +667,7 @@ trait CustomExecutionContext extends TestBase { f onSuccess { case _ => assertEC() - done() + done(true) } } } @@ -935,15 +691,10 @@ trait CustomExecutionContext extends TestBase { Promise.successful(x + 1).future.map(addOne).map(addOne) } onComplete { case Failure(t) => - try { - throw new AssertionError("error in test: " + t.getMessage, t) - } finally { - done() - } + done(throw new AssertionError("error in test: " + t.getMessage, t)) case Success(x) => assertEC() - assert(x == 14) - done() + done(x == 14) } assertNoEC() } @@ -999,21 +750,14 @@ trait ExecutionContextPrepare extends TestBase { done => theLocal.set("secret") val fut = future { 42 } - fut onComplete { - case _ => - assert(theLocal.get == "secret") - done() - } + fut onComplete { case _ => done(theLocal.get == "secret") } } def testMap(): Unit = once { done => theLocal.set("secret2") val fut = future { 42 } - fut map { x => - assert(theLocal.get == "secret2") - done() - } + fut map { x => done(theLocal.get == "secret2") } } testOnComplete() diff --git a/test/files/neg/macro-abort.check b/test/files/neg/macro-abort.check new file mode 100644 index 0000000000..1e58add533 --- /dev/null +++ b/test/files/neg/macro-abort.check @@ -0,0 +1,4 @@ +Test_2.scala:2: error: aborted + Macros.abort + ^ +one error found diff --git a/test/files/neg/macro-abort/Macros_1.scala b/test/files/neg/macro-abort/Macros_1.scala new file mode 100644 index 0000000000..676c112098 --- /dev/null +++ b/test/files/neg/macro-abort/Macros_1.scala @@ -0,0 +1,9 @@ +import scala.language.experimental.macros +import scala.reflect.macros.Context + +object Macros { + def impl(c: Context) = { + c.abort(c.enclosingPosition, "aborted") + } + def abort = macro impl +}
\ No newline at end of file diff --git a/test/files/neg/macro-abort/Test_2.scala b/test/files/neg/macro-abort/Test_2.scala new file mode 100644 index 0000000000..1d0a7a25dc --- /dev/null +++ b/test/files/neg/macro-abort/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.abort +}
\ No newline at end of file diff --git a/test/files/neg/macro-exception.check b/test/files/neg/macro-exception.check new file mode 100644 index 0000000000..cee8b32ebd --- /dev/null +++ b/test/files/neg/macro-exception.check @@ -0,0 +1,7 @@ +Test_2.scala:2: error: exception during macro expansion: +java.lang.Exception + at Macros$.impl(Macros_1.scala:6) + + Macros.exception + ^ +one error found diff --git a/test/files/neg/macro-exception/Macros_1.scala b/test/files/neg/macro-exception/Macros_1.scala new file mode 100644 index 0000000000..60e4020aec --- /dev/null +++ b/test/files/neg/macro-exception/Macros_1.scala @@ -0,0 +1,9 @@ +import scala.language.experimental.macros +import scala.reflect.macros.Context + +object Macros { + def impl(c: Context) = { + throw new Exception() + } + def exception = macro impl +}
\ No newline at end of file diff --git a/test/files/neg/macro-exception/Test_2.scala b/test/files/neg/macro-exception/Test_2.scala new file mode 100644 index 0000000000..d82b21f2b2 --- /dev/null +++ b/test/files/neg/macro-exception/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.exception +}
\ No newline at end of file diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b.check b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check index 895e0dca50..cde3dbdbe8 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-b.check +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b.check @@ -1,5 +1,11 @@ -Impls_Macros_1.scala:12: error: overriding method foo in trait Foo of type (x: Int)Int; - macro method foo cannot override an abstract method - def foo(x: Int) = macro Impls.impl - ^ -one error found +Test_2.scala:3: error: anonymous class $anon inherits conflicting members: + macro method t in trait C of type ()Unit and + method t in trait A of type ()Unit +(Note: this can be resolved by declaring an override in anonymous class $anon.) + val c2 = new C with A {} + ^ +Test_2.scala:5: error: overriding macro method t in trait C of type ()Unit; + method t cannot override a macro + val c4 = new C with A { override def t(): Unit = () } + ^ +two errors found diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala index e43264f52f..f5b2555aa5 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Impls_Macros_1.scala @@ -1,13 +1,8 @@ -import scala.reflect.macros.{Context => Ctx} +import scala.reflect.macros.Context +import language.experimental.macros -object Impls { - def impl(c: Ctx)(x: c.Expr[Int]) = x -} +trait T { def t(): Unit } +trait A { def t(): Unit = () } -trait Foo { - def foo(x: Int): Int -} - -object Macros extends Foo { - def foo(x: Int) = macro Impls.impl -} +object Macro { def t(c: Context)(): c.Expr[Unit] = c.universe.reify(()) } +trait C extends T { self: A => override def t(): Unit = macro Macro.t } diff --git a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala index 08fff30baf..9b4c8e35f0 100644 --- a/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala +++ b/test/files/neg/macro-override-macro-overrides-abstract-method-b/Test_2.scala @@ -1,4 +1,6 @@ object Test extends App { - val designator: Foo = Macros - designator.foo(42) + val c1 = new A with C {} + val c2 = new C with A {} + val c3 = new C with A { override def t(): Unit = macro Macro.t } + val c4 = new C with A { override def t(): Unit = () } }
\ No newline at end of file diff --git a/test/files/neg/t6138.check b/test/files/neg/t6138.check new file mode 100644 index 0000000000..8fd9978248 --- /dev/null +++ b/test/files/neg/t6138.check @@ -0,0 +1,7 @@ +t6138.scala:4: error: ambiguous reference to overloaded definition, +both method getClass in object definitions of type (s: Int)Any +and method getClass in object definitions of type (s: String)Any +match argument types (Nothing) + getClass(???): String + ^ +one error found diff --git a/test/files/neg/t6138.scala b/test/files/neg/t6138.scala new file mode 100644 index 0000000000..2f45a46b1c --- /dev/null +++ b/test/files/neg/t6138.scala @@ -0,0 +1,5 @@ +object definitions { + def getClass(s: String): Any = ??? + def getClass(s: Int): Any = ??? + getClass(???): String +} diff --git a/test/files/neg/t7020.check b/test/files/neg/t7020.check new file mode 100644 index 0000000000..a869b12363 --- /dev/null +++ b/test/files/neg/t7020.check @@ -0,0 +1,17 @@ +t7020.scala:3: error: match may not be exhaustive. +It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _) + List(5) match { + ^ +t7020.scala:10: error: match may not be exhaustive. +It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _) + List(5) match { + ^ +t7020.scala:17: error: match may not be exhaustive. +It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _) + List(5) match { + ^ +t7020.scala:24: error: match may not be exhaustive. +It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _) + List(5) match { + ^ +four errors found diff --git a/test/files/neg/t7020.flags b/test/files/neg/t7020.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/t7020.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/neg/t7020.scala b/test/files/neg/t7020.scala new file mode 100644 index 0000000000..cc5421bab1 --- /dev/null +++ b/test/files/neg/t7020.scala @@ -0,0 +1,30 @@ +object Test { + // warning was non-deterministic + List(5) match { + case 1 :: Nil | 2 :: Nil => + case (x@(4 | 5 | 6)) :: Nil => + case 7 :: Nil => + case Nil => + } + + List(5) match { + case 1 :: Nil | 2 :: Nil => + case (x@(4 | 5 | 6)) :: Nil => + case 7 :: Nil => + case Nil => + } + + List(5) match { + case 1 :: Nil | 2 :: Nil => + case (x@(4 | 5 | 6)) :: Nil => + case 7 :: Nil => + case Nil => + } + + List(5) match { + case 1 :: Nil | 2 :: Nil => + case (x@(4 | 5 | 6)) :: Nil => + case 7 :: Nil => + case Nil => + } +} diff --git a/test/files/neg/t7473.check b/test/files/neg/t7473.check new file mode 100644 index 0000000000..bc8c29d463 --- /dev/null +++ b/test/files/neg/t7473.check @@ -0,0 +1,7 @@ +t7473.scala:6: error: '<-' expected but '=' found. + (for (x = Option(i); if x == j) yield 42) toList + ^ +t7473.scala:6: error: illegal start of simple expression + (for (x = Option(i); if x == j) yield 42) toList + ^ +two errors found diff --git a/test/files/neg/t7473.scala b/test/files/neg/t7473.scala new file mode 100644 index 0000000000..593231d5f2 --- /dev/null +++ b/test/files/neg/t7473.scala @@ -0,0 +1,7 @@ + +object Foo { + val i,j = 3 + //for (x = Option(i); if x == j) yield 42 //t7473.scala:4: error: '<-' expected but '=' found. + // evil postfix! + (for (x = Option(i); if x == j) yield 42) toList +} diff --git a/test/files/neg/t7507.check b/test/files/neg/t7507.check new file mode 100644 index 0000000000..d402869fd4 --- /dev/null +++ b/test/files/neg/t7507.check @@ -0,0 +1,4 @@ +t7507.scala:6: error: value bippy in trait Cake cannot be accessed in Cake + locally(bippy) + ^ +one error found diff --git a/test/files/neg/t7507.scala b/test/files/neg/t7507.scala new file mode 100644 index 0000000000..1b4756d955 --- /dev/null +++ b/test/files/neg/t7507.scala @@ -0,0 +1,7 @@ +trait Cake extends Slice { + private[this] val bippy = () +} + +trait Slice { self: Cake => + locally(bippy) +} diff --git a/test/files/neg/t7636.check b/test/files/neg/t7636.check new file mode 100644 index 0000000000..f70d50bee3 --- /dev/null +++ b/test/files/neg/t7636.check @@ -0,0 +1,10 @@ +t7636.scala:3: error: illegal inheritance; + self-type Main.C does not conform to Main.ResultTable[_$3]'s selftype Main.ResultTable[_$3] + class C extends ResultTable(Left(5):Either[_,_])(5) + ^ +t7636.scala:3: error: type mismatch; + found : Either[_$2,_$3(in constructor C)] where type _$3(in constructor C), type _$2 + required: Either[_, _$3(in object Main)] where type _$3(in object Main) + class C extends ResultTable(Left(5):Either[_,_])(5) + ^ +two errors found diff --git a/test/files/neg/t7636.scala b/test/files/neg/t7636.scala new file mode 100644 index 0000000000..a7b1b90151 --- /dev/null +++ b/test/files/neg/t7636.scala @@ -0,0 +1,7 @@ +object Main extends App{ + class ResultTable[E]( query : Either[_,E] )( columns : Int ) + class C extends ResultTable(Left(5):Either[_,_])(5) +} +// Inference of the existential type for the parent type argument +// E still fails. That looks tricky to fix, see the comments in SI-7636. +// But we at least prevent a cascading NPE.
\ No newline at end of file diff --git a/test/files/neg/t7694b.check b/test/files/neg/t7694b.check new file mode 100644 index 0000000000..ea3d7736f8 --- /dev/null +++ b/test/files/neg/t7694b.check @@ -0,0 +1,7 @@ +t7694b.scala:8: error: type arguments [_3,_4] do not conform to trait L's type parameter bounds [A2,B2 <: A2] + def d = if (true) (null: L[A, A]) else (null: L[B, B]) + ^ +t7694b.scala:9: error: type arguments [_1,_2] do not conform to trait L's type parameter bounds [A2,B2 <: A2] + val v = if (true) (null: L[A, A]) else (null: L[B, B]) + ^ +two errors found diff --git a/test/files/neg/t7752.check b/test/files/neg/t7752.check new file mode 100644 index 0000000000..0a015d3f37 --- /dev/null +++ b/test/files/neg/t7752.check @@ -0,0 +1,27 @@ +t7752.scala:25: error: overloaded method value foo with alternatives: + [A](heading: String, rows: A*)(A,) <and> + [A, B](heading: (String, String), rows: (A, B)*)(A, B) <and> + [A, B, C](heading: (String, String, String), rows: (A, B, C)*)(A, B, C) <and> + [A, B, C, D](heading: (String, String, String, String), rows: (A, B, C, D)*)(A, B, C, D) <and> + [A, B, C, D, E](heading: (String, String, String, String, String), rows: (A, B, C, D, E)*)(A, B, C, D, E) <and> + [A, B, C, D, E, F](heading: (String, String, String, String, String, String), rows: (A, B, C, D, E, F)*)(A, B, C, D, E, F) <and> + [A, B, C, D, E, F, G](heading: (String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G)*)(A, B, C, D, E, F, G) <and> + [A, B, C, D, E, F, G, H](heading: (String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H)*)(A, B, C, D, E, F, G, H) <and> + [A, B, C, D, E, F, G, H, I](heading: (String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I)*)(A, B, C, D, E, F, G, H, I) <and> + [A, B, C, D, E, F, G, H, I, J](heading: (String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J)*)(A, B, C, D, E, F, G, H, I, J) <and> + [A, B, C, D, E, F, G, H, I, J, K](heading: (String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K)*)(A, B, C, D, E, F, G, H, I, J, K) <and> + [A, B, C, D, E, F, G, H, I, J, K, L](heading: (String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L)*)(A, B, C, D, E, F, G, H, I, J, K, L) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M)*)(A, B, C, D, E, F, G, H, I, J, K, L, M) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) <and> + [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)*)(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V) + cannot be applied to (Int) + foo((1)) + ^ +one error found diff --git a/test/files/neg/t7752.scala b/test/files/neg/t7752.scala new file mode 100644 index 0000000000..40ba2103b1 --- /dev/null +++ b/test/files/neg/t7752.scala @@ -0,0 +1,26 @@ +object Test { + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)*): Tuple22[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U)*): Tuple21[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T)*): Tuple20[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S)*): Tuple19[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R)*): Tuple18[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q)*): Tuple17[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)*): Tuple16[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)*): Tuple15[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M, N](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M, N)*): Tuple14[A,B,C,D,E,F,G,H,I,J,K,L,M,N] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L, M](heading: (String, String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L, M)*): Tuple13[A,B,C,D,E,F,G,H,I,J,K,L,M] = null + def foo[A, B, C, D, E, F, G, H, I, J, K, L](heading: (String, String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K, L)*): Tuple12[A,B,C,D,E,F,G,H,I,J,K,L] = null + def foo[A, B, C, D, E, F, G, H, I, J, K](heading: (String, String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J, K)*): Tuple11[A,B,C,D,E,F,G,H,I,J,K] = null + def foo[A, B, C, D, E, F, G, H, I, J](heading: (String, String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I, J)*): Tuple10[A,B,C,D,E,F,G,H,I,J] = null + def foo[A, B, C, D, E, F, G, H, I](heading: (String, String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H, I)*): Tuple9[A,B,C,D,E,F,G,H,I] = null + def foo[A, B, C, D, E, F, G, H](heading: (String, String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G, H)*): Tuple8[A,B,C,D,E,F,G,H] = null + def foo[A, B, C, D, E, F, G](heading: (String, String, String, String, String, String, String), rows: (A, B, C, D, E, F, G)*): Tuple7[A,B,C,D,E,F,G] = null + def foo[A, B, C, D, E, F](heading: (String, String, String, String, String, String), rows: (A, B, C, D, E, F)*): Tuple6[A,B,C,D,E,F] = null + def foo[A, B, C, D, E](heading: (String, String, String, String, String), rows: (A, B, C, D, E)*): Tuple5[A,B,C,D,E] = null + def foo[A, B, C, D](heading: (String, String, String, String), rows: (A, B, C, D)*): Tuple4[A,B,C,D] = null + def foo[A, B, C](heading: (String, String, String), rows: (A, B, C)*): Tuple3[A,B,C] = null + def foo[A, B](heading: (String, String), rows: (A, B)*): Tuple2[A,B] = null + def foo[A](heading: String, rows: A*): Tuple1[A] = null + + foo((1)) +}
\ No newline at end of file diff --git a/test/files/neg/valueclasses-impl-restrictions.check b/test/files/neg/valueclasses-impl-restrictions.check index 63924493aa..0af9173f74 100644 --- a/test/files/neg/valueclasses-impl-restrictions.check +++ b/test/files/neg/valueclasses-impl-restrictions.check @@ -6,12 +6,8 @@ valueclasses-impl-restrictions.scala:9: error: implementation restriction: neste This restriction is planned to be removed in subsequent releases. trait I2 { ^ -valueclasses-impl-restrictions.scala:15: error: implementation restriction: nested class is not allowed in value class -This restriction is planned to be removed in subsequent releases. - val i2 = new I2 { val q = x.s } - ^ -valueclasses-impl-restrictions.scala:21: error: implementation restriction: nested class is not allowed in value class +valueclasses-impl-restrictions.scala:23: error: implementation restriction: nested class is not allowed in value class This restriction is planned to be removed in subsequent releases. private[this] class I2(val q: String) ^ -four errors found +three errors found diff --git a/test/files/neg/valueclasses-impl-restrictions.scala b/test/files/neg/valueclasses-impl-restrictions.scala index 137f3f854c..f0577a94aa 100644 --- a/test/files/neg/valueclasses-impl-restrictions.scala +++ b/test/files/neg/valueclasses-impl-restrictions.scala @@ -12,8 +12,10 @@ class X1(val s: String) extends AnyVal { } def y(x: X1) = { - val i2 = new I2 { val q = x.s } + val i2 = new I2 { val q = x.s } // allowed as of SI-7571 i2.z + + { case x => x } : PartialFunction[Int, Int] // allowed } } diff --git a/test/files/pos/SI-7638.scala b/test/files/pos/SI-7638.scala new file mode 100644 index 0000000000..da16e0bd2c --- /dev/null +++ b/test/files/pos/SI-7638.scala @@ -0,0 +1,51 @@ +package miniboxing.tests.compile + +trait Ordering[@specialized(Int) A] { + def eqv(x: Array[A], y: Array[A]): Boolean = false +} + +trait ArrayVectorOrder[@specialized(Int) A] extends Ordering[A] { + override def eqv(x: Array[A], y: Array[A]): Boolean = super.eqv(x, y) +} + +object vectorOrder { + implicit def arrayOrder[@specialized(Int) A]() = + /* + * Before applying patch: + * + * while compiling: SI-7638.scala + * during phase: mixin + * library version: version 2.10.3-20130625-164027-d22e8d282c + * compiler version: version 2.10.3-20130627-153946-54cb6af7db + * reconstructed args: + * + * last tree to typer: TypeTree(class Array) + * symbol: class Array in package scala (flags: final) + * symbol definition: final class Array[T >: ? <: ?] extends Object + * tpe: Array[Int] + * symbol owners: class Array -> package scala + * context owners: anonymous class anon$1 -> package compile + * + * == Expanded type of tree == + * + * TypeRef( + * TypeSymbol(final class Array[T >: ? <: ?] extends Object) + * args = List(TypeRef(TypeSymbol(final abstract class Int extends ))) + * ) + * + * unhandled exception while transforming SI-7638.scala + * error: uncaught exception during compilation: java.lang.UnsupportedOperationException + * error: java.lang.UnsupportedOperationException: tail of empty list + * at scala.collection.immutable.Nil$.tail(List.scala:339) + * at scala.collection.immutable.Nil$.tail(List.scala:334) + * at scala.tools.nsc.transform.Mixin$$anonfun$scala$tools$nsc$transform$Mixin$$rebindSuper$1.apply(Mixin.scala:123) + * at scala.tools.nsc.transform.Mixin$$anonfun$scala$tools$nsc$transform$Mixin$$rebindSuper$1.apply(Mixin.scala:122) + * at scala.reflect.internal.SymbolTable.atPhase(SymbolTable.scala:207) + * at scala.reflect.internal.SymbolTable.afterPhase(SymbolTable.scala:216) + * at scala.tools.nsc.Global.afterPickler(Global.scala:1104) + * at scala.tools.nsc.transform.Mixin.scala$tools$nsc$transform$Mixin$$rebindSuper(Mixin.scala:122) + * at scala.tools.nsc.transform.Mixin$$anonfun$scala$tools$nsc$transform$Mixin$$mixinTraitMembers$1$1.apply(Mixin.scala:339) + * at scala.tools.nsc.transform.Mixin$$anonfun$scala$tools$nsc$transform$Mixin$$mixinTraitMembers$1$1.apply(Mixin.scala:292) + */ + new ArrayVectorOrder[A] { } +} diff --git a/test/files/pos/lub-dealias-widen.scala b/test/files/pos/lub-dealias-widen.scala new file mode 100644 index 0000000000..38854fbc5c --- /dev/null +++ b/test/files/pos/lub-dealias-widen.scala @@ -0,0 +1,34 @@ +import scala.language.higherKinds + +sealed trait Path { + type EncodeFunc + type Route[R] = List[String] => R + + def >>(f: Route[Int]): Sitelet[EncodeFunc] = ??? +} + +case object PAny extends Path { + type EncodeFunc = List[String] => String +} + +case class PLit[Next <: Path]() extends Path { + type EncodeFunc = Next#EncodeFunc +} + +trait Sitelet[EncodeFunc] { self => + def &[G <: H, H >: EncodeFunc](that: Sitelet[G]): Sitelet[H] = ??? +} + +object Test { + val r: Sitelet[Int => (Int => String)] = ??? + + val p2: PLit[PAny.type] = ??? + val r2 /*: Sitelet[List[String] => String] */ // annotate type and it compiles with 2.10.0 + = p2 >> { (xs: List[String]) => 0 } + + // This works after https://github.com/scala/scala/commit/a06d31f6a + // Before: error: inferred type arguments [List[String] => String,List[String] => String] + // do not conform to method &'s type parameter bounds + // [G <: H,H >: Int => (Int => String)] + val s = r & r2 +}
\ No newline at end of file diff --git a/test/files/pos/t7014/ThreadSafety.java b/test/files/pos/t7014/ThreadSafety.java new file mode 100644 index 0000000000..ed508804e3 --- /dev/null +++ b/test/files/pos/t7014/ThreadSafety.java @@ -0,0 +1,9 @@ +package t7014; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) // must be exactly RUNTIME retention (those we parse) +public @interface ThreadSafety { + ThreadSafetyLevel level(); +}
\ No newline at end of file diff --git a/test/files/pos/t7014/ThreadSafetyLevel.java b/test/files/pos/t7014/ThreadSafetyLevel.java new file mode 100644 index 0000000000..4df1dc787a --- /dev/null +++ b/test/files/pos/t7014/ThreadSafetyLevel.java @@ -0,0 +1,8 @@ +package t7014; // package needed due to other bug in scalac's java parser + +// since we parse eagerly, we have not yet parsed the classfile when parsing the annotation, +// and on doing so, fail to find a symbol for the COMPLETELY_THREADSAFE reference +// from the annotation's argument to the enum's member +// for now, let's just not crash -- should implement lazy completing at some point +@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) +public enum ThreadSafetyLevel { COMPLETELY_THREADSAFE } diff --git a/test/files/pos/t7014/t7014.scala b/test/files/pos/t7014/t7014.scala new file mode 100644 index 0000000000..faec4c7740 --- /dev/null +++ b/test/files/pos/t7014/t7014.scala @@ -0,0 +1,4 @@ +package t7014 + +import ThreadSafetyLevel.COMPLETELY_THREADSAFE // refer to annotation so it gets parsed +
\ No newline at end of file diff --git a/test/files/pos/t7461.check b/test/files/pos/t7461.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/pos/t7461.check diff --git a/test/files/pos/t7461/Macros_1.scala b/test/files/pos/t7461/Macros_1.scala new file mode 100644 index 0000000000..353dec66d7 --- /dev/null +++ b/test/files/pos/t7461/Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + def impl(c: Context) = { + import c.universe._ + val wut = c.typeCheck(Select(Literal(Constant(10)), newTermName("$minus")), silent = true) + // println(showRaw(wut, printIds = true, printTypes = true)) + c.literalUnit + } + + def foo = macro impl +}
\ No newline at end of file diff --git a/test/files/pos/t7461/Test_2.scala b/test/files/pos/t7461/Test_2.scala new file mode 100644 index 0000000000..3839659c9a --- /dev/null +++ b/test/files/pos/t7461/Test_2.scala @@ -0,0 +1,3 @@ +class C { + def foo = Macros.foo +}
\ No newline at end of file diff --git a/test/files/pos/t7505.scala b/test/files/pos/t7505.scala new file mode 100644 index 0000000000..3e1e6ab8b4 --- /dev/null +++ b/test/files/pos/t7505.scala @@ -0,0 +1,16 @@ +import scala.language.reflectiveCalls + +case class ContextProperty(value: Any) { + type HasToInt = { def toInt:Int } + + def toInt: Int = value match { + case n: HasToInt => n.toInt + } +} + +// was: +// error:7: error during expansion of this match (this is a scalac bug). +// The underlying error was: type mismatch; +// found : Boolean(true) +// required: AnyRef +// def toInt: Int = value match {
\ No newline at end of file diff --git a/test/files/pos/t7649.flags b/test/files/pos/t7649.flags new file mode 100644 index 0000000000..fcf951d907 --- /dev/null +++ b/test/files/pos/t7649.flags @@ -0,0 +1 @@ +-Yrangepos
\ No newline at end of file diff --git a/test/files/pos/t7649.scala b/test/files/pos/t7649.scala new file mode 100644 index 0000000000..a1b02f63f1 --- /dev/null +++ b/test/files/pos/t7649.scala @@ -0,0 +1,20 @@ +object Test { + val c: reflect.macros.Context = ??? + import c.universe._ + reify { + // The lookup of the implicit WeakTypeTag[Any] + // was triggering an unpositioned tree. + c.Expr[Any](Literal(Constant(0))).splice + } + + import scala.reflect.ClassTag + def ct[A: ClassTag]: Expr[A] = ??? + def tt[A: TypeTag]: Expr[A] = ??? + def wtt[A: WeakTypeTag]: Expr[A] = ??? + + reify { + ct[String].splice + tt[String].splice + wtt[String].splice + } +} diff --git a/test/files/pos/t7694.scala b/test/files/pos/t7694.scala new file mode 100644 index 0000000000..9852d5ec79 --- /dev/null +++ b/test/files/pos/t7694.scala @@ -0,0 +1,40 @@ +trait A +trait B + +trait L[A2, B2 <: A2] { + def bar(a: Any, b: Any) = 0 +} + +object Lub { + // use named args transforms to include TypeTree(<lub.tpe>) in the AST before refchecks. + def foo(a: L[_, _], b: Any) = 0 + + foo(b = 0, a = if (true) (null: L[A, A]) else (null: L[B, B])) + + (if (true) (null: L[A, A]) else (null: L[B, B])).bar(b = 0, a = 0) +} + +/* +The LUB ends up as: + +TypeRef( + TypeSymbol( + abstract trait L#7038[A2#7039, B2#7040 <: A2#7039] extends AnyRef#2197 + + ) + args = List( + AbstractTypeRef( + AbstractType( + type _1#13680 >: A#7036 with B#7037 <: Object#1752 + ) + ) + AbstractTypeRef( + AbstractType( + type _2#13681 >: A#7036 with B#7037 <: Object#1752 + ) + ) + ) +) + +Note that type _2#13681 is *not* bound by _1#13680 +*/ diff --git a/test/files/pos/t7716.scala b/test/files/pos/t7716.scala new file mode 100644 index 0000000000..40117051ed --- /dev/null +++ b/test/files/pos/t7716.scala @@ -0,0 +1,16 @@ +object Test { + def test: Unit = { + val e: java.lang.Enum[_] = java.util.concurrent.TimeUnit.SECONDS + e match { case x => println(x) } + + + trait TA[X <: CharSequence] + val ta: TA[_] = new TA[String] {} + + ta match { + case _ => println("hi") + } + + def f(ta: TA[_]) = ta match { case _ => "hi" } + } +} diff --git a/test/files/run/classfile-format-51.scala b/test/files/run/classfile-format-51.scala index 9b1e612f4f..378caa7936 100644 --- a/test/files/run/classfile-format-51.scala +++ b/test/files/run/classfile-format-51.scala @@ -112,12 +112,12 @@ object Driver { System.setErr(System.out) try { // this test is only valid under JDK 1.7+ - // cheat a little by using 'ScalaVersion' because it can parse java versions just as well - val requiredJavaVersion = ScalaVersion("1.7") - val executingJavaVersion = ScalaVersion(System.getProperty("java.specification.version")) - if (executingJavaVersion >= requiredJavaVersion) { + testUnderJavaAtLeast("1.7") { generateClass() compile() + () + } otherwise { + () } } finally diff --git a/test/files/run/classfile-format-52.check b/test/files/run/classfile-format-52.check new file mode 100644 index 0000000000..5d24ef03cc --- /dev/null +++ b/test/files/run/classfile-format-52.check @@ -0,0 +1,2 @@ +hello from publicMethod +hello from staticMethod diff --git a/test/files/run/classfile-format-52.scala b/test/files/run/classfile-format-52.scala new file mode 100644 index 0000000000..7afa09ae0b --- /dev/null +++ b/test/files/run/classfile-format-52.scala @@ -0,0 +1,77 @@ +import java.io.{File, FileOutputStream} + +import scala.tools.nsc.settings.ScalaVersion +import scala.tools.partest._ +import scala.tools.asm +import asm.{AnnotationVisitor, ClassWriter, FieldVisitor, Handle, MethodVisitor, Opcodes} +import Opcodes._ + +// This test ensures that we can read JDK 8 (classfile format 52) files, including those +// with default methods. To do that it first uses ASM to generate an interface called +// HasDefaultMethod. Then it runs a normal compile on Scala source that extends that +// interface. Any failure will be dumped to std out. +// +// By it's nature the test can only work on JDK 8+ because under JDK 7- the +// interface won't verify. +object Test extends DirectTest { + override def extraSettings: String = "-optimise -usejavacp -d " + testOutput.path + " -cp " + testOutput.path + + def generateInterface() { + val interfaceName = "HasDefaultMethod" + val methodType = "()Ljava/lang/String;" + + val cw = new ClassWriter(0) + cw.visit(52, ACC_PUBLIC+ACC_ABSTRACT+ACC_INTERFACE, interfaceName, null, "java/lang/Object", null) + + def createMethod(flags:Int, name: String) { + val method = cw.visitMethod(flags, name, methodType, null, null) + method.visitCode() + method.visitLdcInsn(s"hello from $name") + method.visitInsn(ARETURN) + method.visitMaxs(1, 1) + method.visitEnd() + } + + createMethod(ACC_PUBLIC, "publicMethod") + createMethod(ACC_PUBLIC+ACC_STATIC, "staticMethod") + createMethod(ACC_PRIVATE, "privateMethod") + + cw.visitEnd() + val bytes = cw.toByteArray() + + val fos = new FileOutputStream(new File(s"${testOutput.path}/$interfaceName.class")) + try + fos write bytes + finally + fos.close() + + } + + def code = +""" +class Driver extends HasDefaultMethod { + println(publicMethod()) + println(HasDefaultMethod.staticMethod()) +} +""" + + override def show(): Unit = { + // redirect err to out, for logging + val prevErr = System.err + System.setErr(System.out) + try { + // this test is only valid under JDK 1.8+ + testUnderJavaAtLeast("1.8") { + generateInterface() + compile() + Class.forName("Driver").newInstance() + () + } otherwise { + println("hello from publicMethod") + println("hello from staticMethod") + } + } + finally + System.setErr(prevErr) + } +} diff --git a/test/files/run/macro-auto-duplicate.check b/test/files/run/macro-auto-duplicate.check new file mode 100644 index 0000000000..d81cc0710e --- /dev/null +++ b/test/files/run/macro-auto-duplicate.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-auto-duplicate/Macros_1.scala b/test/files/run/macro-auto-duplicate/Macros_1.scala new file mode 100644 index 0000000000..e3df05ba50 --- /dev/null +++ b/test/files/run/macro-auto-duplicate/Macros_1.scala @@ -0,0 +1,17 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + def impl(c: Context) = { + import c.universe._ + val x = Ident(newTermName("x")) + def defAndUseX(rhs: Tree) = { + Block(List(ValDef(NoMods, newTermName("x"), TypeTree(), rhs)), x) + } + val xi4 = defAndUseX(Literal(Constant(4))) + val xs2 = defAndUseX(Literal(Constant("2"))) + c.Expr[String](Apply(Select(xi4, newTermName("$plus")), List(xs2))) + } + + def foo = macro impl +}
\ No newline at end of file diff --git a/test/files/run/macro-auto-duplicate/Test_2.scala b/test/files/run/macro-auto-duplicate/Test_2.scala new file mode 100644 index 0000000000..f697da6020 --- /dev/null +++ b/test/files/run/macro-auto-duplicate/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + println(Macros.foo) +}
\ No newline at end of file diff --git a/test/files/run/macro-duplicate.check b/test/files/run/macro-duplicate.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/run/macro-duplicate.check diff --git a/test/files/run/macro-duplicate.flags b/test/files/run/macro-duplicate.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-duplicate.flags @@ -0,0 +1 @@ +-language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-duplicate/Impls_Macros_1.scala b/test/files/run/macro-duplicate/Impls_Macros_1.scala new file mode 100644 index 0000000000..de81923330 --- /dev/null +++ b/test/files/run/macro-duplicate/Impls_Macros_1.scala @@ -0,0 +1,29 @@ +import scala.reflect.macros.Context + +object Macros { + def impl(c: Context) = { + import c.universe._ + val Expr(Block((cdef: ClassDef) :: Nil, _)) = reify { class C { def x = 2 } } + val cdef1 = + new Transformer { + override def transform(tree: Tree): Tree = tree match { + case Template(_, _, ctor :: defs) => + val defs1 = defs collect { + case ddef @ DefDef(mods, name, tparams, vparamss, tpt, body) => + val future = Select(Select(Select(Ident(newTermName("scala")), newTermName("concurrent")), newTermName("package")), newTermName("future")) + val Future = Select(Select(Ident(newTermName("scala")), newTermName("concurrent")), newTypeName("Future")) + val tpt1 = if (tpt.isEmpty) tpt else AppliedTypeTree(Future, List(tpt)) + val body1 = Apply(future, List(body)) + val name1 = newTermName("async" + name.toString.capitalize) + DefDef(mods, name1, tparams, vparamss, tpt1, body1) + } + Template(Nil, emptyValDef, ctor +: defs ::: defs1) + case _ => + super.transform(tree) + } + } transform cdef + c.Expr[Unit](Block(cdef1 :: Nil, Literal(Constant(())))) + } + + def foo = macro impl +}
\ No newline at end of file diff --git a/test/files/run/macro-duplicate/Test_2.scala b/test/files/run/macro-duplicate/Test_2.scala new file mode 100644 index 0000000000..6dbd4382d3 --- /dev/null +++ b/test/files/run/macro-duplicate/Test_2.scala @@ -0,0 +1,6 @@ +import scala.concurrent._ +import ExecutionContext.Implicits.global + +object Test extends App { + Macros.foo +}
\ No newline at end of file diff --git a/test/files/run/reflection-magicsymbols-invoke.check b/test/files/run/reflection-magicsymbols-invoke.check index f5258efeb7..352aefaf25 100644 --- a/test/files/run/reflection-magicsymbols-invoke.check +++ b/test/files/run/reflection-magicsymbols-invoke.check @@ -82,7 +82,7 @@ Array it's important to print the list of Array's members if some of them change (possibly, adding and/or removing magic symbols), we must update this test constructor Array: (_length: Int)Array[T] -constructor Object: ()java.lang.Object +constructor Cloneable: ()java.lang.Cloneable method !=: (x$1: Any)Boolean method !=: (x$1: AnyRef)Boolean method ##: ()Int diff --git a/test/files/run/t6392b.check b/test/files/run/t6392b.check index e9c7ecaa34..b7872f0e08 100644 --- a/test/files/run/t6392b.check +++ b/test/files/run/t6392b.check @@ -1 +1 @@ -ModuleDef(Modifiers(), newTermName("C"), Template(List(Select(Ident(scala#PK), newTypeName("AnyRef")#TPE)), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(newTypeName("C")), tpnme.EMPTY), nme.CONSTRUCTOR#PCTOR), List())), Literal(Constant(()))))))) +ModuleDef(Modifiers(), newTermName("C")#MOD, Template(List(Select(Ident(scala#PK), newTypeName("AnyRef")#TPE)), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR#PCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(newTypeName("C")), tpnme.EMPTY), nme.CONSTRUCTOR#PCTOR), List())), Literal(Constant(()))))))) diff --git a/test/files/run/t6481.check b/test/files/run/t6481.check new file mode 100644 index 0000000000..7ec29631b1 --- /dev/null +++ b/test/files/run/t6481.check @@ -0,0 +1,4 @@ +delayed init +new foo(1, 2) +delayed init +new foo(b = 2, a = 1) diff --git a/test/files/run/t6481.scala b/test/files/run/t6481.scala new file mode 100644 index 0000000000..125da3b15a --- /dev/null +++ b/test/files/run/t6481.scala @@ -0,0 +1,13 @@ +abstract class foo(a: Int, b: Int) extends scala.DelayedInit { + def delayedInit(x: => Unit) { + println("delayed init"); + x + } +} + +object Test { + def main(args: Array[String]) { + new foo(1, 2) { println("new foo(1, 2)") } + new foo(b = 2, a = 1) { println("new foo(b = 2, a = 1)") } + } +} diff --git a/test/files/run/t6989.check b/test/files/run/t6989.check index 8943792115..43d4bbaf02 100644 --- a/test/files/run/t6989.check +++ b/test/files/run/t6989.check @@ -101,6 +101,12 @@ isProtected = false isPublic = false privateWithin = <none> ============ +sym = constructor $PrivateJavaClass, signature = ()JavaClass_1.this.$PrivateJavaClass, owner = class $PrivateJavaClass +isPrivate = false +isProtected = false +isPublic = true +privateWithin = <none> +============ sym = value this$0, signature = foo.JavaClass_1, owner = class $PrivateJavaClass isPrivate = false isProtected = false @@ -119,6 +125,12 @@ isProtected = true isPublic = false privateWithin = package foo ============ +sym = constructor $ProtectedJavaClass, signature = ()JavaClass_1.this.$ProtectedJavaClass, owner = class $ProtectedJavaClass +isPrivate = false +isProtected = false +isPublic = true +privateWithin = <none> +============ sym = value this$0, signature = foo.JavaClass_1, owner = class $ProtectedJavaClass isPrivate = false isProtected = false @@ -173,6 +185,12 @@ isProtected = false isPublic = false privateWithin = <none> ============ +sym = constructor PrivateStaticJavaClass, signature = ()foo.JavaClass_1.PrivateStaticJavaClass, owner = class PrivateStaticJavaClass +isPrivate = false +isProtected = false +isPublic = true +privateWithin = <none> +============ sym = object PrivateStaticJavaClass, signature = foo.JavaClass_1.PrivateStaticJavaClass.type, owner = object JavaClass_1 isPrivate = true isProtected = false @@ -185,6 +203,12 @@ isProtected = false isPublic = false privateWithin = <none> ============ +sym = constructor ProtectedStaticJavaClass, signature = ()foo.JavaClass_1.ProtectedStaticJavaClass, owner = class ProtectedStaticJavaClass +isPrivate = false +isProtected = false +isPublic = true +privateWithin = <none> +============ sym = object ProtectedStaticJavaClass, signature = foo.JavaClass_1.ProtectedStaticJavaClass.type, owner = object JavaClass_1 isPrivate = true isProtected = false diff --git a/test/files/run/t7265.scala b/test/files/run/t7265.scala new file mode 100644 index 0000000000..c556930303 --- /dev/null +++ b/test/files/run/t7265.scala @@ -0,0 +1,27 @@ + +import scala.util.Properties._ + +object Test extends App { + + setProp("java.specification.version", "1.7") + + assert( isJavaAtLeast("1.5")) + assert( isJavaAtLeast("1.6")) + assert( isJavaAtLeast("1.7")) + assert(!isJavaAtLeast("1.8")) + assert(!isJavaAtLeast("1.71")) + + failing(isJavaAtLeast("1.a")) + failing(isJavaAtLeast("1")) + failing(isJavaAtLeast("")) + failing(isJavaAtLeast(".")) + failing(isJavaAtLeast(".5")) + failing(isJavaAtLeast("1.7.1")) + + def failing(u: =>Unit) = try { + u + assert(false, "Expected Exception") + } catch { + case _: NumberFormatException => + } +} diff --git a/test/files/run/t7331a.check b/test/files/run/t7331a.check new file mode 100644 index 0000000000..a59b400344 --- /dev/null +++ b/test/files/run/t7331a.check @@ -0,0 +1,2 @@ +source-<toolbox>,line-1,offset=0 +2
\ No newline at end of file diff --git a/test/files/run/t7331a.scala b/test/files/run/t7331a.scala new file mode 100644 index 0000000000..1851945e63 --- /dev/null +++ b/test/files/run/t7331a.scala @@ -0,0 +1,10 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + val tb = cm.mkToolBox() + val tree = tb.parse("x") + println(tree.pos) + println(tree.pos.source.content.length) +}
\ No newline at end of file diff --git a/test/files/run/t7331b.check b/test/files/run/t7331b.check new file mode 100644 index 0000000000..7034a95a3f --- /dev/null +++ b/test/files/run/t7331b.check @@ -0,0 +1,3 @@ +reflective compilation has failed: + +')' expected but eof found. diff --git a/test/files/run/t7331b.scala b/test/files/run/t7331b.scala new file mode 100644 index 0000000000..052656d11b --- /dev/null +++ b/test/files/run/t7331b.scala @@ -0,0 +1,11 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.{ToolBox, ToolBoxError} + +object Test extends App { + val tb = cm.mkToolBox() + try tb.parse("f(x") + catch { + case ToolBoxError(msg, _) => println(msg) + } +}
\ No newline at end of file diff --git a/test/files/run/t7331c.check b/test/files/run/t7331c.check new file mode 100644 index 0000000000..af9f1b1ad9 --- /dev/null +++ b/test/files/run/t7331c.check @@ -0,0 +1,3 @@ +ClassDef(Modifiers(), newTypeName("C"), List(), Template(List(Select(Ident(scala), newTypeName("AnyRef"))), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(()))))))) +source-<toolbox>,line-1,offset=6 +NoPosition diff --git a/test/files/run/t7331c.scala b/test/files/run/t7331c.scala new file mode 100644 index 0000000000..75873afcd0 --- /dev/null +++ b/test/files/run/t7331c.scala @@ -0,0 +1,11 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + val tb = cm.mkToolBox() + val tree = tb.parse("class C").asInstanceOf[ClassDef] + println(showRaw(tree)) + println(tree.pos) + println(tree.impl.self.pos) +}
\ No newline at end of file diff --git a/test/files/run/t7336.scala b/test/files/run/t7336.scala new file mode 100644 index 0000000000..ace83f2c1f --- /dev/null +++ b/test/files/run/t7336.scala @@ -0,0 +1,31 @@ +import scala.concurrent.Await +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future +import scala.concurrent.duration.Duration + +/** This test uses recursive calls to Future.flatMap to create arrays whose + * combined size is slightly greater than the JVM heap size. A previous + * implementation of Future.flatMap would retain references to each array, + * resulting in a speedy OutOfMemoryError. Now, each array should be freed soon + * after it is created and the test should complete without problems. + */ +object Test { + def main(args: Array[String]) { + def loop(i: Int, arraySize: Int): Future[Unit] = { + val array = new Array[Byte](arraySize) + Future.successful(i).flatMap { i => + if (i == 0) { + Future.successful(()) + } else { + array.size // Force closure to refer to array + loop(i - 1, arraySize) + } + + } + } + + val arraySize = 1000000 + val tooManyArrays = (Runtime.getRuntime().totalMemory() / arraySize).toInt + 1 + Await.ready(loop(tooManyArrays, arraySize), Duration.Inf) + } +}
\ No newline at end of file diff --git a/test/files/run/t7375a.check b/test/files/run/t7375a.check new file mode 100644 index 0000000000..a0a15dfb2f --- /dev/null +++ b/test/files/run/t7375a.check @@ -0,0 +1,4 @@ +C1 +C2 +C1 +C2 diff --git a/test/files/run/t7375a.scala b/test/files/run/t7375a.scala new file mode 100644 index 0000000000..e46ad08f63 --- /dev/null +++ b/test/files/run/t7375a.scala @@ -0,0 +1,16 @@ +import scala.reflect.ClassTag + +class C1(val n: Int) extends AnyVal +class C2(val n: Int) extends AnyRef + +object Test { + type F1 = C1 + type F2 = C2 + + def main(args: Array[String]): Unit = { + println(implicitly[ClassTag[C1]]) + println(implicitly[ClassTag[C2]]) + println(implicitly[ClassTag[F1]]) + println(implicitly[ClassTag[F2]]) + } +} diff --git a/test/files/run/t7375b.check b/test/files/run/t7375b.check new file mode 100644 index 0000000000..d7578e28ba --- /dev/null +++ b/test/files/run/t7375b.check @@ -0,0 +1,4 @@ +Predef.this.classOf[C1] +Predef.this.classOf[C2] +Predef.this.classOf[C1] +Predef.this.classOf[C2] diff --git a/test/files/run/t7375b/Macros_1.scala b/test/files/run/t7375b/Macros_1.scala new file mode 100644 index 0000000000..70e79cc2b4 --- /dev/null +++ b/test/files/run/t7375b/Macros_1.scala @@ -0,0 +1,18 @@ +import language.experimental.macros +import scala.reflect.macros.Context + +class C1(val n: Int) extends AnyVal +class C2(val n: Int) extends AnyRef + +object Macros { + type F1 = C1 + type F2 = C2 + + def foo = macro impl + def impl(c: Context) = { + import c.universe._ + def test[T: c.TypeTag] = reify(println(c.literal(c.reifyRuntimeClass(c.typeOf[T]).toString).splice)).tree + def tests = Block(List(test[C1], test[C2], test[F1], test[F2]), Literal(Constant(()))) + c.Expr[Unit](tests) + } +}
\ No newline at end of file diff --git a/test/files/run/t7375b/Test_2.scala b/test/files/run/t7375b/Test_2.scala new file mode 100644 index 0000000000..acfddae942 --- /dev/null +++ b/test/files/run/t7375b/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +}
\ No newline at end of file diff --git a/test/files/run/t7398.scala b/test/files/run/t7398.scala index e4090f7db3..dd59697b71 100644 --- a/test/files/run/t7398.scala +++ b/test/files/run/t7398.scala @@ -3,14 +3,11 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - def javaVersion = scala.util.Properties.javaVersion - def isJavaEight = javaVersion startsWith "1.8" // This way we auto-pass on non-java8 since there's nothing to check - override lazy val units = { - val res: List[CompilationUnit] = if (isJavaEight) javaCompilationUnits(global)(defaultMethodSource) else Nil - val word = if (isJavaEight) "Attempting" else "Skipping" - log(s"$word java8-specific test under java version $javaVersion") - res + override lazy val units: List[CompilationUnit] = testUnderJavaAtLeast("1.8") { + javaCompilationUnits(global)(defaultMethodSource) + } otherwise { + Nil } private def defaultMethodSource = """ diff --git a/test/files/run/t7455.check b/test/files/run/t7455.check new file mode 100644 index 0000000000..0eb9342888 --- /dev/null +++ b/test/files/run/t7455.check @@ -0,0 +1,4 @@ +private[package <empty>] def <init>(x$1: String): Outer[E] +private[package <empty>] def <init>(): Outer$PrivateInner +private[package <empty>] def <init>(): Outer$PrivateStaticInner +private[package <empty>] def <init>(x$2: String): Outer$PublicInner diff --git a/test/files/run/t7455/Outer.java b/test/files/run/t7455/Outer.java new file mode 100644 index 0000000000..10c97a9150 --- /dev/null +++ b/test/files/run/t7455/Outer.java @@ -0,0 +1,31 @@ +public class Outer<E> { + public void elements() { + new C<E>() { + }; + } + + private Outer(String a) {} + + static class SubSelf extends Outer<String> { + public SubSelf() { super(""); } + } + + private class PrivateInner { + } + class SubPrivateInner extends PrivateInner { + } + + private class PublicInner { + private PublicInner(String a) {} + } + class SubPublicInner extends PublicInner { + public SubPublicInner() { super(""); } + } + + private static class PrivateStaticInner { + } + public static class SubPrivateStaticInner extends PrivateStaticInner { + } +} + +class C<E> {} diff --git a/test/files/run/t7455/Test.scala b/test/files/run/t7455/Test.scala new file mode 100644 index 0000000000..b23a724c78 --- /dev/null +++ b/test/files/run/t7455/Test.scala @@ -0,0 +1,30 @@ +import scala.tools.partest._ + +// javac adds dummy parameters of type Outer$1 to synthetic access constructors +// This test shows that we strip them from the signatures. If we don't, we trigger +// parsing of Outer$1 which can fail if it references type parameters of the Outer. +// +// OLD OUTPUT: +// private[package <empty>] def <init>(x$2: Outer$1): Outer$PrivateInner +// error: error while loading Outer$1, class file 't7455-run.obj/Outer$1.class' is broken +// (class java.util.NoSuchElementException/key not found: E) +// ... +object Test extends DirectTest { + override def code = "" + + def show { + val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator") + val compiler = newCompiler("-cp", classpath, "-d", testOutput.path) + import compiler._, definitions._ + new compiler.Run + + for { + name <- Seq("Outer", "Outer$PrivateInner", "Outer$PrivateStaticInner", "Outer$PublicInner") + clazz = compiler.rootMirror.staticClass(name) + constr <- clazz.info.member(nme.CONSTRUCTOR).alternatives + } { + println(constr.defString) + fullyInitializeSymbol(constr) + } + } +} diff --git a/test/files/run/t7498.scala b/test/files/run/t7498.scala new file mode 100644 index 0000000000..1dbf0597e0 --- /dev/null +++ b/test/files/run/t7498.scala @@ -0,0 +1,20 @@ + + + + + + + +object Test extends App { + import scala.collection.concurrent.TrieMap + + class Collision(val idx: Int) { + override def hashCode = idx % 10 + } + + val tm = TrieMap[Collision, Unit]() + for (i <- 0 until 1000) tm(new Collision(i)) = () + + tm.par.foreach(kv => ()) +} + diff --git a/test/files/run/t7507.scala b/test/files/run/t7507.scala new file mode 100644 index 0000000000..6c1959ddac --- /dev/null +++ b/test/files/run/t7507.scala @@ -0,0 +1,31 @@ +trait Cake extends Slice + +// Minimization +trait Slice { self: Cake => // must have self type that extends `Slice` + private[this] val bippy = () // must be private[this] + locally(bippy) +} + +// Originally reported bug: +trait Cake1 extends Slice1 +trait Slice1 { self: Cake1 => + import java.lang.String // any import will do! + val Tuple2(x, y) = ((1, 2)) +} + + +// Nesting +trait Cake3 extends Outer.Slice3 + +// Minimization +object Outer { + private[this] val bippy = () + trait Slice3 { self: Cake3 => + locally(bippy) + } +} + +object Test extends App { + val s1 = new Cake1 {} + assert((s1.x, s1.y) == (1, 2), (s1.x, s1.y)) +} diff --git a/test/files/run/t7510.check b/test/files/run/t7510.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/run/t7510.check diff --git a/test/files/run/t7510/Ann_1.java b/test/files/run/t7510/Ann_1.java new file mode 100644 index 0000000000..c8c5b2035f --- /dev/null +++ b/test/files/run/t7510/Ann_1.java @@ -0,0 +1,4 @@ +package foo; + +public @interface Ann_1 { +}
\ No newline at end of file diff --git a/test/files/run/t7510/Test_2.scala b/test/files/run/t7510/Test_2.scala new file mode 100644 index 0000000000..7d7a95e0f2 --- /dev/null +++ b/test/files/run/t7510/Test_2.scala @@ -0,0 +1,9 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + val tb = cm.mkToolBox() + tb.compile(tb.parse("@foo.Ann_1 class C")) +} + diff --git a/test/files/run/t7556.check b/test/files/run/t7556.check new file mode 100644 index 0000000000..3328708a6d --- /dev/null +++ b/test/files/run/t7556.check @@ -0,0 +1,2 @@ +class annotations: List(scala.reflect.ScalaLongSignature) +3001 decls via runtime reflection diff --git a/test/files/run/t7556/Test_2.scala b/test/files/run/t7556/Test_2.scala new file mode 100644 index 0000000000..31848738ef --- /dev/null +++ b/test/files/run/t7556/Test_2.scala @@ -0,0 +1,11 @@ +import scala.reflect.runtime.universe._ + +object Test { + def main(args: Array[String]) { + val mc = new MegaClass + val anns = mc.getClass.getAnnotations.map(_.annotationType.getName).toList.sorted + println(s"class annotations: $anns") + val N = typeTag[MegaClass].tpe.declarations.size // was: error reading Scala signature of MegaClass: 65935 + println(s"$N decls via runtime reflection") + } +} diff --git a/test/files/run/t7556/mega-class_1.scala b/test/files/run/t7556/mega-class_1.scala new file mode 100644 index 0000000000..dcc9ba8bcd --- /dev/null +++ b/test/files/run/t7556/mega-class_1.scala @@ -0,0 +1,3002 @@ +class MegaClass { + def method0: Int = 0 + def method1: Int = 0 + def method2: Int = 0 + def method3: Int = 0 + def method4: Int = 0 + def method5: Int = 0 + def method6: Int = 0 + def method7: Int = 0 + def method8: Int = 0 + def method9: Int = 0 + def method10: Int = 0 + def method11: Int = 0 + def method12: Int = 0 + def method13: Int = 0 + def method14: Int = 0 + def method15: Int = 0 + def method16: Int = 0 + def method17: Int = 0 + def method18: Int = 0 + def method19: Int = 0 + def method20: Int = 0 + def method21: Int = 0 + def method22: Int = 0 + def method23: Int = 0 + def method24: Int = 0 + def method25: Int = 0 + def method26: Int = 0 + def method27: Int = 0 + def method28: Int = 0 + def method29: Int = 0 + def method30: Int = 0 + def method31: Int = 0 + def method32: Int = 0 + def method33: Int = 0 + def method34: Int = 0 + def method35: Int = 0 + def method36: Int = 0 + def method37: Int = 0 + def method38: Int = 0 + def method39: Int = 0 + def method40: Int = 0 + def method41: Int = 0 + def method42: Int = 0 + def method43: Int = 0 + def method44: Int = 0 + def method45: Int = 0 + def method46: Int = 0 + def method47: Int = 0 + def method48: Int = 0 + def method49: Int = 0 + def method50: Int = 0 + def method51: Int = 0 + def method52: Int = 0 + def method53: Int = 0 + def method54: Int = 0 + def method55: Int = 0 + def method56: Int = 0 + def method57: Int = 0 + def method58: Int = 0 + def method59: Int = 0 + def method60: Int = 0 + def method61: Int = 0 + def method62: Int = 0 + def method63: Int = 0 + def method64: Int = 0 + def method65: Int = 0 + def method66: Int = 0 + def method67: Int = 0 + def method68: Int = 0 + def method69: Int = 0 + def method70: Int = 0 + def method71: Int = 0 + def method72: Int = 0 + def method73: Int = 0 + def method74: Int = 0 + def method75: Int = 0 + def method76: Int = 0 + def method77: Int = 0 + def method78: Int = 0 + def method79: Int = 0 + def method80: Int = 0 + def method81: Int = 0 + def method82: Int = 0 + def method83: Int = 0 + def method84: Int = 0 + def method85: Int = 0 + def method86: Int = 0 + def method87: Int = 0 + def method88: Int = 0 + def method89: Int = 0 + def method90: Int = 0 + def method91: Int = 0 + def method92: Int = 0 + def method93: Int = 0 + def method94: Int = 0 + def method95: Int = 0 + def method96: Int = 0 + def method97: Int = 0 + def method98: Int = 0 + def method99: Int = 0 + def method100: Int = 0 + def method101: Int = 0 + def method102: Int = 0 + def method103: Int = 0 + def method104: Int = 0 + def method105: Int = 0 + def method106: Int = 0 + def method107: Int = 0 + def method108: Int = 0 + def method109: Int = 0 + def method110: Int = 0 + def method111: Int = 0 + def method112: Int = 0 + def method113: Int = 0 + def method114: Int = 0 + def method115: Int = 0 + def method116: Int = 0 + def method117: Int = 0 + def method118: Int = 0 + def method119: Int = 0 + def method120: Int = 0 + def method121: Int = 0 + def method122: Int = 0 + def method123: Int = 0 + def method124: Int = 0 + def method125: Int = 0 + def method126: Int = 0 + def method127: Int = 0 + def method128: Int = 0 + def method129: Int = 0 + def method130: Int = 0 + def method131: Int = 0 + def method132: Int = 0 + def method133: Int = 0 + def method134: Int = 0 + def method135: Int = 0 + def method136: Int = 0 + def method137: Int = 0 + def method138: Int = 0 + def method139: Int = 0 + def method140: Int = 0 + def method141: Int = 0 + def method142: Int = 0 + def method143: Int = 0 + def method144: Int = 0 + def method145: Int = 0 + def method146: Int = 0 + def method147: Int = 0 + def method148: Int = 0 + def method149: Int = 0 + def method150: Int = 0 + def method151: Int = 0 + def method152: Int = 0 + def method153: Int = 0 + def method154: Int = 0 + def method155: Int = 0 + def method156: Int = 0 + def method157: Int = 0 + def method158: Int = 0 + def method159: Int = 0 + def method160: Int = 0 + def method161: Int = 0 + def method162: Int = 0 + def method163: Int = 0 + def method164: Int = 0 + def method165: Int = 0 + def method166: Int = 0 + def method167: Int = 0 + def method168: Int = 0 + def method169: Int = 0 + def method170: Int = 0 + def method171: Int = 0 + def method172: Int = 0 + def method173: Int = 0 + def method174: Int = 0 + def method175: Int = 0 + def method176: Int = 0 + def method177: Int = 0 + def method178: Int = 0 + def method179: Int = 0 + def method180: Int = 0 + def method181: Int = 0 + def method182: Int = 0 + def method183: Int = 0 + def method184: Int = 0 + def method185: Int = 0 + def method186: Int = 0 + def method187: Int = 0 + def method188: Int = 0 + def method189: Int = 0 + def method190: Int = 0 + def method191: Int = 0 + def method192: Int = 0 + def method193: Int = 0 + def method194: Int = 0 + def method195: Int = 0 + def method196: Int = 0 + def method197: Int = 0 + def method198: Int = 0 + def method199: Int = 0 + def method200: Int = 0 + def method201: Int = 0 + def method202: Int = 0 + def method203: Int = 0 + def method204: Int = 0 + def method205: Int = 0 + def method206: Int = 0 + def method207: Int = 0 + def method208: Int = 0 + def method209: Int = 0 + def method210: Int = 0 + def method211: Int = 0 + def method212: Int = 0 + def method213: Int = 0 + def method214: Int = 0 + def method215: Int = 0 + def method216: Int = 0 + def method217: Int = 0 + def method218: Int = 0 + def method219: Int = 0 + def method220: Int = 0 + def method221: Int = 0 + def method222: Int = 0 + def method223: Int = 0 + def method224: Int = 0 + def method225: Int = 0 + def method226: Int = 0 + def method227: Int = 0 + def method228: Int = 0 + def method229: Int = 0 + def method230: Int = 0 + def method231: Int = 0 + def method232: Int = 0 + def method233: Int = 0 + def method234: Int = 0 + def method235: Int = 0 + def method236: Int = 0 + def method237: Int = 0 + def method238: Int = 0 + def method239: Int = 0 + def method240: Int = 0 + def method241: Int = 0 + def method242: Int = 0 + def method243: Int = 0 + def method244: Int = 0 + def method245: Int = 0 + def method246: Int = 0 + def method247: Int = 0 + def method248: Int = 0 + def method249: Int = 0 + def method250: Int = 0 + def method251: Int = 0 + def method252: Int = 0 + def method253: Int = 0 + def method254: Int = 0 + def method255: Int = 0 + def method256: Int = 0 + def method257: Int = 0 + def method258: Int = 0 + def method259: Int = 0 + def method260: Int = 0 + def method261: Int = 0 + def method262: Int = 0 + def method263: Int = 0 + def method264: Int = 0 + def method265: Int = 0 + def method266: Int = 0 + def method267: Int = 0 + def method268: Int = 0 + def method269: Int = 0 + def method270: Int = 0 + def method271: Int = 0 + def method272: Int = 0 + def method273: Int = 0 + def method274: Int = 0 + def method275: Int = 0 + def method276: Int = 0 + def method277: Int = 0 + def method278: Int = 0 + def method279: Int = 0 + def method280: Int = 0 + def method281: Int = 0 + def method282: Int = 0 + def method283: Int = 0 + def method284: Int = 0 + def method285: Int = 0 + def method286: Int = 0 + def method287: Int = 0 + def method288: Int = 0 + def method289: Int = 0 + def method290: Int = 0 + def method291: Int = 0 + def method292: Int = 0 + def method293: Int = 0 + def method294: Int = 0 + def method295: Int = 0 + def method296: Int = 0 + def method297: Int = 0 + def method298: Int = 0 + def method299: Int = 0 + def method300: Int = 0 + def method301: Int = 0 + def method302: Int = 0 + def method303: Int = 0 + def method304: Int = 0 + def method305: Int = 0 + def method306: Int = 0 + def method307: Int = 0 + def method308: Int = 0 + def method309: Int = 0 + def method310: Int = 0 + def method311: Int = 0 + def method312: Int = 0 + def method313: Int = 0 + def method314: Int = 0 + def method315: Int = 0 + def method316: Int = 0 + def method317: Int = 0 + def method318: Int = 0 + def method319: Int = 0 + def method320: Int = 0 + def method321: Int = 0 + def method322: Int = 0 + def method323: Int = 0 + def method324: Int = 0 + def method325: Int = 0 + def method326: Int = 0 + def method327: Int = 0 + def method328: Int = 0 + def method329: Int = 0 + def method330: Int = 0 + def method331: Int = 0 + def method332: Int = 0 + def method333: Int = 0 + def method334: Int = 0 + def method335: Int = 0 + def method336: Int = 0 + def method337: Int = 0 + def method338: Int = 0 + def method339: Int = 0 + def method340: Int = 0 + def method341: Int = 0 + def method342: Int = 0 + def method343: Int = 0 + def method344: Int = 0 + def method345: Int = 0 + def method346: Int = 0 + def method347: Int = 0 + def method348: Int = 0 + def method349: Int = 0 + def method350: Int = 0 + def method351: Int = 0 + def method352: Int = 0 + def method353: Int = 0 + def method354: Int = 0 + def method355: Int = 0 + def method356: Int = 0 + def method357: Int = 0 + def method358: Int = 0 + def method359: Int = 0 + def method360: Int = 0 + def method361: Int = 0 + def method362: Int = 0 + def method363: Int = 0 + def method364: Int = 0 + def method365: Int = 0 + def method366: Int = 0 + def method367: Int = 0 + def method368: Int = 0 + def method369: Int = 0 + def method370: Int = 0 + def method371: Int = 0 + def method372: Int = 0 + def method373: Int = 0 + def method374: Int = 0 + def method375: Int = 0 + def method376: Int = 0 + def method377: Int = 0 + def method378: Int = 0 + def method379: Int = 0 + def method380: Int = 0 + def method381: Int = 0 + def method382: Int = 0 + def method383: Int = 0 + def method384: Int = 0 + def method385: Int = 0 + def method386: Int = 0 + def method387: Int = 0 + def method388: Int = 0 + def method389: Int = 0 + def method390: Int = 0 + def method391: Int = 0 + def method392: Int = 0 + def method393: Int = 0 + def method394: Int = 0 + def method395: Int = 0 + def method396: Int = 0 + def method397: Int = 0 + def method398: Int = 0 + def method399: Int = 0 + def method400: Int = 0 + def method401: Int = 0 + def method402: Int = 0 + def method403: Int = 0 + def method404: Int = 0 + def method405: Int = 0 + def method406: Int = 0 + def method407: Int = 0 + def method408: Int = 0 + def method409: Int = 0 + def method410: Int = 0 + def method411: Int = 0 + def method412: Int = 0 + def method413: Int = 0 + def method414: Int = 0 + def method415: Int = 0 + def method416: Int = 0 + def method417: Int = 0 + def method418: Int = 0 + def method419: Int = 0 + def method420: Int = 0 + def method421: Int = 0 + def method422: Int = 0 + def method423: Int = 0 + def method424: Int = 0 + def method425: Int = 0 + def method426: Int = 0 + def method427: Int = 0 + def method428: Int = 0 + def method429: Int = 0 + def method430: Int = 0 + def method431: Int = 0 + def method432: Int = 0 + def method433: Int = 0 + def method434: Int = 0 + def method435: Int = 0 + def method436: Int = 0 + def method437: Int = 0 + def method438: Int = 0 + def method439: Int = 0 + def method440: Int = 0 + def method441: Int = 0 + def method442: Int = 0 + def method443: Int = 0 + def method444: Int = 0 + def method445: Int = 0 + def method446: Int = 0 + def method447: Int = 0 + def method448: Int = 0 + def method449: Int = 0 + def method450: Int = 0 + def method451: Int = 0 + def method452: Int = 0 + def method453: Int = 0 + def method454: Int = 0 + def method455: Int = 0 + def method456: Int = 0 + def method457: Int = 0 + def method458: Int = 0 + def method459: Int = 0 + def method460: Int = 0 + def method461: Int = 0 + def method462: Int = 0 + def method463: Int = 0 + def method464: Int = 0 + def method465: Int = 0 + def method466: Int = 0 + def method467: Int = 0 + def method468: Int = 0 + def method469: Int = 0 + def method470: Int = 0 + def method471: Int = 0 + def method472: Int = 0 + def method473: Int = 0 + def method474: Int = 0 + def method475: Int = 0 + def method476: Int = 0 + def method477: Int = 0 + def method478: Int = 0 + def method479: Int = 0 + def method480: Int = 0 + def method481: Int = 0 + def method482: Int = 0 + def method483: Int = 0 + def method484: Int = 0 + def method485: Int = 0 + def method486: Int = 0 + def method487: Int = 0 + def method488: Int = 0 + def method489: Int = 0 + def method490: Int = 0 + def method491: Int = 0 + def method492: Int = 0 + def method493: Int = 0 + def method494: Int = 0 + def method495: Int = 0 + def method496: Int = 0 + def method497: Int = 0 + def method498: Int = 0 + def method499: Int = 0 + def method500: Int = 0 + def method501: Int = 0 + def method502: Int = 0 + def method503: Int = 0 + def method504: Int = 0 + def method505: Int = 0 + def method506: Int = 0 + def method507: Int = 0 + def method508: Int = 0 + def method509: Int = 0 + def method510: Int = 0 + def method511: Int = 0 + def method512: Int = 0 + def method513: Int = 0 + def method514: Int = 0 + def method515: Int = 0 + def method516: Int = 0 + def method517: Int = 0 + def method518: Int = 0 + def method519: Int = 0 + def method520: Int = 0 + def method521: Int = 0 + def method522: Int = 0 + def method523: Int = 0 + def method524: Int = 0 + def method525: Int = 0 + def method526: Int = 0 + def method527: Int = 0 + def method528: Int = 0 + def method529: Int = 0 + def method530: Int = 0 + def method531: Int = 0 + def method532: Int = 0 + def method533: Int = 0 + def method534: Int = 0 + def method535: Int = 0 + def method536: Int = 0 + def method537: Int = 0 + def method538: Int = 0 + def method539: Int = 0 + def method540: Int = 0 + def method541: Int = 0 + def method542: Int = 0 + def method543: Int = 0 + def method544: Int = 0 + def method545: Int = 0 + def method546: Int = 0 + def method547: Int = 0 + def method548: Int = 0 + def method549: Int = 0 + def method550: Int = 0 + def method551: Int = 0 + def method552: Int = 0 + def method553: Int = 0 + def method554: Int = 0 + def method555: Int = 0 + def method556: Int = 0 + def method557: Int = 0 + def method558: Int = 0 + def method559: Int = 0 + def method560: Int = 0 + def method561: Int = 0 + def method562: Int = 0 + def method563: Int = 0 + def method564: Int = 0 + def method565: Int = 0 + def method566: Int = 0 + def method567: Int = 0 + def method568: Int = 0 + def method569: Int = 0 + def method570: Int = 0 + def method571: Int = 0 + def method572: Int = 0 + def method573: Int = 0 + def method574: Int = 0 + def method575: Int = 0 + def method576: Int = 0 + def method577: Int = 0 + def method578: Int = 0 + def method579: Int = 0 + def method580: Int = 0 + def method581: Int = 0 + def method582: Int = 0 + def method583: Int = 0 + def method584: Int = 0 + def method585: Int = 0 + def method586: Int = 0 + def method587: Int = 0 + def method588: Int = 0 + def method589: Int = 0 + def method590: Int = 0 + def method591: Int = 0 + def method592: Int = 0 + def method593: Int = 0 + def method594: Int = 0 + def method595: Int = 0 + def method596: Int = 0 + def method597: Int = 0 + def method598: Int = 0 + def method599: Int = 0 + def method600: Int = 0 + def method601: Int = 0 + def method602: Int = 0 + def method603: Int = 0 + def method604: Int = 0 + def method605: Int = 0 + def method606: Int = 0 + def method607: Int = 0 + def method608: Int = 0 + def method609: Int = 0 + def method610: Int = 0 + def method611: Int = 0 + def method612: Int = 0 + def method613: Int = 0 + def method614: Int = 0 + def method615: Int = 0 + def method616: Int = 0 + def method617: Int = 0 + def method618: Int = 0 + def method619: Int = 0 + def method620: Int = 0 + def method621: Int = 0 + def method622: Int = 0 + def method623: Int = 0 + def method624: Int = 0 + def method625: Int = 0 + def method626: Int = 0 + def method627: Int = 0 + def method628: Int = 0 + def method629: Int = 0 + def method630: Int = 0 + def method631: Int = 0 + def method632: Int = 0 + def method633: Int = 0 + def method634: Int = 0 + def method635: Int = 0 + def method636: Int = 0 + def method637: Int = 0 + def method638: Int = 0 + def method639: Int = 0 + def method640: Int = 0 + def method641: Int = 0 + def method642: Int = 0 + def method643: Int = 0 + def method644: Int = 0 + def method645: Int = 0 + def method646: Int = 0 + def method647: Int = 0 + def method648: Int = 0 + def method649: Int = 0 + def method650: Int = 0 + def method651: Int = 0 + def method652: Int = 0 + def method653: Int = 0 + def method654: Int = 0 + def method655: Int = 0 + def method656: Int = 0 + def method657: Int = 0 + def method658: Int = 0 + def method659: Int = 0 + def method660: Int = 0 + def method661: Int = 0 + def method662: Int = 0 + def method663: Int = 0 + def method664: Int = 0 + def method665: Int = 0 + def method666: Int = 0 + def method667: Int = 0 + def method668: Int = 0 + def method669: Int = 0 + def method670: Int = 0 + def method671: Int = 0 + def method672: Int = 0 + def method673: Int = 0 + def method674: Int = 0 + def method675: Int = 0 + def method676: Int = 0 + def method677: Int = 0 + def method678: Int = 0 + def method679: Int = 0 + def method680: Int = 0 + def method681: Int = 0 + def method682: Int = 0 + def method683: Int = 0 + def method684: Int = 0 + def method685: Int = 0 + def method686: Int = 0 + def method687: Int = 0 + def method688: Int = 0 + def method689: Int = 0 + def method690: Int = 0 + def method691: Int = 0 + def method692: Int = 0 + def method693: Int = 0 + def method694: Int = 0 + def method695: Int = 0 + def method696: Int = 0 + def method697: Int = 0 + def method698: Int = 0 + def method699: Int = 0 + def method700: Int = 0 + def method701: Int = 0 + def method702: Int = 0 + def method703: Int = 0 + def method704: Int = 0 + def method705: Int = 0 + def method706: Int = 0 + def method707: Int = 0 + def method708: Int = 0 + def method709: Int = 0 + def method710: Int = 0 + def method711: Int = 0 + def method712: Int = 0 + def method713: Int = 0 + def method714: Int = 0 + def method715: Int = 0 + def method716: Int = 0 + def method717: Int = 0 + def method718: Int = 0 + def method719: Int = 0 + def method720: Int = 0 + def method721: Int = 0 + def method722: Int = 0 + def method723: Int = 0 + def method724: Int = 0 + def method725: Int = 0 + def method726: Int = 0 + def method727: Int = 0 + def method728: Int = 0 + def method729: Int = 0 + def method730: Int = 0 + def method731: Int = 0 + def method732: Int = 0 + def method733: Int = 0 + def method734: Int = 0 + def method735: Int = 0 + def method736: Int = 0 + def method737: Int = 0 + def method738: Int = 0 + def method739: Int = 0 + def method740: Int = 0 + def method741: Int = 0 + def method742: Int = 0 + def method743: Int = 0 + def method744: Int = 0 + def method745: Int = 0 + def method746: Int = 0 + def method747: Int = 0 + def method748: Int = 0 + def method749: Int = 0 + def method750: Int = 0 + def method751: Int = 0 + def method752: Int = 0 + def method753: Int = 0 + def method754: Int = 0 + def method755: Int = 0 + def method756: Int = 0 + def method757: Int = 0 + def method758: Int = 0 + def method759: Int = 0 + def method760: Int = 0 + def method761: Int = 0 + def method762: Int = 0 + def method763: Int = 0 + def method764: Int = 0 + def method765: Int = 0 + def method766: Int = 0 + def method767: Int = 0 + def method768: Int = 0 + def method769: Int = 0 + def method770: Int = 0 + def method771: Int = 0 + def method772: Int = 0 + def method773: Int = 0 + def method774: Int = 0 + def method775: Int = 0 + def method776: Int = 0 + def method777: Int = 0 + def method778: Int = 0 + def method779: Int = 0 + def method780: Int = 0 + def method781: Int = 0 + def method782: Int = 0 + def method783: Int = 0 + def method784: Int = 0 + def method785: Int = 0 + def method786: Int = 0 + def method787: Int = 0 + def method788: Int = 0 + def method789: Int = 0 + def method790: Int = 0 + def method791: Int = 0 + def method792: Int = 0 + def method793: Int = 0 + def method794: Int = 0 + def method795: Int = 0 + def method796: Int = 0 + def method797: Int = 0 + def method798: Int = 0 + def method799: Int = 0 + def method800: Int = 0 + def method801: Int = 0 + def method802: Int = 0 + def method803: Int = 0 + def method804: Int = 0 + def method805: Int = 0 + def method806: Int = 0 + def method807: Int = 0 + def method808: Int = 0 + def method809: Int = 0 + def method810: Int = 0 + def method811: Int = 0 + def method812: Int = 0 + def method813: Int = 0 + def method814: Int = 0 + def method815: Int = 0 + def method816: Int = 0 + def method817: Int = 0 + def method818: Int = 0 + def method819: Int = 0 + def method820: Int = 0 + def method821: Int = 0 + def method822: Int = 0 + def method823: Int = 0 + def method824: Int = 0 + def method825: Int = 0 + def method826: Int = 0 + def method827: Int = 0 + def method828: Int = 0 + def method829: Int = 0 + def method830: Int = 0 + def method831: Int = 0 + def method832: Int = 0 + def method833: Int = 0 + def method834: Int = 0 + def method835: Int = 0 + def method836: Int = 0 + def method837: Int = 0 + def method838: Int = 0 + def method839: Int = 0 + def method840: Int = 0 + def method841: Int = 0 + def method842: Int = 0 + def method843: Int = 0 + def method844: Int = 0 + def method845: Int = 0 + def method846: Int = 0 + def method847: Int = 0 + def method848: Int = 0 + def method849: Int = 0 + def method850: Int = 0 + def method851: Int = 0 + def method852: Int = 0 + def method853: Int = 0 + def method854: Int = 0 + def method855: Int = 0 + def method856: Int = 0 + def method857: Int = 0 + def method858: Int = 0 + def method859: Int = 0 + def method860: Int = 0 + def method861: Int = 0 + def method862: Int = 0 + def method863: Int = 0 + def method864: Int = 0 + def method865: Int = 0 + def method866: Int = 0 + def method867: Int = 0 + def method868: Int = 0 + def method869: Int = 0 + def method870: Int = 0 + def method871: Int = 0 + def method872: Int = 0 + def method873: Int = 0 + def method874: Int = 0 + def method875: Int = 0 + def method876: Int = 0 + def method877: Int = 0 + def method878: Int = 0 + def method879: Int = 0 + def method880: Int = 0 + def method881: Int = 0 + def method882: Int = 0 + def method883: Int = 0 + def method884: Int = 0 + def method885: Int = 0 + def method886: Int = 0 + def method887: Int = 0 + def method888: Int = 0 + def method889: Int = 0 + def method890: Int = 0 + def method891: Int = 0 + def method892: Int = 0 + def method893: Int = 0 + def method894: Int = 0 + def method895: Int = 0 + def method896: Int = 0 + def method897: Int = 0 + def method898: Int = 0 + def method899: Int = 0 + def method900: Int = 0 + def method901: Int = 0 + def method902: Int = 0 + def method903: Int = 0 + def method904: Int = 0 + def method905: Int = 0 + def method906: Int = 0 + def method907: Int = 0 + def method908: Int = 0 + def method909: Int = 0 + def method910: Int = 0 + def method911: Int = 0 + def method912: Int = 0 + def method913: Int = 0 + def method914: Int = 0 + def method915: Int = 0 + def method916: Int = 0 + def method917: Int = 0 + def method918: Int = 0 + def method919: Int = 0 + def method920: Int = 0 + def method921: Int = 0 + def method922: Int = 0 + def method923: Int = 0 + def method924: Int = 0 + def method925: Int = 0 + def method926: Int = 0 + def method927: Int = 0 + def method928: Int = 0 + def method929: Int = 0 + def method930: Int = 0 + def method931: Int = 0 + def method932: Int = 0 + def method933: Int = 0 + def method934: Int = 0 + def method935: Int = 0 + def method936: Int = 0 + def method937: Int = 0 + def method938: Int = 0 + def method939: Int = 0 + def method940: Int = 0 + def method941: Int = 0 + def method942: Int = 0 + def method943: Int = 0 + def method944: Int = 0 + def method945: Int = 0 + def method946: Int = 0 + def method947: Int = 0 + def method948: Int = 0 + def method949: Int = 0 + def method950: Int = 0 + def method951: Int = 0 + def method952: Int = 0 + def method953: Int = 0 + def method954: Int = 0 + def method955: Int = 0 + def method956: Int = 0 + def method957: Int = 0 + def method958: Int = 0 + def method959: Int = 0 + def method960: Int = 0 + def method961: Int = 0 + def method962: Int = 0 + def method963: Int = 0 + def method964: Int = 0 + def method965: Int = 0 + def method966: Int = 0 + def method967: Int = 0 + def method968: Int = 0 + def method969: Int = 0 + def method970: Int = 0 + def method971: Int = 0 + def method972: Int = 0 + def method973: Int = 0 + def method974: Int = 0 + def method975: Int = 0 + def method976: Int = 0 + def method977: Int = 0 + def method978: Int = 0 + def method979: Int = 0 + def method980: Int = 0 + def method981: Int = 0 + def method982: Int = 0 + def method983: Int = 0 + def method984: Int = 0 + def method985: Int = 0 + def method986: Int = 0 + def method987: Int = 0 + def method988: Int = 0 + def method989: Int = 0 + def method990: Int = 0 + def method991: Int = 0 + def method992: Int = 0 + def method993: Int = 0 + def method994: Int = 0 + def method995: Int = 0 + def method996: Int = 0 + def method997: Int = 0 + def method998: Int = 0 + def method999: Int = 0 + def method1000: Int = 0 + def method1001: Int = 0 + def method1002: Int = 0 + def method1003: Int = 0 + def method1004: Int = 0 + def method1005: Int = 0 + def method1006: Int = 0 + def method1007: Int = 0 + def method1008: Int = 0 + def method1009: Int = 0 + def method1010: Int = 0 + def method1011: Int = 0 + def method1012: Int = 0 + def method1013: Int = 0 + def method1014: Int = 0 + def method1015: Int = 0 + def method1016: Int = 0 + def method1017: Int = 0 + def method1018: Int = 0 + def method1019: Int = 0 + def method1020: Int = 0 + def method1021: Int = 0 + def method1022: Int = 0 + def method1023: Int = 0 + def method1024: Int = 0 + def method1025: Int = 0 + def method1026: Int = 0 + def method1027: Int = 0 + def method1028: Int = 0 + def method1029: Int = 0 + def method1030: Int = 0 + def method1031: Int = 0 + def method1032: Int = 0 + def method1033: Int = 0 + def method1034: Int = 0 + def method1035: Int = 0 + def method1036: Int = 0 + def method1037: Int = 0 + def method1038: Int = 0 + def method1039: Int = 0 + def method1040: Int = 0 + def method1041: Int = 0 + def method1042: Int = 0 + def method1043: Int = 0 + def method1044: Int = 0 + def method1045: Int = 0 + def method1046: Int = 0 + def method1047: Int = 0 + def method1048: Int = 0 + def method1049: Int = 0 + def method1050: Int = 0 + def method1051: Int = 0 + def method1052: Int = 0 + def method1053: Int = 0 + def method1054: Int = 0 + def method1055: Int = 0 + def method1056: Int = 0 + def method1057: Int = 0 + def method1058: Int = 0 + def method1059: Int = 0 + def method1060: Int = 0 + def method1061: Int = 0 + def method1062: Int = 0 + def method1063: Int = 0 + def method1064: Int = 0 + def method1065: Int = 0 + def method1066: Int = 0 + def method1067: Int = 0 + def method1068: Int = 0 + def method1069: Int = 0 + def method1070: Int = 0 + def method1071: Int = 0 + def method1072: Int = 0 + def method1073: Int = 0 + def method1074: Int = 0 + def method1075: Int = 0 + def method1076: Int = 0 + def method1077: Int = 0 + def method1078: Int = 0 + def method1079: Int = 0 + def method1080: Int = 0 + def method1081: Int = 0 + def method1082: Int = 0 + def method1083: Int = 0 + def method1084: Int = 0 + def method1085: Int = 0 + def method1086: Int = 0 + def method1087: Int = 0 + def method1088: Int = 0 + def method1089: Int = 0 + def method1090: Int = 0 + def method1091: Int = 0 + def method1092: Int = 0 + def method1093: Int = 0 + def method1094: Int = 0 + def method1095: Int = 0 + def method1096: Int = 0 + def method1097: Int = 0 + def method1098: Int = 0 + def method1099: Int = 0 + def method1100: Int = 0 + def method1101: Int = 0 + def method1102: Int = 0 + def method1103: Int = 0 + def method1104: Int = 0 + def method1105: Int = 0 + def method1106: Int = 0 + def method1107: Int = 0 + def method1108: Int = 0 + def method1109: Int = 0 + def method1110: Int = 0 + def method1111: Int = 0 + def method1112: Int = 0 + def method1113: Int = 0 + def method1114: Int = 0 + def method1115: Int = 0 + def method1116: Int = 0 + def method1117: Int = 0 + def method1118: Int = 0 + def method1119: Int = 0 + def method1120: Int = 0 + def method1121: Int = 0 + def method1122: Int = 0 + def method1123: Int = 0 + def method1124: Int = 0 + def method1125: Int = 0 + def method1126: Int = 0 + def method1127: Int = 0 + def method1128: Int = 0 + def method1129: Int = 0 + def method1130: Int = 0 + def method1131: Int = 0 + def method1132: Int = 0 + def method1133: Int = 0 + def method1134: Int = 0 + def method1135: Int = 0 + def method1136: Int = 0 + def method1137: Int = 0 + def method1138: Int = 0 + def method1139: Int = 0 + def method1140: Int = 0 + def method1141: Int = 0 + def method1142: Int = 0 + def method1143: Int = 0 + def method1144: Int = 0 + def method1145: Int = 0 + def method1146: Int = 0 + def method1147: Int = 0 + def method1148: Int = 0 + def method1149: Int = 0 + def method1150: Int = 0 + def method1151: Int = 0 + def method1152: Int = 0 + def method1153: Int = 0 + def method1154: Int = 0 + def method1155: Int = 0 + def method1156: Int = 0 + def method1157: Int = 0 + def method1158: Int = 0 + def method1159: Int = 0 + def method1160: Int = 0 + def method1161: Int = 0 + def method1162: Int = 0 + def method1163: Int = 0 + def method1164: Int = 0 + def method1165: Int = 0 + def method1166: Int = 0 + def method1167: Int = 0 + def method1168: Int = 0 + def method1169: Int = 0 + def method1170: Int = 0 + def method1171: Int = 0 + def method1172: Int = 0 + def method1173: Int = 0 + def method1174: Int = 0 + def method1175: Int = 0 + def method1176: Int = 0 + def method1177: Int = 0 + def method1178: Int = 0 + def method1179: Int = 0 + def method1180: Int = 0 + def method1181: Int = 0 + def method1182: Int = 0 + def method1183: Int = 0 + def method1184: Int = 0 + def method1185: Int = 0 + def method1186: Int = 0 + def method1187: Int = 0 + def method1188: Int = 0 + def method1189: Int = 0 + def method1190: Int = 0 + def method1191: Int = 0 + def method1192: Int = 0 + def method1193: Int = 0 + def method1194: Int = 0 + def method1195: Int = 0 + def method1196: Int = 0 + def method1197: Int = 0 + def method1198: Int = 0 + def method1199: Int = 0 + def method1200: Int = 0 + def method1201: Int = 0 + def method1202: Int = 0 + def method1203: Int = 0 + def method1204: Int = 0 + def method1205: Int = 0 + def method1206: Int = 0 + def method1207: Int = 0 + def method1208: Int = 0 + def method1209: Int = 0 + def method1210: Int = 0 + def method1211: Int = 0 + def method1212: Int = 0 + def method1213: Int = 0 + def method1214: Int = 0 + def method1215: Int = 0 + def method1216: Int = 0 + def method1217: Int = 0 + def method1218: Int = 0 + def method1219: Int = 0 + def method1220: Int = 0 + def method1221: Int = 0 + def method1222: Int = 0 + def method1223: Int = 0 + def method1224: Int = 0 + def method1225: Int = 0 + def method1226: Int = 0 + def method1227: Int = 0 + def method1228: Int = 0 + def method1229: Int = 0 + def method1230: Int = 0 + def method1231: Int = 0 + def method1232: Int = 0 + def method1233: Int = 0 + def method1234: Int = 0 + def method1235: Int = 0 + def method1236: Int = 0 + def method1237: Int = 0 + def method1238: Int = 0 + def method1239: Int = 0 + def method1240: Int = 0 + def method1241: Int = 0 + def method1242: Int = 0 + def method1243: Int = 0 + def method1244: Int = 0 + def method1245: Int = 0 + def method1246: Int = 0 + def method1247: Int = 0 + def method1248: Int = 0 + def method1249: Int = 0 + def method1250: Int = 0 + def method1251: Int = 0 + def method1252: Int = 0 + def method1253: Int = 0 + def method1254: Int = 0 + def method1255: Int = 0 + def method1256: Int = 0 + def method1257: Int = 0 + def method1258: Int = 0 + def method1259: Int = 0 + def method1260: Int = 0 + def method1261: Int = 0 + def method1262: Int = 0 + def method1263: Int = 0 + def method1264: Int = 0 + def method1265: Int = 0 + def method1266: Int = 0 + def method1267: Int = 0 + def method1268: Int = 0 + def method1269: Int = 0 + def method1270: Int = 0 + def method1271: Int = 0 + def method1272: Int = 0 + def method1273: Int = 0 + def method1274: Int = 0 + def method1275: Int = 0 + def method1276: Int = 0 + def method1277: Int = 0 + def method1278: Int = 0 + def method1279: Int = 0 + def method1280: Int = 0 + def method1281: Int = 0 + def method1282: Int = 0 + def method1283: Int = 0 + def method1284: Int = 0 + def method1285: Int = 0 + def method1286: Int = 0 + def method1287: Int = 0 + def method1288: Int = 0 + def method1289: Int = 0 + def method1290: Int = 0 + def method1291: Int = 0 + def method1292: Int = 0 + def method1293: Int = 0 + def method1294: Int = 0 + def method1295: Int = 0 + def method1296: Int = 0 + def method1297: Int = 0 + def method1298: Int = 0 + def method1299: Int = 0 + def method1300: Int = 0 + def method1301: Int = 0 + def method1302: Int = 0 + def method1303: Int = 0 + def method1304: Int = 0 + def method1305: Int = 0 + def method1306: Int = 0 + def method1307: Int = 0 + def method1308: Int = 0 + def method1309: Int = 0 + def method1310: Int = 0 + def method1311: Int = 0 + def method1312: Int = 0 + def method1313: Int = 0 + def method1314: Int = 0 + def method1315: Int = 0 + def method1316: Int = 0 + def method1317: Int = 0 + def method1318: Int = 0 + def method1319: Int = 0 + def method1320: Int = 0 + def method1321: Int = 0 + def method1322: Int = 0 + def method1323: Int = 0 + def method1324: Int = 0 + def method1325: Int = 0 + def method1326: Int = 0 + def method1327: Int = 0 + def method1328: Int = 0 + def method1329: Int = 0 + def method1330: Int = 0 + def method1331: Int = 0 + def method1332: Int = 0 + def method1333: Int = 0 + def method1334: Int = 0 + def method1335: Int = 0 + def method1336: Int = 0 + def method1337: Int = 0 + def method1338: Int = 0 + def method1339: Int = 0 + def method1340: Int = 0 + def method1341: Int = 0 + def method1342: Int = 0 + def method1343: Int = 0 + def method1344: Int = 0 + def method1345: Int = 0 + def method1346: Int = 0 + def method1347: Int = 0 + def method1348: Int = 0 + def method1349: Int = 0 + def method1350: Int = 0 + def method1351: Int = 0 + def method1352: Int = 0 + def method1353: Int = 0 + def method1354: Int = 0 + def method1355: Int = 0 + def method1356: Int = 0 + def method1357: Int = 0 + def method1358: Int = 0 + def method1359: Int = 0 + def method1360: Int = 0 + def method1361: Int = 0 + def method1362: Int = 0 + def method1363: Int = 0 + def method1364: Int = 0 + def method1365: Int = 0 + def method1366: Int = 0 + def method1367: Int = 0 + def method1368: Int = 0 + def method1369: Int = 0 + def method1370: Int = 0 + def method1371: Int = 0 + def method1372: Int = 0 + def method1373: Int = 0 + def method1374: Int = 0 + def method1375: Int = 0 + def method1376: Int = 0 + def method1377: Int = 0 + def method1378: Int = 0 + def method1379: Int = 0 + def method1380: Int = 0 + def method1381: Int = 0 + def method1382: Int = 0 + def method1383: Int = 0 + def method1384: Int = 0 + def method1385: Int = 0 + def method1386: Int = 0 + def method1387: Int = 0 + def method1388: Int = 0 + def method1389: Int = 0 + def method1390: Int = 0 + def method1391: Int = 0 + def method1392: Int = 0 + def method1393: Int = 0 + def method1394: Int = 0 + def method1395: Int = 0 + def method1396: Int = 0 + def method1397: Int = 0 + def method1398: Int = 0 + def method1399: Int = 0 + def method1400: Int = 0 + def method1401: Int = 0 + def method1402: Int = 0 + def method1403: Int = 0 + def method1404: Int = 0 + def method1405: Int = 0 + def method1406: Int = 0 + def method1407: Int = 0 + def method1408: Int = 0 + def method1409: Int = 0 + def method1410: Int = 0 + def method1411: Int = 0 + def method1412: Int = 0 + def method1413: Int = 0 + def method1414: Int = 0 + def method1415: Int = 0 + def method1416: Int = 0 + def method1417: Int = 0 + def method1418: Int = 0 + def method1419: Int = 0 + def method1420: Int = 0 + def method1421: Int = 0 + def method1422: Int = 0 + def method1423: Int = 0 + def method1424: Int = 0 + def method1425: Int = 0 + def method1426: Int = 0 + def method1427: Int = 0 + def method1428: Int = 0 + def method1429: Int = 0 + def method1430: Int = 0 + def method1431: Int = 0 + def method1432: Int = 0 + def method1433: Int = 0 + def method1434: Int = 0 + def method1435: Int = 0 + def method1436: Int = 0 + def method1437: Int = 0 + def method1438: Int = 0 + def method1439: Int = 0 + def method1440: Int = 0 + def method1441: Int = 0 + def method1442: Int = 0 + def method1443: Int = 0 + def method1444: Int = 0 + def method1445: Int = 0 + def method1446: Int = 0 + def method1447: Int = 0 + def method1448: Int = 0 + def method1449: Int = 0 + def method1450: Int = 0 + def method1451: Int = 0 + def method1452: Int = 0 + def method1453: Int = 0 + def method1454: Int = 0 + def method1455: Int = 0 + def method1456: Int = 0 + def method1457: Int = 0 + def method1458: Int = 0 + def method1459: Int = 0 + def method1460: Int = 0 + def method1461: Int = 0 + def method1462: Int = 0 + def method1463: Int = 0 + def method1464: Int = 0 + def method1465: Int = 0 + def method1466: Int = 0 + def method1467: Int = 0 + def method1468: Int = 0 + def method1469: Int = 0 + def method1470: Int = 0 + def method1471: Int = 0 + def method1472: Int = 0 + def method1473: Int = 0 + def method1474: Int = 0 + def method1475: Int = 0 + def method1476: Int = 0 + def method1477: Int = 0 + def method1478: Int = 0 + def method1479: Int = 0 + def method1480: Int = 0 + def method1481: Int = 0 + def method1482: Int = 0 + def method1483: Int = 0 + def method1484: Int = 0 + def method1485: Int = 0 + def method1486: Int = 0 + def method1487: Int = 0 + def method1488: Int = 0 + def method1489: Int = 0 + def method1490: Int = 0 + def method1491: Int = 0 + def method1492: Int = 0 + def method1493: Int = 0 + def method1494: Int = 0 + def method1495: Int = 0 + def method1496: Int = 0 + def method1497: Int = 0 + def method1498: Int = 0 + def method1499: Int = 0 + def method1500: Int = 0 + def method1501: Int = 0 + def method1502: Int = 0 + def method1503: Int = 0 + def method1504: Int = 0 + def method1505: Int = 0 + def method1506: Int = 0 + def method1507: Int = 0 + def method1508: Int = 0 + def method1509: Int = 0 + def method1510: Int = 0 + def method1511: Int = 0 + def method1512: Int = 0 + def method1513: Int = 0 + def method1514: Int = 0 + def method1515: Int = 0 + def method1516: Int = 0 + def method1517: Int = 0 + def method1518: Int = 0 + def method1519: Int = 0 + def method1520: Int = 0 + def method1521: Int = 0 + def method1522: Int = 0 + def method1523: Int = 0 + def method1524: Int = 0 + def method1525: Int = 0 + def method1526: Int = 0 + def method1527: Int = 0 + def method1528: Int = 0 + def method1529: Int = 0 + def method1530: Int = 0 + def method1531: Int = 0 + def method1532: Int = 0 + def method1533: Int = 0 + def method1534: Int = 0 + def method1535: Int = 0 + def method1536: Int = 0 + def method1537: Int = 0 + def method1538: Int = 0 + def method1539: Int = 0 + def method1540: Int = 0 + def method1541: Int = 0 + def method1542: Int = 0 + def method1543: Int = 0 + def method1544: Int = 0 + def method1545: Int = 0 + def method1546: Int = 0 + def method1547: Int = 0 + def method1548: Int = 0 + def method1549: Int = 0 + def method1550: Int = 0 + def method1551: Int = 0 + def method1552: Int = 0 + def method1553: Int = 0 + def method1554: Int = 0 + def method1555: Int = 0 + def method1556: Int = 0 + def method1557: Int = 0 + def method1558: Int = 0 + def method1559: Int = 0 + def method1560: Int = 0 + def method1561: Int = 0 + def method1562: Int = 0 + def method1563: Int = 0 + def method1564: Int = 0 + def method1565: Int = 0 + def method1566: Int = 0 + def method1567: Int = 0 + def method1568: Int = 0 + def method1569: Int = 0 + def method1570: Int = 0 + def method1571: Int = 0 + def method1572: Int = 0 + def method1573: Int = 0 + def method1574: Int = 0 + def method1575: Int = 0 + def method1576: Int = 0 + def method1577: Int = 0 + def method1578: Int = 0 + def method1579: Int = 0 + def method1580: Int = 0 + def method1581: Int = 0 + def method1582: Int = 0 + def method1583: Int = 0 + def method1584: Int = 0 + def method1585: Int = 0 + def method1586: Int = 0 + def method1587: Int = 0 + def method1588: Int = 0 + def method1589: Int = 0 + def method1590: Int = 0 + def method1591: Int = 0 + def method1592: Int = 0 + def method1593: Int = 0 + def method1594: Int = 0 + def method1595: Int = 0 + def method1596: Int = 0 + def method1597: Int = 0 + def method1598: Int = 0 + def method1599: Int = 0 + def method1600: Int = 0 + def method1601: Int = 0 + def method1602: Int = 0 + def method1603: Int = 0 + def method1604: Int = 0 + def method1605: Int = 0 + def method1606: Int = 0 + def method1607: Int = 0 + def method1608: Int = 0 + def method1609: Int = 0 + def method1610: Int = 0 + def method1611: Int = 0 + def method1612: Int = 0 + def method1613: Int = 0 + def method1614: Int = 0 + def method1615: Int = 0 + def method1616: Int = 0 + def method1617: Int = 0 + def method1618: Int = 0 + def method1619: Int = 0 + def method1620: Int = 0 + def method1621: Int = 0 + def method1622: Int = 0 + def method1623: Int = 0 + def method1624: Int = 0 + def method1625: Int = 0 + def method1626: Int = 0 + def method1627: Int = 0 + def method1628: Int = 0 + def method1629: Int = 0 + def method1630: Int = 0 + def method1631: Int = 0 + def method1632: Int = 0 + def method1633: Int = 0 + def method1634: Int = 0 + def method1635: Int = 0 + def method1636: Int = 0 + def method1637: Int = 0 + def method1638: Int = 0 + def method1639: Int = 0 + def method1640: Int = 0 + def method1641: Int = 0 + def method1642: Int = 0 + def method1643: Int = 0 + def method1644: Int = 0 + def method1645: Int = 0 + def method1646: Int = 0 + def method1647: Int = 0 + def method1648: Int = 0 + def method1649: Int = 0 + def method1650: Int = 0 + def method1651: Int = 0 + def method1652: Int = 0 + def method1653: Int = 0 + def method1654: Int = 0 + def method1655: Int = 0 + def method1656: Int = 0 + def method1657: Int = 0 + def method1658: Int = 0 + def method1659: Int = 0 + def method1660: Int = 0 + def method1661: Int = 0 + def method1662: Int = 0 + def method1663: Int = 0 + def method1664: Int = 0 + def method1665: Int = 0 + def method1666: Int = 0 + def method1667: Int = 0 + def method1668: Int = 0 + def method1669: Int = 0 + def method1670: Int = 0 + def method1671: Int = 0 + def method1672: Int = 0 + def method1673: Int = 0 + def method1674: Int = 0 + def method1675: Int = 0 + def method1676: Int = 0 + def method1677: Int = 0 + def method1678: Int = 0 + def method1679: Int = 0 + def method1680: Int = 0 + def method1681: Int = 0 + def method1682: Int = 0 + def method1683: Int = 0 + def method1684: Int = 0 + def method1685: Int = 0 + def method1686: Int = 0 + def method1687: Int = 0 + def method1688: Int = 0 + def method1689: Int = 0 + def method1690: Int = 0 + def method1691: Int = 0 + def method1692: Int = 0 + def method1693: Int = 0 + def method1694: Int = 0 + def method1695: Int = 0 + def method1696: Int = 0 + def method1697: Int = 0 + def method1698: Int = 0 + def method1699: Int = 0 + def method1700: Int = 0 + def method1701: Int = 0 + def method1702: Int = 0 + def method1703: Int = 0 + def method1704: Int = 0 + def method1705: Int = 0 + def method1706: Int = 0 + def method1707: Int = 0 + def method1708: Int = 0 + def method1709: Int = 0 + def method1710: Int = 0 + def method1711: Int = 0 + def method1712: Int = 0 + def method1713: Int = 0 + def method1714: Int = 0 + def method1715: Int = 0 + def method1716: Int = 0 + def method1717: Int = 0 + def method1718: Int = 0 + def method1719: Int = 0 + def method1720: Int = 0 + def method1721: Int = 0 + def method1722: Int = 0 + def method1723: Int = 0 + def method1724: Int = 0 + def method1725: Int = 0 + def method1726: Int = 0 + def method1727: Int = 0 + def method1728: Int = 0 + def method1729: Int = 0 + def method1730: Int = 0 + def method1731: Int = 0 + def method1732: Int = 0 + def method1733: Int = 0 + def method1734: Int = 0 + def method1735: Int = 0 + def method1736: Int = 0 + def method1737: Int = 0 + def method1738: Int = 0 + def method1739: Int = 0 + def method1740: Int = 0 + def method1741: Int = 0 + def method1742: Int = 0 + def method1743: Int = 0 + def method1744: Int = 0 + def method1745: Int = 0 + def method1746: Int = 0 + def method1747: Int = 0 + def method1748: Int = 0 + def method1749: Int = 0 + def method1750: Int = 0 + def method1751: Int = 0 + def method1752: Int = 0 + def method1753: Int = 0 + def method1754: Int = 0 + def method1755: Int = 0 + def method1756: Int = 0 + def method1757: Int = 0 + def method1758: Int = 0 + def method1759: Int = 0 + def method1760: Int = 0 + def method1761: Int = 0 + def method1762: Int = 0 + def method1763: Int = 0 + def method1764: Int = 0 + def method1765: Int = 0 + def method1766: Int = 0 + def method1767: Int = 0 + def method1768: Int = 0 + def method1769: Int = 0 + def method1770: Int = 0 + def method1771: Int = 0 + def method1772: Int = 0 + def method1773: Int = 0 + def method1774: Int = 0 + def method1775: Int = 0 + def method1776: Int = 0 + def method1777: Int = 0 + def method1778: Int = 0 + def method1779: Int = 0 + def method1780: Int = 0 + def method1781: Int = 0 + def method1782: Int = 0 + def method1783: Int = 0 + def method1784: Int = 0 + def method1785: Int = 0 + def method1786: Int = 0 + def method1787: Int = 0 + def method1788: Int = 0 + def method1789: Int = 0 + def method1790: Int = 0 + def method1791: Int = 0 + def method1792: Int = 0 + def method1793: Int = 0 + def method1794: Int = 0 + def method1795: Int = 0 + def method1796: Int = 0 + def method1797: Int = 0 + def method1798: Int = 0 + def method1799: Int = 0 + def method1800: Int = 0 + def method1801: Int = 0 + def method1802: Int = 0 + def method1803: Int = 0 + def method1804: Int = 0 + def method1805: Int = 0 + def method1806: Int = 0 + def method1807: Int = 0 + def method1808: Int = 0 + def method1809: Int = 0 + def method1810: Int = 0 + def method1811: Int = 0 + def method1812: Int = 0 + def method1813: Int = 0 + def method1814: Int = 0 + def method1815: Int = 0 + def method1816: Int = 0 + def method1817: Int = 0 + def method1818: Int = 0 + def method1819: Int = 0 + def method1820: Int = 0 + def method1821: Int = 0 + def method1822: Int = 0 + def method1823: Int = 0 + def method1824: Int = 0 + def method1825: Int = 0 + def method1826: Int = 0 + def method1827: Int = 0 + def method1828: Int = 0 + def method1829: Int = 0 + def method1830: Int = 0 + def method1831: Int = 0 + def method1832: Int = 0 + def method1833: Int = 0 + def method1834: Int = 0 + def method1835: Int = 0 + def method1836: Int = 0 + def method1837: Int = 0 + def method1838: Int = 0 + def method1839: Int = 0 + def method1840: Int = 0 + def method1841: Int = 0 + def method1842: Int = 0 + def method1843: Int = 0 + def method1844: Int = 0 + def method1845: Int = 0 + def method1846: Int = 0 + def method1847: Int = 0 + def method1848: Int = 0 + def method1849: Int = 0 + def method1850: Int = 0 + def method1851: Int = 0 + def method1852: Int = 0 + def method1853: Int = 0 + def method1854: Int = 0 + def method1855: Int = 0 + def method1856: Int = 0 + def method1857: Int = 0 + def method1858: Int = 0 + def method1859: Int = 0 + def method1860: Int = 0 + def method1861: Int = 0 + def method1862: Int = 0 + def method1863: Int = 0 + def method1864: Int = 0 + def method1865: Int = 0 + def method1866: Int = 0 + def method1867: Int = 0 + def method1868: Int = 0 + def method1869: Int = 0 + def method1870: Int = 0 + def method1871: Int = 0 + def method1872: Int = 0 + def method1873: Int = 0 + def method1874: Int = 0 + def method1875: Int = 0 + def method1876: Int = 0 + def method1877: Int = 0 + def method1878: Int = 0 + def method1879: Int = 0 + def method1880: Int = 0 + def method1881: Int = 0 + def method1882: Int = 0 + def method1883: Int = 0 + def method1884: Int = 0 + def method1885: Int = 0 + def method1886: Int = 0 + def method1887: Int = 0 + def method1888: Int = 0 + def method1889: Int = 0 + def method1890: Int = 0 + def method1891: Int = 0 + def method1892: Int = 0 + def method1893: Int = 0 + def method1894: Int = 0 + def method1895: Int = 0 + def method1896: Int = 0 + def method1897: Int = 0 + def method1898: Int = 0 + def method1899: Int = 0 + def method1900: Int = 0 + def method1901: Int = 0 + def method1902: Int = 0 + def method1903: Int = 0 + def method1904: Int = 0 + def method1905: Int = 0 + def method1906: Int = 0 + def method1907: Int = 0 + def method1908: Int = 0 + def method1909: Int = 0 + def method1910: Int = 0 + def method1911: Int = 0 + def method1912: Int = 0 + def method1913: Int = 0 + def method1914: Int = 0 + def method1915: Int = 0 + def method1916: Int = 0 + def method1917: Int = 0 + def method1918: Int = 0 + def method1919: Int = 0 + def method1920: Int = 0 + def method1921: Int = 0 + def method1922: Int = 0 + def method1923: Int = 0 + def method1924: Int = 0 + def method1925: Int = 0 + def method1926: Int = 0 + def method1927: Int = 0 + def method1928: Int = 0 + def method1929: Int = 0 + def method1930: Int = 0 + def method1931: Int = 0 + def method1932: Int = 0 + def method1933: Int = 0 + def method1934: Int = 0 + def method1935: Int = 0 + def method1936: Int = 0 + def method1937: Int = 0 + def method1938: Int = 0 + def method1939: Int = 0 + def method1940: Int = 0 + def method1941: Int = 0 + def method1942: Int = 0 + def method1943: Int = 0 + def method1944: Int = 0 + def method1945: Int = 0 + def method1946: Int = 0 + def method1947: Int = 0 + def method1948: Int = 0 + def method1949: Int = 0 + def method1950: Int = 0 + def method1951: Int = 0 + def method1952: Int = 0 + def method1953: Int = 0 + def method1954: Int = 0 + def method1955: Int = 0 + def method1956: Int = 0 + def method1957: Int = 0 + def method1958: Int = 0 + def method1959: Int = 0 + def method1960: Int = 0 + def method1961: Int = 0 + def method1962: Int = 0 + def method1963: Int = 0 + def method1964: Int = 0 + def method1965: Int = 0 + def method1966: Int = 0 + def method1967: Int = 0 + def method1968: Int = 0 + def method1969: Int = 0 + def method1970: Int = 0 + def method1971: Int = 0 + def method1972: Int = 0 + def method1973: Int = 0 + def method1974: Int = 0 + def method1975: Int = 0 + def method1976: Int = 0 + def method1977: Int = 0 + def method1978: Int = 0 + def method1979: Int = 0 + def method1980: Int = 0 + def method1981: Int = 0 + def method1982: Int = 0 + def method1983: Int = 0 + def method1984: Int = 0 + def method1985: Int = 0 + def method1986: Int = 0 + def method1987: Int = 0 + def method1988: Int = 0 + def method1989: Int = 0 + def method1990: Int = 0 + def method1991: Int = 0 + def method1992: Int = 0 + def method1993: Int = 0 + def method1994: Int = 0 + def method1995: Int = 0 + def method1996: Int = 0 + def method1997: Int = 0 + def method1998: Int = 0 + def method1999: Int = 0 + def method2000: Int = 0 + def method2001: Int = 0 + def method2002: Int = 0 + def method2003: Int = 0 + def method2004: Int = 0 + def method2005: Int = 0 + def method2006: Int = 0 + def method2007: Int = 0 + def method2008: Int = 0 + def method2009: Int = 0 + def method2010: Int = 0 + def method2011: Int = 0 + def method2012: Int = 0 + def method2013: Int = 0 + def method2014: Int = 0 + def method2015: Int = 0 + def method2016: Int = 0 + def method2017: Int = 0 + def method2018: Int = 0 + def method2019: Int = 0 + def method2020: Int = 0 + def method2021: Int = 0 + def method2022: Int = 0 + def method2023: Int = 0 + def method2024: Int = 0 + def method2025: Int = 0 + def method2026: Int = 0 + def method2027: Int = 0 + def method2028: Int = 0 + def method2029: Int = 0 + def method2030: Int = 0 + def method2031: Int = 0 + def method2032: Int = 0 + def method2033: Int = 0 + def method2034: Int = 0 + def method2035: Int = 0 + def method2036: Int = 0 + def method2037: Int = 0 + def method2038: Int = 0 + def method2039: Int = 0 + def method2040: Int = 0 + def method2041: Int = 0 + def method2042: Int = 0 + def method2043: Int = 0 + def method2044: Int = 0 + def method2045: Int = 0 + def method2046: Int = 0 + def method2047: Int = 0 + def method2048: Int = 0 + def method2049: Int = 0 + def method2050: Int = 0 + def method2051: Int = 0 + def method2052: Int = 0 + def method2053: Int = 0 + def method2054: Int = 0 + def method2055: Int = 0 + def method2056: Int = 0 + def method2057: Int = 0 + def method2058: Int = 0 + def method2059: Int = 0 + def method2060: Int = 0 + def method2061: Int = 0 + def method2062: Int = 0 + def method2063: Int = 0 + def method2064: Int = 0 + def method2065: Int = 0 + def method2066: Int = 0 + def method2067: Int = 0 + def method2068: Int = 0 + def method2069: Int = 0 + def method2070: Int = 0 + def method2071: Int = 0 + def method2072: Int = 0 + def method2073: Int = 0 + def method2074: Int = 0 + def method2075: Int = 0 + def method2076: Int = 0 + def method2077: Int = 0 + def method2078: Int = 0 + def method2079: Int = 0 + def method2080: Int = 0 + def method2081: Int = 0 + def method2082: Int = 0 + def method2083: Int = 0 + def method2084: Int = 0 + def method2085: Int = 0 + def method2086: Int = 0 + def method2087: Int = 0 + def method2088: Int = 0 + def method2089: Int = 0 + def method2090: Int = 0 + def method2091: Int = 0 + def method2092: Int = 0 + def method2093: Int = 0 + def method2094: Int = 0 + def method2095: Int = 0 + def method2096: Int = 0 + def method2097: Int = 0 + def method2098: Int = 0 + def method2099: Int = 0 + def method2100: Int = 0 + def method2101: Int = 0 + def method2102: Int = 0 + def method2103: Int = 0 + def method2104: Int = 0 + def method2105: Int = 0 + def method2106: Int = 0 + def method2107: Int = 0 + def method2108: Int = 0 + def method2109: Int = 0 + def method2110: Int = 0 + def method2111: Int = 0 + def method2112: Int = 0 + def method2113: Int = 0 + def method2114: Int = 0 + def method2115: Int = 0 + def method2116: Int = 0 + def method2117: Int = 0 + def method2118: Int = 0 + def method2119: Int = 0 + def method2120: Int = 0 + def method2121: Int = 0 + def method2122: Int = 0 + def method2123: Int = 0 + def method2124: Int = 0 + def method2125: Int = 0 + def method2126: Int = 0 + def method2127: Int = 0 + def method2128: Int = 0 + def method2129: Int = 0 + def method2130: Int = 0 + def method2131: Int = 0 + def method2132: Int = 0 + def method2133: Int = 0 + def method2134: Int = 0 + def method2135: Int = 0 + def method2136: Int = 0 + def method2137: Int = 0 + def method2138: Int = 0 + def method2139: Int = 0 + def method2140: Int = 0 + def method2141: Int = 0 + def method2142: Int = 0 + def method2143: Int = 0 + def method2144: Int = 0 + def method2145: Int = 0 + def method2146: Int = 0 + def method2147: Int = 0 + def method2148: Int = 0 + def method2149: Int = 0 + def method2150: Int = 0 + def method2151: Int = 0 + def method2152: Int = 0 + def method2153: Int = 0 + def method2154: Int = 0 + def method2155: Int = 0 + def method2156: Int = 0 + def method2157: Int = 0 + def method2158: Int = 0 + def method2159: Int = 0 + def method2160: Int = 0 + def method2161: Int = 0 + def method2162: Int = 0 + def method2163: Int = 0 + def method2164: Int = 0 + def method2165: Int = 0 + def method2166: Int = 0 + def method2167: Int = 0 + def method2168: Int = 0 + def method2169: Int = 0 + def method2170: Int = 0 + def method2171: Int = 0 + def method2172: Int = 0 + def method2173: Int = 0 + def method2174: Int = 0 + def method2175: Int = 0 + def method2176: Int = 0 + def method2177: Int = 0 + def method2178: Int = 0 + def method2179: Int = 0 + def method2180: Int = 0 + def method2181: Int = 0 + def method2182: Int = 0 + def method2183: Int = 0 + def method2184: Int = 0 + def method2185: Int = 0 + def method2186: Int = 0 + def method2187: Int = 0 + def method2188: Int = 0 + def method2189: Int = 0 + def method2190: Int = 0 + def method2191: Int = 0 + def method2192: Int = 0 + def method2193: Int = 0 + def method2194: Int = 0 + def method2195: Int = 0 + def method2196: Int = 0 + def method2197: Int = 0 + def method2198: Int = 0 + def method2199: Int = 0 + def method2200: Int = 0 + def method2201: Int = 0 + def method2202: Int = 0 + def method2203: Int = 0 + def method2204: Int = 0 + def method2205: Int = 0 + def method2206: Int = 0 + def method2207: Int = 0 + def method2208: Int = 0 + def method2209: Int = 0 + def method2210: Int = 0 + def method2211: Int = 0 + def method2212: Int = 0 + def method2213: Int = 0 + def method2214: Int = 0 + def method2215: Int = 0 + def method2216: Int = 0 + def method2217: Int = 0 + def method2218: Int = 0 + def method2219: Int = 0 + def method2220: Int = 0 + def method2221: Int = 0 + def method2222: Int = 0 + def method2223: Int = 0 + def method2224: Int = 0 + def method2225: Int = 0 + def method2226: Int = 0 + def method2227: Int = 0 + def method2228: Int = 0 + def method2229: Int = 0 + def method2230: Int = 0 + def method2231: Int = 0 + def method2232: Int = 0 + def method2233: Int = 0 + def method2234: Int = 0 + def method2235: Int = 0 + def method2236: Int = 0 + def method2237: Int = 0 + def method2238: Int = 0 + def method2239: Int = 0 + def method2240: Int = 0 + def method2241: Int = 0 + def method2242: Int = 0 + def method2243: Int = 0 + def method2244: Int = 0 + def method2245: Int = 0 + def method2246: Int = 0 + def method2247: Int = 0 + def method2248: Int = 0 + def method2249: Int = 0 + def method2250: Int = 0 + def method2251: Int = 0 + def method2252: Int = 0 + def method2253: Int = 0 + def method2254: Int = 0 + def method2255: Int = 0 + def method2256: Int = 0 + def method2257: Int = 0 + def method2258: Int = 0 + def method2259: Int = 0 + def method2260: Int = 0 + def method2261: Int = 0 + def method2262: Int = 0 + def method2263: Int = 0 + def method2264: Int = 0 + def method2265: Int = 0 + def method2266: Int = 0 + def method2267: Int = 0 + def method2268: Int = 0 + def method2269: Int = 0 + def method2270: Int = 0 + def method2271: Int = 0 + def method2272: Int = 0 + def method2273: Int = 0 + def method2274: Int = 0 + def method2275: Int = 0 + def method2276: Int = 0 + def method2277: Int = 0 + def method2278: Int = 0 + def method2279: Int = 0 + def method2280: Int = 0 + def method2281: Int = 0 + def method2282: Int = 0 + def method2283: Int = 0 + def method2284: Int = 0 + def method2285: Int = 0 + def method2286: Int = 0 + def method2287: Int = 0 + def method2288: Int = 0 + def method2289: Int = 0 + def method2290: Int = 0 + def method2291: Int = 0 + def method2292: Int = 0 + def method2293: Int = 0 + def method2294: Int = 0 + def method2295: Int = 0 + def method2296: Int = 0 + def method2297: Int = 0 + def method2298: Int = 0 + def method2299: Int = 0 + def method2300: Int = 0 + def method2301: Int = 0 + def method2302: Int = 0 + def method2303: Int = 0 + def method2304: Int = 0 + def method2305: Int = 0 + def method2306: Int = 0 + def method2307: Int = 0 + def method2308: Int = 0 + def method2309: Int = 0 + def method2310: Int = 0 + def method2311: Int = 0 + def method2312: Int = 0 + def method2313: Int = 0 + def method2314: Int = 0 + def method2315: Int = 0 + def method2316: Int = 0 + def method2317: Int = 0 + def method2318: Int = 0 + def method2319: Int = 0 + def method2320: Int = 0 + def method2321: Int = 0 + def method2322: Int = 0 + def method2323: Int = 0 + def method2324: Int = 0 + def method2325: Int = 0 + def method2326: Int = 0 + def method2327: Int = 0 + def method2328: Int = 0 + def method2329: Int = 0 + def method2330: Int = 0 + def method2331: Int = 0 + def method2332: Int = 0 + def method2333: Int = 0 + def method2334: Int = 0 + def method2335: Int = 0 + def method2336: Int = 0 + def method2337: Int = 0 + def method2338: Int = 0 + def method2339: Int = 0 + def method2340: Int = 0 + def method2341: Int = 0 + def method2342: Int = 0 + def method2343: Int = 0 + def method2344: Int = 0 + def method2345: Int = 0 + def method2346: Int = 0 + def method2347: Int = 0 + def method2348: Int = 0 + def method2349: Int = 0 + def method2350: Int = 0 + def method2351: Int = 0 + def method2352: Int = 0 + def method2353: Int = 0 + def method2354: Int = 0 + def method2355: Int = 0 + def method2356: Int = 0 + def method2357: Int = 0 + def method2358: Int = 0 + def method2359: Int = 0 + def method2360: Int = 0 + def method2361: Int = 0 + def method2362: Int = 0 + def method2363: Int = 0 + def method2364: Int = 0 + def method2365: Int = 0 + def method2366: Int = 0 + def method2367: Int = 0 + def method2368: Int = 0 + def method2369: Int = 0 + def method2370: Int = 0 + def method2371: Int = 0 + def method2372: Int = 0 + def method2373: Int = 0 + def method2374: Int = 0 + def method2375: Int = 0 + def method2376: Int = 0 + def method2377: Int = 0 + def method2378: Int = 0 + def method2379: Int = 0 + def method2380: Int = 0 + def method2381: Int = 0 + def method2382: Int = 0 + def method2383: Int = 0 + def method2384: Int = 0 + def method2385: Int = 0 + def method2386: Int = 0 + def method2387: Int = 0 + def method2388: Int = 0 + def method2389: Int = 0 + def method2390: Int = 0 + def method2391: Int = 0 + def method2392: Int = 0 + def method2393: Int = 0 + def method2394: Int = 0 + def method2395: Int = 0 + def method2396: Int = 0 + def method2397: Int = 0 + def method2398: Int = 0 + def method2399: Int = 0 + def method2400: Int = 0 + def method2401: Int = 0 + def method2402: Int = 0 + def method2403: Int = 0 + def method2404: Int = 0 + def method2405: Int = 0 + def method2406: Int = 0 + def method2407: Int = 0 + def method2408: Int = 0 + def method2409: Int = 0 + def method2410: Int = 0 + def method2411: Int = 0 + def method2412: Int = 0 + def method2413: Int = 0 + def method2414: Int = 0 + def method2415: Int = 0 + def method2416: Int = 0 + def method2417: Int = 0 + def method2418: Int = 0 + def method2419: Int = 0 + def method2420: Int = 0 + def method2421: Int = 0 + def method2422: Int = 0 + def method2423: Int = 0 + def method2424: Int = 0 + def method2425: Int = 0 + def method2426: Int = 0 + def method2427: Int = 0 + def method2428: Int = 0 + def method2429: Int = 0 + def method2430: Int = 0 + def method2431: Int = 0 + def method2432: Int = 0 + def method2433: Int = 0 + def method2434: Int = 0 + def method2435: Int = 0 + def method2436: Int = 0 + def method2437: Int = 0 + def method2438: Int = 0 + def method2439: Int = 0 + def method2440: Int = 0 + def method2441: Int = 0 + def method2442: Int = 0 + def method2443: Int = 0 + def method2444: Int = 0 + def method2445: Int = 0 + def method2446: Int = 0 + def method2447: Int = 0 + def method2448: Int = 0 + def method2449: Int = 0 + def method2450: Int = 0 + def method2451: Int = 0 + def method2452: Int = 0 + def method2453: Int = 0 + def method2454: Int = 0 + def method2455: Int = 0 + def method2456: Int = 0 + def method2457: Int = 0 + def method2458: Int = 0 + def method2459: Int = 0 + def method2460: Int = 0 + def method2461: Int = 0 + def method2462: Int = 0 + def method2463: Int = 0 + def method2464: Int = 0 + def method2465: Int = 0 + def method2466: Int = 0 + def method2467: Int = 0 + def method2468: Int = 0 + def method2469: Int = 0 + def method2470: Int = 0 + def method2471: Int = 0 + def method2472: Int = 0 + def method2473: Int = 0 + def method2474: Int = 0 + def method2475: Int = 0 + def method2476: Int = 0 + def method2477: Int = 0 + def method2478: Int = 0 + def method2479: Int = 0 + def method2480: Int = 0 + def method2481: Int = 0 + def method2482: Int = 0 + def method2483: Int = 0 + def method2484: Int = 0 + def method2485: Int = 0 + def method2486: Int = 0 + def method2487: Int = 0 + def method2488: Int = 0 + def method2489: Int = 0 + def method2490: Int = 0 + def method2491: Int = 0 + def method2492: Int = 0 + def method2493: Int = 0 + def method2494: Int = 0 + def method2495: Int = 0 + def method2496: Int = 0 + def method2497: Int = 0 + def method2498: Int = 0 + def method2499: Int = 0 + def method2500: Int = 0 + def method2501: Int = 0 + def method2502: Int = 0 + def method2503: Int = 0 + def method2504: Int = 0 + def method2505: Int = 0 + def method2506: Int = 0 + def method2507: Int = 0 + def method2508: Int = 0 + def method2509: Int = 0 + def method2510: Int = 0 + def method2511: Int = 0 + def method2512: Int = 0 + def method2513: Int = 0 + def method2514: Int = 0 + def method2515: Int = 0 + def method2516: Int = 0 + def method2517: Int = 0 + def method2518: Int = 0 + def method2519: Int = 0 + def method2520: Int = 0 + def method2521: Int = 0 + def method2522: Int = 0 + def method2523: Int = 0 + def method2524: Int = 0 + def method2525: Int = 0 + def method2526: Int = 0 + def method2527: Int = 0 + def method2528: Int = 0 + def method2529: Int = 0 + def method2530: Int = 0 + def method2531: Int = 0 + def method2532: Int = 0 + def method2533: Int = 0 + def method2534: Int = 0 + def method2535: Int = 0 + def method2536: Int = 0 + def method2537: Int = 0 + def method2538: Int = 0 + def method2539: Int = 0 + def method2540: Int = 0 + def method2541: Int = 0 + def method2542: Int = 0 + def method2543: Int = 0 + def method2544: Int = 0 + def method2545: Int = 0 + def method2546: Int = 0 + def method2547: Int = 0 + def method2548: Int = 0 + def method2549: Int = 0 + def method2550: Int = 0 + def method2551: Int = 0 + def method2552: Int = 0 + def method2553: Int = 0 + def method2554: Int = 0 + def method2555: Int = 0 + def method2556: Int = 0 + def method2557: Int = 0 + def method2558: Int = 0 + def method2559: Int = 0 + def method2560: Int = 0 + def method2561: Int = 0 + def method2562: Int = 0 + def method2563: Int = 0 + def method2564: Int = 0 + def method2565: Int = 0 + def method2566: Int = 0 + def method2567: Int = 0 + def method2568: Int = 0 + def method2569: Int = 0 + def method2570: Int = 0 + def method2571: Int = 0 + def method2572: Int = 0 + def method2573: Int = 0 + def method2574: Int = 0 + def method2575: Int = 0 + def method2576: Int = 0 + def method2577: Int = 0 + def method2578: Int = 0 + def method2579: Int = 0 + def method2580: Int = 0 + def method2581: Int = 0 + def method2582: Int = 0 + def method2583: Int = 0 + def method2584: Int = 0 + def method2585: Int = 0 + def method2586: Int = 0 + def method2587: Int = 0 + def method2588: Int = 0 + def method2589: Int = 0 + def method2590: Int = 0 + def method2591: Int = 0 + def method2592: Int = 0 + def method2593: Int = 0 + def method2594: Int = 0 + def method2595: Int = 0 + def method2596: Int = 0 + def method2597: Int = 0 + def method2598: Int = 0 + def method2599: Int = 0 + def method2600: Int = 0 + def method2601: Int = 0 + def method2602: Int = 0 + def method2603: Int = 0 + def method2604: Int = 0 + def method2605: Int = 0 + def method2606: Int = 0 + def method2607: Int = 0 + def method2608: Int = 0 + def method2609: Int = 0 + def method2610: Int = 0 + def method2611: Int = 0 + def method2612: Int = 0 + def method2613: Int = 0 + def method2614: Int = 0 + def method2615: Int = 0 + def method2616: Int = 0 + def method2617: Int = 0 + def method2618: Int = 0 + def method2619: Int = 0 + def method2620: Int = 0 + def method2621: Int = 0 + def method2622: Int = 0 + def method2623: Int = 0 + def method2624: Int = 0 + def method2625: Int = 0 + def method2626: Int = 0 + def method2627: Int = 0 + def method2628: Int = 0 + def method2629: Int = 0 + def method2630: Int = 0 + def method2631: Int = 0 + def method2632: Int = 0 + def method2633: Int = 0 + def method2634: Int = 0 + def method2635: Int = 0 + def method2636: Int = 0 + def method2637: Int = 0 + def method2638: Int = 0 + def method2639: Int = 0 + def method2640: Int = 0 + def method2641: Int = 0 + def method2642: Int = 0 + def method2643: Int = 0 + def method2644: Int = 0 + def method2645: Int = 0 + def method2646: Int = 0 + def method2647: Int = 0 + def method2648: Int = 0 + def method2649: Int = 0 + def method2650: Int = 0 + def method2651: Int = 0 + def method2652: Int = 0 + def method2653: Int = 0 + def method2654: Int = 0 + def method2655: Int = 0 + def method2656: Int = 0 + def method2657: Int = 0 + def method2658: Int = 0 + def method2659: Int = 0 + def method2660: Int = 0 + def method2661: Int = 0 + def method2662: Int = 0 + def method2663: Int = 0 + def method2664: Int = 0 + def method2665: Int = 0 + def method2666: Int = 0 + def method2667: Int = 0 + def method2668: Int = 0 + def method2669: Int = 0 + def method2670: Int = 0 + def method2671: Int = 0 + def method2672: Int = 0 + def method2673: Int = 0 + def method2674: Int = 0 + def method2675: Int = 0 + def method2676: Int = 0 + def method2677: Int = 0 + def method2678: Int = 0 + def method2679: Int = 0 + def method2680: Int = 0 + def method2681: Int = 0 + def method2682: Int = 0 + def method2683: Int = 0 + def method2684: Int = 0 + def method2685: Int = 0 + def method2686: Int = 0 + def method2687: Int = 0 + def method2688: Int = 0 + def method2689: Int = 0 + def method2690: Int = 0 + def method2691: Int = 0 + def method2692: Int = 0 + def method2693: Int = 0 + def method2694: Int = 0 + def method2695: Int = 0 + def method2696: Int = 0 + def method2697: Int = 0 + def method2698: Int = 0 + def method2699: Int = 0 + def method2700: Int = 0 + def method2701: Int = 0 + def method2702: Int = 0 + def method2703: Int = 0 + def method2704: Int = 0 + def method2705: Int = 0 + def method2706: Int = 0 + def method2707: Int = 0 + def method2708: Int = 0 + def method2709: Int = 0 + def method2710: Int = 0 + def method2711: Int = 0 + def method2712: Int = 0 + def method2713: Int = 0 + def method2714: Int = 0 + def method2715: Int = 0 + def method2716: Int = 0 + def method2717: Int = 0 + def method2718: Int = 0 + def method2719: Int = 0 + def method2720: Int = 0 + def method2721: Int = 0 + def method2722: Int = 0 + def method2723: Int = 0 + def method2724: Int = 0 + def method2725: Int = 0 + def method2726: Int = 0 + def method2727: Int = 0 + def method2728: Int = 0 + def method2729: Int = 0 + def method2730: Int = 0 + def method2731: Int = 0 + def method2732: Int = 0 + def method2733: Int = 0 + def method2734: Int = 0 + def method2735: Int = 0 + def method2736: Int = 0 + def method2737: Int = 0 + def method2738: Int = 0 + def method2739: Int = 0 + def method2740: Int = 0 + def method2741: Int = 0 + def method2742: Int = 0 + def method2743: Int = 0 + def method2744: Int = 0 + def method2745: Int = 0 + def method2746: Int = 0 + def method2747: Int = 0 + def method2748: Int = 0 + def method2749: Int = 0 + def method2750: Int = 0 + def method2751: Int = 0 + def method2752: Int = 0 + def method2753: Int = 0 + def method2754: Int = 0 + def method2755: Int = 0 + def method2756: Int = 0 + def method2757: Int = 0 + def method2758: Int = 0 + def method2759: Int = 0 + def method2760: Int = 0 + def method2761: Int = 0 + def method2762: Int = 0 + def method2763: Int = 0 + def method2764: Int = 0 + def method2765: Int = 0 + def method2766: Int = 0 + def method2767: Int = 0 + def method2768: Int = 0 + def method2769: Int = 0 + def method2770: Int = 0 + def method2771: Int = 0 + def method2772: Int = 0 + def method2773: Int = 0 + def method2774: Int = 0 + def method2775: Int = 0 + def method2776: Int = 0 + def method2777: Int = 0 + def method2778: Int = 0 + def method2779: Int = 0 + def method2780: Int = 0 + def method2781: Int = 0 + def method2782: Int = 0 + def method2783: Int = 0 + def method2784: Int = 0 + def method2785: Int = 0 + def method2786: Int = 0 + def method2787: Int = 0 + def method2788: Int = 0 + def method2789: Int = 0 + def method2790: Int = 0 + def method2791: Int = 0 + def method2792: Int = 0 + def method2793: Int = 0 + def method2794: Int = 0 + def method2795: Int = 0 + def method2796: Int = 0 + def method2797: Int = 0 + def method2798: Int = 0 + def method2799: Int = 0 + def method2800: Int = 0 + def method2801: Int = 0 + def method2802: Int = 0 + def method2803: Int = 0 + def method2804: Int = 0 + def method2805: Int = 0 + def method2806: Int = 0 + def method2807: Int = 0 + def method2808: Int = 0 + def method2809: Int = 0 + def method2810: Int = 0 + def method2811: Int = 0 + def method2812: Int = 0 + def method2813: Int = 0 + def method2814: Int = 0 + def method2815: Int = 0 + def method2816: Int = 0 + def method2817: Int = 0 + def method2818: Int = 0 + def method2819: Int = 0 + def method2820: Int = 0 + def method2821: Int = 0 + def method2822: Int = 0 + def method2823: Int = 0 + def method2824: Int = 0 + def method2825: Int = 0 + def method2826: Int = 0 + def method2827: Int = 0 + def method2828: Int = 0 + def method2829: Int = 0 + def method2830: Int = 0 + def method2831: Int = 0 + def method2832: Int = 0 + def method2833: Int = 0 + def method2834: Int = 0 + def method2835: Int = 0 + def method2836: Int = 0 + def method2837: Int = 0 + def method2838: Int = 0 + def method2839: Int = 0 + def method2840: Int = 0 + def method2841: Int = 0 + def method2842: Int = 0 + def method2843: Int = 0 + def method2844: Int = 0 + def method2845: Int = 0 + def method2846: Int = 0 + def method2847: Int = 0 + def method2848: Int = 0 + def method2849: Int = 0 + def method2850: Int = 0 + def method2851: Int = 0 + def method2852: Int = 0 + def method2853: Int = 0 + def method2854: Int = 0 + def method2855: Int = 0 + def method2856: Int = 0 + def method2857: Int = 0 + def method2858: Int = 0 + def method2859: Int = 0 + def method2860: Int = 0 + def method2861: Int = 0 + def method2862: Int = 0 + def method2863: Int = 0 + def method2864: Int = 0 + def method2865: Int = 0 + def method2866: Int = 0 + def method2867: Int = 0 + def method2868: Int = 0 + def method2869: Int = 0 + def method2870: Int = 0 + def method2871: Int = 0 + def method2872: Int = 0 + def method2873: Int = 0 + def method2874: Int = 0 + def method2875: Int = 0 + def method2876: Int = 0 + def method2877: Int = 0 + def method2878: Int = 0 + def method2879: Int = 0 + def method2880: Int = 0 + def method2881: Int = 0 + def method2882: Int = 0 + def method2883: Int = 0 + def method2884: Int = 0 + def method2885: Int = 0 + def method2886: Int = 0 + def method2887: Int = 0 + def method2888: Int = 0 + def method2889: Int = 0 + def method2890: Int = 0 + def method2891: Int = 0 + def method2892: Int = 0 + def method2893: Int = 0 + def method2894: Int = 0 + def method2895: Int = 0 + def method2896: Int = 0 + def method2897: Int = 0 + def method2898: Int = 0 + def method2899: Int = 0 + def method2900: Int = 0 + def method2901: Int = 0 + def method2902: Int = 0 + def method2903: Int = 0 + def method2904: Int = 0 + def method2905: Int = 0 + def method2906: Int = 0 + def method2907: Int = 0 + def method2908: Int = 0 + def method2909: Int = 0 + def method2910: Int = 0 + def method2911: Int = 0 + def method2912: Int = 0 + def method2913: Int = 0 + def method2914: Int = 0 + def method2915: Int = 0 + def method2916: Int = 0 + def method2917: Int = 0 + def method2918: Int = 0 + def method2919: Int = 0 + def method2920: Int = 0 + def method2921: Int = 0 + def method2922: Int = 0 + def method2923: Int = 0 + def method2924: Int = 0 + def method2925: Int = 0 + def method2926: Int = 0 + def method2927: Int = 0 + def method2928: Int = 0 + def method2929: Int = 0 + def method2930: Int = 0 + def method2931: Int = 0 + def method2932: Int = 0 + def method2933: Int = 0 + def method2934: Int = 0 + def method2935: Int = 0 + def method2936: Int = 0 + def method2937: Int = 0 + def method2938: Int = 0 + def method2939: Int = 0 + def method2940: Int = 0 + def method2941: Int = 0 + def method2942: Int = 0 + def method2943: Int = 0 + def method2944: Int = 0 + def method2945: Int = 0 + def method2946: Int = 0 + def method2947: Int = 0 + def method2948: Int = 0 + def method2949: Int = 0 + def method2950: Int = 0 + def method2951: Int = 0 + def method2952: Int = 0 + def method2953: Int = 0 + def method2954: Int = 0 + def method2955: Int = 0 + def method2956: Int = 0 + def method2957: Int = 0 + def method2958: Int = 0 + def method2959: Int = 0 + def method2960: Int = 0 + def method2961: Int = 0 + def method2962: Int = 0 + def method2963: Int = 0 + def method2964: Int = 0 + def method2965: Int = 0 + def method2966: Int = 0 + def method2967: Int = 0 + def method2968: Int = 0 + def method2969: Int = 0 + def method2970: Int = 0 + def method2971: Int = 0 + def method2972: Int = 0 + def method2973: Int = 0 + def method2974: Int = 0 + def method2975: Int = 0 + def method2976: Int = 0 + def method2977: Int = 0 + def method2978: Int = 0 + def method2979: Int = 0 + def method2980: Int = 0 + def method2981: Int = 0 + def method2982: Int = 0 + def method2983: Int = 0 + def method2984: Int = 0 + def method2985: Int = 0 + def method2986: Int = 0 + def method2987: Int = 0 + def method2988: Int = 0 + def method2989: Int = 0 + def method2990: Int = 0 + def method2991: Int = 0 + def method2992: Int = 0 + def method2993: Int = 0 + def method2994: Int = 0 + def method2995: Int = 0 + def method2996: Int = 0 + def method2997: Int = 0 + def method2998: Int = 0 + def method2999: Int = 0 +} diff --git a/test/files/run/t7558.scala b/test/files/run/t7558.scala new file mode 100644 index 0000000000..bfcaaba5cc --- /dev/null +++ b/test/files/run/t7558.scala @@ -0,0 +1,9 @@ +object Test extends App { + val cm = reflect.runtime.currentMirror + val u = cm.universe + import scala.tools.reflect.ToolBox + val tb = cm.mkToolBox() + val t = { var x = "ab".toList; u.reify { x = x.reverse; x }.tree } + val evaluated = tb.eval(t) + assert(evaluated == "ba".toList, evaluated) +} diff --git a/test/files/run/t7569.check b/test/files/run/t7569.check new file mode 100644 index 0000000000..aade96d233 --- /dev/null +++ b/test/files/run/t7569.check @@ -0,0 +1,12 @@ +source-newSource1.scala,line-3,offset=49 A.this.one +source-newSource1.scala,line-3,offset=49 A.this +source-newSource1.scala,line-2,offset=41 A.super.<init>() +source-newSource1.scala,line-2,offset=41 A.super.<init> +source-newSource1.scala,line-2,offset=41 this +source-newSource1.scala,line-3,offset=49 A.this.one +source-newSource1.scala,line-3,offset=49 A.this +RangePosition(newSource1.scala, 55, 57, 65) scala.Int.box(1).toString() +RangePosition(newSource1.scala, 55, 57, 65) scala.Int.box(1).toString +RangePosition(newSource1.scala, 55, 55, 56) scala.Int.box(1) +NoPosition scala.Int.box +NoPosition scala.Int diff --git a/test/files/run/t7569.scala b/test/files/run/t7569.scala new file mode 100644 index 0000000000..b1b1443a18 --- /dev/null +++ b/test/files/run/t7569.scala @@ -0,0 +1,19 @@ +import scala.tools.partest._ +object Test extends CompilerTest { + import global._ + override def extraSettings = super.extraSettings + " -Yrangepos" + override def sources = List( + """|import scala.language.postfixOps + |class A { + | val one = 1 toString + |}""".stripMargin + ) + def check(source: String, unit: CompilationUnit) { + for (ClassDef(_, _, _, Template(_, _, stats)) <- unit.body ; stat <- stats ; t <- stat) { + t match { + case _: Select | _ : Apply | _:This => println("%-15s %s".format(t.pos.toString, t)) + case _ => + } + } + } +} diff --git a/test/files/run/t7571.scala b/test/files/run/t7571.scala new file mode 100644 index 0000000000..00b9695168 --- /dev/null +++ b/test/files/run/t7571.scala @@ -0,0 +1,12 @@ +class Foo(val a: Int) extends AnyVal { + def foo = { {case x => x + a}: PartialFunction[Int, Int]} + + def bar = (new {}).toString +} + +object Test extends App { + val x = new Foo(1).foo.apply(2) + assert(x == 3, x) + val s = new Foo(1).bar + assert(s.nonEmpty, s) +} diff --git a/test/files/run/t7617a.check b/test/files/run/t7617a.check new file mode 100644 index 0000000000..94954abda4 --- /dev/null +++ b/test/files/run/t7617a.check @@ -0,0 +1,2 @@ +hello +world diff --git a/test/files/run/t7617a/Macros_1.scala b/test/files/run/t7617a/Macros_1.scala new file mode 100644 index 0000000000..f9772c83c0 --- /dev/null +++ b/test/files/run/t7617a/Macros_1.scala @@ -0,0 +1,22 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + def getValueImpl[T](c: Context): c.Expr[T] = { + import c.universe._ + c.Expr[T](Apply(Select(c.prefix.tree, newTermName("getVal")), Nil)) + } + def setValueImpl[T](c: Context)(value: c.Expr[T]): c.Expr[Unit] = { + import c.universe._ + c.Expr[Unit](Apply(Select(c.prefix.tree, newTermName("setVal")), List(value.tree))) + } +} + +object Module { + private var _val: String = "hello" + def setVal(value: String): Unit = this._val = value + def getVal(): String = this._val + + def value: String = macro Macros.getValueImpl[String] + def value_=(value: String): Unit = macro Macros.setValueImpl[String] +} diff --git a/test/files/run/t7617a/Test_2.scala b/test/files/run/t7617a/Test_2.scala new file mode 100644 index 0000000000..da6e34e09d --- /dev/null +++ b/test/files/run/t7617a/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + println(Module.value) + Module.value = "world" + println(Module.value) +}
\ No newline at end of file diff --git a/test/files/run/t7617b.check b/test/files/run/t7617b.check new file mode 100644 index 0000000000..81ec7e8b74 --- /dev/null +++ b/test/files/run/t7617b.check @@ -0,0 +1 @@ +foo = 2 diff --git a/test/files/run/t7617b/Macros_1.scala b/test/files/run/t7617b/Macros_1.scala new file mode 100644 index 0000000000..bc919935c9 --- /dev/null +++ b/test/files/run/t7617b/Macros_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.macros.Context + +object Macros { + def impl(c: Context)(name: c.Expr[String])(value: c.Expr[Any]) = { + import c.universe._ + reify(println(s"${name.splice} = ${value.splice}")) + } +}
\ No newline at end of file diff --git a/test/files/run/t7617b/Test_2.scala b/test/files/run/t7617b/Test_2.scala new file mode 100644 index 0000000000..e27f650e80 --- /dev/null +++ b/test/files/run/t7617b/Test_2.scala @@ -0,0 +1,11 @@ +import scala.language.dynamics +import language.experimental.macros + +class C extends Dynamic { + def updateDynamic(name: String)(value: Any) = macro Macros.impl +} + +object Test extends App { + val c = new C + c.foo = 2 +}
\ No newline at end of file diff --git a/test/files/run/t7657.check b/test/files/run/t7657.check new file mode 100644 index 0000000000..c25d8d1c1b --- /dev/null +++ b/test/files/run/t7657.check @@ -0,0 +1,3 @@ +() +() +() diff --git a/test/files/run/t7657/Macros_1.scala b/test/files/run/t7657/Macros_1.scala new file mode 100644 index 0000000000..b1e31aa2dd --- /dev/null +++ b/test/files/run/t7657/Macros_1.scala @@ -0,0 +1,8 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +trait T { def t(): Unit } +abstract class A extends T { override def t(): Unit = () } + +object Macro { def t(c: Context)(): c.Expr[Unit] = c.universe.reify(()) } +class C extends A { override def t(): Unit = macro Macro.t } diff --git a/test/files/run/t7657/Test_2.scala b/test/files/run/t7657/Test_2.scala new file mode 100644 index 0000000000..5cc46b6aa1 --- /dev/null +++ b/test/files/run/t7657/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + val c = new C() + println(c.t()) + println((c: T).t()) + println((c: A).t()) +}
\ No newline at end of file diff --git a/test/files/run/t7733.check b/test/files/run/t7733.check new file mode 100644 index 0000000000..19765bd501 --- /dev/null +++ b/test/files/run/t7733.check @@ -0,0 +1 @@ +null diff --git a/test/files/run/t7733/Separate_1.scala b/test/files/run/t7733/Separate_1.scala new file mode 100644 index 0000000000..a326ecd53e --- /dev/null +++ b/test/files/run/t7733/Separate_1.scala @@ -0,0 +1,5 @@ +package test + +class Separate { + for (i <- 1 to 10) println(i) +}
\ No newline at end of file diff --git a/test/files/run/t7733/Test_2.scala b/test/files/run/t7733/Test_2.scala new file mode 100644 index 0000000000..28358574ec --- /dev/null +++ b/test/files/run/t7733/Test_2.scala @@ -0,0 +1,9 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + val tb = cm.mkToolBox() + val code = tb.parse("{ val x: test.Separate$$anonfun$1 = null; x }") + println(tb.eval(code)) +}
\ No newline at end of file diff --git a/test/files/run/toolbox_current_run_compiles.check b/test/files/run/toolbox_current_run_compiles.check new file mode 100644 index 0000000000..da29283aaa --- /dev/null +++ b/test/files/run/toolbox_current_run_compiles.check @@ -0,0 +1,2 @@ +true +false diff --git a/test/files/run/toolbox_current_run_compiles.scala b/test/files/run/toolbox_current_run_compiles.scala new file mode 100644 index 0000000000..b48c998e64 --- /dev/null +++ b/test/files/run/toolbox_current_run_compiles.scala @@ -0,0 +1,28 @@ +package pkg { + import scala.reflect.macros.Context + import scala.language.experimental.macros + + object Macros { + def impl[T: c.WeakTypeTag](c: Context) = { + import c.universe._ + val sym = c.weakTypeOf[T].typeSymbol + val g = c.universe.asInstanceOf[scala.tools.nsc.Global] + c.Expr[Boolean](Literal(Constant(g.currentRun.compiles(sym.asInstanceOf[g.Symbol])))) + } + def compiles[T] = macro impl[T] + } +} + +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{universe => ru} +import scala.tools.reflect.ToolBox + +object Test extends App { + val cm = ru.runtimeMirror(getClass.getClassLoader) + val toolbox = cm.mkToolBox() + toolbox.eval(toolbox.parse("""{ + class C + println(pkg.Macros.compiles[C]) + println(pkg.Macros.compiles[Object]) + }""")) +}
\ No newline at end of file diff --git a/test/files/specialized/SI-7343.scala b/test/files/specialized/SI-7343.scala new file mode 100644 index 0000000000..5ee683064c --- /dev/null +++ b/test/files/specialized/SI-7343.scala @@ -0,0 +1,55 @@ +class Parent[@specialized(Int) T] + +object Test extends App { + + /** + * This method will check if specialization is correctly rewiring parents + * for classes defined inside methods. The pattern is important since this + * is how closures are currently represented: as locally-defined anonymous + * classes, which usually end up inside methods. For these closures we do + * want their parents rewired correctly: + * + * ``` + * def checkSuperClass$mIc$sp[T](t: T, ...) = { + * class X extends Parent$mcI$sp // instead of just Parent + * ... + * } + */ + def checkSuperClass[@specialized(Int) T](t: T, expectedXSuper: String) = { + // test target: + // - in checkSuperClass, X should extend Parent + // - in checkSuperClass$mIc$sp, X should extend Parent$mcI$sp + class X extends Parent[T]() + + // get the superclass for X and make sure it's correct + val actualXSuper = (new X).getClass().getSuperclass().getSimpleName() + assert(actualXSuper == expectedXSuper, actualXSuper + " != " + expectedXSuper) + } + + checkSuperClass("x", "Parent") + checkSuperClass(101, "Parent$mcI$sp") + + /** + * This is the same check, but in value. It should work exactly the same + * as its method counterpart. + */ + class Val[@specialized(Int) T](t: T, expectedXSuper: String) { + val check: T = { + class X extends Parent[T]() + + // get the superclass for X and make sure it's correct + val actualXSuper = (new X).getClass().getSuperclass().getSimpleName() + assert(actualXSuper == expectedXSuper, actualXSuper + " != " + expectedXSuper) + t + } + } + + new Val("x", "Parent") + new Val(101, "Parent$mcI$sp") + + /** + * NOTE: The the same check, only modified to affect constructors, won't + * work since the class X definition will always be lifted to become a + * member of the class, making it impossible to force its duplication. + */ +} diff --git a/test/files/specialized/SI-7344.scala b/test/files/specialized/SI-7344.scala new file mode 100644 index 0000000000..1040460bd1 --- /dev/null +++ b/test/files/specialized/SI-7344.scala @@ -0,0 +1,53 @@ +/* Test for SI-7344, where specialized methods inside the bodies of other + * methods are not specialized, although they might as well be. The name + * for the specialized method should not be different depending on the + * outside method/class' specialization. */ + +class Test[@specialized(Int, Double) X](val x: X) { + + def checkSpecialization[Y](@specialized(Int, Double) y: Y): X = { + + // checking the specialization using the method name, which we can + // extract from an exception's stack trace. We can match just the + // prefix, since the compiler will add a suffix to the method name + // during lambdalift, when it lifts the local methods outside. + def specMe[@specialized(Int, Double) T, N](t: T, n: N): Unit = checkNameStartsWith(n.toString) + + // expected to specialize: + specMe("x", "specMe") + specMe(123, "specMe$mIc$sp") + specMe(1.3, new { override def toString = "specMe$mDc$sp" }) + + x + } + + // name matching: + private[this] def checkNameStartsWith(prefix: String): Unit = { + val method = (new Exception).getStackTrace()(1).getMethodName() + assert(method.startsWith(prefix), method + ".startsWith(" + prefix + ") should be true") + } +} + +object Test extends App { + val t1 = new Test("x") + val t2 = new Test(123) + val t3 = new Test(1.3) + + // we want specialization to rewire these, + // that's why they're not in a for loop: + t1.checkSpecialization("x") + + // Prevented by SI-7579: + // The duplicator loses the @specialized annotation, + // so our tree transformation doesn't know it needs to + // specialize specMe inside the duplicated (and specialized) + // variants of the `checkSpecialization` method + // t1.checkSpecialization(123) + // t1.checkSpecialization(1.3) + // t2.checkSpecialization("x") + // t2.checkSpecialization(123) + // t2.checkSpecialization(1.3) + // t3.checkSpecialization("x") + // t3.checkSpecialization(123) + // t3.checkSpecialization(1.3) +} diff --git a/test/files/specialized/spec-ame.check b/test/files/specialized/spec-ame.check index 9c1713cc8a..cf18c01191 100644 --- a/test/files/specialized/spec-ame.check +++ b/test/files/specialized/spec-ame.check @@ -1,3 +1,3 @@ abc 10 -3
\ No newline at end of file +2 diff --git a/test/files/specialized/spec-ame.scala b/test/files/specialized/spec-ame.scala index 79ee4217ed..129fb9f447 100644 --- a/test/files/specialized/spec-ame.scala +++ b/test/files/specialized/spec-ame.scala @@ -13,6 +13,9 @@ object Test { def main(args: Array[String]) { println((new A("abc")).foo.value) println((new A(10)).foo.value) + // before fixing SI-7343, this was printing 3. Now it's printing 2, + // since the anonymous class created by doing new B[T] { ... } when + // T = Int is now rewired to B$mcI$sp instead of just B[Int] println(runtime.BoxesRunTime.integerBoxCount) } } diff --git a/test/junit/scala/concurrent/impl/DefaultPromiseTest.scala b/test/junit/scala/concurrent/impl/DefaultPromiseTest.scala new file mode 100644 index 0000000000..f3a75e24d0 --- /dev/null +++ b/test/junit/scala/concurrent/impl/DefaultPromiseTest.scala @@ -0,0 +1,344 @@ +package scala.concurrent.impl + +import java.util.concurrent.ConcurrentLinkedQueue +import java.util.concurrent.CountDownLatch +import org.junit.Assert._ +import org.junit.{ After, Before, Test } +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import scala.annotation.tailrec +import scala.concurrent.ExecutionContext +import scala.concurrent.impl.Promise.DefaultPromise +import scala.util.{ Failure, Success, Try } +import scala.util.control.NonFatal + +/** Tests for the private class DefaultPromise */ +@RunWith(classOf[JUnit4]) +class DefaultPromiseTest { + + // Many tests in this class use a helper class, Tester, to track the state of + // promises and to ensure they behave correctly, particularly the complex behaviour + // of linking. + + type Result = Int + type PromiseId = Int + type HandlerId = Int + type ChainId = Int + + /** The state of a set of set of linked promises. */ + case class Chain( + promises: Set[PromiseId], + state: Either[Set[HandlerId],Try[Result]] + ) + + /** A helper class that provides methods for creating, linking, completing and + * adding handlers to promises. With each operation it verifies that handlers + * are called, any expected exceptions are thrown, and that all promises have + * the expected value. + * + * The links between promises are not tracked precisely. Instead, linked promises + * are placed in the same Chain object. Each link in the same chain will share + * the same value. + */ + class Tester { + var promises = Map.empty[PromiseId, DefaultPromise[Result]] + var chains = Map.empty[ChainId, Chain] + + private var counter = 0 + private def freshId(): Int = { + val id = counter + counter += 1 + id + } + + /** Handlers report their activity on this queue */ + private val handlerQueue = new ConcurrentLinkedQueue[(Try[Result], HandlerId)]() + + /** Get the chain for a given promise */ + private def promiseChain(p: PromiseId): Option[(ChainId, Chain)] = { + val found: Iterable[(ChainId, Chain)] = for ((cid, c) <- chains; p0 <- c.promises; if (p0 == p)) yield ((cid, c)) + found.toList match { + case Nil => None + case x::Nil => Some(x) + case _ => throw new IllegalStateException(s"Promise $p found in more than one chain") + } + } + + /** Passed to `checkEffect` to indicate the expected effect of an operation */ + sealed trait Effect + case object NoEffect extends Effect + case class HandlersFired(result: Try[Result], handlers: Set[HandlerId]) extends Effect + case object MaybeIllegalThrown extends Effect + case object IllegalThrown extends Effect + + /** Runs an operation while verifying that the operation has the expected effect */ + private def checkEffect(expected: Effect)(f: => Any) { + assert(handlerQueue.isEmpty()) // Should have been cleared by last usage + val result = Try(f) + + var fireCounts = Map.empty[(Try[Result], HandlerId), Int] + while (!handlerQueue.isEmpty()) { + val key = handlerQueue.poll() + val newCount = fireCounts.getOrElse(key, 0) + 1 + fireCounts = fireCounts.updated(key, newCount) + } + + def assertIllegalResult = result match { + case Failure(e: IllegalStateException) => () + case _ => fail(s"Expected IllegalStateException: $result") + } + + expected match { + case NoEffect => + assertTrue(s"Shouldn't throw exception: $result", result.isSuccess) + assertEquals(Map.empty[(Try[Result], HandlerId), Int], fireCounts) + case HandlersFired(firingResult, handlers) => + assert(result.isSuccess) + val expectedCounts = handlers.foldLeft(Map.empty[(Try[Result], HandlerId), Int]) { + case (map, hid) => map.updated((firingResult, hid), 1) + } + assertEquals(expectedCounts, fireCounts) + case MaybeIllegalThrown => + if (result.isFailure) assertIllegalResult + assertEquals(Map.empty, fireCounts) + case IllegalThrown => + assertIllegalResult + assertEquals(Map.empty, fireCounts) + } + } + + /** Check each promise has the expected value. */ + private def assertPromiseValues() { + for ((cid, chain) <- chains; p <- chain.promises) { + chain.state match { + case Right(result) => assertEquals(Some(result), promises(p).value) + case Left(_) => () + } + } + } + + /** Create a promise, returning a handle. */ + def newPromise(): PromiseId = { + val pid = freshId() + val cid = freshId() + promises = promises.updated(pid, new DefaultPromise[Result]()) + chains = chains.updated(cid, Chain(Set(pid), Left(Set.empty))) + assertPromiseValues() + pid + } + + /** Complete a promise */ + def complete(p: PromiseId) { + val r = Success(freshId()) + val (cid, chain) = promiseChain(p).get + val (completionEffect, newState) = chain.state match { + case Left(handlers) => (HandlersFired(r, handlers), Right(r)) + case Right(completion) => (IllegalThrown, chain.state) + } + checkEffect(completionEffect) { promises(p).complete(r) } + chains = chains.updated(cid, chain.copy(state = newState)) + assertPromiseValues() + } + + /** Attempt to link two promises together */ + def link(a: PromiseId, b: PromiseId): (ChainId, ChainId) = { + val promiseA = promises(a) + val promiseB = promises(b) + val (cidA, chainA) = promiseChain(a).get + val (cidB, chainB) = promiseChain(b).get + + // Examine the state of each promise's chain to work out + // the effect of linking the promises, and to work out + // if the two chains should be merged. + + sealed trait MergeOp + case object NoMerge extends MergeOp + case class Merge(state: Either[Set[HandlerId],Try[Result]]) extends MergeOp + + val (linkEffect, mergeOp) = (chainA.state, chainB.state) match { + case (Left(handlers1), Left(handlers2)) => + (NoEffect, Merge(Left(handlers1 ++ handlers2))) + case (Left(handlers), Right(result)) => + (HandlersFired(result, handlers), Merge(Right(result))) + case (Right(result), Left(handlers)) => + (HandlersFired(result, handlers), Merge(Right(result))) + case (Right(_), Right(_)) if (cidA == cidB) => + (MaybeIllegalThrown, NoMerge) // Won't be thrown if happen to link a promise to itself + case (Right(_), Right(_)) => + (IllegalThrown, NoMerge) + } + + // Perform the linking and merge the chains, if appropriate + + checkEffect(linkEffect) { promiseA.linkRootOf(promiseB) } + + val (newCidA, newCidB) = mergeOp match { + case NoMerge => (cidA, cidB) + case Merge(newState) => { + chains = chains - cidA + chains = chains - cidB + val newCid = freshId() + chains = chains.updated(newCid, Chain(chainA.promises ++ chainB.promises, newState)) + (newCid, newCid) + } + } + assertPromiseValues() + (newCidA, newCidB) + } + + /** Attach an onComplete handler. When called, the handler will + * place an entry into `handlerQueue` with the handler's identity. + * This allows verification of handler calling semantics. + */ + def attachHandler(p: PromiseId): HandlerId = { + val hid = freshId() + val promise = promises(p) + val (cid, chain) = promiseChain(p).get + val (attachEffect, newState) = chain.state match { + case Left(handlers) => + (NoEffect, Left(handlers + hid)) + case Right(result) => + (HandlersFired(result, Set(hid)), Right(result)) + } + implicit val ec = new ExecutionContext { + def execute(r: Runnable) { r.run() } + def reportFailure(t: Throwable) { t.printStackTrace() } + } + + checkEffect(attachEffect) { promise.onComplete(result => handlerQueue.add((result, hid))) } + chains = chains.updated(cid, chain.copy(state = newState)) + assertPromiseValues() + hid + } + } + + // Some methods and objects that build a list of promise + // actions to test and then execute them + + type PromiseKey = Int + + sealed trait Action + case class Complete(p: PromiseKey) extends Action + case class Link(a: PromiseKey, b: PromiseKey) extends Action + case class AttachHandler(p: PromiseKey) extends Action + + /** Tests a sequence of actions on a Tester. Creates promises as needed. */ + private def testActions(actions: Seq[Action]) { + val t = new Tester() + var pMap = Map.empty[PromiseKey, PromiseId] + def byKey(key: PromiseKey): PromiseId = { + if (!pMap.contains(key)) { + pMap = pMap.updated(key, t.newPromise()) + } + pMap(key) + } + + actions foreach { action => + action match { + case Complete(p) => t.complete(byKey(p)) + case Link(a, b) => t.link(byKey(a), byKey(b)) + case AttachHandler(p) => t.attachHandler(byKey(p)) + } + } + } + + /** Tests all permutations of actions for `count` promises */ + private def testPermutations(count: Int) { + val ps = (0 until count).toList + val pPairs = for (a <- ps; b <- ps) yield (a, b) + + var allActions = ps.map(Complete(_)) ++ pPairs.map { case (a, b) => Link(a, b) } ++ ps.map(AttachHandler(_)) + for ((permutation, i) <- allActions.permutations.zipWithIndex) { + testActions(permutation) + } + } + + /** Test all permutations of actions with a single promise */ + @Test + def testPermutations1 { + testPermutations(1) + } + + /** Test all permutations of actions with two promises - about 40 thousand */ + @Test + def testPermutations2 { + testPermutations(2) + } + + /** Link promises in different orders, using the same link structure as is + * used in Future.flatMap */ + @Test + def simulateFlatMapLinking { + val random = new scala.util.Random(1) + for (_ <- 0 until 10) { + val t = new Tester() + val flatMapCount = 100 + + sealed trait FlatMapEvent + case class Link(a: PromiseId, b: PromiseId) extends FlatMapEvent + case class Complete(p: PromiseId) extends FlatMapEvent + + @tailrec + def flatMapEvents(count: Int, p1: PromiseId, acc: List[FlatMapEvent]): List[FlatMapEvent] = { + if (count == 0) { + Complete(p1)::acc + } else { + val p2 = t.newPromise() + flatMapEvents(count - 1, p2, Link(p2, p1)::acc) + } + } + + val events = flatMapEvents(flatMapCount, t.newPromise(), Nil) + assertEquals(flatMapCount + 1, t.chains.size) // All promises are unlinked + val shuffled = random.shuffle(events) + shuffled foreach { + case Link(a, b) => t.link(a, b) + case Complete(p) => t.complete(p) + } + // All promises should be linked together, no matter the order of their linking + assertEquals(1, t.chains.size) + } + } + + /** Link promises together on more than one thread, using the same link + * structure as is used in Future.flatMap */ + @Test + def testFlatMapLinking { + for (_ <- 0 until 100) { + val flatMapCount = 100 + val startLatch = new CountDownLatch(1) + val doneLatch = new CountDownLatch(flatMapCount + 1) + def execute(f: => Unit) { + val ec = ExecutionContext.global + ec.execute(new Runnable { + def run() { + try { + startLatch.await() + f + doneLatch.countDown() + } catch { + case NonFatal(e) => ec.reportFailure(e) + } + } + }) + } + @tailrec + def flatMapTimes(count: Int, p1: DefaultPromise[Int]) { + if (count == 0) { + execute { p1.success(1) } + } else { + val p2 = new DefaultPromise[Int]() + execute { p2.linkRootOf(p1) } + flatMapTimes(count - 1, p2) + } + } + + val p = new DefaultPromise[Int]() + flatMapTimes(flatMapCount, p) + startLatch.countDown() + doneLatch.await() + assertEquals(Some(Success(1)), p.value) + } + } + +} diff --git a/test/junit/scala/tools/nsc/SampleTest.scala b/test/junit/scala/tools/nsc/SampleTest.scala new file mode 100644 index 0000000000..8e026da1ea --- /dev/null +++ b/test/junit/scala/tools/nsc/SampleTest.scala @@ -0,0 +1,17 @@ +package scala.tools.nsc +package test + +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +/** Sample JUnit test that shows that all pieces + of JUnit infrastructure work correctly */ +@RunWith(classOf[JUnit4]) +class SampleTest { + @Test + def testMath: Unit = { + assert(2+2 == 4, "you didn't get the math right fellow") + } +} diff --git a/test/pending/junit/scala/util/t7265.scala b/test/pending/junit/scala/util/t7265.scala new file mode 100644 index 0000000000..3b8fa80dbe --- /dev/null +++ b/test/pending/junit/scala/util/t7265.scala @@ -0,0 +1,46 @@ + +package scala.util +package test + +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +import scala.util.PropertiesTrait + +/** The java version property uses the spec version + * and must work for all "major.minor" and fail otherwise. + */ +@RunWith(classOf[JUnit4]) +class SpecVersionTest { + val sut = new PropertiesTrait { + override def javaSpecVersion = "1.7" + + override protected def pickJarBasedOn: Class[_] = ??? + override protected def propCategory: String = "test" + + // override because of vals like releaseVersion + override lazy val scalaProps = new java.util.Properties + } + + @Test + def comparesCorrectly(): Unit = { + assert(sut isJavaAtLeast "1.5") + assert(sut isJavaAtLeast "1.6") + assert(sut isJavaAtLeast "1.7") + assert(!(sut isJavaAtLeast "1.8")) + } + @Test(expected = classOf[NumberFormatException]) + def badVersion(): Unit = { + sut isJavaAtLeast "1.a" + } + @Test(expected = classOf[NumberFormatException]) + def missingVersion(): Unit = { + sut isJavaAtLeast "1" + } + @Test(expected = classOf[NumberFormatException]) + def notASpec(): Unit = { + sut isJavaAtLeast "1.7.1" + } +} |