use of org.eclipse.jdt.core.dom.MethodInvocation in project che by eclipse.
the class ConvertIterableLoopOperation method checkExpressionCondition.
private IStatus checkExpressionCondition() {
Expression expression = getForStatement().getExpression();
if (!(expression instanceof MethodInvocation))
return SEMANTIC_CHANGE_WARNING_STATUS;
MethodInvocation invoc = (MethodInvocation) expression;
IMethodBinding methodBinding = invoc.resolveMethodBinding();
if (methodBinding == null)
return ERROR_STATUS;
ITypeBinding declaringClass = methodBinding.getDeclaringClass();
if (declaringClass == null)
return ERROR_STATUS;
String qualifiedName = declaringClass.getQualifiedName();
String methodName = invoc.getName().getIdentifier();
if (qualifiedName.startsWith("java.util.Enumeration")) {
//$NON-NLS-1$
if (//$NON-NLS-1$
!methodName.equals("hasMoreElements"))
return SEMANTIC_CHANGE_WARNING_STATUS;
} else if (qualifiedName.startsWith("java.util.Iterator")) {
//$NON-NLS-1$
if (//$NON-NLS-1$
!methodName.equals("hasNext"))
return SEMANTIC_CHANGE_WARNING_STATUS;
return checkIteratorCondition();
} else {
return SEMANTIC_CHANGE_WARNING_STATUS;
}
return StatusInfo.OK_STATUS;
}
use of org.eclipse.jdt.core.dom.MethodInvocation in project che by eclipse.
the class ConvertIterableLoopOperation method convert.
@Override
protected Statement convert(CompilationUnitRewrite cuRewrite, final TextEditGroup group, final LinkedProposalModel positionGroups) throws CoreException {
final AST ast = cuRewrite.getAST();
final ASTRewrite astRewrite = cuRewrite.getASTRewrite();
final ImportRewrite importRewrite = cuRewrite.getImportRewrite();
final ImportRemover remover = cuRewrite.getImportRemover();
fEnhancedForLoop = ast.newEnhancedForStatement();
String[] names = getVariableNameProposals();
String name;
if (fElementVariable != null) {
name = fElementVariable.getName();
} else {
name = names[0];
}
final LinkedProposalPositionGroup pg = positionGroups.getPositionGroup(name, true);
if (fElementVariable != null)
pg.addProposal(name, null, 10);
for (int i = 0; i < names.length; i++) {
pg.addProposal(names[i], null, 10);
}
final Statement body = getForStatement().getBody();
if (body != null) {
final ListRewrite list;
if (body instanceof Block) {
list = astRewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY);
for (final Iterator<Expression> iterator = fOccurrences.iterator(); iterator.hasNext(); ) {
final Statement parent = (Statement) ASTNodes.getParent(iterator.next(), Statement.class);
if (parent != null && list.getRewrittenList().contains(parent)) {
list.remove(parent, null);
remover.registerRemovedNode(parent);
}
}
} else {
list = null;
}
final String text = name;
body.accept(new ASTVisitor() {
private boolean replace(final Expression expression) {
final SimpleName node = ast.newSimpleName(text);
astRewrite.replace(expression, node, group);
remover.registerRemovedNode(expression);
pg.addPosition(astRewrite.track(node), false);
return false;
}
@Override
public final boolean visit(final MethodInvocation node) {
final IMethodBinding binding = node.resolveMethodBinding();
if (binding != null && (binding.getName().equals("next") || binding.getName().equals("nextElement"))) {
//$NON-NLS-1$ //$NON-NLS-2$
final Expression expression = node.getExpression();
if (expression instanceof Name) {
final IBinding result = ((Name) expression).resolveBinding();
if (result != null && result.equals(fIteratorVariable))
return replace(node);
} else if (expression instanceof FieldAccess) {
final IBinding result = ((FieldAccess) expression).resolveFieldBinding();
if (result != null && result.equals(fIteratorVariable))
return replace(node);
}
}
return super.visit(node);
}
@Override
public final boolean visit(final SimpleName node) {
if (fElementVariable != null) {
final IBinding binding = node.resolveBinding();
if (binding != null && binding.equals(fElementVariable)) {
final Statement parent = (Statement) ASTNodes.getParent(node, Statement.class);
if (parent != null && (list == null || list.getRewrittenList().contains(parent)))
pg.addPosition(astRewrite.track(node), false);
}
}
return false;
}
});
fEnhancedForLoop.setBody(getBody(cuRewrite, group, positionGroups));
}
final SingleVariableDeclaration declaration = ast.newSingleVariableDeclaration();
final SimpleName simple = ast.newSimpleName(name);
pg.addPosition(astRewrite.track(simple), true);
declaration.setName(simple);
final ITypeBinding elementType = getElementType(fIteratorVariable.getType());
declaration.setType(importType(elementType, getForStatement(), importRewrite, getRoot()));
if (fMakeFinal) {
ModifierRewrite.create(astRewrite, declaration).setModifiers(Modifier.FINAL, 0, group);
}
remover.registerAddedImport(elementType.getQualifiedName());
fEnhancedForLoop.setParameter(declaration);
fEnhancedForLoop.setExpression(getExpression(astRewrite));
for (Iterator<Expression> iterator = getForStatement().initializers().iterator(); iterator.hasNext(); ) {
ASTNode node = iterator.next();
if (node instanceof VariableDeclarationExpression) {
VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) node;
remover.registerRemovedNode(variableDeclarationExpression.getType());
} else {
remover.registerRemovedNode(node);
}
}
for (Iterator<Expression> iterator = getForStatement().updaters().iterator(); iterator.hasNext(); ) {
ASTNode node = iterator.next();
remover.registerRemovedNode(node);
}
return fEnhancedForLoop;
}
use of org.eclipse.jdt.core.dom.MethodInvocation in project che by eclipse.
the class CodeStyleFix method createToStaticAccessOperations.
private static ToStaticAccessOperation[] createToStaticAccessOperations(CompilationUnit astRoot, HashMap<ASTNode, Block> createdBlocks, IProblemLocation problem, boolean conservative) {
ASTNode selectedNode = problem.getCoveringNode(astRoot);
if (selectedNode == null) {
return null;
}
Expression qualifier = null;
IBinding accessBinding = null;
if (selectedNode instanceof SimpleName) {
selectedNode = selectedNode.getParent();
}
if (selectedNode instanceof QualifiedName) {
QualifiedName name = (QualifiedName) selectedNode;
qualifier = name.getQualifier();
accessBinding = name.resolveBinding();
} else if (selectedNode instanceof MethodInvocation) {
MethodInvocation methodInvocation = (MethodInvocation) selectedNode;
qualifier = methodInvocation.getExpression();
accessBinding = methodInvocation.getName().resolveBinding();
} else if (selectedNode instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) selectedNode;
qualifier = fieldAccess.getExpression();
accessBinding = fieldAccess.getName().resolveBinding();
}
if (accessBinding != null && qualifier != null) {
if (conservative && ASTResolving.findParentStatement(qualifier) == null)
return null;
ToStaticAccessOperation declaring = null;
ITypeBinding declaringTypeBinding = getDeclaringTypeBinding(accessBinding);
if (declaringTypeBinding != null) {
// use generic to avoid any type arguments
declaringTypeBinding = declaringTypeBinding.getTypeDeclaration();
declaring = new ToStaticAccessOperation(declaringTypeBinding, qualifier, createdBlocks);
}
ToStaticAccessOperation instance = null;
ITypeBinding instanceTypeBinding = Bindings.normalizeTypeBinding(qualifier.resolveTypeBinding());
if (instanceTypeBinding != null) {
// use generic to avoid any type arguments
instanceTypeBinding = instanceTypeBinding.getTypeDeclaration();
if (instanceTypeBinding.getTypeDeclaration() != declaringTypeBinding) {
instance = new ToStaticAccessOperation(instanceTypeBinding, qualifier, createdBlocks);
}
}
if (declaring != null && instance != null) {
return new ToStaticAccessOperation[] { declaring, instance };
} else {
return new ToStaticAccessOperation[] { declaring };
}
}
return null;
}
use of org.eclipse.jdt.core.dom.MethodInvocation in project buck by facebook.
the class JavaFileParser method extractFeaturesFromJavaCode.
public JavaFileFeatures extractFeaturesFromJavaCode(String code) {
// For now, we will harcode this. Ultimately, we probably want to make this configurable via
// .buckconfig. For example, the Buck project itself is diligent about disallowing wildcard
// imports, but the one exception is the Java code generated via Thrift in src-gen.
final boolean shouldThrowForUnsupportedWildcardImport = false;
final AtomicBoolean isPoisonedByUnsupportedWildcardImport = new AtomicBoolean(false);
final CompilationUnit compilationUnit = makeCompilationUnitFromSource(code);
final ImmutableSortedSet.Builder<String> providedSymbols = ImmutableSortedSet.naturalOrder();
final ImmutableSortedSet.Builder<String> requiredSymbols = ImmutableSortedSet.naturalOrder();
final ImmutableSortedSet.Builder<String> exportedSymbols = ImmutableSortedSet.naturalOrder();
final ImmutableSortedSet.Builder<String> requiredSymbolsFromExplicitImports = ImmutableSortedSet.naturalOrder();
compilationUnit.accept(new ASTVisitor() {
@Nullable
private String packageName;
/** Maps simple name to fully-qualified name. */
private Map<String, String> simpleImportedTypes = new HashMap<>();
/**
* Maps wildcard import prefixes, such as {@code "java.util"} to the types in the respective
* package if a wildcard import such as {@code import java.util.*} is used.
*/
private Map<String, ImmutableSet<String>> wildcardImports = new HashMap<>();
@Override
public boolean visit(PackageDeclaration node) {
Preconditions.checkState(packageName == null, "There should be at most one package declaration");
packageName = node.getName().getFullyQualifiedName();
return false;
}
// providedSymbols
@Override
public boolean visit(TypeDeclaration node) {
// Local classes can be declared inside of methods. Skip over these.
if (node.getParent() instanceof TypeDeclarationStatement) {
return true;
}
String fullyQualifiedName = getFullyQualifiedTypeName(node);
if (fullyQualifiedName != null) {
providedSymbols.add(fullyQualifiedName);
}
@SuppressWarnings("unchecked") List<Type> interfaceTypes = node.superInterfaceTypes();
for (Type interfaceType : interfaceTypes) {
tryAddType(interfaceType, DependencyType.EXPORTED);
}
Type superclassType = node.getSuperclassType();
if (superclassType != null) {
tryAddType(superclassType, DependencyType.EXPORTED);
}
return true;
}
@Override
public boolean visit(EnumDeclaration node) {
String fullyQualifiedName = getFullyQualifiedTypeName(node);
if (fullyQualifiedName != null) {
providedSymbols.add(fullyQualifiedName);
}
return true;
}
@Override
public boolean visit(AnnotationTypeDeclaration node) {
String fullyQualifiedName = getFullyQualifiedTypeName(node);
if (fullyQualifiedName != null) {
providedSymbols.add(fullyQualifiedName);
}
return true;
}
// requiredSymbols
/**
* Uses heuristics to try to figure out what type of QualifiedName this is. Returns a non-null
* value if this is believed to be a reference that qualifies as a "required symbol"
* relationship.
*/
@Override
public boolean visit(QualifiedName node) {
QualifiedName ancestor = findMostQualifiedAncestor(node);
ASTNode parent = ancestor.getParent();
if (!(parent instanceof PackageDeclaration) && !(parent instanceof ImportDeclaration)) {
String symbol = ancestor.getFullyQualifiedName();
// lookup.
if (CharMatcher.javaUpperCase().matches(symbol.charAt(0))) {
addTypeFromDotDelimitedSequence(symbol, DependencyType.REQUIRED);
}
}
return false;
}
/**
* @param expr could be "Example", "Example.field", "com.example.Example". Note it could also
* be a built-in type, such as "java.lang.Integer", in which case it will not be added to
* the set of required symbols.
*/
private void addTypeFromDotDelimitedSequence(String expr, DependencyType dependencyType) {
// check it against JAVA_LANG_TYPES.
if (startsWithUppercaseChar(expr)) {
int index = expr.indexOf('.');
if (index >= 0) {
String leftmostComponent = expr.substring(0, index);
if (JAVA_LANG_TYPES.contains(leftmostComponent)) {
return;
}
}
}
expr = qualifyWithPackageNameIfNecessary(expr);
addSymbol(expr, dependencyType);
}
@Override
public boolean visit(ImportDeclaration node) {
String fullyQualifiedName = node.getName().getFullyQualifiedName();
// third-party code. As such, we will tolerate these for some of the common cases.
if (node.isOnDemand()) {
ImmutableSet<String> value = SUPPORTED_WILDCARD_IMPORTS.get(fullyQualifiedName);
if (value != null) {
wildcardImports.put(fullyQualifiedName, value);
return false;
} else if (shouldThrowForUnsupportedWildcardImport) {
throw new RuntimeException(String.format("Use of wildcard 'import %s.*' makes it impossible to statically determine " + "required symbols in this file. Please enumerate explicit imports.", fullyQualifiedName));
} else {
isPoisonedByUnsupportedWildcardImport.set(true);
return false;
}
}
// Only worry about the dependency on the enclosing type.
Optional<String> simpleName = getSimpleNameFromFullyQualifiedName(fullyQualifiedName);
if (simpleName.isPresent()) {
String name = simpleName.get();
int index = fullyQualifiedName.indexOf("." + name);
String enclosingType = fullyQualifiedName.substring(0, index + name.length() + 1);
requiredSymbolsFromExplicitImports.add(enclosingType);
simpleImportedTypes.put(name, enclosingType);
} else {
LOG.warn("Suspicious import lacks obvious enclosing type: %s", fullyQualifiedName);
// The one example we have seen of this in the wild is
// "org.whispersystems.curve25519.java.curve_sigs". In practice, we still need to add it
// as a required symbol in this case.
requiredSymbols.add(fullyQualifiedName);
}
return false;
}
@Override
public boolean visit(MethodInvocation node) {
if (node.getExpression() == null) {
return true;
}
String receiver = node.getExpression().toString();
if (looksLikeAType(receiver)) {
addTypeFromDotDelimitedSequence(receiver, DependencyType.REQUIRED);
}
return true;
}
/** An annotation on a member with zero arguments. */
@Override
public boolean visit(MarkerAnnotation node) {
DependencyType dependencyType = findDependencyTypeForAnnotation(node);
addSimpleTypeName(node.getTypeName(), dependencyType);
return true;
}
/** An annotation on a member with named arguments. */
@Override
public boolean visit(NormalAnnotation node) {
DependencyType dependencyType = findDependencyTypeForAnnotation(node);
addSimpleTypeName(node.getTypeName(), dependencyType);
return true;
}
/** An annotation on a member with a single, unnamed argument. */
@Override
public boolean visit(SingleMemberAnnotation node) {
DependencyType dependencyType = findDependencyTypeForAnnotation(node);
addSimpleTypeName(node.getTypeName(), dependencyType);
return true;
}
private DependencyType findDependencyTypeForAnnotation(Annotation annotation) {
ASTNode parentNode = annotation.getParent();
if (parentNode == null) {
return DependencyType.REQUIRED;
}
if (parentNode instanceof BodyDeclaration) {
// Note that BodyDeclaration is an abstract class. Its subclasses are things like
// FieldDeclaration and MethodDeclaration. We want to be sure that an annotation on any
// non-private declaration is considered an exported symbol.
BodyDeclaration declaration = (BodyDeclaration) parentNode;
int modifiers = declaration.getModifiers();
if ((modifiers & Modifier.PRIVATE) == 0) {
return DependencyType.EXPORTED;
}
}
return DependencyType.REQUIRED;
}
@Override
public boolean visit(SimpleType node) {
// This method is responsible for finding the overwhelming majority of the required symbols
// in the AST.
tryAddType(node, DependencyType.REQUIRED);
return true;
}
// exportedSymbols
@Override
public boolean visit(MethodDeclaration node) {
// Types from private method signatures need not be exported.
if ((node.getModifiers() & Modifier.PRIVATE) != 0) {
return true;
}
Type returnType = node.getReturnType2();
if (returnType != null) {
tryAddType(returnType, DependencyType.EXPORTED);
}
@SuppressWarnings("unchecked") List<SingleVariableDeclaration> params = node.parameters();
for (SingleVariableDeclaration decl : params) {
tryAddType(decl.getType(), DependencyType.EXPORTED);
}
@SuppressWarnings("unchecked") List<Type> exceptions = node.thrownExceptionTypes();
for (Type exception : exceptions) {
tryAddType(exception, DependencyType.EXPORTED);
}
return true;
}
@Override
public boolean visit(FieldDeclaration node) {
// Types from private fields need not be exported.
if ((node.getModifiers() & Modifier.PRIVATE) == 0) {
tryAddType(node.getType(), DependencyType.EXPORTED);
}
return true;
}
private void tryAddType(Type type, DependencyType dependencyType) {
if (type.isSimpleType()) {
SimpleType simpleType = (SimpleType) type;
Name simpleTypeName = simpleType.getName();
String simpleName = simpleTypeName.toString();
// rather than simply required.
if (!CharMatcher.javaUpperCase().matchesAllOf(simpleName) || (dependencyType == DependencyType.EXPORTED && simpleImportedTypes.containsKey(simpleName))) {
addSimpleTypeName(simpleTypeName, dependencyType);
}
} else if (type.isArrayType()) {
ArrayType arrayType = (ArrayType) type;
tryAddType(arrayType.getElementType(), dependencyType);
} else if (type.isParameterizedType()) {
ParameterizedType parameterizedType = (ParameterizedType) type;
tryAddType(parameterizedType.getType(), dependencyType);
@SuppressWarnings("unchecked") List<Type> argTypes = parameterizedType.typeArguments();
for (Type argType : argTypes) {
tryAddType(argType, dependencyType);
}
}
}
private void addSimpleTypeName(Name simpleTypeName, DependencyType dependencyType) {
String simpleName = simpleTypeName.toString();
if (JAVA_LANG_TYPES.contains(simpleName)) {
return;
}
String fullyQualifiedNameForSimpleName = simpleImportedTypes.get(simpleName);
if (fullyQualifiedNameForSimpleName != null) {
// May need to promote from required to exported in this case.
if (dependencyType == DependencyType.EXPORTED) {
addSymbol(fullyQualifiedNameForSimpleName, DependencyType.EXPORTED);
}
return;
}
// the iterator most of the time.
if (!wildcardImports.isEmpty()) {
for (Map.Entry<String, ImmutableSet<String>> entry : wildcardImports.entrySet()) {
Set<String> types = entry.getValue();
if (types.contains(simpleName)) {
String packageName = entry.getKey();
addSymbol(packageName + "." + simpleName, dependencyType);
return;
}
}
}
String symbol = simpleTypeName.getFullyQualifiedName();
symbol = qualifyWithPackageNameIfNecessary(symbol);
addSymbol(symbol, dependencyType);
}
private void addSymbol(String symbol, DependencyType dependencyType) {
((dependencyType == DependencyType.REQUIRED) ? requiredSymbols : exportedSymbols).add(symbol);
}
private String qualifyWithPackageNameIfNecessary(String symbol) {
if (!startsWithUppercaseChar(symbol)) {
return symbol;
}
// If the symbol starts with a capital letter, then we assume that it is a reference to
// a type in the same package.
int index = symbol.indexOf('.');
if (index >= 0) {
symbol = symbol.substring(0, index);
}
if (packageName != null) {
symbol = packageName + "." + symbol;
}
return symbol;
}
});
// TODO(bolinfest): Special treatment for exportedSymbols when poisoned by wildcard import.
ImmutableSortedSet<String> totalExportedSymbols = exportedSymbols.build();
// If we were poisoned by an unsupported wildcard import, then we should rely exclusively on
// the explicit imports to determine the required symbols.
Set<String> totalRequiredSymbols = new HashSet<>();
if (isPoisonedByUnsupportedWildcardImport.get()) {
totalRequiredSymbols.addAll(requiredSymbolsFromExplicitImports.build());
} else {
totalRequiredSymbols.addAll(requiredSymbolsFromExplicitImports.build());
totalRequiredSymbols.addAll(requiredSymbols.build());
}
// Make sure that required and exported symbols are disjoint sets.
totalRequiredSymbols.removeAll(totalExportedSymbols);
return new JavaFileFeatures(providedSymbols.build(), ImmutableSortedSet.copyOf(totalRequiredSymbols), totalExportedSymbols);
}
use of org.eclipse.jdt.core.dom.MethodInvocation in project che by eclipse.
the class CallInliner method needsExplicitCast.
/**
* @param status the status
* @return <code>true</code> if explicit cast is needed otherwise <code>false</code>
*/
private boolean needsExplicitCast(RefactoringStatus status) {
// returned expression then we don't need an explicit cast.
if (fSourceProvider.returnTypeMatchesReturnExpressions())
return false;
List<Expression> returnExprs = fSourceProvider.getReturnExpressions();
// method invocations
if (returnExprs.size() != 1)
return false;
if (fTargetNode.getLocationInParent() == MethodInvocation.ARGUMENTS_PROPERTY) {
MethodInvocation methodInvocation = (MethodInvocation) fTargetNode.getParent();
if (methodInvocation.getExpression() == fTargetNode)
return false;
IMethodBinding method = methodInvocation.resolveMethodBinding();
if (method == null) {
status.addError(RefactoringCoreMessages.CallInliner_cast_analysis_error, JavaStatusContext.create(fCUnit, methodInvocation));
return false;
}
ITypeBinding[] parameters = method.getParameterTypes();
int argumentIndex = methodInvocation.arguments().indexOf(fInvocation);
ITypeBinding parameterType = returnExprs.get(0).resolveTypeBinding();
if (method.isVarargs() && argumentIndex >= parameters.length - 1) {
argumentIndex = parameters.length - 1;
parameterType = parameterType.createArrayType(1);
}
parameters[argumentIndex] = parameterType;
ITypeBinding type = ASTNodes.getReceiverTypeBinding(methodInvocation);
TypeBindingVisitor visitor = new AmbiguousMethodAnalyzer(fTypeEnvironment, method, fTypeEnvironment.create(parameters));
if (!visitor.visit(type)) {
return true;
} else if (type.isInterface()) {
return !Bindings.visitInterfaces(type, visitor);
} else if (Modifier.isAbstract(type.getModifiers())) {
return !Bindings.visitHierarchy(type, visitor);
} else {
// it is not needed to visit interfaces if receiver is a concrete class
return !Bindings.visitSuperclasses(type, visitor);
}
} else {
ITypeBinding explicitCast = ASTNodes.getExplicitCast(returnExprs.get(0), (Expression) fTargetNode);
return explicitCast != null;
}
}
Aggregations