Package dtool.sourcegen

Source Code of dtool.sourcegen.AnnotatedSource$MetadataEntry

package dtool.sourcegen;

import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue;
import static melnorme.utilbox.core.CoreUtil.areEqual;

import java.util.ArrayList;
import java.util.ListIterator;

import melnorme.lang.tooling.ast.SourceRange;
import melnorme.utilbox.misc.StringUtil;

public class AnnotatedSource {
 
  public final String source;
  public final String originalTemplatedSource;
  public final ArrayList<AnnotatedSource.MetadataEntry> metadata;
 
  public AnnotatedSource(String source, String originalTemplatedSource, ArrayList<MetadataEntry> arrayList) {
    this.source = source;
    this.originalTemplatedSource = originalTemplatedSource;
    this.metadata = arrayList;
  }
 
  public static class MetadataEntry {
    public final String name;
    public final String value;
    public final int offset;
    public final String sourceValue;
    // the parent MDE to which offset applies, or null for top-level TODO
    private final Object parentScopeMDE;
    public final boolean sourceWasIncluded;
   
    public MetadataEntry(String name, String extraValue, String associatedSource, int offset) {
      this(name, extraValue, associatedSource, offset, null, true);
    }
    public MetadataEntry(String name, String extraValue, String associatedSource, int offset,
      Object parentScopeMDE) {
      this(name, extraValue, associatedSource, offset, parentScopeMDE, true);
    }
    public MetadataEntry(String name, String extraValue, String associatedSource, int offset,
      boolean sourceWasIncluded) {
      this(name, extraValue, associatedSource, offset, null, sourceWasIncluded);
    }
   
    public MetadataEntry(String name, String extraValue, String mdSource, int offset,
      Object parentScopeMDE, boolean sourceWasIncluded) {
      this.name = name;
      this.value = extraValue;
      this.offset = offset;
      assertTrue(offset >= 0);
      this.sourceValue = mdSource;
      this.parentScopeMDE = parentScopeMDE;
      this.sourceWasIncluded = sourceWasIncluded;
    }
   
    public SourceRange getSourceRange() {
      return new SourceRange(offset, sourceValue == null ? 0 : sourceValue.length());
    }
   
    public boolean isTopLevelMetadata() {
      return parentScopeMDE == null;
    }
   
    @Override
    public String toString() {
      return "["+offset+"]" + name +
        (sourceWasIncluded ? "" : "¤") +
        (value != null ? "("+value+")" : "") +
        (sourceValue != null ? "【"+sourceValue+"】" : "");
    }
  }
 
  @Override
  public String toString() {
    return source + "\n--------- METADATA: ---------\n" + StringUtil.collToString(metadata, "\n");
  }
 
  public MetadataEntry findMetadata(String name) {
    return findMetadata(name, true);
  }
  public MetadataEntry findMetadata(String name, boolean requireUnique) {
    MetadataEntry foundMde = null;
    for (MetadataEntry mde : metadata) {
      if(areEqual(mde.name, name)) {
        if(!requireUnique){
          return mde;
        }
        assertTrue(foundMde == null);
        foundMde = mde;
      }
    }
    return foundMde;
  }
 
  public MetadataEntry findMetadata(String name, String value) {
    MetadataEntry foundMde = null;
    for (MetadataEntry mde : metadata) {
      if(areEqual(mde.name, name) && areEqual(mde.value, value)) {
        assertTrue(foundMde == null);
        foundMde = mde;
      }
    }
    return foundMde;
  }
 
  public static String printSourceWithMetadata(AnnotatedSource testCase) {
    ListIterator<MetadataEntry> mdeIter = testCase.metadata.listIterator();
    StringBuffer sb = new StringBuffer();
    printCaseSourceWithMetaData(testCase.source, mdeIter, 0, testCase.source.length(), null, sb);
    assertTrue(mdeIter.hasNext() == false);
    return sb.toString();
  }
 
  public static void printCaseSourceWithMetaData(String source, ListIterator<MetadataEntry> mdeIter,
    final int startOffset, final int maxSourceOffset, MetadataEntry parentMDE, StringBuffer sb) {
    int offset = startOffset;

    while(mdeIter.hasNext()) {
      MetadataEntry mde = mdeIter.next();
      assertTrue(offset >= 0 && maxSourceOffset >= offset);
      int nextOffset = mde.offset;
      assertTrue(nextOffset >= offset);
     
      // TODO This condition is actually buggy and will be incorrect on child MDEs of child MDEs (depth 2)
      // This is because AnnotatedSource class doesn't provide parent MDE info
      boolean mdeIsParentOfParentMDE = mde.isTopLevelMetadata() == (parentMDE == null);
     
      if(nextOffset > maxSourceOffset || !mdeIsParentOfParentMDE) {
        mdeIter.previous();
        break;
      }
     
      sb.append(source.substring(offset, nextOffset));
      offset = nextOffset;
     
      sb.append("#" + mde.name);
      if(mde.value != null) {
        sb.append("(" + mde.value + ")");
      }
      if(mde.sourceValue != null) {
        sb.append(mde.sourceWasIncluded ? "【" : "¤【");
        if(mde.sourceWasIncluded) {
          nextOffset += mde.sourceValue.length();
          printCaseSourceWithMetaData(source, mdeIter, offset, nextOffset, parentMDE, sb);
          offset = nextOffset;
        } else {
          printCaseSourceWithMetaData(mde.sourceValue, mdeIter, 0, mde.sourceValue.length(), mde, sb);
        }
        sb.append("】");
      }
    }
    assertTrue(offset >= 0 && maxSourceOffset >= offset);
    sb.append(source.substring(offset, maxSourceOffset));
  }
}
TOP

Related Classes of dtool.sourcegen.AnnotatedSource$MetadataEntry

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.