diff options
29 files changed, 298 insertions, 46 deletions
@@ -128,6 +128,7 @@ TODO: <!-- Sets location of build folders --> <property name="build.dir" value="${basedir}/build"/> + <property name="build-deps.dir" value="${build.dir}/deps"/> <property name="build-libs.dir" value="${build.dir}/libs"/> <property name="build-asm.dir" value="${build.dir}/asm"/> <property name="build-forkjoin.dir" value="${build-libs.dir}"/> @@ -192,6 +193,18 @@ TODO: </touch> </target> + <macrodef name="copy-deps" description="Copy a file set based on maven dependency resolution to a directory. Currently used by the IntelliJ config files."> + <attribute name="fileset.prefix"></attribute> + <attribute name="out"></attribute> + <sequential> + <delete dir="${build-deps.dir}/@{out}" includes="*.jar"/> + <copy todir="${build-deps.dir}/@{out}"> + <fileset refid="@{fileset.prefix}.fileset" /> + <mapper type="flatten" /> + </copy> + </sequential> + </macrodef> + <target name="init" depends="boot"> <!-- Set up Ant contrib tasks so we can use <if><then><else> instead of the clunky `unless` attribute --> <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib-ant.dir}/ant-contrib.jar"/> @@ -218,6 +231,7 @@ TODO: <artifact:dependencies pathId="junit.classpath" filesetId="junit.fileset"> <dependency groupId="junit" artifactId="junit" version="${junit.version}"/> </artifact:dependencies> + <copy-deps fileset.prefix="junit" out="junit"/> <!-- Pax runner --> <property name="pax.exam.version" value="2.5.0"/> @@ -238,10 +252,12 @@ TODO: <dependency groupId="com.googlecode.java-diff-utils" artifactId="diffutils" version="1.3.0"/> <dependency groupId="org.scala-tools.testing" artifactId="test-interface" version="0.5" /> </artifact:dependencies> + <copy-deps fileset.prefix="partest.extras" out="partest"/> <artifact:dependencies pathId="repl.deps.classpath" filesetId="repl.deps.fileset" versionsId="repl.deps.versions"> <dependency groupId="jline" artifactId="jline" version="${jline.version}"/> </artifact:dependencies> + <copy-deps fileset.prefix="repl.deps" out="repl"/> <!-- BND support --> <typedef resource="aQute/bnd/ant/taskdef.properties" classpathref="extra.tasks.classpath" /> diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index 7578def687..b6f27f71ce 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -256,7 +256,7 @@ trait Reshape { val flags1 = (flags0 & GetterFlags) & ~(STABLE | ACCESSOR | METHOD) val mods1 = Modifiers(flags1, privateWithin0, annotations0) setPositions mods0.positions val mods2 = toPreTyperModifiers(mods1, ddef.symbol) - ValDef(mods2, name1.toTermName, tpt0, extractRhs(rhs0)) + ValDef(mods2, name1, tpt0, extractRhs(rhs0)) } private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = { diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index b17de9b9d5..66ed0c8fae 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -187,7 +187,7 @@ trait TreeDSL { def vparamss: List[List[ValDef]] type ResultTreeType = DefDef - def mkTree(rhs: Tree): DefDef = DefDef(mods, name, tparams, vparamss, tpt, rhs) + def mkTree(rhs: Tree): DefDef = DefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs) } class DefSymStart(val sym: Symbol) extends SymVODDStart with DefCreator { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index eb924a811b..d0b0c09d59 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2542,7 +2542,7 @@ self => } expr() } - DefDef(newmods, name, tparams, vparamss, restype, rhs) + DefDef(newmods, name.toTermName, tparams, vparamss, restype, rhs) } signalParseProgress(result.pos) result diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 2a799acbc7..239ecb4f8a 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -510,7 +510,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { if (inInterface) mods1 |= Flags.DEFERRED List { atPos(pos) { - DefDef(mods1, name, tparams, List(vparams), rtpt, body) + DefDef(mods1, name.toTermName, tparams, List(vparams), rtpt, body) } } } else { diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 0f65b11e9b..ee687e56b0 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -706,7 +706,8 @@ abstract class Erasure extends AddInterfaces // } typed(untyped) } - } else tree + } else qual1 + case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) if tree.symbol == Any_isInstanceOf => targ.tpe match { diff --git a/src/intellij/README b/src/intellij/README index 9ef612bd0a..ade87749cd 100644 --- a/src/intellij/README +++ b/src/intellij/README @@ -1,13 +1,8 @@ Use the latest IntelliJ IDEA release and install the Scala plugin from within the IDE. The following steps are required to use IntelliJ IDEA on Scala trunk - - compile "locker" using "ant locker.done" - - Copy the *.iml.SAMPLE / *.ipr.SAMPLE files to *.iml / *.ipr - - In IDEA, create a global library named "ant" which contains "ant.jar" - - Also create an SDK entry named "1.6" containing the java 1.6 SDK - - In the Scala Facet of the "library" and "reflect" modules, update the path in the - command-line argument for "-sourcepath" - - In the Project Settings, update the "Version Control" to match your checkout - -Known problems - - Due to SI-4365, the "library" module has to be built using "-Yno-generic-signatures" + - compile "locker" using "ant locker.done". This will also download some JARs from + Maven to ./build/deps, which are included in IntelliJ's classpath. + - Run src/intellij/setup.sh + - Open ./src/intellij/scala-lang.ipr in IntelliJ + - File, Project Settings, Project, SDK. Create an SDK entry named "1.6" containing the java 1.6 SDK diff --git a/src/intellij/compiler.iml.SAMPLE b/src/intellij/compiler.iml.SAMPLE index f8b1f31327..9fb9cd55eb 100644 --- a/src/intellij/compiler.iml.SAMPLE +++ b/src/intellij/compiler.iml.SAMPLE @@ -19,9 +19,8 @@ <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="module" module-name="library" /> <orderEntry type="module" module-name="reflect" /> - <orderEntry type="module" module-name="asm" /> - <orderEntry type="library" name="ant" level="application" /> - <orderEntry type="library" name="jline" level="project" /> + <orderEntry type="module" module-name="asm" exported="" /> + <orderEntry type="library" exported="" name="ant" level="project" /> </component> </module> diff --git a/src/intellij/diff.sh b/src/intellij/diff.sh new file mode 100755 index 0000000000..54f9248608 --- /dev/null +++ b/src/intellij/diff.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# +# Diffs the SAMPLE files against the working project config. +# +export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" +for f in "$SCRIPT_DIR"/*.{iml,ipr}; do + echo $f; diff -u $f.SAMPLE $f; +done diff --git a/src/intellij/library.iml.SAMPLE b/src/intellij/library.iml.SAMPLE index 9c1b7ec185..cac53dff15 100644 --- a/src/intellij/library.iml.SAMPLE +++ b/src/intellij/library.iml.SAMPLE @@ -5,7 +5,7 @@ <configuration> <option name="compilerLibraryLevel" value="Project" /> <option name="compilerLibraryName" value="compiler-locker" /> - <option name="compilerOptions" value="-sourcepath /Users/luc/scala/scala/src/library -Yno-generic-signatures" /> + <option name="compilerOptions" value="-sourcepath $BASE_DIR$/src/library" /> <option name="maximumHeapSize" value="1536" /> <option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" /> </configuration> diff --git a/src/intellij/manual.iml.SAMPLE b/src/intellij/manual.iml.SAMPLE index 62810e0cba..3295a4a877 100644 --- a/src/intellij/manual.iml.SAMPLE +++ b/src/intellij/manual.iml.SAMPLE @@ -18,7 +18,8 @@ <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="module" module-name="library" /> - <orderEntry type="library" name="ant" level="application" /> + <orderEntry type="module" module-name="xml" /> + <orderEntry type="library" name="ant" level="project" /> </component> </module> diff --git a/src/intellij/parser-combinators.iml.SAMPLE b/src/intellij/parser-combinators.iml.SAMPLE new file mode 100644 index 0000000000..1ef913dbe4 --- /dev/null +++ b/src/intellij/parser-combinators.iml.SAMPLE @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="FacetManager"> + <facet type="scala" name="Scala"> + <configuration> + <option name="compilerLibraryLevel" value="Project" /> + <option name="compilerLibraryName" value="compiler-locker" /> + <option name="maximumHeapSize" value="1536" /> + <option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" /> + </configuration> + </facet> + </component> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$/../parser-combinators"> + <sourceFolder url="file://$MODULE_DIR$/../parser-combinators" isTestSource="false" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="library" /> + </component> +</module> diff --git a/src/intellij/partest.iml.SAMPLE b/src/intellij/partest.iml.SAMPLE index ab4a32a9b3..5b8cfa3f38 100644 --- a/src/intellij/partest.iml.SAMPLE +++ b/src/intellij/partest.iml.SAMPLE @@ -18,11 +18,13 @@ <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="module" module-name="library" /> + <orderEntry type="module" module-name="xml" /> <orderEntry type="module" module-name="reflect" /> <orderEntry type="module" module-name="actors" /> <orderEntry type="module" module-name="scalap" /> <orderEntry type="module" module-name="compiler" /> - <orderEntry type="library" name="ant" level="application" /> + <orderEntry type="library" name="partest-deps" level="project" /> + <orderEntry type="module" module-name="repl" /> </component> </module> diff --git a/src/intellij/reflect.iml.SAMPLE b/src/intellij/reflect.iml.SAMPLE index 10973c503f..7d10522826 100644 --- a/src/intellij/reflect.iml.SAMPLE +++ b/src/intellij/reflect.iml.SAMPLE @@ -5,7 +5,7 @@ <configuration> <option name="compilerLibraryLevel" value="Project" /> <option name="compilerLibraryName" value="compiler-locker" /> - <option name="compilerOptions" value="-sourcepath /Users/luc/scala/scala/src/reflect" /> + <option name="compilerOptions" value="-sourcepath $BASE_DIR$/src/reflect" /> <option name="maximumHeapSize" value="1536" /> <option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" /> </configuration> diff --git a/src/intellij/repl.iml.SAMPLE b/src/intellij/repl.iml.SAMPLE index 5e11ff1cf6..fc78ffe8c2 100644 --- a/src/intellij/repl.iml.SAMPLE +++ b/src/intellij/repl.iml.SAMPLE @@ -20,6 +20,6 @@ <orderEntry type="module" module-name="library" /> <orderEntry type="module" module-name="reflect" /> <orderEntry type="module" module-name="compiler" /> + <orderEntry type="library" name="repl-deps" level="project" /> </component> </module> - diff --git a/src/intellij/scala-lang.ipr.SAMPLE b/src/intellij/scala-lang.ipr.SAMPLE index 61c813df01..f91a346b75 100644 --- a/src/intellij/scala-lang.ipr.SAMPLE +++ b/src/intellij/scala-lang.ipr.SAMPLE @@ -33,6 +33,9 @@ <component name="EntryPointsManager"> <entry_points version="2.0" /> </component> + <component name="HighlightingAdvisor"> + <option name="SUGGEST_TYPE_AWARE_HIGHLIGHTING" value="false" /> + </component> <component name="InspectionProjectProfileManager"> <profiles> <profile version="1.0" is_locked="false"> @@ -204,6 +207,7 @@ <module fileurl="file://$PROJECT_DIR$/interactive.iml" filepath="$PROJECT_DIR$/interactive.iml" /> <module fileurl="file://$PROJECT_DIR$/library.iml" filepath="$PROJECT_DIR$/library.iml" /> <module fileurl="file://$PROJECT_DIR$/manual.iml" filepath="$PROJECT_DIR$/manual.iml" /> + <module fileurl="file://$PROJECT_DIR$/parser-combinators.iml" filepath="$PROJECT_DIR$/parser-combinators.iml" /> <module fileurl="file://$PROJECT_DIR$/partest.iml" filepath="$PROJECT_DIR$/partest.iml" /> <module fileurl="file://$PROJECT_DIR$/reflect.iml" filepath="$PROJECT_DIR$/reflect.iml" /> <module fileurl="file://$PROJECT_DIR$/repl.iml" filepath="$PROJECT_DIR$/repl.iml" /> @@ -212,6 +216,7 @@ <module fileurl="file://$PROJECT_DIR$/scalap.iml" filepath="$PROJECT_DIR$/scalap.iml" /> <module fileurl="file://$PROJECT_DIR$/swing.iml" filepath="$PROJECT_DIR$/swing.iml" /> <module fileurl="file://$PROJECT_DIR$/test.iml" filepath="$PROJECT_DIR$/test.iml" /> + <module fileurl="file://$PROJECT_DIR$/xml.iml" filepath="$PROJECT_DIR$/xml.iml" /> </modules> </component> <component name="ProjectResources"> @@ -228,6 +233,13 @@ <mapping directory="$PROJECT_DIR$/../.." vcs="Git" /> </component> <component name="libraryTable"> + <library name="ant"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/../../lib/ant/ant.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> <library name="compiler-locker"> <CLASSES> <root url="file://$PROJECT_DIR$/../../build/locker/classes/library" /> @@ -238,13 +250,35 @@ <JAVADOC /> <SOURCES /> </library> - <library name="jline"> + <library name="junit"> <CLASSES> - <root url="jar://$PROJECT_DIR$/../../lib/jline.jar!/" /> + <root url="file://$PROJECT_DIR$/../../build/deps/junit" /> </CLASSES> <JAVADOC /> - <SOURCES /> + <SOURCES> + <root url="file://$PROJECT_DIR$/../../build/deps/junit" /> + </SOURCES> + <jarDirectory url="file://$PROJECT_DIR$/../../build/deps/junit" recursive="false" /> + <jarDirectory url="file://$PROJECT_DIR$/../../build/deps/junit" recursive="false" type="SOURCES" /> + </library> + <library name="partest-deps"> + <CLASSES> + <root url="file://$PROJECT_DIR$/../../build/deps/partest" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="file://$PROJECT_DIR$/../../build/deps/junit" /> + </SOURCES> + <jarDirectory url="file://$PROJECT_DIR$/../../build/deps/partest" recursive="false" /> + <jarDirectory url="file://$PROJECT_DIR$/../../build/deps/junit" recursive="false" type="SOURCES" /> </library> + <library name="repl-deps"> + <CLASSES> + <root url="file://$PROJECT_DIR$/../../build/deps/repl" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + <jarDirectory url="file://$PROJECT_DIR$/../../build/deps/repl" recursive="false" /> + </library> </component> </project> - diff --git a/src/intellij/scala.iml.SAMPLE b/src/intellij/scala.iml.SAMPLE index 8ea9d0dd71..a4d863800b 100644 --- a/src/intellij/scala.iml.SAMPLE +++ b/src/intellij/scala.iml.SAMPLE @@ -2,7 +2,9 @@ <module type="JAVA_MODULE" version="4"> <component name="NewModuleRootManager" inherit-compiler-output="true"> <exclude-output /> - <content url="file://$MODULE_DIR$/../.." /> + <content url="file://$MODULE_DIR$/../.."> + <excludeFolder url="file://$MODULE_DIR$/../../build" /> + </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> </component> diff --git a/src/intellij/scaladoc.iml.SAMPLE b/src/intellij/scaladoc.iml.SAMPLE index 6cc609919c..07bea5bf5d 100644 --- a/src/intellij/scaladoc.iml.SAMPLE +++ b/src/intellij/scaladoc.iml.SAMPLE @@ -20,5 +20,8 @@ <orderEntry type="module" module-name="library" /> <orderEntry type="module" module-name="reflect" /> <orderEntry type="module" module-name="compiler" /> + <orderEntry type="module" module-name="xml" /> + <orderEntry type="module" module-name="parser-combinators" /> + <orderEntry type="module" module-name="partest" /> </component> </module> diff --git a/src/intellij/setup.sh b/src/intellij/setup.sh new file mode 100755 index 0000000000..d0e1abeb96 --- /dev/null +++ b/src/intellij/setup.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# +# Generates IntelliJ IDEA project files based on the checked-in samples. +# + +set -e +export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" +export BASE="$( cd "$( dirname "$0" )"/../.. && pwd )" +echo "About to delete .ipr and .iml files and replace with the .SAMPLE files. Press enter to continue or CTRL-C to cancel." +read + +(rm *.ipr *.iml 2>/dev/null) +for f in $(ls "$SCRIPT_DIR"/*.SAMPLE); do + NEW_FILE=`echo $f | perl -pe 's/.SAMPLE//'`; + + cp $f $NEW_FILE + + # IntelliJ doesn't process the "compilerOptions" setting for variable + # replacement. If it did, we would just use "$PROJECT_DIR$". Instead, + # we do this replacement ourselves. + perl -pi -e 's/\$BASE_DIR\$/$ENV{"BASE"}/g' $NEW_FILE + echo "Created $NEW_FILE" +done diff --git a/src/intellij/test.iml.SAMPLE b/src/intellij/test.iml.SAMPLE index 3ce369be05..423be2062c 100644 --- a/src/intellij/test.iml.SAMPLE +++ b/src/intellij/test.iml.SAMPLE @@ -6,6 +6,8 @@ <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="module" module-name="library" /> + <orderEntry type="module" module-name="xml" /> + <orderEntry type="module" module-name="parser-combinators" /> <orderEntry type="module" module-name="reflect" /> <orderEntry type="module" module-name="compiler" /> <orderEntry type="module" module-name="actors" /> @@ -13,6 +15,7 @@ <orderEntry type="module" module-name="partest" /> <orderEntry type="module" module-name="asm" /> <orderEntry type="module" module-name="forkjoin" /> + <orderEntry type="library" name="junit" level="project" /> </component> </module> diff --git a/src/intellij/xml.iml.SAMPLE b/src/intellij/xml.iml.SAMPLE new file mode 100644 index 0000000000..b721f4e7f2 --- /dev/null +++ b/src/intellij/xml.iml.SAMPLE @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="FacetManager"> + <facet type="scala" name="Scala"> + <configuration> + <option name="compilerLibraryLevel" value="Project" /> + <option name="compilerLibraryName" value="compiler-locker" /> + <option name="maximumHeapSize" value="1536" /> + <option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" /> + </configuration> + </facet> + </component> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$/../xml"> + <sourceFolder url="file://$MODULE_DIR$/../xml" isTestSource="false" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="library" /> + </component> +</module> diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index c01694960c..b11368acdf 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -161,6 +161,8 @@ sealed abstract class List[+A] extends AbstractSeq[A] * @inheritdoc */ @inline final def mapConserve[B >: A <: AnyRef](f: A => B): List[B] = { + // Note to developers: there exists a duplication between this function and `reflect.internal.util.Collections#map2Conserve`. + // If any successful optimization attempts or other changes are made, please rehash them there too. @tailrec def loop(mapped: ListBuffer[B], unchanged: List[A], pending: List[A]): List[B] = if (pending.isEmpty) { diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index f7a6a68946..443f34ccae 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -572,8 +572,8 @@ trait Trees { self: Universe => * @group Extractors */ abstract class DefDefExtractor { - def apply(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef - def unapply(defDef: DefDef): Option[(Modifiers, Name, List[TypeDef], List[List[ValDef]], Tree, Tree)] + def apply(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef + def unapply(defDef: DefDef): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)] } /** The API that all def defs support @@ -584,7 +584,7 @@ trait Trees { self: Universe => def mods: Modifiers /** @inheritdoc */ - def name: Name + def name: TermName /** The type parameters of the method. */ def tparams: List[TypeDef] diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index ceb3b383d7..df1ba1e2ea 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -312,7 +312,7 @@ trait Trees extends api.Trees { self: SymbolTable => case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef with ValDefApi object ValDef extends ValDefExtractor - case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], + case class DefDef(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef with DefDefApi object DefDef extends DefDefExtractor diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 11527d88ca..71f46fedb7 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -80,7 +80,8 @@ trait Types with tpe.CommonOwners with tpe.GlbLubs with tpe.TypeMaps - with tpe.TypeConstraints { self: SymbolTable => + with tpe.TypeConstraints + with util.Collections { self: SymbolTable => import definitions._ import TypesStats._ @@ -4317,18 +4318,6 @@ trait Types } } - /** like map2, but returns list `xs` itself - instead of a copy - if function - * `f` maps all elements to themselves. - */ - def map2Conserve[A <: AnyRef, B](xs: List[A], ys: List[B])(f: (A, B) => A): List[A] = - if (xs.isEmpty || ys.isEmpty) xs - else { - val x1 = f(xs.head, ys.head) - val xs1 = map2Conserve(xs.tail, ys.tail)(f) - if ((x1 eq xs.head) && (xs1 eq xs.tail)) xs - else x1 :: xs1 - } - /** Do type arguments `targs` conform to formal parameters `tparams`? */ def isWithinBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): Boolean = { diff --git a/src/reflect/scala/reflect/internal/util/Collections.scala b/src/reflect/scala/reflect/internal/util/Collections.scala index e127d577e1..59af819dad 100644 --- a/src/reflect/scala/reflect/internal/util/Collections.scala +++ b/src/reflect/scala/reflect/internal/util/Collections.scala @@ -53,6 +53,42 @@ trait Collections { } lb.toList } + + /** like map2, but returns list `xs` itself - instead of a copy - if function + * `f` maps all elements to themselves. + */ + final def map2Conserve[A <: AnyRef, B](xs: List[A], ys: List[B])(f: (A, B) => A): List[A] = { + // Note to developers: there exists a duplication between this function and `List#mapConserve`. + // If any successful optimization attempts or other changes are made, please rehash them there too. + @tailrec + def loop(mapped: ListBuffer[A], unchanged: List[A], pending0: List[A], pending1: List[B]): List[A] = { + if (pending0.isEmpty || pending1.isEmpty) { + if (mapped eq null) unchanged + else mapped.prependToList(unchanged) + } else { + val head00 = pending0.head + val head01 = pending1.head + val head1 = f(head00, head01) + + if ((head1 eq head00.asInstanceOf[AnyRef])) { + loop(mapped, unchanged, pending0.tail, pending1.tail) + } else { + val b = if (mapped eq null) new ListBuffer[A] else mapped + var xc = unchanged + while ((xc ne pending0) && (xc ne pending1)) { + b += xc.head + xc = xc.tail + } + b += head1 + val tail0 = pending0.tail + val tail1 = pending1.tail + loop(b, tail0, tail0, tail1) + } + } + } + loop(null, xs, xs, ys) + } + final def map3[A, B, C, D](xs1: List[A], xs2: List[B], xs3: List[C])(f: (A, B, C) => D): List[D] = { if (xs1.isEmpty || xs2.isEmpty || xs3.isEmpty) Nil else f(xs1.head, xs2.head, xs3.head) :: map3(xs1.tail, xs2.tail, xs3.tail)(f) diff --git a/test/files/pos/erasure-nsquared.scala b/test/files/pos/erasure-nsquared.scala new file mode 100644 index 0000000000..b0e30ade58 --- /dev/null +++ b/test/files/pos/erasure-nsquared.scala @@ -0,0 +1,35 @@ +trait BigCast { + def bar(x: Int): AnyRef = ( + null + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + .asInstanceOf[List[AnyRef]].head + ) +} diff --git a/test/files/scalacheck/CheckCollections.scala b/test/files/scalacheck/CheckCollections.scala new file mode 100644 index 0000000000..108040b900 --- /dev/null +++ b/test/files/scalacheck/CheckCollections.scala @@ -0,0 +1,59 @@ +import org.scalacheck.{ ConsoleReporter, Properties } +import org.scalacheck.Prop._ + +import scala.reflect.internal.util.Collections._ + +object Test extends Properties("reflect.internal.util.Collections") { + def map2ConserveOld[A <: AnyRef, B](xs: List[A], ys: List[B])(f: (A, B) => A): List[A] = + if (xs.isEmpty || ys.isEmpty) xs + else { + val x1 = f(xs.head, ys.head) + val xs1 = map2Conserve(xs.tail, ys.tail)(f) + if ((x1 eq xs.head) && (xs1 eq xs.tail)) xs + else x1 :: xs1 + } + + val testfun: (String, Int) => String = { case(x, y) => + x.toLowerCase + y.toString + } + val testid: (String, Int) => String = { case (x, y) => x } + + val prop1_map2Conserve = forAll { (xs: List[String], ys: List[Int]) => + val res = map2Conserve(xs, ys)(testid) + res eq xs + } + + val prop2_map2Conserve = forAll { (xs: List[String], ys: List[Int]) => + map2Conserve(xs, ys)(testid) == map2ConserveOld(xs, ys)(testid) && + map2Conserve(xs, ys)(testfun) == map2ConserveOld(xs, ys)(testfun) + } + + def checkStackOverflow() { + var xs: List[String] = Nil + var ys: List[Int] = Nil + for (i <- 0 until 250000) { + xs = "X" :: xs + ys = 1 :: ys + } + map2Conserve(xs, ys){ case(x, y) => x.toLowerCase + y.toString } + } + + + val tests = List( + ("map2Conserve(identity)", prop1_map2Conserve), + ("map2Conserve == old impl", prop2_map2Conserve) + ) + + checkStackOverflow() + + for { + (label, prop) <- tests + } property(label) = prop + + import org.scalacheck.{ Test => STest } + + def runTests() = + STest.checkProperties( + STest.Params(testCallback = ConsoleReporter(0)), this) + +} diff --git a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala index 03f8aa58d3..23b6a5fbdb 100644 --- a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala +++ b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala @@ -91,7 +91,7 @@ trait ArbitraryTreesAndNames { yield CompoundTypeTree(templ) def genDefDef(size: Int) = - for(mods <- genModifiers; name <- genName; + for(mods <- genModifiers; name <- genTermName; tpt <- genTree(size -1); rhs <- genTree(size - 1); tparams <- smallList(size, genTypeDef(size - 1)); vparamss <- smallList(size, smallList(size, genValDef(size - 1)))) |