zoukankan      html  css  js  c++  java
  • Razor潜入2令人疑惑的LocateOwner方法

           我们知道页面引擎尤其是Razor的核心是如何对页面上的代码的解析。

    而其中的核心的是一个语法解析树中的定位应该改变也算是非常频繁的操作。

    对于其中关键的LocateOwner函数真的令我疑惑。

    简单说明一下Razor中的语法树。Razor源码中是这样定义的。

    image

    基本机构,由上图可以知道。

    Block就是一个集合,可以看成是一篇文章或一个句子,span就是具体表达的一个小块。

    其中Block 提供了一个为'变动'提供定位span的方法。

    /// <summary> 
          
    /// 定位改变所属的 块 
          
    /// </summary> 
          
    /// <param name="change"></param> 
          
    /// <returns></returns> 
          public Span LocateOwner(TextChange change) { 
              
    // Ask each child recursively 
              Span owner = null;
              
    foreach (SyntaxTreeNode element in Children) { 
                  Span span 
    = element as Span;
                  
    if (span == null) { 
                      owner 
    = ((Block)element).LocateOwner(change);//如果是块则递归往下找 
                  } 
                  
    else { 
                      
    if (change.Position < span.Start.AbsoluteIndex) {//超出-属于span 
                          
    // Early escape for cases where changes overlap multiple spans 
                          
    // In those cases, the span will return false, and we don't want to search the whole tree 
                          
    // So if the current span starts after the change, we know we've searched as far as we need to 
                          break
                      } 
                      owner 
    = span.OwnsChange(change) ? span : owner;//deph 
                  }
                  
    if (owner != null) {//是否已经得到答案 
                      break
                  } 
              }
              
    return owner; 
          }
    //再给出span.OwnsChange(change) 的源码

    /// <summary> 
          
    /// Determines if the specified change belongs to this span. 
          
    /// </summary> 
          
    /// <remarks> 
          
    /// Used for Partial Parsing to identify which span to augment with the specified change. 
          
    /// Some changes have no owner, because they overlap multiple spans. 
          
    /// Also, just because a span owns a change, doesn't mean it can accept it 
          
    /// </remarks> 
          public virtual bool OwnsChange(TextChange change) { 
              
    int changeOldEnd = change.Position + change.OldLength; 
              
    return change.Position >= Start.AbsoluteIndex && 
                     (changeOldEnd 
    < EndIndex || (changeOldEnd == EndIndex && CanGrow)); 
          }

    这里很明显可以看到作者采用深度优先的策略,这不是很奇怪吗?为什么不采用广度优先?

    不是更容易定位吗?难道我又错了?想到半夜都没想通。大家说说看。

  • 相关阅读:
    MAC LAMP环境 php执行使用问题
    centos 服务器 安全设置
    Linux系统发现占用CPU达100%的进程并处理
    git 使用国内镜像 ,查看镜像更改情况
    mac安装composer
    MySql反向模糊查询
    Linux启动或重启网卡
    MAMP环境 nginx配置忽略index.php入口文件
    php 验证码生成 不保存的情况下 缩小图片质量
    KMP字符串模式匹配详解
  • 原文地址:https://www.cnblogs.com/facingwaller/p/1910347.html
Copyright © 2011-2022 走看看