| 1 | /******************************************************************************* |
|---|---|
| 2 | * Copyright (c) 2000, 2017 IBM Corporation and others. |
| 3 | * |
| 4 | * This program and the accompanying materials |
| 5 | * are made available under the terms of the Eclipse Public License 2.0 |
| 6 | * which accompanies this distribution, and is available at |
| 7 | * https://www.eclipse.org/legal/epl-2.0/ |
| 8 | * |
| 9 | * SPDX-License-Identifier: EPL-2.0 |
| 10 | * |
| 11 | * Contributors: |
| 12 | * IBM Corporation - initial API and implementation |
| 13 | *******************************************************************************/ |
| 14 | |
| 15 | package org.eclipse.jdt.astview.views; |
| 16 | |
| 17 | import java.util.ArrayList; |
| 18 | import java.util.List; |
| 19 | |
| 20 | import org.eclipse.jdt.astview.ASTViewPlugin; |
| 21 | |
| 22 | import org.eclipse.jface.viewers.ITreeContentProvider; |
| 23 | import org.eclipse.jface.viewers.Viewer; |
| 24 | |
| 25 | import org.eclipse.jdt.core.dom.ASTNode; |
| 26 | import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; |
| 27 | import org.eclipse.jdt.core.dom.Annotation; |
| 28 | import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; |
| 29 | import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; |
| 30 | import org.eclipse.jdt.core.dom.ClassInstanceCreation; |
| 31 | import org.eclipse.jdt.core.dom.CompilationUnit; |
| 32 | import org.eclipse.jdt.core.dom.ConstructorInvocation; |
| 33 | import org.eclipse.jdt.core.dom.EnumConstantDeclaration; |
| 34 | import org.eclipse.jdt.core.dom.Expression; |
| 35 | import org.eclipse.jdt.core.dom.FieldAccess; |
| 36 | import org.eclipse.jdt.core.dom.IAnnotationBinding; |
| 37 | import org.eclipse.jdt.core.dom.IBinding; |
| 38 | import org.eclipse.jdt.core.dom.IMethodBinding; |
| 39 | import org.eclipse.jdt.core.dom.ITypeBinding; |
| 40 | import org.eclipse.jdt.core.dom.IVariableBinding; |
| 41 | import org.eclipse.jdt.core.dom.ImportDeclaration; |
| 42 | import org.eclipse.jdt.core.dom.LambdaExpression; |
| 43 | import org.eclipse.jdt.core.dom.MemberRef; |
| 44 | import org.eclipse.jdt.core.dom.MemberValuePair; |
| 45 | import org.eclipse.jdt.core.dom.MethodDeclaration; |
| 46 | import org.eclipse.jdt.core.dom.MethodInvocation; |
| 47 | import org.eclipse.jdt.core.dom.MethodRef; |
| 48 | import org.eclipse.jdt.core.dom.MethodReference; |
| 49 | import org.eclipse.jdt.core.dom.ModuleDeclaration; |
| 50 | import org.eclipse.jdt.core.dom.Name; |
| 51 | import org.eclipse.jdt.core.dom.PackageDeclaration; |
| 52 | import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; |
| 53 | import org.eclipse.jdt.core.dom.SuperConstructorInvocation; |
| 54 | import org.eclipse.jdt.core.dom.SuperFieldAccess; |
| 55 | import org.eclipse.jdt.core.dom.SuperMethodInvocation; |
| 56 | import org.eclipse.jdt.core.dom.Type; |
| 57 | import org.eclipse.jdt.core.dom.TypeParameter; |
| 58 | import org.eclipse.jdt.core.dom.VariableDeclaration; |
| 59 | |
| 60 | public class ASTViewContentProvider implements ITreeContentProvider { |
| 61 | |
| 62 | @Override |
| 63 | public void inputChanged(Viewer v, Object oldInput, Object newInput) { |
| 64 | } |
| 65 | |
| 66 | @Override |
| 67 | public void dispose() { |
| 68 | } |
| 69 | |
| 70 | @Override |
| 71 | public Object[] getElements(Object parent) { |
| 72 | return getChildren(parent); |
| 73 | } |
| 74 | |
| 75 | @Override |
| 76 | public Object getParent(Object child) { |
| 77 | if (child instanceof ASTNode) { |
| 78 | ASTNode node= (ASTNode) child; |
| 79 | ASTNode parent= node.getParent(); |
| 80 | if (parent != null) { |
| 81 | StructuralPropertyDescriptor prop= node.getLocationInParent(); |
| 82 | return new NodeProperty(parent, prop); |
| 83 | } |
| 84 | } else if (child instanceof ASTAttribute) { |
| 85 | return ((ASTAttribute) child).getParent(); |
| 86 | } |
| 87 | return null; |
| 88 | } |
| 89 | |
| 90 | @Override |
| 91 | public Object[] getChildren(Object parent) { |
| 92 | if (parent instanceof ASTAttribute) { |
| 93 | return ((ASTAttribute) parent).getChildren(); |
| 94 | } else if (parent instanceof ASTNode) { |
| 95 | return getNodeChildren((ASTNode) parent); |
| 96 | } |
| 97 | return new Object[0]; |
| 98 | } |
| 99 | |
| 100 | private Object[] getNodeChildren(ASTNode node) { |
| 101 | ArrayList<Object> res= new ArrayList<>(); |
| 102 | |
| 103 | if (node instanceof Expression) { |
| 104 | Expression expression= (Expression) node; |
| 105 | ITypeBinding expressionTypeBinding= expression.resolveTypeBinding(); |
| 106 | res.add(createExpressionTypeBinding(node, expressionTypeBinding)); |
| 107 | |
| 108 | // expressions: |
| 109 | if (expression instanceof Name) { |
| 110 | IBinding binding= ((Name) expression).resolveBinding(); |
| 111 | if (binding != expressionTypeBinding) |
| 112 | res.add(createBinding(expression, binding)); |
| 113 | } else if (expression instanceof MethodInvocation) { |
| 114 | MethodInvocation methodInvocation= (MethodInvocation) expression; |
| 115 | IMethodBinding binding= methodInvocation.resolveMethodBinding(); |
| 116 | res.add(createBinding(expression, binding)); |
| 117 | String inferred= String.valueOf(methodInvocation.isResolvedTypeInferredFromExpectedType()); |
| 118 | res.add(new GeneralAttribute(expression, "ResolvedTypeInferredFromExpectedType", inferred)); //$NON-NLS-1$ |
| 119 | } else if (expression instanceof SuperMethodInvocation) { |
| 120 | SuperMethodInvocation superMethodInvocation= (SuperMethodInvocation) expression; |
| 121 | IMethodBinding binding= superMethodInvocation.resolveMethodBinding(); |
| 122 | res.add(createBinding(expression, binding)); |
| 123 | String inferred= String.valueOf(superMethodInvocation.isResolvedTypeInferredFromExpectedType()); |
| 124 | res.add(new GeneralAttribute(expression, "ResolvedTypeInferredFromExpectedType", inferred)); //$NON-NLS-1$ |
| 125 | } else if (expression instanceof ClassInstanceCreation) { |
| 126 | ClassInstanceCreation classInstanceCreation= (ClassInstanceCreation) expression; |
| 127 | IMethodBinding binding= classInstanceCreation.resolveConstructorBinding(); |
| 128 | res.add(createBinding(expression, binding)); |
| 129 | String inferred= String.valueOf(classInstanceCreation.isResolvedTypeInferredFromExpectedType()); |
| 130 | res.add(new GeneralAttribute(expression, "ResolvedTypeInferredFromExpectedType", inferred)); //$NON-NLS-1$ |
| 131 | } else if (expression instanceof FieldAccess) { |
| 132 | IVariableBinding binding= ((FieldAccess) expression).resolveFieldBinding(); |
| 133 | res.add(createBinding(expression, binding)); |
| 134 | } else if (expression instanceof SuperFieldAccess) { |
| 135 | IVariableBinding binding= ((SuperFieldAccess) expression).resolveFieldBinding(); |
| 136 | res.add(createBinding(expression, binding)); |
| 137 | } else if (expression instanceof Annotation) { |
| 138 | IAnnotationBinding binding= ((Annotation) expression).resolveAnnotationBinding(); |
| 139 | res.add(createBinding(expression, binding)); |
| 140 | } else if (expression instanceof LambdaExpression) { |
| 141 | ASTAttribute bindingAttribute; |
| 142 | try { |
| 143 | IMethodBinding binding= ((LambdaExpression) expression).resolveMethodBinding(); |
| 144 | bindingAttribute= createBinding(expression, binding); |
| 145 | } catch (RuntimeException e) { |
| 146 | bindingAttribute= new Error(res, ">binding: Error: " + e.getMessage(), e); |
| 147 | ASTViewPlugin.log("Exception thrown in LambdaExpression#resolveMethodBinding() for \"" + expression + "\"", e); |
| 148 | } |
| 149 | res.add(bindingAttribute); |
| 150 | } else if (expression instanceof MethodReference) { |
| 151 | IMethodBinding binding= ((MethodReference) expression).resolveMethodBinding(); |
| 152 | res.add(createBinding(expression, binding)); |
| 153 | } |
| 154 | // Expression attributes: |
| 155 | res.add(new GeneralAttribute(expression, "Boxing: " + expression.resolveBoxing() + "; Unboxing: " + expression.resolveUnboxing())); //$NON-NLS-1$ //$NON-NLS-2$ |
| 156 | res.add(new GeneralAttribute(expression, "ConstantExpressionValue", expression.resolveConstantExpressionValue())); //$NON-NLS-1$ |
| 157 | |
| 158 | // references: |
| 159 | } else if (node instanceof ConstructorInvocation) { |
| 160 | IMethodBinding binding= ((ConstructorInvocation) node).resolveConstructorBinding(); |
| 161 | res.add(createBinding(node, binding)); |
| 162 | } else if (node instanceof SuperConstructorInvocation) { |
| 163 | IMethodBinding binding= ((SuperConstructorInvocation) node).resolveConstructorBinding(); |
| 164 | res.add(createBinding(node, binding)); |
| 165 | } else if (node instanceof MethodRef) { |
| 166 | IBinding binding= ((MethodRef) node).resolveBinding(); |
| 167 | res.add(createBinding(node, binding)); |
| 168 | } else if (node instanceof MemberRef) { |
| 169 | IBinding binding= ((MemberRef) node).resolveBinding(); |
| 170 | res.add(createBinding(node, binding)); |
| 171 | } else if (node instanceof Type) { |
| 172 | IBinding binding= ((Type) node).resolveBinding(); |
| 173 | res.add(createBinding(node, binding)); |
| 174 | |
| 175 | // declarations: |
| 176 | } else if (node instanceof AbstractTypeDeclaration) { |
| 177 | IBinding binding= ((AbstractTypeDeclaration) node).resolveBinding(); |
| 178 | res.add(createBinding(node, binding)); |
| 179 | } else if (node instanceof AnnotationTypeMemberDeclaration) { |
| 180 | IBinding binding= ((AnnotationTypeMemberDeclaration) node).resolveBinding(); |
| 181 | res.add(createBinding(node, binding)); |
| 182 | } else if (node instanceof EnumConstantDeclaration) { |
| 183 | IBinding binding= ((EnumConstantDeclaration) node).resolveVariable(); |
| 184 | res.add(createBinding(node, binding)); |
| 185 | IBinding binding2= ((EnumConstantDeclaration) node).resolveConstructorBinding(); |
| 186 | res.add(createBinding(node, binding2)); |
| 187 | } else if (node instanceof MethodDeclaration) { |
| 188 | IBinding binding= ((MethodDeclaration) node).resolveBinding(); |
| 189 | res.add(createBinding(node, binding)); |
| 190 | } else if (node instanceof VariableDeclaration) { |
| 191 | IBinding binding= ((VariableDeclaration) node).resolveBinding(); |
| 192 | res.add(createBinding(node, binding)); |
| 193 | } else if (node instanceof AnonymousClassDeclaration) { |
| 194 | IBinding binding= ((AnonymousClassDeclaration) node).resolveBinding(); |
| 195 | res.add(createBinding(node, binding)); |
| 196 | } else if (node instanceof ImportDeclaration) { |
| 197 | IBinding binding= ((ImportDeclaration) node).resolveBinding(); |
| 198 | res.add(createBinding(node, binding)); |
| 199 | } else if (node instanceof PackageDeclaration) { |
| 200 | IBinding binding= ((PackageDeclaration) node).resolveBinding(); |
| 201 | res.add(createBinding(node, binding)); |
| 202 | } else if (node instanceof TypeParameter) { |
| 203 | IBinding binding= ((TypeParameter) node).resolveBinding(); |
| 204 | res.add(createBinding(node, binding)); |
| 205 | } else if (node instanceof MemberValuePair) { |
| 206 | IBinding binding= ((MemberValuePair) node).resolveMemberValuePairBinding(); |
| 207 | res.add(createBinding(node, binding)); |
| 208 | } else if (node instanceof ModuleDeclaration) { |
| 209 | IBinding binding= ((ModuleDeclaration) node).resolveBinding(); |
| 210 | res.add(createBinding(node, binding)); |
| 211 | } |
| 212 | |
| 213 | |
| 214 | |
| 215 | List<StructuralPropertyDescriptor> list= node.structuralPropertiesForType(); |
| 216 | for (StructuralPropertyDescriptor curr : list) { |
| 217 | res.add(new NodeProperty(node, curr)); |
| 218 | } |
| 219 | |
| 220 | if (node instanceof CompilationUnit) { |
| 221 | CompilationUnit root= (CompilationUnit) node; |
| 222 | res.add(new JavaElement(root, root.getJavaElement())); |
| 223 | res.add(new CommentsProperty(root)); |
| 224 | res.add(new ProblemsProperty(root)); |
| 225 | res.add(new SettingsProperty(root)); |
| 226 | res.add(new WellKnownTypesProperty(root)); |
| 227 | } |
| 228 | |
| 229 | return res.toArray(); |
| 230 | } |
| 231 | |
| 232 | private Binding createBinding(ASTNode parent, IBinding binding) { |
| 233 | String label= Binding.getBindingLabel(binding); |
| 234 | return new Binding(parent, label, binding, true); |
| 235 | } |
| 236 | |
| 237 | private Object createExpressionTypeBinding(ASTNode parent, ITypeBinding binding) { |
| 238 | String label= "> (Expression) type binding"; //$NON-NLS-1$ |
| 239 | return new Binding(parent, label, binding, true); |
| 240 | } |
| 241 | |
| 242 | @Override |
| 243 | public boolean hasChildren(Object parent) { |
| 244 | return getChildren(parent).length > 0; |
| 245 | } |
| 246 | } |
| 247 |
Members