Don't mark compiler-created PSI elements as generated

This saves some memory on storing the generated flag in the PsiElement
userdata and time required to store the flag.
This commit is contained in:
Dmitry Jemerov
2017-03-21 17:53:58 +01:00
parent dc3aa26e3f
commit 3c7678092e
14 changed files with 26 additions and 18 deletions
@@ -161,6 +161,6 @@ object CodegenUtil {
val fakeFunctionCall = StringBuilder("callableReferenceFakeCall(")
fakeFunctionCall.append(referencedFunction.valueParameters.map { "p${it.index}" }.joinToString(", "))
fakeFunctionCall.append(")")
return KtPsiFactory(project).createExpression(fakeFunctionCall.toString()) as KtCallExpression
return KtPsiFactory(project, markGenerated = false).createExpression(fakeFunctionCall.toString()) as KtCallExpression
}
}
@@ -4885,7 +4885,7 @@ The "returned" value of try expression with no finally is either the last expres
}
private Call makeFakeCall(ReceiverValue initializerAsReceiver) {
KtSimpleNameExpression fake = KtPsiFactoryKt.KtPsiFactory(state.getProject()).createSimpleName("fake");
KtSimpleNameExpression fake = KtPsiFactoryKt.KtPsiFactory(state.getProject(), false).createSimpleName("fake");
return CallMaker.makeCall(fake, initializerAsReceiver);
}
@@ -173,7 +173,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
) {
if (receiver == null) return null;
KtExpression receiverExpression = KtPsiFactoryKt.KtPsiFactory(state.getProject()).createExpression("callableReferenceFakeReceiver");
KtExpression receiverExpression = KtPsiFactoryKt.KtPsiFactory(state.getProject(), false).createExpression("callableReferenceFakeReceiver");
codegen.tempVariables.put(receiverExpression, receiverParameterStackValue(signature, codegen));
return ExpressionReceiver.Companion.create(receiverExpression, receiver.getType(), BindingContext.EMPTY);
}
@@ -137,7 +137,7 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
newCall.recordValueArgument(newCandidateDescriptor.valueParameters[it.key.index], it.value)
}
val psiFactory = KtPsiFactory(project)
val psiFactory = KtPsiFactory(project, markGenerated = false)
val arguments = psiFactory.createCallArguments("(this)").arguments.single()
val thisExpression = arguments.getArgumentExpression()!!
newCall.recordValueArgument(
@@ -43,7 +43,7 @@ public class KtImportsFactory {
return directive;
}
KtImportDirective createdDirective = KtPsiFactoryKt.KtPsiFactory(project).createImportDirective(importPath);
KtImportDirective createdDirective = KtPsiFactoryKt.KtPsiFactory(project, false).createImportDirective(importPath);
importsCache.put(importPath, createdDirective);
return createdDirective;
@@ -33,8 +33,11 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.ImportPath
fun KtPsiFactory(project: Project?): KtPsiFactory = KtPsiFactory(project!!)
fun KtPsiFactory(elementForProject: PsiElement): KtPsiFactory = KtPsiFactory(elementForProject.project)
@JvmOverloads
fun KtPsiFactory(project: Project?, markGenerated: Boolean = true): KtPsiFactory = KtPsiFactory(project!!, markGenerated)
@JvmOverloads
fun KtPsiFactory(elementForProject: PsiElement, markGenerated: Boolean = true): KtPsiFactory = KtPsiFactory(elementForProject.project, markGenerated)
private val DO_NOT_ANALYZE_NOTIFICATION = "This file was created by KtPsiFactory and should not be analyzed\n" +
"Use createAnalyzableFile to create file that can be analyzed\n"
@@ -43,7 +46,12 @@ var KtFile.doNotAnalyze: String? by UserDataProperty(Key.create("DO_NOT_ANALYZE"
var KtFile.analysisContext: PsiElement? by UserDataProperty(Key.create("ANALYSIS_CONTEXT"))
var PsiFile.moduleInfo: ModuleInfo? by UserDataProperty(Key.create("MODULE_INFO"))
class KtPsiFactory(private val project: Project) {
/**
* @param markGenerated This needs to be set to true if the `KtPsiFactory` is going to be used for creating elements that are going
* 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) {
fun createValKeyword(): PsiElement {
val property = createProperty("val x = 1")
@@ -197,7 +205,7 @@ class KtPsiFactory(private val project: Project) {
}
private fun doCreateFile(fileName: String, text: String): KtFile {
return PsiFileFactory.getInstance(project).createFileFromText(fileName, KotlinFileType.INSTANCE, text, LocalTimeCounter.currentTime(), false) as KtFile
return PsiFileFactory.getInstance(project).createFileFromText(fileName, KotlinFileType.INSTANCE, text, LocalTimeCounter.currentTime(), false, markGenerated) as KtFile
}
fun createFile(fileName: String, text: String): KtFile {
@@ -422,7 +422,7 @@ public class BodyResolver {
return;
}
KtInitializerList ktInitializerList = new KtPsiFactory(project).createEnumEntryInitializerList();
KtInitializerList ktInitializerList = new KtPsiFactory(project, false).createEnumEntryInitializerList();
KtSuperTypeCallEntry ktCallEntry = (KtSuperTypeCallEntry) ktInitializerList.getInitializers().get(0);
Call call = CallMaker.makeConstructorCallWithoutTypeArguments(ktCallEntry);
trace.record(BindingContext.TYPE, ktCallEntry.getTypeReference(), enumClassDescriptor.getDefaultType());
@@ -280,7 +280,7 @@ class DelegatedPropertyResolver(
val hasThis = propertyDescriptor.extensionReceiverParameter != null || propertyDescriptor.dispatchReceiverParameter != null
val arguments = Lists.newArrayList<KtExpression>()
val psiFactory = KtPsiFactory(delegateExpression)
val psiFactory = KtPsiFactory(delegateExpression, markGenerated = false)
arguments.add(psiFactory.createExpression(if (hasThis) "this" else "null"))
arguments.add(psiFactory.createExpressionForProperty())
@@ -313,7 +313,7 @@ class DelegatedPropertyResolver(
val expectedType = TypeUtils.NO_EXPECTED_TYPE
val context = ExpressionTypingContext.newContext(trace, initializerScope, dataFlowInfo, expectedType)
val propertyHasReceiver = propertyDescriptor.dispatchReceiverParameter != null
val arguments = KtPsiFactory(delegateExpression).run {
val arguments = KtPsiFactory(delegateExpression, markGenerated = false).run {
listOf(
createExpression(if (propertyHasReceiver) "this" else "null"),
createExpressionForProperty()
@@ -107,7 +107,7 @@ public class CallTransformer {
this.explicitExtensionReceiver = explicitExtensionReceiver;
this.calleeExpressionAsDispatchReceiver = calleeExpressionAsDispatchReceiver;
this.fakeInvokeExpression =
(KtSimpleNameExpression) KtPsiFactoryKt.KtPsiFactory(call.getCallElement())
(KtSimpleNameExpression) KtPsiFactoryKt.KtPsiFactory(call.getCallElement(), false)
.createExpression(OperatorNameConventions.INVOKE.asString());
itIsVariableAsFunctionCall = functionCall;
}
@@ -1193,7 +1193,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
expression,
receiver,
// semantically, a call to `==` is a safe call
new KtPsiFactory(expression.getProject()).createSafeCallNode(),
new KtPsiFactory(expression.getProject(), false).createSafeCallNode(),
operationSign,
Collections.singletonList(right)
);
@@ -119,7 +119,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
return getTypeInfoWhenOnlyOneBranchIsPresent(
elseBranch, elseScope, elseInfo, thenInfo, contextWithExpectedType, ifExpression);
}
KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(ifExpression);
KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(ifExpression, false);
KtBlockExpression thenBlock = psiFactory.wrapInABlockWrapper(thenBranch);
KtBlockExpression elseBlock = psiFactory.wrapInABlockWrapper(elseBranch);
Call callForIf = createCallForSpecialConstruction(ifExpression, ifExpression, Lists.newArrayList(thenBlock, elseBlock));
@@ -262,7 +262,7 @@ class DoubleColonExpressionResolver(
private fun KtQualifiedExpression.buildNewExpressionForReservedGenericPropertyCallChainResolution(): KtExpression? {
val parts = this.getQualifierChainParts()?.map { it.getQualifiedNameStringPart() ?: return null } ?: return null
val qualifiedExpressionText = parts.joinToString(separator = ".")
return KtPsiFactory(this).createExpression(qualifiedExpressionText)
return KtPsiFactory(this, markGenerated = false).createExpression(qualifiedExpressionText)
}
private fun resolveReservedExpressionOnLHS(expression: KtExpression, c: ExpressionTypingContext): DoubleColonLHS.Expression? {
@@ -96,7 +96,7 @@ public class ExpressionTypingUtils {
@NotNull String argumentName,
@NotNull KotlinType argumentType
) {
KtExpression fakeExpression = KtPsiFactoryKt.KtPsiFactory(project).createExpression(argumentName);
KtExpression fakeExpression = KtPsiFactoryKt.KtPsiFactory(project, false).createExpression(argumentName);
trace.recordType(fakeExpression, argumentType);
trace.record(PROCESSED, fakeExpression);
return fakeExpression;
@@ -108,7 +108,7 @@ class FakeCallResolver(
callElement: KtExpression,
onComplete: (KtSimpleNameExpression, Boolean) -> Unit = { _, _ -> }
): Pair<Call, OverloadResolutionResults<FunctionDescriptor>> {
val fakeCalleeExpression = KtPsiFactory(project).createSimpleName(name.asString())
val fakeCalleeExpression = KtPsiFactory(project, markGenerated = false).createSimpleName(name.asString())
val call = CallMaker.makeCallWithExpressions(
callElement, receiver, /* callOperationNode = */ null, fakeCalleeExpression, valueArguments
)