use of com.sun.source.tree.MethodTree in project st-js by st-js.
the class ClassDuplicateMemberNameCheck method checkMethod.
private void checkMethod(TypeElement classElement, Tree member, GenerationContext<Void> context, Multimap<String, Element> existingNames) {
if (member instanceof MethodTree) {
MethodTree method = (MethodTree) member;
ExecutableElement methodElement = TreeUtils.elementFromDeclaration(method);
if (JavaNodes.isNative(methodElement)) {
// generic version of the overloaded method
return;
}
TreeWrapper<Tree, Void> tw = context.getCurrentWrapper().child(member);
if (MemberWriters.shouldSkip(tw)) {
return;
}
if (methodElement.getKind() != ElementKind.METHOD) {
// skip the constructors
return;
}
checkMethodName(classElement, method, methodElement, context, existingNames);
}
}
use of com.sun.source.tree.MethodTree in project st-js by st-js.
the class IdentifierGlobalScopeNameClashCheck method findVariablesInMethod.
private static void findVariablesInMethod(final String name, final GenerationContext<Void> context) {
MethodTree enclosingMethod = getEnclosingMethod(context.getCurrentPath());
if (enclosingMethod == null) {
// don't see a reason why!?
return;
}
enclosingMethod.accept(new TreeScanner<Void, Void>() {
private boolean checkStopped;
@Override
public Void visitClass(ClassTree arg0, Void arg1) {
// stop the checks if a new type is encountered
checkStopped = true;
return super.visitClass(arg0, arg1);
}
@Override
public Void visitVariable(VariableTree var, Void arg1) {
if (!checkStopped && var.getName().toString().equals(name)) {
context.addError(var, "A variable with the same name as your global variable is already defined in this method's scope. " + "Please rename either the local variable/parameter or the global variable.");
}
return super.visitVariable(var, arg1);
}
}, null);
}
use of com.sun.source.tree.MethodTree in project checker-framework by typetools.
the class JointJavacJavaParserVisitor method visitAnonymousClassBody.
/**
* Visits the the members of an anonymous class body.
*
* <p>In normal classes, javac inserts a synthetic no-argument constructor if no constructor is
* explicitly defined, which is skipped when visiting members. Anonymous class bodies may
* introduce constructors that take arguments if the constructor invocation that created them was
* passed arguments. For example, if {@code MyClass} has a constructor taking a single integer
* argument, then writing {@code new MyClass(5) { }} expands to the javac tree
*
* <pre>{@code
* new MyClass(5) {
* (int arg) {
* super(arg);
* }
* }
* }</pre>
*
* <p>This method skips these synthetic constructors.
*
* @param javacBody body of an anonymous class body
* @param javaParserMembers list of members for the anonymous class body of an {@code
* ObjectCreationExpr}
*/
public void visitAnonymousClassBody(ClassTree javacBody, List<BodyDeclaration<?>> javaParserMembers) {
List<Tree> javacMembers = new ArrayList<>(javacBody.getMembers());
if (!javacMembers.isEmpty()) {
Tree member = javacMembers.get(0);
if (member.getKind() == Tree.Kind.METHOD) {
MethodTree methodTree = (MethodTree) member;
if (methodTree.getName().contentEquals("<init>")) {
javacMembers.remove(0);
}
}
}
visitClassMembers(javacMembers, javaParserMembers);
}
use of com.sun.source.tree.MethodTree in project checker-framework by typetools.
the class WholeProgramInferenceJavaParserStorage method createWrappersForClass.
/**
* The first two arugments are a javac tree and a JavaParser node representing the same class.
* This method creates wrappers around all the classes, fields, and methods in that class, and
* stores those wrappers in {@code sourceAnnos}.
*
* @param javacClass javac tree for class
* @param javaParserClass JavaParser node corresponding to the same class as {@code javacClass}
* @param sourceAnnos compilation unit wrapper to add new wrappers to
*/
private void createWrappersForClass(ClassTree javacClass, TypeDeclaration<?> javaParserClass, CompilationUnitAnnos sourceAnnos) {
JointJavacJavaParserVisitor visitor = new DefaultJointVisitor() {
@Override
public void processClass(ClassTree javacTree, ClassOrInterfaceDeclaration javaParserNode) {
addClass(javacTree);
}
@Override
public void processClass(ClassTree javacTree, EnumDeclaration javaParserNode) {
addClass(javacTree);
}
@Override
public void processClass(ClassTree javacTree, RecordDeclaration javaParserNode) {
addClass(javacTree);
}
@Override
public void processNewClass(NewClassTree javacTree, ObjectCreationExpr javaParserNode) {
if (javacTree.getClassBody() != null) {
addClass(javacTree.getClassBody());
}
}
/**
* Creates a wrapper around the class for {@code tree} and stores it in {@code
* sourceAnnos}.
*
* @param tree tree to add
*/
private void addClass(ClassTree tree) {
TypeElement classElt = TreeUtils.elementFromDeclaration(tree);
String className = ElementUtils.getBinaryName(classElt);
ClassOrInterfaceAnnos typeWrapper = new ClassOrInterfaceAnnos();
if (!classToAnnos.containsKey(className)) {
classToAnnos.put(className, typeWrapper);
}
sourceAnnos.types.add(typeWrapper);
}
@Override
public void processMethod(MethodTree javacTree, MethodDeclaration javaParserNode) {
addCallableDeclaration(javacTree, javaParserNode);
}
@Override
public void processMethod(MethodTree javacTree, ConstructorDeclaration javaParserNode) {
addCallableDeclaration(javacTree, javaParserNode);
}
/**
* Creates a wrapper around {@code javacTree} with the corresponding declaration {@code
* javaParserNode} and stores it in {@code sourceAnnos}.
*
* @param javacTree javac tree for declaration to add
* @param javaParserNode JavaParser node for the same class as {@code javacTree}
*/
private void addCallableDeclaration(MethodTree javacTree, CallableDeclaration<?> javaParserNode) {
ExecutableElement elt = TreeUtils.elementFromDeclaration(javacTree);
String className = ElementUtils.getEnclosingClassName(elt);
ClassOrInterfaceAnnos enclosingClass = classToAnnos.get(className);
String executableSignature = JVMNames.getJVMMethodSignature(javacTree);
if (!enclosingClass.callableDeclarations.containsKey(executableSignature)) {
enclosingClass.callableDeclarations.put(executableSignature, new CallableDeclarationAnnos(javaParserNode));
}
}
@Override
public void processVariable(VariableTree javacTree, EnumConstantDeclaration javaParserNode) {
VariableElement elt = TreeUtils.elementFromDeclaration(javacTree);
if (!elt.getKind().isField()) {
throw new BugInCF(elt + " is not a field but a " + elt.getKind());
}
String enclosingClassName = ElementUtils.getEnclosingClassName(elt);
ClassOrInterfaceAnnos enclosingClass = classToAnnos.get(enclosingClassName);
String fieldName = javacTree.getName().toString();
enclosingClass.enumConstants.add(fieldName);
// Ensure that if an enum constant defines a class, that class gets registered properly.
// See e.g. https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.1 for
// the specification of an enum constant, which does permit it to define an anonymous
// class.
NewClassTree constructor = (NewClassTree) javacTree.getInitializer();
if (constructor.getClassBody() != null) {
addClass(constructor.getClassBody());
}
}
@Override
public void processVariable(VariableTree javacTree, VariableDeclarator javaParserNode) {
// below call to TreeUtils.elementFromDeclaration causes a crash.
if (TreeUtils.elementFromTree(javacTree) == null) {
return;
}
VariableElement elt = TreeUtils.elementFromDeclaration(javacTree);
if (!elt.getKind().isField()) {
return;
}
String enclosingClassName = ElementUtils.getEnclosingClassName(elt);
ClassOrInterfaceAnnos enclosingClass = classToAnnos.get(enclosingClassName);
String fieldName = javacTree.getName().toString();
if (!enclosingClass.fields.containsKey(fieldName)) {
enclosingClass.fields.put(fieldName, new FieldAnnos(javaParserNode));
}
}
};
visitor.visitClass(javacClass, javaParserClass);
}
use of com.sun.source.tree.MethodTree in project checker-framework by typetools.
the class FormatterVisitor method visitMethodInvocation.
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
FormatterTreeUtil ftu = atypeFactory.treeUtil;
FormatCall fc = ftu.create(node, atypeFactory);
if (fc != null) {
MethodTree enclosingMethod = TreePathUtil.enclosingMethod(atypeFactory.getPath(fc.invocationTree));
Result<String> errMissingFormat = fc.errMissingFormatAnnotation();
if (errMissingFormat != null) {
// The string's type has no @Format annotation.
if (isWrappedFormatCall(fc, enclosingMethod)) {
// Nothing to do, because call is legal.
} else {
// I.1
ftu.failure(errMissingFormat, "format.string", errMissingFormat.value());
}
} else {
// The string has a @Format annotation.
Result<InvocationType> invc = fc.getInvocationType();
ConversionCategory[] formatCats = fc.getFormatCategories();
switch(invc.value()) {
case VARARG:
Result<TypeMirror>[] argTypes = fc.getArgTypes();
int argl = argTypes.length;
int formatl = formatCats.length;
if (argl < formatl) {
// For assignments, format.missing.arguments is issued from commonAssignmentCheck.
// II.1
ftu.failure(invc, "format.missing.arguments", formatl, argl);
} else {
if (argl > formatl) {
// II.2
ftu.warning(invc, "format.excess.arguments", formatl, argl);
}
for (int i = 0; i < formatl; ++i) {
ConversionCategory formatCat = formatCats[i];
Result<TypeMirror> arg = argTypes[i];
TypeMirror argType = arg.value();
switch(formatCat) {
case UNUSED:
// I.2
ftu.warning(arg, "format.argument.unused", " " + (1 + i));
break;
case NULL:
// I.3
if (argType.getKind() == TypeKind.NULL) {
ftu.warning(arg, "format.specifier.null", " " + (1 + i));
} else {
ftu.failure(arg, "format.specifier.null", " " + (1 + i));
}
break;
case GENERAL:
break;
default:
if (!fc.isValidArgument(formatCat, argType)) {
// II.3
ExecutableElement method = TreeUtils.elementFromUse(node);
CharSequence methodName = ElementUtils.getSimpleNameOrDescription(method);
ftu.failure(arg, "argument", "in varargs position", methodName, argType, formatCat);
}
break;
}
}
}
break;
case ARRAY:
// III
if (!isWrappedFormatCall(fc, enclosingMethod)) {
ftu.warning(invc, "format.indirect.arguments");
}
// fall through
case NULLARRAY:
for (ConversionCategory cat : formatCats) {
if (cat == ConversionCategory.NULL) {
// I.3
if (invc.value() == FormatterTreeUtil.InvocationType.NULLARRAY) {
ftu.warning(invc, "format.specifier.null", "");
} else {
ftu.failure(invc, "format.specifier.null", "");
}
}
if (cat == ConversionCategory.UNUSED) {
// I.2
ftu.warning(invc, "format.argument.unused", "");
}
}
break;
}
}
// Support -Ainfer command-line argument.
WholeProgramInference wpi = atypeFactory.getWholeProgramInference();
if (wpi != null && forwardsArguments(node, enclosingMethod)) {
wpi.addMethodDeclarationAnnotation(TreeUtils.elementFromDeclaration(enclosingMethod), atypeFactory.FORMATMETHOD);
}
}
return super.visitMethodInvocation(node, p);
}
Aggregations