104b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller/*
204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * Copyright (C) 2015 The Android Open Source Project
304b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller *
404b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License");
504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * you may not use this file except in compliance with the License.
604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * You may obtain a copy of the License at
704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller *
804b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller *      http://www.apache.org/licenses/LICENSE-2.0
904b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller *
1004b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * Unless required by applicable law or agreed to in writing, software
1104b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS,
1204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1304b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * See the License for the specific language governing permissions and
1404b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * limitations under the License.
1504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller */
16ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fullerpackage com.google.currysrc.api.process.ast;
1704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
1804b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fullerimport org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
1904b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fullerimport org.eclipse.jdt.core.dom.BodyDeclaration;
2004b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fullerimport org.eclipse.jdt.core.dom.CompilationUnit;
2104b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fullerimport org.eclipse.jdt.core.dom.FieldDeclaration;
2204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fullerimport org.eclipse.jdt.core.dom.VariableDeclarationFragment;
2304b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
2493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fullerimport java.util.ArrayList;
2504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fullerimport java.util.List;
2604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
2704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller/**
2804b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * Locates the {@link org.eclipse.jdt.core.dom.BodyDeclaration} associated with an field
2904b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller * declaration.
3004b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller */
31ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fullerpublic final class FieldLocator implements BodyDeclarationLocator {
3204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
33ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller  static final String LOCATOR_TYPE_NAME = "field";
3493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller
35ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller  private final TypeLocator typeLocator;
3604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
3704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  private final String fieldName;
3804b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
39ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller  public FieldLocator(String packageName, String typeName, String fieldName) {
40ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller    this(new TypeLocator(packageName, typeName), fieldName);
4104b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  }
4204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
43ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller  public FieldLocator(TypeLocator typeLocator, String fieldName) {
44ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller    this.typeLocator = typeLocator;
4504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    this.fieldName = fieldName;
4604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  }
4704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
48ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller  @Override public TypeLocator getTypeLocator() {
49ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller    return typeLocator;
5093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller  }
5193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller
5204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  @Override
5304b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  public boolean matches(BodyDeclaration node) {
5404b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    if (node instanceof FieldDeclaration) {
5504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller      FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
5604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller      for (VariableDeclarationFragment variableDeclarationFragment
5704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller          : (List<VariableDeclarationFragment>) fieldDeclaration.fragments()) {
5804b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        String nodeFieldName = variableDeclarationFragment.getName().getFullyQualifiedName();
5904b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        if (nodeFieldName.equals(fieldName)) {
6004b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller          BodyDeclaration parentNode = (BodyDeclaration) node.getParent();
61ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller          return typeLocator.matches(parentNode);
6204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        }
6304b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller      }
6404b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    }
6504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    return false;
6604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  }
6704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
6804b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  @Override
6904b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  public FieldDeclaration find(CompilationUnit cu) {
70ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller    AbstractTypeDeclaration typeDeclaration = typeLocator.find(cu);
7104b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    if (typeDeclaration == null) {
7204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller      return null;
7304b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    }
7404b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    for (BodyDeclaration bodyDeclaration
7504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        : (List<BodyDeclaration>) typeDeclaration.bodyDeclarations()) {
7604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller      if (bodyDeclaration instanceof FieldDeclaration) {
7704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        FieldDeclaration fieldDeclaration = (FieldDeclaration) bodyDeclaration;
7804b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        for (VariableDeclarationFragment variableDeclarationFragment
7904b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller            : (List<VariableDeclarationFragment>) fieldDeclaration.fragments()) {
8004b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller          String nodeFieldName = variableDeclarationFragment.getName().getFullyQualifiedName();
8104b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller          if (nodeFieldName.equals(fieldName)) {
8204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller            return fieldDeclaration;
8304b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller          }
8404b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        }
8504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller      }
8604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    }
8704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    return null;
8804b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  }
8904b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller
9093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller  @Override public String getStringFormType() {
91ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller    return LOCATOR_TYPE_NAME;
9293cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller  }
9393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller
9493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller  @Override public String getStringFormTarget() {
95ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller    return typeLocator.getStringFormTarget() + "#" + fieldName;
9693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller  }
9793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller
9893cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller  /**
9993cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller   * Returns the names of the fields declared in the supplied {@code fieldDeclarationNode}.
10093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller   */
10193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller  public static List<String> getFieldNames(FieldDeclaration fieldDeclarationNode) {
10293cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller    List<VariableDeclarationFragment> fieldDeclarations = fieldDeclarationNode.fragments();
10393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller    List<String> fieldNames = new ArrayList<>(fieldDeclarations.size());
10493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller    for (VariableDeclarationFragment fieldDeclaration : fieldDeclarations) {
10593cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller      fieldNames.add(fieldDeclaration.getName().getIdentifier());
10693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller    }
10793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller    return fieldNames;
10893cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller  }
10993cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller
11004b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  @Override
11104b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  public String toString() {
11204b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller    return "FieldLocator{" +
113ac1c676b1256aaa85c5cc22494ea56bd2d276b9fNeil Fuller        "typeLocator=" + typeLocator +
11404b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        ", fieldName='" + fieldName + '\'' +
11504b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller        '}';
11604b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller  }
11704b228542fa91e91551c6ea4e6a2bac1d55ca1afNeil Fuller}
118