/*
* 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.html.angular;
import com.google.dart.engine.ast.Expression;
import com.google.dart.engine.ast.SimpleIdentifier;
import com.google.dart.engine.element.CompilationUnitElement;
import com.google.dart.engine.element.Element;
import com.google.dart.engine.element.HtmlElement;
import com.google.dart.engine.element.angular.AngularElement;
import com.google.dart.engine.html.ast.HtmlUnit;
import com.google.dart.engine.html.ast.XmlAttributeNode;
import com.google.dart.engine.html.ast.XmlTagNode;
import com.google.dart.engine.html.scanner.Token;
import com.google.dart.engine.index.IndexStore;
import com.google.dart.engine.index.Location;
import com.google.dart.engine.index.Relationship;
import com.google.dart.engine.internal.index.IndexConstants;
import com.google.dart.engine.internal.index.IndexContributor;
/**
* Visits resolved {@link HtmlUnit} and adds relationships into {@link IndexStore}.
*
* @coverage dart.engine.index
*/
public class AngularHtmlIndexContributor extends ExpressionVisitor {
/**
* The {@link IndexStore} to record relations into.
*/
private final IndexStore store;
/**
* The index contributor used to index Dart {@link Expression}s.
*/
private final IndexContributor indexContributor;
private HtmlElement htmlUnitElement;
/**
* Initialize a newly created Angular HTML index contributor.
*
* @param store the {@link IndexStore} to record relations into.
*/
public AngularHtmlIndexContributor(IndexStore store) {
this.store = store;
indexContributor = new IndexContributor(store) {
@Override
public Element peekElement() {
return htmlUnitElement;
}
@Override
protected void recordRelationship(Element element, Relationship relationship,
Location location) {
AngularElement angularElement = AngularHtmlUnitResolver.getAngularElement(element);
if (angularElement != null) {
element = angularElement;
relationship = IndexConstants.ANGULAR_REFERENCE;
}
super.recordRelationship(element, relationship, location);
}
};
}
@Override
public void visitExpression(Expression expression) {
// Formatter
if (expression instanceof SimpleIdentifier) {
SimpleIdentifier identifier = (SimpleIdentifier) expression;
Element element = identifier.getBestElement();
if (element instanceof AngularElement) {
store.recordRelationship(
element,
IndexConstants.ANGULAR_REFERENCE,
createLocationForIdentifier(identifier));
return;
}
}
// index as a normal Dart expression
expression.accept(indexContributor);
}
@Override
public Void visitHtmlUnit(HtmlUnit node) {
htmlUnitElement = node.getElement();
CompilationUnitElement dartUnitElement = htmlUnitElement.getAngularCompilationUnit();
indexContributor.enterScope(dartUnitElement);
return super.visitHtmlUnit(node);
}
@Override
public Void visitXmlAttributeNode(XmlAttributeNode node) {
Element element = node.getElement();
if (element != null) {
Token nameToken = node.getNameToken();
Location location = createLocationForToken(nameToken);
store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, location);
}
return super.visitXmlAttributeNode(node);
}
@Override
public Void visitXmlTagNode(XmlTagNode node) {
Element element = node.getElement();
if (element != null) {
// tag
{
Token tagToken = node.getTagToken();
Location location = createLocationForToken(tagToken);
store.recordRelationship(element, IndexConstants.ANGULAR_REFERENCE, location);
}
// maybe add closing tag range
Token closingTag = node.getClosingTag();
if (closingTag != null) {
Location location = createLocationForToken(closingTag);
store.recordRelationship(element, IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, location);
}
}
return super.visitXmlTagNode(node);
}
private Location createLocationForIdentifier(SimpleIdentifier identifier) {
return new Location(htmlUnitElement, identifier.getOffset(), identifier.getLength());
}
private Location createLocationForToken(Token token) {
return new Location(htmlUnitElement, token.getOffset(), token.getLength());
}
}