@Override public StackValue visitLabeledExpression( @NotNull KtLabeledExpression expression, StackValue receiver) { KtExpression baseExpression = expression.getBaseExpression(); assert baseExpression != null : "Label expression should have base one: " + expression.getText(); return baseExpression.accept(this, receiver); }
@Override public void invoke(@NotNull Project project, Editor editor, KtFile file) throws IncorrectOperationException { if (getElement() instanceof KtBinaryExpressionWithTypeRHS) { KtExpression left = ((KtBinaryExpressionWithTypeRHS) getElement()).getLeft(); KtTypeReference right = ((KtBinaryExpressionWithTypeRHS) getElement()).getRight(); if (right != null) { KtExpression expression = KtPsiFactoryKt.KtPsiFactory(file) .createExpression(left.getText() + operation + right.getText()); getElement().replace(expression); } } }
@NotNull private static KtBinaryExpression createVariableAssignment(@NotNull KtProperty property) { String propertyName = property.getName(); assert propertyName != null : "Property should have a name " + property.getText(); KtBinaryExpression assignment = (KtBinaryExpression) KtPsiFactoryKt.KtPsiFactory(property).createExpression(propertyName + " = x"); KtExpression right = assignment.getRight(); assert right != null : "Created binary expression should have a right part " + assignment.getText(); KtExpression initializer = property.getInitializer(); assert initializer != null : "Initializer should exist for property " + property.getText(); right.replace(initializer); return assignment; }
public LambdaInfo( @NotNull KtExpression expression, @NotNull KotlinTypeMapper typeMapper, boolean isCrossInline, boolean isBoundCallableReference) { this.isCrossInline = isCrossInline; this.expression = expression instanceof KtLambdaExpression ? ((KtLambdaExpression) expression).getFunctionLiteral() : expression; this.typeMapper = typeMapper; this.isBoundCallableReference = isBoundCallableReference; BindingContext bindingContext = typeMapper.getBindingContext(); FunctionDescriptor function = bindingContext.get(BindingContext.FUNCTION, this.expression); if (function == null && expression instanceof KtCallableReferenceExpression) { VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, this.expression); assert variableDescriptor instanceof VariableDescriptorWithAccessors : "Reference expression not resolved to variable descriptor with accessors: " + expression.getText(); classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor); closureClassType = typeMapper.mapClass(classDescriptor); SimpleFunctionDescriptor getFunction = PropertyReferenceCodegen.findGetFunction(variableDescriptor); functionDescriptor = PropertyReferenceCodegen.createFakeOpenDescriptor(getFunction, classDescriptor); ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert( ((KtCallableReferenceExpression) expression).getCallableReference(), bindingContext); propertyReferenceInfo = new PropertyReferenceInfo( (VariableDescriptor) resolvedCall.getResultingDescriptor(), getFunction); } else { propertyReferenceInfo = null; functionDescriptor = function; assert functionDescriptor != null : "Function is not resolved to descriptor: " + expression.getText(); classDescriptor = anonymousClassForCallable(bindingContext, functionDescriptor); closureClassType = asmTypeForAnonymousClass(bindingContext, functionDescriptor); } closure = bindingContext.get(CLOSURE, classDescriptor); assert closure != null : "Closure for lambda should be not null " + expression.getText(); labels = InlineCodegen.getDeclarationLabels(expression, functionDescriptor); }
@NotNull public KotlinType safeGetType( @NotNull LexicalScope scope, @NotNull KtExpression expression, @NotNull KotlinType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace) { KotlinType type = getType(scope, expression, expectedType, dataFlowInfo, trace); return type != null ? type : ErrorUtils.createErrorType("Type for " + expression.getText()); }
@Nullable @Override protected TextRange surroundStatements( Project project, Editor editor, PsiElement container, PsiElement[] statements) { statements = MoveDeclarationsOutHelper.move(container, statements, isGenerateDefaultInitializers()); if (statements.length == 0) { KotlinSurrounderUtils.showErrorHint( project, editor, KotlinSurrounderUtils.SURROUND_WITH_ERROR); return null; } KtIfExpression ifExpression = (KtIfExpression) KtPsiFactoryKt.KtPsiFactory(project).createExpression(getCodeTemplate()); ifExpression = (KtIfExpression) container.addAfter(ifExpression, statements[statements.length - 1]); // TODO move a comment for first statement KtBlockExpression thenBranch = (KtBlockExpression) ifExpression.getThen(); assert thenBranch != null : "Then branch should exist for created if expression: " + ifExpression.getText(); // Add statements in then branch of created if KotlinSurrounderUtils.addStatementsInBlock(thenBranch, statements); // Delete statements from original code container.deleteChildRange(statements[0], statements[statements.length - 1]); ifExpression = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(ifExpression); KtExpression condition = ifExpression.getCondition(); assert condition != null : "Condition should exists for created if expression: " + ifExpression.getText(); // Delete condition from created if TextRange range = condition.getTextRange(); TextRange textRange = new TextRange(range.getStartOffset(), range.getStartOffset()); editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset()); return textRange; }
/** * Visits block statements propagating data flow information from the first to the last. * Determines block returned type and data flow information at the end of the block AND at the * nearest jump point from the block beginning. */ /*package*/ KotlinTypeInfo getBlockReturnedTypeWithWritableScope( @NotNull LexicalWritableScope scope, @NotNull List<? extends KtElement> block, @NotNull CoercionStrategy coercionStrategyForLastExpression, @NotNull ExpressionTypingContext context) { if (block.isEmpty()) { return TypeInfoFactoryKt.createTypeInfo( expressionTypingComponents.builtIns.getUnitType(), context); } ExpressionTypingInternals blockLevelVisitor = new ExpressionTypingVisitorDispatcher.ForBlock( expressionTypingComponents, annotationChecker, scope); ExpressionTypingContext newContext = context.replaceScope(scope).replaceExpectedType(NO_EXPECTED_TYPE); KotlinTypeInfo result = TypeInfoFactoryKt.noTypeInfo(context); // Jump point data flow info DataFlowInfo beforeJumpInfo = newContext.dataFlowInfo; boolean jumpOutPossible = false; for (Iterator<? extends KtElement> iterator = block.iterator(); iterator.hasNext(); ) { KtElement statement = iterator.next(); if (!(statement instanceof KtExpression)) { continue; } KtExpression statementExpression = (KtExpression) statement; if (!iterator.hasNext()) { result = getTypeOfLastExpressionInBlock( statementExpression, newContext.replaceExpectedType(context.expectedType), coercionStrategyForLastExpression, blockLevelVisitor); if (result.getType() != null && statementExpression.getParent() instanceof KtBlockExpression) { DataFlowValue lastExpressionValue = DataFlowValueFactory.createDataFlowValue( statementExpression, result.getType(), context); DataFlowValue blockExpressionValue = DataFlowValueFactory.createDataFlowValue( (KtBlockExpression) statementExpression.getParent(), result.getType(), context); result = result.replaceDataFlowInfo( result.getDataFlowInfo().assign(blockExpressionValue, lastExpressionValue)); } } else { result = blockLevelVisitor.getTypeInfo( statementExpression, newContext.replaceContextDependency(ContextDependency.INDEPENDENT), true); } DataFlowInfo newDataFlowInfo = result.getDataFlowInfo(); // If jump is not possible, we take new data flow info before jump if (!jumpOutPossible) { beforeJumpInfo = result.getJumpFlowInfo(); jumpOutPossible = result.getJumpOutPossible(); } if (newDataFlowInfo != context.dataFlowInfo) { newContext = newContext.replaceDataFlowInfo(newDataFlowInfo); // We take current data flow info if jump there is not possible } blockLevelVisitor = new ExpressionTypingVisitorDispatcher.ForBlock( expressionTypingComponents, annotationChecker, scope); } return result.replaceJumpOutPossible(jumpOutPossible).replaceJumpFlowInfo(beforeJumpInfo); }