IDEA-66564 (parse indeterminate FP literals in compiled annotations, better fix)

This commit is contained in:
Roman Shevchenko
2011-04-17 21:30:57 +02:00
parent 4c0a4722ba
commit b6f416c990
3 changed files with 17 additions and 52 deletions
@@ -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;
}
}