Search in sources :

Example 6 with TypeMigrationUsageInfo

use of com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo in project intellij-community by JetBrains.

the class TypeMigrationLabeler method setRootAndMigrate.

public void setRootAndMigrate(final TypeMigrationUsageInfo newRootUsageInfo, final PsiType migrationType, final PsiReference[] usages) {
    final TypeMigrationUsageInfo oldRoot = getCurrentRoot();
    myCurrentRoot = newRootUsageInfo;
    PsiElement root = newRootUsageInfo.getElement();
    if (root instanceof PsiMethod) {
        migrateMethodReturnExpression(migrationType, (PsiMethod) root);
    } else if (root instanceof PsiParameter && ((PsiParameter) root).getDeclarationScope() instanceof PsiMethod) {
        migrateMethodCallExpressions(migrationType, (PsiParameter) root, null);
    } else if (root instanceof PsiVariable || root instanceof PsiExpression) {
        final PsiElement element = getContainingStatement(root);
        if (root instanceof PsiExpression) {
            migrateExpressionType((PsiExpression) root, migrationType, element, false, true);
            myTypeEvaluator.setType(newRootUsageInfo, migrationType);
        }
        element.accept(new TypeMigrationStatementProcessor(element, this));
    } else if (root instanceof PsiReferenceParameterList) {
        final TypeMigrationUsageInfo info = new TypeMigrationUsageInfo(root);
        info.setOwnerRoot(oldRoot);
        myClassTypeArgumentsChange.put(info, (PsiClassType) migrationType);
        new ClassTypeArgumentMigrationProcessor(this).migrateClassTypeParameter((PsiReferenceParameterList) root, (PsiClassType) migrationType);
    }
    final Set<PsiElement> processed = new HashSet<>();
    for (PsiReference usage : usages) {
        migrateRootUsageExpression(usage, processed);
    }
}
Also used : TypeMigrationUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo)

Example 7 with TypeMigrationUsageInfo

use of com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo in project intellij-community by JetBrains.

the class TypeMigrationLabeler method migrateExpressionType.

public void migrateExpressionType(final PsiExpression expr, final PsiType migrationType, final PsiElement place, boolean alreadyProcessed, final boolean isCovariant) {
    PsiType originalType = expr.getType();
    if (originalType == null || originalType.equals(migrationType))
        return;
    if (originalType.equals(PsiType.NULL)) {
        if (migrationType instanceof PsiPrimitiveType) {
            markFailedConversion(Pair.create(originalType, migrationType), expr);
        }
        return;
    }
    if (expr instanceof PsiConditionalExpression) {
        final PsiConditionalExpression condExpr = (PsiConditionalExpression) expr;
        for (PsiExpression e : ContainerUtil.newArrayList(condExpr.getThenExpression(), condExpr.getElseExpression())) {
            if (e != null) {
                migrateExpressionType(e, migrationType, place, alreadyProcessed, false);
            }
        }
        getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), migrationType);
        return;
    } else if (expr instanceof PsiClassObjectAccessExpression) {
        if (!TypeConversionUtil.isAssignable(migrationType, expr.getType())) {
            markFailedConversion(Pair.create(expr.getType(), migrationType), expr);
            return;
        }
    } else if (expr instanceof PsiArrayInitializerExpression && migrationType instanceof PsiArrayType) {
        final PsiExpression[] initializers = ((PsiArrayInitializerExpression) expr).getInitializers();
        for (PsiExpression initializer : initializers) {
            migrateExpressionType(initializer, ((PsiArrayType) migrationType).getComponentType(), expr, alreadyProcessed, true);
        }
        getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), migrationType);
        return;
    } else if (expr instanceof PsiArrayAccessExpression) {
        migrateExpressionType(((PsiArrayAccessExpression) expr).getArrayExpression(), migrationType.createArrayType(), place, alreadyProcessed, isCovariant);
        return;
    } else if (expr instanceof PsiReferenceExpression) {
        final PsiElement resolved = ((PsiReferenceExpression) expr).resolve();
        if (resolved != null) {
            if (!addMigrationRoot(resolved, migrationType, place, alreadyProcessed, !isCovariant)) {
                convertExpression(expr, migrationType, getTypeEvaluator().evaluateType(expr), isCovariant);
            }
        }
        return;
    } else if (expr instanceof PsiMethodCallExpression) {
        final PsiMethod resolved = ((PsiMethodCallExpression) expr).resolveMethod();
        if (resolved != null) {
            if (!addMigrationRoot(resolved, migrationType, place, alreadyProcessed, !isCovariant)) {
                convertExpression(expr, migrationType, getTypeEvaluator().evaluateType(expr), isCovariant);
            }
        }
        return;
    } else if (expr instanceof PsiNewExpression) {
        if (originalType.getArrayDimensions() == migrationType.getArrayDimensions()) {
            if (migrationType.getArrayDimensions() > 0) {
                final PsiType elementType = ((PsiArrayType) migrationType).getComponentType();
                final PsiArrayInitializerExpression arrayInitializer = ((PsiNewExpression) expr).getArrayInitializer();
                if (arrayInitializer != null) {
                    final PsiExpression[] initializers = arrayInitializer.getInitializers();
                    for (int i = initializers.length - 1; i >= 0; i--) {
                        migrateExpressionType(initializers[i], elementType, place, alreadyProcessed, true);
                    }
                }
                if (isGenericsArrayType(elementType)) {
                    markFailedConversion(Pair.create(originalType, migrationType), expr);
                    return;
                }
                final TypeMigrationUsageInfo usageInfo = new TypeMigrationUsageInfo(expr);
                usageInfo.setOwnerRoot(myCurrentRoot);
                myNewExpressionTypeChange.put(usageInfo, migrationType);
                getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), migrationType);
                return;
            } else {
                if (migrationType instanceof PsiClassType && originalType instanceof PsiClassType && ((PsiClassType) migrationType).rawType().isAssignableFrom(((PsiClassType) originalType).rawType())) {
                    final PsiClass originalClass = PsiUtil.resolveClassInType(originalType);
                    if (originalClass instanceof PsiAnonymousClass) {
                        originalType = ((PsiAnonymousClass) originalClass).getBaseClassType();
                    }
                    final PsiType type = TypeEvaluator.substituteType(migrationType, originalType, true, ((PsiClassType) originalType).resolveGenerics().getElement(), JavaPsiFacade.getElementFactory(expr.getProject()).createType(((PsiClassType) originalType).resolve(), PsiSubstitutor.EMPTY));
                    if (type != null) {
                        final TypeMigrationUsageInfo usageInfo = new TypeMigrationUsageInfo(expr);
                        usageInfo.setOwnerRoot(myCurrentRoot);
                        myNewExpressionTypeChange.put(usageInfo, type);
                        getTypeEvaluator().setType(new TypeMigrationUsageInfo(expr), type);
                        return;
                    }
                }
            }
        }
    } else if (expr instanceof PsiLambdaExpression) {
        //TODO conversion of lambda expression now works incorrectly [Dmitry Batkovich]
        return;
    }
    convertExpression(expr, migrationType, originalType, isCovariant);
}
Also used : TypeMigrationUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo)

Example 8 with TypeMigrationUsageInfo

use of com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo in project intellij-community by JetBrains.

the class TypeMigrationLabeler method markRootUsages.

PsiReference[] markRootUsages(final PsiElement element, final PsiType migrationType, final PsiReference[] refs) {
    final List<PsiReference> validReferences = new ArrayList<>();
    for (PsiReference ref1 : refs) {
        final PsiElement ref = ref1.getElement();
        if (ref != null) {
            if (element instanceof PsiMethod) {
                final PsiElement parent = Util.getEssentialParent(ref);
                if (!(parent instanceof PsiMethodCallExpression)) {
                    continue;
                }
                getTypeEvaluator().setType(new TypeMigrationUsageInfo(parent), migrationType);
            } else if (element instanceof PsiVariable) {
                if (ref instanceof PsiReferenceExpression) {
                    getTypeEvaluator().setType(new TypeMigrationUsageInfo(ref), PsiUtil.captureToplevelWildcards(migrationType, ref));
                }
            } else {
                LOG.error("Method call expression or reference expression expected but found " + element.getClass().getName());
                continue;
            }
            validReferences.add(ref1);
        }
    }
    Collections.sort(validReferences, Comparator.comparingInt(o -> o.getElement().getTextOffset()));
    return validReferences.toArray(new PsiReference[validReferences.size()]);
}
Also used : PsiImmediateClassType(com.intellij.psi.impl.source.PsiImmediateClassType) TypeConversionUtil(com.intellij.psi.util.TypeConversionUtil) java.util(java.util) PsiDocTagValue(com.intellij.psi.javadoc.PsiDocTagValue) OverriddenUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.OverriddenUsageInfo) DFSTBuilder(com.intellij.util.graph.DFSTBuilder) UsageInfo(com.intellij.usageView.UsageInfo) SearchScope(com.intellij.psi.search.SearchScope) PsiExtendedTypeVisitor(com.intellij.refactoring.typeCook.deductive.PsiExtendedTypeVisitor) ContainerUtil(com.intellij.util.containers.ContainerUtil) THashMap(gnu.trove.THashMap) TypeMigrationUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) Comparing(com.intellij.openapi.util.Comparing) RenameProcessor(com.intellij.refactoring.rename.RenameProcessor) Semaphore(com.intellij.util.concurrency.Semaphore) Project(com.intellij.openapi.project.Project) PsiUtil(com.intellij.psi.util.PsiUtil) Messages(com.intellij.openapi.ui.Messages) Logger(com.intellij.openapi.diagnostic.Logger) ProjectRootManager(com.intellij.openapi.roots.ProjectRootManager) JavaLanguage(com.intellij.lang.java.JavaLanguage) MultiMap(com.intellij.util.containers.MultiMap) OverriderUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.OverriderUsageInfo) ReferencesSearch(com.intellij.psi.search.searches.ReferencesSearch) StringUtil(com.intellij.openapi.util.text.StringUtil) OverridingMethodsSearch(com.intellij.psi.search.searches.OverridingMethodsSearch) GenerateMembersUtil(com.intellij.codeInsight.generation.GenerateMembersUtil) TextRange(com.intellij.openapi.util.TextRange) TestOnly(org.jetbrains.annotations.TestOnly) Nullable(org.jetbrains.annotations.Nullable) InboundSemiGraph(com.intellij.util.graph.InboundSemiGraph) PsiSearchScopeUtil(com.intellij.psi.search.PsiSearchScopeUtil) GraphGenerator(com.intellij.util.graph.GraphGenerator) Pair(com.intellij.openapi.util.Pair) ApplicationManager(com.intellij.openapi.application.ApplicationManager) GetterSetterPrototypeProvider(com.intellij.codeInsight.generation.GetterSetterPrototypeProvider) com.intellij.psi(com.intellij.psi) com.intellij.util(com.intellij.util) NotNull(org.jetbrains.annotations.NotNull) javax.swing(javax.swing) TypeMigrationUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo)

Example 9 with TypeMigrationUsageInfo

use of com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo in project intellij-community by JetBrains.

the class TypeMigrationLabeler method getMigratedUsages.

public TypeMigrationUsageInfo[] getMigratedUsages() {
    final LinkedList<Pair<TypeMigrationUsageInfo, PsiType>> declarations = getTypeEvaluator().getMigratedDeclarations();
    final TypeMigrationUsageInfo[] usages = new TypeMigrationUsageInfo[declarations.size() + myConversions.size() + myNewExpressionTypeChange.size() + myClassTypeArgumentsChange.size()];
    int j = 0;
    for (final PsiElement element : myConversions.keySet()) {
        final Object conv = myConversions.get(element);
        usages[j++] = new TypeMigrationUsageInfo(element) {

            public String getTooltipText() {
                if (conv instanceof String) {
                    //todo
                    final String conversion = (String) conv;
                    return "Replaced with " + conversion.replaceAll("\\$", element.getText());
                } else {
                    return "Replaced with " + conv.toString();
                }
            }

            @Override
            public boolean isExcluded() {
                if (conv instanceof TypeConversionDescriptorBase)
                    return ((TypeConversionDescriptorBase) conv).getRoot().isExcluded();
                return super.isExcluded();
            }

            @Override
            public TypeMigrationUsageInfo getOwnerRoot() {
                return conv instanceof TypeConversionDescriptorBase ? ((TypeConversionDescriptorBase) conv).getRoot() : null;
            }
        };
    }
    for (final Pair<TypeMigrationUsageInfo, PsiType> p : declarations) {
        final TypeMigrationUsageInfo element = p.getFirst();
        usages[j++] = element;
    }
    for (TypeMigrationUsageInfo info : myClassTypeArgumentsChange.keySet()) {
        usages[j++] = info;
    }
    for (final TypeMigrationUsageInfo expr : myNewExpressionTypeChange.keySet()) {
        usages[j++] = expr;
    }
    return sortMigratedUsages(usages);
}
Also used : TypeMigrationUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo) Pair(com.intellij.openapi.util.Pair)

Example 10 with TypeMigrationUsageInfo

use of com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo in project intellij-community by JetBrains.

the class TypeMigrationProcessor method change.

public static void change(UsageInfo[] usages, TypeMigrationLabeler labeler, Project project) {
    final List<SmartPsiElementPointer<PsiNewExpression>> newExpressionsToCheckDiamonds = new SmartList<>();
    final TypeMigrationLabeler.MigrationProducer producer = labeler.createMigratorFor(usages);
    final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project);
    List<UsageInfo> nonCodeUsages = new ArrayList<>();
    for (UsageInfo usage : usages) {
        if (((TypeMigrationUsageInfo) usage).isExcluded())
            continue;
        final PsiElement element = usage.getElement();
        if (element instanceof PsiVariable || element instanceof PsiMember || element instanceof PsiExpression || element instanceof PsiReferenceParameterList) {
            producer.change((TypeMigrationUsageInfo) usage, expression -> newExpressionsToCheckDiamonds.add(smartPointerManager.createSmartPsiElementPointer(expression)));
        } else {
            nonCodeUsages.add(usage);
        }
    }
    for (SmartPsiElementPointer<PsiNewExpression> newExpressionPointer : newExpressionsToCheckDiamonds) {
        final PsiNewExpression newExpression = newExpressionPointer.getElement();
        if (newExpression != null) {
            labeler.postProcessNewExpression(newExpression);
        }
    }
    for (UsageInfo usageInfo : nonCodeUsages) {
        final PsiElement element = usageInfo.getElement();
        if (element != null) {
            final PsiReference reference = element.getReference();
            if (reference != null) {
                final Object target = producer.getConversion(usageInfo);
                if (target instanceof PsiMember) {
                    try {
                        reference.bindToElement((PsiElement) target);
                    } catch (IncorrectOperationException ignored) {
                    }
                }
            }
        }
    }
    producer.flush();
}
Also used : TypeMigrationUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo) UsageInfo(com.intellij.usageView.UsageInfo) TypeMigrationUsageInfo(com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo)

Aggregations

TypeMigrationUsageInfo (com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo)17 Pair (com.intellij.openapi.util.Pair)7 NotNull (org.jetbrains.annotations.NotNull)5 UsageInfo (com.intellij.usageView.UsageInfo)4 Logger (com.intellij.openapi.diagnostic.Logger)3 Comparing (com.intellij.openapi.util.Comparing)3 StringUtil (com.intellij.openapi.util.text.StringUtil)3 com.intellij.psi (com.intellij.psi)3 PsiImmediateClassType (com.intellij.psi.impl.source.PsiImmediateClassType)3 PsiTreeUtil (com.intellij.psi.util.PsiTreeUtil)3 PsiUtil (com.intellij.psi.util.PsiUtil)3 TypeConversionUtil (com.intellij.psi.util.TypeConversionUtil)3 PsiExtendedTypeVisitor (com.intellij.refactoring.typeCook.deductive.PsiExtendedTypeVisitor)3 OverriddenUsageInfo (com.intellij.refactoring.typeMigration.usageInfo.OverriddenUsageInfo)3 OverriderUsageInfo (com.intellij.refactoring.typeMigration.usageInfo.OverriderUsageInfo)3 Nullable (org.jetbrains.annotations.Nullable)3 GenerateMembersUtil (com.intellij.codeInsight.generation.GenerateMembersUtil)2 GetterSetterPrototypeProvider (com.intellij.codeInsight.generation.GetterSetterPrototypeProvider)2 JavaLanguage (com.intellij.lang.java.JavaLanguage)2 ApplicationManager (com.intellij.openapi.application.ApplicationManager)2