use of javax.lang.model.util.Types in project graal by oracle.
the class MatchProcessor method processMethodMatchRule.
private void processMethodMatchRule(ExecutableElement method, MatchRuleDescriptor info, MatchRule matchRule, AnnotationMirror mirror) {
logMessage("processMethodMatchRule %s %s\n", method, mirror);
Types typeUtils = typeUtils();
if (!method.getModifiers().contains(Modifier.PUBLIC)) {
errorMessage(method, "MatchRule method %s must be public", method.getSimpleName());
return;
}
if (method.getModifiers().contains(Modifier.STATIC)) {
errorMessage(method, "MatchRule method %s must be non-static", method.getSimpleName());
return;
}
try {
TypeMirror returnType = method.getReturnType();
if (!typeUtils.isSameType(returnType, processingEnv.getElementUtils().getTypeElement(ComplexMatchResult.class.getName()).asType())) {
errorMessage(method, "MatchRule method return type must be %s", ComplexMatchResult.class.getName());
return;
}
String rule = matchRule.value();
RuleParser parser = new RuleParser(rule);
ArrayList<TypeDescriptor> expectedTypes = parser.capturedTypes();
ArrayList<String> expectedNames = parser.capturedNames();
List<? extends VariableElement> actualParameters = method.getParameters();
if (expectedTypes.size() + 1 < actualParameters.size()) {
errorMessage(method, "Too many arguments for match method %s != %s", expectedTypes.size() + 1, actualParameters.size());
return;
}
// must be assignment compatible.
for (VariableElement parameter : actualParameters) {
String name = parameter.getSimpleName().toString();
int nameIndex = expectedNames.indexOf(name);
if (nameIndex == -1) {
errorMessage(method, "Argument \"%s\" isn't captured in the match rule", name);
return;
}
TypeMirror type = parameter.asType();
if (!typeUtils.isAssignable(expectedTypes.get(nameIndex).mirror, type)) {
errorMessage(method, "Captured value \"%s\" of type %s is not assignable to argument of type %s", name, expectedTypes.get(nameIndex).mirror, type);
return;
}
}
String methodName = method.getSimpleName().toString();
MethodInvokerItem invoker = info.invokers.get(methodName);
if (invoker == null) {
invoker = new MethodInvokerItem(methodName, topDeclaringType(method).getSimpleName().toString(), method, actualParameters);
info.invokers.put(methodName, invoker);
} else if (invoker.method != method) {
// This could be supported but it's easier if they are unique since the names
// are used in log output and snippet counters.
errorMessage(method, "Use unique method names for match methods: %s.%s != %s.%s", method.getReceiverType(), method.getSimpleName(), invoker.method.getReceiverType(), invoker.method.getSimpleName());
return;
}
Element enclosing = method.getEnclosingElement();
String declaringClass = "";
String separator = "";
EconomicSet<Element> originatingElementsList = info.originatingElements;
originatingElementsList.add(method);
while (enclosing != null) {
if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) {
if (enclosing.getModifiers().contains(Modifier.PRIVATE)) {
errorMessage(method, "MatchRule cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing);
return;
}
originatingElementsList.add(enclosing);
declaringClass = enclosing.getSimpleName() + separator + declaringClass;
separator = ".";
} else {
assert enclosing.getKind() == ElementKind.PACKAGE;
}
enclosing = enclosing.getEnclosingElement();
}
originatingElementsList.addAll(parser.originatingElements);
info.requiredPackages.addAll(parser.requiredPackages);
// Accumulate any position declarations.
parser.generatePositionDeclarations(info.positionDeclarations);
List<String> matches = parser.generateVariants();
for (String match : matches) {
info.matchRules.add(new MatchRuleItem(match, invoker));
}
} catch (RuleParseError e) {
errorMessage(method, mirror, e.getMessage());
}
}
use of javax.lang.model.util.Types in project SpongeAPI by SpongePowered.
the class ListenerProcessor method isTypeSubclass.
private boolean isTypeSubclass(Element typedElement, String subclass) {
Elements elements = this.processingEnv.getElementUtils();
Types types = this.processingEnv.getTypeUtils();
TypeMirror event = types.getDeclaredType(elements.getTypeElement(subclass));
return types.isAssignable(typedElement.asType(), event);
}
use of javax.lang.model.util.Types in project checker-framework by typetools.
the class AnnotationFileParser method annotate.
/**
* Add to formal parameter {@code atype}:
*
* <ol>
* <li>the annotations from {@code typeDef}, and
* <li>any type annotations that parsed as declaration annotations (i.e., type annotations in
* {@code declAnnos}).
* </ol>
*
* @param atype annotated type to which to add annotations
* @param typeDef parsed type
* @param declAnnos annotations stored on the declaration of the variable with this type, or null
* @param astNode where to report errors
*/
private void annotate(AnnotatedTypeMirror atype, Type typeDef, @Nullable NodeList<AnnotationExpr> declAnnos, NodeWithRange<?> astNode) {
if (atype.getKind() == TypeKind.ARRAY) {
if (typeDef instanceof ReferenceType) {
annotateAsArray((AnnotatedArrayType) atype, (ReferenceType) typeDef, declAnnos, astNode);
} else {
warn(astNode, "expected ReferenceType but found: " + typeDef);
}
return;
}
clearAnnotations(atype, typeDef);
// Primary annotations for the type of a variable declaration are not stored in typeDef, but
// rather as declaration annotations (passed as declAnnos to this method). But, if typeDef
// is not the type of a variable, then the primary annotations are stored in typeDef.
NodeList<AnnotationExpr> primaryAnnotations;
if (typeDef.getAnnotations().isEmpty() && declAnnos != null) {
primaryAnnotations = declAnnos;
} else {
primaryAnnotations = typeDef.getAnnotations();
}
if (atype.getKind() != TypeKind.WILDCARD) {
// The primary annotation on a wildcard applies to the super or extends bound and
// are added below.
annotate(atype, primaryAnnotations, astNode);
}
switch(atype.getKind()) {
case DECLARED:
ClassOrInterfaceType declType = unwrapDeclaredType(typeDef);
if (declType == null) {
break;
}
AnnotatedDeclaredType adeclType = (AnnotatedDeclaredType) atype;
// Process type arguments.
if (declType.getTypeArguments().isPresent() && !declType.getTypeArguments().get().isEmpty() && !adeclType.getTypeArguments().isEmpty()) {
if (declType.getTypeArguments().get().size() != adeclType.getTypeArguments().size()) {
warn(astNode, String.format("Mismatch in type argument size between %s (%d) and %s (%d)", declType, declType.getTypeArguments().get().size(), adeclType, adeclType.getTypeArguments().size()));
break;
}
for (int i = 0; i < declType.getTypeArguments().get().size(); ++i) {
annotate(adeclType.getTypeArguments().get(i), declType.getTypeArguments().get().get(i), null, astNode);
}
}
break;
case WILDCARD:
AnnotatedWildcardType wildcardType = (AnnotatedWildcardType) atype;
// Ensure that the file also has a wildcard type, report an error otherwise
if (!typeDef.isWildcardType()) {
// We throw an error here, as otherwise we are just getting a generic cast error
// on the very next line.
warn(astNode, "Wildcard type <" + atype + "> does not match type in stubs file" + filename + ": <" + typeDef + ">" + " while parsing " + typeBeingParsed);
return;
}
WildcardType wildcardDef = (WildcardType) typeDef;
if (wildcardDef.getExtendedType().isPresent()) {
annotate(wildcardType.getExtendsBound(), wildcardDef.getExtendedType().get(), null, astNode);
annotate(wildcardType.getSuperBound(), primaryAnnotations, astNode);
} else if (wildcardDef.getSuperType().isPresent()) {
annotate(wildcardType.getSuperBound(), wildcardDef.getSuperType().get(), null, astNode);
annotate(wildcardType.getExtendsBound(), primaryAnnotations, astNode);
} else {
annotate(atype, primaryAnnotations, astNode);
}
break;
case TYPEVAR:
// Add annotations from the declaration of the TypeVariable
AnnotatedTypeVariable typeVarUse = (AnnotatedTypeVariable) atype;
Types typeUtils = processingEnv.getTypeUtils();
for (AnnotatedTypeVariable typePar : typeParameters) {
if (typeUtils.isSameType(typePar.getUnderlyingType(), atype.getUnderlyingType())) {
atypeFactory.replaceAnnotations(typePar.getUpperBound(), typeVarUse.getUpperBound());
atypeFactory.replaceAnnotations(typePar.getLowerBound(), typeVarUse.getLowerBound());
}
}
break;
default:
}
}
use of javax.lang.model.util.Types in project checker-framework by typetools.
the class CFAbstractStore method canAlias.
/**
* Can the objects {@code a} and {@code b} be aliases? Returns a conservative answer (i.e.,
* returns {@code true} if not enough information is available to determine aliasing).
*/
@Override
public boolean canAlias(JavaExpression a, JavaExpression b) {
TypeMirror tb = b.getType();
TypeMirror ta = a.getType();
Types types = analysis.getTypes();
return types.isSubtype(ta, tb) || types.isSubtype(tb, ta);
}
use of javax.lang.model.util.Types in project checker-framework by typetools.
the class CFAbstractValue method mostSpecific.
/**
* Returns the more specific version of two values {@code this} and {@code other}. If they do not
* contain information for all hierarchies, then it is possible that information from both {@code
* this} and {@code other} are taken.
*
* <p>If neither of the two is more specific for one of the hierarchies (i.e., if the two are
* incomparable as determined by {@link QualifierHierarchy#isSubtype(AnnotationMirror,
* AnnotationMirror)}, then the respective value from {@code backup} is used.
*/
public V mostSpecific(@Nullable V other, @Nullable V backup) {
if (other == null) {
@SuppressWarnings("unchecked") V v = (V) this;
return v;
}
Types types = analysis.getTypes();
TypeMirror mostSpecifTypeMirror;
if (types.isAssignable(this.getUnderlyingType(), other.getUnderlyingType())) {
mostSpecifTypeMirror = this.getUnderlyingType();
} else if (types.isAssignable(other.getUnderlyingType(), this.getUnderlyingType())) {
mostSpecifTypeMirror = other.getUnderlyingType();
} else if (TypesUtils.isErasedSubtype(this.getUnderlyingType(), other.getUnderlyingType(), types)) {
mostSpecifTypeMirror = this.getUnderlyingType();
} else if (TypesUtils.isErasedSubtype(other.getUnderlyingType(), this.getUnderlyingType(), types)) {
mostSpecifTypeMirror = other.getUnderlyingType();
} else {
mostSpecifTypeMirror = this.getUnderlyingType();
}
MostSpecificVisitor ms = new MostSpecificVisitor(this.getUnderlyingType(), other.getUnderlyingType(), backup);
Set<AnnotationMirror> mostSpecific = ms.combineSets(this.getUnderlyingType(), this.getAnnotations(), other.getUnderlyingType(), other.getAnnotations(), canBeMissingAnnotations(mostSpecifTypeMirror));
if (ms.error) {
return backup;
}
return analysis.createAbstractValue(mostSpecific, mostSpecifTypeMirror);
}
Aggregations