| Index: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/builder/HtmlUnitBuilder.java
|
| diff --git a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/builder/HtmlUnitBuilder.java b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/builder/HtmlUnitBuilder.java
|
| index 4a3ad66d68664a3d883d0550b94d5e1c7bd82417..89fbdcf677af8e8c58a06aaa360955ddc6ba5b9d 100644
|
| --- a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/builder/HtmlUnitBuilder.java
|
| +++ b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/builder/HtmlUnitBuilder.java
|
| @@ -15,17 +15,18 @@ package com.google.dart.engine.internal.builder;
|
|
|
| import com.google.common.annotations.VisibleForTesting;
|
| import com.google.dart.engine.AnalysisEngine;
|
| -import com.google.dart.engine.ast.CompilationUnit;
|
| +import com.google.dart.engine.ast.Expression;
|
| import com.google.dart.engine.context.AnalysisException;
|
| import com.google.dart.engine.element.HtmlScriptElement;
|
| import com.google.dart.engine.error.AnalysisError;
|
| import com.google.dart.engine.error.ErrorCode;
|
| import com.google.dart.engine.error.HtmlWarningCode;
|
| +import com.google.dart.engine.html.ast.EmbeddedExpression;
|
| +import com.google.dart.engine.html.ast.HtmlScriptTagNode;
|
| 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.ast.visitor.XmlVisitor;
|
| -import com.google.dart.engine.html.scanner.Token;
|
| import com.google.dart.engine.html.scanner.TokenType;
|
| import com.google.dart.engine.internal.context.InternalAnalysisContext;
|
| import com.google.dart.engine.internal.context.RecordingErrorListener;
|
| @@ -35,13 +36,9 @@ import com.google.dart.engine.internal.element.HtmlElementImpl;
|
| import com.google.dart.engine.internal.element.LibraryElementImpl;
|
| import com.google.dart.engine.internal.resolver.Library;
|
| import com.google.dart.engine.internal.resolver.LibraryResolver;
|
| -import com.google.dart.engine.parser.Parser;
|
| -import com.google.dart.engine.scanner.Scanner;
|
| -import com.google.dart.engine.scanner.SubSequenceReader;
|
| import com.google.dart.engine.source.Source;
|
| import com.google.dart.engine.utilities.io.UriUtilities;
|
| import com.google.dart.engine.utilities.source.LineInfo;
|
| -import com.google.dart.engine.utilities.source.LineInfo.Location;
|
|
|
| import java.net.URI;
|
| import java.net.URISyntaxException;
|
| @@ -53,11 +50,7 @@ import java.util.Set;
|
| * Instances of the class {@code HtmlUnitBuilder} build an element model for a single HTML unit.
|
| */
|
| public class HtmlUnitBuilder implements XmlVisitor<Void> {
|
| - private static final String APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
|
| - private static final String APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
|
| - private static final String SCRIPT = "script";
|
| private static final String SRC = "src";
|
| - private static final String TYPE = "type";
|
|
|
| /**
|
| * The analysis context in which the element model will be built.
|
| @@ -163,6 +156,65 @@ public class HtmlUnitBuilder implements XmlVisitor<Void> {
|
| }
|
|
|
| @Override
|
| + public Void visitHtmlScriptTagNode(HtmlScriptTagNode node) {
|
| + if (parentNodes.contains(node)) {
|
| + return reportCircularity(node);
|
| + }
|
| + parentNodes.add(node);
|
| + try {
|
| + Source htmlSource = htmlElement.getSource();
|
| + XmlAttributeNode scriptAttribute = getScriptSourcePath(node);
|
| + String scriptSourcePath = scriptAttribute == null ? null : scriptAttribute.getText();
|
| + if (node.getAttributeEnd().getType() == TokenType.GT && scriptSourcePath == null) {
|
| + EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl(node);
|
| + try {
|
| + LibraryResolver resolver = new LibraryResolver(context);
|
| + LibraryElementImpl library = (LibraryElementImpl) resolver.resolveEmbeddedLibrary(
|
| + htmlSource,
|
| + modificationStamp,
|
| + node.getScript(),
|
| + true);
|
| + script.setScriptLibrary(library);
|
| + resolvedLibraries.addAll(resolver.getResolvedLibraries());
|
| + errorListener.addAll(resolver.getErrorListener());
|
| + } catch (AnalysisException exception) {
|
| + //TODO (danrubel): Handle or forward the exception
|
| + AnalysisEngine.getInstance().getLogger().logError(exception);
|
| + }
|
| + node.setScriptElement(script);
|
| + scripts.add(script);
|
| + } else {
|
| + ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl(node);
|
| + if (scriptSourcePath != null) {
|
| + try {
|
| + scriptSourcePath = UriUtilities.encode(scriptSourcePath);
|
| + // Force an exception to be thrown if the URI is invalid so that we can report the
|
| + // problem.
|
| + new URI(scriptSourcePath);
|
| + Source scriptSource = context.getSourceFactory().resolveUri(
|
| + htmlSource,
|
| + scriptSourcePath);
|
| + script.setScriptSource(scriptSource);
|
| + if (scriptSource == null || !scriptSource.exists()) {
|
| + reportValueError(
|
| + HtmlWarningCode.URI_DOES_NOT_EXIST,
|
| + scriptAttribute,
|
| + scriptSourcePath);
|
| + }
|
| + } catch (URISyntaxException exception) {
|
| + reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, scriptSourcePath);
|
| + }
|
| + }
|
| + node.setScriptElement(script);
|
| + scripts.add(script);
|
| + }
|
| + } finally {
|
| + parentNodes.remove(node);
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + @Override
|
| public Void visitHtmlUnit(HtmlUnit node) {
|
| parentNodes = new ArrayList<XmlTagNode>();
|
| scripts = new ArrayList<HtmlScriptElement>();
|
| @@ -178,108 +230,23 @@ public class HtmlUnitBuilder implements XmlVisitor<Void> {
|
|
|
| @Override
|
| public Void visitXmlAttributeNode(XmlAttributeNode node) {
|
| + for (EmbeddedExpression expression : node.getExpressions()) {
|
| + resolveExpression(expression.getExpression());
|
| + }
|
| return null;
|
| }
|
|
|
| @Override
|
| public Void visitXmlTagNode(XmlTagNode node) {
|
| if (parentNodes.contains(node)) {
|
| - //
|
| - // This should not be possible, but we have an error report that suggests that it happened at
|
| - // least once. This code will guard against infinite recursion and might help us identify the
|
| - // cause of the issue.
|
| - //
|
| - StringBuilder builder = new StringBuilder();
|
| - builder.append("Found circularity in XML nodes: ");
|
| - boolean first = true;
|
| - for (XmlTagNode pathNode : parentNodes) {
|
| - if (first) {
|
| - first = false;
|
| - } else {
|
| - builder.append(", ");
|
| - }
|
| - String tagName = pathNode.getTag().getLexeme();
|
| - if (pathNode == node) {
|
| - builder.append("*");
|
| - builder.append(tagName);
|
| - builder.append("*");
|
| - } else {
|
| - builder.append(tagName);
|
| - }
|
| - }
|
| - AnalysisEngine.getInstance().getLogger().logError(builder.toString());
|
| - return null;
|
| + return reportCircularity(node);
|
| }
|
| parentNodes.add(node);
|
| try {
|
| - if (isScriptNode(node)) {
|
| - Source htmlSource = htmlElement.getSource();
|
| - XmlAttributeNode scriptAttribute = getScriptSourcePath(node);
|
| - String scriptSourcePath = scriptAttribute == null ? null : scriptAttribute.getText();
|
| - if (node.getAttributeEnd().getType() == TokenType.GT && scriptSourcePath == null) {
|
| - EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl(node);
|
| - String contents = node.getContent();
|
| -
|
| - //TODO (danrubel): Move scanning embedded scripts into AnalysisContextImpl
|
| - // so that clients such as builder can scan, parse, and get errors without resolving
|
| - int attributeEnd = node.getAttributeEnd().getEnd();
|
| - Location location = lineInfo.getLocation(attributeEnd);
|
| - Scanner scanner = new Scanner(
|
| - htmlSource,
|
| - new SubSequenceReader(contents, attributeEnd),
|
| - errorListener);
|
| - scanner.setSourceStart(location.getLineNumber(), location.getColumnNumber());
|
| - com.google.dart.engine.scanner.Token firstToken = scanner.tokenize();
|
| - int[] lineStarts = scanner.getLineStarts();
|
| -
|
| - //TODO (danrubel): Move parsing embedded scripts into AnalysisContextImpl
|
| - // so that clients such as builder can scan, parse, and get errors without resolving
|
| - Parser parser = new Parser(htmlSource, errorListener);
|
| - CompilationUnit unit = parser.parseCompilationUnit(firstToken);
|
| -// unit.setLineInfo(new LineInfo(lineStarts));
|
| -
|
| - try {
|
| - LibraryResolver resolver = new LibraryResolver(context);
|
| - LibraryElementImpl library = (LibraryElementImpl) resolver.resolveEmbeddedLibrary(
|
| - htmlSource,
|
| - modificationStamp,
|
| - unit,
|
| - true);
|
| - script.setScriptLibrary(library);
|
| - resolvedLibraries.addAll(resolver.getResolvedLibraries());
|
| - errorListener.addAll(resolver.getErrorListener());
|
| - } catch (AnalysisException exception) {
|
| - //TODO (danrubel): Handle or forward the exception
|
| - AnalysisEngine.getInstance().getLogger().logError(exception);
|
| - }
|
| - scripts.add(script);
|
| - } else {
|
| - ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl(node);
|
| - if (scriptSourcePath != null) {
|
| - try {
|
| - scriptSourcePath = UriUtilities.encode(scriptSourcePath);
|
| - // Force an exception to be thrown if the URI is invalid so that we can report the
|
| - // problem.
|
| - new URI(scriptSourcePath);
|
| - Source scriptSource = context.getSourceFactory().resolveUri(
|
| - htmlSource,
|
| - scriptSourcePath);
|
| - script.setScriptSource(scriptSource);
|
| - if (scriptSource == null || !scriptSource.exists()) {
|
| - reportValueError(
|
| - HtmlWarningCode.URI_DOES_NOT_EXIST,
|
| - scriptAttribute,
|
| - scriptSourcePath);
|
| - }
|
| - } catch (URISyntaxException exception) {
|
| - reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, scriptSourcePath);
|
| - }
|
| - }
|
| - scripts.add(script);
|
| - }
|
| - } else {
|
| - node.visitChildren(this);
|
| + for (EmbeddedExpression expression : node.getExpressions()) {
|
| + resolveExpression(expression.getExpression());
|
| }
|
| + node.visitChildren(this);
|
| } finally {
|
| parentNodes.remove(node);
|
| }
|
| @@ -301,29 +268,32 @@ public class HtmlUnitBuilder implements XmlVisitor<Void> {
|
| return null;
|
| }
|
|
|
| - /**
|
| - * Determine if the specified node is a Dart script.
|
| - *
|
| - * @param node the node to be tested (not {@code null})
|
| - * @return {@code true} if the node is a Dart script
|
| - */
|
| - private boolean isScriptNode(XmlTagNode node) {
|
| - if (node.getTagNodes().size() != 0 || !node.getTag().getLexeme().equals(SCRIPT)) {
|
| - return false;
|
| - }
|
| - for (XmlAttributeNode attribute : node.getAttributes()) {
|
| - if (attribute.getName().getLexeme().equals(TYPE)) {
|
| - Token valueToken = attribute.getValue();
|
| - if (valueToken != null) {
|
| - String value = valueToken.getLexeme();
|
| - if (value.equals(APPLICATION_DART_IN_DOUBLE_QUOTES)
|
| - || value.equals(APPLICATION_DART_IN_SINGLE_QUOTES)) {
|
| - return true;
|
| - }
|
| - }
|
| + private Void reportCircularity(XmlTagNode node) {
|
| + //
|
| + // This should not be possible, but we have an error report that suggests that it happened at
|
| + // least once. This code will guard against infinite recursion and might help us identify the
|
| + // cause of the issue.
|
| + //
|
| + StringBuilder builder = new StringBuilder();
|
| + builder.append("Found circularity in XML nodes: ");
|
| + boolean first = true;
|
| + for (XmlTagNode pathNode : parentNodes) {
|
| + if (first) {
|
| + first = false;
|
| + } else {
|
| + builder.append(", ");
|
| + }
|
| + String tagName = pathNode.getTag().getLexeme();
|
| + if (pathNode == node) {
|
| + builder.append("*");
|
| + builder.append(tagName);
|
| + builder.append("*");
|
| + } else {
|
| + builder.append(tagName);
|
| }
|
| }
|
| - return false;
|
| + AnalysisEngine.getInstance().getLogger().logError(builder.toString());
|
| + return null;
|
| }
|
|
|
| /**
|
| @@ -359,4 +329,9 @@ public class HtmlUnitBuilder implements XmlVisitor<Void> {
|
| int length = attribute.getValue().getLength() - 2;
|
| reportError(errorCode, offset, length, arguments);
|
| }
|
| +
|
| + private void resolveExpression(Expression expression) {
|
| + // TODO(brianwilkerson) Implement this. We need to figure out the right context in which to
|
| + // resolve the expression.
|
| + }
|
| }
|
|
|