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

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

/*
* 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.context.AnalysisException;
import com.google.dart.engine.element.CompilationUnitElement;
import com.google.dart.engine.element.LibraryElement;
import com.google.dart.engine.error.AnalysisErrorListener;
import com.google.dart.engine.error.BooleanErrorListener;
import com.google.dart.engine.internal.context.IncrementalAnalysisCache;
import com.google.dart.engine.internal.context.InternalAnalysisContext;
import com.google.dart.engine.internal.resolver.IncrementalResolver;
import com.google.dart.engine.internal.resolver.TypeProvider;
import com.google.dart.engine.parser.IncrementalParser;
import com.google.dart.engine.scanner.CharSequenceReader;
import com.google.dart.engine.scanner.CharacterReader;
import com.google.dart.engine.scanner.IncrementalScanner;
import com.google.dart.engine.source.Source;

/**
* Instances of the class {@code IncrementalAnalysisTask} incrementally update existing analysis.
*/
public class IncrementalAnalysisTask extends AnalysisTask {

  /**
   * The information used to perform incremental analysis.
   */
  private final IncrementalAnalysisCache cache;

  /**
   * The compilation unit that was produced by incrementally updating the existing unit.
   */
  private CompilationUnit updatedUnit;

  /**
   * 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 cache the incremental analysis cache used to perform the analysis
   */
  public IncrementalAnalysisTask(InternalAnalysisContext context, IncrementalAnalysisCache cache) {
    super(context);
    this.cache = cache;
  }

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

  /**
   * Return the incremental cache used for analysis
   *
   * @return the cache
   */
  public IncrementalAnalysisCache getCache() {
    return cache;
  }

  /**
   * Return the compilation unit that was produced by incrementally updating the existing
   * compilation unit, or {@code null} if the task has not yet been performed, could not be
   * performed, or if an exception occurred.
   *
   * @return the compilation unit
   */
  public CompilationUnit getCompilationUnit() {
    return updatedUnit;
  }

  /**
   * Return the source that is to be incrementally analyzed.
   *
   * @return the source
   */
  public Source getSource() {
    return cache != null ? cache.getSource() : null;
  }

  @Override
  protected String getTaskDescription() {
    return "incremental analysis " + (cache != null ? cache.getSource() : "null");
  }

  @Override
  protected void internalPerform() throws AnalysisException {
    if (cache == null) {
      return;
    }

    // Only handle small changes
    if (cache.getOldLength() > 0 || cache.getNewLength() > 30) {
      return;
    }

    // Produce an updated token stream
    CharacterReader reader = new CharSequenceReader(cache.getNewContents());
    BooleanErrorListener errorListener = new BooleanErrorListener();
    IncrementalScanner scanner = new IncrementalScanner(cache.getSource(), reader, errorListener);
    scanner.rescan(
        cache.getResolvedUnit().getBeginToken(),
        cache.getOffset(),
        cache.getOldLength(),
        cache.getNewLength());
    if (errorListener.getErrorReported()) {
      return;
    }

    // Produce an updated AST
    IncrementalParser parser = new IncrementalParser(
        cache.getSource(),
        scanner.getTokenMap(),
        AnalysisErrorListener.NULL_LISTENER);
    updatedUnit = parser.reparse(
        cache.getResolvedUnit(),
        scanner.getLeftToken(),
        scanner.getRightToken(),
        cache.getOffset(),
        cache.getOffset() + cache.getOldLength());

    // Update the resolution
    TypeProvider typeProvider = getTypeProvider();
    if (updatedUnit != null && typeProvider != null) {
      CompilationUnitElement element = updatedUnit.getElement();
      if (element != null) {
        LibraryElement library = element.getLibrary();
        if (library != null) {
          IncrementalResolver resolver = new IncrementalResolver(
              library,
              cache.getSource(),
              typeProvider,
              errorListener);
          resolver.resolve(parser.getUpdatedNode());
        }
      }
    }
  }

  /**
   * Return the type provider used for incremental resolution.
   *
   * @return the type provider (or {@code null} if an exception occurs)
   */
  private TypeProvider getTypeProvider() {
    try {
      return getContext().getTypeProvider();
    } catch (AnalysisException exception) {
      return null;
    }
  }
}
TOP

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

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.