/* * Copyright (c) 2014, 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.index.file; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.dart.engine.context.AnalysisContext; import com.google.dart.engine.element.Element; import com.google.dart.engine.index.Location; import com.google.dart.engine.index.Relationship; import java.util.List; import java.util.Map; /** * A single index file in-memory presentation. * * @coverage dart.engine.index */ public class IndexNode { private final AnalysisContext context; private final ElementCodec elementCodec; private final RelationshipCodec relationshipCodec; private final Map<RelationKeyData, List<LocationData>> relations = Maps.newHashMap(); public IndexNode(AnalysisContext context, ElementCodec elementCodec, RelationshipCodec relationshipCodec) { this.context = context; this.elementCodec = elementCodec; this.relationshipCodec = relationshipCodec; } /** * Returns the {@link AnalysisContext} this node is created for. */ public AnalysisContext getContext() { return context; } /** * Returns number of locations in this node. */ public int getLocationCount() { int locationCount = 0; for (List<LocationData> locations : relations.values()) { locationCount += locations.size(); } return locationCount; } /** * Returns the recorded relations. */ public Map<RelationKeyData, List<LocationData>> getRelations() { return relations; } /** * Return the locations of the elements that have the given relationship with the given element. * * @param element the the element that has the relationship with the locations to be returned * @param relationship the {@link Relationship} between the given element and the locations to be * returned */ public Location[] getRelationships(Element element, Relationship relationship) { // prepare key RelationKeyData key = new RelationKeyData( elementCodec, relationshipCodec, element, relationship); // find LocationData(s) List<LocationData> locationDatas = relations.get(key); if (locationDatas == null) { return Location.EMPTY_ARRAY; } // convert to Location(s) List<Location> locations = Lists.newArrayList(); for (LocationData locationData : locationDatas) { Location location = locationData.getLocation(context, elementCodec); if (location != null) { locations.add(location); } } return locations.toArray(new Location[locations.size()]); } /** * Records that the given element and location have the given relationship. * * @param element the element that is related to the location * @param relationship the {@link Relationship} between the element and the location * @param location the {@link Location} where relationship happens */ public void recordRelationship(Element element, Relationship relationship, Location location) { RelationKeyData key = new RelationKeyData( elementCodec, relationshipCodec, element, relationship); // prepare LocationData(s) List<LocationData> locationDatas = relations.get(key); if (locationDatas == null) { locationDatas = Lists.newArrayList(); relations.put(key, locationDatas); } // add new LocationData locationDatas.add(new LocationData(elementCodec, location)); } /** * Sets relations data. This method is used during loading data from a storage. */ public void setRelations(Map<RelationKeyData, List<LocationData>> relations) { this.relations.clear(); this.relations.putAll(relations); } }