mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IDEA-66564 (parse indeterminate FP literals in compiled annotations, better fix)
This commit is contained in:
@@ -53,7 +53,7 @@ public class ClassFileStubBuilder implements BinaryFileStubBuilder {
|
||||
}
|
||||
|
||||
public int getStubVersion() {
|
||||
return JavaFileElementType.STUB_VERSION + 1;
|
||||
return JavaFileElementType.STUB_VERSION + 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.java.parser.DeclarationParser;
|
||||
import com.intellij.lang.java.parser.JavaParserUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.CharFilter;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiElementFactoryImpl;
|
||||
@@ -31,9 +29,7 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
@@ -48,23 +44,6 @@ public class ClsParsingUtil {
|
||||
}
|
||||
};
|
||||
|
||||
private static final Map<String, String> INDETERMINATE_MAP;
|
||||
static {
|
||||
INDETERMINATE_MAP = new HashMap<String, String>();
|
||||
INDETERMINATE_MAP.put("-1.0/0.0", "NEGATIVE_INFINITY");
|
||||
INDETERMINATE_MAP.put("0.0/0.0", "NaN");
|
||||
INDETERMINATE_MAP.put("1.0/0.0", "POSITIVE_INFINITY");
|
||||
}
|
||||
|
||||
private static final CharFilter INDETERMINATE_FILTER = new CharFilter() {
|
||||
private static final String UNWANTED = " fFdD";
|
||||
|
||||
@Override
|
||||
public boolean accept(final char ch) {
|
||||
return UNWANTED.indexOf(ch) == -1;
|
||||
}
|
||||
};
|
||||
|
||||
private ClsParsingUtil() { }
|
||||
|
||||
public static PsiExpression createExpressionFromText(final String exprText, final PsiManager manager, final ClsElementImpl parent) {
|
||||
@@ -84,33 +63,19 @@ public class ClsParsingUtil {
|
||||
|
||||
@NotNull
|
||||
public static PsiAnnotationMemberValue createMemberValueFromText(final String text, final PsiManager manager, final ClsElementImpl parent) {
|
||||
final String exprText = mapIndeterminate(text);
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
|
||||
final PsiJavaFile context = ((PsiElementFactoryImpl)factory).getDummyJavaFile(); // to resolve classes from java.lang
|
||||
final LanguageLevel level = PsiUtil.getLanguageLevel(parent);
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(manager, new JavaDummyElement(exprText, ANNOTATION_VALUE, level), context);
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(manager, new JavaDummyElement(text, ANNOTATION_VALUE, level), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiAnnotationMemberValue)) {
|
||||
LOG.error("Could not parse initializer:'" + exprText + "'");
|
||||
LOG.error("Could not parse initializer:'" + text + "'");
|
||||
return null;
|
||||
}
|
||||
|
||||
return getMemberValue(element, parent);
|
||||
}
|
||||
|
||||
private static String mapIndeterminate(final String original) {
|
||||
final int divPos = original.indexOf('/');
|
||||
if (divPos > 0) {
|
||||
final String symbol = INDETERMINATE_MAP.get(StringUtil.strip(original, INDETERMINATE_FILTER));
|
||||
if (symbol != null) {
|
||||
final int fPos = original.toLowerCase().indexOf('f');
|
||||
final String type = (0 < fPos && fPos < divPos) ? CommonClassNames.JAVA_LANG_FLOAT : CommonClassNames.JAVA_LANG_DOUBLE;
|
||||
return type + "." + symbol;
|
||||
}
|
||||
}
|
||||
return original;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiAnnotationMemberValue getMemberValue(final PsiElement element, final ClsElementImpl parent) {
|
||||
if (element instanceof PsiExpression) {
|
||||
@@ -152,7 +117,7 @@ public class ClsParsingUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiExpression psiToClsExpression(final PsiExpression expr, final ClsElementImpl parent) {
|
||||
private static PsiExpression psiToClsExpression(final PsiExpression expr, @Nullable final ClsElementImpl parent) {
|
||||
if (expr instanceof PsiLiteralExpression) {
|
||||
return new ClsLiteralExpressionImpl(parent, expr.getText(), expr.getType(), ((PsiLiteralExpression)expr).getValue());
|
||||
}
|
||||
|
||||
@@ -676,25 +676,26 @@ public class ClsStubBuilder {
|
||||
if (value instanceof Long) return value.toString() + "L";
|
||||
|
||||
if (value instanceof Double) {
|
||||
final double d = ((Double)value).doubleValue();
|
||||
if (Double.isInfinite(d)) {
|
||||
return d > 0 ? "1.0 / 0.0" : "-1.0 / 0.0";
|
||||
} else if (Double.isNaN(d)) {
|
||||
return "0.0d / 0.0";
|
||||
final double v = ((Double)value).doubleValue();
|
||||
if (Double.isInfinite(v)) {
|
||||
return StringUtil.join(CommonClassNames.JAVA_LANG_DOUBLE, ".", (v > 0 ? "POSITIVE_INFINITY" : "NEGATIVE_INFINITY"));
|
||||
}
|
||||
return Double.toString(d);
|
||||
else if (Double.isNaN(v)) {
|
||||
return StringUtil.join(CommonClassNames.JAVA_LANG_DOUBLE, ".", "NaN");
|
||||
}
|
||||
return Double.toString(v);
|
||||
}
|
||||
|
||||
if (value instanceof Float) {
|
||||
final float v = ((Float)value).floatValue();
|
||||
|
||||
if (Float.isInfinite(v)) {
|
||||
return v > 0 ? "1.0f / 0.0" : "-1.0f / 0.0";
|
||||
} else if (Float.isNaN(v)) {
|
||||
return "0.0f / 0.0";
|
||||
} else {
|
||||
return Float.toString(v) + "f";
|
||||
return StringUtil.join(CommonClassNames.JAVA_LANG_FLOAT, ".", (v > 0 ? "POSITIVE_INFINITY" : "NEGATIVE_INFINITY"));
|
||||
}
|
||||
else if (Float.isNaN(v)) {
|
||||
return StringUtil.join(CommonClassNames.JAVA_LANG_FLOAT, ".", "NaN");
|
||||
}
|
||||
return Float.toString(v) + "f";
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -717,5 +718,4 @@ public class ClsStubBuilder {
|
||||
// Leading and trailing $ chars should be left unchanged.
|
||||
return raw.contains("$")? REGEX_PATTERN.matcher(raw).replaceAll("\\.") : raw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user