Package com.google.dart.engine.internal.search

Source Code of com.google.dart.engine.internal.search.SearchEngineImpl$RelationshipCallbackImpl

/*
* Copyright (c) 2013, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.engine.internal.search;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Uninterruptibles;
import com.google.dart.engine.element.ClassElement;
import com.google.dart.engine.element.CompilationUnitElement;
import com.google.dart.engine.element.ConstructorElement;
import com.google.dart.engine.element.Element;
import com.google.dart.engine.element.FunctionElement;
import com.google.dart.engine.element.FunctionTypeAliasElement;
import com.google.dart.engine.element.ImportElement;
import com.google.dart.engine.element.LibraryElement;
import com.google.dart.engine.element.LocalVariableElement;
import com.google.dart.engine.element.MethodElement;
import com.google.dart.engine.element.ParameterElement;
import com.google.dart.engine.element.PropertyAccessorElement;
import com.google.dart.engine.element.PropertyInducingElement;
import com.google.dart.engine.element.TypeParameterElement;
import com.google.dart.engine.element.VariableElement;
import com.google.dart.engine.element.angular.AngularElement;
import com.google.dart.engine.index.Index;
import com.google.dart.engine.index.Location;
import com.google.dart.engine.index.LocationWithData;
import com.google.dart.engine.index.Relationship;
import com.google.dart.engine.index.RelationshipCallback;
import com.google.dart.engine.internal.element.member.Member;
import com.google.dart.engine.internal.index.IndexConstants;
import com.google.dart.engine.internal.index.NameElementImpl;
import com.google.dart.engine.internal.search.listener.CountingSearchListener;
import com.google.dart.engine.internal.search.listener.FilteredSearchListener;
import com.google.dart.engine.internal.search.listener.GatheringSearchListener;
import com.google.dart.engine.internal.search.listener.NameMatchingSearchListener;
import com.google.dart.engine.internal.search.scope.LibrarySearchScope;
import com.google.dart.engine.search.MatchKind;
import com.google.dart.engine.search.MatchQuality;
import com.google.dart.engine.search.SearchEngine;
import com.google.dart.engine.search.SearchFilter;
import com.google.dart.engine.search.SearchListener;
import com.google.dart.engine.search.SearchMatch;
import com.google.dart.engine.search.SearchPattern;
import com.google.dart.engine.search.SearchScope;
import com.google.dart.engine.type.Type;
import com.google.dart.engine.utilities.source.SourceRange;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

/**
* Implementation of {@link SearchEngine}.
*
* @coverage dart.engine.search
*/
public class SearchEngineImpl implements SearchEngine {

  /**
   * Instances of the class <code>RelationshipCallbackImpl</code> implement a callback that can be
   * used to report results to a search listener.
   */
  private static class RelationshipCallbackImpl implements RelationshipCallback {
    private final SearchScope scope;
    /**
     * The kind of matches that are represented by the results that will be provided to this
     * callback.
     */
    private MatchKind matchKind;

    /**
     * The search listener that should be notified when results are found.
     */
    private SearchListener listener;

    /**
     * Initialize a newly created callback to report matches of the given kind to the given listener
     * when results are found.
     *
     * @param scope the {@link SearchScope} to return matches from, may be {@code null} to return
     *          all matches
     * @param matchKind the kind of matches that are represented by the results
     * @param listener the search listener that should be notified when results are found
     */
    public RelationshipCallbackImpl(SearchScope scope, MatchKind matchKind, SearchListener listener) {
      this.scope = scope;
      this.matchKind = matchKind;
      this.listener = listener;
    }

    @Override
    public void hasRelationships(Element element, Relationship relationship, Location[] locations) {
      for (Location location : locations) {
        Element targetElement = location.getElement();
        // check scope
        if (scope != null && !scope.encloses(targetElement)) {
          continue;
        }
        SourceRange range = new SourceRange(location.getOffset(), location.getLength());
        // TODO(scheglov) IndexConstants.DYNAMIC for MatchQuality.NAME
        MatchQuality quality = MatchQuality.EXACT;
//          MatchQuality quality = element.getResource() != IndexConstants.DYNAMIC
//              ? MatchQuality.EXACT : MatchQuality.NAME;
        SearchMatch match = new SearchMatch(quality, matchKind, targetElement, range);
        match.setQualified(relationship == IndexConstants.IS_REFERENCED_BY_QUALIFIED
            || relationship == IndexConstants.IS_INVOKED_BY_QUALIFIED);
        listener.matchFound(match);
      }
      listener.searchComplete();
    }
  }

  /**
   * The interface <code>SearchRunner</code> defines the behavior of objects that can be used to
   * perform an asynchronous search.
   */
  private interface SearchRunner {
    /**
     * Perform an asynchronous search, passing the results to the given listener.
     *
     * @param listener the listener to which search results should be passed @ if the results could
     *          not be computed
     */
    public void performSearch(SearchListener listener);
  }

  /**
   * Apply the given filter to the given listener.
   *
   * @param filter the filter to be used before passing matches on to the listener, or {@code null}
   *          if all matches should be passed on
   * @param listener the listener that will only be given matches that pass the filter
   * @return a search listener that will pass to the given listener any matches that pass the given
   *         filter
   */
  private static SearchListener applyFilter(SearchFilter filter, SearchListener listener) {
    if (filter == null) {
      return listener;
    }
    return new FilteredSearchListener(filter, listener);
  }

  /**
   * Apply the given pattern to the given listener.
   *
   * @param pattern the pattern to be used before passing matches on to the listener, or
   *          {@code null} if all matches should be passed on
   * @param listener the listener that will only be given matches that match the pattern
   * @return a search listener that will pass to the given listener any matches that match the given
   *         pattern
   */
  private static SearchListener applyPattern(SearchPattern pattern, SearchListener listener) {
    if (pattern == null) {
      return listener;
    }
    return new NameMatchingSearchListener(pattern, listener);
  }

  private static Element[] createElements(SearchScope scope) {
    if (scope instanceof LibrarySearchScope) {
      return ((LibrarySearchScope) scope).getLibraries();
    }
    return new Element[] {IndexConstants.UNIVERSE};
  }

  private static RelationshipCallback newCallback(MatchKind matchKind, SearchScope scope,
      SearchListener listener) {
    return new RelationshipCallbackImpl(scope, matchKind, listener);
  }

  /**
   * The index used to respond to the search requests.
   */
  private Index index;

  /**
   * Initialize a newly created search engine to use the given index.
   *
   * @param index the index used to respond to the search requests
   */
  public SearchEngineImpl(Index index) {
    this.index = index;
  }

  @Override
  public Set<Type> searchAssignedTypes(PropertyInducingElement variable, SearchScope scope) {
    PropertyAccessorElement setter = variable.getSetter();
    int numRequests = (setter != null ? 2 : 0) + 2;
    // find locations
    final List<Location> locations = Lists.newArrayList();
    final CountDownLatch latch = new CountDownLatch(numRequests);
    class Callback implements RelationshipCallback {
      @Override
      public void hasRelationships(Element element, Relationship relationship, Location[] locs) {
        Collections.addAll(locations, locs);
        latch.countDown();
      }
    }
    if (setter != null) {
      index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, new Callback());
      index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, new Callback());
    }
    index.getRelationships(variable, IndexConstants.IS_REFERENCED_BY, new Callback());
    index.getRelationships(variable, IndexConstants.IS_DEFINED_BY, new Callback());
    Uninterruptibles.awaitUninterruptibly(latch);
    // get types from locations
    Set<Type> types = Sets.newHashSet();
    for (Location location : locations) {
      // check scope
      if (scope != null) {
        Element targetElement = location.getElement();
        if (!scope.encloses(targetElement)) {
          continue;
        }
      }
      // we need data
      if (!(location instanceof LocationWithData<?>)) {
        continue;
      }
      LocationWithData<?> locationWithData = (LocationWithData<?>) location;
      // add type
      Object data = locationWithData.getData();
      if (data instanceof Type) {
        Type type = (Type) data;
        types.add(type);
      }
    }
    // done
    return types;
  }

  @Override
  public List<SearchMatch> searchDeclarations(final String name, final SearchScope scope,
      final SearchFilter filter) {
    return gatherResults(new SearchRunner() {
      @Override
      public void performSearch(SearchListener listener) {
        searchDeclarations(name, scope, filter, listener);
      }
    });
  }

  @Override
  public void searchDeclarations(String name, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.IS_DEFINED_BY,
        newCallback(MatchKind.NAME_DECLARATION, scope, listener));
  }

  @Override
  public List<SearchMatch> searchFunctionDeclarations(final SearchScope scope,
      final SearchPattern pattern, final SearchFilter filter) {
    return gatherResults(new SearchRunner() {
      @Override
      public void performSearch(SearchListener listener) {
        searchFunctionDeclarations(scope, pattern, filter, listener);
      }
    });
  }

  @Override
  public void searchFunctionDeclarations(SearchScope scope, SearchPattern pattern,
      SearchFilter filter, SearchListener listener) {
    assert listener != null;
    Element[] elements = createElements(scope);
    listener = applyPattern(pattern, listener);
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(elements.length, listener);
    for (Element element : elements) {
      index.getRelationships(
          element,
          IndexConstants.DEFINES_FUNCTION,
          newCallback(MatchKind.FUNCTION_DECLARATION, scope, listener));
    }
  }

  @Override
  public List<SearchMatch> searchQualifiedMemberReferences(final String name,
      final SearchScope scope, final SearchFilter filter) {
    return gatherResults(new SearchRunner() {
      @Override
      public void performSearch(SearchListener listener) {
        searchQualifiedMemberReferences(name, scope, filter, listener);
      }
    });
  }

  @Override
  public void searchQualifiedMemberReferences(String name, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(10, listener);
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
        newCallback(MatchKind.NAME_REFERENCE_RESOLVED, scope, listener));
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
        newCallback(MatchKind.NAME_REFERENCE_UNRESOLVED, scope, listener));
    // granular resolved operations
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.NAME_IS_INVOKED_BY_RESOLVED,
        newCallback(MatchKind.NAME_INVOCATION_RESOLVED, scope, listener));
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.NAME_IS_READ_BY_RESOLVED,
        newCallback(MatchKind.NAME_READ_RESOLVED, scope, listener));
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED,
        newCallback(MatchKind.NAME_READ_WRITE_RESOLVED, scope, listener));
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED,
        newCallback(MatchKind.NAME_WRITE_RESOLVED, scope, listener));
    // granular unresolved operations
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED,
        newCallback(MatchKind.NAME_INVOCATION_UNRESOLVED, scope, listener));
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.NAME_IS_READ_BY_UNRESOLVED,
        newCallback(MatchKind.NAME_READ_UNRESOLVED, scope, listener));
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED,
        newCallback(MatchKind.NAME_READ_WRITE_UNRESOLVED, scope, listener));
    index.getRelationships(
        new NameElementImpl(name),
        IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED,
        newCallback(MatchKind.NAME_WRITE_UNRESOLVED, scope, listener));
  }

  @Override
  public List<SearchMatch> searchReferences(final Element element, final SearchScope scope,
      final SearchFilter filter) {
    return gatherResults(new SearchRunner() {
      @Override
      public void performSearch(SearchListener listener) {
        searchReferences(element, scope, filter, listener);
      }
    });
  }

  @Override
  public void searchReferences(Element element, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    if (element == null) {
      listener.searchComplete();
      return;
    }
    if (element instanceof Member) {
      element = ((Member) element).getBaseElement();
    }
    switch (element.getKind()) {
      case ANGULAR_COMPONENT:
      case ANGULAR_CONTROLLER:
      case ANGULAR_FORMATTER:
      case ANGULAR_PROPERTY:
      case ANGULAR_SCOPE_PROPERTY:
      case ANGULAR_SELECTOR:
        searchReferences((AngularElement) element, scope, filter, listener);
        return;
      case CLASS:
        searchReferences((ClassElement) element, scope, filter, listener);
        return;
      case COMPILATION_UNIT:
        searchReferences((CompilationUnitElement) element, scope, filter, listener);
        return;
      case CONSTRUCTOR:
        searchReferences((ConstructorElement) element, scope, filter, listener);
        return;
      case FIELD:
      case TOP_LEVEL_VARIABLE:
        searchReferences((PropertyInducingElement) element, scope, filter, listener);
        return;
      case FUNCTION:
        searchReferences((FunctionElement) element, scope, filter, listener);
        return;
      case GETTER:
      case SETTER:
        searchReferences((PropertyAccessorElement) element, scope, filter, listener);
        return;
      case IMPORT:
        searchReferences((ImportElement) element, scope, filter, listener);
        return;
      case LIBRARY:
        searchReferences((LibraryElement) element, scope, filter, listener);
        return;
      case LOCAL_VARIABLE:
        searchReferences((LocalVariableElement) element, scope, filter, listener);
        return;
      case METHOD:
        searchReferences((MethodElement) element, scope, filter, listener);
        return;
      case PARAMETER:
        searchReferences((ParameterElement) element, scope, filter, listener);
        return;
      case FUNCTION_TYPE_ALIAS:
        searchReferences((FunctionTypeAliasElement) element, scope, filter, listener);
        return;
      case TYPE_PARAMETER:
        searchReferences((TypeParameterElement) element, scope, filter, listener);
        return;
      default:
        listener.searchComplete();
        return;
    }
  }

  @Override
  public List<SearchMatch> searchSubtypes(final ClassElement type, final SearchScope scope,
      final SearchFilter filter) {
    return gatherResults(new SearchRunner() {
      @Override
      public void performSearch(SearchListener listener) {
        searchSubtypes(type, scope, filter, listener);
      }
    });
  }

  @Override
  public void searchSubtypes(ClassElement type, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(3, listener);
    index.getRelationships(
        type,
        IndexConstants.IS_EXTENDED_BY,
        newCallback(MatchKind.EXTENDS_REFERENCE, scope, listener));
    index.getRelationships(
        type,
        IndexConstants.IS_MIXED_IN_BY,
        newCallback(MatchKind.WITH_REFERENCE, scope, listener));
    index.getRelationships(
        type,
        IndexConstants.IS_IMPLEMENTED_BY,
        newCallback(MatchKind.IMPLEMENTS_REFERENCE, scope, listener));
  }

  @Override
  public List<SearchMatch> searchTypeDeclarations(final SearchScope scope,
      final SearchPattern pattern, final SearchFilter filter) {
    return gatherResults(new SearchRunner() {
      @Override
      public void performSearch(SearchListener listener) {
        searchTypeDeclarations(scope, pattern, filter, listener);
      }
    });
  }

  @Override
  public void searchTypeDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    Element[] elements = createElements(scope);
    listener = applyPattern(pattern, listener);
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(elements.length * 3, listener);
    for (Element element : elements) {
      index.getRelationships(
          element,
          IndexConstants.DEFINES_CLASS,
          newCallback(MatchKind.CLASS_DECLARATION, scope, listener));
      index.getRelationships(
          element,
          IndexConstants.DEFINES_CLASS_ALIAS,
          newCallback(MatchKind.CLASS_ALIAS_DECLARATION, scope, listener));
      index.getRelationships(
          element,
          IndexConstants.DEFINES_FUNCTION_TYPE,
          newCallback(MatchKind.FUNCTION_TYPE_DECLARATION, scope, listener));
    }
  }

  @Override
  public List<SearchMatch> searchVariableDeclarations(final SearchScope scope,
      final SearchPattern pattern, final SearchFilter filter) {
    return gatherResults(new SearchRunner() {
      @Override
      public void performSearch(SearchListener listener) {
        searchVariableDeclarations(scope, pattern, filter, listener);
      }
    });
  }

  @Override
  public void searchVariableDeclarations(SearchScope scope, SearchPattern pattern,
      SearchFilter filter, SearchListener listener) {
    assert listener != null;
    Element[] elements = createElements(scope);
    listener = applyPattern(pattern, listener);
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(elements.length, listener);
    for (Element element : elements) {
      index.getRelationships(
          element,
          IndexConstants.DEFINES_VARIABLE,
          newCallback(MatchKind.VARIABLE_DECLARATION, scope, listener));
    }
  }

  /**
   * Use the given runner to perform the given number of asynchronous searches, then wait until the
   * search has completed and return the results that were produced.
   *
   * @param runner the runner used to perform an asynchronous search
   * @return the results that were produced @ if the results of at least one of the searched could
   *         not be computed
   */
  private List<SearchMatch> gatherResults(SearchRunner runner) {
    GatheringSearchListener listener = new GatheringSearchListener();
    runner.performSearch(listener);
    while (!listener.isComplete()) {
      Thread.yield();
    }
    return listener.getMatches();
  }

  private void searchReferences(AngularElement element, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(2, listener);
    index.getRelationships(
        element,
        IndexConstants.ANGULAR_REFERENCE,
        newCallback(MatchKind.ANGULAR_REFERENCE, scope, listener));
    index.getRelationships(
        element,
        IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE,
        newCallback(MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, scope, listener));
  }

  private void searchReferences(ClassElement type, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    index.getRelationships(
        type,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.TYPE_REFERENCE, scope, listener));
  }

  private void searchReferences(CompilationUnitElement unit, SearchScope scope,
      SearchFilter filter, SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    index.getRelationships(
        unit,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.UNIT_REFERENCE, scope, listener));
  }

  private void searchReferences(ConstructorElement constructor, SearchScope scope,
      SearchFilter filter, SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(2, listener);
    index.getRelationships(
        constructor,
        IndexConstants.IS_DEFINED_BY,
        newCallback(MatchKind.CONSTRUCTOR_DECLARATION, scope, listener));
    index.getRelationships(
        constructor,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.CONSTRUCTOR_REFERENCE, scope, listener));
  }

  private void searchReferences(FunctionElement function, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(2, listener);
    index.getRelationships(
        function,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.FUNCTION_REFERENCE, scope, listener));
    index.getRelationships(
        function,
        IndexConstants.IS_INVOKED_BY,
        newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
  }

  private void searchReferences(FunctionTypeAliasElement alias, SearchScope scope,
      SearchFilter filter, SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    index.getRelationships(
        alias,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.FUNCTION_TYPE_REFERENCE, scope, listener));
  }

  private void searchReferences(ImportElement imp, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    index.getRelationships(
        imp,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.IMPORT_REFERENCE, scope, listener));
  }

  private void searchReferences(LibraryElement library, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    index.getRelationships(
        library,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.LIBRARY_REFERENCE, scope, listener));
  }

  private void searchReferences(MethodElement method, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    // TODO(scheglov) use "5" when add named matches
    listener = new CountingSearchListener(4, listener);
    // exact matches
    index.getRelationships(
        method,
        IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
        newCallback(MatchKind.METHOD_INVOCATION, scope, listener));
    index.getRelationships(
        method,
        IndexConstants.IS_INVOKED_BY_QUALIFIED,
        newCallback(MatchKind.METHOD_INVOCATION, scope, listener));
    index.getRelationships(
        method,
        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
        newCallback(MatchKind.METHOD_REFERENCE, scope, listener));
    index.getRelationships(
        method,
        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
        newCallback(MatchKind.METHOD_REFERENCE, scope, listener));
    // TODO(scheglov)
    // inexact matches
//    index.getRelationships(
//        new Element(IndexConstants.DYNAMIC, method.getElementName()),
//        IndexConstants.IS_INVOKED_BY_QUALIFIED,
//        newCallback(MatchKind.METHOD_INVOCATION, listener));
  }

  private void searchReferences(ParameterElement parameter, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(5, listener);
    index.getRelationships(
        parameter,
        IndexConstants.IS_READ_BY,
        newCallback(MatchKind.VARIABLE_READ, scope, listener));
    index.getRelationships(
        parameter,
        IndexConstants.IS_READ_WRITTEN_BY,
        newCallback(MatchKind.VARIABLE_READ_WRITE, scope, listener));
    index.getRelationships(
        parameter,
        IndexConstants.IS_WRITTEN_BY,
        newCallback(MatchKind.VARIABLE_WRITE, scope, listener));
    index.getRelationships(
        parameter,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.NAMED_PARAMETER_REFERENCE, scope, listener));
    index.getRelationships(
        parameter,
        IndexConstants.IS_INVOKED_BY,
        newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
  }

  private void searchReferences(PropertyAccessorElement accessor, SearchScope scope,
      SearchFilter filter, SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(2, listener);
    index.getRelationships(
        accessor,
        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
        newCallback(MatchKind.PROPERTY_ACCESSOR_REFERENCE, scope, listener));
    index.getRelationships(
        accessor,
        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
        newCallback(MatchKind.PROPERTY_ACCESSOR_REFERENCE, scope, listener));
  }

  private void searchReferences(PropertyInducingElement field, SearchScope scope,
      SearchFilter filter, SearchListener listener) {
    assert listener != null;
    PropertyAccessorElement getter = field.getGetter();
    PropertyAccessorElement setter = field.getSetter();
    int numRequests = (getter != null ? 4 : 0) + (setter != null ? 2 : 0) + 2;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(numRequests, listener);
    if (getter != null) {
      index.getRelationships(
          getter,
          IndexConstants.IS_REFERENCED_BY_QUALIFIED,
          newCallback(MatchKind.FIELD_READ, scope, listener));
      index.getRelationships(
          getter,
          IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
          newCallback(MatchKind.FIELD_READ, scope, listener));
      index.getRelationships(
          getter,
          IndexConstants.IS_INVOKED_BY_QUALIFIED,
          newCallback(MatchKind.FIELD_INVOCATION, scope, listener));
      index.getRelationships(
          getter,
          IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
          newCallback(MatchKind.FIELD_INVOCATION, scope, listener));
    }
    if (setter != null) {
      index.getRelationships(
          setter,
          IndexConstants.IS_REFERENCED_BY_QUALIFIED,
          newCallback(MatchKind.FIELD_WRITE, scope, listener));
      index.getRelationships(
          setter,
          IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
          newCallback(MatchKind.FIELD_WRITE, scope, listener));
    }
    index.getRelationships(
        field,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.FIELD_REFERENCE, scope, listener));
    index.getRelationships(
        field,
        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
        newCallback(MatchKind.FIELD_REFERENCE, scope, listener));
  }

  private void searchReferences(TypeParameterElement typeParameter, SearchScope scope,
      SearchFilter filter, SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    index.getRelationships(
        typeParameter,
        IndexConstants.IS_REFERENCED_BY,
        newCallback(MatchKind.TYPE_PARAMETER_REFERENCE, scope, listener));
  }

  private void searchReferences(VariableElement variable, SearchScope scope, SearchFilter filter,
      SearchListener listener) {
    assert listener != null;
    listener = applyFilter(filter, listener);
    listener = new CountingSearchListener(4, listener);
    index.getRelationships(
        variable,
        IndexConstants.IS_READ_BY,
        newCallback(MatchKind.VARIABLE_READ, scope, listener));
    index.getRelationships(
        variable,
        IndexConstants.IS_READ_WRITTEN_BY,
        newCallback(MatchKind.VARIABLE_READ_WRITE, scope, listener));
    index.getRelationships(
        variable,
        IndexConstants.IS_WRITTEN_BY,
        newCallback(MatchKind.VARIABLE_WRITE, scope, listener));
    index.getRelationships(
        variable,
        IndexConstants.IS_INVOKED_BY,
        newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
  }
}
TOP

Related Classes of com.google.dart.engine.internal.search.SearchEngineImpl$RelationshipCallbackImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.