public static void foldWhenExpressionWithReturns(JetWhenExpression whenExpression) { Project project = whenExpression.getProject(); assert !whenExpression.getEntries().isEmpty() : FOLD_WITHOUT_CHECK; JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, whenExpression); JetWhenExpression newWhenExpression = (JetWhenExpression) newReturnExpression.getReturnedExpression(); assertNotNull(newWhenExpression); //noinspection ConstantConditions for (JetWhenEntry entry : newWhenExpression.getEntries()) { JetReturnExpression currReturn = getFoldableBranchedReturn(entry.getExpression()); assertNotNull(currReturn); JetExpression currExpr = currReturn.getReturnedExpression(); assertNotNull(currExpr); //noinspection ConstantConditions currReturn.replace(currExpr); } whenExpression.replace(newReturnExpression); }
/** * Check that function or property with the given qualified name can be resolved in given scope * and called on given receiver * * @param callableFQN * @param project * @param scope * @return */ public static List<CallableDescriptor> canFindSuitableCall( @NotNull FqName callableFQN, @NotNull Project project, @NotNull JetExpression receiverExpression, @NotNull JetType receiverType, @NotNull JetScope scope) { JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, callableFQN.getFqName()); Collection<? extends DeclarationDescriptor> declarationDescriptors = ImportsResolver.analyseImportReference(importDirective, scope, new BindingTraceContext()); List<CallableDescriptor> callableExtensionDescriptors = new ArrayList<CallableDescriptor>(); ReceiverDescriptor receiverDescriptor = new ExpressionReceiver(receiverExpression, receiverType); for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { if (declarationDescriptor instanceof CallableDescriptor) { CallableDescriptor callableDescriptor = (CallableDescriptor) declarationDescriptor; if (checkIsExtensionCallable(receiverDescriptor, callableDescriptor)) { callableExtensionDescriptors.add(callableDescriptor); } } } return callableExtensionDescriptors; }
@SuppressWarnings("ConstantConditions") public static void foldWhenExpressionWithAssignments(JetWhenExpression whenExpression) { Project project = whenExpression.getProject(); assert !whenExpression.getEntries().isEmpty() : FOLD_WITHOUT_CHECK; JetBinaryExpression firstAssignment = getFoldableBranchedAssignment(whenExpression.getEntries().get(0).getExpression()); assertNotNull(firstAssignment); String op = firstAssignment.getOperationReference().getText(); JetSimpleNameExpression lhs = (JetSimpleNameExpression) firstAssignment.getLeft(); JetBinaryExpression assignment = JetPsiFactory.createBinaryExpression(project, lhs, op, whenExpression); JetWhenExpression newWhenExpression = (JetWhenExpression) assignment.getRight(); assertNotNull(newWhenExpression); for (JetWhenEntry entry : newWhenExpression.getEntries()) { JetBinaryExpression currAssignment = getFoldableBranchedAssignment(entry.getExpression()); assertNotNull(currAssignment); JetExpression currRhs = currAssignment.getRight(); assertNotNull(currRhs); currAssignment.replace(currRhs); } whenExpression.replace(assignment); }
public static void foldIfExpressionWithReturns(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, ifExpression); JetIfExpression newIfExpression = (JetIfExpression) newReturnExpression.getReturnedExpression(); assertNotNull(newIfExpression); //noinspection ConstantConditions JetReturnExpression thenReturn = getFoldableBranchedReturn(newIfExpression.getThen()); JetReturnExpression elseReturn = getFoldableBranchedReturn(newIfExpression.getElse()); assertNotNull(thenReturn); assertNotNull(elseReturn); JetExpression thenExpr = thenReturn.getReturnedExpression(); JetExpression elseExpr = elseReturn.getReturnedExpression(); assertNotNull(thenExpr); assertNotNull(elseExpr); //noinspection ConstantConditions thenReturn.replace(thenExpr); //noinspection ConstantConditions elseReturn.replace(elseExpr); ifExpression.replace(newReturnExpression); }
@Override public void invoke(@NotNull Project project, Editor editor, @NotNull JetFile file) throws IncorrectOperationException { JetPsiFactory factory = new JetPsiFactory(annotationClass.getProject()); JetModifierList list = annotationClass.getModifierList(); String annotation = KotlinBuiltIns.FQ_NAMES.annotation.shortName().asString(); PsiElement added; if (list == null) { JetModifierList newModifierList = factory.createModifierList(annotation); added = annotationClass.addBefore(newModifierList, annotationClass.getClassOrInterfaceKeyword()); } else { JetAnnotationEntry entry = factory.createAnnotationEntry(annotation); added = list.addBefore(entry, list.getFirstChild()); } annotationClass.addAfter(factory.createWhiteSpace(), added); }
@NotNull public static JetExpression createStubExpressionOfNecessaryType( @NotNull Project project, @NotNull JetType type, @NotNull BindingTrace trace) { JetExpression expression = JetPsiFactory.createExpression(project, "$e"); trace.record(PROCESSED, expression); trace.record(EXPRESSION_TYPE, expression, type); return expression; }
public static void foldIfExpressionWithAsymmetricReturns(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); JetExpression condition = ifExpression.getCondition(); JetExpression thenRoot = ifExpression.getThen(); JetExpression elseRoot = (JetExpression) JetPsiUtil.skipTrailingWhitespacesAndComments(ifExpression); assertNotNull(condition); assertNotNull(thenRoot); assertNotNull(elseRoot); //noinspection ConstantConditions JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, newIfExpression); newIfExpression = (JetIfExpression) newReturnExpression.getReturnedExpression(); assertNotNull(newIfExpression); //noinspection ConstantConditions JetReturnExpression thenReturn = getFoldableBranchedReturn(newIfExpression.getThen()); JetReturnExpression elseReturn = getFoldableBranchedReturn(newIfExpression.getElse()); assertNotNull(thenReturn); assertNotNull(elseReturn); JetExpression thenExpr = thenReturn.getReturnedExpression(); JetExpression elseExpr = elseReturn.getReturnedExpression(); assertNotNull(thenExpr); assertNotNull(elseExpr); //noinspection ConstantConditions thenReturn.replace(thenExpr); //noinspection ConstantConditions elseReturn.replace(elseExpr); elseRoot.delete(); ifExpression.replace(newReturnExpression); }
private void changeParameter( int parameterIndex, JetParameter parameter, JetParameterInfo parameterInfo) { ASTNode valOrVarAstNode = parameter.getValOrVarNode(); PsiElement valOrVarNode = valOrVarAstNode != null ? valOrVarAstNode.getPsi() : null; JetValVar valOrVar = parameterInfo.getValOrVar(); JetPsiFactory psiFactory = JetPsiFactory(getProject()); if (valOrVarNode != null) { if (valOrVar == JetValVar.None) { valOrVarNode.delete(); } else { valOrVarNode.replace(psiFactory.createValOrVarNode(valOrVar.toString()).getPsi()); } } else if (valOrVar != JetValVar.None) { PsiElement firstChild = parameter.getFirstChild(); parameter.addBefore(psiFactory.createValOrVarNode(valOrVar.toString()).getPsi(), firstChild); parameter.addBefore(psiFactory.createWhiteSpace(), firstChild); } if (parameterInfo.getIsTypeChanged() && parameter.getTypeReference() != null) { String renderedType = parameterInfo.renderType(parameterIndex, this); parameter.setTypeReference(psiFactory.createType(renderedType)); } PsiElement identifier = parameter.getNameIdentifier(); if (identifier != null) { //noinspection unchecked String newName = parameterInfo.getInheritedName((JetFunctionDefinitionUsage<PsiElement>) this); identifier.replace(psiFactory.createIdentifier(newName)); } }
public AlternativeMethodSignatureData( @NotNull ExternalAnnotationResolver externalAnnotationResolver, @NotNull JavaMethod method, @Nullable JetType receiverType, @NotNull Project project, @NotNull List<ValueParameterDescriptor> valueParameters, @Nullable JetType originalReturnType, @NotNull List<TypeParameterDescriptor> methodTypeParameters, boolean hasSuperMethods) { String signature = SignaturesUtil.getKotlinSignature(externalAnnotationResolver, method); if (signature == null) { setAnnotated(false); altFunDeclaration = null; return; } if (receiverType != null) { throw new UnsupportedOperationException( "Alternative annotations for extension functions are not supported yet"); } setAnnotated(true); altFunDeclaration = JetPsiFactory.createFunction(project, signature); originalToAltTypeParameters = DescriptorResolverUtils.recreateTypeParametersAndReturnMapping(methodTypeParameters, null); try { checkForSyntaxErrors(altFunDeclaration); checkEqualFunctionNames(altFunDeclaration, method); computeTypeParameters(methodTypeParameters); computeValueParameters(valueParameters); if (originalReturnType != null) { altReturnType = computeReturnType( originalReturnType, altFunDeclaration.getReturnTypeRef(), originalToAltTypeParameters); } if (hasSuperMethods) { checkParameterAndReturnTypesForOverridingMethods( valueParameters, methodTypeParameters, originalReturnType); } } catch (AlternativeSignatureMismatchException e) { setError(e.getMessage()); } }
public static void addImportDirective( @NotNull ImportPath importPath, @Nullable String aliasName, @NotNull JetFile file) { if (!doNeedImport(importPath, aliasName, file)) { return; } JetImportDirective newDirective = JetPsiFactory.createImportDirective(file.getProject(), importPath, aliasName); List<JetImportDirective> importDirectives = file.getImportDirectives(); if (!importDirectives.isEmpty()) { JetImportDirective lastDirective = importDirectives.get(importDirectives.size() - 1); lastDirective.getParent().addAfter(newDirective, lastDirective); } else { file.getNamespaceHeader().getParent().addAfter(newDirective, file.getNamespaceHeader()); } }
public static void writeImportToFile(ImportPath importPath, JetFile file) { JetImportDirective newDirective = JetPsiFactory.createImportDirective(file.getProject(), importPath); List<JetImportDirective> importDirectives = file.getImportDirectives(); if (!importDirectives.isEmpty()) { JetImportDirective lastDirective = importDirectives.get(importDirectives.size() - 1); lastDirective.getParent().addAfter(newDirective, lastDirective); } else { JetNamespaceHeader header = file.getNamespaceHeader(); if (header == null) { throw new IllegalStateException("Scripts are not supported: " + file.getName()); } header.getParent().addAfter(newDirective, file.getNamespaceHeader()); } }
public static boolean isVariableIterable( @NotNull ExpressionTypingServices expressionTypingServices, @NotNull Project project, @NotNull VariableDescriptor variableDescriptor, @NotNull JetScope scope) { JetExpression expression = JetPsiFactory.createExpression(project, "fake"); ExpressionReceiver expressionReceiver = new ExpressionReceiver(expression, variableDescriptor.getType()); ExpressionTypingContext context = ExpressionTypingContext.newContext( expressionTypingServices, new HashMap<JetPattern, DataFlowInfo>(), new HashMap<JetPattern, List<VariableDescriptor>>(), new LabelResolver(), new BindingTraceContext(), scope, DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE, false); return ControlStructureTypingVisitor.checkIterableConvention(expressionReceiver, context) != null; }
public static void foldIfExpressionWithAssignments(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); JetBinaryExpression thenAssignment = getFoldableBranchedAssignment(ifExpression.getThen()); assertNotNull(thenAssignment); String op = thenAssignment.getOperationReference().getText(); JetSimpleNameExpression lhs = (JetSimpleNameExpression) thenAssignment.getLeft(); JetBinaryExpression assignment = JetPsiFactory.createBinaryExpression(project, lhs, op, ifExpression); JetIfExpression newIfExpression = (JetIfExpression) assignment.getRight(); assertNotNull(newIfExpression); //noinspection ConstantConditions thenAssignment = getFoldableBranchedAssignment(newIfExpression.getThen()); JetBinaryExpression elseAssignment = getFoldableBranchedAssignment(newIfExpression.getElse()); assertNotNull(thenAssignment); assertNotNull(elseAssignment); JetExpression thenRhs = thenAssignment.getRight(); JetExpression elseRhs = elseAssignment.getRight(); assertNotNull(thenRhs); assertNotNull(elseRhs); //noinspection ConstantConditions thenAssignment.replace(thenRhs); //noinspection ConstantConditions elseAssignment.replace(elseRhs); ifExpression.replace(assignment); }
private void processParameterListWithStructuralChanges( JetChangeInfo changeInfo, PsiElement element, JetParameterList parameterList, JetPsiFactory psiFactory) { int parametersCount = changeInfo.getNonReceiverParametersCount(); boolean isLambda = element instanceof JetFunctionLiteral; boolean canReplaceEntireList = false; JetParameterList newParameterList = null; if (isLambda) { if (parametersCount == 0 && ((JetFunctionLiteral) element).getTypeReference() == null) { if (parameterList != null) { parameterList.delete(); ASTNode arrowNode = ((JetFunctionLiteral) element).getArrowNode(); if (arrowNode != null) { arrowNode.getPsi().delete(); } parameterList = null; } } else { newParameterList = psiFactory.createFunctionLiteralParameterList( changeInfo.getNewParametersSignature( (JetFunctionDefinitionUsage<PsiElement>) this)); canReplaceEntireList = true; } } else { newParameterList = psiFactory.createParameterList( changeInfo.getNewParametersSignature((JetFunctionDefinitionUsage<PsiElement>) this)); } if (newParameterList == null) return; if (parameterList != null) { if (canReplaceEntireList) { newParameterList = (JetParameterList) parameterList.replace(newParameterList); } else { newParameterList = replaceParameterListAndKeepDelimiters(parameterList, newParameterList); } } else { if (element instanceof JetClass) { PsiElement anchor = ((JetClass) element).getTypeParameterList(); if (anchor == null) { anchor = ((JetClass) element).getNameIdentifier(); } if (anchor != null) { JetPrimaryConstructor constructor = (JetPrimaryConstructor) element.addAfter(psiFactory.createPrimaryConstructor(), anchor); JetParameterList oldParameterList = constructor.getValueParameterList(); assert oldParameterList != null : "primary constructor from factory has parameter list"; newParameterList = (JetParameterList) oldParameterList.replace(newParameterList); } } else if (isLambda) { //noinspection ConstantConditions JetFunctionLiteral functionLiteral = (JetFunctionLiteral) element; PsiElement anchor = functionLiteral.getLBrace(); newParameterList = (JetParameterList) element.addAfter(newParameterList, anchor); if (functionLiteral.getArrowNode() == null) { Pair<PsiElement, PsiElement> whitespaceAndArrow = psiFactory.createWhitespaceAndArrow(); element.addRangeAfter( whitespaceAndArrow.getFirst(), whitespaceAndArrow.getSecond(), newParameterList); } } } if (newParameterList != null) { ShortenPackage.addToShorteningWaitSet(newParameterList, Options.DEFAULT); } }
@Override public boolean processUsage(JetChangeInfo changeInfo, PsiElement element) { JetParameterList parameterList; JetPsiFactory psiFactory = JetPsiFactory(element.getProject()); if (element instanceof JetFunction) { JetFunction function = (JetFunction) element; parameterList = function.getValueParameterList(); if (changeInfo.isNameChanged()) { PsiElement identifier = function.getNameIdentifier(); if (identifier != null) { identifier.replace(psiFactory.createIdentifier(changeInfo.getNewName())); } } boolean returnTypeIsNeeded = (changeInfo.isRefactoringTarget(originalFunctionDescriptor) || !(function instanceof JetFunctionLiteral) || function.getTypeReference() != null) && !(function instanceof JetSecondaryConstructor); if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) { function.setTypeReference(null); String returnTypeText = changeInfo.renderReturnType((JetFunctionDefinitionUsage<PsiElement>) this); // TODO use ChangeFunctionReturnTypeFix.invoke when JetTypeCodeFragment.getType() is ready if (!KotlinBuiltIns.getInstance().getUnitType().toString().equals(returnTypeText)) { ShortenPackage.addToShorteningWaitSet( function.setTypeReference(JetPsiFactory(function).createType(returnTypeText)), Options.DEFAULT); } } } else { parameterList = ((JetClass) element).getPrimaryConstructorParameterList(); } if (changeInfo.isParameterSetOrOrderChanged()) { processParameterListWithStructuralChanges(changeInfo, element, parameterList, psiFactory); } else if (parameterList != null) { int paramIndex = 0; for (JetParameter parameter : parameterList.getParameters()) { JetParameterInfo parameterInfo = changeInfo.getNewParameters()[paramIndex]; changeParameter(paramIndex, parameter, parameterInfo); paramIndex++; } ShortenPackage.addToShorteningWaitSet(parameterList, Options.DEFAULT); } if (element instanceof JetFunction && changeInfo.isReceiverTypeChanged()) { //noinspection unchecked String receiverTypeText = changeInfo.renderReceiverType((JetFunctionDefinitionUsage<PsiElement>) this); JetTypeReference receiverTypeRef = receiverTypeText != null ? psiFactory.createType(receiverTypeText) : null; JetTypeReference newReceiverTypeRef = TypeRefHelpersPackage.setReceiverTypeReference((JetFunction) element, receiverTypeRef); if (newReceiverTypeRef != null) { ShortenPackage.addToShorteningWaitSet( newReceiverTypeRef, ShortenReferences.Options.DEFAULT); } } if (changeInfo.isVisibilityChanged() && !JetPsiUtil.isLocal((JetDeclaration) element)) { changeVisibility(changeInfo, element); } return true; }
@NotNull public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName( @NotNull String name, @NotNull JetSimpleNameExpression expression, @NotNull ResolveSession resolveSession, @NotNull GlobalSearchScope scope) { // name parameter can differ from expression.getReferenceName() when expression contains // completion suffix Name referenceName = expression.getIdentifier() == null ? JetPsiUtil.getConventionName(expression) : Name.identifier(name); if (referenceName == null || referenceName.toString().isEmpty()) { return Collections.emptyList(); } BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression); JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); if (jetScope == null) { return Collections.emptyList(); } Set<FunctionDescriptor> result = Sets.newHashSet(); Collection<PsiMethod> topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName( referenceName.getName(), project, scope); for (PsiMethod method : topLevelFunctionPrototypes) { FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); if (functionFQN != null) { JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, new ImportPath(functionFQN, false)); Collection<? extends DeclarationDescriptor> declarationDescriptors = new QualifiedExpressionResolver() .analyseImportReference( importDirective, jetScope, new BindingTraceContext(), resolveSession.getModuleConfiguration()); for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { if (declarationDescriptor instanceof FunctionDescriptor) { result.add((FunctionDescriptor) declarationDescriptor); } } } } Set<FqName> affectedPackages = Sets.newHashSet(); Collection<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(referenceName.getName(), project, scope); for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { PsiFile containingFile = jetNamedFunction.getContainingFile(); if (containingFile instanceof JetFile) { JetFile jetFile = (JetFile) containingFile; String packageName = jetFile.getPackageName(); if (packageName != null) { affectedPackages.add(new FqName(packageName)); } } } for (FqName affectedPackage : affectedPackages) { NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName(affectedPackage); assert packageDescriptor != null : "There's a function in stub index with invalid package: " + affectedPackage; JetScope memberScope = packageDescriptor.getMemberScope(); result.addAll(memberScope.getFunctions(referenceName)); } return result; }