diff options
Diffstat (limited to 'src')
22 files changed, 129 insertions, 80 deletions
diff --git a/src/build/genprod.scala b/src/build/genprod.scala index ed436fe2e4..b470348e8c 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -123,7 +123,10 @@ object FunctionOne extends Function(1) { * def apply(x: Int): Int = x + 1 * } * assert(succ(0) == anonfun1(0)) - * """) + * """) + """ + * + * Note that the difference between `Function1` and [[scala.PartialFunction]] + * is that the latter can specify inputs which it will not handle.""" override def moreMethods = """ /** Composes two instances of Function1 in a new Function1, with this function applied last. @@ -178,13 +181,7 @@ class Function(val i: Int) extends Group("Function") with Arity { * * {{{ * object Main extends App {%s} - * }}} - * - * Note that `Function1` does not define a total function, as might - * be suggested by the existence of [[scala.PartialFunction]]. The only - * distinction between `Function1` and `PartialFunction` is that the - * latter can specify inputs which it will not handle. -""" + * }}}""" def toStr() = "\"" + ("<function%d>" format i) + "\"" def apply() = { diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 4430a84f06..3469726455 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1675,23 +1675,25 @@ class Global(var currentSettings: Settings, var reporter: Reporter) def getFile(clazz: Symbol, suffix: String): File = getFile(clazz.sourceFile, clazz.fullName split '.', suffix) private def writeICode() { - val printer = new icodes.TextPrinter(null, icodes.linearizer) - icodes.classes.values.foreach((cls) => { - 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") + val printer = new icodes.TextPrinter(writer = null, icodes.linearizer) + icodes.classes.values foreach { cls => + val file = { + val module = if (cls.symbol.hasModuleFlag) "$" else "" + val faze = if (settings.debug) phase.name else f"${phase.id}%02d" // avoid breaking windows build with long filename + getFile(cls.symbol, s"$module-$faze.icode") + } try { val stream = new FileOutputStream(file) printer.setWriter(new PrintWriter(stream, true)) printer.printClass(cls) - informProgress("wrote " + file) + informProgress(s"wrote $file") } catch { - case ex: IOException => - if (settings.debug) ex.printStackTrace() - globalError("could not write file " + file) + case e: IOException => + if (settings.debug) e.printStackTrace() + globalError(s"could not write file $file") } - }) + } } def createJavadoc = false } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala index 1b9fd5e298..fffb9286b8 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala @@ -213,6 +213,35 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes { assert(!primitiveTypeMap.contains(sym) || isCompilingPrimitive, sym) } + /** + * Reconstruct the classfile flags from a Java defined class symbol. + * + * The implementation of this method is slightly different that [[javaFlags]]. The javaFlags + * method is primarily used to map Scala symbol flags to sensible classfile flags that are used + * in the generated classfiles. For example, all classes emitted by the Scala compiler have + * ACC_PUBLIC. + * + * When building a [[ClassBType]] from a Java class symbol, the flags in the type's `info` have + * to correspond exactly to the flags in the classfile. For example, if the class is package + * protected (i.e., it doesn't have the ACC_PUBLIC flag), this needs to be reflected in the + * ClassBType. For example, the inliner needs the correct flags for access checks. + * + * Class flags are listed here: + * https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1-200-E.1 + */ + private def javaClassfileFlags(classSym: Symbol): Int = { + assert(classSym.isJava, s"Expected Java class symbol, got ${classSym.fullName}") + import asm.Opcodes._ + GenBCode.mkFlags( + if (classSym.isPublic) ACC_PUBLIC else 0, + if (classSym.isFinal) ACC_FINAL else 0, + if (classSym.isInterface) ACC_INTERFACE else ACC_SUPER, // see the link above. javac does the same: ACC_SUPER for all classes, but not interfaces. + if (classSym.hasAbstractFlag) ACC_ABSTRACT else 0, + if (classSym.isArtifact) ACC_SYNTHETIC else 0, + if (classSym.hasEnumFlag) ACC_ENUM else 0 + ) + } + private def setClassInfo(classSym: Symbol, classBType: ClassBType): ClassBType = { val superClassSym = if (classSym.isImplClass) ObjectClass else classSym.superClass assert( @@ -230,7 +259,10 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes { val interfaces = implementedInterfaces(classSym).map(classBTypeFromSymbol) - val flags = javaFlags(classSym) + val flags = { + if (classSym.isJava) javaClassfileFlags(classSym) // see comment on javaClassfileFlags + else javaFlags(classSym) + } /* The InnerClass table of a class C must contain all nested classes of C, even if they are only * declared but not otherwise referenced in C (from the bytecode or a method / field signature). diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala index 814c78b69c..b4f091b37f 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala @@ -562,38 +562,62 @@ class Inliner[BT <: BTypes](val btypes: BT) { * @param memberDeclClass The class in which the member is declared (A) * @param memberRefClass The class used in the member reference (B) * + * (B0) JVMS 5.4.3.2 / 5.4.3.3: when resolving a member of class C in D, the class C is resolved + * first. According to 5.4.3.1, this requires C to be accessible in D. + * * JVMS 5.4.4 summary: A field or method R is accessible to a class D (destinationClass) iff * (B1) R is public * (B2) R is protected, declared in C (memberDeclClass) and D is a subclass of C. * If R is not static, R must contain a symbolic reference to a class T (memberRefClass), * such that T is either a subclass of D, a superclass of D, or D itself. + * Also (P) needs to be satisfied. * (B3) R is either protected or has default access and declared by a class in the same * run-time package as D. + * If R is protected, also (P) needs to be satisfied. * (B4) R is private and is declared in D. + * + * (P) When accessing a protected instance member, the target object on the stack (the receiver) + * has to be a subtype of D (destinationClass). This is enforced by classfile verification + * (https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.8). + * + * TODO: we cannot currently implement (P) because we don't have the necessary information + * available. Once we have a type propagation analysis implemented, we can extract the receiver + * type from there (https://github.com/scala-opt/scala/issues/13). */ def memberIsAccessible(memberFlags: Int, memberDeclClass: ClassBType, memberRefClass: ClassBType): Either[OptimizerWarning, Boolean] = { // TODO: B3 requires "same run-time package", which seems to be package + classloader (JMVS 5.3.). is the below ok? def samePackageAsDestination = memberDeclClass.packageInternalName == destinationClass.packageInternalName - - val key = (ACC_PUBLIC | ACC_PROTECTED | ACC_PRIVATE) & memberFlags - key match { - case ACC_PUBLIC => // B1 - Right(true) - - case ACC_PROTECTED => // B2 - tryEither { - val condB2 = destinationClass.isSubtypeOf(memberDeclClass).orThrow && { - val isStatic = (ACC_STATIC & memberFlags) != 0 - isStatic || memberRefClass.isSubtypeOf(destinationClass).orThrow || destinationClass.isSubtypeOf(memberRefClass).orThrow + def targetObjectConformsToDestinationClass = false // needs type propagation analysis, see above + + def memberIsAccessibleImpl = { + val key = (ACC_PUBLIC | ACC_PROTECTED | ACC_PRIVATE) & memberFlags + key match { + case ACC_PUBLIC => // B1 + Right(true) + + case ACC_PROTECTED => // B2 + val isStatic = (ACC_STATIC & memberFlags) != 0 + tryEither { + val condB2 = destinationClass.isSubtypeOf(memberDeclClass).orThrow && { + isStatic || memberRefClass.isSubtypeOf(destinationClass).orThrow || destinationClass.isSubtypeOf(memberRefClass).orThrow + } + Right( + (condB2 || samePackageAsDestination /* B3 (protected) */) && + (isStatic || targetObjectConformsToDestinationClass) // (P) + ) } - Right(condB2 || samePackageAsDestination) // B3 (protected) - } - case 0 => // B3 (default access) - Right(samePackageAsDestination) + case 0 => // B3 (default access) + Right(samePackageAsDestination) + + case ACC_PRIVATE => // B4 + Right(memberDeclClass == destinationClass) + } + } - case ACC_PRIVATE => // B4 - Right(memberDeclClass == destinationClass) + classIsAccessible(memberDeclClass) match { // B0 + case Right(true) => memberIsAccessibleImpl + case r => r } } diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index 8f6fc65706..8cd2a14066 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -773,7 +773,7 @@ abstract class Inliners extends SubComponent { staleOut += block - tfa.remainingCALLs.remove(instr) // this bookkpeeping is done here and not in MTFAGrowable.reinit due to (1st) convenience and (2nd) necessity. + tfa.remainingCALLs.remove(instr) // this bookkeeping is done here and not in MTFAGrowable.reinit due to (1st) convenience and (2nd) necessity. tfa.isOnWatchlist.remove(instr) // ditto tfa.warnIfInlineFails.remove(instr) diff --git a/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala b/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala index 84e21a3ccd..85c7c3c843 100644 --- a/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala +++ b/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala @@ -61,7 +61,7 @@ object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory { } /** - * This type of classpath is closly related to the support for JSR-223. + * This type of classpath is closely related to the support for JSR-223. * Its usage can be observed e.g. when running: * jrunscript -classpath scala-compiler.jar;scala-reflect.jar;scala-library.jar -l scala * with a particularly prepared scala-library.jar. It should have all classes listed in the manifest like e.g. this entry: diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index a22428075c..4f5589fd7c 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -373,7 +373,7 @@ abstract class SymbolLoaders { protected def doComplete(root: Symbol) { root.sourceModule.initialize } } - /** used from classfile parser to avoid cyclies */ + /** used from classfile parser to avoid cycles */ var parentsLevel = 0 var pendingLoadActions: List[() => Unit] = Nil } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala index 6302e34ac9..451b72d498 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala @@ -248,7 +248,7 @@ trait MatchTranslation { if (caseDefs forall treeInfo.isCatchCase) caseDefs else { val swatches = { // switch-catches - // SI-7459 must duplicate here as we haven't commited to switch emission, and just figuring out + // SI-7459 must duplicate here as we haven't committed to switch emission, and just figuring out // if we can ends up mutating `caseDefs` down in the use of `substituteSymbols` in // `TypedSubstitution#Substitution`. That is called indirectly by `emitTypeSwitch`. val bindersAndCases = caseDefs.map(_.duplicate) map { caseDef => diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 27a574a449..b5129af9ec 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4443,7 +4443,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def onError(typeErrors: Seq[AbsTypeError], warnings: Seq[(Position, String)]): Tree = { if (Statistics.canEnable) Statistics.stopTimer(failedApplyNanos, start) - // If the problem is with raw types, copnvert to existentials and try again. + // If the problem is with raw types, convert to existentials and try again. // See #4712 for a case where this situation arises, if ((fun.symbol ne null) && fun.symbol.isJavaDefined) { val newtpe = rawToExistential(fun.tpe) @@ -4988,7 +4988,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper TypeTreeWithDeferredRefCheck(){ () => // wrap the tree and include the bounds check -- refchecks will perform this check (that the beta reduction was indeed allowed) and unwrap // we can't simply use original in refchecks because it does not contains types - // (and the only typed trees we have have been mangled so they're not quite the original tree anymore) + // (and the only typed trees we have been mangled so they're not quite the original tree anymore) checkBounds(result, tpt1.tpe.prefix, tpt1.symbol.owner, tpt1.symbol.typeParams, argtypes, "") result // you only get to see the wrapped tree after running this check :-p } setType (result.tpe) setPos(result.pos) diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index e13aaad7bc..15d0f14938 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ // GENERATED CODE: DO NOT EDIT. -// genprod generated these sources at: Sun Sep 15 20:42:00 CEST 2013 +// genprod generated these sources at: Mon Jun 08 18:05:40 CEST 2015 package scala @@ -26,12 +26,6 @@ package scala * assert(javaVersion() == anonfun0()) * } * }}} - * - * Note that `Function1` does not define a total function, as might - * be suggested by the existence of [[scala.PartialFunction]]. The only - * distinction between `Function1` and `PartialFunction` is that the - * latter can specify inputs which it will not handle. - */ trait Function0[@specialized(Specializable.Primitives) +R] extends AnyRef { self => /** Apply the body of this function to the arguments. diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index 620dcc19aa..572901c6f3 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -25,11 +25,8 @@ package scala * } * }}} * - * Note that `Function1` does not define a total function, as might - * be suggested by the existence of [[scala.PartialFunction]]. The only - * distinction between `Function1` and `PartialFunction` is that the - * latter can specify inputs which it will not handle. - + * Note that the difference between `Function1` and [[scala.PartialFunction]] + * is that the latter can specify inputs which it will not handle. */ @annotation.implicitNotFound(msg = "No implicit view available from ${T1} => ${R}.") trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double) +R] extends AnyRef { self => diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index 5690adb56a..e2c094ea40 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -25,12 +25,6 @@ package scala * assert(max(0, 1) == anonfun2(0, 1)) * } * }}} - * - * Note that `Function1` does not define a total function, as might - * be suggested by the existence of [[scala.PartialFunction]]. The only - * distinction between `Function1` and `PartialFunction` is that the - * latter can specify inputs which it will not handle. - */ trait Function2[@specialized(scala.Int, scala.Long, scala.Double) -T1, @specialized(scala.Int, scala.Long, scala.Double) -T2, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double) +R] extends AnyRef { self => /** Apply the body of this function to the arguments. diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala index f1ac161e9a..28e56a6d87 100644 --- a/src/library/scala/collection/immutable/NumericRange.scala +++ b/src/library/scala/collection/immutable/NumericRange.scala @@ -12,6 +12,9 @@ package immutable import mutable.{ Builder, ListBuffer } +// TODO: Now the specialization exists there is no clear reason to have +// separate classes for Range/NumericRange. Investigate and consolidate. + /** `NumericRange` is a more generic version of the * `Range` class which works with arbitrary types. * It must be supplied with an `Integral` implementation of the @@ -28,9 +31,6 @@ import mutable.{ Builder, ListBuffer } * assert(r1 sameElements r2.map(_ - veryBig)) * }}} * - * TODO: Now the specialization exists there is no clear reason to have - * separate classes for Range/NumericRange. Investigate and consolidate. - * * @author Paul Phillips * @version 2.8 * @define Coll `NumericRange` @@ -266,7 +266,7 @@ object NumericRange { // Numbers may be big. val one = num.one val limit = num.fromInt(Int.MaxValue) - def check(t: T): T = + def check(t: T): T = if (num.gt(t, limit)) throw new IllegalArgumentException("More than Int.MaxValue elements.") else t // If the range crosses zero, it might overflow when subtracted diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index cf7b7e272a..7edd36dc22 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -1180,7 +1180,13 @@ object Stream extends SeqFactory[Stream] { * to streams. */ class ConsWrapper[A](tl: => Stream[A]) { + /** Construct a stream consisting of a given first element followed by elements + * from a lazily evaluated Stream. + */ def #::(hd: A): Stream[A] = cons(hd, tl) + /** Construct a stream consisting of the concatenation of the given stream and + * a lazily evaluated Stream. + */ def #:::(prefix: Stream[A]): Stream[A] = prefix append tl } diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index d6e2963ad8..6bb35606a6 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -49,7 +49,7 @@ object BigDecimal { /** Constructs a `BigDecimal` using the decimal text representation of `Double` value `d`, rounding if necessary. */ def decimal(d: Double, mc: MathContext): BigDecimal = - new BigDecimal(new BigDec(java.lang.Double.toString(d), mc)) + new BigDecimal(new BigDec(java.lang.Double.toString(d), mc), mc) /** Constructs a `BigDecimal` using the decimal text representation of `Double` value `d`. */ def decimal(d: Double): BigDecimal = decimal(d, defaultMathContext) @@ -59,7 +59,7 @@ object BigDecimal { * `0.1 != 0.1f`. */ def decimal(f: Float, mc: MathContext): BigDecimal = - new BigDecimal(new BigDec(java.lang.Float.toString(f), mc)) + new BigDecimal(new BigDec(java.lang.Float.toString(f), mc), mc) /** Constructs a `BigDecimal` using the decimal text representation of `Float` value `f`. * Note that `BigDecimal.decimal(0.1f) != 0.1f` since equality agrees with the `Double` representation, and diff --git a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala index 74310e1c34..1ba014d19d 100644 --- a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala +++ b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala @@ -60,7 +60,7 @@ trait AnnotationCheckers { * mode (see method adapt in trait Typers). * * An implementation cannot rely on canAdaptAnnotations being called before. If the implementing - * class cannot do the adaptiong, it should return the tree unchanged. + * class cannot do the adapting, it should return the tree unchanged. */ @deprecated("Create an AnalyzerPlugin and use adaptAnnotations", "2.10.1") def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = tree diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index abe966920b..285d59c5e2 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -987,7 +987,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => || isLocalToBlock ) ) - /** Is this symbol effectively final or a concrete term member of sealed class whose childred do not override it */ + /** Is this symbol effectively final or a concrete term member of sealed class whose children do not override it */ final def isEffectivelyFinalOrNotOverridden: Boolean = isEffectivelyFinal || (isTerm && !isDeferred && isNotOverridden) /** Is this symbol owned by a package? */ diff --git a/src/scaladoc/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala index 44683f1755..067b2b2c29 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Settings.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala @@ -143,7 +143,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) "dot" // by default, just pick up the system-wide dot ) - /** The maxium nuber of normal classes to show in the diagram */ + /** The maximum number of normal classes to show in the diagram */ val docDiagramsMaxNormalClasses = IntSetting( "-diagrams-max-classes", "The maximum number of superclasses or subclasses to show in a diagram", @@ -152,7 +152,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) _ => None ) - /** The maxium nuber of implcit classes to show in the diagram */ + /** The maximum number of implicit classes to show in the diagram */ val docDiagramsMaxImplicitClasses = IntSetting( "-diagrams-max-implicits", "The maximum number of implicitly converted classes to show in a diagram", 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 c384ed7034..81036b4908 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala @@ -177,7 +177,6 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp <li class="hideall out"><span>Hide All</span></li> <li class="showall in"><span>Show all</span></li> </ol> - <a href="http://docs.scala-lang.org/overviews/scaladoc/usage.html#members" target="_blank">Learn more about member selection</a> </div> } { diff --git a/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala index 7fe8903c76..90de51d763 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/Entity.scala @@ -298,7 +298,7 @@ trait DocTemplateEntity extends MemberTemplateEntity { /** The shadowing information for the implicitly added members */ def implicitsShadowing: Map[MemberEntity, ImplicitMemberShadowing] - /** Classes that can be implcitly converted to this class */ + /** Classes that can be implicitly converted to this class */ def incomingImplicitlyConvertedClasses: List[(DocTemplateEntity, ImplicitConversion)] /** Classes to which this class can be implicitly converted to @@ -484,10 +484,10 @@ trait ImplicitConversion { /** The entity for the method that performed the conversion, if it's documented (or just its name, otherwise) */ def convertorMethod: Either[MemberEntity, String] - /** A short name of the convertion */ + /** A short name of the conversion */ def conversionShortName: String - /** A qualified name uniquely identifying the convertion (currently: the conversion method's qualified name) */ + /** A qualified name uniquely identifying the conversion (currently: the conversion method's qualified name) */ def conversionQualifiedName: String /** The entity that performed the conversion */ diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index f984b4579f..db39d059d7 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -90,8 +90,12 @@ trait ModelFactoryImplicitSupport { else { val context: global.analyzer.Context = global.analyzer.rootContext(NoCompilationUnit) - val results = global.analyzer.allViewsFrom(sym.tpe_*, context, sym.typeParams) + val results = global.analyzer.allViewsFrom(sym.tpe_*, context, sym.typeParams) ++ + global.analyzer.allViewsFrom(byNameType(sym.tpe_*), context, sym.typeParams) var conversions = results.flatMap(result => makeImplicitConversion(sym, result._1, result._2, context, inTpl)) + //debug(results.mkString("All views\n ", "\n ", "\n")) + //debug(conversions.mkString("Conversions\n ", "\n ", "\n")) + // also keep empty conversions, so they appear in diagrams // conversions = conversions.filter(!_.members.isEmpty) @@ -193,7 +197,7 @@ trait ModelFactoryImplicitSupport { List(new ImplicitConversionImpl(sym, result.tree.symbol, toType, constraints, inTpl)) } catch { case i: ImplicitNotFound => - //println(" Eliminating: " + toType) + //debug(s" Eliminating: $toType") Nil } } @@ -396,7 +400,7 @@ trait ModelFactoryImplicitSupport { def isHiddenConversion = settings.hiddenImplicits(conversionQualifiedName) - override def toString = "Implcit conversion from " + sym.tpe + " to " + toType + " done by " + convSym + override def toString = "Implicit conversion from " + sym.tpe + " to " + toType + " done by " + convSym } /* ========================= HELPER METHODS ========================== */ @@ -475,7 +479,7 @@ trait ModelFactoryImplicitSupport { } /** - * Make implicits explicit - Not used curently + * Make implicits explicit - Not used currently */ // object implicitToExplicit extends TypeMap { // def apply(tp: Type): Type = mapOver(tp) match { @@ -557,7 +561,7 @@ trait ModelFactoryImplicitSupport { * * The trick here is that the resultType does not matter - the condition for removal it that paramss have the same * structure (A => B => C may not override (A, B) => C) and that all the types involved are - * of the implcit conversion's member are subtypes of the parent members' parameters */ + * of the implicit conversion's member are subtypes of the parent members' parameters */ def isDistinguishableFrom(t1: Type, t2: Type): Boolean = { // Vlad: I tried using matches but it's not exactly what we need: // (p: AnyRef)AnyRef matches ((t: String)AnyRef returns false -- but we want that to be true diff --git a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala index 87d7ece8f2..093899231e 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala @@ -51,7 +51,7 @@ trait DiagramFactory extends DiagramDirectiveParser { case p: (TemplateEntity, TypeEntity) if !classExcluded(p._1) => NormalNode(p._2, Some(p._1))() }.reverse - // incoming implcit conversions + // incoming implicit conversions lazy val incomingImplicitNodes = tpl.incomingImplicitlyConvertedClasses.map { case (incomingTpl, conv) => ImplicitNode(makeType(incomingTpl.sym.tpe, tpl), Some(incomingTpl))(implicitTooltip(from=incomingTpl, to=tpl, conv=conv)) |