[FE] Support analyzable files throughout all 'KtPsiFactory' API
Before, the only way of getting analyzable elements was to create an analyzable file by using 'createAnalyzableFile()'. So made all utilities available in 'KtPsiFactory' useless as they delegate to 'createFile()' that always set the 'doNotAnalyze' flag. The new behavior is to pass the 'analysisContext' instead if it is passed to the 'KtPsiFactory' constructor. The newly appeared API is going to be used in the Kotlin's UAST implementation.
This commit is contained in:
@@ -45,7 +45,7 @@ object EditCommaSeparatedListHelper {
|
||||
list.add(item) as TItem
|
||||
}
|
||||
} else {
|
||||
var comma = KtPsiFactory(list).createComma()
|
||||
var comma = KtPsiFactory(list.project).createComma()
|
||||
return if (anchor != null) {
|
||||
comma = list.addAfter(comma, anchor)
|
||||
list.addAfter(item, comma) as TItem
|
||||
|
||||
@@ -53,7 +53,7 @@ abstract class KtClassOrObject :
|
||||
return EditCommaSeparatedListHelper.addItem(it, superTypeListEntries, superTypeListEntry)
|
||||
}
|
||||
|
||||
val psiFactory = KtPsiFactory(this)
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
val specifierListToAdd = psiFactory.createSuperTypeCallEntry("A()").replace(superTypeListEntry).parent
|
||||
val colon = addBefore(psiFactory.createColon(), getBody())
|
||||
return (addAfter(specifierListToAdd, colon) as KtSuperTypeList).entries.first()
|
||||
@@ -202,7 +202,7 @@ abstract class KtClassOrObject :
|
||||
fun KtClassOrObject.getOrCreateBody(): KtClassBody {
|
||||
getBody()?.let { return it }
|
||||
|
||||
val newBody = KtPsiFactory(this).createEmptyClassBody()
|
||||
val newBody = KtPsiFactory(project).createEmptyClassBody()
|
||||
if (this is KtEnumEntry) return addAfter(newBody, initializerList ?: nameIdentifier) as KtClassBody
|
||||
return add(newBody) as KtClassBody
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ abstract class KtCodeFragment(
|
||||
|
||||
fun importsAsImportList(): KtImportList? {
|
||||
if (imports.isNotEmpty() && context != null) {
|
||||
return KtPsiFactory(this).createAnalyzableFile("imports_for_codeFragment.kt", imports.joinToString("\n"), context).importList
|
||||
return KtPsiFactory.contextual(context).createFile("imports_for_codeFragment.kt", imports.joinToString("\n")).importList
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -35,15 +35,14 @@ abstract class KtExpressionImpl(node: ASTNode) : KtElementImpl(node), KtExpressi
|
||||
when (parent) {
|
||||
is KtExpression, is KtValueArgument -> {
|
||||
if (KtPsiUtil.areParenthesesNecessary(newElement, expression, parent as KtElement)) {
|
||||
return rawReplaceHandler(
|
||||
KtPsiFactory(expression).createExpressionByPattern("($0)", newElement, reformat = reformat)
|
||||
)
|
||||
val factory = KtPsiFactory(expression.project)
|
||||
return rawReplaceHandler(factory.createExpressionByPattern("($0)", newElement, reformat = reformat))
|
||||
}
|
||||
}
|
||||
is KtSimpleNameStringTemplateEntry -> {
|
||||
if (newElement !is KtSimpleNameExpression && !newElement.isThisWithoutLabel()) {
|
||||
val newEntry =
|
||||
parent.replace(KtPsiFactory(expression).createBlockStringTemplateEntry(newElement)) as KtBlockStringTemplateEntry
|
||||
val factory = KtPsiFactory(expression.project)
|
||||
val newEntry = parent.replace(factory.createBlockStringTemplateEntry(newElement)) as KtBlockStringTemplateEntry
|
||||
return newEntry.expression!!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) :
|
||||
if (packageDirective != null) {
|
||||
packageDirective.fqName = value
|
||||
} else {
|
||||
val newPackageDirective = KtPsiFactory(this).createPackageDirectiveIfNeeded(value) ?: return
|
||||
val newPackageDirective = KtPsiFactory(project).createPackageDirectiveIfNeeded(value) ?: return
|
||||
addAfter(newPackageDirective, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class KtImportAlias : KtElementImplStub<KotlinImportAliasStub>, PsiNameIdentifie
|
||||
override fun getName() = stub?.getName() ?: nameIdentifier?.text
|
||||
|
||||
override fun setName(name: String): PsiElement {
|
||||
nameIdentifier?.replace(KtPsiFactory(this).createNameIdentifier(name))
|
||||
nameIdentifier?.replace(KtPsiFactory(project).createNameIdentifier(name))
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public class KtImportsFactory {
|
||||
return directive;
|
||||
}
|
||||
|
||||
KtImportDirective createdDirective = KtPsiFactoryKt.KtPsiFactory(project, false).createImportDirective(importPath);
|
||||
KtImportDirective createdDirective = new KtPsiFactory(project, false).createImportDirective(importPath);
|
||||
importsCache.put(importPath, createdDirective);
|
||||
|
||||
return createdDirective;
|
||||
@@ -58,6 +58,6 @@ public class KtImportsFactory {
|
||||
|
||||
@NotNull
|
||||
public Collection<KtImportDirective> createImportDirectivesNotCached(@NotNull Collection<ImportPath> importPaths) {
|
||||
return KtPsiFactoryKt.KtPsiFactory(project, false).createImportDirectives(importPaths);
|
||||
return new KtPsiFactory(project, false).createImportDirectives(importPaths);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
|
||||
import static org.jetbrains.kotlin.psi.KtPsiFactoryKt.KtPsiFactory;
|
||||
|
||||
// TODO: Remove when all named declarations get stubs
|
||||
@Deprecated
|
||||
abstract class KtNamedDeclarationNotStubbed extends KtDeclarationImpl implements KtNamedDeclaration {
|
||||
@@ -67,7 +65,7 @@ abstract class KtNamedDeclarationNotStubbed extends KtDeclarationImpl implements
|
||||
PsiElement identifier = getNameIdentifier();
|
||||
if (identifier == null) throw new IncorrectOperationException();
|
||||
|
||||
return identifier.replace(KtPsiFactory(this).createNameIdentifier(name));
|
||||
return identifier.replace(new KtPsiFactory(getProject()).createNameIdentifier(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,8 +32,6 @@ import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.psi.KtPsiFactoryKt.KtPsiFactory;
|
||||
|
||||
abstract class KtNamedDeclarationStub<T extends KotlinStubWithFqName<?>> extends KtDeclarationStub<T> implements KtNamedDeclaration {
|
||||
public KtNamedDeclarationStub(@NotNull T stub, @NotNull IStubElementType nodeType) {
|
||||
super(stub, nodeType);
|
||||
@@ -99,8 +97,7 @@ abstract class KtNamedDeclarationStub<T extends KotlinStubWithFqName<?>> extends
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement newIdentifier =
|
||||
KtPsiFactory(this).createNameIdentifierIfPossible(KtPsiUtilKt.quoteIfNeeded(name));
|
||||
PsiElement newIdentifier = new KtPsiFactory(getProject()).createNameIdentifierIfPossible(KtPsiUtilKt.quoteIfNeeded(name));
|
||||
if (newIdentifier != null) {
|
||||
KtPsiUtilKt.astReplace(identifier, newIdentifier);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class KtPrimaryConstructor : KtConstructor<KtPrimaryConstructor> {
|
||||
override fun getContainingClassOrObject() = parent as KtClassOrObject
|
||||
|
||||
private fun getOrCreateConstructorKeyword(): PsiElement {
|
||||
return getConstructorKeyword() ?: addBefore(KtPsiFactory(this).createConstructorKeyword(), valueParameterList!!)
|
||||
return getConstructorKeyword() ?: addBefore(KtPsiFactory(project).createConstructorKeyword(), valueParameterList!!)
|
||||
}
|
||||
|
||||
fun removeRedundantConstructorKeywordAndSpace() {
|
||||
@@ -53,7 +53,7 @@ class KtPrimaryConstructor : KtConstructor<KtPrimaryConstructor> {
|
||||
}
|
||||
} else {
|
||||
if (modifier == KtTokens.PUBLIC_KEYWORD) return
|
||||
val newModifierList = KtPsiFactory(this).createModifierList(modifier)
|
||||
val newModifierList = KtPsiFactory(project).createModifierList(modifier)
|
||||
addBefore(newModifierList, getOrCreateConstructorKeyword())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,19 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isIdentifier
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.checkWithAttachment
|
||||
|
||||
@JvmOverloads
|
||||
fun KtPsiFactory(project: Project?, markGenerated: Boolean = true): KtPsiFactory = KtPsiFactory(project!!, markGenerated)
|
||||
@JvmName("KtPsiFactory")
|
||||
@Suppress("FunctionName", "unused")
|
||||
@Deprecated("Use 'KtPsiFactory' constructor instead", level = DeprecationLevel.HIDDEN)
|
||||
fun KtPsiFactoryOld(project: Project?, markGenerated: Boolean = true): KtPsiFactory = KtPsiFactory(project!!, markGenerated)
|
||||
|
||||
@JvmOverloads
|
||||
fun KtPsiFactory(elementForProject: PsiElement, markGenerated: Boolean = true): KtPsiFactory =
|
||||
@JvmName("KtPsiFactory")
|
||||
@Suppress("FunctionName", "unused")
|
||||
@Deprecated("Use 'KtPsiFactory' constructor instead", level = DeprecationLevel.HIDDEN)
|
||||
fun KtPsiFactoryOld(elementForProject: PsiElement, markGenerated: Boolean = true): KtPsiFactory =
|
||||
KtPsiFactory(elementForProject.project, markGenerated)
|
||||
|
||||
private const val DO_NOT_ANALYZE_NOTIFICATION = "This file was created by KtPsiFactory and should not be analyzed\n" +
|
||||
@@ -43,7 +48,25 @@ var KtFile.analysisContext: PsiElement? by UserDataProperty(Key.create("ANALYSIS
|
||||
* to be inserted in the user source code (this ensures that the elements will be formatted correctly). In other cases, `markGenerated`
|
||||
* should be false, which saves time and memory.
|
||||
*/
|
||||
class KtPsiFactory @JvmOverloads constructor(private val project: Project, val markGenerated: Boolean = true) {
|
||||
class KtPsiFactory private constructor(
|
||||
private val project: Project,
|
||||
private val markGenerated: Boolean,
|
||||
private val context: PsiElement?
|
||||
) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun contextual(context: PsiElement, markGenerated: Boolean = true): KtPsiFactory {
|
||||
return KtPsiFactory(context.project, markGenerated, context)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
constructor(project: Project, markGenerated: Boolean = true) : this(project, markGenerated, context = null)
|
||||
|
||||
@JvmOverloads
|
||||
@Deprecated("Use 'KtPsiFactory(project, markGenerated)' or 'KtPsiFactory.contextual(context, markGenerated)' instead")
|
||||
constructor(element: KtElement, markGenerated: Boolean = true) : this(element.project, markGenerated, context = null)
|
||||
|
||||
fun createValKeyword(): PsiElement {
|
||||
val property = createProperty("val x = 1")
|
||||
@@ -217,17 +240,24 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m
|
||||
fun createFile(@NonNls fileName: String, @NonNls text: String): KtFile {
|
||||
val file = doCreateFile(fileName, text)
|
||||
|
||||
file.doNotAnalyze = DO_NOT_ANALYZE_NOTIFICATION
|
||||
val analysisContext = this@KtPsiFactory.context
|
||||
if (analysisContext != null) {
|
||||
file.analysisContext = analysisContext
|
||||
} else {
|
||||
file.doNotAnalyze = DO_NOT_ANALYZE_NOTIFICATION
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
@Deprecated("Call 'createFile()' on a contextual 'KtPsiFactory' instead")
|
||||
fun createAnalyzableFile(@NonNls fileName: String, @NonNls text: String, contextToAnalyzeIn: PsiElement): KtFile {
|
||||
val file = doCreateFile(fileName, text)
|
||||
file.analysisContext = contextToAnalyzeIn
|
||||
return file
|
||||
}
|
||||
|
||||
@Deprecated("Call 'createPhysicalFile() on a contextual 'KtPsiFactory' instead")
|
||||
fun createFileWithLightClassSupport(@NonNls fileName: String, @NonNls text: String, contextToAnalyzeIn: PsiElement): KtFile {
|
||||
val file = createPhysicalFile(fileName, text)
|
||||
file.analysisContext = contextToAnalyzeIn
|
||||
@@ -235,13 +265,10 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m
|
||||
}
|
||||
|
||||
fun createPhysicalFile(@NonNls fileName: String, @NonNls text: String): KtFile {
|
||||
return PsiFileFactory.getInstance(project).createFileFromText(
|
||||
fileName,
|
||||
KotlinFileType.INSTANCE,
|
||||
text,
|
||||
LocalTimeCounter.currentTime(),
|
||||
true
|
||||
) as KtFile
|
||||
val time = LocalTimeCounter.currentTime()
|
||||
val file = PsiFileFactory.getInstance(project).createFileFromText(fileName, KotlinFileType.INSTANCE, text, time, true) as KtFile
|
||||
file.analysisContext = this@KtPsiFactory.context
|
||||
return file
|
||||
}
|
||||
|
||||
fun createProperty(
|
||||
|
||||
@@ -22,7 +22,7 @@ private fun KtModifierListOwner.addModifierList(newModifierList: KtModifierList)
|
||||
}
|
||||
|
||||
private fun createModifierList(text: String, owner: KtModifierListOwner): KtModifierList {
|
||||
return owner.addModifierList(KtPsiFactory(owner).createModifierList(text))
|
||||
return owner.addModifierList(KtPsiFactory(owner.project).createModifierList(text))
|
||||
}
|
||||
|
||||
fun KtModifierListOwner.setModifierList(newModifierList: KtModifierList) {
|
||||
@@ -55,7 +55,7 @@ fun addAnnotationEntry(owner: KtModifierListOwner, annotationEntry: KtAnnotation
|
||||
internal fun addModifier(modifierList: KtModifierList, modifier: KtModifierKeywordToken) {
|
||||
if (modifierList.hasModifier(modifier)) return
|
||||
|
||||
val newModifier = KtPsiFactory(modifierList).createModifier(modifier)
|
||||
val newModifier = KtPsiFactory(modifierList.project).createModifier(modifier)
|
||||
val modifierToReplace = MODIFIERS_TO_REPLACE[modifier]
|
||||
?.mapNotNull { modifierList.getModifier(it) }
|
||||
?.firstOrNull()
|
||||
@@ -113,7 +113,7 @@ fun removeModifier(owner: KtModifierListOwner, modifier: KtModifierKeywordToken)
|
||||
|
||||
val lastChild = it.lastChild
|
||||
if (lastChild is PsiComment) {
|
||||
it.addAfter(KtPsiFactory(owner).createNewLine(), lastChild)
|
||||
it.addAfter(KtPsiFactory(owner.project).createNewLine(), lastChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ fun isDoubleColonReceiver(expression: KtExpression) =
|
||||
fun KtFunctionLiteral.getOrCreateParameterList(): KtParameterList {
|
||||
valueParameterList?.let { return it }
|
||||
|
||||
val psiFactory = KtPsiFactory(this)
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
|
||||
val anchor = lBrace
|
||||
val newParameterList = addAfter(psiFactory.createLambdaParameterList("x"), anchor) as KtParameterList
|
||||
@@ -589,7 +589,7 @@ fun KtFunctionLiteral.findLabelAndCall(): Pair<Name?, KtCallExpression?> {
|
||||
fun KtCallExpression.getOrCreateValueArgumentList(): KtValueArgumentList {
|
||||
valueArgumentList?.let { return it }
|
||||
return addAfter(
|
||||
KtPsiFactory(this).createCallArguments("()"),
|
||||
KtPsiFactory(project).createCallArguments("()"),
|
||||
typeArgumentList ?: calleeExpression,
|
||||
) as KtValueArgumentList
|
||||
}
|
||||
@@ -598,7 +598,7 @@ fun KtCallExpression.addTypeArgument(typeArgument: KtTypeProjection) {
|
||||
if (typeArgumentList != null) {
|
||||
typeArgumentList?.addArgument(typeArgument)
|
||||
} else {
|
||||
addAfter(KtPsiFactory(this).createTypeArguments("<${typeArgument.text}>"), calleeExpression)
|
||||
addAfter(KtPsiFactory(project).createTypeArguments("<${typeArgument.text}>"), calleeExpression)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user