@@ -65,7 +65,7 @@ open class CFileImpl(viewProvider: FileViewProvider, language: Language) :
6565 else -> fileStubForced
6666 }
6767 }
68- internal val fileStubForced: CFileStub ?
68+ internal val fileStubForced: CFileStub
6969 get() = fileStubRef?.get() ? : run {
7070 val stub = if (virtualFile !is VirtualFileWithId ) buildStubTree(this )
7171 else StubTreeLoader .getInstance().readFromVFile(project, virtualFile)?.root as ? CFileStub ? : buildStubTree(this )
@@ -110,7 +110,7 @@ open class CFileImpl(viewProvider: FileViewProvider, language: Language) :
110110 val helper = RoleHelper ()
111111 helper.assignRoles(this , curState != null && curState.timeStamp < 0 )
112112 val definitions = cljTraverser().traverse()
113- .filter { (it as ? CComposite )?.roleImpl == Role . DEF }
113+ .filter { (it as ? CComposite )?.dataImpl is IDef }
114114 .filter(CList ::class ).toList()
115115 val state = State (curTimeStamp, helper.fileNS, definitions, helper.imports)
116116 myState = state
@@ -343,7 +343,7 @@ private fun processSyntheticDeclarations(def: IDef, private: Boolean,
343343private class RoleHelper {
344344 val langStack = ArrayDeque <Dialect >()
345345 val nsReader = NSReader (this )
346- val fileNS: String get() = nsReader.fileNS
346+ val fileNS: String get() = nsReader.fileNS ? : ClojureConstants . NS_USER
347347 val imports: List <Imports > get() = nsReader.result
348348
349349 fun currentLangKind () = langStack.peek()!!
@@ -362,7 +362,7 @@ private class RoleHelper {
362362 langStack.push(if (file.language == ClojureScriptLanguage ) Dialect .CLJS else Dialect .CLJ )
363363
364364 val s = file.cljTraverser().expand {
365- it !is CListBase || (it as CComposite ).roleImpl != Role .DEF && (it as CComposite ).roleImpl != Role .NS
365+ it !is CListBase || (it as CComposite ).roleImpl. let { r -> r != Role .DEF && r != Role .NS }
366366 }.traverse()
367367
368368 if (firstTime) {
@@ -396,14 +396,13 @@ private class RoleHelper {
396396 val ns = first.qualifier?.name?.let { resolveAlias(it) } ? :
397397 if (seenDefs.contains(firstName.withNamespace(fileNS))) fileNS else langKind.coreNs
398398 setData(first.qualifier, ns)
399+ val nameSym = (first.nextForm as ? CSymbol )?.apply { initFlags(this ) }
399400 if (ClojureConstants .DEF_ALIKE_SYMBOLS .contains(firstName) && ns == langKind.coreNs ||
400401 firstName != " defmethod" &&
401402 firstName.startsWith(" def" ) && firstName != " default" && firstName != " def" /* clojure.spec/def */ ) {
402- val nameSym = first.nextForm as ? CSymbol
403- if (nameSym != null && nameSym.firstChild !is CReaderMacro ) {
403+ if (nameSym != null && ! nameSym.fastFlagIsSet(FLAG_QUOTED ) && ! nameSym.fastFlagIsSet(FLAG_UNQUOTED )) {
404404 // optimization: delay up until the end, so that other threads may skip this
405- val type = if (firstName == " create-ns" ) " ns" else firstName
406- val key = SymKey (nameSym.name, resolveAlias(nameSym.qualifier?.name) ? : fileNS, type)
405+ val key = SymKey (nameSym.name, resolveAlias(nameSym.qualifier?.name) ? : fileNS, firstName)
407406 setData(nameSym.qualifier, key.namespace)
408407 setData(nameSym, Role .NAME )
409408 delayedDefs[e] = createDef(e, nameSym, key)
@@ -429,7 +428,6 @@ private class RoleHelper {
429428 seenDefs.add(key.name)
430429 }
431430 else if (ClojureConstants .NS_ALIKE_SYMBOLS .contains(firstName) && ns == langKind.coreNs) {
432- setData(e, Role .NS ) // prevents deep traversal for e
433431 processNSElement(e)
434432 }
435433 else if (ClojureConstants .LET_ALIKE_SYMBOLS .contains(firstName) && ns == langKind.coreNs) {
@@ -566,23 +564,26 @@ private class RoleHelper {
566564}
567565
568566private class NSReader (val helper : RoleHelper ) {
569- var fileNS: String = ClojureConstants . NS_USER
567+ var fileNS: String? = null
570568 val result = mutableListOf<Imports >()
571569
572570 fun processElement (e : CListBase ) {
573571 val nsType = (e as CList ).first!! .name
574572 var imports: MutableList <Imports >? = null
575- if (nsType == " in-ns" || nsType == " ns" ) {
576- val nameSym = e.first.nextForm as ? CSymbol
573+ val nameSym = e.first.nextForm as ? CSymbol
574+ val nsName = nameSym?.name
575+ val nsQuotedOK = (nsType == " ns" ) != nameSym.fastFlagIsSet(FLAG_QUOTED )
576+ if (nsName != null && nsQuotedOK && (nsType == " ns" || nsType == " create-ns" || nsType == " in-ns" )) {
577577 imports = mutableListOf ()
578- if (nameSym != null ) {
579- val name = nameSym.name
580- setData(nameSym, Role .NAME )
581- setData(e, NSDef (SymKey (name, " " , " ns" ), imports))
582- if (result.isEmpty()) {
583- fileNS = name
584- }
578+ setData(nameSym, Role .NAME )
579+ setData(e, NSDef (SymKey (nsName, " " , " ns" ), imports))
580+ if (fileNS == null && nsType != " create-ns" && e.parentForm == null ) {
581+ fileNS = nsName
585582 }
583+ if (nsType != " ns" ) return
584+ }
585+ else {
586+ setData(e, Role .NS )
586587 }
587588 val hasRC = e.cljTraverser().filter(CListBase ::class .java)
588589 .reduce(false , { flag, it -> helper.processRCParenForm(it) || flag })
@@ -618,7 +619,8 @@ private class NSReader(val helper: RoleHelper) {
618619 }
619620 if (imports.isEmpty()) return null
620621 val scope = e.parentForms.skip(1 ).filter { it.fastRole != Role .RCOND && it.fastRole != Role .RCOND_S }.first()
621- return Imports (imports, dialect, e.textRange, scope?.textRange?.endOffset ? : - 1 )
622+ val range = TextRange (e.first!! .textRange.endOffset, e.textRange.endOffset)
623+ return Imports (imports, dialect, range, scope?.textRange?.endOffset ? : - 1 )
622624 }
623625
624626 fun readNSElement2 (root : CListBase , traverser : SyntaxTraverser <PsiElement >, nsType : String , inNs : Boolean , dialect : Dialect ): List <Import > {
@@ -666,8 +668,8 @@ private class NSReader(val helper: RoleHelper) {
666668 val iterator = content.iterator()
667669 val aliasSym = iterator.safeNext() as ? CSymbol ? : return emptyList()
668670 val nsSym = iterator.safeNext() as ? CSymbol
669- val aliasQuoted = aliasSym.fastFlags and FLAG_QUOTED != 0
670- val nsQuoted = nsSym.fastFlags and FLAG_QUOTED != 0
671+ val aliasQuoted = aliasSym.fastFlagIsSet( FLAG_QUOTED )
672+ val nsQuoted = nsSym.fastFlagIsSet( FLAG_QUOTED )
671673 val namespace = if (nsQuoted) nsSym?.name ? : " " else " "
672674 if (aliasQuoted) {
673675 setResolveTo(aliasSym, SymKey (aliasSym.name, namespace, " alias" ))
@@ -731,8 +733,10 @@ private class NSReader(val helper: RoleHelper) {
731733 for (item in iterator) {
732734 when (item) {
733735 is CKeyword -> if (item.name == " as" ) iterator.safeNext() // ignore the next form to get it highlighted
734- is CSymbol -> addImport(item, " " )
735- is CLVForm -> if (inNs == (item.fastFlags and FLAG_QUOTED == 0 )) {
736+ is CSymbol -> if (inNs != item.fastFlagIsSet(FLAG_QUOTED )) {
737+ addImport(item, " " )
738+ }
739+ is CLVForm -> if (inNs != item.fastFlagIsSet(FLAG_QUOTED )) {
736740 if (item is CVec && (item.childForm(CKeyword ::class ) != null || item.childForm(CLVForm ::class ) == null )) {
737741 addImport(item, " " )
738742 }
0 commit comments