Skip to content

Commit 033220c

Browse files
committed
WIP integrated debugging
1 parent de7ff28 commit 033220c

File tree

4 files changed

+63
-20
lines changed

4 files changed

+63
-20
lines changed

src/main/kotlin/com/emberjs/Ember.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,34 @@ package com.emberjs
33
import com.emberjs.utils.isEmberFolder
44
import com.emberjs.utils.parents
55
import com.intellij.openapi.vfs.VirtualFile
6+
import java.util.regex.Pattern
67

78
object Ember {
89
/**
910
* Traverses the `file` parents until it finds root folder of the Ember.js project.
1011
*
1112
* This does not stop for in-repo-addon roots.
1213
*/
13-
fun findProjectFolder(file: VirtualFile) = file.parents.asSequence().firstOrNull { it.isEmberFolder }
14+
fun findProjectFolder(file: VirtualFile) = sequenceOf(file).plus(file.parents).firstOrNull { it.isEmberFolder }
1415

1516
fun findEnvironmentConfigFile(file: VirtualFile) =
1617
Ember.findProjectFolder(file)?.findFileByRelativePath("config/environment.js")
18+
19+
/** Detect the name of the ember application */
20+
fun getAppName(file: VirtualFile): String? {
21+
// TODO: cache the app name?
22+
val env = findEnvironmentConfigFile(file) ?: return null
23+
return env.inputStream.use { stream ->
24+
stream.reader().useLines { lines ->
25+
lines.mapNotNull { line ->
26+
val matcher = ModulePrefixPattern.matcher(line)
27+
if (matcher.find()) matcher.group(1) else null
28+
}.firstOrNull()
29+
}
30+
}
31+
}
32+
33+
/** Captures `my-app` from the string `modulePrefix: 'my-app'` */
34+
private val ModulePrefixPattern = Pattern.compile("modulePrefix:\\s*['\"](.+?)['\"]")
1735
}
1836

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.emberjs.resolver
2+
3+
import com.emberjs.Ember
4+
import com.emberjs.cli.EmberCliProjectConfigurator.Companion.inRepoAddons
5+
import com.emberjs.utils.emberRoot
6+
import com.emberjs.utils.parentEmberModule
7+
import com.intellij.openapi.module.ModuleManager
8+
import com.intellij.openapi.project.Project
9+
import com.intellij.openapi.vfs.VirtualFile
10+
import com.intellij.util.Url
11+
import com.intellij.util.Urls
12+
import com.jetbrains.javascript.debugger.FileUrlMapper
13+
14+
class EmberFileUrlMapper : FileUrlMapper() {
15+
/** Find the source file associated with the URL */
16+
override fun getFile(url: Url, project: Project, requestor: Url?): VirtualFile? {
17+
return ModuleManager.getInstance(project).modules.asSequence()
18+
.mapNotNull { it.emberRoot }
19+
.flatMap { sequenceOf(it).plus(inRepoAddons(it)) }
20+
.mapNotNull { root ->
21+
Ember.getAppName(root)?.let { appName ->
22+
val path = url.path.removePrefix("/assets/$appName/")
23+
root.findFileByRelativePath("app/$path")
24+
}
25+
}
26+
.firstOrNull()
27+
}
28+
29+
/** Calculate the URL for a source file path */
30+
override fun getUrls(file: VirtualFile, project: Project, currentAuthority: String?): MutableList<Url> {
31+
val authority = currentAuthority ?: return mutableListOf()
32+
val module = file.parentEmberModule ?: return mutableListOf()
33+
val appName = Ember.getAppName(module) ?: return mutableListOf()
34+
35+
val path = file.path.removePrefix("${module.path}/app/")
36+
return mutableListOf(Urls.newHttpUrl(authority, "/assets/$appName/$path"))
37+
}
38+
}

src/main/kotlin/com/emberjs/resolver/EmberScopeProvider.kt

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
package com.emberjs.resolver
22

3+
import com.emberjs.Ember
34
import com.emberjs.cli.EmberCliProjectConfigurator
45
import com.emberjs.utils.emberRoot
56
import com.intellij.lang.javascript.DialectDetector
67
import com.intellij.lang.javascript.frameworks.amd.JSModuleReference
78
import com.intellij.lang.javascript.frameworks.modules.JSExactFileReference
89
import com.intellij.lang.javascript.psi.resolve.JSModuleReferenceContributor
910
import com.intellij.openapi.util.TextRange
10-
import com.intellij.openapi.vfs.VirtualFile
1111
import com.intellij.psi.PsiElement
1212
import com.intellij.psi.PsiFileSystemItem
1313
import com.intellij.psi.PsiReference
1414
import com.intellij.psi.PsiReferenceProvider
1515
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference
1616
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet
17-
import java.util.regex.Pattern
1817

1918
/**
2019
* Resolves absolute imports from the ember application root, e.g.
@@ -31,7 +30,7 @@ class EmberAppReferenceContributor : JSModuleReferenceContributor {
3130

3231
override fun getCommonJSModuleReferences(unquotedRefText: String, host: PsiElement, offset: Int, provider: PsiReferenceProvider?): Array<out PsiReference> {
3332
val appRoot = host.emberRoot ?: return emptyArray()
34-
val appName = getAppName(appRoot) ?: return emptyArray()
33+
val appName = Ember.getAppName(appRoot) ?: return emptyArray()
3534

3635
val importPath = unquotedRefText.removePrefix(appName + "/")
3736
if (unquotedRefText == importPath) {
@@ -59,20 +58,4 @@ class EmberAppReferenceContributor : JSModuleReferenceContributor {
5958
}
6059

6160
override fun isApplicable(host: PsiElement): Boolean = DialectDetector.isES6(host)
62-
63-
/** Detect the name of the ember application */
64-
private fun getAppName(appRoot: VirtualFile): String? {
65-
val env = appRoot.findFileByRelativePath("config/environment.js") ?: return null
66-
return env.inputStream.use { stream ->
67-
stream.reader().useLines { lines ->
68-
lines.mapNotNull { line ->
69-
val matcher = ModulePrefixPattern.matcher(line)
70-
if (matcher.find()) matcher.group(1) else null
71-
}.firstOrNull()
72-
}
73-
}
74-
}
75-
76-
/** Captures `my-app` from the string `modulePrefix: 'my-app'` */
77-
private val ModulePrefixPattern = Pattern.compile("modulePrefix:\\s*['\"](.+?)['\"]")
7861
}

src/main/resources/META-INF/plugin.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@
6969
<moduleReferenceContributor implementation="com.emberjs.resolver.EmberAppReferenceContributor"/>
7070
</extensions>
7171

72+
<extensions defaultExtensionNs="com.jetbrains">
73+
<fileUrlMapper implementation="com.emberjs.resolver.EmberFileUrlMapper" order="first"/>
74+
</extensions>
75+
7276
<actions>
7377
<action id="GenerateEmberCode" class="com.emberjs.actions.EmberGenerateCodeAction">
7478
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFromTemplate"/>

0 commit comments

Comments
 (0)