Package com.google.dart.engine.internal.context

Source Code of com.google.dart.engine.internal.context.IncrementalAnalysisCache

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

import com.google.dart.engine.ast.CompilationUnit;
import com.google.dart.engine.internal.cache.DartEntry;
import com.google.dart.engine.internal.cache.DartEntryImpl;
import com.google.dart.engine.internal.cache.SourceEntry;
import com.google.dart.engine.source.Source;
import com.google.dart.engine.utilities.ast.AstComparator;

/**
* Instances of the class {@code IncrementalAnalysisCache} hold information used to perform
* incremental analysis.
*
* @see AnalysisContextImpl#setChangedContents(Source, String, int, int, int)
*/
public class IncrementalAnalysisCache {

  /**
   * Determine if the incremental analysis result can be cached for the next incremental analysis.
   *
   * @param cache the prior incremental analysis cache
   * @param unit the incrementally updated compilation unit
   * @return the cache used for incremental analysis or {@code null} if incremental analysis results
   *         cannot be cached for the next incremental analysis
   */
  public static IncrementalAnalysisCache cacheResult(IncrementalAnalysisCache cache,
      CompilationUnit unit) {
    if (cache != null && unit != null) {
      return new IncrementalAnalysisCache(
          cache.librarySource,
          cache.source,
          unit,
          cache.newContents,
          cache.newContents,
          0,
          0,
          0);
    }
    return null;
  }

  /**
   * Determine if the cache should be cleared.
   *
   * @param cache the prior cache or {@code null} if none
   * @param source the source being updated (not {@code null})
   * @return the cache used for incremental analysis or {@code null} if incremental analysis cannot
   *         be performed
   */
  public static IncrementalAnalysisCache clear(IncrementalAnalysisCache cache, Source source) {
    if (cache == null || cache.getSource().equals(source)) {
      return null;
    }
    return cache;
  }

  /**
   * Determine if incremental analysis can be performed from the given information.
   *
   * @param cache the prior cache or {@code null} if none
   * @param source the source being updated (not {@code null})
   * @param oldContents the original source contents prior to this update (may be {@code null})
   * @param newContents the new contents after this incremental change (not {@code null})
   * @param offset the offset at which the change occurred
   * @param oldLength the length of the text being replaced
   * @param newLength the length of the replacement text
   * @param sourceEntry the cached entry for the given source or {@code null} if none
   * @return the cache used for incremental analysis or {@code null} if incremental analysis cannot
   *         be performed
   */
  public static IncrementalAnalysisCache update(IncrementalAnalysisCache cache, Source source,
      String oldContents, String newContents, int offset, int oldLength, int newLength,
      SourceEntry sourceEntry) {

    // Determine the cache resolved unit
    Source librarySource = null;
    CompilationUnit unit = null;
    if (sourceEntry instanceof DartEntryImpl) {
      DartEntryImpl dartEntry = (DartEntryImpl) sourceEntry;
      Source[] librarySources = dartEntry.getLibrariesContaining();
      if (librarySources.length == 1) {
        librarySource = librarySources[0];
        if (librarySource != null) {
          unit = dartEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
        }
      }
    }

    // Create a new cache if there is not an existing cache or the source is different
    // or a new resolved compilation unit is available
    if (cache == null || !cache.getSource().equals(source) || unit != null) {
      if (unit == null) {
        return null;
      }
      if (oldContents == null) {
        if (oldLength != 0) {
          return null;
        }
        oldContents = newContents.substring(0, offset) + newContents.substring(offset + newLength);
      }
      return new IncrementalAnalysisCache(
          librarySource,
          source,
          unit,
          oldContents,
          newContents,
          offset,
          oldLength,
          newLength);
    }

    // Update the existing cache if the change is contiguous
    if (cache.oldLength == 0 && cache.newLength == 0) {
      cache.offset = offset;
      cache.oldLength = oldLength;
      cache.newLength = newLength;
    } else {
      if (cache.offset > offset || offset > cache.offset + cache.newLength) {
        return null;
      }
      cache.newLength += newLength - oldLength;
    }
    cache.newContents = newContents;
    return cache;
  }

  /**
   * Verify that the incrementally parsed and resolved unit in the incremental cache is structurally
   * equivalent to the fully parsed unit.
   *
   * @param cache the prior cache or {@code null} if none
   * @param source the source of the compilation unit that was parsed (not {@code null})
   * @param unit the compilation unit that was just parsed
   * @return the cache used for incremental analysis or {@code null} if incremental analysis results
   *         cannot be cached for the next incremental analysis
   */
  public static IncrementalAnalysisCache verifyStructure(IncrementalAnalysisCache cache,
      Source source, CompilationUnit unit) {
    if (cache != null && unit != null && cache.source.equals(source)) {
      if (!AstComparator.equalNodes(cache.resolvedUnit, unit)) {
        return null;
      }
    }
    return cache;
  }

  private final Source librarySource;
  private final Source source;
  private final String oldContents;
  private final CompilationUnit resolvedUnit;

  private String newContents;
  private int offset;
  private int oldLength;
  private int newLength;

  public IncrementalAnalysisCache(Source librarySource, Source source,
      CompilationUnit resolvedUnit, String oldContents, String newContents, int offset,
      int oldLength, int newLength) {
    this.librarySource = librarySource;
    this.source = source;
    this.resolvedUnit = resolvedUnit;
    this.oldContents = oldContents;
    this.newContents = newContents;
    this.offset = offset;
    this.oldLength = oldLength;
    this.newLength = newLength;
  }

  /**
   * Answer the library source for the incremental analysis to be performed
   *
   * @return the source (not {@code null})
   */
  public Source getLibrarySource() {
    return librarySource;
  }

  /**
   * Return the current contents for the receiver's source.
   *
   * @return the contents (not {@code null})
   */
  public String getNewContents() {
    return newContents;
  }

  /**
   * Return the number of characters in the replacement text.
   *
   * @return the replacement length (zero or greater)
   */
  public int getNewLength() {
    return newLength;
  }

  /**
   * Return the character position of the first changed character.
   *
   * @return the offset (zero or greater)
   */
  public int getOffset() {
    return offset;
  }

  /**
   * Return the original contents for the receiver's source.
   *
   * @return the contents (not {@code null})
   */
  public String getOldContents() {
    return oldContents;
  }

  /**
   * Return the number of characters that were replaced.
   *
   * @return the replaced length (zero or greater)
   */
  public int getOldLength() {
    return oldLength;
  }

  /**
   * Return the resolved compilation unit to be used for incremental analysis
   *
   * @return the resolved unit (not {@code null})
   */
  public CompilationUnit getResolvedUnit() {
    return resolvedUnit;
  }

  /**
   * Return the source for which incremental analysis is to be performed
   *
   * @return the source (not {@code null})
   */
  public Source getSource() {
    return source;
  }

  /**
   * Determine if the cache contains source changes that need to be analyzed
   *
   * @return {@code true} if the cache contains changes to be analyzed, else {@code false}
   */
  public boolean hasWork() {
    return oldLength > 0 || newLength > 0;
  }
}
TOP

Related Classes of com.google.dart.engine.internal.context.IncrementalAnalysisCache

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.