mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] return true type of a list literal in initializer position
Handle list literals in array context individually in the generator. Extract new method isCastNeeded(), use Java assignability rules.
This commit is contained in:
+5
-8
@@ -16,11 +16,13 @@
|
||||
package org.jetbrains.plugins.groovy.lang.typing
|
||||
|
||||
import com.intellij.openapi.util.RecursionManager
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.util.InheritanceUtil.isInheritor
|
||||
import com.intellij.psi.util.PsiUtil.substituteTypeParameter
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil
|
||||
@@ -34,7 +36,7 @@ class DefaultListOrMapTypeCalculator : GrTypeCalculator<GrListOrMap> {
|
||||
return getMapTypeFromDiamond(expression) ?: GrMapType.createFromNamedArgs(expression, expression.namedArguments)
|
||||
}
|
||||
else {
|
||||
return getArrayTypeFromDeclaration(expression) ?: getListTypeFromDiamond(expression) ?: getTupleType(expression)
|
||||
return getListTypeFromDiamond(expression) ?: getTupleType(expression)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,11 +76,6 @@ class DefaultListOrMapTypeCalculator : GrTypeCalculator<GrListOrMap> {
|
||||
)
|
||||
}
|
||||
|
||||
private fun getArrayTypeFromDeclaration(expression: GrListOrMap): PsiType? {
|
||||
val parent = expression.parent?.parent as? GrVariableDeclaration
|
||||
return parent?.typeElementGroovy?.type as? PsiArrayType
|
||||
}
|
||||
|
||||
private fun getTupleType(expression: GrListOrMap): PsiType? {
|
||||
val initializers = expression.initializers
|
||||
|
||||
|
||||
+18
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -90,19 +90,21 @@ public class ExpressionGenerator extends Generator {
|
||||
private final GroovyPsiElementFactory factory;
|
||||
|
||||
private final ExpressionContext context;
|
||||
private final @Nullable PsiType expectedType;
|
||||
|
||||
public ExpressionGenerator(StringBuilder builder, ExpressionContext context) {
|
||||
public ExpressionGenerator(StringBuilder builder, ExpressionContext context, @Nullable PsiType expectedType) {
|
||||
this.builder = builder;
|
||||
this.context = context;
|
||||
this.expectedType = expectedType;
|
||||
this.factory = GroovyPsiElementFactory.getInstance(context.project);
|
||||
}
|
||||
|
||||
factory = GroovyPsiElementFactory.getInstance(context.project);
|
||||
public ExpressionGenerator(StringBuilder builder, ExpressionContext context) {
|
||||
this(builder, context, null);
|
||||
}
|
||||
|
||||
public ExpressionGenerator(ExpressionContext context) {
|
||||
this.builder = new StringBuilder();
|
||||
this.context = context;
|
||||
|
||||
factory = GroovyPsiElementFactory.getInstance(context.project);
|
||||
this(new StringBuilder(), context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1172,16 +1174,14 @@ public class ExpressionGenerator extends Generator {
|
||||
}
|
||||
else {
|
||||
TypeWriter.writeTypeForNew(builder, type, typeCastExpression);
|
||||
|
||||
builder.append('{');
|
||||
final PsiType newExpectedType = expectedType instanceof PsiArrayType ? ((PsiArrayType)expectedType).getComponentType() : null;
|
||||
final ExpressionGenerator childGenerator = new ExpressionGenerator(builder, context, newExpectedType);
|
||||
for (GrExpression initializer : initializers) {
|
||||
initializer.accept(this);
|
||||
initializer.accept(childGenerator);
|
||||
builder.append(", ");
|
||||
}
|
||||
if (initializers.length > 0) {
|
||||
builder.delete(builder.length() - 2, builder.length());
|
||||
//builder.removeFromTheEnd(2);
|
||||
}
|
||||
builder.delete(builder.length() - 2, builder.length());
|
||||
builder.append('}');
|
||||
}
|
||||
return;
|
||||
@@ -1407,8 +1407,7 @@ public class ExpressionGenerator extends Generator {
|
||||
public void visitListOrMap(@NotNull GrListOrMap listOrMap) {
|
||||
final PsiType type = listOrMap.getType();
|
||||
|
||||
//can be PsiArrayType or GrLiteralClassType
|
||||
LOG.assertTrue(type instanceof GrLiteralClassType || type instanceof PsiArrayType || type instanceof PsiClassType);
|
||||
LOG.assertTrue(type instanceof GrLiteralClassType || type instanceof PsiClassType);
|
||||
|
||||
if (listOrMap.isMap()) {
|
||||
if (listOrMap.getNamedArguments().length == 0) {
|
||||
@@ -1448,13 +1447,16 @@ public class ExpressionGenerator extends Generator {
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiType getTypeToUseByList(GrListOrMap listOrMap, PsiType type) {
|
||||
private PsiType getTypeToUseByList(GrListOrMap listOrMap, PsiType type) {
|
||||
if (isImplicitlyCastedToArray(listOrMap)) {
|
||||
PsiType iterable = ClosureParameterEnhancer.findTypeForIteration(listOrMap, listOrMap);
|
||||
if (iterable != null) {
|
||||
return new PsiArrayType(iterable);
|
||||
}
|
||||
}
|
||||
else if (expectedType instanceof PsiArrayType) {
|
||||
return expectedType;
|
||||
}
|
||||
if (type instanceof PsiClassType) {
|
||||
PsiClass resolved = ((PsiClassType)type).resolve();
|
||||
if (resolved != null && CommonClassNames.JAVA_UTIL_LIST.equals(resolved.getQualifiedName())) {
|
||||
|
||||
+29
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -33,6 +34,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
@@ -40,6 +42,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaratio
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
|
||||
@@ -55,6 +58,7 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProces
|
||||
import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
@@ -434,22 +438,42 @@ public class GenerationUtil {
|
||||
}
|
||||
builder.append('(');
|
||||
}
|
||||
final PsiType iType = getDeclaredType(initializer, expressionContext);
|
||||
|
||||
//generate cast
|
||||
if (original != null && iType != null && !TypesUtil.isAssignable(original, iType, initializer)) {
|
||||
if (isCastNeeded(original, initializer, expressionContext)) {
|
||||
builder.append('(');
|
||||
TypeWriter.writeType(builder, original, initializer);
|
||||
builder.append(')');
|
||||
}
|
||||
|
||||
initializer.accept(new ExpressionGenerator(builder, expressionContext));
|
||||
initializer.accept(new ExpressionGenerator(builder, expressionContext, original));
|
||||
if (wrapped) {
|
||||
builder.append(')');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCastNeeded(PsiType target, GrExpression initializer, ExpressionContext expressionContext) {
|
||||
if (target == null) return false;
|
||||
final PsiType iType = getDeclaredType(initializer, expressionContext);
|
||||
if (iType == null) return false;
|
||||
if (TypeConversionUtil.isAssignable(target, iType)) return false;
|
||||
|
||||
if (initializer instanceof GrLiteral) {
|
||||
Object value = ((GrLiteral)initializer).getValue();
|
||||
if (value instanceof BigDecimal && Double.isFinite(((BigDecimal)value).doubleValue())) {
|
||||
return !TypeConversionUtil.isAssignable(target, PsiType.DOUBLE);
|
||||
}
|
||||
else if (value instanceof String && ((String)value).length() == 1) {
|
||||
return !PsiType.CHAR.equals(PsiPrimitiveType.getOptionallyUnboxedType(target));
|
||||
}
|
||||
}
|
||||
else if (initializer instanceof GrListOrMap && target instanceof PsiArrayType) {
|
||||
GrListOrMap listOrMap = (GrListOrMap)initializer;
|
||||
return listOrMap.isMap();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void writeVariableSeparately(GrVariable variable, StringBuilder builder, ExpressionContext expressionContext) {
|
||||
PsiType type = expressionContext.typeProvider.getVarType(variable);
|
||||
ModifierListGenerator.writeModifiers(builder, variable.getModifierList());
|
||||
@@ -583,12 +607,6 @@ public class GenerationUtil {
|
||||
final GrExpression invokedExpression = ((GrMethodCall)expression).getInvokedExpression();
|
||||
return getDeclaredType(invokedExpression, context);
|
||||
}
|
||||
else if (expression instanceof GrBinaryExpression) {
|
||||
final GroovyResolveResult result = PsiImplUtil.extractUniqueResult(((GrBinaryExpression)expression).multiResolve(false));
|
||||
if (result.getElement() instanceof PsiMethod) {
|
||||
return getDeclaredType((PsiMethod)result.getElement(), result.getSubstitutor(), context);
|
||||
}
|
||||
}
|
||||
else if (expression instanceof GrIndexProperty) {
|
||||
final GroovyResolveResult result = ((GrIndexProperty)expression).advancedResolve();
|
||||
if (result.getElement() instanceof PsiMethod) {
|
||||
|
||||
+2
-1
@@ -15,4 +15,5 @@
|
||||
*/
|
||||
def list = []
|
||||
int[] arr = []
|
||||
List<String> strings = []
|
||||
List<String> strings = []
|
||||
int[] arr2 = list
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
java.util.List list = new java.util.ArrayList();
|
||||
java.lang.Integer[] arr = new java.lang.Integer[0];
|
||||
java.util.List<java.lang.String> strings = new java.util.ArrayList<java.lang.String>();
|
||||
java.lang.Integer[] arr2 = (java.lang.Integer[])list;
|
||||
Reference in New Issue
Block a user