@@ -163,7 +163,23 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
163163 */
164164 class Worker1 (needsOutFolder : Boolean ) {
165165
166- val caseInsensitively = scala.collection.mutable.HashMap .empty[String , Symbol ]
166+ private val lowerCaseNames = mutable.HashMap .empty[String , Symbol ]
167+ private def checkForCaseConflict (javaClassName : String , classSymbol : Symbol ) = {
168+ val lowerCaseName = javaClassName.toLowerCase
169+ lowerCaseNames.get(lowerCaseName) match {
170+ case None =>
171+ lowerCaseNames.put(lowerCaseName, classSymbol)
172+ case Some (dupClassSym) =>
173+ // Order is not deterministic so we enforce lexicographic order between the duplicates for error-reporting
174+ val (cl1, cl2) =
175+ if (classSymbol.effectiveName.toString < dupClassSym.effectiveName.toString) (classSymbol, dupClassSym)
176+ else (dupClassSym, classSymbol)
177+ ctx.atPhase(ctx.typerPhase) { implicit ctx =>
178+ ctx.warning(s " ${cl1.show} differs only in case from ${cl2.showLocated}. " +
179+ " Such classes will overwrite one another on case-insensitive filesystems." , cl1.pos)
180+ }
181+ }
182+ }
167183
168184 def run (): Unit = {
169185 while (true ) {
@@ -193,30 +209,6 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
193209 val Item1 (arrivalPos, cd, cunit) = item
194210 val claszSymbol = cd.symbol
195211
196- // GenASM checks this before classfiles are emitted, https://github.com/scala/scala/commit/e4d1d930693ac75d8eb64c2c3c69f2fc22bec739
197- def checkName (claszSymbol : Symbol ): Unit = {
198- val lowercaseJavaClassName = claszSymbol.effectiveName.toString.toLowerCase
199- caseInsensitively.get(lowercaseJavaClassName) match {
200- case None =>
201- caseInsensitively.put(lowercaseJavaClassName, claszSymbol)
202- case Some (dupClassSym) =>
203- if (claszSymbol.effectiveName.toString != dupClassSym.effectiveName.toString) {
204- // Order is not deterministic so we enforce lexicographic order between the duplicates for error-reporting
205- val (cl1, cl2) =
206- if (claszSymbol.effectiveName.toString < dupClassSym.effectiveName.toString) (claszSymbol, dupClassSym)
207- else (dupClassSym, claszSymbol)
208- ctx.warning(s " Class ${cl1.effectiveName} differs only in case from ${cl2.effectiveName}. " +
209- " Such classes will overwrite one another on case-insensitive filesystems." , cl1.pos)
210- }
211- }
212- }
213- checkName(claszSymbol)
214- if (int.symHelper(claszSymbol).isModuleClass) {
215- val companionModule = claszSymbol.companionModule
216- if (int.symHelper(companionModule.owner).isPackageClass)
217- checkName(companionModule)
218- }
219-
220212 // -------------- mirror class, if needed --------------
221213 val mirrorC =
222214 if (int.symHelper(claszSymbol).isTopLevelModuleClass) {
@@ -263,6 +255,7 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
263255 val classFiles = classNodes.map(cls =>
264256 if (outF != null && cls != null ) {
265257 try {
258+ checkForCaseConflict(cls.name, claszSymbol)
266259 getFileForClassfile(outF, cls.name, " .class" )
267260 } catch {
268261 case e : FileConflictException =>
@@ -272,7 +265,7 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
272265 } else null
273266 )
274267
275- // ----------- sbt's callbacks
268+ // ----------- compiler and sbt's callbacks
276269
277270 val (fullClassName, isLocal) = ctx.atPhase(ctx.sbtExtractDependenciesPhase) { implicit ctx =>
278271 (ExtractDependencies .classNameAsString(claszSymbol), claszSymbol.isLocal)
0 commit comments