astview.ASTViewContentProvider.java Source code

Java tutorial

Introduction

Here is the source code for astview.ASTViewContentProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package astview;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.MemberRef;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.MethodRef;
import org.eclipse.jdt.core.dom.MethodReference;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.SuperFieldAccess;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.VariableDeclaration;

import run.Driver;

public class ASTViewContentProvider {

    public static boolean printed = false; // indicate whether the astview is printed

    public Object[] getElements(Object parent) {
        return getChildren(parent);
    }

    public Object getParent(Object child) {
        if (child instanceof ASTNode) {
            ASTNode node = (ASTNode) child;
            ASTNode parent = node.getParent();
            if (parent != null) {
                StructuralPropertyDescriptor prop = node.getLocationInParent();
                return new NodeProperty(parent, prop);
            }
        } else if (child instanceof ASTAttribute) {
            return ((ASTAttribute) child).getParent();
        }
        return null;
    }

    public Object[] getChildren(Object parent) {
        if (parent instanceof ASTAttribute) {
            return ((ASTAttribute) parent).getChildren();
        } else if (parent instanceof ASTNode) {

            // print only when the AST is first visited
            if (printed == false) {

                String[] out = Driver.PATH.split("\\.");
                File file = new File(out[out.length - 2] + ".txt");
                PrintWriter output = null;
                try {
                    output = new PrintWriter(file);
                } catch (FileNotFoundException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                Object[] obj = getNodeChildren((ASTNode) parent);
                for (int i = 0; i < obj.length; i++) {
                    if (obj[i] instanceof NodeProperty) {
                        NodeProperty node = (NodeProperty) obj[i];
                        try {
                            dfsDisplayProperty(node, 0, file, output);
                        } catch (FileNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }

                output.close();
                printed = true;

                // Test end
            }

            return getNodeChildren((ASTNode) parent);
        }

        return new Object[0];
    }

    /**
     * recursively display all astview on AST
     * @param node the <code>NodeProperty</code> instance
     * @param level indent level
     * @param file
     * @param output 
     * @throws FileNotFoundException
     */
    public void dfsDisplayProperty(NodeProperty node, int level, File file, PrintWriter output)
            throws FileNotFoundException {
        for (int i = 0; i < level; i++) {
            System.out.print(" ");
            output.print(" ");
        }

        String str = ((Object) node).toString();
        System.out.println(str);
        output.println(str);
        Object[] ob = node.getChildren();
        for (Object o : ob) {
            if (o instanceof ASTNode) {
                String[] name = o.getClass().getName().split("\\.");
                level++;
                for (int i = 0; i < level; i++) {
                    System.out.print(" ");
                    output.print(" ");
                }
                System.out.println(name[name.length - 1]);
                output.println(name[name.length - 1]);
                Object[] obj = getNodeChildren((ASTNode) o);
                for (int i = 0; i < obj.length; i++) {
                    if (obj[i] instanceof NodeProperty) {
                        NodeProperty n = (NodeProperty) obj[i];
                        dfsDisplayProperty(n, level + 1, file, output);
                    }
                }
            }
        }
    }

    // Test end
    private Object[] getNodeChildren(ASTNode node) {
        ArrayList<Object> res = new ArrayList<>();

        if (node instanceof Expression) {
            Expression expression = (Expression) node;
            ITypeBinding expressionTypeBinding = expression.resolveTypeBinding();
            res.add(createExpressionTypeBinding(node, expressionTypeBinding));

            // expressions:
            if (expression instanceof Name) {
                IBinding binding = ((Name) expression).resolveBinding();
                if (binding != expressionTypeBinding)
                    res.add(createBinding(expression, binding));
            } else if (expression instanceof MethodInvocation) {
                MethodInvocation methodInvocation = (MethodInvocation) expression;
                IMethodBinding binding = methodInvocation.resolveMethodBinding();
                res.add(createBinding(expression, binding));
                String inferred = String.valueOf(methodInvocation.isResolvedTypeInferredFromExpectedType());
                res.add(new GeneralAttribute(expression, "ResolvedTypeInferredFromExpectedType", inferred)); //$NON-NLS-1$
            } else if (expression instanceof SuperMethodInvocation) {
                SuperMethodInvocation superMethodInvocation = (SuperMethodInvocation) expression;
                IMethodBinding binding = superMethodInvocation.resolveMethodBinding();
                res.add(createBinding(expression, binding));
                String inferred = String.valueOf(superMethodInvocation.isResolvedTypeInferredFromExpectedType());
                res.add(new GeneralAttribute(expression, "ResolvedTypeInferredFromExpectedType", inferred)); //$NON-NLS-1$
            } else if (expression instanceof ClassInstanceCreation) {
                ClassInstanceCreation classInstanceCreation = (ClassInstanceCreation) expression;
                IMethodBinding binding = classInstanceCreation.resolveConstructorBinding();
                res.add(createBinding(expression, binding));
                String inferred = String.valueOf(classInstanceCreation.isResolvedTypeInferredFromExpectedType());
                res.add(new GeneralAttribute(expression, "ResolvedTypeInferredFromExpectedType", inferred)); //$NON-NLS-1$
            } else if (expression instanceof FieldAccess) {
                IVariableBinding binding = ((FieldAccess) expression).resolveFieldBinding();
                res.add(createBinding(expression, binding));
            } else if (expression instanceof SuperFieldAccess) {
                IVariableBinding binding = ((SuperFieldAccess) expression).resolveFieldBinding();
                res.add(createBinding(expression, binding));
            } else if (expression instanceof Annotation) {
                IAnnotationBinding binding = ((Annotation) expression).resolveAnnotationBinding();
                res.add(createBinding(expression, binding));
            } else if (expression instanceof LambdaExpression) {
                ASTAttribute bindingAttribute;
                try {
                    IMethodBinding binding = ((LambdaExpression) expression).resolveMethodBinding();
                    bindingAttribute = createBinding(expression, binding);
                } catch (RuntimeException e) {
                    bindingAttribute = new Error(res, ">binding: Error: " + e.getMessage(), e);
                }
                res.add(bindingAttribute);
            } else if (expression instanceof MethodReference) {
                IMethodBinding binding = ((MethodReference) expression).resolveMethodBinding();
                res.add(createBinding(expression, binding));
            }
            // Expression attributes:
            res.add(new GeneralAttribute(expression,
                    "Boxing: " + expression.resolveBoxing() + "; Unboxing: " + expression.resolveUnboxing())); //$NON-NLS-1$ //$NON-NLS-2$
            res.add(new GeneralAttribute(expression, "ConstantExpressionValue", //$NON-NLS-1$
                    expression.resolveConstantExpressionValue()));

            // references:
        } else if (node instanceof ConstructorInvocation) {
            IMethodBinding binding = ((ConstructorInvocation) node).resolveConstructorBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof SuperConstructorInvocation) {
            IMethodBinding binding = ((SuperConstructorInvocation) node).resolveConstructorBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof MethodRef) {
            IBinding binding = ((MethodRef) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof MemberRef) {
            IBinding binding = ((MemberRef) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof Type) {
            IBinding binding = ((Type) node).resolveBinding();
            res.add(createBinding(node, binding));

            // declarations:
        } else if (node instanceof AbstractTypeDeclaration) {
            IBinding binding = ((AbstractTypeDeclaration) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof AnnotationTypeMemberDeclaration) {
            IBinding binding = ((AnnotationTypeMemberDeclaration) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof EnumConstantDeclaration) {
            IBinding binding = ((EnumConstantDeclaration) node).resolveVariable();
            res.add(createBinding(node, binding));
            IBinding binding2 = ((EnumConstantDeclaration) node).resolveConstructorBinding();
            res.add(createBinding(node, binding2));
        } else if (node instanceof MethodDeclaration) {
            IBinding binding = ((MethodDeclaration) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof VariableDeclaration) {
            IBinding binding = ((VariableDeclaration) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof AnonymousClassDeclaration) {
            IBinding binding = ((AnonymousClassDeclaration) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof ImportDeclaration) {
            IBinding binding = ((ImportDeclaration) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof PackageDeclaration) {
            IBinding binding = ((PackageDeclaration) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof TypeParameter) {
            IBinding binding = ((TypeParameter) node).resolveBinding();
            res.add(createBinding(node, binding));
        } else if (node instanceof MemberValuePair) {
            IBinding binding = ((MemberValuePair) node).resolveMemberValuePairBinding();
            res.add(createBinding(node, binding));
        }

        @SuppressWarnings("unchecked")
        List<StructuralPropertyDescriptor> list = node.structuralPropertiesForType();
        for (int i = 0; i < list.size(); i++) {
            StructuralPropertyDescriptor curr = list.get(i);
            res.add(new NodeProperty(node, curr));
        }

        return res.toArray();
    }

    private Binding createBinding(ASTNode parent, IBinding binding) {
        String label = Binding.getBindingLabel(binding);
        return new Binding(parent, label, binding, true);
    }

    private Object createExpressionTypeBinding(ASTNode parent, ITypeBinding binding) {
        String label = "> (Expression) type binding"; //$NON-NLS-1$
        return new Binding(parent, label, binding, true);
    }

    public boolean hasChildren(Object parent) {
        return getChildren(parent).length > 0;
    }
}