summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build/maven/maven-deploy.xml281
-rw-r--r--src/build/maven/scala-dist-pom.xml6
-rw-r--r--src/build/maven/scala-library-all-pom.xml10
-rw-r--r--src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala2
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Names.scala3
-rw-r--r--src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala2
-rwxr-xr-x[-rw-r--r--]src/compiler/scala/tools/ant/templates/tool-unix.tmpl8
-rw-r--r--src/compiler/scala/tools/ant/templates/tool-windows.tmpl10
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala11
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala38
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala14
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/Logic.scala23
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala19
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala122
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala44
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala64
-rw-r--r--src/compiler/scala/tools/reflect/FormatInterpolator.scala3
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Holes.scala16
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala15
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala6
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala2
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala58
-rw-r--r--src/intellij/README10
-rw-r--r--src/intellij/actors.iml.SAMPLE3
-rw-r--r--src/intellij/compiler.iml.SAMPLE7
-rw-r--r--src/intellij/interactive.iml.SAMPLE4
-rw-r--r--src/intellij/library.iml.SAMPLE5
-rw-r--r--src/intellij/manual.iml.SAMPLE5
-rw-r--r--src/intellij/partest-extras.iml.SAMPLE27
-rw-r--r--src/intellij/partest-javaagent.iml.SAMPLE13
-rw-r--r--src/intellij/reflect.iml.SAMPLE6
-rw-r--r--src/intellij/repl.iml.SAMPLE4
-rw-r--r--src/intellij/scala-lang.ipr.SAMPLE72
-rw-r--r--src/intellij/scaladoc.iml.SAMPLE9
-rw-r--r--src/intellij/scalap.iml.SAMPLE3
-rwxr-xr-xsrc/intellij/setup.sh15
-rw-r--r--src/intellij/test-junit.iml.SAMPLE30
-rw-r--r--src/intellij/test.iml.SAMPLE22
-rwxr-xr-xsrc/intellij/update.sh22
-rw-r--r--src/library/scala/PartialFunction.scala2
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala1
-rw-r--r--src/library/scala/collection/Iterator.scala10
-rw-r--r--src/library/scala/collection/LinearSeq.scala2
-rw-r--r--src/library/scala/collection/convert/Wrappers.scala2
-rw-r--r--src/library/scala/collection/generic/Sorted.scala3
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala19
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala9
-rw-r--r--src/library/scala/reflect/Manifest.scala3
-rw-r--r--src/reflect/scala/reflect/api/Internals.scala69
-rw-r--r--src/reflect/scala/reflect/api/Liftables.scala8
-rw-r--r--src/reflect/scala/reflect/api/Mirror.scala18
-rw-r--r--src/reflect/scala/reflect/api/Quasiquotes.scala2
-rw-r--r--src/reflect/scala/reflect/api/StandardLiftables.scala1
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala8
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala13
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala5
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala234
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala77
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala8
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Variances.scala9
-rw-r--r--src/reflect/scala/reflect/internal/pickling/Translations.scala31
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala23
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala13
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala10
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala9
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/DocFactory.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala2
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala4
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala25
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala12
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js54
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/permalink.pngbin0 -> 943 bytes
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css31
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js94
-rw-r--r--src/scalap/scala/tools/scalap/Arguments.scala1
-rw-r--r--src/scalap/scala/tools/scalap/ByteArrayReader.scala12
-rw-r--r--src/scalap/scala/tools/scalap/Classfile.scala2
-rw-r--r--src/scalap/scala/tools/scalap/Classfiles.scala2
-rw-r--r--src/scalap/scala/tools/scalap/CodeWriter.scala8
-rw-r--r--src/scalap/scala/tools/scalap/Decode.scala30
-rw-r--r--src/scalap/scala/tools/scalap/JavaWriter.scala4
-rw-r--r--src/scalap/scala/tools/scalap/Main.scala16
-rw-r--r--src/scalap/scala/tools/scalap/MetaParser.scala6
-rw-r--r--src/scalap/scala/tools/scalap/Properties.scala3
-rw-r--r--src/scalap/scala/tools/scalap/rules/package.scala6
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/Memoisable.scala (renamed from src/scalap/scala/tools/scalap/rules/Memoisable.scala)9
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/Result.scala (renamed from src/scalap/scala/tools/scalap/rules/Result.scala)4
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/Rule.scala (renamed from src/scalap/scala/tools/scalap/rules/Rule.scala)7
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/Rules.scala (renamed from src/scalap/scala/tools/scalap/rules/Rules.scala)3
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/SeqRule.scala (renamed from src/scalap/scala/tools/scalap/rules/SeqRule.scala)9
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala (renamed from src/scalap/scala/tools/scalap/scalasig/ClassFileParser.scala)23
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/Flags.scala (renamed from src/scalap/scala/tools/scalap/scalasig/Flags.scala)5
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala (renamed from src/scalap/scala/tools/scalap/scalasig/ScalaSig.scala)20
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala (renamed from src/scalap/scala/tools/scalap/scalasig/ScalaSigPrinter.scala)31
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/SourceFileAttributeParser.scala (renamed from src/scalap/scala/tools/scalap/scalasig/SourceFileAttributeParser.scala)12
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/Symbol.scala (renamed from src/scalap/scala/tools/scalap/scalasig/Symbol.scala)5
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/Type.scala (renamed from src/scalap/scala/tools/scalap/scalasig/Type.scala)5
-rw-r--r--src/scalap/scala/tools/scalap/scalax/util/StringUtil.scala19
112 files changed, 1335 insertions, 804 deletions
diff --git a/src/build/maven/maven-deploy.xml b/src/build/maven/maven-deploy.xml
deleted file mode 100644
index a2c3eefbca..0000000000
--- a/src/build/maven/maven-deploy.xml
+++ /dev/null
@@ -1,281 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-THIS FILE WILL SOON SELF DESTRUCT; DO NOT USE
-see publish.* targets in /build.xml
--->
-<project name="sabbus-maven-deploy" xmlns:artifact="urn:maven-artifact-ant">
-
- <description>
- SuperSabbus extension for deploying a distribution to Maven. THIS FILE IS MEANT TO BE RUN STANDALONE IN THE MAVEN "distpack" DIRECTORY
- </description>
-
-
- <macrodef name="deploy-remote">
- <attribute name="jar" default=""/>
- <attribute name="pom"/>
- <element name="artifacts" implicit="true" optional="true"/>
- <sequential>
- <if><equals arg1="@{jar}" arg2="true"/><then>
- <artifact:deploy settingsFile="${settings.file}">
- <artifact:remoteRepository url="${remote.repository}" id="${repository.credentials.id}" />
- <artifact:pom refid="@{pom}" />
- <artifacts/>
- </artifact:deploy>
- </then><else>
- <artifact:deploy file="@{jar}" settingsFile="${settings.file}">
- <artifact:remoteRepository url="${remote.repository}" id="${repository.credentials.id}" />
- <artifact:pom refid="@{pom}" />
- <artifacts/>
- </artifact:deploy>
- </else></if>
- </sequential>
- </macrodef>
-
- <macrodef name="deploy-local">
- <attribute name="jar" default=""/>
- <attribute name="pom"/>
- <element name="artifacts" implicit="true" optional="true"/>
- <sequential>
- <if><equals arg1="@{jar}" arg2="true"/><then>
- <artifact:install>
- <artifact:localRepository path="${local.repository}" id="${repository.credentials.id}" />
- <artifact:pom refid="@{pom}" />
- <artifacts/>
- </artifact:install>
- </then><else>
- <artifact:install file="@{jar}">
- <artifact:localRepository path="${local.repository}" id="${repository.credentials.id}" />
- <artifact:pom refid="@{pom}" />
- <artifacts/>
- </artifact:install>
- </else></if>
- </sequential>
- </macrodef>
-
- <macrodef name="deploy-to">
- <attribute name="jar" default=""/>
- <attribute name="pom"/>
- <attribute name="local"/>
- <element name="artifacts" implicit="true" optional="true"/>
- <sequential>
- <if><equals arg1="@{local}" arg2="true"/><then>
- <deploy-local jar="@{jar}" pom="@{pom}"> <artifacts/> </deploy-local>
- </then><else>
- <deploy-remote jar="@{jar}" pom="@{pom}"> <artifacts/> </deploy-remote>
- </else></if>
- </sequential>
- </macrodef>
-
- <macrodef name="filter-pom">
- <attribute name="path" />
- <attribute name="name" />
-
- <sequential>
- <copy file="${path}-pom.xml" tofile="${path}-pom-filtered.xml" overwrite="true">
- <filterset>
- <filter token="VERSION" value="${maven.version.number}" />
- <filter token="SCALA_BINARY_VERSION" value="${scala.binary.version}" />
- <filter token="XML_VERSION" value="${scala-xml.version.number}" />
- <filter token="PARSER_COMBINATORS_VERSION" value="${scala-parser-combinators.version.number}" />
- <filter token="CONTINUATIONS_PLUGIN_VERSION" value="${scala-continuations-plugin.version.number}" />
- <filter token="CONTINUATIONS_LIBRARY_VERSION" value="${scala-continuations-library.version.number}" />
- <filter token="SCALA_SWING_VERSION" value="${scala-swing.version.number}" />
- <filter token="RELEASE_REPOSITORY" value="${remote.release.repository}" />
- <filter token="SNAPSHOT_REPOSITORY" value="${remote.snapshot.repository}" />
- <filter token="JLINE_VERSION" value="${jline.version}" />
- <filter token="AKKA_ACTOR_VERSION" value="${akka-actor.version.number}" />
- <filter token="ACTORS_MIGRATION_VERSION" value="${actors-migration.version.number}" />
-
- <!-- TODO modularize compiler.
- <filter token="SCALA_COMPILER_DOC_VERSION" value="${scala-compiler-doc.version.number}" />
- <filter token="SCALA_COMPILER_INTERACTIVE_VERSION" value="${scala-compiler-interactive.version.number}" />
- -->
- </filterset>
- </copy>
- <artifact:pom id="@{name}.pom" file="${path}-pom-filtered.xml" />
- </sequential>
- </macrodef>
-
- <macrodef name="deploy-one">
- <attribute name="name" />
- <attribute name="local" default="false"/>
- <attribute name="signed" default="false"/>
-
- <sequential>
- <local name="path"/> <property name="path" value="${dist.maven}/@{name}/@{name}"/>
-
- <echo>Deploying ${path}-[pom.xml|src.jar|docs.jar].</echo>
-
- <filter-pom name="@{name}" path="@{path}"/>
-
- <if><equals arg1="@{signed}" arg2="false"/><then>
- <if><isset property="docs.skip"/><then>
- <deploy-to local="@{local}" jar="${path}.jar" pom="@{name}.pom">
- <artifact:attach type="jar" file="${path}-src.jar" classifier="sources" />
- </deploy-to>
- </then><else>
- <deploy-to local="@{local}" jar="${path}.jar" pom="@{name}.pom">
- <artifact:attach type="jar" file="${path}-src.jar" classifier="sources" />
- <artifact:attach type="jar" file="${path}-docs.jar" classifier="javadoc" />
- </deploy-to>
- </else></if>
- </then><else>
- <local name="repo"/>
- <if><equals arg1="@{local}" arg2="false"/><then>
- <property name="repo" value="${remote.repository}"/>
- </then><else>
- <property name="repo" value="${local.repository}"/>
- </else></if>
- <artifact:mvn failonerror="true">
- <arg value="org.apache.maven.plugins:maven-gpg-plugin:1.3:sign-and-deploy-file" />
- <arg value="-Durl=${repo}" />
- <arg value="-DrepositoryId=${repository.credentials.id}" />
- <arg value="-DpomFile=${path}-pom-filtered.xml" />
- <arg value= "-Dfile=${path}.jar" />
- <arg value="-Dsources=${path}-src.jar" />
- <arg value="-Djavadoc=${path}-docs.jar" />
- <arg value="-Pgpg" />
- <arg value="-Dgpg.useagent=true" />
- </artifact:mvn>
- </else></if>
- </sequential>
- </macrodef>
-
- <macrodef name="deploy-jar">
- <attribute name="name" />
- <attribute name="local" default="false"/>
- <attribute name="signed" default="false"/>
-
- <sequential>
- <local name="path"/> <property name="path" value="${dist.maven}/@{name}/@{name}"/>
-
- <echo>Deploying ${path}.jar with ${path}-pom.xml.</echo>
-
- <filter-pom name="@{name}" path="@{path}"/>
-
- <if><equals arg1="@{signed}" arg2="false"/><then>
- <deploy-to local="@{local}" jar="${path}.jar" pom="@{name}.pom"/>
- </then><else>
- <local name="repo"/>
- <if><equals arg1="@{local}" arg2="false"/><then>
- <property name="repo" value="${remote.repository}"/>
- </then><else>
- <property name="repo" value="${local.repository}"/>
- </else></if>
- <artifact:mvn failonerror="true">
- <arg value="org.apache.maven.plugins:maven-gpg-plugin:1.3:sign-and-deploy-file" />
- <arg value="-Durl=${repo}" />
- <arg value="-DrepositoryId=${repository.credentials.id}" />
- <arg value="-DpomFile=${path}-pom-filtered.xml" />
- <arg value= "-Dfile=${path}.jar" />
- <arg value="-Pgpg" />
- <arg value="-Dgpg.useagent=true" />
- </artifact:mvn>
- </else></if>
- </sequential>
- </macrodef>
-
- <macrodef name="deploy-pom">
- <attribute name="name" />
- <attribute name="local" default="false"/>
- <attribute name="signed" default="false"/>
-
- <sequential>
- <local name="path"/> <property name="path" value="${dist.maven}/@{name}/@{name}"/>
-
- <echo>Deploying ${path}-pom.xml.</echo>
-
- <filter-pom name="@{name}" path="@{path}"/>
-
- <if><equals arg1="@{signed}" arg2="false"/><then>
- <deploy-to local="@{local}" pom="@{name}.pom"/>
- </then><else>
- <local name="repo"/>
- <if><equals arg1="@{local}" arg2="false"/><then>
- <property name="repo" value="${remote.repository}"/>
- </then><else>
- <property name="repo" value="${local.repository}"/>
- </else></if>
- <artifact:mvn failonerror="true">
- <arg value="org.apache.maven.plugins:maven-gpg-plugin:1.3:sign-and-deploy-file" />
- <arg value="-Durl=${repo}" />
- <arg value="-DrepositoryId=${repository.credentials.id}" />
- <arg value="-DpomFile=${path}-pom-filtered.xml" />
- <arg value= "-Dfile=${path}-pom-filtered.xml" />
- <arg value="-Pgpg" />
- <arg value="-Dgpg.useagent=true" />
- </artifact:mvn>
- </else></if>
- </sequential>
- </macrodef>
-
- <macrodef name="deploy">
- <attribute name="local" default="false"/>
- <attribute name="signed" default="false"/>
-
- <sequential>
- <deploy-one name="scala-library" local="@{local}" signed="@{signed}"/>
- <deploy-one name="scala-reflect" local="@{local}" signed="@{signed}"/>
- <deploy-one name="scala-compiler" local="@{local}" signed="@{signed}"/>
-
- <!-- TODO modularize compiler.
- <deploy-one name="scala-compiler-doc" local="@{local}" signed="@{signed}"/>
- <deploy-one name="scala-compiler-interactive" local="@{local}" signed="@{signed}"/>
- -->
-
- <deploy-one name="scala-actors" local="@{local}" signed="@{signed}"/>
- <deploy-one name="scalap" local="@{local}" signed="@{signed}"/>
- </sequential>
- </macrodef>
-
-
- <target name="boot.maven">
- <!-- Pull in properties from build -->
- <property file="build.properties" />
- <!-- Set up Ant contrib tasks so we can use <if><then><else> instead of the clunky `unless` attribute -->
- <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="ant-contrib.jar"/>
-
- <!-- Add our maven ant tasks -->
- <path id="maven-ant-tasks.classpath" path="maven-ant-tasks-2.1.1.jar" />
- <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
- </target>
-
- <target name="init.maven" depends="boot.maven">
- <property name="remote.snapshot.repository" value="https://oss.sonatype.org/content/repositories/snapshots" />
- <property name="remote.release.repository" value="https://oss.sonatype.org/service/local/staging/deploy/maven2" />
-
- <property name="local.snapshot.repository" value="${user.home}/.m2/repository" />
- <property name="local.release.repository" value="${user.home}/.m2/repository" />
-
- <property name="repository.credentials.id" value="sonatype-nexus" />
- <property name="settings.file" value="${user.home}/.m2/settings.xml" />
-
- <if><contains string="${maven.version.number}" substring="-SNAPSHOT"/><then>
- <property name="remote.repository" value="${remote.snapshot.repository}"/>
- <property name="local.repository" value="${local.snapshot.repository}"/>
- </then><else>
- <property name="remote.repository" value="${remote.release.repository}"/>
- <property name="local.repository" value="${local.release.repository}"/>
- </else></if>
-
- <echo>Using server[${repository.credentials.id}] for maven repository credentials.
- Please make sure that your ~/.m2/settings.xml has the needed username/password for this server id
- </echo>
- </target>
-
- <target name="deploy" depends="init.maven" description="Deploys unsigned artifacts to the maven repo.">
- <echo message="WARNING!1! THIS TARGET HAS BEEN DEPRECATED -- CALL `ant publish` FROM /build.xml"/>
- <deploy/>
- </target>
-
- <target name="deploy.local" depends="init.maven" description="Deploys unsigned artifacts to the local maven repo.">
- <echo message="WARNING!1! THIS TARGET HAS BEEN DEPRECATED -- CALL `ant publish.local` FROM /build.xml"/>
- <deploy local="true"/>
- </target>
-
- <target name="deploy.signed" depends="init.maven" description="Deploys signed artifacts to the remote maven repo.">
- <echo message="WARNING!1! THIS TARGET HAS BEEN DEPRECATED -- CALL `ant publish.signed` FROM /build.xml"/>
- <deploy signed="true"/>
- </target>
-</project>
diff --git a/src/build/maven/scala-dist-pom.xml b/src/build/maven/scala-dist-pom.xml
index 9a566d231b..22a24dea21 100644
--- a/src/build/maven/scala-dist-pom.xml
+++ b/src/build/maven/scala-dist-pom.xml
@@ -39,6 +39,12 @@
<artifactId>scala-compiler</artifactId>
<version>@VERSION@</version>
</dependency>
+ <dependency>
+ <groupId>org.scala-lang.plugins</groupId>
+ <!-- plugins are fully cross-versioned. But, we don't publish with 2.11.0-SNAPSHOT, instead use full version of the last non-snapshot version -->
+ <artifactId>scala-continuations-plugin_@SCALA_FULL_VERSION@</artifactId>
+ <version>@CONTINUATIONS_PLUGIN_VERSION@</version>
+ </dependency>
<!-- duplicated from scala-compiler, where it's optional,
so that resolving scala-dist's transitive dependencies does not include jline,
even though we need to include it in the dist, but macros depending on the compiler
diff --git a/src/build/maven/scala-library-all-pom.xml b/src/build/maven/scala-library-all-pom.xml
index b649c8c525..3fcf207559 100644
--- a/src/build/maven/scala-library-all-pom.xml
+++ b/src/build/maven/scala-library-all-pom.xml
@@ -49,11 +49,11 @@
<artifactId>scala-parser-combinators_@SCALA_BINARY_VERSION@</artifactId>
<version>@PARSER_COMBINATORS_VERSION@</version>
</dependency>
- <dependency>
- <groupId>org.scala-lang.plugins</groupId>
- <artifactId>scala-continuations-plugin_@SCALA_BINARY_VERSION@</artifactId>
- <version>@CONTINUATIONS_PLUGIN_VERSION@</version>
- </dependency>
+ <!--
+ the continuations plugin is a dependency of scala-dist, as scala-library-all should be
+ a drop-in replacement for scala-library, and as such should not (indirectly)
+ depend on plugins/the compiler.
+ -->
<dependency>
<groupId>org.scala-lang.plugins</groupId>
<artifactId>scala-continuations-library_@SCALA_BINARY_VERSION@</artifactId>
diff --git a/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala
index 1413065a27..a13a778b2f 100644
--- a/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala
+++ b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala
@@ -53,7 +53,7 @@ abstract class DefaultMacroCompiler extends Resolvers
(EmptyTree, TermName(""), Nil)
}
val bundleImplRef = MacroImplRefCompiler(
- atPos(macroDdef.rhs.pos)(gen.mkTypeApply(Select(New(maybeBundleRef, List(List(Ident(Predef_???)))), methName), targs)),
+ atPos(macroDdef.rhs.pos)(gen.mkTypeApply(Select(New(maybeBundleRef, List(List(Literal(Constant(null))))), methName), targs)),
isImplBundle = true
)
val vanillaResult = tryCompile(vanillaImplRef)
diff --git a/src/compiler/scala/reflect/macros/contexts/Names.scala b/src/compiler/scala/reflect/macros/contexts/Names.scala
index 299af40b94..5a5bb428b5 100644
--- a/src/compiler/scala/reflect/macros/contexts/Names.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Names.scala
@@ -33,8 +33,9 @@ trait Names {
//
// TODO: hopefully SI-7823 will provide an ultimate answer to this problem.
// In the meanwhile I will also keep open the original issue: SI-6879 "c.freshName is broken".
+ val prefix = if (name.endsWith("$")) name else name + "$" // SI-8425
val sortOfUniqueSuffix = freshNameCreator.newName(nme.FRESH_SUFFIX)
- name + "$" + sortOfUniqueSuffix
+ prefix + sortOfUniqueSuffix
}
def freshName[NameType <: Name](name: NameType): NameType =
diff --git a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
index ecdd48db22..be114efbc0 100644
--- a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
+++ b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
@@ -14,7 +14,7 @@ trait JavaReflectionRuntimes {
def resolveJavaReflectionRuntime(classLoader: ClassLoader): MacroRuntime = {
val implClass = Class.forName(className, true, classLoader)
- val implMeths = implClass.getDeclaredMethods.find(_.getName == methName)
+ val implMeths = implClass.getMethods.find(_.getName == methName)
// relies on the fact that macro impls cannot be overloaded
// so every methName can resolve to at maximum one method
val implMeth = implMeths getOrElse { throw new NoSuchMethodException(s"$className.$methName") }
diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
index 88fee71843..f58223a39e 100644..100755
--- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
+++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
@@ -144,6 +144,10 @@ classpathArgs () {
fi
}
+# SI-8358, SI-8368 -- the default should really be false,
+# but I don't want to flip the default during 2.11's RC cycle
+OVERRIDE_USEJAVACP="-Dscala.usejavacp=true"
+
while [[ $# -gt 0 ]]; do
case "$1" in
-D*)
@@ -151,6 +155,8 @@ while [[ $# -gt 0 ]]; do
# need it, e.g. communicating with a server compiler.
java_args=("${java_args[@@]}" "$1")
scala_args=("${scala_args[@@]}" "$1")
+ # respect user-supplied -Dscala.usejavacp
+ case "$1" in -Dscala.usejavacp*) OVERRIDE_USEJAVACP="";; esac
shift
;;
-J*)
@@ -199,7 +205,7 @@ execCommand \
"${java_args[@@]}" \
$(classpathArgs) \
-Dscala.home="$SCALA_HOME" \
- -Dscala.usejavacp=true \
+ $OVERRIDE_USEJAVACP \
"$EMACS_OPT" \
$WINDOWS_OPT \
@properties@ @class@ @toolflags@ "$@@"
diff --git a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
index 8441f3af23..cf0e003f10 100644
--- a/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
+++ b/src/compiler/scala/tools/ant/templates/tool-windows.tmpl
@@ -25,6 +25,10 @@ shift
:notoolcp
+rem SI-8358, SI-8368 -- the default should really be false,
+rem but I don't want to flip the default during 2.11's RC cycle
+set _OVERRIDE_USEJAVACP="-Dscala.usejavacp=true"
+
rem We keep in _JAVA_PARAMS all -J-prefixed and -D-prefixed arguments
set _JAVA_PARAMS=
@@ -45,6 +49,10 @@ if "%_TEST_PARAM:~0,2%"=="-J" (
)
if "%_TEST_PARAM:~0,2%"=="-D" (
+ rem Only match beginning of the -D option. The relevant bit is 17 chars long.
+ if "%_TEST_PARAM:~0,17%"=="-Dscala.usejavacp" (
+ set _OVERRIDE_USEJAVACP=
+ )
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%" (
@@ -126,7 +134,7 @@ if "%_TOOL_CLASSPATH%"=="" (
if not "%_LINE_TOOLCP%"=="" call :add_cpath "%_LINE_TOOLCP%"
-set _PROPS=-Dscala.home="!_SCALA_HOME!" -Denv.emacs="%EMACS%" -Dscala.usejavacp=true @properties@
+set _PROPS=-Dscala.home="!_SCALA_HOME!" -Denv.emacs="%EMACS%" %_OVERRIDE_USEJAVACP% @properties@
rem echo "%_JAVACMD%" %_JAVA_OPTS% %_PROPS% -cp "%_TOOL_CLASSPATH%" @class@ @toolflags@ %*
"%_JAVACMD%" %_JAVA_OPTS% %_PROPS% -cp "%_TOOL_CLASSPATH%" @class@ @toolflags@ %*
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 6b14461cac..35eab94333 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -236,6 +236,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
override def inform(msg: String) = inform(NoPosition, msg)
override def globalError(msg: String) = globalError(NoPosition, msg)
override def warning(msg: String) = warning(NoPosition, msg)
+ override def deprecationWarning(pos: Position, msg: String) = currentUnit.deprecationWarning(pos, msg)
def globalError(pos: Position, msg: String) = reporter.error(pos, msg)
def warning(pos: Position, msg: String) = if (settings.fatalWarnings) globalError(pos, msg) else reporter.warning(pos, msg)
@@ -1236,7 +1237,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
}
private val unitbuf = new SyncedCompilationBuffer
-
+
val compiledFiles = new mutable.HashSet[String]
/** A map from compiled top-level symbols to their source files */
@@ -1491,7 +1492,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
made to the underlying structure.
*/
def units: Iterator[CompilationUnit] = unitbuf.iterator
-
+
def registerPickle(sym: Symbol): Unit = ()
/** does this run compile given class, module, or case factory? */
@@ -1798,8 +1799,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
private def writeICode() {
val printer = new icodes.TextPrinter(null, icodes.linearizer)
icodes.classes.values.foreach((cls) => {
- val suffix = s"${if (cls.symbol.hasModuleFlag) "$" else ""}_${phase}.icode"
- val file = getFile(cls.symbol, suffix)
+ val moduleSfx = if (cls.symbol.hasModuleFlag) "$" else ""
+ val phaseSfx = if (settings.debug) phase else "" // only for debugging, appending the full phasename breaks windows build
+ val file = getFile(cls.symbol, s"$moduleSfx$phaseSfx.icode")
+
try {
val stream = new FileOutputStream(file)
printer.setWriter(new PrintWriter(stream, true))
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 9ca06427e8..3652f51153 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -240,6 +240,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
registerLocal(sym.moduleClass)
registerLocal(sym.companionClass)
registerLocal(sym.companionModule)
+ registerLocal(sym.deSkolemize)
sym match {
case sym: TermSymbol => registerLocal(sym.referenced)
case _ => ;
@@ -309,7 +310,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
// if we move these trees into lexical contexts different from their original locations.
if (dupl.hasSymbol) {
val sym = dupl.symbol
- val vetoScope = !brutally && !(locals contains sym)
+ val vetoScope = !brutally && !(locals contains sym) && !(locals contains sym.deSkolemize)
val vetoThis = dupl.isInstanceOf[This] && sym.isPackageClass
if (!(vetoScope || vetoThis)) dupl.symbol = NoSymbol
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 3542fe5945..ffc45b21ea 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -654,9 +654,10 @@ self =>
def isIdentExcept(except: Name) = isIdent && in.name != except
def isIdentOf(name: Name) = isIdent && in.name == name
- def isUnaryOp = isIdent && raw.isUnary(in.name)
- def isRawStar = isIdent && in.name == raw.STAR
- def isRawBar = isIdent && in.name == raw.BAR
+ def isUnaryOp = isIdent && raw.isUnary(in.name)
+ def isRawStar = isRawIdent && in.name == raw.STAR
+ def isRawBar = isRawIdent && in.name == raw.BAR
+ def isRawIdent = in.token == IDENTIFIER
def isIdent = in.token == IDENTIFIER || in.token == BACKQUOTED_IDENT
def isMacro = in.token == IDENTIFIER && in.name == nme.MACROkw
@@ -1001,19 +1002,30 @@ self =>
}
def infixTypeRest(t: Tree, mode: InfixMode.Value): Tree = {
- if (isIdent && in.name != nme.STAR) {
- val opOffset = in.offset
+ // Detect postfix star for repeated args.
+ // Only RPAREN can follow, but accept COMMA and EQUALS for error's sake.
+ // Take RBRACE as a paren typo.
+ def checkRepeatedParam = if (isRawStar) {
+ lookingAhead (in.token match {
+ case RPAREN | COMMA | EQUALS | RBRACE => t
+ case _ => EmptyTree
+ })
+ } else EmptyTree
+ def asInfix = {
+ val opOffset = in.offset
val leftAssoc = treeInfo.isLeftAssoc(in.name)
- if (mode != InfixMode.FirstOp) checkAssoc(opOffset, in.name, leftAssoc = mode == InfixMode.LeftOp)
- val op = identForType()
- val tycon = atPos(opOffset) { Ident(op) }
+ if (mode != InfixMode.FirstOp)
+ checkAssoc(opOffset, in.name, leftAssoc = mode == InfixMode.LeftOp)
+ val tycon = atPos(opOffset) { Ident(identForType()) }
newLineOptWhenFollowing(isTypeIntroToken)
def mkOp(t1: Tree) = atPos(t.pos.start, opOffset) { AppliedTypeTree(tycon, List(t, t1)) }
if (leftAssoc)
infixTypeRest(mkOp(compoundType()), InfixMode.LeftOp)
else
mkOp(infixType(InfixMode.RightOp))
- } else t
+ }
+ if (isIdent) checkRepeatedParam orElse asInfix
+ else t
}
/** {{{
@@ -3096,10 +3108,6 @@ self =>
stats ++= importClause()
acceptStatSepOpt()
}
- else if (isExprIntro) {
- stats += statement(InBlock)
- if (!isCaseDefEnd) acceptStatSep()
- }
else if (isDefIntro || isLocalModifier || isAnnotation) {
if (in.token == IMPLICIT) {
val start = in.skipToken()
@@ -3110,6 +3118,10 @@ self =>
}
acceptStatSepOpt()
}
+ else if (isExprIntro) {
+ stats += statement(InBlock)
+ if (!isCaseDefEnd) acceptStatSep()
+ }
else if (isStatSep) {
in.nextToken()
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index 359e5d6c29..f800dbf9cd 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -239,6 +239,13 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
}
/*
+ * must-single-thread
+ */
+ def serialVUID(csym: Symbol): Option[Long] = csym getAnnotation definitions.SerialVersionUIDAttr collect {
+ case AnnotationInfo(_, _, (_, LiteralAnnotArg(const)) :: Nil) => const.longValue
+ }
+
+ /*
* Populates the InnerClasses JVM attribute with `refedInnerClasses`.
* In addition to inner classes mentioned somewhere in `jclass` (where `jclass` is a class file being emitted)
* `refedInnerClasses` should contain those inner classes defined as direct member classes of `jclass`
@@ -881,13 +888,6 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
val MIN_SWITCH_DENSITY = 0.7
/*
- * must-single-thread
- */
- def serialVUID(csym: Symbol): Option[Long] = csym getAnnotation definitions.SerialVersionUIDAttr collect {
- case AnnotationInfo(_, Literal(const) :: _, _) => const.longValue
- }
-
- /*
* Add public static final field serialVersionUID with value `id`
*
* can-multi-thread
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index a389816caf..b7f9b30e19 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -1142,9 +1142,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
def isParcelableClass = isAndroidParcelableClass(clasz.symbol)
- def serialVUID: Option[Long] = clasz.symbol getAnnotation SerialVersionUIDAttr collect {
- case AnnotationInfo(_, Literal(const) :: _, _) => const.longValue
- }
+ def serialVUID: Option[Long] = genBCode.serialVUID(clasz.symbol)
private def getSuperInterfaces(c: IClass): Array[String] = {
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index bd2f6f0018..e036035397 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -600,7 +600,7 @@ abstract class Erasure extends AddInterfaces
if (tree.symbol == NoSymbol) {
tree
} else if (name == nme.CONSTRUCTOR) {
- if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.info.decl(nme.CONSTRUCTOR)
+ if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.primaryConstructor
tree
} else if (tree.symbol == Any_asInstanceOf)
adaptMember(atPos(tree.pos)(Select(qual, Object_asInstanceOf)))
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 8a7d30235f..d77c6b54a9 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -221,7 +221,9 @@ abstract class UnCurry extends InfoTransform
def mkMethod(owner: Symbol, name: TermName, additionalFlags: FlagSet = NoFlags): DefDef =
gen.mkMethodFromFunction(localTyper)(fun, owner, name, additionalFlags)
- if (inlineFunctionExpansion) {
+ val canUseDelamdafyMethod = (inConstructorFlag == 0) // Avoiding synthesizing code prone to SI-6666, SI-8363 by using old-style lambda translation
+
+ if (inlineFunctionExpansion || !canUseDelamdafyMethod) {
val parents = addSerializable(abstractFunctionForFunctionType(fun.tpe))
val anonClass = fun.symbol.owner newAnonymousFunctionClass(fun.pos, inConstructorFlag) addAnnotation SerialVersionUIDAnnotation
anonClass setInfo ClassInfoType(parents, newScope, anonClass)
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
index e0bc478fad..fde0aca584 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
@@ -86,7 +86,7 @@ trait Logic extends Debugging {
def mayBeNull: Boolean
// compute the domain and return it (call registerNull first!)
- def domainSyms: Option[Set[Sym]]
+ def domainSyms: Option[mutable.LinkedHashSet[Sym]]
// the symbol for this variable being equal to its statically known type
// (only available if registerEquality has been called for that type before)
@@ -162,11 +162,18 @@ trait Logic extends Debugging {
// to govern how much time we spend analyzing matches for unreachability/exhaustivity
object AnalysisBudget {
- private val budgetProp = scala.sys.Prop[Int]("scalac.patmat.analysisBudget")
+ private val budgetProp = scala.sys.Prop[String]("scalac.patmat.analysisBudget")
private val budgetOff = "off"
val max: Int = {
val DefaultBudget = 256
- budgetProp.option.getOrElse(if (budgetProp.get.equalsIgnoreCase("off")) Integer.MAX_VALUE else DefaultBudget)
+ budgetProp.option match {
+ case Some(`budgetOff`) =>
+ Integer.MAX_VALUE
+ case Some(x) =>
+ x.toInt
+ case None =>
+ DefaultBudget
+ }
}
abstract class Exception(val advice: String) extends RuntimeException("CNF budget exceeded")
@@ -197,7 +204,7 @@ trait Logic extends Debugging {
def removeVarEq(props: List[Prop], modelNull: Boolean = false): (Formula, List[Formula]) = {
val start = if (Statistics.canEnable) Statistics.startTimer(patmatAnaVarEq) else null
- val vars = new scala.collection.mutable.HashSet[Var]
+ val vars = mutable.LinkedHashSet[Var]()
object gatherEqualities extends PropTraverser {
override def apply(p: Prop) = p match {
@@ -334,9 +341,9 @@ trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis {
// we enumerate the subtypes of the full type, as that allows us to filter out more types statically,
// once we go to run-time checks (on Const's), convert them to checkable types
// TODO: there seems to be bug for singleton domains (variable does not show up in model)
- lazy val domain: Option[Set[Const]] = {
- val subConsts = enumerateSubtypes(staticTp).map{ tps =>
- tps.toSet[Type].map{ tp =>
+ lazy val domain: Option[mutable.LinkedHashSet[Const]] = {
+ val subConsts: Option[mutable.LinkedHashSet[Const]] = enumerateSubtypes(staticTp).map { tps =>
+ mutable.LinkedHashSet(tps: _*).map{ tp =>
val domainC = TypeConst(tp)
registerEquality(domainC)
domainC
@@ -479,7 +486,7 @@ trait ScalaLogic extends Interface with Logic with TreeAndTypeAnalysis {
}
// accessing after calling registerNull will result in inconsistencies
- lazy val domainSyms: Option[Set[Sym]] = domain map { _ map symForEqualsTo }
+ lazy val domainSyms: Option[collection.mutable.LinkedHashSet[Sym]] = domain map { _ map symForEqualsTo }
lazy val symForStaticTp: Option[Sym] = symForEqualsTo.get(TypeConst(staticTpCheckable))
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
index 699e98f963..4cf8980689 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
@@ -81,14 +81,14 @@ trait MatchTranslation {
object SymbolAndTypeBound {
def unapply(tree: Tree): Option[(Symbol, Type)] = tree match {
- case SymbolBound(sym, SymbolAndTypeBound(_, tpe)) => Some(sym -> tpe)
- case TypeBound(tpe) => Some(binder -> tpe)
- case _ => None
+ case SymbolBound(sym, TypeBound(tpe)) => Some(sym -> tpe)
+ case TypeBound(tpe) => Some(binder -> tpe)
+ case _ => None
}
}
object TypeBound {
- def unapply(tree: Tree): Option[Type] = unbind(tree) match {
+ def unapply(tree: Tree): Option[Type] = tree match {
case Typed(Ident(_), _) if tree.tpe != null => Some(tree.tpe)
case _ => None
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 2043eb5d5d..9715fdaf00 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -359,6 +359,14 @@ trait ContextErrors {
//setError(sel)
}
+ def SelectWithUnderlyingError(sel: Tree, err: AbsTypeError) = {
+ // if there's no position, this is likely the result of a MissingRequirementError
+ // use the position of the selection we failed to type check to report the original message
+ if (err.errPos == NoPosition) issueNormalTypeError(sel, err.errMsg)
+ else issueTypeError(err)
+ setError(sel)
+ }
+
//typedNew
def IsAbstractError(tree: Tree, sym: Symbol) = {
issueNormalTypeError(tree, sym + " is abstract; cannot be instantiated")
@@ -725,11 +733,18 @@ trait ContextErrors {
NormalTypeError(expandee, "too many argument lists for " + fun)
}
- def MacroIncompatibleEngineError(macroEngine: String) = {
- val message = s"macro cannot be expanded, because it was compiled by an incompatible macro engine $macroEngine"
+ private def MacroIncompatibleEngineError(friendlyMessage: String, internalMessage: String) = {
+ def debugDiagnostic = s"(internal diagnostic: $internalMessage)"
+ val message = if (macroDebugLite || macroDebugVerbose) s"$friendlyMessage $debugDiagnostic" else friendlyMessage
issueNormalTypeError(lastTreeToTyper, message)
}
+ def MacroCantExpand210xMacrosError(internalMessage: String) =
+ MacroIncompatibleEngineError("can't expand macros compiled by previous versions of Scala", internalMessage)
+
+ def MacroCantExpandIncompatibleMacrosError(internalMessage: String) =
+ MacroIncompatibleEngineError("macro cannot be expanded, because it was compiled by an incompatible macro engine", internalMessage)
+
case object MacroExpansionException extends Exception with scala.util.control.ControlThrowable
protected def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 98ee4ad94d..8e1ceffecd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -103,7 +103,7 @@ trait Contexts { self: Analyzer =>
// there must be a scala.xml package when xml literals were parsed in this unit
if (unit.hasXml && ScalaXmlPackage == NoSymbol)
- unit.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see https://github.com/scala/scala/wiki/Scala-2.11#xml.")
+ unit.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see http://docs.scala-lang.org/overviews/core/scala-2.11.html#scala-xml.")
// scala-xml needs `scala.xml.TopScope` to be in scope globally as `$scope`
// We detect `scala-xml` by looking for `scala.xml.TopScope` and
@@ -433,8 +433,10 @@ trait Contexts { self: Analyzer =>
case _ => false
}
val isImport = tree match {
- case _: Import => true
- case _ => false
+ // The guard is for SI-8403. It prevents adding imports again in the context created by
+ // `Namer#createInnerNamer`
+ case _: Import if tree != this.tree => true
+ case _ => false
}
val sameOwner = owner == this.owner
val prefixInChild =
@@ -542,6 +544,8 @@ trait Contexts { self: Analyzer =>
if (checking) onTreeCheckerError(pos, msg) else unit.error(pos, msg)
@inline private def issueCommon(err: AbsTypeError)(pf: PartialFunction[AbsTypeError, Unit]) {
+ // TODO: are errors allowed to have pos == NoPosition??
+ // if not, Jason suggests doing: val pos = err.errPos.orElse( { devWarning("Que?"); context.tree.pos })
if (settings.Yissuedebug) {
log("issue error: " + err.errMsg)
(new Exception).printStackTrace()
@@ -652,6 +656,13 @@ trait Contexts { self: Analyzer =>
c
}
+ def enclosingNonImportContext: Context = {
+ var c = this
+ while (c != NoContext && c.tree.isInstanceOf[Import])
+ c = c.outer
+ c
+ }
+
/** Is `sym` accessible as a member of `pre` in current context? */
def isAccessible(sym: Symbol, pre: Type, superAccess: Boolean = false): Boolean = {
lastAccessCheckDetails = ""
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index c8ac3622e2..d87090fa46 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -82,7 +82,7 @@ trait Implicits {
// `implicitSearchContext.undetparams`, *not* in `context.undetparams`
// Here, we copy them up to parent context (analogously to the way the errors are copied above),
// and then filter out any which *were* inferred and are part of the substitutor in the implicit search result.
- context.undetparams = ((context.undetparams ++ implicitSearchContext.undetparams) filterNot result.subst.from.contains).distinct
+ context.undetparams = ((context.undetparams ++ result.undetparams) filterNot result.subst.from.contains).distinct
if (Statistics.canEnable) Statistics.stopTimer(implicitNanos, start)
if (Statistics.canEnable) Statistics.stopCounter(rawTypeImpl, rawTypeStart)
@@ -162,8 +162,9 @@ trait Implicits {
* @param tree The tree representing the implicit
* @param subst A substituter that represents the undetermined type parameters
* that were instantiated by the winning implicit.
+ * @param undetparams undeterminted type parameters
*/
- class SearchResult(val tree: Tree, val subst: TreeTypeSubstituter) {
+ class SearchResult(val tree: Tree, val subst: TreeTypeSubstituter, val undetparams: List[Symbol]) {
override def toString = "SearchResult(%s, %s)".format(tree,
if (subst.isEmpty) "" else subst)
@@ -173,16 +174,16 @@ trait Implicits {
final def isSuccess = !isFailure
}
- lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
}
- lazy val DivergentSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val DivergentSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
override def isDivergent = true
}
- lazy val AmbiguousSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ lazy val AmbiguousSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter, Nil) {
override def isFailure = true
override def isAmbiguousFailure = true
}
@@ -719,7 +720,7 @@ trait Implicits {
case Some(err) =>
fail("typing TypeApply reported errors for the implicit tree: " + err.errMsg)
case None =>
- val result = new SearchResult(unsuppressMacroExpansion(itree3), subst)
+ val result = new SearchResult(unsuppressMacroExpansion(itree3), subst, context.undetparams)
if (Statistics.canEnable) Statistics.incCounter(foundImplicits)
typingLog("success", s"inferred value of type $ptInstantiated is $result")
result
@@ -832,19 +833,41 @@ trait Implicits {
* so that if there is a best candidate it can still be selected.
*/
object DivergentImplicitRecovery {
- // symbol of the implicit that caused the divergence.
- // Initially null, will be saved on first diverging expansion.
- private var implicitSym: Symbol = _
- private var countdown: Int = 1
-
- def sym: Symbol = implicitSym
- def apply(search: SearchResult, i: ImplicitInfo): SearchResult =
- if (search.isDivergent && countdown > 0) {
- countdown -= 1
- implicitSym = i.sym
- log(s"discarding divergent implicit $implicitSym during implicit search")
+ private var divergentError: Option[DivergentImplicitTypeError] = None
+
+ private def saveDivergent(err: DivergentImplicitTypeError) {
+ if (divergentError.isEmpty) divergentError = Some(err)
+ }
+
+ def issueSavedDivergentError() {
+ divergentError foreach (err => context.issue(err))
+ }
+
+ def apply(search: SearchResult, i: ImplicitInfo, errors: Seq[AbsTypeError]): SearchResult = {
+ // A divergent error from a nested implicit search will be found in `errors`. Stash that
+ // aside to be re-issued if this implicit search fails.
+ errors.collectFirst { case err: DivergentImplicitTypeError => err } foreach saveDivergent
+
+ if (search.isDivergent && divergentError.isEmpty) {
+ // Divergence triggered by `i` at this level of the implicit serach. We haven't
+ // seen divergence so far, we won't issue this error just yet, and instead temporarily
+ // treat `i` as a failed candidate.
+ saveDivergent(DivergentImplicitTypeError(tree, pt, i.sym))
+ log(s"discarding divergent implicit ${i.sym} during implicit search")
SearchFailure
- } else search
+ } else {
+ if (search.isFailure) {
+ // We don't want errors that occur during checking implicit info
+ // to influence the check of further infos, but we should retain divergent implicit errors
+ // (except for the one we already squirreled away)
+ val saved = divergentError.getOrElse(null)
+ context.reportBuffer.retainErrors {
+ case err: DivergentImplicitTypeError => err ne saved
+ }
+ }
+ search
+ }
+ }
}
/** Sorted list of eligible implicits.
@@ -868,31 +891,33 @@ trait Implicits {
* - if it matches, forget about all others it improves upon
*/
@tailrec private def rankImplicits(pending: Infos, acc: Infos): Infos = pending match {
- case Nil => acc
- case i :: is =>
- DivergentImplicitRecovery(typedImplicit(i, ptChecked = true, isLocalToCallsite), i) match {
- case sr if sr.isDivergent =>
- Nil
- case sr if sr.isFailure =>
- // We don't want errors that occur during checking implicit info
- // to influence the check of further infos.
- context.reportBuffer.retainErrors {
- case err: DivergentImplicitTypeError => true
+ case Nil => acc
+ case firstPending :: otherPending =>
+ def firstPendingImproves(alt: ImplicitInfo) =
+ firstPending == alt || (
+ try improves(firstPending, alt)
+ catch {
+ case e: CyclicReference =>
+ debugwarn(s"Discarding $firstPending during implicit search due to cyclic reference.")
+ true
}
- rankImplicits(is, acc)
- case newBest =>
- best = newBest
- val newPending = undoLog undo {
- is filterNot (alt => alt == i || {
- try improves(i, alt)
- catch {
- case e: CyclicReference =>
- debugwarn(s"Discarding $i during implicit search due to cyclic reference")
- true
- }
- })
+ )
+
+ val typedFirstPending = typedImplicit(firstPending, ptChecked = true, isLocalToCallsite)
+
+ // Pass the errors to `DivergentImplicitRecovery` so that it can note
+ // the first `DivergentImplicitTypeError` that is being propagated
+ // from a nested implicit search; this one will be
+ // re-issued if this level of the search fails.
+ DivergentImplicitRecovery(typedFirstPending, firstPending, context.errors) match {
+ case sr if sr.isDivergent => Nil
+ case sr if sr.isFailure => rankImplicits(otherPending, acc)
+ case newBest =>
+ best = newBest // firstPending is our new best, since we already pruned last time around:
+ val pendingImprovingBest = undoLog undo {
+ otherPending filterNot firstPendingImproves
}
- rankImplicits(newPending, i :: acc)
+ rankImplicits(pendingImprovingBest, firstPending :: acc)
}
}
@@ -920,12 +945,9 @@ trait Implicits {
}
if (best.isFailure) {
- /* If there is no winner, and we witnessed and caught divergence,
- * now we can throw it for the error message.
- */
- if (DivergentImplicitRecovery.sym != null) {
- DivergingImplicitExpansionError(tree, pt, DivergentImplicitRecovery.sym)(context)
- }
+ // If there is no winner, and we witnessed and recorded a divergence error,
+ // our recovery attempt has failed, so we must now issue it.
+ DivergentImplicitRecovery.issueSavedDivergentError()
if (invalidImplicits.nonEmpty)
setAddendum(pos, () =>
@@ -1126,7 +1148,7 @@ trait Implicits {
val tree1 = typedPos(pos.focus)(arg)
context.firstError match {
case Some(err) => processMacroExpansionError(err.errPos, err.errMsg)
- case None => new SearchResult(tree1, EmptyTreeTypeSubstituter)
+ case None => new SearchResult(tree1, EmptyTreeTypeSubstituter, Nil)
}
} catch {
case ex: TypeError =>
@@ -1196,7 +1218,7 @@ trait Implicits {
def findSubManifest(tp: Type) = findManifest(tp, if (full) FullManifestClass else OptManifestClass)
def mot(tp0: Type, from: List[Symbol], to: List[Type]): SearchResult = {
implicit def wrapResult(tree: Tree): SearchResult =
- if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to))
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to), Nil)
val tp1 = tp0.dealias
tp1 match {
@@ -1284,7 +1306,7 @@ trait Implicits {
}
def wrapResult(tree: Tree): SearchResult =
- if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter)
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter, Nil)
/** Materializes implicits of predefined types (currently, manifests and tags).
* Will be replaced by implicit macros once we fix them.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index b42113c84f..fc0e2c7c80 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -578,13 +578,21 @@ trait Infer extends Checkable {
*/
private[typechecker] def isApplicableBasedOnArity(tpe: Type, argsCount: Int, varargsStar: Boolean, tuplingAllowed: Boolean): Boolean = followApply(tpe) match {
case OverloadedType(pre, alts) =>
+ // followApply may return an OverloadedType (tpe is a value type with multiple `apply` methods)
alts exists (alt => isApplicableBasedOnArity(pre memberType alt, argsCount, varargsStar, tuplingAllowed))
case _ =>
val paramsCount = tpe.params.length
+ // simpleMatch implies we're not using defaults
val simpleMatch = paramsCount == argsCount
val varargsTarget = isVarArgsList(tpe.params)
+
+ // varargsMatch implies we're not using defaults, as varargs and defaults are mutually exclusive
def varargsMatch = varargsTarget && (paramsCount - 1) <= argsCount
+ // another reason why auto-tupling is a bad idea: it can hide the use of defaults, so must rule those out explicitly
def tuplingMatch = tuplingAllowed && eligibleForTupleConversion(paramsCount, argsCount, varargsTarget)
+ // varargs and defaults are mutually exclusive, so not using defaults if `varargsTarget`
+ // we're not using defaults if there are (at least as many) arguments as parameters (not using exact match to allow for tupling)
+ def notUsingDefaults = varargsTarget || paramsCount <= argsCount
// A varargs star call, e.g. (x, y:_*) can only match a varargs method
// with the same number of parameters. See SI-5859 for an example of what
@@ -592,7 +600,7 @@ trait Infer extends Checkable {
if (varargsStar)
varargsTarget && simpleMatch
else
- simpleMatch || varargsMatch || tuplingMatch
+ simpleMatch || varargsMatch || (tuplingMatch && notUsingDefaults)
}
private[typechecker] def followApply(tp: Type): Type = tp match {
@@ -633,7 +641,7 @@ trait Infer extends Checkable {
if (pos == -1) {
if (positionalAllowed) { // treat assignment as positional argument
argPos(index) = index
- res = UnitTpe
+ res = UnitTpe // TODO: this is a bit optimistic, the name may not refer to a mutable variable...
} else // unknown parameter name
namesOK = false
} else if (argPos.contains(pos)) { // parameter specified twice
@@ -1316,21 +1324,33 @@ trait Infer extends Checkable {
* @param varargsStar true if the call site has a `: _*` attached to the last argument
*/
private def overloadsToConsiderBySpecificity(eligible: List[Symbol], argtpes: List[Type], varargsStar: Boolean): List[Symbol] = {
+ // TODO spec: this namesMatch business is not spec'ed, and is the wrong fix for SI-4592
+ // we should instead clarify what the spec means by "typing each argument with an undefined expected type".
+ // What does typing a named argument entail when we don't know what the valid parameter names are?
+ // (Since we're doing overload resolution, there are multiple alternatives that can define different names.)
+ // Luckily, the next step checks applicability to the individual alternatives, so it knows whether an assignment is:
+ // 1) a valid named argument
+ // 2) a well-typed assignment
+ // 3) an error (e.g., rhs does not refer to a variable)
+ //
+ // For now, the logic is:
// If there are any foo=bar style arguments, and any of the overloaded
- // methods has a parameter named `foo`, then only those methods are considered.
- val namesMatch = namesOfNamedArguments(argtpes) match {
+ // methods has a parameter named `foo`, then only those methods are considered when we must disambiguate.
+ def namesMatch = namesOfNamedArguments(argtpes) match {
case Nil => Nil
case names => eligible filter (m => names forall (name => m.info.params exists (p => paramMatchesName(p, name))))
}
- if (namesMatch.nonEmpty)
- namesMatch
- else if (eligible.isEmpty || eligible.tail.isEmpty)
- eligible
+ if (eligible.isEmpty || eligible.tail.isEmpty) eligible
else
- eligible filter (alt =>
- !alt.info.params.exists(_.hasDefault) // run/t8197b first parameter list only!
- && isApplicableBasedOnArity(alt.tpe, argtpes.length, varargsStar, tuplingAllowed = true)
- )
+ namesMatch match {
+ case namesMatch if namesMatch.nonEmpty => namesMatch // TODO: this has no basis in the spec, remove!
+ case _ =>
+ // If there are multiple applicable alternatives, drop those using default arguments.
+ // This is done indirectly by checking applicability based on arity in `isApplicableBasedOnArity`.
+ // If defaults are required in the application, the arities won't match up exactly.
+ // TODO: should we really allow tupling here?? (If we don't, this is the only call-site with `tuplingAllowed = true`)
+ eligible filter (alt => isApplicableBasedOnArity(alt.tpe, argtpes.length, varargsStar, tuplingAllowed = true))
+ }
}
/** Assign `tree` the type of an alternative which is applicable
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 677c94e063..9cf92ca5b9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -224,7 +224,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
val Apply(_, pickledPayload) = wrapped
val payload = pickledPayload.map{ case Assign(k, v) => (unpickleAtom(k), unpickleAtom(v)) }.toMap
- def fail(msg: String) = abort(s"bad macro impl binding: $msg")
+ import typer.TyperErrorGen._
+ def fail(msg: String) = MacroCantExpandIncompatibleMacrosError(msg)
def unpickle[T](field: String, clazz: Class[T]): T = {
def failField(msg: String) = fail(s"$field $msg")
if (!payload.contains(field)) failField("is supposed to be there")
@@ -236,8 +237,9 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
raw.asInstanceOf[T]
}
+ if (!payload.contains("macroEngine")) MacroCantExpand210xMacrosError("macroEngine field not found")
val macroEngine = unpickle("macroEngine", classOf[String])
- if (self.macroEngine != macroEngine) typer.TyperErrorGen.MacroIncompatibleEngineError(macroEngine)
+ if (self.macroEngine != macroEngine) MacroCantExpandIncompatibleMacrosError(s"expected = ${self.macroEngine}, actual = $macroEngine")
val isBundle = unpickle("isBundle", classOf[Boolean])
val isBlackbox = unpickle("isBlackbox", classOf[Boolean])
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index b166bf988d..4540017b62 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -132,7 +132,16 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
defaultMethodNames.toList.distinct foreach { name =>
val methods = clazz.info.findMember(name, 0L, requiredFlags = METHOD, stableOnly = false).alternatives
- val haveDefaults = methods filter (sym => mexists(sym.info.paramss)(_.hasDefault) && !nme.isProtectedAccessorName(sym.name))
+ def hasDefaultParam(tpe: Type): Boolean = tpe match {
+ case MethodType(params, restpe) => (params exists (_.hasDefault)) || hasDefaultParam(restpe)
+ case _ => false
+ }
+ val haveDefaults = methods filter (
+ if (settings.isScala211)
+ (sym => mexists(sym.info.paramss)(_.hasDefault) && !nme.isProtectedAccessorName(sym.name))
+ else
+ (sym => hasDefaultParam(sym.info) && !nme.isProtectedAccessorName(sym.name))
+ )
if (haveDefaults.lengthCompare(1) > 0) {
val owners = haveDefaults map (_.owner)
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 87da565142..9b9e641cad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -346,12 +346,14 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
* performance hit for the compiler as a whole.
*/
override def atOwner[A](tree: Tree, owner: Symbol)(trans: => A): A = {
+ val savedValid = validCurrentOwner
if (owner.isClass) validCurrentOwner = true
val savedLocalTyper = localTyper
localTyper = localTyper.atOwner(tree, if (owner.isModule) owner.moduleClass else owner)
typers = typers updated (owner, localTyper)
val result = super.atOwner(tree, owner)(trans)
localTyper = savedLocalTyper
+ validCurrentOwner = savedValid
typers -= owner
result
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 14aa25eeb8..bf98c0e3dc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -197,7 +197,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
!from.isError
&& !to.isError
&& context.implicitsEnabled
- && (inferView(EmptyTree, from, to, reportAmbiguous = false) != EmptyTree)
+ && (inferView(context.tree, from, to, reportAmbiguous = false, saveErrors = true) != EmptyTree)
+ // SI-8230 / SI-8463 We'd like to change this to `saveErrors = false`, but can't.
+ // For now, we can at least pass in `context.tree` rather then `EmptyTree` so as
+ // to avoid unpositioned type errors.
)
def inferView(tree: Tree, from: Type, to: Type, reportAmbiguous: Boolean): Tree =
@@ -1041,11 +1044,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (tree.tpe <:< AnyTpe) pt.dealias match {
case TypeRef(_, UnitClass, _) => // (12)
if (settings.warnValueDiscard)
- context.unit.warning(tree.pos, "discarded non-Unit value")
+ context.warning(tree.pos, "discarded non-Unit value")
return typedPos(tree.pos, mode, pt)(Block(List(tree), Literal(Constant(()))))
case TypeRef(_, sym, _) if isNumericValueClass(sym) && isNumericSubType(tree.tpe, pt) =>
if (settings.warnNumericWiden)
- context.unit.warning(tree.pos, "implicit numeric widening")
+ context.warning(tree.pos, "implicit numeric widening")
return typedPos(tree.pos, mode, pt)(Select(tree, "to" + sym.name))
case _ =>
}
@@ -2479,7 +2482,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
* an alternative TODO: add partial function AST node or equivalent and get rid of this synthesis --> do everything in uncurry (or later)
* however, note that pattern matching codegen is designed to run *before* uncurry
*/
- def synthesizePartialFunction(paramName: TermName, paramPos: Position, tree: Tree, mode: Mode, pt: Type): Tree = {
+ def synthesizePartialFunction(paramName: TermName, paramPos: Position, paramSynthetic: Boolean,
+ tree: Tree, mode: Mode, pt: Type): Tree = {
assert(pt.typeSymbol == PartialFunctionClass, s"PartialFunction synthesis for match in $tree requires PartialFunction expected type, but got $pt.")
val targs = pt.dealiasWiden.typeArgs
@@ -2507,7 +2511,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val casesTrue = cases map (c => deriveCaseDef(c)(x => atPos(x.pos.focus)(TRUE)).duplicate.asInstanceOf[CaseDef])
// must generate a new tree every time
- def selector: Tree = gen.mkUnchecked(
+ def selector(paramSym: Symbol): Tree = gen.mkUnchecked(
if (sel != EmptyTree) sel.duplicate
else atPos(tree.pos.focusStart)(
// SI-6925: subsume type of the selector to `argTp`
@@ -2518,7 +2522,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// hence the cast, which will be erased in posterasure
// (the cast originally caused extremely weird types to show up
// in test/scaladoc/run/SI-5933.scala because `variantToSkolem` was missing `tpSym.initialize`)
- gen.mkCastPreservingAnnotations(Ident(paramName), argTp)
+ gen.mkCastPreservingAnnotations(Ident(paramSym), argTp)
))
def mkParam(methodSym: Symbol, tp: Type = argTp) =
@@ -2546,14 +2550,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
methodSym setInfo polyType(List(A1, B1), MethodType(paramSyms, B1.tpe))
val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym))
- // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
- paramSyms foreach (methodBodyTyper.context.scope enter _)
+ if (!paramSynthetic) methodBodyTyper.context.scope enter x
// First, type without the default case; only the cases provided
// by the user are typed. The LUB of these becomes `B`, the lower
// bound of `B1`, which in turn is the result type of the default
// case
- val match0 = methodBodyTyper.typedMatch(selector, cases, mode, resTp)
+ val match0 = methodBodyTyper.typedMatch(selector(x), cases, mode, resTp)
val matchResTp = match0.tpe
B1 setInfo TypeBounds.lower(matchResTp) // patch info
@@ -2627,11 +2630,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val paramSym = mkParam(methodSym)
val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
- methodBodyTyper.context.scope enter paramSym
+ if (!paramSynthetic) methodBodyTyper.context.scope enter paramSym
methodSym setInfo MethodType(List(paramSym), BooleanTpe)
val defaultCase = mkDefaultCase(FALSE)
- val match_ = methodBodyTyper.typedMatch(selector, casesTrue :+ defaultCase, mode, BooleanTpe)
+ val match_ = methodBodyTyper.typedMatch(selector(paramSym), casesTrue :+ defaultCase, mode, BooleanTpe)
DefDef(methodSym, methodBodyTyper.virtualizedMatch(match_, mode, BooleanTpe))
}
@@ -2645,10 +2648,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
methodSym setInfo MethodType(List(paramSym), AnyTpe)
val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym))
- // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it)
- methodBodyTyper.context.scope enter paramSym
+ if (!paramSynthetic) methodBodyTyper.context.scope enter paramSym
- val match_ = methodBodyTyper.typedMatch(selector, cases, mode, resTp)
+ val match_ = methodBodyTyper.typedMatch(selector(paramSym), cases, mode, resTp)
val matchResTp = match_.tpe
methodSym setInfo MethodType(List(paramSym), matchResTp) // patch info
@@ -2920,7 +2922,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val p = fun.vparams.head
if (p.tpt.tpe == null) p.tpt setType outerTyper.typedType(p.tpt).tpe
- outerTyper.synthesizePartialFunction(p.name, p.pos, fun.body, mode, pt)
+ outerTyper.synthesizePartialFunction(p.name, p.pos, paramSynthetic = false, fun.body, mode, pt)
// Use synthesizeSAMFunction to expand `(p1: T1, ..., pN: TN) => body`
// to an instance of the corresponding anonymous subclass of `pt`.
@@ -3214,10 +3216,23 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
args.map {
case arg @ AssignOrNamedArg(Ident(name), rhs) =>
// named args: only type the righthand sides ("unknown identifier" errors otherwise)
- val rhs1 = typedArg0(rhs)
// the assign is untyped; that's ok because we call doTypedApply
- val arg1 = treeCopy.AssignOrNamedArg(arg, arg.lhs, rhs1)
- (arg1, NamedType(name, rhs1.tpe.deconst))
+ val typedRhs = typedArg0(rhs)
+ val argWithTypedRhs = treeCopy.AssignOrNamedArg(arg, arg.lhs, typedRhs)
+
+ // TODO: SI-8197/SI-4592: check whether this named argument could be interpreted as an assign
+ // infer.checkNames must not use UnitType: it may not be a valid assignment, or the setter may return another type from Unit
+ //
+ // var typedAsAssign = true
+ // val argTyped = silent(_.typedArg(argWithTypedRhs, amode, BYVALmode, WildcardType)) orElse { errors =>
+ // typedAsAssign = false
+ // argWithTypedRhs
+ // }
+ //
+ // TODO: add an assignmentType field to NamedType, equal to:
+ // assignmentType = if (typedAsAssign) argTyped.tpe else NoType
+
+ (argWithTypedRhs, NamedType(name, typedRhs.tpe.deconst))
case arg @ treeInfo.WildcardStarArg(repeated) =>
val arg1 = typedArg0(arg)
(arg1, RepeatedType(arg1.tpe.deconst))
@@ -3933,7 +3948,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
* - simplest solution: have two method calls
*
*/
- def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = {
+ def mkInvoke(context: Context, tree: Tree, qual: Tree, name: Name): Option[Tree] = {
+ val cxTree = context.enclosingNonImportContext.tree // SI-8364
debuglog(s"dyna.mkInvoke($cxTree, $tree, $qual, $name)")
val treeInfo.Applied(treeSelection, _, _) = tree
def isDesugaredApply = {
@@ -4193,7 +4209,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val cases = tree.cases
if (selector == EmptyTree) {
if (pt.typeSymbol == PartialFunctionClass)
- synthesizePartialFunction(newTermName(context.unit.fresh.newName("x")), tree.pos, tree, mode, pt)
+ synthesizePartialFunction(newTermName(context.unit.fresh.newName("x")), tree.pos, paramSynthetic = true, tree, mode, pt)
else {
val arity = if (isFunctionType(pt)) pt.dealiasWiden.typeArgs.length - 1 else 1
val params = for (i <- List.range(0, arity)) yield
@@ -4595,7 +4611,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
t
}
def typedSelectInternal(tree: Tree, qual: Tree, name: Name): Tree = {
- def asDynamicCall = dyna.mkInvoke(context.tree, tree, qual, name) map { t =>
+ def asDynamicCall = dyna.mkInvoke(context, tree, qual, name) map { t =>
dyna.wrapErrors(t, (_.typed1(t, mode, pt)))
}
@@ -4656,8 +4672,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case SilentTypeError(err: AccessTypeError) =>
(tree1, Some(err))
case SilentTypeError(err) =>
- context issue err
- return setError(tree)
+ SelectWithUnderlyingError(tree, err)
+ return tree
case SilentResultValue(treeAndPre) =>
(stabilize(treeAndPre._1, treeAndPre._2, mode, pt), None)
}
@@ -5095,7 +5111,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def isPlausible(m: Symbol) = m.alternatives exists (m => requiresNoArgs(m.info))
def maybeWarn(s: String): Unit = {
- def warn(message: String) = context.unit.warning(lit.pos, s"$message Did you forget the interpolator?")
+ def warn(message: String) = context.warning(lit.pos, s"$message Did you forget the interpolator?")
def suspiciousSym(name: TermName) = context.lookupSymbol(name, _ => true).symbol
def suspiciousExpr = InterpolatorCodeRegex findFirstIn s
def suspiciousIdents = InterpolatorIdentRegex findAllIn s map (s => suspiciousSym(s drop 1))
diff --git a/src/compiler/scala/tools/reflect/FormatInterpolator.scala b/src/compiler/scala/tools/reflect/FormatInterpolator.scala
index 0258002850..e0f9bb6044 100644
--- a/src/compiler/scala/tools/reflect/FormatInterpolator.scala
+++ b/src/compiler/scala/tools/reflect/FormatInterpolator.scala
@@ -93,7 +93,8 @@ abstract class FormatInterpolator {
case '\n' => "\\n"
case '\f' => "\\f"
case '\r' => "\\r"
- case '\"' => "\\u0022" // $" in future
+ case '\"' => "${'\"'}" /* avoid lint warn */ +
+ " or a triple-quoted literal \"\"\"with embedded \" or \\u0022\"\"\"" // $" in future
case '\'' => "'"
case '\\' => """\\"""
case x => "\\u%04x" format x
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
index 8376fca4ad..68cc728eb3 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
@@ -43,13 +43,13 @@ trait Holes { self: Quasiquotes =>
tpe <:< NothingClass.tpe || tpe <:< NullClass.tpe
private def extractIterableTParam(tpe: Type) =
IterableTParam.asSeenFrom(tpe, IterableClass)
- private def stripIterable(tpe: Type, limit: Option[Rank] = None): (Rank, Type) =
- if (limit.map { _ == NoDot }.getOrElse { false }) (NoDot, tpe)
+ private def stripIterable(tpe: Type, limit: Rank = DotDotDot): (Rank, Type) =
+ if (limit == NoDot) (NoDot, tpe)
else if (tpe != null && !isIterableType(tpe)) (NoDot, tpe)
else if (isBottomType(tpe)) (NoDot, tpe)
else {
val targ = extractIterableTParam(tpe)
- val (rank, innerTpe) = stripIterable(targ, limit.map { _.pred })
+ val (rank, innerTpe) = stripIterable(targ, limit.pred)
(rank.succ, innerTpe)
}
private def iterableTypeFromRank(n: Rank, tpe: Type): Type = {
@@ -76,10 +76,12 @@ trait Holes { self: Quasiquotes =>
class ApplyHole(annotatedRank: Rank, unquotee: Tree) extends Hole {
val (strippedTpe, tpe): (Type, Type) = {
- val (strippedRank, strippedTpe) = stripIterable(unquotee.tpe, limit = Some(annotatedRank))
+ val (strippedRank, strippedTpe) = stripIterable(unquotee.tpe, limit = annotatedRank)
if (isBottomType(strippedTpe)) cantSplice()
- else if (isNativeType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, strippedTpe))
- else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, treeType))
+ else if (isNativeType(strippedTpe)) {
+ if (strippedRank != NoDot && !(strippedTpe <:< treeType) && !isLiftableType(strippedTpe)) cantSplice()
+ else (strippedTpe, iterableTypeFromRank(annotatedRank, strippedTpe))
+ } else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromRank(annotatedRank, treeType))
else cantSplice()
}
@@ -191,7 +193,7 @@ trait Holes { self: Quasiquotes =>
val (iterableRank, _) = stripIterable(tpe)
if (iterableRank.value < rank.value)
c.abort(pat.pos, s"Can't extract $tpe with $rank, consider using $iterableRank")
- val (_, strippedTpe) = stripIterable(tpe, limit = Some(rank))
+ val (_, strippedTpe) = stripIterable(tpe, limit = rank)
if (strippedTpe <:< treeType) treeNoUnlift
else
unlifters.spawn(strippedTpe, rank).map {
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
index 3b93a8933d..b68022afd9 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
@@ -22,7 +22,8 @@ trait Parsers { self: Quasiquotes =>
def parse(code: String): Tree = {
try {
val file = new BatchSourceFile(nme.QUASIQUOTE_FILE, code)
- new QuasiquoteParser(file).parseRule(entryPoint)
+ val parser = new QuasiquoteParser(file)
+ parser.checkNoEscapingPlaceholders { parser.parseRule(entryPoint) }
} catch {
case mi: MalformedInput => c.abort(correspondingPosition(mi.offset), mi.msg)
}
@@ -30,15 +31,15 @@ trait Parsers { self: Quasiquotes =>
def correspondingPosition(offset: Int): Position = {
val posMapList = posMap.toList
- def containsOffset(start: Int, end: Int) = start <= offset && offset <= end
+ def containsOffset(start: Int, end: Int) = start <= offset && offset < end
def fallbackPosition = posMapList match {
case (pos1, (start1, end1)) :: _ if start1 > offset => pos1
- case _ :+ ((pos2, (start2, end2))) if offset > end2 => pos2.withPoint(pos2.point + (end2 - start2))
+ case _ :+ ((pos2, (start2, end2))) if end2 <= offset => pos2.withPoint(pos2.point + (end2 - start2))
}
posMapList.sliding(2).collect {
- case (pos1, (start1, end1)) :: _ if containsOffset(start1, end1) => (pos1, offset - start1)
- case (pos1, (_, end1)) :: (_, (start2, _)) :: _ if containsOffset(end1, start2) => (pos1, end1)
- case _ :: (pos2, (start2, end2)) :: _ if containsOffset(start2, end2) => (pos2, offset - start2)
+ case (pos1, (start1, end1)) :: _ if containsOffset(start1, end1) => (pos1, offset - start1)
+ case (pos1, (start1, end1)) :: (pos2, (start2, _)) :: _ if containsOffset(end1, start2) => (pos1, end1 - start1)
+ case _ :: (pos2, (start2, end2)) :: _ if containsOffset(start2, end2) => (pos2, offset - start2)
}.map { case (pos, offset) =>
pos.withPoint(pos.point + offset)
}.toList.headOption.getOrElse(fallbackPosition)
@@ -118,6 +119,8 @@ trait Parsers { self: Quasiquotes =>
override def isTemplateIntro: Boolean = super.isTemplateIntro || (isHole && lookingAhead { isTemplateIntro })
+ override def isDefIntro: Boolean = super.isDefIntro || (isHole && lookingAhead { isDefIntro })
+
override def isDclIntro: Boolean = super.isDclIntro || (isHole && lookingAhead { isDclIntro })
override def isStatSep(token: Int) = token == EOF || super.isStatSep(token)
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
index 5986758c2b..b287971815 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
@@ -17,7 +17,7 @@ trait Placeholders { self: Quasiquotes =>
// Step 1: Transform Scala source with holes into vanilla Scala source
- lazy val posMap = mutable.ListMap[Position, (Int, Int)]()
+ lazy val posMap = mutable.LinkedHashMap[Position, (Int, Int)]()
lazy val code = {
val sb = new StringBuilder()
val sessionSuffix = randomUUID().toString.replace("-", "").substring(0, 8) + "$"
@@ -40,9 +40,7 @@ trait Placeholders { self: Quasiquotes =>
val iargs = method match {
case nme.apply => args
- case nme.unapply =>
- val (dummy @ Ident(nme.SELECTOR_DUMMY)) :: Nil = args
- internal.subpatterns(dummy).get
+ case nme.unapply => internal.subpatterns(args.head).get
case _ => global.abort("unreachable")
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala
index 396688c437..b33069181c 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Quasiquotes.scala
@@ -51,7 +51,7 @@ abstract class Quasiquotes extends Parsers
def sreified =
reified
.toString
- .replace("scala.reflect.runtime.`package`.universe.build.", "")
+ .replace("scala.reflect.runtime.`package`.universe.internal.reificationSupport.", "")
.replace("scala.reflect.runtime.`package`.universe.", "")
.replace("scala.collection.immutable.", "")
debug(s"reified tree:\n$sreified\n")
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 61fb22bc73..95113d5b00 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -131,6 +131,10 @@ trait Reifiers { self: Quasiquotes =>
case Placeholder(Hole(tree, NoDot)) if isReifyingPatterns => tree
case Placeholder(hole @ Hole(_, rank @ Dot())) => c.abort(hole.pos, s"Can't $action with $rank here")
case TuplePlaceholder(args) => reifyTuple(args)
+ // Due to greediness of syntactic applied we need to pre-emptively peek inside.
+ // `rest` will always be non-empty due to the rule on top of this one.
+ case SyntacticApplied(id @ Ident(nme.QUASIQUOTE_TUPLE), first :: rest) =>
+ mirrorBuildCall(nme.SyntacticApplied, reifyTreePlaceholder(Apply(id, first)), reify(rest))
case TupleTypePlaceholder(args) => reifyTupleType(args)
case FunctionTypePlaceholder(argtpes, restpe) => reifyFunctionType(argtpes, restpe)
case CasePlaceholder(hole) => hole.tree
@@ -151,21 +155,20 @@ trait Reifiers { self: Quasiquotes =>
mirrorCall(nme.This, tree)
case SyntacticTraitDef(mods, name, tparams, earlyDefs, parents, selfdef, body) =>
reifyBuildCall(nme.SyntacticTraitDef, mods, name, tparams, earlyDefs, parents, selfdef, body)
- case SyntacticClassDef(mods, name, tparams, constrmods, vparamss, earlyDefs, parents, selfdef, body) =>
- reifyBuildCall(nme.SyntacticClassDef, mods, name, tparams, constrmods, vparamss,
- earlyDefs, parents, selfdef, body)
+ case SyntacticClassDef(mods, name, tparams, constrmods, vparamss,
+ earlyDefs, parents, selfdef, body) =>
+ mirrorBuildCall(nme.SyntacticClassDef, reify(mods), reify(name), reify(tparams), reify(constrmods),
+ reifyVparamss(vparamss), reify(earlyDefs), reify(parents),
+ reify(selfdef), reify(body))
case SyntacticPackageObjectDef(name, earlyDefs, parents, selfdef, body) =>
reifyBuildCall(nme.SyntacticPackageObjectDef, name, earlyDefs, parents, selfdef, body)
case SyntacticObjectDef(mods, name, earlyDefs, parents, selfdef, body) =>
reifyBuildCall(nme.SyntacticObjectDef, mods, name, earlyDefs, parents, selfdef, body)
case SyntacticNew(earlyDefs, parents, selfdef, body) =>
reifyBuildCall(nme.SyntacticNew, earlyDefs, parents, selfdef, body)
- case SyntacticDefDef(mods, name, tparams, build.ImplicitParams(vparamss, implparams), tpt, rhs) =>
- if (implparams.nonEmpty)
- mirrorBuildCall(nme.SyntacticDefDef, reify(mods), reify(name), reify(tparams),
- reifyBuildCall(nme.ImplicitParams, vparamss, implparams), reify(tpt), reify(rhs))
- else
- reifyBuildCall(nme.SyntacticDefDef, mods, name, tparams, vparamss, tpt, rhs)
+ case SyntacticDefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ mirrorBuildCall(nme.SyntacticDefDef, reify(mods), reify(name), reify(tparams),
+ reifyVparamss(vparamss), reify(tpt), reify(rhs))
case SyntacticValDef(mods, name, tpt, rhs) if tree != noSelfType =>
reifyBuildCall(nme.SyntacticValDef, mods, name, tpt, rhs)
case SyntacticVarDef(mods, name, tpt, rhs) =>
@@ -186,14 +189,32 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticApplied, fun, argss)
case SyntacticTypeApplied(fun, targs) if targs.nonEmpty =>
reifyBuildCall(nme.SyntacticTypeApplied, fun, targs)
+ case SyntacticAppliedType(tpt, targs) if targs.nonEmpty =>
+ reifyBuildCall(nme.SyntacticAppliedType, tpt, targs)
case SyntacticFunction(args, body) =>
reifyBuildCall(nme.SyntacticFunction, args, body)
- case SyntacticIdent(name, isBackquoted) =>
- reifyBuildCall(nme.SyntacticIdent, name, isBackquoted)
case SyntacticEmptyTypeTree() =>
reifyBuildCall(nme.SyntacticEmptyTypeTree)
case SyntacticImport(expr, selectors) =>
reifyBuildCall(nme.SyntacticImport, expr, selectors)
+ case SyntacticPartialFunction(cases) =>
+ reifyBuildCall(nme.SyntacticPartialFunction, cases)
+ case SyntacticMatch(scrutinee, cases) =>
+ reifyBuildCall(nme.SyntacticMatch, scrutinee, cases)
+ case SyntacticTermIdent(name, isBackquoted) =>
+ reifyBuildCall(nme.SyntacticTermIdent, name, isBackquoted)
+ case SyntacticTypeIdent(name) =>
+ reifyBuildCall(nme.SyntacticTypeIdent, name)
+ case SyntacticCompoundType(parents, defns) =>
+ reifyBuildCall(nme.SyntacticCompoundType, parents, defns)
+ case SyntacticSingletonType(ref) =>
+ reifyBuildCall(nme.SyntacticSingletonType, ref)
+ case SyntacticTypeProjection(qual, name) =>
+ reifyBuildCall(nme.SyntacticTypeProjection, qual, name)
+ case SyntacticAnnotatedType(tpt, annot) =>
+ reifyBuildCall(nme.SyntacticAnnotatedType, tpt, annot)
+ case SyntacticExistentialType(tpt, where) =>
+ reifyBuildCall(nme.SyntacticExistentialType, tpt, where)
case Q(tree) if fillListHole.isDefinedAt(tree) =>
mirrorBuildCall(nme.SyntacticBlock, fillListHole(tree))
case Q(other) =>
@@ -202,16 +223,21 @@ trait Reifiers { self: Quasiquotes =>
// not to cause infinite recursion.
case block @ SyntacticBlock(stats) if block.isInstanceOf[Block] =>
reifyBuildCall(nme.SyntacticBlock, stats)
+ case SyntheticUnit() =>
+ reifyBuildCall(nme.SyntacticBlock, Nil)
case Try(block, catches, finalizer) =>
reifyBuildCall(nme.SyntacticTry, block, catches, finalizer)
- case Match(selector, cases) =>
- reifyBuildCall(nme.SyntacticMatch, selector, cases)
+ case CaseDef(pat, guard, body) if fillListHole.isDefinedAt(body) =>
+ mirrorCall(nme.CaseDef, reify(pat), reify(guard), mirrorBuildCall(nme.SyntacticBlock, fillListHole(body)))
// parser emits trees with scala package symbol to ensure
// that some names hygienically point to various scala package
// members; we need to preserve this symbol to preserve
// correctness of the trees produced by quasiquotes
case Select(id @ Ident(nme.scala_), name) if id.symbol == ScalaPackage =>
reifyBuildCall(nme.ScalaDot, name)
+ case Select(qual, name) =>
+ val ctor = if (name.isTypeName) nme.SyntacticSelectType else nme.SyntacticSelectTerm
+ reifyBuildCall(ctor, qual, name)
case _ =>
super.reifyTreeSyntactically(tree)
}
@@ -266,6 +292,12 @@ trait Reifiers { self: Quasiquotes =>
def reifyPackageStat(hole: Hole) = reifyConstructionCheck(nme.mkPackageStat, hole)
+ def reifyVparamss(vparamss: List[List[ValDef]]) = {
+ val build.ImplicitParams(paramss, implparams) = vparamss
+ if (implparams.isEmpty) reify(paramss)
+ else reifyBuildCall(nme.ImplicitParams, paramss, implparams)
+ }
+
/** Splits list into a list of groups where subsequent elements are considered
* similar by the corresponding function.
*
diff --git a/src/intellij/README b/src/intellij/README
index ade87749cd..a39691f4f0 100644
--- a/src/intellij/README
+++ b/src/intellij/README
@@ -1,8 +1,12 @@
Use the latest IntelliJ IDEA release and install the Scala plugin from within the IDE.
+Compilation withing IDEA is performed in "-Dlocker.skip=1" mode: the sources are built
+directly using the STARR compiler.
+
The following steps are required to use IntelliJ IDEA on Scala trunk
- - 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 "ant init". This will download some JARs from 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
+ - File, Project Settings, Project, SDK. Create an SDK entry named "1.6" containing the
+ java 1.6 SDK
diff --git a/src/intellij/actors.iml.SAMPLE b/src/intellij/actors.iml.SAMPLE
index 896c4966ff..b15af8b110 100644
--- a/src/intellij/actors.iml.SAMPLE
+++ b/src/intellij/actors.iml.SAMPLE
@@ -4,7 +4,8 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
<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/compiler.iml.SAMPLE b/src/intellij/compiler.iml.SAMPLE
index 9fb9cd55eb..50253000ab 100644
--- a/src/intellij/compiler.iml.SAMPLE
+++ b/src/intellij/compiler.iml.SAMPLE
@@ -4,7 +4,8 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
<option name="maximumHeapSize" value="1536" />
<option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" />
</configuration>
@@ -19,8 +20,8 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="library" />
<orderEntry type="module" module-name="reflect" />
- <orderEntry type="module" module-name="asm" exported="" />
- <orderEntry type="library" exported="" name="ant" level="project" />
+ <orderEntry type="module" module-name="asm" />
+ <orderEntry type="library" name="ant" level="project" />
</component>
</module>
diff --git a/src/intellij/interactive.iml.SAMPLE b/src/intellij/interactive.iml.SAMPLE
index c6c8ebb606..83178021d3 100644
--- a/src/intellij/interactive.iml.SAMPLE
+++ b/src/intellij/interactive.iml.SAMPLE
@@ -4,7 +4,8 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
<option name="maximumHeapSize" value="1536" />
<option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" />
</configuration>
@@ -23,3 +24,4 @@
<orderEntry type="module" module-name="scaladoc" />
</component>
</module>
+
diff --git a/src/intellij/library.iml.SAMPLE b/src/intellij/library.iml.SAMPLE
index cac53dff15..137ce6eb9c 100644
--- a/src/intellij/library.iml.SAMPLE
+++ b/src/intellij/library.iml.SAMPLE
@@ -4,8 +4,9 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
- <option name="compilerOptions" value="-sourcepath $BASE_DIR$/src/library" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="compilerOptions" value="-sourcepath $MODULE_DIR$/../library" />
+ <option name="languageLevel" value="Scala 2.11" />
<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 3295a4a877..8babde73ea 100644
--- a/src/intellij/manual.iml.SAMPLE
+++ b/src/intellij/manual.iml.SAMPLE
@@ -4,7 +4,8 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
<option name="maximumHeapSize" value="1536" />
<option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" />
</configuration>
@@ -18,8 +19,8 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="library" />
- <orderEntry type="module" module-name="xml" />
<orderEntry type="library" name="ant" level="project" />
+ <orderEntry type="library" name="scaladoc-deps" level="project" />
</component>
</module>
diff --git a/src/intellij/partest-extras.iml.SAMPLE b/src/intellij/partest-extras.iml.SAMPLE
new file mode 100644
index 0000000000..c2ada43493
--- /dev/null
+++ b/src/intellij/partest-extras.iml.SAMPLE
@@ -0,0 +1,27 @@
+<?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="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
+ </configuration>
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../partest-extras">
+ <sourceFolder url="file://$MODULE_DIR$/../partest-extras" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="asm" />
+ <orderEntry type="module" module-name="library" />
+ <orderEntry type="module" module-name="reflect" />
+ <orderEntry type="module" module-name="compiler" />
+ <orderEntry type="module" module-name="repl" />
+ <orderEntry type="library" name="partest" level="project" />
+ </component>
+</module>
+
diff --git a/src/intellij/partest-javaagent.iml.SAMPLE b/src/intellij/partest-javaagent.iml.SAMPLE
new file mode 100644
index 0000000000..e47e0f6349
--- /dev/null
+++ b/src/intellij/partest-javaagent.iml.SAMPLE
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../partest-javaagent">
+ <sourceFolder url="file://$MODULE_DIR$/../partest-javaagent" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="asm" />
+ </component>
+</module>
+
diff --git a/src/intellij/reflect.iml.SAMPLE b/src/intellij/reflect.iml.SAMPLE
index 7d10522826..d206304896 100644
--- a/src/intellij/reflect.iml.SAMPLE
+++ b/src/intellij/reflect.iml.SAMPLE
@@ -4,8 +4,9 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
- <option name="compilerOptions" value="-sourcepath $BASE_DIR$/src/reflect" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="compilerOptions" value="-sourcepath $MODULE_DIR$/../reflect" />
+ <option name="languageLevel" value="Scala 2.11" />
<option name="maximumHeapSize" value="1536" />
<option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" />
</configuration>
@@ -19,7 +20,6 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="library" />
- <orderEntry type="library" name="jline" level="project" />
</component>
</module>
diff --git a/src/intellij/repl.iml.SAMPLE b/src/intellij/repl.iml.SAMPLE
index fc78ffe8c2..83791f4f6e 100644
--- a/src/intellij/repl.iml.SAMPLE
+++ b/src/intellij/repl.iml.SAMPLE
@@ -4,7 +4,8 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
<option name="maximumHeapSize" value="1536" />
<option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" />
</configuration>
@@ -23,3 +24,4 @@
<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 a0765b3e99..c0614c946c 100644
--- a/src/intellij/scala-lang.ipr.SAMPLE
+++ b/src/intellij/scala-lang.ipr.SAMPLE
@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
- <component name="AntConfiguration">
- <defaultAnt bundledAnt="true" />
- </component>
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions>
@@ -21,11 +18,13 @@
<entry name="?*.tld" />
<entry name="?*.ftl" />
</wildcardResourcePatterns>
- <annotationProcessing enabled="false" useClasspath="true" />
- </component>
- <component name="CopyrightManager" default="">
- <module2copyright />
+ <annotationProcessing>
+ <profile default="true" name="Default" enabled="false">
+ <processorPath useClasspath="true" />
+ </profile>
+ </annotationProcessing>
</component>
+ <component name="CopyrightManager" default="" />
<component name="DependencyValidationManager">
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</component>
@@ -41,11 +40,16 @@
<profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" />
<option name="myLocal" value="false" />
+ <inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
+ <option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
+ </inspection_tool>
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
+ <inspection_tool class="UnitMethodIsParameterless" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</profiles>
<option name="PROJECT_PROFILE" value="Project Default" />
@@ -53,7 +57,7 @@
<version value="1.0" />
</component>
<component name="JavacSettings">
- <option name="ADDITIONAL_OPTIONS_STRING" value="-source 1.5 -target 1.5" />
+ <option name="ADDITIONAL_OPTIONS_STRING" value="-source 1.6 -target 1.6" />
</component>
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" />
@@ -205,12 +209,15 @@
<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$/partest-extras.iml" filepath="$PROJECT_DIR$/partest-extras.iml" />
+ <module fileurl="file://$PROJECT_DIR$/partest-javaagent.iml" filepath="$PROJECT_DIR$/partest-javaagent.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" />
<module fileurl="file://$PROJECT_DIR$/scala.iml" filepath="$PROJECT_DIR$/scala.iml" />
<module fileurl="file://$PROJECT_DIR$/scaladoc.iml" filepath="$PROJECT_DIR$/scaladoc.iml" />
<module fileurl="file://$PROJECT_DIR$/scalap.iml" filepath="$PROJECT_DIR$/scalap.iml" />
<module fileurl="file://$PROJECT_DIR$/test.iml" filepath="$PROJECT_DIR$/test.iml" />
+ <module fileurl="file://$PROJECT_DIR$/test-junit.iml" filepath="$PROJECT_DIR$/test-junit.iml" />
</modules>
</component>
<component name="ProjectResources">
@@ -234,45 +241,46 @@
<JAVADOC />
<SOURCES />
</library>
- <library name="compiler-locker">
- <CLASSES>
- <root url="file://$PROJECT_DIR$/../../build/locker/classes/library" />
- <root url="file://$PROJECT_DIR$/../../build/locker/classes/compiler" />
- <root url="file://$PROJECT_DIR$/../../build/locker/classes/reflect" />
- <root url="file://$PROJECT_DIR$/../../build/asm/classes" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
<library name="junit">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../build/deps/junit" />
</CLASSES>
<JAVADOC />
- <SOURCES>
- <root url="file://$PROJECT_DIR$/../../build/deps/junit" />
- </SOURCES>
+ <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">
+ <library name="partest">
<CLASSES>
<root url="file://$PROJECT_DIR$/../../build/deps/partest" />
</CLASSES>
<JAVADOC />
- <SOURCES>
- <root url="file://$PROJECT_DIR$/../../build/deps/junit" />
- </SOURCES>
+ <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>
+ <CLASSES>
<root url="file://$PROJECT_DIR$/../../build/deps/repl" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
<jarDirectory url="file://$PROJECT_DIR$/../../build/deps/repl" recursive="false" />
- </library>
+ </library>
+ <library name="scaladoc-deps">
+ <CLASSES>
+ <root url="file://$PROJECT_DIR$/../../build/deps/scaladoc" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ <jarDirectory url="file://$PROJECT_DIR$/../../build/deps/scaladoc" recursive="false" />
+ </library>
+ <library name="starr">
+ <CLASSES>
+ <root url="file://$PROJECT_DIR$/../../build/deps/starr" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ <jarDirectory url="file://$PROJECT_DIR$/../../build/deps/starr" recursive="false" />
+ </library>
</component>
</project>
+
diff --git a/src/intellij/scaladoc.iml.SAMPLE b/src/intellij/scaladoc.iml.SAMPLE
index 07bea5bf5d..8f9a0d8344 100644
--- a/src/intellij/scaladoc.iml.SAMPLE
+++ b/src/intellij/scaladoc.iml.SAMPLE
@@ -4,7 +4,8 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
<option name="maximumHeapSize" value="1536" />
<option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" />
</configuration>
@@ -20,8 +21,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" />
+ <orderEntry type="library" name="partest" level="project" />
+ <orderEntry type="library" name="scaladoc-deps" level="project" />
</component>
</module>
+
diff --git a/src/intellij/scalap.iml.SAMPLE b/src/intellij/scalap.iml.SAMPLE
index 77eea7c38f..27ae451369 100644
--- a/src/intellij/scalap.iml.SAMPLE
+++ b/src/intellij/scalap.iml.SAMPLE
@@ -4,7 +4,8 @@
<facet type="scala" name="Scala">
<configuration>
<option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
+ <option name="compilerLibraryName" value="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
<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/setup.sh b/src/intellij/setup.sh
index bd324ba5bd..ec303778ed 100755
--- a/src/intellij/setup.sh
+++ b/src/intellij/setup.sh
@@ -5,19 +5,10 @@
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 -f *.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"
+for f in "$SCRIPT_DIR"/*.SAMPLE; do
+ g=${f%.SAMPLE}
+ cp $f $g
done
diff --git a/src/intellij/test-junit.iml.SAMPLE b/src/intellij/test-junit.iml.SAMPLE
new file mode 100644
index 0000000000..bb51c30a4f
--- /dev/null
+++ b/src/intellij/test-junit.iml.SAMPLE
@@ -0,0 +1,30 @@
+<?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="starr" />
+ </configuration>
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/../../test/junit">
+ <sourceFolder url="file://$MODULE_DIR$/../../test/junit" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="actors" />
+ <orderEntry type="module" module-name="asm" />
+ <orderEntry type="module" module-name="compiler" />
+ <orderEntry type="module" module-name="library" />
+ <orderEntry type="module" module-name="reflect" />
+ <orderEntry type="module" module-name="repl" />
+ <orderEntry type="module" module-name="partest-extras" />
+ <orderEntry type="module" module-name="forkjoin" />
+ <orderEntry type="library" name="junit" level="project" />
+ <orderEntry type="library" name="scaladoc-deps" level="project" />
+ </component>
+</module>
+
diff --git a/src/intellij/test.iml.SAMPLE b/src/intellij/test.iml.SAMPLE
index 423be2062c..cb4a8568a1 100644
--- a/src/intellij/test.iml.SAMPLE
+++ b/src/intellij/test.iml.SAMPLE
@@ -1,21 +1,31 @@
<?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="starr" />
+ <option name="languageLevel" value="Scala 2.11" />
+ </configuration>
+ </facet>
+ </component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
- <content url="file://$MODULE_DIR$/../../test" />
+ <content url="file://$MODULE_DIR$/../../test">
+ <excludeFolder url="file://$MODULE_DIR$/../../test/junit" />
+ </content>
<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="repl" />
<orderEntry type="module" module-name="actors" />
- <orderEntry type="module" module-name="swing" />
- <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" />
+ <orderEntry type="module" module-name="partest-extras" />
+ <orderEntry type="library" name="scaladoc-deps" level="project" />
+ <orderEntry type="library" name="partest" level="project" />
</component>
</module>
diff --git a/src/intellij/update.sh b/src/intellij/update.sh
new file mode 100755
index 0000000000..eb6fea782f
--- /dev/null
+++ b/src/intellij/update.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+#
+# Updates the .SAMPLE files with the current project files.
+#
+
+set -e
+export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
+
+echo "About to create overwrite the .ipr.SAMPLE and .iml.SAMPLE files with the current project files. Press enter to continue or CTRL-C to cancel."
+read
+
+for f in "$SCRIPT_DIR"/*.{iml,ipr}; do
+ cp $f $f.SAMPLE
+done
+
+for f in "$SCRIPT_DIR"/*.SAMPLE; do
+ g=${f%.SAMPLE}
+ if [[ ! -f $g ]]; then
+ echo "Stale sample file, deleting $f"
+ rm $f
+ fi
+done
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index 9ff648a05a..7f4a9dc45d 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -94,7 +94,7 @@ trait PartialFunction[-A, +B] extends (A => B) { self =>
* Note that expression `pf.applyOrElse(x, default)` is equivalent to
* {{{ if(pf isDefinedAt x) pf(x) else default(x) }}}
* except that `applyOrElse` method can be implemented more efficiently.
- * For all partial function literals compiler generates `applyOrElse` implementation which
+ * For all partial function literals the compiler generates an `applyOrElse` implementation which
* avoids double evaluation of pattern matchers and guards.
* This makes `applyOrElse` the basis for the efficient implementation for many operations and scenarios, such as:
*
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index 01d179aeb6..0cd91409cf 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -506,7 +506,6 @@ trait GenTraversableOnce[+A] extends Any {
def toIndexedSeq: immutable.IndexedSeq[A]
/** Converts this $coll to a stream.
- * $willNotTerminateInf
* @return a stream containing all elements of this $coll.
*/
def toStream: Stream[A]
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 01a0aa3b51..1b496383a3 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -165,11 +165,11 @@ object Iterator {
/** Avoid stack overflows when applying ++ to lots of iterators by
* flattening the unevaluated iterators out into a vector of closures.
*/
- private[scala] final class ConcatIterator[+A](initial: Vector[() => Iterator[A]]) extends Iterator[A] {
- // current set to null when all iterators are exhausted
- private[this] var current: Iterator[A] = Iterator.empty
+ private[scala] final class ConcatIterator[+A](private[this] var current: Iterator[A], initial: Vector[() => Iterator[A]]) extends Iterator[A] {
+ @deprecated def this(initial: Vector[() => Iterator[A]]) = this(Iterator.empty, initial) // for binary compatibility
private[this] var queue: Vector[() => Iterator[A]] = initial
// Advance current to the next non-empty iterator
+ // current is set to null when all iterators are exhausted
private[this] def advance(): Boolean = {
if (queue.isEmpty) {
current = null
@@ -185,7 +185,7 @@ object Iterator {
def next() = if (hasNext) current.next else Iterator.empty.next
override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] =
- new ConcatIterator(queue :+ (() => that.toIterator))
+ new ConcatIterator(current, queue :+ (() => that.toIterator))
}
private[scala] final class JoinIterator[+A](lhs: Iterator[A], that: => GenTraversableOnce[A]) extends Iterator[A] {
@@ -194,7 +194,7 @@ object Iterator {
def next = if (lhs.hasNext) lhs.next else rhs.next
override def ++[B >: A](that: => GenTraversableOnce[B]) =
- new ConcatIterator(Vector(() => this, () => that.toIterator))
+ new ConcatIterator(this, Vector(() => that.toIterator))
}
}
diff --git a/src/library/scala/collection/LinearSeq.scala b/src/library/scala/collection/LinearSeq.scala
index 1e4975a0a7..49fbb902ab 100644
--- a/src/library/scala/collection/LinearSeq.scala
+++ b/src/library/scala/collection/LinearSeq.scala
@@ -25,7 +25,7 @@ trait LinearSeq[+A] extends Seq[A]
}
/** $factoryInfo
- * The current default implementation of a $Coll is a `Vector`.
+ * The current default implementation of a $Coll is a `List`.
* @define coll linear sequence
* @define Coll `LinearSeq`
*/
diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala
index 14ae57c43a..7d1d6b3781 100644
--- a/src/library/scala/collection/convert/Wrappers.scala
+++ b/src/library/scala/collection/convert/Wrappers.scala
@@ -194,7 +194,7 @@ private[collection] trait Wrappers {
def getKey = k
def getValue = v
def setValue(v1 : B) = self.put(k, v1)
- override def hashCode = byteswap32(k.hashCode) + (byteswap32(v.hashCode) << 16)
+ override def hashCode = byteswap32(k.##) + (byteswap32(v.##) << 16)
override def equals(other: Any) = other match {
case e: ju.Map.Entry[_, _] => k == e.getKey && v == e.getValue
case _ => false
diff --git a/src/library/scala/collection/generic/Sorted.scala b/src/library/scala/collection/generic/Sorted.scala
index ab0d443a03..a0b0e1318b 100644
--- a/src/library/scala/collection/generic/Sorted.scala
+++ b/src/library/scala/collection/generic/Sorted.scala
@@ -62,7 +62,8 @@ trait Sorted[K, +This <: Sorted[K, This]] {
/** Creates a ranged projection of this collection with both a lower-bound
* and an upper-bound.
*
- * @param from The upper-bound (exclusive) of the ranged projection.
+ * @param from The lower-bound (inclusive) of the ranged projection.
+ * @param until The upper-bound (exclusive) of the ranged projection.
*/
def range(from: K, until: K): This = rangeImpl(Some(from), Some(until))
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index e342e134b4..00491ef20e 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -114,10 +114,16 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
* @tparam T2 the type of the second half of the element pairs
* @param asPair an implicit conversion which asserts that the element type
* of this Array is a pair.
+ * @param ct1 a class tag for T1 type parameter that is required to create an instance
+ * of Array[T1]
+ * @param ct2 a class tag for T2 type parameter that is required to create an instance
+ * of Array[T2]
* @return a pair of Arrays, containing, respectively, the first and second half
* of each element pair of this Array.
*/
- def unzip[T1: ClassTag, T2: ClassTag](implicit asPair: T => (T1, T2)): (Array[T1], Array[T2]) = {
+ // implementation NOTE: ct1 and ct2 can't be written as context bounds because desugared
+ // implicits are put in front of asPair parameter that is supposed to guide type inference
+ def unzip[T1, T2](implicit asPair: T => (T1, T2), ct1: ClassTag[T1], ct2: ClassTag[T2]): (Array[T1], Array[T2]) = {
val a1 = new Array[T1](length)
val a2 = new Array[T2](length)
var i = 0
@@ -137,10 +143,19 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
* @tparam T3 the type of the third of three elements in the triple
* @param asTriple an implicit conversion which asserts that the element type
* of this Array is a triple.
+ * @param ct1 a class tag for T1 type parameter that is required to create an instance
+ * of Array[T1]
+ * @param ct2 a class tag for T2 type parameter that is required to create an instance
+ * of Array[T2]
+ * @param ct3 a class tag for T3 type parameter that is required to create an instance
+ * of Array[T3]
* @return a triple of Arrays, containing, respectively, the first, second, and third
* elements from each element triple of this Array.
*/
- def unzip3[T1: ClassTag, T2: ClassTag, T3: ClassTag](implicit asTriple: T => (T1, T2, T3)): (Array[T1], Array[T2], Array[T3]) = {
+ // implementation NOTE: ct1, ct2, ct3 can't be written as context bounds because desugared
+ // implicits are put in front of asPair parameter that is supposed to guide type inference
+ def unzip3[T1, T2, T3](implicit asTriple: T => (T1, T2, T3), ct1: ClassTag[T1], ct2: ClassTag[T2],
+ ct3: ClassTag[T3]): (Array[T1], Array[T2], Array[T3]) = {
val a1 = new Array[T1](length)
val a2 = new Array[T2](length)
val a3 = new Array[T3](length)
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index a55432fd71..a1e94c8876 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -14,8 +14,13 @@ import scala.annotation.implicitNotFound
import scala.util.Try
/**
- * An `ExecutionContext` can execute program logic, typically but not
- * necessarily on a thread pool.
+ * An `ExecutionContext` can execute program logic asynchronously,
+ * typically but not necessarily on a thread pool.
+ *
+ * A general purpose `ExecutionContext` must be asynchronous in executing
+ * any `Runnable` that is passed into its `execute`-method. A special purpose
+ * `ExecutionContext` may be synchronous but must only be passed to code that
+ * is explicitly safe to be run using a synchronously executing `ExecutionContext`.
*
* APIs such as `Future.onComplete` require you to provide a callback
* and an implicit `ExecutionContext`. The implicit `ExecutionContext`
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index 803c980058..2f7643bccf 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -64,6 +64,7 @@ trait Manifest[T] extends ClassManifest[T] with Equals {
// TODO undeprecated until Scala reflection becomes non-experimental
// @deprecated("Use type tags and manually check the corresponding class or type instead", "2.10.0")
+@SerialVersionUID(1L)
abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals {
override def <:<(that: ClassManifest[_]): Boolean =
(that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal)
@@ -72,6 +73,7 @@ abstract class AnyValManifest[T <: AnyVal](override val toString: String) extend
case _ => false
}
override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
+ @transient
override val hashCode = System.identityHashCode(this)
}
@@ -228,6 +230,7 @@ object ManifestFactory {
private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_],
override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) {
override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
+ @transient
override val hashCode = System.identityHashCode(this)
}
diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala
index 01700345d1..577cd09295 100644
--- a/src/reflect/scala/reflect/api/Internals.scala
+++ b/src/reflect/scala/reflect/api/Internals.scala
@@ -581,7 +581,7 @@ trait Internals { self: Universe =>
val ImplicitParams: ImplicitParamsExtractor
trait ImplicitParamsExtractor {
- def apply(paramss: List[List[ValDef]], implparams: List[ValDef]): List[List[ValDef]]
+ def apply(paramss: List[List[Tree]], implparams: List[Tree]): List[List[Tree]]
def unapply(vparamss: List[List[ValDef]]): Some[(List[List[ValDef]], List[ValDef])]
}
@@ -600,10 +600,11 @@ trait Internals { self: Universe =>
}
val SyntacticTypeApplied: SyntacticTypeAppliedExtractor
+ val SyntacticAppliedType: SyntacticTypeAppliedExtractor
trait SyntacticTypeAppliedExtractor {
def apply(tree: Tree, targs: List[Tree]): Tree
- def unapply(tree: Tree): Some[(Tree, List[Tree])]
+ def unapply(tree: Tree): Option[(Tree, List[Tree])]
}
val SyntacticApplied: SyntacticAppliedExtractor
@@ -761,9 +762,15 @@ trait Internals { self: Universe =>
def unapply(lst: List[List[Tree]]): Option[List[List[T]]]
}
+ val SyntacticPartialFunction: SyntacticPartialFunctionExtractor
+ trait SyntacticPartialFunctionExtractor {
+ def apply(cases: List[Tree]): Match
+ def unapply(tree: Tree): Option[List[CaseDef]]
+ }
+
val SyntacticMatch: SyntacticMatchExtractor
trait SyntacticMatchExtractor {
- def apply(selector: Tree, cases: List[Tree]): Match
+ def apply(scrutinee: Tree, cases: List[Tree]): Match
def unapply(tree: Match): Option[(Tree, List[CaseDef])]
}
@@ -773,10 +780,16 @@ trait Internals { self: Universe =>
def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)]
}
- val SyntacticIdent: SyntacticIdentExtractor
- trait SyntacticIdentExtractor {
- def apply(name: Name, isBackquoted: Boolean = false): Ident
- def unapply(tree: Ident): Option[(Name, Boolean)]
+ val SyntacticTermIdent: SyntacticTermIdentExtractor
+ trait SyntacticTermIdentExtractor {
+ def apply(name: TermName, isBackquoted: Boolean = false): Ident
+ def unapply(id: Ident): Option[(TermName, Boolean)]
+ }
+
+ val SyntacticTypeIdent: SyntacticTypeIdentExtractor
+ trait SyntacticTypeIdentExtractor {
+ def apply(name: TypeName): Ident
+ def unapply(tree: Tree): Option[TypeName]
}
val SyntacticImport: SyntacticImportExtractor
@@ -784,6 +797,48 @@ trait Internals { self: Universe =>
def apply(expr: Tree, selectors: List[Tree]): Import
def unapply(imp: Import): Some[(Tree, List[Tree])]
}
+
+ val SyntacticSelectType: SyntacticSelectTypeExtractor
+ trait SyntacticSelectTypeExtractor {
+ def apply(qual: Tree, name: TypeName): Select
+ def unapply(tree: Tree): Option[(Tree, TypeName)]
+ }
+
+ val SyntacticSelectTerm: SyntacticSelectTermExtractor
+ trait SyntacticSelectTermExtractor {
+ def apply(qual: Tree, name: TermName): Select
+ def unapply(tree: Tree): Option[(Tree, TermName)]
+ }
+
+ val SyntacticCompoundType: SyntacticCompoundTypeExtractor
+ trait SyntacticCompoundTypeExtractor {
+ def apply(parents: List[Tree], defns: List[Tree]): CompoundTypeTree
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree])]
+ }
+
+ val SyntacticSingletonType: SyntacitcSingletonTypeExtractor
+ trait SyntacitcSingletonTypeExtractor {
+ def apply(tree: Tree): SingletonTypeTree
+ def unapply(tree: Tree): Option[Tree]
+ }
+
+ val SyntacticTypeProjection: SyntacticTypeProjectionExtractor
+ trait SyntacticTypeProjectionExtractor {
+ def apply(qual: Tree, name: TypeName): SelectFromTypeTree
+ def unapply(tree: Tree): Option[(Tree, TypeName)]
+ }
+
+ val SyntacticAnnotatedType: SyntacticAnnotatedTypeExtractor
+ trait SyntacticAnnotatedTypeExtractor {
+ def apply(tpt: Tree, annot: Tree): Annotated
+ def unapply(tree: Tree): Option[(Tree, Tree)]
+ }
+
+ val SyntacticExistentialType: SyntacticExistentialTypeExtractor
+ trait SyntacticExistentialTypeExtractor {
+ def apply(tpt: Tree, where: List[Tree]): ExistentialTypeTree
+ def unapply(tree: Tree): Option[(Tree, List[MemberDef])]
+ }
}
@deprecated("Use `internal.reificationSupport` instead", "2.11.0")
diff --git a/src/reflect/scala/reflect/api/Liftables.scala b/src/reflect/scala/reflect/api/Liftables.scala
index ec9d85b69e..673dbce6f5 100644
--- a/src/reflect/scala/reflect/api/Liftables.scala
+++ b/src/reflect/scala/reflect/api/Liftables.scala
@@ -6,7 +6,7 @@ trait Liftables { self: Universe =>
/** A type class that defines a representation of `T` as a `Tree`.
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#lifting]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/lifting.html]]
*/
trait Liftable[T] {
def apply(value: T): Tree
@@ -32,7 +32,7 @@ trait Liftables { self: Universe =>
* lifted: universe.Tree = O
* }}}
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#lifting]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/lifting.html]]
*/
def apply[T](f: T => Tree): Liftable[T] =
new Liftable[T] { def apply(value: T): Tree = f(value) }
@@ -40,7 +40,7 @@ trait Liftables { self: Universe =>
/** A type class that defines a way to extract instance of `T` from a `Tree`.
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#unlifting]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/unlifting.html]]
*/
trait Unliftable[T] {
def unapply(tree: Tree): Option[T]
@@ -66,7 +66,7 @@ trait Liftables { self: Universe =>
* scala> val q"${_: O.type}" = q"$Oref"
* }}}
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#unlifting]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/unlifting.html]]
*/
def apply[T](pf: PartialFunction[Tree, T]): Unliftable[T] = new Unliftable[T] {
def unapply(value: Tree): Option[T] = pf.lift(value)
diff --git a/src/reflect/scala/reflect/api/Mirror.scala b/src/reflect/scala/reflect/api/Mirror.scala
index da3afd89ff..318fdb369a 100644
--- a/src/reflect/scala/reflect/api/Mirror.scala
+++ b/src/reflect/scala/reflect/api/Mirror.scala
@@ -118,4 +118,22 @@ abstract class Mirror[U <: Universe with Singleton] {
* @group Mirror
*/
def staticPackage(fullName: String): U#ModuleSymbol
+
+ /**
+ * Shortcut for `implicitly[WeakTypeTag[T]].tpe`
+ * @group TypeTags
+ */
+ def weakTypeOf[T: universe.WeakTypeTag]: U#Type = universe.weakTypeTag[T].in(this).tpe
+
+ /**
+ * Shortcut for `implicitly[TypeTag[T]].tpe`
+ * @group TypeTags
+ */
+ def typeOf[T: universe.TypeTag]: U#Type = universe.typeTag[T].in(this).tpe
+
+ /**
+ * Type symbol of `x` as derived from a type tag.
+ * @group TypeTags
+ */
+ def symbolOf[T: universe.WeakTypeTag]: U#TypeSymbol
}
diff --git a/src/reflect/scala/reflect/api/Quasiquotes.scala b/src/reflect/scala/reflect/api/Quasiquotes.scala
index 0065926e3b..e905aa4153 100644
--- a/src/reflect/scala/reflect/api/Quasiquotes.scala
+++ b/src/reflect/scala/reflect/api/Quasiquotes.scala
@@ -7,7 +7,7 @@ trait Quasiquotes { self: Universe =>
* that are also known as quasiquotes. With their help you can easily manipulate
* Scala reflection ASTs.
*
- * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html]]
+ * @see [[http://docs.scala-lang.org/overviews/quasiquotes/intro.html]]
*/
implicit class Quasiquote(ctx: StringContext) {
protected trait api {
diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala
index af11de46ce..66ac62cc9e 100644
--- a/src/reflect/scala/reflect/api/StandardLiftables.scala
+++ b/src/reflect/scala/reflect/api/StandardLiftables.scala
@@ -27,6 +27,7 @@ trait StandardLiftables { self: Universe =>
callScala(stdnme.Symbol)(Literal(Constant(v.name)) :: Nil)
}
+ implicit def liftTree[T <: Tree]: Liftable[T] = Liftable { identity }
implicit def liftName[T <: Name]: Liftable[T] = Liftable { name => Ident(name) }
implicit def liftExpr[T <: Expr[_]]: Liftable[T] = Liftable { expr => expr.tree }
implicit def liftType[T <: Type]: Liftable[T] = Liftable { tpe => TypeTree(tpe) }
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index a5a50f1088..dddd3c0e61 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -919,6 +919,14 @@ trait Symbols { self: Universe =>
* For a Scala package class, NoSymbol.
* For a Java class, NoSymbol.
*
+ * Known issues: Due to SI-8367, primaryConstructor may return unexpected results
+ * when called for Java classes (for some vague definition of a "Java class", which apparently
+ * not only includes javac-produced classfiles, but also consists of classes defined in
+ * Scala programs under the java.lang package). What's even worse, for some Java classes
+ * we can't even guarantee stability of the return value - depending on your classloader configuration
+ * and/or JDK version you might get different primaryConstructor for the same ClassSymbol.
+ * We have logged these issues at SI-8193.
+ *
* @group Class
*/
// TODO: SI-8193 I think we should only return a non-empty symbol if called for Scala classes
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 558e1aa611..bf560a21e5 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -410,7 +410,8 @@ trait Definitions extends api.StandardDefinitions {
else if (isScalaRepeatedParamType(tp)) elementExtract(RepeatedParamClass, tp) orElse tp
else tp
)
- def repeatedToSingle(tp: Type): Type = elementExtract(RepeatedParamClass, tp) orElse tp
+ def repeatedToSingle(tp: Type): Type = elementExtract(RepeatedParamClass, tp) orElse elementExtract(JavaRepeatedParamClass, tp) orElse tp
+ // We don't need to deal with JavaRepeatedParamClass here, as `repeatedToSeq` is only called in the patmat translation for Scala sources.
def repeatedToSeq(tp: Type): Type = elementTransform(RepeatedParamClass, tp)(seqType) orElse tp
def seqToRepeated(tp: Type): Type = elementTransform(SeqClass, tp)(scalaRepeatedType) orElse tp
def isReferenceArray(tp: Type) = elementTest(ArrayClass, tp)(_ <:< AnyRefTpe)
@@ -489,8 +490,10 @@ trait Definitions extends api.StandardDefinitions {
lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful
lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful
- lazy val BlackboxContextClass = getClassIfDefined("scala.reflect.macros.blackbox.Context") // defined in scala-reflect.jar, so we need to be careful
- lazy val WhiteboxContextClass = getClassIfDefined("scala.reflect.macros.whitebox.Context") // defined in scala-reflect.jar, so we need to be careful
+ private def Context_210 = if (settings.isScala211) NoSymbol else getClassIfDefined("scala.reflect.macros.Context") // needed under -Xsource:2.10
+ lazy val BlackboxContextClass = getClassIfDefined("scala.reflect.macros.blackbox.Context").orElse(Context_210) // defined in scala-reflect.jar, so we need to be careful
+
+ lazy val WhiteboxContextClass = getClassIfDefined("scala.reflect.macros.whitebox.Context").orElse(Context_210) // defined in scala-reflect.jar, so we need to be careful
def MacroContextPrefix = BlackboxContextClass.map(sym => getMemberMethod(sym, nme.prefix))
def MacroContextPrefixType = BlackboxContextClass.map(sym => getTypeMember(sym, tpnme.PrefixType))
def MacroContextUniverse = BlackboxContextClass.map(sym => getMemberMethod(sym, nme.universe))
@@ -501,7 +504,9 @@ trait Definitions extends api.StandardDefinitions {
lazy val StringContextClass = requiredClass[scala.StringContext]
- lazy val QuasiquoteClass = if (ApiUniverseClass != NoSymbol) getMember(ApiUniverseClass, tpnme.Quasiquote) else NoSymbol
+ // SI-8392 a reflection universe on classpath may not have
+ // quasiquotes, if e.g. crosstyping with -Xsource on
+ lazy val QuasiquoteClass = if (ApiUniverseClass != NoSymbol) getMemberIfDefined(ApiUniverseClass, tpnme.Quasiquote) else NoSymbol
lazy val QuasiquoteClass_api = if (QuasiquoteClass != NoSymbol) getMember(QuasiquoteClass, tpnme.api) else NoSymbol
lazy val QuasiquoteClass_api_apply = if (QuasiquoteClass_api != NoSymbol) getMember(QuasiquoteClass_api, nme.apply) else NoSymbol
lazy val QuasiquoteClass_api_unapply = if (QuasiquoteClass_api != NoSymbol) getMember(QuasiquoteClass_api, nme.unapply) else NoSymbol
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 7065a8cd6d..4a35e024de 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -30,6 +30,8 @@ trait Mirrors extends api.Mirrors {
val EmptyPackageClass: ClassSymbol
val EmptyPackage: ModuleSymbol
+ def symbolOf[T: universe.WeakTypeTag]: universe.TypeSymbol = universe.weakTypeTag[T].in(this).tpe.typeSymbolDirect.asType
+
def findMemberFromRoot(fullName: Name): Symbol = {
val segs = nme.segments(fullName.toString, fullName.isTermName)
if (segs.isEmpty) NoSymbol
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 680c19e426..fcc377ba32 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -567,8 +567,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
override protected val commentsRequired = true
- protected def needsParentheses(parent: Tree)(insideIf: Boolean = true, insideMatch: Boolean = true,
- insideTry: Boolean = true, insideAnnotated: Boolean = true, insideBlock: Boolean = true, insideLabelDef: Boolean = true) = {
+ protected def needsParentheses(parent: Tree)(insideIf: Boolean = true, insideMatch: Boolean = true, insideTry: Boolean = true,
+ insideAnnotated: Boolean = true, insideBlock: Boolean = true, insideLabelDef: Boolean = true, insideAssign: Boolean = true) = {
parent match {
case _: If => insideIf
case _: Match => insideMatch
@@ -576,6 +576,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case _: Annotated => insideAnnotated
case _: Block => insideBlock
case _: LabelDef => insideLabelDef
+ case _: Assign => insideAssign
case _ => false
}
}
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index ea230a215b..ad8a2594dd 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -6,7 +6,7 @@ import Flags._
import util._
trait ReificationSupport { self: SymbolTable =>
- import definitions.{TupleClass, FunctionClass, ScalaPackage, UnitClass}
+ import definitions._
import internal._
class ReificationSupportImpl extends ReificationSupportApi {
@@ -94,10 +94,14 @@ trait ReificationSupport { self: SymbolTable =>
def setSymbol[T <: Tree](tree: T, sym: Symbol): T = { tree.setSymbol(sym); tree }
- def toStats(tree: Tree): List[Tree] = SyntacticBlock.unapply(tree).get
+ def toStats(tree: Tree): List[Tree] = tree match {
+ case EmptyTree => Nil
+ case SyntacticBlock(stats) => stats
+ case _ => throw new IllegalArgumentException(s"can't flatten $tree")
+ }
def mkAnnotation(tree: Tree): Tree = tree match {
- case SyntacticNew(Nil, SyntacticApplied(SyntacticTypeApplied(_, _), _) :: Nil, noSelfType, Nil) =>
+ case SyntacticNew(Nil, SyntacticApplied(SyntacticAppliedType(_, _), _) :: Nil, noSelfType, Nil) =>
tree
case _ =>
throw new IllegalArgumentException(s"Tree ${showRaw(tree)} isn't a correct representation of annotation." +
@@ -106,14 +110,14 @@ trait ReificationSupport { self: SymbolTable =>
def mkAnnotation(trees: List[Tree]): List[Tree] = trees.map(mkAnnotation)
- def mkParam(argss: List[List[Tree]], extraFlags: FlagSet = NoFlags): List[List[ValDef]] =
- argss.map { args => args.map { mkParam(_, extraFlags) } }
+ def mkParam(argss: List[List[Tree]], extraFlags: FlagSet = NoFlags, excludeFlags: FlagSet = DEFERRED): List[List[ValDef]] =
+ argss.map { args => args.map { mkParam(_, extraFlags, excludeFlags) } }
- def mkParam(tree: Tree, extraFlags: FlagSet): ValDef = tree match {
+ def mkParam(tree: Tree, extraFlags: FlagSet, excludeFlags: FlagSet): ValDef = tree match {
case Typed(Ident(name: TermName), tpt) =>
- mkParam(ValDef(NoMods, name, tpt, EmptyTree), extraFlags)
+ mkParam(ValDef(NoMods, name, tpt, EmptyTree), extraFlags, excludeFlags)
case vd: ValDef =>
- var newmods = vd.mods & (~DEFERRED)
+ var newmods = vd.mods & (~excludeFlags)
if (vd.rhs.nonEmpty) newmods |= DEFAULTPARAM
copyValDef(vd)(mods = newmods | extraFlags)
case _ =>
@@ -123,7 +127,7 @@ trait ReificationSupport { self: SymbolTable =>
def mkImplicitParam(args: List[Tree]): List[ValDef] = args.map(mkImplicitParam)
- def mkImplicitParam(tree: Tree): ValDef = mkParam(tree, IMPLICIT | PARAM)
+ def mkImplicitParam(tree: Tree): ValDef = mkParam(tree, IMPLICIT | PARAM, NoFlags)
def mkTparams(tparams: List[Tree]): List[TypeDef] =
tparams.map {
@@ -183,7 +187,7 @@ trait ReificationSupport { self: SymbolTable =>
protected implicit def fresh: FreshNameCreator = self.currentFreshNameCreator
object ImplicitParams extends ImplicitParamsExtractor {
- def apply(paramss: List[List[ValDef]], implparams: List[ValDef]): List[List[ValDef]] =
+ def apply(paramss: List[List[Tree]], implparams: List[Tree]): List[List[Tree]] =
if (implparams.nonEmpty) paramss :+ mkImplicitParam(implparams) else paramss
def unapply(vparamss: List[List[ValDef]]): Some[(List[List[ValDef]], List[ValDef])] = vparamss match {
@@ -197,17 +201,35 @@ trait ReificationSupport { self: SymbolTable =>
def unapply(flags: Long): Some[Long] = Some(flags)
}
+ /** Construct/deconstruct type application term trees.
+ * Treats other term trees as zero-argument type applications.
+ */
object SyntacticTypeApplied extends SyntacticTypeAppliedExtractor {
def apply(tree: Tree, targs: List[Tree]): Tree =
if (targs.isEmpty) tree
else if (tree.isTerm) TypeApply(tree, targs)
- else if (tree.isType) AppliedTypeTree(tree, targs)
- else throw new IllegalArgumentException(s"can't apply types to $tree")
+ else throw new IllegalArgumentException(s"can't apply type arguments to $tree")
- def unapply(tree: Tree): Some[(Tree, List[Tree])] = tree match {
+ def unapply(tree: Tree): Option[(Tree, List[Tree])] = tree match {
case TypeApply(fun, targs) => Some((fun, targs))
- case AppliedTypeTree(tpe, targs) => Some((tpe, targs))
- case _ => Some((tree, Nil))
+ case _ if tree.isTerm => Some((tree, Nil))
+ case _ => None
+ }
+ }
+
+ /** Construct/deconstruct applied type trees.
+ * Treats other types as zero-arity applied types.
+ */
+ object SyntacticAppliedType extends SyntacticTypeAppliedExtractor {
+ def apply(tree: Tree, targs: List[Tree]): Tree =
+ if (targs.isEmpty) tree
+ else if (tree.isType) AppliedTypeTree(tree, targs)
+ else throw new IllegalArgumentException(s"can't create applied type from non-type $tree")
+
+ def unapply(tree: Tree): Option[(Tree, List[Tree])] = tree match {
+ case MaybeTypeTreeOriginal(AppliedTypeTree(tpe, targs)) => Some((tpe, targs))
+ case _ if tree.isType => Some((tree, Nil))
+ case _ => None
}
}
@@ -219,7 +241,15 @@ trait ReificationSupport { self: SymbolTable =>
case UnApply(treeInfo.Unapplied(Select(fun, nme.unapply)), pats) =>
Some((fun, pats :: Nil))
case treeInfo.Applied(fun, targs, argss) =>
- Some((SyntacticTypeApplied(fun, targs), argss))
+ fun match {
+ case Select(_: New, nme.CONSTRUCTOR) =>
+ Some((tree, Nil))
+ case _ =>
+ val callee =
+ if (fun.isTerm) SyntacticTypeApplied(fun, targs)
+ else SyntacticAppliedType(fun, targs)
+ Some((callee, argss))
+ }
}
}
@@ -239,7 +269,7 @@ trait ReificationSupport { self: SymbolTable =>
def unapply(templ: Template): Option[(List[Tree], ValDef, Modifiers, List[List[ValDef]], List[Tree], List[Tree])] = {
val Template(parents, selfType, _) = templ
val tbody = treeInfo.untypecheckedTemplBody(templ)
-
+
def result(ctorMods: Modifiers, vparamss: List[List[ValDef]], edefs: List[Tree], body: List[Tree]) =
Some((parents, selfType, ctorMods, vparamss, edefs, body))
def indexOfCtor(trees: List[Tree]) =
@@ -296,7 +326,7 @@ trait ReificationSupport { self: SymbolTable =>
constrMods: Modifiers, vparamss: List[List[Tree]],
earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef = {
val extraFlags = PARAMACCESSOR | (if (mods.isCase) CASEACCESSOR else 0L)
- val vparamss0 = mkParam(vparamss, extraFlags)
+ val vparamss0 = mkParam(vparamss, extraFlags, excludeFlags = DEFERRED | PARAM)
val tparams0 = mkTparams(tparams)
val parents0 = gen.mkParents(mods,
if (mods.isCase) parents.filter {
@@ -448,28 +478,25 @@ trait ReificationSupport { self: SymbolTable =>
* block as a list of elements rather than (stats, expr) pair
* it also:
*
- * 1. Treats of q"" (empty tree) as zero-element block.
- *
- * 2. Strips trailing synthetic units which are inserted by the
+ * 1. Strips trailing synthetic units which are inserted by the
* compiler if the block ends with a definition rather
- * than an expression.
+ * than an expression or is empty.
*
- * 3. Matches non-block term trees and recognizes them as
+ * 2. Matches non-block term trees and recognizes them as
* single-element blocks for sake of consistency with
* compiler's default to treat single-element blocks with
- * expressions as just expressions.
+ * expressions as just expressions. The only exception is q""
+ * which is not considered to be a block.
*/
object SyntacticBlock extends SyntacticBlockExtractor {
- def apply(stats: List[Tree]): Tree =
- if (stats.isEmpty) EmptyTree
- else gen.mkBlock(stats)
+ def apply(stats: List[Tree]): Tree = gen.mkBlock(stats)
def unapply(tree: Tree): Option[List[Tree]] = tree match {
case bl @ self.Block(stats, SyntheticUnit()) => Some(treeInfo.untypecheckedBlockBody(bl))
case bl @ self.Block(stats, expr) => Some(treeInfo.untypecheckedBlockBody(bl) :+ expr)
- case EmptyTree => Some(Nil)
- case _ if tree.isTerm => Some(tree :: Nil)
- case _ => None
+ case SyntheticUnit() => Some(Nil)
+ case _ if tree.isTerm && tree.nonEmpty => Some(tree :: Nil)
+ case _ => None
}
}
@@ -488,8 +515,10 @@ trait ReificationSupport { self: SymbolTable =>
gen.mkNew(parents, mkSelfType(selfType), earlyDefs ::: body, NoPosition, NoPosition)
def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] = tree match {
- case SyntacticApplied(Select(New(SyntacticTypeApplied(ident, targs)), nme.CONSTRUCTOR), argss) =>
- Some((Nil, SyntacticApplied(SyntacticTypeApplied(ident, targs), argss) :: Nil, noSelfType, Nil))
+ case treeInfo.Applied(Select(New(SyntacticAppliedType(ident, targs)), nme.CONSTRUCTOR), Nil, List(Nil)) =>
+ Some((Nil, SyntacticAppliedType(ident, targs) :: Nil, noSelfType, Nil))
+ case treeInfo.Applied(Select(New(SyntacticAppliedType(ident, targs)), nme.CONSTRUCTOR), Nil, argss) =>
+ Some((Nil, SyntacticApplied(SyntacticAppliedType(ident, targs), argss) :: Nil, noSelfType, Nil))
case SyntacticBlock(SyntacticClassDef(_, tpnme.ANON_CLASS_NAME, Nil, _, ListOfNil, earlyDefs, parents, selfType, body) ::
Apply(Select(New(Ident(tpnme.ANON_CLASS_NAME)), nme.CONSTRUCTOR), Nil) :: Nil) =>
Some((earlyDefs, parents, selfType, body))
@@ -501,11 +530,21 @@ trait ReificationSupport { self: SymbolTable =>
object SyntacticDefDef extends SyntacticDefDefExtractor {
def apply(mods: Modifiers, name: TermName, tparams: List[Tree],
vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef = {
+ val tparams0 = mkTparams(tparams)
val vparamss0 = mkParam(vparamss, PARAM)
- DefDef(mods, name, mkTparams(tparams), vparamss0, tpt, rhs)
+ val rhs0 = {
+ if (name != nme.CONSTRUCTOR) rhs
+ else rhs match {
+ case Block(_, _) => rhs
+ case _ => Block(List(rhs), gen.mkSyntheticUnit)
+ }
+ }
+ DefDef(mods, name, tparams0, vparamss0, tpt, rhs0)
}
def unapply(tree: Tree): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)] = tree match {
+ case DefDef(mods, nme.CONSTRUCTOR, tparams, vparamss, tpt, Block(List(expr), Literal(Constant(())))) =>
+ Some((mods, nme.CONSTRUCTOR, tparams, vparamss, tpt, expr))
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
Some((mods, name, tparams, vparamss, tpt, rhs))
case _ => None
@@ -807,10 +846,10 @@ trait ReificationSupport { self: SymbolTable =>
// drop potential @scala.unchecked annotation
protected object MaybeUnchecked {
def unapply(tree: Tree): Some[Tree] = tree match {
- case Annotated(SyntacticNew(Nil, Apply(ScalaDot(tpnme.unchecked), Nil) :: Nil, noSelfType, Nil), annottee) =>
+ case Annotated(SyntacticNew(Nil, ScalaDot(tpnme.unchecked) :: Nil, noSelfType, Nil), annottee) =>
Some(annottee)
case Typed(annottee, MaybeTypeTreeOriginal(
- Annotated(SyntacticNew(Nil, Apply(ScalaDot(tpnme.unchecked), Nil) :: Nil, noSelfType, Nil), _))) =>
+ Annotated(SyntacticNew(Nil, ScalaDot(tpnme.unchecked) :: Nil, noSelfType, Nil), _))) =>
Some(annottee)
case annottee => Some(annottee)
}
@@ -828,9 +867,40 @@ trait ReificationSupport { self: SymbolTable =>
case tree => throw new IllegalArgumentException("$tree is not valid representation of pattern match case")
}
+ object SyntacticPartialFunction extends SyntacticPartialFunctionExtractor {
+ def apply(cases: List[Tree]): Match = Match(EmptyTree, mkCases(cases))
+ def unapply(tree: Tree): Option[List[CaseDef]] = tree match {
+ case Match(EmptyTree, cases) => Some(cases)
+ case Typed(
+ Block(
+ List(ClassDef(clsMods, tpnme.ANON_FUN_NAME, Nil, Template(
+ List(abspf: TypeTree, ser: TypeTree), noSelfType, List(
+ DefDef(_, nme.CONSTRUCTOR, _, _, _, _),
+ DefDef(_, nme.applyOrElse, _, _, _,
+ Match(_, cases :+
+ CaseDef(Bind(nme.DEFAULT_CASE, Ident(nme.WILDCARD)), _, _))),
+ DefDef(_, nme.isDefinedAt, _, _, _, _))))),
+ Apply(Select(New(Ident(tpnme.ANON_FUN_NAME)), termNames.CONSTRUCTOR), List())),
+ pf: TypeTree)
+ if pf.tpe != null && pf.tpe.typeSymbol.eq(PartialFunctionClass) &&
+ abspf.tpe != null && abspf.tpe.typeSymbol.eq(AbstractPartialFunctionClass) &&
+ ser.tpe != null && ser.tpe.typeSymbol.eq(SerializableClass) &&
+ clsMods.hasFlag(FINAL) && clsMods.hasFlag(SYNTHETIC) =>
+ Some(cases)
+ case _ => None
+ }
+ }
+
object SyntacticMatch extends SyntacticMatchExtractor {
- def apply(selector: Tree, cases: List[Tree]) = Match(selector, mkCases(cases))
- def unapply(tree: Match): Option[(Tree, List[CaseDef])] = Match.unapply(tree)
+ def apply(scrutinee: Tree, cases: List[Tree]) = {
+ require(scrutinee.nonEmpty, "match's scrutinee may not be empty")
+ Match(scrutinee, mkCases(cases))
+ }
+
+ def unapply(tree: Match): Option[(Tree, List[CaseDef])] = tree match {
+ case Match(scrutinee, cases) if scrutinee.nonEmpty => Some((scrutinee, cases))
+ case _ => None
+ }
}
object SyntacticTry extends SyntacticTryExtractor {
@@ -838,13 +908,24 @@ trait ReificationSupport { self: SymbolTable =>
def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)] = Try.unapply(tree)
}
- object SyntacticIdent extends SyntacticIdentExtractor {
- def apply(name: Name, isBackquoted: Boolean) = {
+ object SyntacticTermIdent extends SyntacticTermIdentExtractor {
+ def apply(name: TermName, isBackquoted: Boolean): Ident = {
val id = self.Ident(name)
if (isBackquoted) id updateAttachment BackquotedIdentifierAttachment
id
}
- def unapply(tree: Ident): Some[(Name, Boolean)] = Some((tree.name, tree.hasAttachment[BackquotedIdentifierAttachment.type]))
+ def unapply(id: Ident): Option[(TermName, Boolean)] = id.name match {
+ case name: TermName => Some((name, id.hasAttachment[BackquotedIdentifierAttachment.type]))
+ case _ => None
+ }
+ }
+
+ object SyntacticTypeIdent extends SyntacticTypeIdentExtractor {
+ def apply(name: TypeName): Ident = self.Ident(name)
+ def unapply(tree: Tree): Option[TypeName] = tree match {
+ case MaybeTypeTreeOriginal(Ident(name: TypeName)) => Some(name)
+ case _ => None
+ }
}
/** Facade over Imports and ImportSelectors that lets to structurally
@@ -986,6 +1067,79 @@ trait ReificationSupport { self: SymbolTable =>
Some((imp.expr, selectors))
}
}
+
+ object SyntacticSelectType extends SyntacticSelectTypeExtractor {
+ def apply(qual: Tree, name: TypeName): Select = Select(qual, name)
+ def unapply(tree: Tree): Option[(Tree, TypeName)] = tree match {
+ case MaybeTypeTreeOriginal(Select(qual, name: TypeName)) => Some((qual, name))
+ case _ => None
+ }
+ }
+
+ object SyntacticSelectTerm extends SyntacticSelectTermExtractor {
+ def apply(qual: Tree, name: TermName): Select = Select(qual, name)
+ def unapply(tree: Tree): Option[(Tree, TermName)] = tree match {
+ case Select(qual, name: TermName) => Some((qual, name))
+ case _ => None
+ }
+ }
+
+ object SyntacticCompoundType extends SyntacticCompoundTypeExtractor {
+ def apply(parents: List[Tree], defns: List[Tree]) =
+ CompoundTypeTree(Template(gen.mkParents(NoMods, parents), noSelfType, defns))
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree])] = tree match {
+ case MaybeTypeTreeOriginal(CompoundTypeTree(Template(parents, _, defns))) =>
+ Some((parents, defns))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticSingletonType extends SyntacitcSingletonTypeExtractor {
+ def apply(ref: Tree): SingletonTypeTree = SingletonTypeTree(ref)
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case MaybeTypeTreeOriginal(SingletonTypeTree(ref)) =>
+ Some(ref)
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticTypeProjection extends SyntacticTypeProjectionExtractor {
+ def apply(qual: Tree, name: TypeName): SelectFromTypeTree =
+ SelectFromTypeTree(qual, name)
+ def unapply(tree: Tree): Option[(Tree, TypeName)] = tree match {
+ case MaybeTypeTreeOriginal(SelectFromTypeTree(qual, name)) =>
+ Some((qual, name))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticAnnotatedType extends SyntacticAnnotatedTypeExtractor {
+ def apply(tpt: Tree, annot: Tree): Annotated =
+ Annotated(annot, tpt)
+ def unapply(tree: Tree): Option[(Tree, Tree)] = tree match {
+ case MaybeTypeTreeOriginal(Annotated(annot, tpt)) =>
+ Some((tpt, annot))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticExistentialType extends SyntacticExistentialTypeExtractor {
+ def apply(tpt: Tree, where: List[Tree]): ExistentialTypeTree =
+ ExistentialTypeTree(tpt, where.map {
+ case md: MemberDef => md
+ case tree => throw new IllegalArgumentException("$tree is not legal forSome definition")
+ })
+ def unapply(tree: Tree): Option[(Tree, List[MemberDef])] = tree match {
+ case MaybeTypeTreeOriginal(ExistentialTypeTree(tpt, where)) =>
+ Some((tpt, where))
+ case _ =>
+ None
+ }
+ }
}
val build = new ReificationSupportImpl
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index f3467ff9f4..6848c357c5 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -580,6 +580,7 @@ trait StdNames {
val AnyVal: NameType = "AnyVal"
val Apply: NameType = "Apply"
val ArrayAnnotArg: NameType = "ArrayAnnotArg"
+ val CaseDef: NameType = "CaseDef"
val ClassInfoType: NameType = "ClassInfoType"
val ConstantType: NameType = "ConstantType"
val EmptyPackage: NameType = "EmptyPackage"
@@ -611,33 +612,6 @@ trait StdNames {
val SelectFromTypeTree: NameType = "SelectFromTypeTree"
val SingleType: NameType = "SingleType"
val SuperType: NameType = "SuperType"
- val SyntacticApplied: NameType = "SyntacticApplied"
- val SyntacticAssign: NameType = "SyntacticAssign"
- val SyntacticBlock: NameType = "SyntacticBlock"
- val SyntacticClassDef: NameType = "SyntacticClassDef"
- val SyntacticDefDef: NameType = "SyntacticDefDef"
- val SyntacticEmptyTypeTree: NameType = "SyntacticEmptyTypeTree"
- val SyntacticFilter: NameType = "SyntacticFilter"
- val SyntacticFor: NameType = "SyntacticFor"
- val SyntacticForYield: NameType = "SyntacticForYield"
- val SyntacticFunction: NameType = "SyntacticFunction"
- val SyntacticFunctionType: NameType = "SyntacticFunctionType"
- val SyntacticIdent: NameType = "SyntacticIdent"
- val SyntacticImport: NameType = "SyntacticImport"
- val SyntacticMatch: NameType = "SyntacticMatch"
- val SyntacticNew: NameType = "SyntacticNew"
- val SyntacticObjectDef: NameType = "SyntacticObjectDef"
- val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef"
- val SyntacticPatDef: NameType = "SyntacticPatDef"
- val SyntacticTraitDef: NameType = "SyntacticTraitDef"
- val SyntacticTry: NameType = "SyntacticTry"
- val SyntacticTuple: NameType = "SyntacticTuple"
- val SyntacticTupleType: NameType = "SyntacticTupleType"
- val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
- val SyntacticValDef: NameType = "SyntacticValDef"
- val SyntacticValEq: NameType = "SyntacticValEq"
- val SyntacticValFrom: NameType = "SyntacticValFrom"
- val SyntacticVarDef: NameType = "SyntacticVarDef"
val This: NameType = "This"
val ThisType: NameType = "ThisType"
val Tuple2: NameType = "Tuple2"
@@ -805,11 +779,50 @@ trait StdNames {
val zero: NameType = "zero"
// quasiquote interpolators:
- val q: NameType = "q"
- val tq: NameType = "tq"
- val cq: NameType = "cq"
- val pq: NameType = "pq"
- val fq: NameType = "fq"
+ val q: NameType = "q"
+ val tq: NameType = "tq"
+ val cq: NameType = "cq"
+ val pq: NameType = "pq"
+ val fq: NameType = "fq"
+
+ // quasiquote's syntactic combinators
+ val SyntacticAnnotatedType: NameType = "SyntacticAnnotatedType"
+ val SyntacticApplied: NameType = "SyntacticApplied"
+ val SyntacticAppliedType: NameType = "SyntacticAppliedType"
+ val SyntacticAssign: NameType = "SyntacticAssign"
+ val SyntacticBlock: NameType = "SyntacticBlock"
+ val SyntacticClassDef: NameType = "SyntacticClassDef"
+ val SyntacticCompoundType: NameType = "SyntacticCompoundType"
+ val SyntacticDefDef: NameType = "SyntacticDefDef"
+ val SyntacticEmptyTypeTree: NameType = "SyntacticEmptyTypeTree"
+ val SyntacticExistentialType: NameType = "SyntacticExistentialType"
+ val SyntacticFilter: NameType = "SyntacticFilter"
+ val SyntacticFor: NameType = "SyntacticFor"
+ val SyntacticForYield: NameType = "SyntacticForYield"
+ val SyntacticFunction: NameType = "SyntacticFunction"
+ val SyntacticFunctionType: NameType = "SyntacticFunctionType"
+ val SyntacticImport: NameType = "SyntacticImport"
+ val SyntacticMatch: NameType = "SyntacticMatch"
+ val SyntacticNew: NameType = "SyntacticNew"
+ val SyntacticObjectDef: NameType = "SyntacticObjectDef"
+ val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef"
+ val SyntacticPartialFunction: NameType = "SyntacticPartialFunction"
+ val SyntacticPatDef: NameType = "SyntacticPatDef"
+ val SyntacticSelectTerm: NameType = "SyntacticSelectTerm"
+ val SyntacticSelectType: NameType = "SyntacticSelectType"
+ val SyntacticSingletonType: NameType = "SyntacticSingletonType"
+ val SyntacticTermIdent: NameType = "SyntacticTermIdent"
+ val SyntacticTraitDef: NameType = "SyntacticTraitDef"
+ val SyntacticTry: NameType = "SyntacticTry"
+ val SyntacticTuple: NameType = "SyntacticTuple"
+ val SyntacticTupleType: NameType = "SyntacticTupleType"
+ val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
+ val SyntacticTypeIdent: NameType = "SyntacticTypeIdent"
+ val SyntacticTypeProjection: NameType = "SyntacticTypeProjection"
+ val SyntacticValDef: NameType = "SyntacticValDef"
+ val SyntacticValEq: NameType = "SyntacticValEq"
+ val SyntacticValFrom: NameType = "SyntacticValFrom"
+ val SyntacticVarDef: NameType = "SyntacticVarDef"
// unencoded operators
object raw {
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index e50c65c9ca..c76dedbff4 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -51,6 +51,7 @@ abstract class SymbolTable extends macros.Universe
val gen = new InternalTreeGen { val global: SymbolTable.this.type = SymbolTable.this }
def log(msg: => AnyRef): Unit
+ def deprecationWarning(pos: Position, msg: String): Unit = warning(msg)
def warning(msg: String): Unit = Console.err.println(msg)
def inform(msg: String): Unit = Console.err.println(msg)
def globalError(msg: String): Unit = abort(msg)
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 03d8f97831..2ce54d2259 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -1904,6 +1904,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The next enclosing method. */
def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod
+ /** The primary constructor of a class. */
def primaryConstructor: Symbol = NoSymbol
/** The self symbol (a TermSymbol) of a class with explicit self type, or else the
@@ -2342,7 +2343,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def localName: TermName = name.localName
/** The setter of this value or getter definition, or NoSymbol if none exists */
+ @deprecated("Use `setterIn` instead", "2.11.0")
final def setter(base: Symbol, hasExpandedName: Boolean = needsExpandedSetterName): Symbol =
+ setterIn(base, hasExpandedName)
+
+ final def setterIn(base: Symbol, hasExpandedName: Boolean = needsExpandedSetterName): Symbol =
base.info decl setterNameInBase(base, hasExpandedName) filter (_.hasAccessorFlag)
def needsExpandedSetterName = (
@@ -3188,8 +3193,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def primaryConstructor = {
val c = info decl primaryConstructorName
- if (isJavaDefined) NoSymbol // need to force info before checking the flag
- else if (c.isOverloaded) c.alternatives.head else c
+ if (c.isOverloaded) c.alternatives.head else c
}
override def associatedFile = (
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 6011289baf..9066c73393 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -452,7 +452,7 @@ abstract class TreeGen {
/** Create block of statements `stats` */
def mkBlock(stats: List[Tree]): Tree =
- if (stats.isEmpty) Literal(Constant(()))
+ if (stats.isEmpty) mkSyntheticUnit()
else if (!stats.last.isTerm) Block(stats, mkSyntheticUnit())
else if (stats.length == 1) stats.head
else Block(stats.init, stats.last)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index e9e5a89aa7..f26315c538 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2271,7 +2271,7 @@ trait Types
case _ => args.mkString("(", ", ", ")")
}
private def customToString = sym match {
- case RepeatedParamClass => args.head + "*"
+ case RepeatedParamClass | JavaRepeatedParamClass => args.head + "*"
case ByNameParamClass => "=> " + args.head
case _ =>
if (isFunctionTypeDirect(this)) {
@@ -4113,8 +4113,8 @@ trait Types
def isSubArgs(tps1: List[Type], tps2: List[Type], tparams: List[Symbol], depth: Depth): Boolean = {
def isSubArg(t1: Type, t2: Type, variance: Variance) = (
- (variance.isContravariant || isSubType(t1, t2, depth))
- && (variance.isCovariant || isSubType(t2, t1, depth))
+ (variance.isCovariant || isSubType(t2, t1, depth)) // The order of these two checks can be material for performance (SI-8478)
+ && (variance.isContravariant || isSubType(t1, t2, depth))
)
corresponds3(tps1, tps2, mapList(tparams)(_.variance))(isSubArg)
diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala
index 3bcfed7d34..cfe2ad8b87 100644
--- a/src/reflect/scala/reflect/internal/Variances.scala
+++ b/src/reflect/scala/reflect/internal/Variances.scala
@@ -75,7 +75,14 @@ trait Variances {
def nextVariance(sym: Symbol, v: Variance): Variance = (
if (shouldFlip(sym, tvar)) v.flip
else if (isLocalOnly(sym)) Bivariant
- else if (sym.isAliasType) Invariant
+ else if (sym.isAliasType) (
+ // Unsound pre-2.11 behavior preserved under -Xsource:2.10
+ if (settings.isScala211 || sym.isOverridingSymbol) Invariant
+ else {
+ deprecationWarning(sym.pos, s"Construct depends on unsound variance analysis and will not compile in scala 2.11 and beyond")
+ Bivariant
+ }
+ )
else v
)
def loop(sym: Symbol, v: Variance): Variance = (
diff --git a/src/reflect/scala/reflect/internal/pickling/Translations.scala b/src/reflect/scala/reflect/internal/pickling/Translations.scala
index e56cf796cb..d924cb3a0c 100644
--- a/src/reflect/scala/reflect/internal/pickling/Translations.scala
+++ b/src/reflect/scala/reflect/internal/pickling/Translations.scala
@@ -62,21 +62,22 @@ trait Translations {
}
def picklerTag(tpe: Type): Int = tpe match {
- case NoType => NOtpe
- case NoPrefix => NOPREFIXtpe
- case _: ThisType => THIStpe
- case _: SingleType => SINGLEtpe
- case _: SuperType => SUPERtpe
- case _: ConstantType => CONSTANTtpe
- case _: TypeBounds => TYPEBOUNDStpe
- case _: TypeRef => TYPEREFtpe
- case _: RefinedType => REFINEDtpe
- case _: ClassInfoType => CLASSINFOtpe
- case _: MethodType => METHODtpe
- case _: PolyType => POLYtpe
- case _: NullaryMethodType => POLYtpe // bad juju, distinct ints are not at a premium!
- case _: ExistentialType => EXISTENTIALtpe
- case _: AnnotatedType => ANNOTATEDtpe
+ case NoType => NOtpe
+ case NoPrefix => NOPREFIXtpe
+ case _: ThisType => THIStpe
+ case _: SingleType => SINGLEtpe
+ case _: SuperType => SUPERtpe
+ case _: ConstantType => CONSTANTtpe
+ case _: TypeBounds => TYPEBOUNDStpe
+ case _: TypeRef => TYPEREFtpe
+ case _: RefinedType => REFINEDtpe
+ case _: ClassInfoType => CLASSINFOtpe
+ case _: MethodType => METHODtpe
+ case _: PolyType => POLYtpe
+ case _: NullaryMethodType => POLYtpe // bad juju, distinct ints are not at a premium!
+ case _: ExistentialType => EXISTENTIALtpe
+ case StaticallyAnnotatedType(_, _) => ANNOTATEDtpe
+ case _: AnnotatedType => picklerTag(tpe.underlying)
}
def picklerSubTag(tree: Tree): Int = tree match {
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 42f794736a..64a1a44722 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -229,6 +229,20 @@ abstract class UnPickler {
NoSymbol
}
+ def moduleAdvice(missing: String): String = {
+ val module =
+ if (missing.startsWith("scala.xml")) Some(("org.scala-lang.modules", "scala-xml"))
+ else if (missing.startsWith("scala.util.parsing")) Some(("org.scala-lang.modules", "scala-parser-combinators"))
+ else if (missing.startsWith("scala.swing")) Some(("org.scala-lang.modules", "scala-swing"))
+ else if (missing.startsWith("scala.util.continuations")) Some(("org.scala-lang.plugins", "scala-continuations-library"))
+ else None
+
+ (module map { case (group, art) =>
+ s"""\n(NOTE: It looks like the $art module is missing; try adding a dependency on "$group" : "$art".
+ | See http://docs.scala-lang.org/overviews/core/scala-2.11.html for more information.)""".stripMargin
+ } getOrElse "")
+ }
+
// (1) Try name.
fromName(name) orElse {
// (2) Try with expanded name. Can happen if references to private
@@ -240,11 +254,12 @@ abstract class UnPickler {
// (4) Call the mirror's "missing" hook.
adjust(mirrorThatLoaded(owner).missingHook(owner, name)) orElse {
// (5) Create a stub symbol to defer hard failure a little longer.
+ val fullName = s"${owner.fullName}.$name"
val missingMessage =
- s"""|bad symbolic reference. A signature in $filename refers to ${name.longString}
- |in ${owner.kindString} ${owner.fullName} which is not available.
- |It may be completely missing from the current classpath, or the version on
- |the classpath might be incompatible with the version used when compiling $filename.""".stripMargin
+ s"""|bad symbolic reference to $fullName encountered in class file '$filename'.
+ |Cannot access ${name.longString} in ${owner.kindString} ${owner.fullName}. The current classpath may be
+ |missing a definition for $fullName, or $filename may have been compiled against a version that's
+ |incompatible with the one found on the current classpath.${moduleAdvice(fullName)}""".stripMargin
owner.newStubSymbol(name, missingMessage)
}
}
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
index 564cbb1ce3..c1c43178e5 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
@@ -16,8 +16,9 @@ private[internal] trait TypeConstraints {
private lazy val _undoLog = new UndoLog
def undoLog = _undoLog
+ import TypeConstraints.UndoPair
class UndoLog extends Clearable {
- private type UndoPairs = List[(TypeVar, TypeConstraint)]
+ type UndoPairs = List[UndoPair[TypeVar, TypeConstraint]]
//OPT this method is public so we can do `manual inlining`
var log: UndoPairs = List()
@@ -29,7 +30,7 @@ private[internal] trait TypeConstraints {
def undoTo(limit: UndoPairs) {
assertCorrectThread()
while ((log ne limit) && log.nonEmpty) {
- val (tv, constr) = log.head
+ val UndoPair(tv, constr) = log.head
tv.constr = constr
log = log.tail
}
@@ -40,7 +41,7 @@ private[internal] trait TypeConstraints {
* which is already synchronized.
*/
private[reflect] def record(tv: TypeVar) = {
- log ::= ((tv, tv.constr.cloneInternal))
+ log ::= UndoPair(tv, tv.constr.cloneInternal)
}
def clear() {
@@ -266,3 +267,9 @@ private[internal] trait TypeConstraints {
tvars forall (tv => tv.instWithinBounds || util.andFalse(logBounds(tv)))
}
}
+
+private[internal] object TypeConstraints {
+ // UndoPair is declared in companion object to not hold an outer pointer reference
+ final case class UndoPair[TypeVar <: SymbolTable#TypeVar,
+ TypeConstraint <: TypeConstraints#TypeConstraint](tv: TypeVar, tConstraint: TypeConstraint)
+}
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index a96bed4696..ce0eadc04f 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -402,7 +402,13 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
private val crashRecovery: PartialFunction[Throwable, Boolean] = {
case ex: Throwable =>
- echo(intp.global.throwableAsString(ex))
+ val (err, explain) = (
+ if (intp.isInitializeComplete)
+ (intp.global.throwableAsString(ex), "")
+ else
+ (ex.getMessage, "The compiler did not initialize.\n")
+ )
+ echo(err)
ex match {
case _: NoSuchMethodError | _: NoClassDefFoundError =>
@@ -410,7 +416,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
throw ex
case _ =>
def fn(): Boolean =
- try in.readYesOrNo(replayQuestionMessage, { echo("\nYou must enter y or n.") ; fn() })
+ try in.readYesOrNo(explain + replayQuestionMessage, { echo("\nYou must enter y or n.") ; fn() })
catch { case _: RuntimeException => false }
if (fn()) replay()
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 8bb5757bbb..47d97dd4dd 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -117,8 +117,10 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
private def _initSources = List(new BatchSourceFile("<init>", "class $repl_$init { }"))
private def _initialize() = {
try {
- // todo. if this crashes, REPL will hang
- new _compiler.Run() compileSources _initSources
+ // if this crashes, REPL will hang its head in shame
+ val run = new _compiler.Run()
+ assert(run.typerPhase != NoPhase, "REPL requires a typer phase.")
+ run compileSources _initSources
_initializeComplete = true
true
}
@@ -306,7 +308,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
*/
override protected def findAbstractFile(name: String): AbstractFile =
super.findAbstractFile(name) match {
- case null => translatePath(name) map (super.findAbstractFile(_)) orNull
+ case null if _initializeComplete => translatePath(name) map (super.findAbstractFile(_)) orNull
case file => file
}
}
@@ -384,6 +386,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def compileSourcesKeepingRun(sources: SourceFile*) = {
val run = new Run()
+ assert(run.typerPhase != NoPhase, "REPL requires a typer phase.")
reporter.reset()
run compileSources sources.toList
(!reporter.hasErrors, run)
diff --git a/src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala b/src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala
index 51fab3082e..07d619bca5 100644
--- a/src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ReplGlobal.scala
@@ -55,6 +55,8 @@ trait ReplGlobal extends Global {
// newNamer(rootContext(unit)).enterSym(unit.body)
}
}
+ // add to initial or terminal phase to sanity check Run at construction
+ override val requires = List("typer") // ensure they didn't -Ystop-after:parser
}
override protected def computePhaseDescriptors: List[SubComponent] = {
diff --git a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala
index 4607684c0d..dce52af56a 100644
--- a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala
@@ -94,7 +94,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
val documentError: PartialFunction[Throwable, Unit] = {
case NoCompilerRunException =>
- reporter.info(null, "No documentation generated with unsucessful compiler run", force = false)
+ reporter.info(null, "No documentation generated with unsuccessful compiler run", force = false)
case _: ClassNotFoundException =>
()
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala
index 212f94c531..e5c64c6f45 100644
--- a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala
@@ -37,7 +37,7 @@ trait ScaladocAnalyzer extends Analyzer {
comment.defineVariables(sym)
val typer1 = newTyper(context.makeNewScope(docDef, context.owner))
for (useCase <- comment.useCases) {
- typer1.silent(_ => typer1 defineUseCases useCase) match {
+ typer1.silent(_.asInstanceOf[ScaladocTyper].defineUseCases(useCase)) match {
case SilentTypeError(err) =>
unit.warning(useCase.pos, err.errMsg)
case _ =>
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala
index d721a96ad7..a0dd154d2e 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlFactory.scala
@@ -97,7 +97,9 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index) {
"selected2.png",
"selected-right-implicits.png",
"selected-implicits.png",
- "unselected.png"
+ "unselected.png",
+
+ "permalink.png"
)
/** Generates the Scaladoc site for a model into the site root.
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
index f6373e9e97..295bae5bef 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -14,6 +14,7 @@ import base.comment._
import model._
import scala.xml.NodeSeq
+import scala.xml.Elem
import scala.xml.dtd.{DocType, PublicID}
import scala.collection._
import java.io.Writer
@@ -219,4 +220,28 @@ abstract class HtmlPage extends Page { thisPage =>
else if (ety.isObject) "object_big.png"
else if (ety.isPackage) "package_big.png"
else "class_big.png" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not
+
+ def permalink(template: Entity, isSelf: Boolean = true): Elem =
+ <span class="permalink">
+ <a href={ memberToUrl(template, isSelf) } title="Permalink" target="_top">
+ <img src={ relativeLinkTo(List("permalink.png", "lib")) } />
+ </a>
+ </span>
+
+ def memberToUrl(template: Entity, isSelf: Boolean = true): String = {
+ val (signature: Option[String], containingTemplate: TemplateEntity) = template match {
+ case dte: DocTemplateEntity if (!isSelf) => (Some(dte.signature), dte.inTemplate)
+ case dte: DocTemplateEntity => (None, dte)
+ case me: MemberEntity => (Some(me.signature), me.inTemplate)
+ case tpl => (None, tpl)
+ }
+
+ def hashFromPath(templatePath: List[String]): String =
+ ((templatePath.head.replace(".html", "") :: templatePath.tail).reverse).mkString(".")
+
+ val containingTemplatePath = templateToPath(containingTemplate)
+ val url = "../" * (containingTemplatePath.size - 1) + "index.html"
+ val hash = hashFromPath(containingTemplatePath)
+ s"$url#$hash" + signature.map("@" + _).getOrElse("")
+ }
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
index 26ee005d3e..b5a8d1ac36 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala
@@ -15,7 +15,7 @@ import base.comment._
import model._
import model.diagram._
-import scala.xml.{ NodeSeq, Text, UnprefixedAttribute }
+import scala.xml.{Elem, NodeSeq, Text, UnprefixedAttribute}
import scala.language.postfixOps
import scala.collection.mutable. { Set, HashSet }
@@ -110,7 +110,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
<img src={ relativeLinkTo(List(docEntityKindToBigImage(tpl), "lib")) }/>
}}
{ owner }
- <h1>{ displayName }</h1>
+ <h1>{ displayName }</h1> { permalink(tpl) }
</div>
{ signature(tpl, isSelf = true) }
@@ -306,9 +306,6 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
<xml:group>
<div id="comment" class="fullcommenttop">{ memberToCommentBodyHtml(mbr, inTpl, isSelf = true) }</div>
</xml:group>
- case dte: DocTemplateEntity if mbr.comment.isDefined =>
- // comment of inner, documented class (only short comment, full comment is on the class' own page)
- memberToInlineCommentHtml(mbr, isSelf)
case _ =>
// comment of non-class member or non-documentented inner class
val commentBody = memberToCommentBodyHtml(mbr, inTpl, isSelf = false)
@@ -723,6 +720,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
/** name, tparams, params, result */
def signature(mbr: MemberEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = {
+
def inside(hasLinks: Boolean, nameLink: String = ""): NodeSeq =
<xml:group>
<span class="modifier_kind">
@@ -833,11 +831,11 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
</xml:group>
mbr match {
case dte: DocTemplateEntity if !isSelf =>
- <h4 class="signature">{ inside(hasLinks = true, nameLink = relativeLinkTo(dte)) }</h4>
+ <h4 class="signature">{ inside(hasLinks = true, nameLink = relativeLinkTo(dte)) }</h4> ++ permalink(dte, isSelf)
case _ if isSelf =>
<h4 id="signature" class="signature">{ inside(hasLinks = true) }</h4>
case _ =>
- <h4 class="signature">{ inside(hasLinks = true) }</h4>
+ <h4 class="signature">{ inside(hasLinks = true) }</h4> ++ permalink(mbr)
}
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
index c201b324e7..3f5cfb4b52 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
@@ -1,5 +1,5 @@
// © 2009–2010 EPFL/LAMP
-// code by Gilles Dubochet with contributions by Johannes Rudolph and "spiros"
+// code by Gilles Dubochet with contributions by Johannes Rudolph, "spiros" and Marcin Kubala
var topLevelTemplates = undefined;
var topLevelPackages = undefined;
@@ -11,7 +11,7 @@ var focusFilterState = undefined;
var title = $(document).attr('title');
-var lastHash = "";
+var lastFragment = "";
$(document).ready(function() {
$('body').layout({
@@ -24,9 +24,13 @@ $(document).ready(function() {
,north__paneSelector: ".ui-west-north"
});
$('iframe').bind("load", function(){
- var subtitle = $(this).contents().find('title').text();
- $(document).attr('title', (title ? title + " - " : "") + subtitle);
-
+ try {
+ var subtitle = $(this).contents().find('title').text();
+ $(document).attr('title', (title ? title + " - " : "") + subtitle);
+ } catch (e) {
+ // Chrome doesn't allow reading the iframe's contents when
+ // used on the local file system.
+ }
setUrlFragmentFromFrameSrc();
});
@@ -64,21 +68,43 @@ $(document).ready(function() {
// Set the iframe's src according to the fragment of the current url.
// fragment = "#scala.Either" => iframe url = "scala/Either.html"
// fragment = "#scala.Either@isRight:Boolean" => iframe url = "scala/Either.html#isRight:Boolean"
+// fragment = "#scalaz.iteratee.package@>@>[E,A]=scalaz.iteratee.package.Iteratee[E,A]" => iframe url = "scalaz/iteratee/package.html#>@>[E,A]=scalaz.iteratee.package.Iteratee[E,A]"
function setFrameSrcFromUrlFragment() {
- var fragment = location.hash.slice(1);
- if(fragment) {
- var loc = fragment.split("@")[0].replace(/\./g, "/");
- if(loc.indexOf(".html") < 0) loc += ".html";
- if(fragment.indexOf('@') > 0) loc += ("#" + fragment.split("@", 2)[1]);
- frames["template"].location.replace(loc);
- }
- else
- frames["template"].location.replace("package.html");
+
+ function extractLoc(fragment) {
+ var loc = fragment.split('@')[0].replace(/\./g, "/");
+ if (loc.indexOf(".html") < 0) {
+ loc += ".html";
+ }
+ return loc;
+ }
+
+ function extractMemberSig(fragment) {
+ var splitIdx = fragment.indexOf('@');
+ if (splitIdx < 0) {
+ return;
+ }
+ return fragment.substr(splitIdx + 1);
+ }
+
+ var fragment = location.hash.slice(1);
+ if (fragment) {
+ var locWithMemeberSig = extractLoc(fragment);
+ var memberSig = extractMemberSig(fragment);
+ if (memberSig) {
+ locWithMemeberSig += "#" + memberSig;
+ }
+ frames["template"].location.replace(locWithMemeberSig);
+ } else {
+ console.log("empty fragment detected");
+ frames["template"].location.replace("package.html");
+ }
}
// Set the url fragment according to the src of the iframe "template".
// iframe url = "scala/Either.html" => url fragment = "#scala.Either"
// iframe url = "scala/Either.html#isRight:Boolean" => url fragment = "#scala.Either@isRight:Boolean"
+// iframe url = "scalaz/iteratee/package.html#>@>[E,A]=scalaz.iteratee.package.Iteratee[E,A]" => fragment = "#scalaz.iteratee.package@>@>[E,A]=scalaz.iteratee.package.Iteratee[E,A]"
function setUrlFragmentFromFrameSrc() {
try {
var commonLength = location.pathname.lastIndexOf("/");
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/permalink.png b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/permalink.png
new file mode 100644
index 0000000000..d54bc93f6a
--- /dev/null
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/permalink.png
Binary files differ
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
index b066027f04..35f66cd5df 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.css
@@ -397,6 +397,37 @@ div.members > ol > li:last-child {
margin-bottom: 5px;
}
+#template .members li .permalink {
+ position: absolute;
+ top: 5px;
+ right: 5px;
+}
+
+#definition .permalink {
+ position: absolute;
+ top: 10px;
+ right: 15px;
+}
+
+#definition .permalink a {
+ color: #EBEBEB;
+}
+
+#template .members li .permalink,
+#definition .permalink a {
+ display: none;
+}
+
+#template .members li:hover .permalink,
+#definition:hover .permalink a {
+ display: block;
+}
+
+#template .members li .permalink a,
+#definition .permalink a {
+ text-decoration: none;
+ font-weight: bold;
+}
/* Comments text formating */
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
index 6d1caf6d50..1ebcb67f04 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js
@@ -1,23 +1,57 @@
// © 2009–2010 EPFL/LAMP
-// code by Gilles Dubochet with contributions by Pedro Furlanetto
+// code by Gilles Dubochet with contributions by Pedro Furlanetto and Marcin Kubala
$(document).ready(function(){
+ var controls = {
+ visibility: {
+ publicOnly: $("#visbl").find("> ol > li.public"),
+ all: $("#visbl").find("> ol > li.all")
+ }
+ };
+
// Escapes special characters and returns a valid jQuery selector
function escapeJquery(str){
- return str.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
+ return str.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=<>\|])/g, '\\$1');
}
- // highlight and jump to selected member
- if (window.location.hash) {
- var temp = window.location.hash.replace('#', '');
- var elem = '#'+escapeJquery(temp);
+ function toggleVisibilityFilter(ctrlToEnable, ctrToDisable) {
+ if (ctrlToEnable.hasClass("out")) {
+ ctrlToEnable.removeClass("out").addClass("in");
+ ctrToDisable.removeClass("in").addClass("out");
+ filter();
+ }
+ }
+
+ controls.visibility.publicOnly.click(function () {
+ toggleVisibilityFilter(controls.visibility.publicOnly, controls.visibility.all);
+ });
- window.scrollTo(0, 0);
- $(elem).parent().effect("highlight", {color: "#FFCC85"}, 3000);
- $('html,body').animate({scrollTop:$(elem).parent().offset().top}, 1000);
+ controls.visibility.all.click(function () {
+ toggleVisibilityFilter(controls.visibility.all, controls.visibility.publicOnly);
+ });
+
+ function exposeMember(jqElem) {
+ var jqElemParent = jqElem.parent(),
+ parentName = jqElemParent.attr("name"),
+ linearizationName = /^([^#]*)(#.*)?$/gi.exec(parentName)[1];
+
+ // switch visibility filter if necessary
+ if (jqElemParent.attr("visbl") == "prt") {
+ toggleVisibilityFilter(controls.visibility.all, controls.visibility.publicOnly);
+ }
+
+ // toggle appropriate linearization buttons
+ if (linearizationName) {
+ $("#linearization li.out[name='" + linearizationName + "']").removeClass("out").addClass("in");
+ }
+
+ filter();
+ window.scrollTo(0, 0);
+ jqElemParent.effect("highlight", {color: "#FFCC85"}, 3000);
+ $('html,body').animate({scrollTop: jqElemParent.offset().top}, 1000);
}
-
+
var isHiddenClass = function (name) {
return name == 'scala.Any' ||
name == 'scala.AnyRef';
@@ -97,7 +131,7 @@ $(document).ready(function(){
else if ($(this).hasClass("out")) {
$(this).removeClass("out");
$(this).addClass("in");
- };
+ }
filter();
});
@@ -109,7 +143,7 @@ $(document).ready(function(){
else if ($(this).hasClass("out")) {
$(this).removeClass("out");
$(this).addClass("in");
- };
+ }
filter();
});
@@ -147,32 +181,18 @@ $(document).ready(function(){
});
$("#visbl > ol > li.public").click(function() {
if ($(this).hasClass("out")) {
- $(this).removeClass("out").addClass("in");
- $("#visbl > ol > li.all").removeClass("in").addClass("out");
- filter();
- };
- })
- $("#visbl > ol > li.all").click(function() {
- if ($(this).hasClass("out")) {
- $(this).removeClass("out").addClass("in");
- $("#visbl > ol > li.public").removeClass("in").addClass("out");
- filter();
- };
- });
- $("#order > ol > li.alpha").click(function() {
- if ($(this).hasClass("out")) {
orderAlpha();
- };
+ }
})
$("#order > ol > li.inherit").click(function() {
if ($(this).hasClass("out")) {
orderInherit();
- };
+ }
});
$("#order > ol > li.group").click(function() {
if ($(this).hasClass("out")) {
orderGroup();
- };
+ }
});
$("#groupedMembers").hide();
@@ -181,7 +201,7 @@ $(document).ready(function(){
// Create tooltips
$(".extype").add(".defval").tooltip({
tip: "#tooltip",
- position:"top center",
+ position: "top center",
predelay: 500,
onBeforeShow: function(ev) {
$(this.getTip()).text(this.getTrigger().attr("name"));
@@ -233,6 +253,20 @@ $(document).ready(function(){
windowTitle();
if ($("#order > ol > li.group").length == 1) { orderGroup(); };
+
+ function findElementByHash(locationHash) {
+ var temp = locationHash.replace('#', '');
+ var memberSelector = '#' + escapeJquery(temp);
+ return $(memberSelector);
+ }
+
+ // highlight and jump to selected member
+ if (window.location.hash) {
+ var jqElem = findElementByHash(window.location.hash);
+ if (jqElem.length > 0) {
+ exposeMember(jqElem);
+ }
+ }
});
function orderAlpha() {
diff --git a/src/scalap/scala/tools/scalap/Arguments.scala b/src/scalap/scala/tools/scalap/Arguments.scala
index cb0a92b6b3..c375a5bac4 100644
--- a/src/scalap/scala/tools/scalap/Arguments.scala
+++ b/src/scalap/scala/tools/scalap/Arguments.scala
@@ -5,6 +5,7 @@
**
*/
+
package scala.tools.scalap
import scala.collection.mutable
diff --git a/src/scalap/scala/tools/scalap/ByteArrayReader.scala b/src/scalap/scala/tools/scalap/ByteArrayReader.scala
index 59f083ee76..cf160871dd 100644
--- a/src/scalap/scala/tools/scalap/ByteArrayReader.scala
+++ b/src/scalap/scala/tools/scalap/ByteArrayReader.scala
@@ -5,7 +5,10 @@
**
*/
-package scala.tools.scalap
+
+package scala
+package tools.scalap
+
class ByteArrayReader(content: Array[Byte]) {
@@ -101,6 +104,9 @@ class ByteArrayReader(content: Array[Byte]) {
def getDouble(bp: Int): Double = java.lang.Double.longBitsToDouble(getLong(bp))
/** skip next 'n' bytes
- */
- def skip(n: Int): Unit = bp += n
+ */
+ def skip(n: Int) {
+ bp += n
+ }
+
}
diff --git a/src/scalap/scala/tools/scalap/Classfile.scala b/src/scalap/scala/tools/scalap/Classfile.scala
index d9d264bbbf..f62df285f9 100644
--- a/src/scalap/scala/tools/scalap/Classfile.scala
+++ b/src/scalap/scala/tools/scalap/Classfile.scala
@@ -5,8 +5,10 @@
**
*/
+
package scala.tools.scalap
+
class Classfile(in: ByteArrayReader) {
import Classfiles._
diff --git a/src/scalap/scala/tools/scalap/Classfiles.scala b/src/scalap/scala/tools/scalap/Classfiles.scala
index 982a83cfa0..9295dd7aff 100644
--- a/src/scalap/scala/tools/scalap/Classfiles.scala
+++ b/src/scalap/scala/tools/scalap/Classfiles.scala
@@ -5,8 +5,10 @@
**
*/
+
package scala.tools.scalap
+
object Classfiles {
final val JAVA_MAGIC = 0xCAFEBABE
final val JAVA_MAJOR_VERSION = 45
diff --git a/src/scalap/scala/tools/scalap/CodeWriter.scala b/src/scalap/scala/tools/scalap/CodeWriter.scala
index 21c4399d5c..168050096d 100644
--- a/src/scalap/scala/tools/scalap/CodeWriter.scala
+++ b/src/scalap/scala/tools/scalap/CodeWriter.scala
@@ -6,9 +6,13 @@
*/
-package scala.tools.scalap
+package scala
+package tools.scalap
-class CodeWriter(writer: java.io.Writer) {
+import java.io._
+
+
+class CodeWriter(writer: Writer) {
private val nl = scala.compat.Platform.EOL
private var step = " "
diff --git a/src/scalap/scala/tools/scalap/Decode.scala b/src/scalap/scala/tools/scalap/Decode.scala
index 69325c1ec8..76ce3f4173 100644
--- a/src/scalap/scala/tools/scalap/Decode.scala
+++ b/src/scalap/scala/tools/scalap/Decode.scala
@@ -5,14 +5,17 @@
**
*/
-package scala.tools.scalap
+// $Id$
-import scala.tools.scalap.scalasig._
+package scala.tools.scalap
-import scala.reflect.internal.util.ScalaClassLoader
+import scala.tools.scalap.scalax.rules.scalasig._
+import scala.tools.nsc.util.ScalaClassLoader
+import scala.tools.nsc.util.ScalaClassLoader.appLoader
import scala.reflect.internal.pickling.ByteCodecs
import ClassFileParser.{ ConstValueIndex, Annotation }
+import Main.{ SCALA_SIG, SCALA_SIG_ANNOTATION, BYTES_VALUE }
/** Temporary decoder. This would be better off in the scala.tools.nsc
* but right now the compiler won't acknowledge scala.tools.scalap
@@ -28,7 +31,7 @@ object Decode {
/** Return the classfile bytes representing the scala sig classfile attribute.
* This has been obsoleted by the switch to annotations.
*/
- def scalaSigBytes(name: String): Option[Array[Byte]] = scalaSigBytes(name, ScalaClassLoader.appLoader)
+ def scalaSigBytes(name: String): Option[Array[Byte]] = scalaSigBytes(name, appLoader)
def scalaSigBytes(name: String, classLoader: ScalaClassLoader): Option[Array[Byte]] = {
val bytes = classLoader.classBytes(name)
val reader = new ByteArrayReader(bytes)
@@ -36,16 +39,17 @@ object Decode {
cf.scalaSigAttribute map (_.data)
}
- /** Return the bytes representing the annotation. */
- def scalaSigAnnotationBytes(name: String): Option[Array[Byte]] = scalaSigAnnotationBytes(name, ScalaClassLoader.appLoader)
+ /** Return the bytes representing the annotation
+ */
+ def scalaSigAnnotationBytes(name: String): Option[Array[Byte]] = scalaSigAnnotationBytes(name, appLoader)
def scalaSigAnnotationBytes(name: String, classLoader: ScalaClassLoader): Option[Array[Byte]] = {
val bytes = classLoader.classBytes(name)
val byteCode = ByteCode(bytes)
val classFile = ClassFileParser.parse(byteCode)
import classFile._
- classFile annotation Main.SCALA_SIG_ANNOTATION map { case Annotation(_, els) =>
- val bytesElem = els find (x => constant(x.elementNameIndex) == Main.BYTES_VALUE) getOrElse null
+ classFile annotation SCALA_SIG_ANNOTATION map { case Annotation(_, els) =>
+ val bytesElem = els find (x => constant(x.elementNameIndex) == BYTES_VALUE) getOrElse null
val _bytes = bytesElem.elementValue match { case ConstValueIndex(x) => constantWrapped(x) }
val bytes = _bytes.asInstanceOf[StringBytesPair].bytes
val length = ByteCodecs.decode(bytes)
@@ -54,7 +58,8 @@ object Decode {
}
}
- /** private[scala] so nobody gets the idea this is a supported interface. */
+ /** private[scala] so nobody gets the idea this is a supported interface.
+ */
private[scala] def caseParamNames(path: String): Option[List[String]] = {
val (outer, inner) = (path indexOf '$') match {
case -1 => (path, "")
@@ -62,7 +67,7 @@ object Decode {
}
for {
- clazz <- ScalaClassLoader.appLoader.tryToLoadClass[AnyRef](outer)
+ clazz <- appLoader.tryToLoadClass[AnyRef](outer)
ssig <- ScalaSigParser.parse(clazz)
}
yield {
@@ -80,10 +85,11 @@ object Decode {
}
}
- /** Returns a map of Alias -> Type for the given package. */
+ /** Returns a map of Alias -> Type for the given package.
+ */
private[scala] def typeAliases(pkg: String) = {
for {
- clazz <- ScalaClassLoader.appLoader.tryToLoadClass[AnyRef](pkg + ".package")
+ clazz <- appLoader.tryToLoadClass[AnyRef](pkg + ".package")
ssig <- ScalaSigParser.parse(clazz)
}
yield {
diff --git a/src/scalap/scala/tools/scalap/JavaWriter.scala b/src/scalap/scala/tools/scalap/JavaWriter.scala
index 1ba89e4702..772cf6eacd 100644
--- a/src/scalap/scala/tools/scalap/JavaWriter.scala
+++ b/src/scalap/scala/tools/scalap/JavaWriter.scala
@@ -5,11 +5,13 @@
**
*/
+
package scala.tools.scalap
+import java.io._
import scala.reflect.NameTransformer
-class JavaWriter(classfile: Classfile, writer: java.io.Writer) extends CodeWriter(writer) {
+class JavaWriter(classfile: Classfile, writer: Writer) extends CodeWriter(writer) {
val cf = classfile
diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala
index 44d7ef6a41..c72f416a89 100644
--- a/src/scalap/scala/tools/scalap/Main.scala
+++ b/src/scalap/scala/tools/scalap/Main.scala
@@ -5,17 +5,17 @@
**
*/
-package scala.tools.scalap
+package scala
+package tools.scalap
import java.io.{ PrintStream, OutputStreamWriter, ByteArrayOutputStream }
-
+import scala.reflect.NameTransformer
+import scalax.rules.scalasig._
import scala.tools.nsc.util.{ ClassPath, JavaClassPath }
-import scala.tools.nsc.util.ClassPath.DefaultJavaContext
+import scala.tools.util.PathResolver
+import ClassPath.DefaultJavaContext
import scala.tools.nsc.io.AbstractFile
-import scala.tools.scalap.scalasig._
-
-
/**The main object used to execute scalap on the command-line.
*
* @author Matthias Zenger, Stephane Micheloud, Burak Emir, Ilya Sergey
@@ -104,7 +104,7 @@ class Main {
// we have to encode every fragment of a name separately, otherwise the NameTransformer
// will encode using unicode escaping dot separators as well
// we can afford allocations because this is not a performance critical code
- classname.split('.').map(scala.reflect.NameTransformer.encode).mkString(".")
+ classname.split('.').map(NameTransformer.encode).mkString(".")
}
val cls = path.findClass(encName)
if (cls.isDefined && cls.get.binary.isDefined) {
@@ -185,7 +185,7 @@ object Main extends Main {
val cparg = List("-classpath", "-cp") map (arguments getArgument _) reduceLeft (_ orElse _)
val path = cparg match {
case Some(cp) => new JavaClassPath(DefaultJavaContext.classesInExpandedPath(cp), DefaultJavaContext)
- case _ => scala.tools.util.PathResolver.fromPathString(".") // include '.' in the default classpath SI-6669
+ case _ => PathResolver.fromPathString(".") // include '.' in the default classpath SI-6669
}
// print the classpath if output is verbose
if (verbose)
diff --git a/src/scalap/scala/tools/scalap/MetaParser.scala b/src/scalap/scala/tools/scalap/MetaParser.scala
index 324330466f..1ebf86268a 100644
--- a/src/scalap/scala/tools/scalap/MetaParser.scala
+++ b/src/scalap/scala/tools/scalap/MetaParser.scala
@@ -6,15 +6,17 @@
*/
-package scala.tools.scalap
+package scala
+package tools.scalap
+import java.util._
/** a parser class for parsing meta type information in classfiles
* generated by pico.
*/
class MetaParser(meta: String) {
- val scanner = new java.util.StringTokenizer(meta, "()[], \t<;", true)
+ val scanner = new StringTokenizer(meta, "()[], \t<;", true)
var token: String = _
val res = new StringBuffer
diff --git a/src/scalap/scala/tools/scalap/Properties.scala b/src/scalap/scala/tools/scalap/Properties.scala
index 432dd495e9..8f9a9d8606 100644
--- a/src/scalap/scala/tools/scalap/Properties.scala
+++ b/src/scalap/scala/tools/scalap/Properties.scala
@@ -9,7 +9,8 @@
package scala.tools.scalap
/** Loads decoder.properties from the jar. */
-object Properties extends scala.util.PropertiesTrait {
+object Properties extends scala.util.PropertiesTrait
+{
protected def propCategory = "decoder"
protected def pickJarBasedOn = classOf[Classfile]
}
diff --git a/src/scalap/scala/tools/scalap/rules/package.scala b/src/scalap/scala/tools/scalap/rules/package.scala
deleted file mode 100644
index dcd5f7ac00..0000000000
--- a/src/scalap/scala/tools/scalap/rules/package.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package scala.tools.scalap
-
-package object rules {
- // make some language features in this package compile without warning
- implicit def postfixOps = scala.language.postfixOps
-}
diff --git a/src/scalap/scala/tools/scalap/rules/Memoisable.scala b/src/scalap/scala/tools/scalap/scalax/rules/Memoisable.scala
index 418141bee7..bdd1761ed9 100644
--- a/src/scalap/scala/tools/scalap/rules/Memoisable.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/Memoisable.scala
@@ -10,7 +10,9 @@
//
// -----------------------------------------------------------------------------
-package scala.tools.scalap.rules
+package scala.tools.scalap
+package scalax
+package rules
import scala.collection.mutable
@@ -20,7 +22,7 @@ trait MemoisableRules extends Rules {
from[In] { in => in.memo(key, rule(in)) }
}
- override def ruleWithName[In, Out, A, X](name: String, f: In => Result[Out, A, X]) = super.ruleWithName(name, (in: In) => in match {
+ override def ruleWithName[In, Out, A, X](name: String, f: In => rules.Result[Out, A, X]) = super.ruleWithName(name, (in: In) => in match {
case s: Memoisable => s.memo(name, f(in))
case _ => f(in)
})
@@ -54,3 +56,6 @@ trait DefaultMemoisable extends Memoisable {
if(DefaultMemoisable.debug) println(key + " -> " + t + " (" + out + ")")
}
}
+
+
+
diff --git a/src/scalap/scala/tools/scalap/rules/Result.scala b/src/scalap/scala/tools/scalap/scalax/rules/Result.scala
index ae05416d7a..f37340e7b7 100644
--- a/src/scalap/scala/tools/scalap/rules/Result.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/Result.scala
@@ -10,7 +10,9 @@
//
// -----------------------------------------------------------------------------
-package scala.tools.scalap.rules;
+package scala.tools.scalap
+package scalax
+package rules;
/** Represents the combined value of two rules applied in sequence.
*
diff --git a/src/scalap/scala/tools/scalap/rules/Rule.scala b/src/scalap/scala/tools/scalap/scalax/rules/Rule.scala
index 0a00111f7a..307458fc7d 100644
--- a/src/scalap/scala/tools/scalap/rules/Rule.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/Rule.scala
@@ -10,7 +10,9 @@
//
// -----------------------------------------------------------------------------
-package scala.tools.scalap.rules
+package scala.tools.scalap
+package scalax
+package rules
/** A Rule is a function from some input to a Result. The result may be:
* <ul>
@@ -170,3 +172,6 @@ trait Choice[-In, +Out, +A, +X] extends Rule[In, Out, A, X] {
lazy val choices = Choice.this.choices ::: other :: Nil
}
}
+
+
+
diff --git a/src/scalap/scala/tools/scalap/rules/Rules.scala b/src/scalap/scala/tools/scalap/scalax/rules/Rules.scala
index bdcc81c22d..dd17c46f79 100644
--- a/src/scalap/scala/tools/scalap/rules/Rules.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/Rules.scala
@@ -11,8 +11,11 @@
// -----------------------------------------------------------------------------
package scala.tools.scalap
+package scalax
package rules
+import language.postfixOps
+
trait Name {
def name: String
override def toString = name
diff --git a/src/scalap/scala/tools/scalap/rules/SeqRule.scala b/src/scalap/scala/tools/scalap/scalax/rules/SeqRule.scala
index e96a38b6be..f3c0235b23 100644
--- a/src/scalap/scala/tools/scalap/rules/SeqRule.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/SeqRule.scala
@@ -10,7 +10,11 @@
//
// -----------------------------------------------------------------------------
-package scala.tools.scalap.rules
+package scala.tools.scalap
+package scalax
+package rules
+
+import language.postfixOps
/**
* A workaround for the difficulties of dealing with
@@ -47,7 +51,7 @@ class SeqRule[S, +A, +X](rule: Rule[S, S, A, X]) {
/** Creates a rule that always succeeds with a Boolean value.
* Value is 'true' if this rule succeeds, 'false' otherwise */
- def -? = ? map { _.isDefined }
+ def -? = ? map { _ isDefined }
def * = from[S] {
// tail-recursive function with reverse list accumulator
@@ -96,3 +100,4 @@ class SeqRule[S, +A, +X](rule: Rule[S, S, A, X]) {
in => rep(0, in)
}
}
+
diff --git a/src/scalap/scala/tools/scalap/scalasig/ClassFileParser.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
index 9bd8402ccc..cfd750055b 100644
--- a/src/scalap/scala/tools/scalap/scalasig/ClassFileParser.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ClassFileParser.scala
@@ -1,6 +1,11 @@
-package scala.tools.scalap.scalasig
+package scala.tools.scalap
+package scalax
+package rules
+package scalasig
-import scala.tools.scalap.rules.{ Success, Failure, ~, RulesWithState }
+import language.postfixOps
+
+import java.io.IOException
object ByteCode {
def apply(bytes: Array[Byte]) = new ByteCode(bytes, 0, bytes.length)
@@ -15,7 +20,7 @@ object ByteCode {
val bytes = new Array[Byte](rest)
while (rest > 0) {
val res = in.read(bytes, bytes.length - rest, rest)
- if (res == -1) throw new java.io.IOException("read error")
+ if (res == -1) throw new IOException("read error")
rest -= res
}
ByteCode(bytes)
@@ -26,7 +31,8 @@ object ByteCode {
}
}
-/** Represents a chunk of raw bytecode. Used as input for the parsers. */
+/** Represents a chunk of raw bytecode. Used as input for the parsers
+ */
class ByteCode(val bytes: Array[Byte], val pos: Int, val length: Int) {
assert(pos >= 0 && length >= 0 && pos + length <= bytes.length)
@@ -78,11 +84,11 @@ trait ByteCodeReader extends RulesWithState {
type S = ByteCode
type Parser[A] = Rule[A, String]
- val byte = apply(_.nextByte)
+ val byte = apply(_ nextByte)
val u1 = byte ^^ (_ & 0xFF)
- val u2 = bytes(2) ^^ (_.toInt)
- val u4 = bytes(4) ^^ (_.toInt) // should map to Long??
+ val u2 = bytes(2) ^^ (_ toInt)
+ val u4 = bytes(4) ^^ (_ toInt) // should map to Long??
def bytes(n: Int) = apply(_ next n)
}
@@ -93,7 +99,7 @@ object ClassFileParser extends ByteCodeReader {
val magicNumber = (u4 filter (_ == 0xCAFEBABE)) | error("Not a valid class file")
val version = u2 ~ u2 ^^ { case minor ~ major => (major, minor) }
- val constantPool = (u2 ^^ ConstantPool) >> repeatUntil(constantPoolEntry)(_.isFull)
+ val constantPool = (u2 ^^ ConstantPool) >> repeatUntil(constantPoolEntry)(_ isFull)
// NOTE currently most constants just evaluate to a string description
// TODO evaluate to useful values
@@ -238,3 +244,4 @@ case class ConstantPool(len: Int) {
this
}
}
+
diff --git a/src/scalap/scala/tools/scalap/scalasig/Flags.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Flags.scala
index b9925150d2..050317cb82 100644
--- a/src/scalap/scala/tools/scalap/scalasig/Flags.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Flags.scala
@@ -1,4 +1,7 @@
-package scala.tools.scalap.scalasig
+package scala.tools.scalap
+package scalax
+package rules
+package scalasig
trait Flags {
def hasFlag(flag: Long): Boolean
diff --git a/src/scalap/scala/tools/scalap/scalasig/ScalaSig.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala
index 311e4acd6f..e3076322dd 100644
--- a/src/scalap/scala/tools/scalap/scalasig/ScalaSig.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala
@@ -5,25 +5,27 @@
**
*/
-package scala.tools.scalap.scalasig
-import scala.language.implicitConversions
-
-import scala.reflect.internal.pickling.ByteCodecs
+package scala.tools.scalap
+package scalax
+package rules
+package scalasig
-import scala.tools.scalap.Main
-import scala.tools.scalap.rules._
+import scala.language.postfixOps
+import scala.language.implicitConversions
import ClassFileParser.{ ConstValueIndex, Annotation }
+import scala.reflect.internal.pickling.ByteCodecs
object ScalaSigParser {
+ import Main.{ SCALA_SIG, SCALA_SIG_ANNOTATION, BYTES_VALUE }
def scalaSigFromAnnotation(classFile: ClassFile): Option[ScalaSig] = {
import classFile._
- classFile.annotation(Main.SCALA_SIG_ANNOTATION) map {
+ classFile.annotation(SCALA_SIG_ANNOTATION) map {
case Annotation(_, elements) =>
- val bytesElem = elements.find(elem => constant(elem.elementNameIndex) == Main.BYTES_VALUE).get
+ val bytesElem = elements.find(elem => constant(elem.elementNameIndex) == BYTES_VALUE).get
val bytes = ((bytesElem.elementValue match {case ConstValueIndex(index) => constantWrapped(index)})
.asInstanceOf[StringBytesPair].bytes)
val length = ByteCodecs.decode(bytes)
@@ -33,7 +35,7 @@ object ScalaSigParser {
}
def scalaSigFromAttribute(classFile: ClassFile): Option[ScalaSig] =
- classFile.attribute(Main.SCALA_SIG).map(_.byteCode).map(ScalaSigAttributeParsers.parse)
+ classFile.attribute(SCALA_SIG).map(_.byteCode).map(ScalaSigAttributeParsers.parse)
def parse(classFile: ClassFile): Option[ScalaSig] = {
val scalaSig = scalaSigFromAttribute(classFile)
diff --git a/src/scalap/scala/tools/scalap/scalasig/ScalaSigPrinter.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala
index 5929e0f59f..dd17c39d84 100644
--- a/src/scalap/scala/tools/scalap/scalasig/ScalaSigPrinter.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala
@@ -5,14 +5,19 @@
**
*/
-package scala.tools.scalap.scalasig
-import scala.language.implicitConversions
+package scala.tools.scalap
+package scalax
+package rules
+package scalasig
+
+import language.postfixOps
import java.io.{PrintStream, ByteArrayOutputStream}
import java.util.regex.Pattern
-
-import scala.tools.scalap.rules.~
+import scala.tools.scalap.scalax.util.StringUtil
+import scala.reflect.NameTransformer
+import java.lang.String
class ScalaSigPrinter(stream: PrintStream, printPrivates: Boolean) {
import stream._
@@ -343,8 +348,8 @@ class ScalaSigPrinter(stream: PrintStream, printPrivates: Boolean) {
}
case "scala.<byname>" => "=> " + toString(typeArgs.head)
case _ => {
- val path = cutSubstring(symbol.path)(".package") //remove package object reference
- trimStart(processName(path) + typeArgString(typeArgs), "<empty>.")
+ val path = StringUtil.cutSubstring(symbol.path)(".package") //remove package object reference
+ StringUtil.trimStart(processName(path) + typeArgString(typeArgs), "<empty>.")
}
})
case TypeBoundsType(lower, upper) => {
@@ -389,7 +394,7 @@ class ScalaSigPrinter(stream: PrintStream, printPrivates: Boolean) {
def typeArgString(typeArgs: Seq[Type]): String =
if (typeArgs.isEmpty) ""
- else typeArgs.map(toString).map(trimStart(_, "=> ")).mkString("[", ", ", "]")
+ else typeArgs.map(toString).map(StringUtil.trimStart(_, "=> ")).mkString("[", ", ", "]")
def typeParamString(params: Seq[Symbol]): String =
if (params.isEmpty) ""
@@ -410,7 +415,7 @@ class ScalaSigPrinter(stream: PrintStream, printPrivates: Boolean) {
if (i > 0) name.substring(i + 2) else name
}
- private def processName(name: String) = {
+ def processName(name: String) = {
val stripped = stripPrivatePrefix(name)
val m = pattern.matcher(stripped)
var temp = stripped
@@ -420,15 +425,7 @@ class ScalaSigPrinter(stream: PrintStream, printPrivates: Boolean) {
temp = temp.replaceAll(re, _syms(re))
}
val result = temp.replaceAll(placeholderPattern, "_")
- scala.reflect.NameTransformer.decode(result)
+ NameTransformer.decode(result)
}
- private def trimStart(s: String, prefix: String) =
- if (s != null && s.startsWith(prefix)) s.substring(prefix.length) else s
-
- private def decapitalize(s: String) =
- java.beans.Introspector.decapitalize(s)
-
- private def cutSubstring(dom: String)(s: String) =
- if (dom != null && s != null) dom.replace(s, "") else dom
}
diff --git a/src/scalap/scala/tools/scalap/scalasig/SourceFileAttributeParser.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/SourceFileAttributeParser.scala
index 88d3d3b8b0..fc5a75c046 100644
--- a/src/scalap/scala/tools/scalap/scalasig/SourceFileAttributeParser.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/SourceFileAttributeParser.scala
@@ -1,4 +1,7 @@
-package scala.tools.scalap.scalasig
+package scala.tools.scalap
+package scalax
+package rules
+package scalasig
/**
* @author ilyas
@@ -13,12 +16,13 @@ object SourceFileAttributeParser extends ByteCodeReader {
/**
*
* SourceFile_attribute {
- u2 attribute_name_index;
- u4 attribute_length;
- u2 sourcefile_index;
+ u2 attribute_name_index;
+ u4 attribute_length;
+ u2 sourcefile_index;
}
*
* Contains only file index in ConstantPool, first two fields are already treated
* by {@link scalax.rules.scalasig.ClassFile.attribute#attribute}
*/
case class SourceFileInfo(sourceFileIndex: Int)
+
diff --git a/src/scalap/scala/tools/scalap/scalasig/Symbol.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Symbol.scala
index 0656938150..6c38687649 100644
--- a/src/scalap/scala/tools/scalap/scalasig/Symbol.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Symbol.scala
@@ -1,4 +1,7 @@
-package scala.tools.scalap.scalasig
+package scala.tools.scalap
+package scalax
+package rules
+package scalasig
import ScalaSigEntryParsers._
diff --git a/src/scalap/scala/tools/scalap/scalasig/Type.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Type.scala
index 97dc28d223..22d90325ce 100644
--- a/src/scalap/scala/tools/scalap/scalasig/Type.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/Type.scala
@@ -1,4 +1,7 @@
-package scala.tools.scalap.scalasig
+package scala.tools.scalap
+package scalax
+package rules
+package scalasig
abstract class Type
diff --git a/src/scalap/scala/tools/scalap/scalax/util/StringUtil.scala b/src/scalap/scala/tools/scalap/scalax/util/StringUtil.scala
new file mode 100644
index 0000000000..6077eded0f
--- /dev/null
+++ b/src/scalap/scala/tools/scalap/scalax/util/StringUtil.scala
@@ -0,0 +1,19 @@
+package scala.tools.scalap
+package scalax
+package util
+
+import java.beans.Introspector
+
+/**
+ * @author ilyas
+ */
+
+object StringUtil {
+
+ def trimStart(s: String, prefix: String) = if (s != null && s.startsWith(prefix)) s.substring(prefix.length) else s
+
+ def decapitalize(s: String) = Introspector.decapitalize(s)
+
+ def cutSubstring(dom: String)(s: String) = if (dom != null && s != null) dom.replace(s, "") else dom
+
+}