Package com.google.dart.engine.internal.task

Source Code of com.google.dart.engine.internal.task.ParseHtmlTask

/*
* 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.task;

import com.google.dart.engine.ast.CompilationUnit;
import com.google.dart.engine.ast.Directive;
import com.google.dart.engine.ast.UriBasedDirective;
import com.google.dart.engine.context.AnalysisContext;
import com.google.dart.engine.context.AnalysisException;
import com.google.dart.engine.error.AnalysisError;
import com.google.dart.engine.error.AnalysisErrorListener;
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.visitor.RecursiveXmlVisitor;
import com.google.dart.engine.html.parser.HtmlParser;
import com.google.dart.engine.html.scanner.AbstractScanner;
import com.google.dart.engine.html.scanner.StringScanner;
import com.google.dart.engine.html.scanner.Token;
import com.google.dart.engine.internal.context.InternalAnalysisContext;
import com.google.dart.engine.internal.context.RecordingErrorListener;
import com.google.dart.engine.source.Source;
import com.google.dart.engine.utilities.source.LineInfo;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;

/**
* Instances of the class {@code ParseHtmlTask} parse a specific source as an HTML file.
*/
public class ParseHtmlTask extends AnalysisTask {
  /**
   * The source to be parsed.
   */
  private Source source;

  /**
   * The time at which the contents of the source were last modified.
   */
  private long modificationTime;

  /**
   * The contents of the source.
   */
  private CharSequence content;

  /**
   * The line information that was produced.
   */
  private LineInfo lineInfo;

  /**
   * The HTML unit that was produced by parsing the source.
   */
  private HtmlUnit unit;

  /**
   * The errors that were produced by scanning and parsing the source.
   */
  private AnalysisError[] errors = AnalysisError.NO_ERRORS;

  /**
   * An array containing the sources of the libraries that are referenced within the HTML.
   */
  private Source[] referencedLibraries = Source.EMPTY_ARRAY;

  /**
   * The name of the 'src' attribute in a HTML tag.
   */
  private static final String ATTRIBUTE_SRC = "src";

  /**
   * The name of the 'script' tag in an HTML file.
   */
  private static final String TAG_SCRIPT = "script";

  /**
   * Initialize a newly created task to perform analysis within the given context.
   *
   * @param context the context in which the task is to be performed
   * @param source the source to be parsed
   * @param modificationTime the time at which the contents of the source were last modified
   * @param content the contents of the source
   */
  public ParseHtmlTask(InternalAnalysisContext context, Source source, long modificationTime,
      CharSequence content) {
    super(context);
    this.source = source;
    this.modificationTime = modificationTime;
    this.content = content;
  }

  @Override
  public <E> E accept(AnalysisTaskVisitor<E> visitor) throws AnalysisException {
    return visitor.visitParseHtmlTask(this);
  }

  /**
   * Return the errors that were produced by scanning and parsing the source, or {@code null} if the
   * task has not yet been performed or if an exception occurred.
   *
   * @return the errors that were produced by scanning and parsing the source
   */
  public AnalysisError[] getErrors() {
    return errors;
  }

  /**
   * Return the HTML unit that was produced by parsing the source.
   *
   * @return the HTML unit that was produced by parsing the source
   */
  public HtmlUnit getHtmlUnit() {
    return unit;
  }

  /**
   * Return the line information that was produced, or {@code null} if the task has not yet been
   * performed or if an exception occurred.
   *
   * @return the line information that was produced
   */
  public LineInfo getLineInfo() {
    return lineInfo;
  }

  /**
   * Return the time at which the contents of the source that was parsed were last modified, or a
   * negative value if the task has not yet been performed or if an exception occurred.
   *
   * @return the time at which the contents of the source that was parsed were last modified
   */
  public long getModificationTime() {
    return modificationTime;
  }

  /**
   * Return an array containing the sources of the libraries that are referenced within the HTML.
   *
   * @return the sources of the libraries that are referenced within the HTML
   */
  public Source[] getReferencedLibraries() {
    return referencedLibraries;
  }

  /**
   * Return the source that was or is to be parsed.
   *
   * @return the source was or is to be parsed
   */
  public Source getSource() {
    return source;
  }

  @Override
  protected String getTaskDescription() {
    if (source == null) {
      return "parse as html null source";
    }
    return "parse as html " + source.getFullName();
  }

  @Override
  protected void internalPerform() throws AnalysisException {
    try {
      AbstractScanner scanner = new StringScanner(source, content);
      scanner.setPassThroughElements(new String[] {TAG_SCRIPT});
      Token token = scanner.tokenize();
      lineInfo = new LineInfo(scanner.getLineStarts());
      final RecordingErrorListener errorListener = new RecordingErrorListener();
      unit = new HtmlParser(source, errorListener).parse(token, lineInfo);
      unit.accept(new RecursiveXmlVisitor<Void>() {
        @Override
        public Void visitHtmlScriptTagNode(HtmlScriptTagNode node) {
          resolveScriptDirectives(node.getScript(), errorListener);
          return null;
        }
      });
      errors = errorListener.getErrorsForSource(source);
      referencedLibraries = getLibrarySources();
    } catch (Exception exception) {
      throw new AnalysisException("Exception", exception);
    }
  }

  /**
   * Return the sources of libraries that are referenced in the specified HTML file.
   *
   * @return the sources of libraries that are referenced in the HTML file
   */
  private Source[] getLibrarySources() {
    final ArrayList<Source> libraries = new ArrayList<Source>();
    unit.accept(new RecursiveXmlVisitor<Void>() {
      @Override
      public Void visitHtmlScriptTagNode(HtmlScriptTagNode node) {
        XmlAttributeNode scriptAttribute = null;
        for (XmlAttributeNode attribute : node.getAttributes()) {
          if (attribute.getName().equalsIgnoreCase(ATTRIBUTE_SRC)) {
            scriptAttribute = attribute;
          }
        }
        if (scriptAttribute != null) {
          try {
            URI uri = new URI(null, null, scriptAttribute.getText(), null);
            String fileName = uri.getPath();
            Source librarySource = getContext().getSourceFactory().resolveUri(source, fileName);
            if (getContext().exists(librarySource)) {
              libraries.add(librarySource);
            }
          } catch (URISyntaxException e) {
            // ignored - invalid URI reported during resolution phase
          }
        }
        return super.visitHtmlScriptTagNode(node);
      }
    });
    if (libraries.isEmpty()) {
      return Source.EMPTY_ARRAY;
    }
    return libraries.toArray(new Source[libraries.size()]);
  }

  /**
   * Resolves directives in the given {@link CompilationUnit}.
   */
  private void resolveScriptDirectives(CompilationUnit script, AnalysisErrorListener errorListener) {
    if (script == null) {
      return;
    }
    AnalysisContext analysisContext = getContext();
    for (Directive directive : script.getDirectives()) {
      if (directive instanceof UriBasedDirective) {
        ParseDartTask.resolveDirective(
            analysisContext,
            source,
            (UriBasedDirective) directive,
            errorListener);
      }
    }
  }
}
TOP

Related Classes of com.google.dart.engine.internal.task.ParseHtmlTask

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.