From 1ce11230546639fd4a06ab96d19784979a7a358c Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Mon, 26 Oct 2015 10:48:39 -0700 Subject: [PATCH] API only tracks declared type of self variable The only aspect of the self variable that's relevant for incremental compilation is its explicitly declared type, and only when it's different from the type of the class that declares it. Technically, any self type that's a super type of the class could be ignored, as it cannot affect external use (instantiation/subclassing) of the class. --- .../interface/src/main/scala/xsbt/ExtractAPI.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala index 945626e12..b410f7198 100644 --- a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala +++ b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala @@ -527,7 +527,16 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, s.fullName } } - private def selfType(in: Symbol, s: Symbol): xsbti.api.Type = processType(in, s.thisSym.typeOfThis) + + /* Representation for the self type of a class symbol `s`, or `emptyType` for an *unascribed* self variable (or no self variable at all). + Only the self variable's explicitly ascribed type is relevant for incremental compilation. */ + private def selfType(in: Symbol, s: Symbol): xsbti.api.Type = + // `sym.typeOfThis` is implemented as `sym.thisSym.info`, which ensures the *self* symbol is initialized (the type completer is run). + // We can safely avoid running the type completer for `thisSym` for *class* symbols where `thisSym == this`, + // as that invariant is established on completing the class symbol (`mkClassLike` calls `s.initialize` before calling us). + // Technically, we could even ignore a self type that's a supertype of the class's type, + // as it does not contribute any information relevant outside of the class definition. + if ((s.thisSym eq s) || s.typeOfThis == s.info) Constants.emptyType else processType(in, s.typeOfThis) def classLike(in: Symbol, c: Symbol): ClassLike = classLikeCache.getOrElseUpdate((in, c), mkClassLike(in, c)) private def mkClassLike(in: Symbol, c: Symbol): ClassLike = {