Search in sources :

Example 1 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor in project che by eclipse.

the class RenameTypeProcessor method analyseEnclosedTypes.

private RefactoringStatus analyseEnclosedTypes() throws CoreException {
    final ISourceRange typeRange = fType.getSourceRange();
    final RefactoringStatus result = new RefactoringStatus();
    CompilationUnit cuNode = new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(fType.getCompilationUnit(), false);
    cuNode.accept(new ASTVisitor() {

        @Override
        public boolean visit(TypeDeclaration node) {
            // enums and annotations can't be local
            if (node.getStartPosition() <= typeRange.getOffset())
                return true;
            if (node.getStartPosition() > typeRange.getOffset() + typeRange.getLength())
                return true;
            if (getNewElementName().equals(node.getName().getIdentifier())) {
                RefactoringStatusContext context = JavaStatusContext.create(fType.getCompilationUnit(), node);
                String msg = null;
                if (node.isLocalTypeDeclaration()) {
                    msg = Messages.format(RefactoringCoreMessages.RenameTypeRefactoring_local_type, new String[] { JavaElementUtil.createSignature(fType), getNewElementLabel() });
                } else if (node.isMemberTypeDeclaration()) {
                    msg = Messages.format(RefactoringCoreMessages.RenameTypeRefactoring_member_type, new String[] { JavaElementUtil.createSignature(fType), getNewElementLabel() });
                }
                if (msg != null)
                    result.addError(msg, context);
            }
            MethodDeclaration[] methods = node.getMethods();
            for (int i = 0; i < methods.length; i++) {
                if (Modifier.isNative(methods[i].getModifiers())) {
                    RefactoringStatusContext context = JavaStatusContext.create(fType.getCompilationUnit(), methods[i]);
                    String msg = Messages.format(RefactoringCoreMessages.RenameTypeRefactoring_enclosed_type_native, BasicElementLabels.getJavaElementName(node.getName().getIdentifier()));
                    result.addWarning(msg, context);
                }
            }
            return true;
        }
    });
    return result;
}
Also used : CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) RefactoringStatusContext(org.eclipse.ltk.core.refactoring.RefactoringStatusContext) RefactoringASTParser(org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser) RefactoringStatus(org.eclipse.ltk.core.refactoring.RefactoringStatus) TypeDeclaration(org.eclipse.jdt.core.dom.TypeDeclaration) ISourceRange(org.eclipse.jdt.core.ISourceRange) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor)

Example 2 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor 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;
}
Also used : IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) ImportRewrite(org.eclipse.jdt.core.dom.rewrite.ImportRewrite) SimpleName(org.eclipse.jdt.core.dom.SimpleName) IBinding(org.eclipse.jdt.core.dom.IBinding) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation) ListRewrite(org.eclipse.jdt.core.dom.rewrite.ListRewrite) SimpleName(org.eclipse.jdt.core.dom.SimpleName) Name(org.eclipse.jdt.core.dom.Name) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ASTNode(org.eclipse.jdt.core.dom.ASTNode) ASTRewrite(org.eclipse.jdt.core.dom.rewrite.ASTRewrite) ImportRemover(org.eclipse.jdt.internal.corext.refactoring.structure.ImportRemover) AST(org.eclipse.jdt.core.dom.AST) Statement(org.eclipse.jdt.core.dom.Statement) ForStatement(org.eclipse.jdt.core.dom.ForStatement) EnhancedForStatement(org.eclipse.jdt.core.dom.EnhancedForStatement) SingleVariableDeclaration(org.eclipse.jdt.core.dom.SingleVariableDeclaration) VariableDeclarationExpression(org.eclipse.jdt.core.dom.VariableDeclarationExpression) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor) Expression(org.eclipse.jdt.core.dom.Expression) VariableDeclarationExpression(org.eclipse.jdt.core.dom.VariableDeclarationExpression) Block(org.eclipse.jdt.core.dom.Block) FieldAccess(org.eclipse.jdt.core.dom.FieldAccess)

Example 3 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor 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);
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashSet(java.util.HashSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) HashMap(java.util.HashMap) MethodInvocation(org.eclipse.jdt.core.dom.MethodInvocation) FieldDeclaration(org.eclipse.jdt.core.dom.FieldDeclaration) QualifiedName(org.eclipse.jdt.core.dom.QualifiedName) Name(org.eclipse.jdt.core.dom.Name) ArrayType(org.eclipse.jdt.core.dom.ArrayType) ParameterizedType(org.eclipse.jdt.core.dom.ParameterizedType) SimpleType(org.eclipse.jdt.core.dom.SimpleType) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) ASTNode(org.eclipse.jdt.core.dom.ASTNode) NormalAnnotation(org.eclipse.jdt.core.dom.NormalAnnotation) List(java.util.List) LinkedList(java.util.LinkedList) PackageDeclaration(org.eclipse.jdt.core.dom.PackageDeclaration) HashSet(java.util.HashSet) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) Optional(java.util.Optional) SingleMemberAnnotation(org.eclipse.jdt.core.dom.SingleMemberAnnotation) MethodDeclaration(org.eclipse.jdt.core.dom.MethodDeclaration) SingleVariableDeclaration(org.eclipse.jdt.core.dom.SingleVariableDeclaration) QualifiedName(org.eclipse.jdt.core.dom.QualifiedName) AnnotationTypeDeclaration(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration) SingleMemberAnnotation(org.eclipse.jdt.core.dom.SingleMemberAnnotation) MarkerAnnotation(org.eclipse.jdt.core.dom.MarkerAnnotation) Annotation(org.eclipse.jdt.core.dom.Annotation) NormalAnnotation(org.eclipse.jdt.core.dom.NormalAnnotation) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor) EnumDeclaration(org.eclipse.jdt.core.dom.EnumDeclaration) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArrayType(org.eclipse.jdt.core.dom.ArrayType) ParameterizedType(org.eclipse.jdt.core.dom.ParameterizedType) SimpleType(org.eclipse.jdt.core.dom.SimpleType) Type(org.eclipse.jdt.core.dom.Type) MarkerAnnotation(org.eclipse.jdt.core.dom.MarkerAnnotation) TypeDeclarationStatement(org.eclipse.jdt.core.dom.TypeDeclarationStatement) ImportDeclaration(org.eclipse.jdt.core.dom.ImportDeclaration) BodyDeclaration(org.eclipse.jdt.core.dom.BodyDeclaration) AbstractTypeDeclaration(org.eclipse.jdt.core.dom.AbstractTypeDeclaration) AnnotationTypeDeclaration(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration) TypeDeclaration(org.eclipse.jdt.core.dom.TypeDeclaration) Nullable(javax.annotation.Nullable)

Example 4 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor in project che by eclipse.

the class CallInliner method crossCheckArguments.

/**
     * Checks whether arguments are passed to the method which do some assignments
     * inside the expression. If so these arguments can't be inlined into the
     * calling method since the assignments might be reorder. An example is:
     * <code>
     *   add((field=args).length,field.hashCode());
     * </code>
     * Field might not be initialized when the arguments are reorder in the called
     * method.
     * @param arguments the arguments
     * @return all arguments that cannot be inlined
     */
private Set<Expression> crossCheckArguments(List<Expression> arguments) {
    final Set<IBinding> assigned = new HashSet<IBinding>();
    final Set<Expression> result = new HashSet<Expression>();
    for (Iterator<Expression> iter = arguments.iterator(); iter.hasNext(); ) {
        final Expression expression = iter.next();
        expression.accept(new ASTVisitor() {

            @Override
            public boolean visit(Assignment node) {
                Expression lhs = node.getLeftHandSide();
                if (lhs instanceof Name) {
                    IBinding binding = ((Name) lhs).resolveBinding();
                    if (binding instanceof IVariableBinding) {
                        assigned.add(binding);
                        result.add(expression);
                    }
                }
                return true;
            }
        });
    }
    for (Iterator<Expression> iter = arguments.iterator(); iter.hasNext(); ) {
        final Expression expression = iter.next();
        if (!result.contains(expression)) {
            expression.accept(new HierarchicalASTVisitor() {

                @Override
                public boolean visit(Name node) {
                    IBinding binding = node.resolveBinding();
                    if (binding != null && assigned.contains(binding))
                        result.add(expression);
                    return false;
                }
            });
        }
    }
    return result;
}
Also used : Assignment(org.eclipse.jdt.core.dom.Assignment) ThisExpression(org.eclipse.jdt.core.dom.ThisExpression) Expression(org.eclipse.jdt.core.dom.Expression) CastExpression(org.eclipse.jdt.core.dom.CastExpression) ParenthesizedExpression(org.eclipse.jdt.core.dom.ParenthesizedExpression) IBinding(org.eclipse.jdt.core.dom.IBinding) IVariableBinding(org.eclipse.jdt.core.dom.IVariableBinding) HierarchicalASTVisitor(org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor) HashSet(java.util.HashSet) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor) HierarchicalASTVisitor(org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor) SimpleName(org.eclipse.jdt.core.dom.SimpleName) Name(org.eclipse.jdt.core.dom.Name)

Example 5 with ASTVisitor

use of org.eclipse.jdt.core.dom.ASTVisitor in project che by eclipse.

the class ConvertAnonymousToNestedRefactoring method getAllAccessedFields.

private List<IBinding> getAllAccessedFields() {
    final List<IBinding> accessedFields = new ArrayList<IBinding>();
    ASTVisitor visitor = new ASTVisitor() {

        @Override
        public boolean visit(FieldAccess node) {
            final IVariableBinding binding = node.resolveFieldBinding();
            if (binding != null && !binding.isEnumConstant())
                accessedFields.add(binding);
            return super.visit(node);
        }

        @Override
        public boolean visit(QualifiedName node) {
            final IBinding binding = node.resolveBinding();
            if (binding != null && binding instanceof IVariableBinding) {
                IVariableBinding variable = (IVariableBinding) binding;
                if (!variable.isEnumConstant() && variable.isField())
                    accessedFields.add(binding);
            }
            return super.visit(node);
        }

        @Override
        public boolean visit(SimpleName node) {
            final IBinding binding = node.resolveBinding();
            if (binding != null && binding instanceof IVariableBinding) {
                IVariableBinding variable = (IVariableBinding) binding;
                if (!variable.isEnumConstant() && variable.isField())
                    accessedFields.add(binding);
            }
            return super.visit(node);
        }

        @Override
        public boolean visit(SuperFieldAccess node) {
            final IVariableBinding binding = node.resolveFieldBinding();
            if (binding != null && !binding.isEnumConstant())
                accessedFields.add(binding);
            return super.visit(node);
        }
    };
    fAnonymousInnerClassNode.accept(visitor);
    return accessedFields;
}
Also used : IBinding(org.eclipse.jdt.core.dom.IBinding) QualifiedName(org.eclipse.jdt.core.dom.QualifiedName) SimpleName(org.eclipse.jdt.core.dom.SimpleName) ArrayList(java.util.ArrayList) SuperFieldAccess(org.eclipse.jdt.core.dom.SuperFieldAccess) FieldAccess(org.eclipse.jdt.core.dom.FieldAccess) SuperFieldAccess(org.eclipse.jdt.core.dom.SuperFieldAccess) IVariableBinding(org.eclipse.jdt.core.dom.IVariableBinding) ASTVisitor(org.eclipse.jdt.core.dom.ASTVisitor)

Aggregations

ASTVisitor (org.eclipse.jdt.core.dom.ASTVisitor)64 ArrayList (java.util.ArrayList)26 ASTNode (org.eclipse.jdt.core.dom.ASTNode)19 SimpleName (org.eclipse.jdt.core.dom.SimpleName)19 CompilationUnit (org.eclipse.jdt.core.dom.CompilationUnit)16 List (java.util.List)13 ICompilationUnit (org.eclipse.jdt.core.ICompilationUnit)13 MethodDeclaration (org.eclipse.jdt.core.dom.MethodDeclaration)13 ASTParser (org.eclipse.jdt.core.dom.ASTParser)11 SingleVariableDeclaration (org.eclipse.jdt.core.dom.SingleVariableDeclaration)11 TypeDeclaration (org.eclipse.jdt.core.dom.TypeDeclaration)11 VariableDeclarationStatement (org.eclipse.jdt.core.dom.VariableDeclarationStatement)11 Block (org.eclipse.jdt.core.dom.Block)10 Statement (org.eclipse.jdt.core.dom.Statement)10 Expression (org.eclipse.jdt.core.dom.Expression)9 ImportDeclaration (org.eclipse.jdt.core.dom.ImportDeclaration)9 Name (org.eclipse.jdt.core.dom.Name)9 SearchResult (com.liferay.blade.api.SearchResult)8 FieldDeclaration (org.eclipse.jdt.core.dom.FieldDeclaration)8 MethodInvocation (org.eclipse.jdt.core.dom.MethodInvocation)8