1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.google.currysrc.api.process.ast; 17 18import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 19import org.eclipse.jdt.core.dom.BodyDeclaration; 20import org.eclipse.jdt.core.dom.CompilationUnit; 21import org.eclipse.jdt.core.dom.FieldDeclaration; 22import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 23 24import java.util.ArrayList; 25import java.util.List; 26 27/** 28 * Locates the {@link org.eclipse.jdt.core.dom.BodyDeclaration} associated with an field 29 * declaration. 30 */ 31public final class FieldLocator implements BodyDeclarationLocator { 32 33 static final String LOCATOR_TYPE_NAME = "field"; 34 35 private final TypeLocator typeLocator; 36 37 private final String fieldName; 38 39 public FieldLocator(String packageName, String typeName, String fieldName) { 40 this(new TypeLocator(packageName, typeName), fieldName); 41 } 42 43 public FieldLocator(TypeLocator typeLocator, String fieldName) { 44 this.typeLocator = typeLocator; 45 this.fieldName = fieldName; 46 } 47 48 @Override public TypeLocator getTypeLocator() { 49 return typeLocator; 50 } 51 52 @Override 53 public boolean matches(BodyDeclaration node) { 54 if (node instanceof FieldDeclaration) { 55 FieldDeclaration fieldDeclaration = (FieldDeclaration) node; 56 for (VariableDeclarationFragment variableDeclarationFragment 57 : (List<VariableDeclarationFragment>) fieldDeclaration.fragments()) { 58 String nodeFieldName = variableDeclarationFragment.getName().getFullyQualifiedName(); 59 if (nodeFieldName.equals(fieldName)) { 60 BodyDeclaration parentNode = (BodyDeclaration) node.getParent(); 61 return typeLocator.matches(parentNode); 62 } 63 } 64 } 65 return false; 66 } 67 68 @Override 69 public FieldDeclaration find(CompilationUnit cu) { 70 AbstractTypeDeclaration typeDeclaration = typeLocator.find(cu); 71 if (typeDeclaration == null) { 72 return null; 73 } 74 for (BodyDeclaration bodyDeclaration 75 : (List<BodyDeclaration>) typeDeclaration.bodyDeclarations()) { 76 if (bodyDeclaration instanceof FieldDeclaration) { 77 FieldDeclaration fieldDeclaration = (FieldDeclaration) bodyDeclaration; 78 for (VariableDeclarationFragment variableDeclarationFragment 79 : (List<VariableDeclarationFragment>) fieldDeclaration.fragments()) { 80 String nodeFieldName = variableDeclarationFragment.getName().getFullyQualifiedName(); 81 if (nodeFieldName.equals(fieldName)) { 82 return fieldDeclaration; 83 } 84 } 85 } 86 } 87 return null; 88 } 89 90 @Override public String getStringFormType() { 91 return LOCATOR_TYPE_NAME; 92 } 93 94 @Override public String getStringFormTarget() { 95 return typeLocator.getStringFormTarget() + "#" + fieldName; 96 } 97 98 /** 99 * Returns the names of the fields declared in the supplied {@code fieldDeclarationNode}. 100 */ 101 public static List<String> getFieldNames(FieldDeclaration fieldDeclarationNode) { 102 List<VariableDeclarationFragment> fieldDeclarations = fieldDeclarationNode.fragments(); 103 List<String> fieldNames = new ArrayList<>(fieldDeclarations.size()); 104 for (VariableDeclarationFragment fieldDeclaration : fieldDeclarations) { 105 fieldNames.add(fieldDeclaration.getName().getIdentifier()); 106 } 107 return fieldNames; 108 } 109 110 @Override 111 public String toString() { 112 return "FieldLocator{" + 113 "typeLocator=" + typeLocator + 114 ", fieldName='" + fieldName + '\'' + 115 '}'; 116 } 117} 118