diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java index 16b8238f560..48553f19a16 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java @@ -15,6 +15,7 @@ import java.util.Optional; import java.util.Queue; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.internal.javac.dom.JavacAnnotationBinding; @@ -24,6 +25,7 @@ import org.eclipse.jdt.internal.javac.dom.JavacTypeBinding; import org.eclipse.jdt.internal.javac.dom.JavacVariableBinding; +import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.PackageSymbol; @@ -329,4 +331,39 @@ private java.util.List getTypeArguments(final MethodInvocation metho .collect(Collectors.toList()); } + /** + * Returns the constant value or the binding that a Javac attribute represents. + * + * See a detailed explanation of the returned value: {@link org.eclipse.jdt.core.dom.IMethodBinding#getDefaultValue()} + * + * @param attribute the javac attribute + * @return the constant value or the binding that a Javac attribute represents + */ + public Object getValueFromAttribute(Attribute attribute) { + if (attribute == null) { + return null; + } + if (attribute instanceof Attribute.Constant constant) { + return constant.value; + } else if (attribute instanceof Attribute.Class clazz) { + return new JavacTypeBinding(clazz.classType.tsym, this, null); + } else if (attribute instanceof Attribute.Enum enumm) { + return new JavacVariableBinding(enumm.value, this); + } else if (attribute instanceof Attribute.Array array) { + return Stream.of(array.values) // + .map(nestedAttr -> { + if (attribute instanceof Attribute.Constant constant) { + return constant.value; + } else if (attribute instanceof Attribute.Class clazz) { + return new JavacTypeBinding(clazz.classType.tsym, this, null); + } else if (attribute instanceof Attribute.Enum enumerable) { + return new JavacVariableBinding(enumerable.value, this); + } + throw new IllegalArgumentException("Unexpected attribute type: " + nestedAttr.getClass().getCanonicalName()); + }) // + .toArray(Object[]::new); + } + throw new IllegalArgumentException("Unexpected attribute type: " + attribute.getClass().getCanonicalName()); + } + } diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMemberValuePairBinding.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMemberValuePairBinding.java index c489e672473..ddf029fa576 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMemberValuePairBinding.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMemberValuePairBinding.java @@ -26,10 +26,12 @@ public class JavacMemberValuePairBinding implements IMemberValuePairBinding { public final JavacMethodBinding method; public final Attribute value; + private final JavacBindingResolver resolver; public JavacMemberValuePairBinding(MethodSymbol key, Attribute value, JavacBindingResolver resolver) { this.method = new JavacMethodBinding(key, resolver, null); this.value = value; + this.resolver = resolver; } @Override @@ -54,8 +56,7 @@ public boolean isDeprecated() { @Override public boolean isRecovered() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'isRecovered'"); + return this.value instanceof Attribute.Error; } @Override @@ -70,8 +71,9 @@ public IJavaElement getJavaElement() { @Override public String getKey() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getKey'"); + // as of writing, not yet implemented for ECJ + // @see org.eclipse.jdt.core.dom.MemberValuePairBinding.getKey + return null; } @Override @@ -92,13 +94,12 @@ public IMethodBinding getMethodBinding() { @Override public Object getValue() { - throw new UnsupportedOperationException("Unimplemented method 'getValue'"); + return this.resolver.getValueFromAttribute(this.value); } @Override public boolean isDefault() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'isDefault'"); + return this.value == this.method.methodSymbol.defaultValue; } } diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMethodBinding.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMethodBinding.java index bf755e2b4ae..6d0b5f82254 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMethodBinding.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMethodBinding.java @@ -210,28 +210,7 @@ public IBinding getDeclaringMember() { @Override public Object getDefaultValue() { - Attribute attribute = this.methodSymbol.defaultValue; - if (attribute instanceof Attribute.Constant constant) { - return constant.value; - } else if (attribute instanceof Attribute.Class clazz) { - return new JavacTypeBinding(clazz.classType.tsym, this.resolver, null); - } else if (attribute instanceof Attribute.Enum enumm) { - return new JavacVariableBinding(enumm.value, this.resolver); - } else if (attribute instanceof Attribute.Array array) { - return Stream.of(array.values) // - .map(nestedAttr -> { - if (attribute instanceof Attribute.Constant constant) { - return constant.value; - } else if (attribute instanceof Attribute.Class clazz) { - return new JavacTypeBinding(clazz.classType.tsym, this.resolver, null); - } else if (attribute instanceof Attribute.Enum enumerable) { - return new JavacVariableBinding(enumerable.value, this.resolver); - } - throw new IllegalArgumentException("Unexpected attribute type: " + nestedAttr.getClass().getCanonicalName()); - }) // - .toArray(Object[]::new); - } - throw new IllegalArgumentException("Unexpected attribute type: " + attribute.getClass().getCanonicalName()); + return this.resolver.getValueFromAttribute(this.methodSymbol.defaultValue); } @Override