示例#1
0
            private ExpressionList Visit(ExpressionList expressionList)
            {
                if (expressionList == null) return null;

                expressionList = expressionList.Clone();
                
                for (int i = 0; i < expressionList.Count; i++)
                {
                    expressionList[i] = Visit(expressionList[i]);
                }
                
                return expressionList;
            }
    public virtual Differences VisitExpressionList(ExpressionList list1, ExpressionList list2,
      out ExpressionList changes, out ExpressionList deletions, out ExpressionList insertions){
      changes = list1 == null ? null : list1.Clone();
      deletions = list1 == null ? null : list1.Clone();
      insertions = list1 == null ? new ExpressionList() : list1.Clone();
      //^ assert insertions != null;

      Differences differences = new Differences();
      for (int j = 0, n = list2 == null ? 0 : list2.Count; j < n; j++){
        //^ assert list2 != null;
        Expression nd2 = list2[j];
        if (nd2 == null) continue;
        insertions.Add(null);
      }
      TrivialHashtable savedDifferencesMapFor = this.differencesMapFor;
      this.differencesMapFor = null;
      TrivialHashtable matchedNodes = new TrivialHashtable();
      for (int i = 0, k = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){
        //^ assert list1 != null && changes != null && deletions != null;
        Expression nd1 = list1[i]; 
        if (nd1 == null) continue;
        Differences diff;
        int j;
        Expression nd2 = this.GetClosestMatch(nd1, list1, list2, i, ref k, matchedNodes, out diff, out j);
        if (nd2 == null || diff == null){Debug.Assert(nd2 == null && diff == null); continue;}
        matchedNodes[nd1.UniqueKey] = nd1;
        matchedNodes[nd2.UniqueKey] = nd2;
        changes[i] = diff.Changes as Expression;
        deletions[i] = diff.Deletions as Expression;
        insertions[i] = diff.Insertions as Expression;
        insertions[n+j] = nd1; //Records the position of nd2 in list2 in case the change involved a permutation
        Debug.Assert(diff.Changes == changes[i] && diff.Deletions == deletions[i] && diff.Insertions == insertions[i]);
        differences.NumberOfDifferences += diff.NumberOfDifferences;
        differences.NumberOfSimilarities += diff.NumberOfSimilarities;
      }
      //Find deletions
      for (int i = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){
        //^ assert list1 != null && changes != null && deletions != null;
        Expression nd1 = list1[i]; 
        if (nd1 == null) continue;
        if (matchedNodes[nd1.UniqueKey] != null) continue;
        changes[i] = null;
        deletions[i] = nd1;
        insertions[i] = null;
        differences.NumberOfDifferences += 1;
      }
      //Find insertions
      for (int j = 0, n = list1 == null ? 0 : list1.Count, m = list2 == null ? 0 : list2.Count; j < m; j++){
        //^ assert list2 != null;
        Expression nd2 = list2[j]; 
        if (nd2 == null) continue;
        if (matchedNodes[nd2.UniqueKey] != null) continue;
        insertions[n+j] = nd2;  //Records nd2 as an insertion into list1, along with its position in list2
        differences.NumberOfDifferences += 1; //REVIEW: put the size of the tree here?
      }
      if (differences.NumberOfDifferences == 0){
        changes = null;
        deletions = null;
        insertions = null;
      }
      this.differencesMapFor = savedDifferencesMapFor;
      return differences;
    }
示例#3
0
 public virtual AttributeNode VisitAttributeNode(AttributeNode attribute, Node target) {
   if (attribute == null || target == null) return null;
   attribute.Constructor = this.VisitAttributeConstructor(attribute, target);
   ExpressionList expressions = attribute.Expressions = this.VisitExpressionList(attribute.Expressions);
   MemberBinding mb = attribute.Constructor as MemberBinding;
   if (mb == null || mb.BoundMember == null) {
     Debug.Assert(attribute.Constructor == null);
     return null;
   }
   //Check arguments for validity
   TypeNode attributeType = mb.BoundMember.DeclaringType;
   if (attributeType == null) return null;
   InstanceInitializer ctor = (InstanceInitializer)mb.BoundMember;
   ParameterList pars = ctor.Parameters;
   ExpressionList positionalArgs = new ExpressionList();
   TrivialHashtable alreadySeenNames = new TrivialHashtable();
   for (int i = 0, n = expressions == null ? 0 : expressions.Count; i < n; i++) {
     Expression e = expressions[i];
     this.TypeInVariableContext(e as Literal);
     NamedArgument narg = e as NamedArgument;
     if (narg == null) { positionalArgs.Add(e); expressions[i] = null; continue; }
     if (narg.Name == null) { expressions[i] = null; continue; }
     if (alreadySeenNames[narg.Name.UniqueIdKey] != null) {
       this.HandleError(narg.Name, Error.DuplicateNamedAttributeArgument, narg.Name.ToString());
       expressions[i] = null; continue;
     }
     alreadySeenNames[narg.Name.UniqueIdKey] = narg.Name;
     Member mem = null;
     TypeNode aType = attributeType;
     while (aType != null) {
       MemberList members = this.GetTypeView(aType).GetMembersNamed(narg.Name);
       for (int j = 0, m = members == null ? 0 : members.Count; j < m; j++) {
         mem = members[j];
         if (mem == null) continue;
         switch (mem.NodeType) {
           case NodeType.Field:
             if (!mem.IsPublic) goto error;
             Field f = (Field)mem;
             if (f.IsInitOnly || f.IsLiteral || f.IsStatic) goto error;
             if (!this.IsValidTypeForCustomAttributeParameter(f.Type)) {
               this.HandleError(narg, Error.BadNamedAttributeArgumentType, this.GetMemberSignature(f));
               this.HandleRelatedError(f);
               return null;
             }
             this.CheckForObsolesence(narg, f);
             narg.IsCustomAttributeProperty = false;
             e = this.typeSystem.ImplicitCoercion(narg.Value, narg.Type = f.Type, this.TypeViewer);
             if (!this.IsValidTypeForCustomAttributeArgument(e, narg.Value)) return null;
             if (e is BinaryExpression && e.NodeType == NodeType.Box) {
               narg.ValueIsBoxed = true;
               e = ((BinaryExpression)e).Operand1;
             }
             narg.Value = e;
             goto doneWithArg;
           case NodeType.Property:
             if (!mem.IsPublic) goto error;
             Property p = (Property)mem;
             if (!this.IsValidTypeForCustomAttributeParameter(p.Type)) {
               this.HandleError(narg, Error.BadNamedAttributeArgumentType, this.GetMemberSignature(p));
               this.HandleRelatedError(p);
               return null;
             }
             if (p.Setter == null || p.Getter == null || p.IsStatic || !p.Setter.IsPublic || !p.Getter.IsPublic) goto error;
             this.CheckForObsolesence(narg, p);
             narg.IsCustomAttributeProperty = true;
             e = this.typeSystem.ImplicitCoercion(narg.Value, narg.Type = p.Type, this.TypeViewer);
             if (!this.IsValidTypeForCustomAttributeArgument(e, narg.Value)) return null;
             if (e is BinaryExpression && e.NodeType == NodeType.Box) {
               narg.ValueIsBoxed = true;
               e = ((BinaryExpression)e).Operand1;
             }
             narg.Value = e;
             goto doneWithArg;
         }
       }
       aType = aType.BaseType;
     }
   error:
     if (mem != null) {
       this.HandleError(narg, Error.BadNamedAttributeArgument, narg.Name.ToString());
       this.HandleRelatedError(mem);
     } else
       this.HandleError(narg, Error.NoSuchMember, this.GetTypeName(attributeType), narg.Name.ToString());
   doneWithArg: ;
   }
   ExpressionList exprs = positionalArgs.Clone();
   this.CoerceArguments(pars, ref positionalArgs, true, ctor.CallingConvention);
   attribute.Expressions = positionalArgs;
   for (int i = 0, n = positionalArgs == null ? 0 : positionalArgs.Count; i < n; i++) {
     Expression e = positionalArgs[i];
     if (e == null) continue;
     if (!this.IsValidTypeForCustomAttributeArgument(e, exprs[i])) return null;
     if (e is BinaryExpression && e.NodeType == NodeType.Box) e = ((BinaryExpression)e).Operand1;
     positionalArgs[i] = e;
   }
   for (int i = 0, n = expressions == null ? 0 : expressions.Count; i < n; i++) {
     Expression e = expressions[i];
     if (e == null) continue;
     positionalArgs.Add(e);
   }
   attribute.Expressions = positionalArgs;
   //Now call specific visitors to deal with any pseudo custom attributes that describe metadata settings for target
   switch (target.NodeType) {
     case NodeType.Assembly: return this.VisitAssemblyAttribute(attribute, (AssemblyNode)target);
     case NodeType.Field: return this.VisitFieldAttribute(attribute, (Field)target);
     case NodeType.InstanceInitializer:
     case NodeType.StaticInitializer:
     case NodeType.Method: return this.VisitMethodAttribute(attribute, (Method)target);
     case NodeType.Property: return this.VisitPropertyAttribute(attribute, (Property)target);
     case NodeType.Parameter: return this.VisitParameterAttribute(attribute, (Parameter)target);
     default:
       TypeNode t = target as TypeNode;
       if (t != null) return this.VisitTypeAttribute(attribute, t);
       break;
   }
   return attribute;
 }