<NME> GlobalScope.kt
<BEF> package org.elm.lang.core.resolve.scope

import com.intellij.openapi.util.Key
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.ParameterizedCachedValue
import org.elm.lang.core.lookup.ClientLocation
import org.elm.lang.core.psi.ElmFile
import org.elm.lang.core.psi.ElmNamedElement
import org.elm.lang.core.psi.elements.ElmModuleDeclaration
import org.elm.lang.core.psi.globalModificationTracker
import org.elm.lang.core.stubs.index.ElmModulesIndex
class GlobalScope(val project: Project) {

    companion object {
        fun implicitlyImportsModule(moduleDecl: ElmModuleDeclaration) =
                moduleDecl.elmFile.isCore() && defaultImports.contains(moduleDecl.name)

        /**
         * Modules that the Elm compiler treats as being implicitly imported.
class GlobalScope private constructor(private val clientFile: ElmFile) {

    companion object {

        fun forElmFile(elmFile: ElmFile): GlobalScope? {
            if (elmFile.elmProject?.isCore() != false) {
                // The `elm/core` standard library does not have an implicit global scope. It must explicitly
                "Tuple",
                "Debug",
                "Platform",
                "Platform.Cmd",
                "Platform.Sub"
        )

        /**
         */
        val defaultImports = listOf(
                "Basics",
                "Char",
                "List",
                "Maybe",
                "Result",
                "String",
                "Tuple",
                "Debug",
                "Platform",
                "Platform.Cmd",
                "Platform.Sub"
        )

        val defaultAliases = mapOf(
                "Cmd" to "Platform.Cmd",
                "Sub" to "Platform.Sub"
        )

        /**
         * Values and Types that are built-in to the Elm compiler. Any occurrences of
         * these symbols should be treated as always resolved.
         */
        val builtInValues = emptySet<String>()

        val builtInTypes = setOf("List")

        val allBuiltInSymbols = builtInValues.union(builtInTypes)

        fun implicitModulesMatching(name: String, clientFile: ElmFile): List<ElmModuleDeclaration> {
            val implicitModuleName = when (name) {
                in defaultImports -> name
                in defaultAliases.keys -> defaultAliases[name]
                else -> null
            } ?: return emptyList()

            return ElmModulesIndex.getAll(listOf(implicitModuleName), clientFile)
                    .filter { it.elmFile.isCore() }
        }


        private fun produceVisibleValues(clientFile: ClientLocation): List<ElmNamedElement> {
            fun helper(moduleName: String) =
                    ElmModulesIndex.get(moduleName, clientFile)
                            ?.let { ModuleScope.getDeclaredValues(it.elmFile) }

            val rest = mutableListOf<ElmNamedElement>()
            helper("Basics")?.list?.let { rest.addAll(it) }
            helper("List")?.get("::")?.let { rest.add(it) }
            return rest
        }


        // this function should also return List, but, unlike all the other global types, Elm doesn't
        // define it anywhere, so there's no element to return
        private fun produceVisibleTypes(location: ClientLocation): List<ElmNamedElement> {
            fun helper(moduleName: String) =
                    ElmModulesIndex.get(moduleName, location)
                            ?.let { ModuleScope.getDeclaredTypes(it.elmFile) }

            val rest = mutableListOf<ElmNamedElement>()
            helper("Basics")?.list?.let { rest.addAll(it) }
            helper("Char")?.get("Char")?.let { rest.add(it) }
            helper("Maybe")?.get("Maybe")?.let { rest.add(it) }
            helper("Result")?.get("Result")?.let { rest.add(it) }
            helper("String")?.get("String")?.let { rest.add(it) }
            helper("Platform")?.get("Program")?.let { rest.add(it) }
            helper("Platform.Cmd")?.get("Cmd")?.let { rest.add(it) }
            helper("Platform.Sub")?.get("Sub")?.let { rest.add(it) }
            return rest
        }

        private fun produceVisibleConstructors(location: ClientLocation): List<ElmNamedElement> {
            fun helper(moduleName: String) =
                    ElmModulesIndex.get(moduleName, location)
                            ?.let { ModuleScope.getDeclaredConstructors(it.elmFile) }

            val rest = mutableListOf<ElmNamedElement>()
            helper("Basics")?.list?.let { rest.addAll(it) }
            helper("Maybe")?.let { ctors ->
                ctors["Just"]?.let { rest.add(it) }
                ctors["Nothing"]?.let { rest.add(it) }
            }
            helper("Result")?.let { ctors ->
                ctors["Ok"]?.let { rest.add(it) }
                ctors["Err"]?.let { rest.add(it) }
            }
            return rest
        }
    }

    fun getVisibleValues(): List<ElmNamedElement> {
        val elmProject = clientFile.elmProject ?: return emptyList()
        return CachedValuesManager.getManager(clientFile.project).getParameterizedCachedValue(elmProject, VISIBLE_VALUES_KEY, {
            CachedValueProvider.Result.create(produceVisibleValues(it), it.globalModificationTracker)
        }, /*trackValue*/ false, /*parameter*/ clientFile)
    }


    fun getVisibleTypes(): List<ElmNamedElement> {
        val elmProject = clientFile.elmProject ?: return emptyList()
        return CachedValuesManager.getManager(clientFile.project).getParameterizedCachedValue(elmProject, VISIBLE_TYPES_KEY, {
            CachedValueProvider.Result.create(produceVisibleTypes(it), it.globalModificationTracker)
        }, /*trackValue*/ false, /*parameter*/ clientFile)
    }


    fun getVisibleConstructors(): List<ElmNamedElement> {
        val elmProject = clientFile.elmProject ?: return emptyList()
        return CachedValuesManager.getManager(clientFile.project).getParameterizedCachedValue(elmProject, VISIBLE_CTORS_KEY, {
            CachedValueProvider.Result.create(produceVisibleConstructors(it), it.globalModificationTracker)
        }, /*trackValue*/ false, /*parameter*/ clientFile)
    }
}

<MSG> Add hack for implicit, aliased import of Platform.Cmd and Platform.Sub

The Elm compiler implicitly adds the following import declarations to
every file:

import Platform.Cmd as Cmd
import Platform.Sub as Sub

To achieve this, I decided to fake-out the name of `Platform.Cmd` and
`Platform.Sub` module declarations, and then when trying to map a
module name to an actual ElmFile, undo the fake-out by re-introducing
the 'Platform.' prefix.

<DFF> @@ -13,8 +13,9 @@ import org.elm.lang.core.psi.elements.ElmModuleDeclaration
 class GlobalScope(val project: Project) {
 
     companion object {
-        fun implicitlyImportsModule(moduleDecl: ElmModuleDeclaration) =
-                moduleDecl.elmFile.isCore() && defaultImports.contains(moduleDecl.name)
+        fun implicitlyImportsModule(moduleDecl: ElmModuleDeclaration): Boolean {
+            return moduleDecl.elmFile.isCore() && defaultImports.contains(moduleDecl.name)
+        }
 
         /**
          * Modules that the Elm compiler treats as being implicitly imported.
@@ -28,8 +29,8 @@ class GlobalScope(val project: Project) {
                 "Tuple",
                 "Debug",
                 "Platform",
-                "Platform.Cmd",
-                "Platform.Sub"
+                "Cmd", // actually Platform.Cmd but aliased as `Cmd` by the Elm compiler
+                "Sub"  // actually Platform.Sub but aliased as `Sub` by the Elm compiler
         )
 
         /**

Add hack for implicit, aliased import of Platform.Cmd and Platform.Sub