Skip to content

Commit

Permalink
fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklx committed Apr 12, 2023
1 parent e360034 commit e459785
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 65 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Changelog
===============================================================================
## 2022.4.4
- feature: support GTS formatting

## 2022.4.3
- feature: Support GTS imports and GTS exports resolution

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ plugins {


group = "com.emberjs"
version = "2022.4.3"
version = "2022.4.4"

// Configure project's dependencies
repositories {
Expand Down
Empty file modified gradlew
100755 → 100644
Empty file.
165 changes: 115 additions & 50 deletions src/main/kotlin/com/emberjs/gts/GtsSupport.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import com.emberjs.resolver.EmberName
import com.emberjs.utils.EmberUtils
import com.emberjs.utils.ifTrue
import com.intellij.embedding.EmbeddingElementType
import com.intellij.formatting.Alignment
import com.intellij.formatting.FormattingContext
import com.intellij.formatting.FormattingModel
import com.intellij.formatting.Wrap
import com.intellij.formatting.*
import com.intellij.formatting.templateLanguages.DataLanguageBlockWrapper
import com.intellij.formatting.templateLanguages.TemplateLanguageBlock
import com.intellij.formatting.templateLanguages.TemplateLanguageFormattingModelBuilder
Expand Down Expand Up @@ -47,6 +44,8 @@ import com.intellij.lang.javascript.types.JEEmbeddedBlockElementType
import com.intellij.lang.javascript.types.JSFileElementType
import com.intellij.lang.javascript.types.TypeScriptEmbeddedContentElementType
import com.intellij.lang.typescript.tsconfig.*
import com.intellij.lang.xml.XMLLanguage
import com.intellij.lang.xml.XmlFormattingModel
import com.intellij.lexer.HtmlLexer
import com.intellij.lexer.Lexer
import com.intellij.lexer.LookAheadLexer
Expand All @@ -59,26 +58,31 @@ import com.intellij.openapi.editor.highlighter.EditorHighlighter
import com.intellij.openapi.fileTypes.*
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.IconLoader
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.*
import com.intellij.psi.codeStyle.CodeStyleSettings
import com.intellij.psi.formatter.DocumentBasedFormattingModel
import com.intellij.psi.formatter.FormattingDocumentModelImpl
import com.intellij.psi.formatter.xml.*
import com.intellij.psi.html.HtmlTag
import com.intellij.psi.impl.source.PsiFileImpl
import com.intellij.psi.impl.source.SourceTreeToPsiMap
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil
import com.intellij.psi.impl.source.html.HtmlDocumentImpl
import com.intellij.psi.impl.source.tree.LeafElement
import com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl
import com.intellij.psi.search.FilenameIndex
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import com.intellij.psi.templateLanguages.OuterLanguageElementImpl
import com.intellij.psi.templateLanguages.TemplateDataElementType
import com.intellij.psi.templateLanguages.TemplateDataModifications
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider
import com.intellij.psi.templateLanguages.*
import com.intellij.psi.tree.*
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.xml.XmlTokenType
import com.intellij.refactoring.suggested.startOffset
import com.intellij.util.Processor
import com.intellij.xml.template.formatter.AbstractXmlTemplateFormattingModelBuilder
import java.util.function.Predicate
import javax.swing.Icon

Expand All @@ -102,36 +106,6 @@ class GtsFile(viewProvider: FileViewProvider?) : JSFileImpl(viewProvider!!, GtsL
}



class TSTemplate2(val ts: TypeScriptEmbeddedContentElementType = TypeScriptEmbeddedContentElementType(TS, "GTS_")):
EmbeddingElementType by ts,
ICustomParsingType by ts,
ILazyParseableElementTypeBase by ts,
ILightLazyParseableElementType by ts,
JEEmbeddedBlockElementType by ts,
TemplateDataElementType.TemplateAwareElementType by ts,
TemplateDataElementType("GTS_TS", TS, GtsElementTypes.JS_TOKEN, GtsElementTypes.GTS_OUTER_ELEMENT_TYPE) {

override fun createTemplateFakeFileType(language: Language?): LanguageFileType {
return TypeScriptFileType.INSTANCE
}

override fun parseContents(node: ASTNode): ASTNode? {
return super.parseContents(node)
}
override fun getTemplateFileLanguage(viewProvider: TemplateLanguageFileViewProvider?): Language {
return TS
}
override fun appendCurrentTemplateToken(tokenEndOffset: Int, tokenText: CharSequence): TemplateDataModifications {
val r = Regex("=\\s*$")
return if (r.containsMatchIn(tokenText)) {
TemplateDataModifications.fromRangeToRemove(tokenEndOffset, "\"\"")
} else {
super.appendCurrentTemplateToken(tokenEndOffset, tokenText)
}
}
}

class GtsFileElementType(language: Language?) : JSFileElementType(language) {
override fun parseContents(chameleon: ASTNode): ASTNode? {
return GtsElementTypes.TS_CONTENT_ELEMENT_TYPE.parseContents(chameleon)
Expand Down Expand Up @@ -328,11 +302,6 @@ class GtsLexerAdapter(val baseLexer: Lexer = HtmlLexer(), val hideMode: Boolean

class GtsFileType : LanguageFileType(GtsLanguage.INSTANCE) {

override fun hashCode(): Int {
return super.hashCode()
return TypeScriptFileType.INSTANCE.hashCode()
}

override fun equals(other: Any?): Boolean {
if (other == TypeScriptFileType.INSTANCE) {
return true
Expand All @@ -359,6 +328,10 @@ class GtsFileType : LanguageFileType(GtsLanguage.INSTANCE) {
override fun getIcon(): Icon? {
return GtsIcons.icon
}

override fun hashCode(): Int {
return javaClass.hashCode()
}
}

class GtsFileViewProviderFactory: FileViewProviderFactory {
Expand Down Expand Up @@ -601,7 +574,10 @@ class GtsImportCandidate(name: String, place: PsiElement, val info: GtsComponent
val type = info.type.equals("named").ifTrue { ES6ImportPsiUtil.ImportExportType.SPECIFIER } ?: ES6ImportPsiUtil.ImportExportType.DEFAULT
val desc = ES6CreateImportUtil.getImportDescriptor(name, null, info.virtualFile, place, true)
val info = ES6ImportPsiUtil.CreateImportExportInfo(info.name, info.name, type, ES6ImportExportDeclaration.ImportExportPrefixKind.IMPORT)
return JSImportCandidateDescriptor(GtsJSModuleDescriptor(desc!!.moduleDescriptor), info.importedName, info.exportedName, info.importExportPrefixKind, info.importType)
if (desc?.moduleDescriptor == null) {
return null
}
return JSImportCandidateDescriptor(GtsJSModuleDescriptor(desc.moduleDescriptor), info.importedName, info.exportedName, info.importExportPrefixKind, info.importType)
}

override fun getContainerText(): String {
Expand All @@ -617,13 +593,102 @@ class GtsIndexedFileTypeProvider : IndexedFileTypeProvider {
override fun getFileTypesToIndex(): Array<FileType> = arrayOf(GtsFileType.INSTANCE)
}

class GtsFormattingModelBuilder : JavascriptFormattingModelBuilder() {
override fun createModel(formattingContext: FormattingContext): FormattingModel {
if (formattingContext.psiElement is PsiFile) {
return super.createModel(formattingContext.withPsiElement(formattingContext.containingFile.viewProvider.getPsi(TS)))
class RootBlockWrapper(block: XmlTagBlock, val policy: HtmlPolicy, indent: Indent): XmlTagBlock(block.node, block.wrap, block.alignment, policy, indent) {

override fun getTextRange(): TextRange {
if (indent!!.type == Indent.Type.NONE) {
return super.getTextRange()
}
val range = super.getTextRange()
var start = range.startOffset - 1
val text = node.psi.containingFile.text
while (start > 0 && text[start] != '\n') {
if (text[start] != ' ') {
break
}
start--
}
val elem = formattingContext.psiElement.containingFile.findElementAt(formattingContext.psiElement.startOffset)
return super.createModel(formattingContext.withPsiElement(elem!!))
return TextRange(start, range.endOffset)
}
override fun getChildIndent(): Indent? {
return Indent.getNormalIndent()
}

override fun getChildAttributes(newChildIndex: Int): ChildAttributes {
return ChildAttributes(Indent.getNormalIndent(), null)
}

override fun getChildrenIndent(): Indent {
return Indent.getNormalIndent()
}
}

class GtsFormattingModelBuilder : AbstractXmlTemplateFormattingModelBuilder() {

fun findTemplateRootBlock(block: Block, element: PsiElement): Block? {
if (block is XmlTagBlock && block.node is HtmlTag && (block.node as HtmlTag).parent is HtmlDocumentImpl && block.textRange.contains(element.textRange)) {
return block
}
block.subBlocks.forEach {
if (it is AnotherLanguageBlockWrapper) {
return@forEach
}
val b = findTemplateRootBlock(it, element)
if (b != null) {
return b
}
}
return null
}
override fun createModel(formattingContext: FormattingContext): FormattingModel {
val element = formattingContext.psiElement.containingFile.findElementAt(formattingContext.formattingRange.startOffset)!!
if (formattingContext.psiElement is PsiFile && formattingContext.formattingRange.startOffset == 0 || element.language is JavascriptLanguage) {
return JavascriptFormattingModelBuilder().createModel(formattingContext.withPsiElement(formattingContext.containingFile.viewProvider.getPsi(TS)))
}
val file: PsiFile = element.containingFile
if (element.language == XMLLanguage.INSTANCE || element.language == HTMLLanguage.INSTANCE) {
val psiFile = element.containingFile
val documentModel = FormattingDocumentModelImpl.createOn(psiFile)
val documentBlock = XmlBlock(SourceTreeToPsiMap.psiElementToTree(psiFile),
null, null, HtmlPolicy(formattingContext.codeStyleSettings, documentModel), null,
null, false)
val block = findTemplateRootBlock(documentBlock, element) as? XmlTagBlock ?: return super.createModel(formattingContext)
var start = block.textRange.startOffset - 1
var indent = Indent.getNormalIndent()
while (start > 0 && psiFile.text[start] != '\n') {
if (psiFile.text[start] != ' ') {
indent = Indent.getNoneIndent()
}
start--
}
val rootBlock = RootBlockWrapper(block, HtmlPolicy(formattingContext.codeStyleSettings, documentModel), indent)
val model = XmlFormattingModel(
psiFile,
rootBlock,
documentModel)
return DocumentBasedFormattingModel(model.rootBlock, element.project, formattingContext.codeStyleSettings, file.fileType, file)
}
var language = element.language
if (language == JavascriptLanguage.INSTANCE) {
language = TS
}
return super.createModel(formattingContext)
}

override fun isTemplateFile(file: PsiFile?): Boolean {
return file is GtsFile
}

override fun isOuterLanguageElement(element: PsiElement?): Boolean {
return element is OuterLanguageElement
}

override fun isMarkupLanguageElement(element: PsiElement?): Boolean {
return false
}

override fun createTemplateLanguageBlock(node: ASTNode?, settings: CodeStyleSettings?, xmlFormattingPolicy: XmlFormattingPolicy?, indent: Indent?, alignment: Alignment?, wrap: Wrap?): Block {
return LanguageFormatting.INSTANCE.forLanguage(node!!.psi.language).createModel(FormattingContext.create(node.psi, settings!!)).rootBlock
}

}
26 changes: 12 additions & 14 deletions src/main/kotlin/com/emberjs/gts/HbLinter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,19 @@ class HbLintExternalAnnotator() : ExternalAnnotator<InitialInfo, AnnotationResul
?.toCollection(result.annotationErrors)
}
val file = collectedInfo.file!!
val tsFile = collectedInfo.file!!.viewProvider.getPsi(JavaScriptSupportLoader.TYPESCRIPT)
val emberTags = collectedInfo.emberTags
val map = collectedInfo.map
if (tsFile != null) {
ApplicationManager.getApplication().runReadAction {
val hbIds = collectedInfo.hbIds.filter { it.parent !is HbData }
val keyFilter = Predicate { name: String? -> name != null && (emberTags.find { name == it.name.split("::").last() } != null || hbIds.find { name == it.text } != null )}
val info = JSImportPlaceInfo(tsFile)
val providers = JSImportCandidatesProvider.getProviders(info)
JSImportCompletionUtil.processExportedElements(file, providers, keyFilter) { elements: Collection<JSImportCandidate?>, name: String? ->
map.entries.filter { name == it.key }.forEach {
it.value.addAll(elements.filterNotNull())
}
return@processExportedElements true
ApplicationManager.getApplication().runReadAction {
val tsFile = collectedInfo.file!!.viewProvider.getPsi(JavaScriptSupportLoader.TYPESCRIPT) ?: return@runReadAction
val hbIds = collectedInfo.hbIds.filter { it.parent !is HbData }
val keyFilter = Predicate { name: String? -> name != null && (emberTags.find { name == it.name.split("::").last() } != null || hbIds.find { name == it.text } != null )}
val info = JSImportPlaceInfo(tsFile)
val providers = JSImportCandidatesProvider.getProviders(info)
JSImportCompletionUtil.processExportedElements(file, providers, keyFilter) { elements: Collection<JSImportCandidate?>, name: String? ->
map.entries.filter { name == it.key }.forEach {
it.value.addAll(elements.filterNotNull())
}
return@processExportedElements true
}
}

Expand Down Expand Up @@ -156,8 +154,8 @@ class HbLintExternalAnnotator() : ExternalAnnotator<InitialInfo, AnnotationResul
val nameElement = it.children.find { it.elementType == XmlTokenType.XML_NAME } ?: return@forEach
val closeNameElement = it.children.findLast { it.elementType == XmlTokenType.XML_NAME }
val message = (((it.name.startsWith(":") || file.viewProvider is HbFileViewProvider)
.ifTrue { JavaScriptBundle.message("javascript.unresolved.symbol.message", Object()) + " '<${it.name}>'" }
?: (JavaScriptBundle.message("js.inspection.missing.import", Object()) + " for <${it.name}>")))
.ifTrue { JavaScriptBundle.message("javascript.unresolved.symbol.message", Object()) + " '${it.name}'" }
?: (JavaScriptBundle.message("js.inspection.missing.import", Object()) + " for '${it.name}'")))
if (closeNameElement != null && closeNameElement.textRange.endOffset == it.endOffset - 1) {
holder.newSilentAnnotation(HighlightSeverity.ERROR)
.range(closeNameElement.textRange)
Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/com/emberjs/resolver/EmberName.kt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ data class EmberName(val type: String, val path: String, val filePath: String =
val file = parts.getOrNull(3)?.let { LocalFileSystem.getInstance().findFileByPath(it) }
return when {
parts.count() >= 3 && file != null -> EmberName(parts[0], parts[1], parts.getOrNull(2) ?: "", file)
parts.count() == 2 -> EmberName(parts[0], parts[1], parts.getOrNull(2) ?: "", file)
else -> null
}
}
Expand Down

0 comments on commit e459785

Please sign in to comment.