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);
}
}
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);
}
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()]);
}
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);
}
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();
}
Aggregations