@Override public void invoke(@NotNull Project project, Editor editor, KtFile file) throws IncorrectOperationException { for (KtTypeReference typeReference : getElement().getTypeArgumentsAsTypes()) { if (typeReference != null) { typeReference.replace(KtPsiFactoryKt.KtPsiFactory(file).createStar()); } } }
public static PsiElement[] move( @NotNull PsiElement container, @NotNull PsiElement[] statements, boolean generateDefaultInitializers) { if (statements.length == 0) { return statements; } Project project = container.getProject(); List<PsiElement> resultStatements = new ArrayList<PsiElement>(); List<KtProperty> propertiesDeclarations = new ArrayList<KtProperty>(); // Dummy element to add new declarations at the beginning KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(project); PsiElement dummyFirstStatement = container.addBefore(psiFactory.createExpression("dummyStatement"), statements[0]); try { SearchScope scope = new LocalSearchScope(container); int lastStatementOffset = statements[statements.length - 1].getTextRange().getEndOffset(); for (PsiElement statement : statements) { if (needToDeclareOut(statement, lastStatementOffset, scope)) { if (statement instanceof KtProperty && ((KtProperty) statement).getInitializer() != null) { KtProperty property = (KtProperty) statement; KtProperty declaration = createVariableDeclaration(property, generateDefaultInitializers); declaration = (KtProperty) container.addBefore(declaration, dummyFirstStatement); propertiesDeclarations.add(declaration); container.addAfter(psiFactory.createNewLine(), declaration); KtBinaryExpression assignment = createVariableAssignment(property); resultStatements.add(property.replace(assignment)); } else { PsiElement newStatement = container.addBefore(statement, dummyFirstStatement); container.addAfter(psiFactory.createNewLine(), newStatement); container.deleteChildRange(statement, statement); } } else { resultStatements.add(statement); } } } finally { dummyFirstStatement.delete(); } ShortenReferences.DEFAULT.process(propertiesDeclarations); return PsiUtilCore.toPsiElementArray(resultStatements); }
@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; }
@NotNull private static KtProperty createProperty( @NotNull KtProperty property, @NotNull KotlinType propertyType, @Nullable String initializer) { KtTypeReference typeRef = property.getTypeReference(); String typeString = null; if (typeRef != null) { typeString = typeRef.getText(); } else if (!propertyType.isError()) { typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(propertyType); } return KtPsiFactoryKt.KtPsiFactory(property) .createProperty(property.getName(), typeString, property.isVar(), initializer); }
public KotlinTypeInfo visitIfExpression( KtIfExpression ifExpression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) { ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE); KtExpression condition = ifExpression.getCondition(); DataFlowInfo conditionDataFlowInfo = checkCondition(context.scope, condition, context); KtExpression elseBranch = ifExpression.getElse(); KtExpression thenBranch = ifExpression.getThen(); LexicalWritableScope thenScope = newWritableScopeImpl(context, "Then scope"); LexicalWritableScope elseScope = newWritableScopeImpl(context, "Else scope"); DataFlowInfo thenInfo = components .dataFlowAnalyzer .extractDataFlowInfoFromCondition(condition, true, context) .and(conditionDataFlowInfo); DataFlowInfo elseInfo = components .dataFlowAnalyzer .extractDataFlowInfoFromCondition(condition, false, context) .and(conditionDataFlowInfo); if (elseBranch == null) { if (thenBranch != null) { KotlinTypeInfo result = getTypeInfoWhenOnlyOneBranchIsPresent( thenBranch, thenScope, thenInfo, elseInfo, contextWithExpectedType, ifExpression, isStatement); // If jump was possible, take condition check info as the jump info return result.getJumpOutPossible() ? result.replaceJumpOutPossible(true).replaceJumpFlowInfo(conditionDataFlowInfo) : result; } return TypeInfoFactoryKt.createTypeInfo( components.dataFlowAnalyzer.checkImplicitCast( components.builtIns.getUnitType(), ifExpression, contextWithExpectedType, isStatement), thenInfo.or(elseInfo)); } if (thenBranch == null) { return getTypeInfoWhenOnlyOneBranchIsPresent( elseBranch, elseScope, elseInfo, thenInfo, contextWithExpectedType, ifExpression, isStatement); } KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(ifExpression); KtBlockExpression thenBlock = psiFactory.wrapInABlockWrapper(thenBranch); KtBlockExpression elseBlock = psiFactory.wrapInABlockWrapper(elseBranch); Call callForIf = createCallForSpecialConstruction( ifExpression, ifExpression, Lists.newArrayList(thenBlock, elseBlock)); MutableDataFlowInfoForArguments dataFlowInfoForArguments = createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo); ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall( callForIf, ResolveConstruct.IF, Lists.newArrayList("thenBranch", "elseBranch"), Lists.newArrayList(false, false), contextWithExpectedType, dataFlowInfoForArguments); BindingContext bindingContext = context.trace.getBindingContext(); KotlinTypeInfo thenTypeInfo = BindingContextUtils.getRecordedTypeInfo(thenBranch, bindingContext); KotlinTypeInfo elseTypeInfo = BindingContextUtils.getRecordedTypeInfo(elseBranch, bindingContext); assert thenTypeInfo != null : "'Then' branch of if expression was not processed: " + ifExpression; assert elseTypeInfo != null : "'Else' branch of if expression was not processed: " + ifExpression; boolean loopBreakContinuePossible = thenTypeInfo.getJumpOutPossible() || elseTypeInfo.getJumpOutPossible(); KotlinType thenType = thenTypeInfo.getType(); KotlinType elseType = elseTypeInfo.getType(); DataFlowInfo thenDataFlowInfo = thenTypeInfo.getDataFlowInfo(); DataFlowInfo elseDataFlowInfo = elseTypeInfo.getDataFlowInfo(); boolean jumpInThen = thenType != null && KotlinBuiltIns.isNothing(thenType); boolean jumpInElse = elseType != null && KotlinBuiltIns.isNothing(elseType); DataFlowInfo resultDataFlowInfo; if (thenType == null && elseType == null) { resultDataFlowInfo = thenDataFlowInfo.or(elseDataFlowInfo); } else if (thenType == null || (jumpInThen && !jumpInElse)) { resultDataFlowInfo = elseDataFlowInfo; } else if (elseType == null || (jumpInElse && !jumpInThen)) { resultDataFlowInfo = thenDataFlowInfo; } else { resultDataFlowInfo = thenDataFlowInfo.or(elseDataFlowInfo); } KotlinType resultType = resolvedCall.getResultingDescriptor().getReturnType(); // If break or continue was possible, take condition check info as the jump info return TypeInfoFactoryKt.createTypeInfo( components.dataFlowAnalyzer.checkImplicitCast( resultType, ifExpression, contextWithExpectedType, isStatement), resultDataFlowInfo, loopBreakContinuePossible, conditionDataFlowInfo); }