public override Expression VisitThis(This This)
        {
            if (This.DeclaringMethod == abbreviation)
                return (Expression) this.Visit(this.targetObject);

            if (This.DeclaringMethod == this.targetMethod)
                // important lower case. Upper case is Duplicator's target method
                return This;

            return base.VisitThis(This);
        }
Example #2
0
 private CodeFlattener(Method method, bool expandAllocations, bool constantFold) 
 {
   this.Method = method;
   this.expandAllocations = expandAllocations;
   this.performConstantFoldingOnBranchConditions = constantFold;
   this.new_stats = new StatementList();
   this.new_blocks = new StatementList();
   this.thisNode = CciHelper.GetThis(method);
   if (thisNode != null && thisNode.Type == null) {
     thisNode.Type = method.DeclaringType;
   }
 }
Example #3
0
 public override InstanceInitializer InjectDefaultConstructor(TypeNode typeNode) {
   if (this.DontInjectDefaultConstructors || typeNode.IsNormalized) return null;
   Class Class = typeNode as Class;
   if (Class != null && Class.Name != null && !(Class is ClassParameter) && ClassHasNoExplicitConstructors(typeNode)) {
     if (Class.IsAbstractSealedContainerForStatics) return null;
     if (Class.PartiallyDefines != null){
       this.InjectDefaultConstructor(Class.PartiallyDefines);
       InstanceInitializer defCons = Class.PartiallyDefines.GetConstructor();
       if (defCons != null && !defCons.HasCompilerGeneratedSignature) 
         defCons = null; //Not an orphan
       if (defCons != null){
         //This is an injected default constructor that is an orphan, adopt it
         defCons.HasCompilerGeneratedSignature = false; //abuse this flag to stop other partial types from adopting it
         Class.Members.Add(defCons);
         Class.BaseClass = ((Class)Class.PartiallyDefines).BaseClass;
       }
       return defCons; //Ok if defCons null, this type should not show up in inheritance chains
     }else{
       //Inject a default constructor
       This thisParameter = new This(Class);
       Class baseClass = Class.BaseClass;
       StatementList statements = new StatementList(2);
       statements.Add(new FieldInitializerBlock(typeNode, false));
       if (baseClass != null) {
         MethodCall mcall = new MethodCall(new QualifiedIdentifier(new Base(), StandardIds.Ctor, typeNode.Name.SourceContext), null);
         mcall.SourceContext = typeNode.Name.SourceContext;
         ExpressionStatement callSupCons = new ExpressionStatement(mcall);
         callSupCons.SourceContext = typeNode.Name.SourceContext;
         statements.Add(callSupCons);
       }
       InstanceInitializer defCons = new InstanceInitializer(typeNode, null, null, new Block(statements));
       defCons.Name = new Identifier(".ctor", typeNode.Name.SourceContext);
       defCons.SourceContext = typeNode.Name.SourceContext;
       defCons.ThisParameter = thisParameter;
       if (typeNode.IsAbstract)
         defCons.Flags |= MethodFlags.Family|MethodFlags.HideBySig;
       else
         defCons.Flags |= MethodFlags.Public|MethodFlags.HideBySig;
       defCons.CallingConvention = CallingConventionFlags.HasThis;
       defCons.IsCompilerGenerated = true;
       typeNode.Members.Add(defCons);
       return defCons;
     }
   }
   return null;
 }
Example #4
0
 private void PrepareGuardedClass(TypeNode typeNode) {
   SpecSharpCompilerOptions options = this.currentOptions as SpecSharpCompilerOptions;
   if (!(options != null && (options.DisableGuardedClassesChecks || options.Compatibility))) {
     if (typeNode is Class && typeNode.Contract != null && (typeNode.Contract.InvariantCount > 0 || typeNode.Contract.ModelfieldContractCount > 0) ||
       typeNode is Class && this.currentPreprocessorDefinedSymbols != null && this.currentPreprocessorDefinedSymbols.ContainsKey("GuardAllClasses")) {
       if (typeNode.Interfaces == null) {
         typeNode.Interfaces = new InterfaceList();
       }
       if (typeNode.Template == null) { //we have to be careful when we are passed a typeNode of a specialized generic type as it shares the contract of the 'real' generic typeNode
         #region Add the field "frame" to the class.
         Field frameField = new Field(typeNode, null, FieldFlags.Public, Identifier.For("SpecSharp::frameGuard"), SystemTypes.Guard, null);
         frameField.CciKind = CciMemberKind.Auxiliary;
         typeNode.Contract.FrameField = frameField;
         typeNode.Members.Add(frameField);
         This thisParameter = new This(typeNode);
         Method frameGetter = new Method(typeNode, NoDefaultExpose(), Identifier.For("get_SpecSharp::FrameGuard"), null, OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Guard),
           new Block(new StatementList(new Return(new BinaryExpression(new MemberBinding(thisParameter, frameField), new Literal(SystemTypes.NonNullType, SystemTypes.Type), System.Compiler.NodeType.ExplicitCoercion, OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Guard))))));
         // Pretend this method is [Delayed] so that we can call it from a delayed constructor.
         frameGetter.Attributes.Add(new AttributeNode(new Literal(ExtendedRuntimeTypes.DelayedAttribute, SystemTypes.Type), null, AttributeTargets.Method));
         frameGetter.CciKind = CciMemberKind.FrameGuardGetter;
         frameGetter.Attributes.Add(new AttributeNode(new Literal(SystemTypes.PureAttribute, SystemTypes.Type), null, AttributeTargets.Method));
         frameGetter.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.SpecialName;
         frameGetter.CallingConvention = CallingConventionFlags.HasThis;
         frameGetter.ThisParameter = thisParameter;
         typeNode.Contract.FramePropertyGetter = frameGetter;
         typeNode.Members.Add(frameGetter);
         Property frameProperty = new Property(typeNode, null, PropertyFlags.None, Identifier.For("SpecSharp::FrameGuard"), frameGetter, null);
         typeNode.Members.Add(frameProperty);
         typeNode.Contract.FrameProperty = frameProperty;
         #endregion
         typeNode.Contract.InitFrameSetsMethod = new Method(typeNode, NoDefaultExpose(), Identifier.For("SpecSharp::InitGuardSets"), null, SystemTypes.Void, null);
         typeNode.Contract.InitFrameSetsMethod.CciKind = CciMemberKind.Auxiliary;
         typeNode.Contract.InitFrameSetsMethod.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.SpecialName;
       }
     }
   }
 }
Example #5
0
 public override Expression VisitThis(This This)
 {
     if (This == null) return null;
     return (Expression)new Identifier("This");
 }
 public ContractLocalToThis(Local local, This @this)
 {
     this.@this = @this;
     this.local = local;
 }
Example #7
0
        public virtual Expression VisitThis(This This)
        {
            if(This == null)
                return null;

            This.Type = this.VisitTypeReference(This.Type);
            ThisBinding tb = This as ThisBinding;

            if (tb != null)
            {
                This boundThis = this.VisitThis(tb.BoundThis) as This;
                if (boundThis != null)
                    tb.BoundThis = boundThis;
            }

            return This;
        }
		/// <summary>
		/// Find the This node in the method body if method is an instance method.
		/// </summary>
		/// <param name="method">Method for which we find the This node</param>
		/// <returns>The This node or null if method is not instance.</returns>
    public static This GetThis (Method method)
    {
      if ((method.CallingConvention & CallingConventionFlags.HasThis) == 0) return null;
      This t = method.ThisParameter;
      if (t == null) 
      {
        if (method.DeclaringType != null && method.DeclaringType.IsValueType) {
            t = new This(method.DeclaringType.GetReferenceType());
        }
        else {
            t = new This(method.DeclaringType);
        }
        method.ThisParameter = t;
      }
      return t;
    }
        public override Expression VisitThis(This This)
        {
            var original = This;

            var result = base.VisitThis(This);
                
            This = result as This;
                
            if (this.replaceThisWithParameter != null && This != null)
            {
                if (original == sourceMethod.ThisParameter)
                {
                    return this.replaceThisWithParameter;
                }
            }

            return result;
        }
Example #10
0
 public override Expression VisitThis(This This)
 {
     if (This == null) return null;
     This dup = (This)this.DuplicateFor[This.UniqueKey];
     if (dup != null) return dup;
     this.DuplicateFor[This.UniqueKey] = dup = (This)This.Clone();
     return base.VisitThis(dup);
 }
Example #11
0
    private Expression ParsePrimaryExpression(TokenSet followers){
      Expression expression = null;
      SourceContext sctx = this.scanner.CurrentSourceContext;
      switch(this.currentToken){
        case Token.ArgList:
          this.GetNextToken();
          expression = new ArglistExpression(sctx);
          break;
        case Token.Delegate:{
          this.GetNextToken();
          ParameterList parameters = null;
          if (this.currentToken == Token.LeftParenthesis)
            parameters = this.ParseParameters(Token.RightParenthesis, followers|Token.LeftBrace);
          Block block = null;
          if (this.currentToken == Token.LeftBrace)
            block = this.ParseBlock(this.scanner.CurrentSourceContext, followers);
          else
            this.SkipTo(followers, Error.ExpectedLeftBrace);
          sctx.EndPos = this.scanner.endPos;
          return new AnonymousNestedDelegate(parameters, block, sctx);}
        case Token.New:
          expression = this.ParseNew(followers|Token.Dot|Token.LeftBracket|Token.Arrow);
          break;
        case Token.Identifier:
          expression = this.scanner.GetIdentifier();
          if (this.sink != null) {
            this.sink.StartName((Identifier)expression);
          }
          this.GetNextToken();
          if (this.currentToken == Token.DoubleColon){
            this.GetNextToken();
            Identifier id = this.scanner.GetIdentifier();
            id.Prefix = (Identifier)expression;
            id.SourceContext.StartPos = expression.SourceContext.StartPos;
            expression = id;
            if (this.currentToken != Token.EndOfFile)
              this.GetNextToken();
          }else if (this.currentToken == Token.Lambda){
            Parameter par = new Parameter((Identifier)expression, null);
            par.SourceContext = expression.SourceContext;
            return this.ParseLambdaExpression(par.SourceContext, new ParameterList(par), followers);
          }
          break;
        case Token.Null:
          expression = new Literal(null, null, sctx);
          this.GetNextToken();
          break;
        case Token.True:
          expression = new Literal(true, null, sctx);
          this.GetNextToken();
          break;
        case Token.False:
          expression = new Literal(false, null, sctx);
          this.GetNextToken();
          break;
        case Token.CharLiteral:
          expression = new Literal(this.scanner.charLiteralValue, null, sctx);
          this.GetNextToken();
          break;
        case Token.HexLiteral:
          expression = this.ParseHexLiteral();
          break;
        case Token.IntegerLiteral:
          expression = this.ParseIntegerLiteral();
          break;
        case Token.RealLiteral:
          expression = this.ParseRealLiteral();
          break;
        case Token.StringLiteral:
          expression = this.scanner.GetStringLiteral();
          this.GetNextToken();
          break;
        case Token.This:
          expression = new This(sctx, false);
          if (this.sink != null) {
            this.sink.StartName(expression);
          }
          this.GetNextToken();
          if (this.currentToken == Token.LeftParenthesis
            && (this.inInstanceConstructor==BaseOrThisCallKind.None
            || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyThisSeen)){
            QualifiedIdentifier thisCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext);
            MethodCall thisConstructorCall = new MethodCall(thisCons, null, NodeType.Call);
            thisConstructorCall.SourceContext = sctx;
            SourceContext lpCtx = this.scanner.CurrentSourceContext;
            this.Skip(Token.LeftParenthesis);
            thisConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out thisConstructorCall.SourceContext.EndPos);
            expression = thisConstructorCall;
            this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyThisSeen;
            goto done;
          }
          break;
        case Token.Base:
          Base ba = new Base(sctx, false);
          expression = ba;
          if (this.sink != null) {
            this.sink.StartName(expression);
          }
          this.GetNextToken();
          if (this.currentToken == Token.Semicolon &&
            (this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen
            || this.inInstanceConstructor == BaseOrThisCallKind.None)) {
            // When there are non-null fields, then the base ctor call can happen only after they are
            // initialized.
            // In Spec#, we allow a base ctor call in the body of the ctor. But if someone is using
            // the C# comment convention, then they cannot do that.
            // So allow "base;" as a marker to indicate where the base ctor call should happen.
            // There may be an explicit "colon base call" or it may be implicit.
            //
            // Just leave expression as a bare "Base" node; later pipeline stages will all have
            // to ignore it. Mark the current ctor as having (at least) one of these bad boys
            // in it.
            ba.UsedAsMarker = true;
            this.currentCtor.ContainsBaseMarkerBecauseOfNonNullFields = true;
            goto done;
          }
          if (this.currentToken == Token.LeftParenthesis
            && (this.inInstanceConstructor==BaseOrThisCallKind.None
              || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyBaseSeen)){
            QualifiedIdentifier supCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext);
            MethodCall superConstructorCall = new MethodCall(supCons, null, NodeType.Call);
            superConstructorCall.SourceContext = sctx;
            SourceContext lpCtx = this.scanner.CurrentSourceContext;
            this.Skip(Token.LeftParenthesis);
            superConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out superConstructorCall.SourceContext.EndPos);
            expression = superConstructorCall;
            this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyBaseSeen;
            goto done;
          }
          break;
        case Token.Typeof:
        case Token.Sizeof:
        case Token.Default:{
          //if (this.currentToken == Token.Sizeof && !this.inUnsafeCode)
            //this.HandleError(Error.SizeofUnsafe);
          UnaryExpression uex = new UnaryExpression(null,
            this.currentToken == Token.Typeof ? NodeType.Typeof : this.currentToken == Token.Sizeof ? NodeType.Sizeof : NodeType.DefaultValue);
          uex.SourceContext = sctx;
          this.GetNextToken();
          this.Skip(Token.LeftParenthesis);
          TypeNode t = null;
          if (this.currentToken == Token.Void && uex.NodeType == NodeType.Typeof){
            t = this.TypeExpressionFor(Token.Void); this.GetNextToken();
          }else
            t = this.ParseTypeExpression(null, followers|Token.RightParenthesis, false, false, uex.NodeType == NodeType.Typeof);
          if (t == null){this.SkipTo(followers); return null;}
          uex.Operand = new MemberBinding(null, t, t.SourceContext, null);
          uex.Operand.SourceContext = t.SourceContext;
          uex.SourceContext.EndPos = this.scanner.endPos;
          this.Skip(Token.RightParenthesis);
          expression = uex;
          break;}
        case Token.Stackalloc:{
          this.GetNextToken();
          TypeNode elementType = this.ParseBaseTypeExpression(null, followers|Token.LeftBracket, false, false);
          if (elementType == null){this.SkipTo(followers); return null;}
          Token openingDelimiter = this.currentToken;
          if (this.currentToken != Token.LeftBracket){
            this.HandleError(Error.BadStackAllocExpr);
            if (this.currentToken == Token.LeftParenthesis) this.GetNextToken();
          }else
            this.GetNextToken();
          Expression numElements = this.ParseExpression(followers|Token.RightBracket|Token.RightParenthesis);
          sctx.EndPos = this.scanner.endPos;
          if (this.currentToken == Token.RightParenthesis && openingDelimiter == Token.LeftParenthesis)
            this.GetNextToken();
          else
            this.Skip(Token.RightBracket);
          this.SkipTo(followers);
          return new StackAlloc(elementType, numElements, sctx);}
        case Token.Checked:
        case Token.Unchecked:
          //TODO: use NodeType.SkipCheck and NodeType.EnforceCheck
          Block b = new Block(new StatementList(1), this.currentToken == Token.Checked, this.currentToken == Token.Unchecked, this.inUnsafeCode);
          b.SourceContext = sctx;
          this.GetNextToken();
          this.Skip(Token.LeftParenthesis);
          b.Statements.Add(new ExpressionStatement(this.ParseExpression(followers|Token.RightParenthesis)));
          this.Skip(Token.RightParenthesis);
          expression = new BlockExpression(b);
          expression.SourceContext = b.SourceContext;
          break;
        case Token.RefType:{
          this.GetNextToken();
          this.Skip(Token.LeftParenthesis);
          Expression e = this.ParseExpression(followers|Token.RightParenthesis);
          this.Skip(Token.RightParenthesis);
          expression = new RefTypeExpression(e, sctx);
          break;
        }
        case Token.RefValue:{
          this.GetNextToken();
          this.Skip(Token.LeftParenthesis);
          Expression e = this.ParseExpression(followers|Token.Comma);
          this.Skip(Token.Comma);
          TypeNode te = this.ParseTypeOrFunctionTypeExpression(followers|Token.RightParenthesis, false, true);
          Expression operand2 = new MemberBinding(null, te);
          if (te is TypeExpression)
            operand2.SourceContext = te.SourceContext;
          else
            operand2.SourceContext = sctx;
          this.Skip(Token.RightParenthesis);
          expression = new RefValueExpression(e, operand2, sctx);
          break;
        }
        case Token.Bool:
        case Token.Decimal:
        case Token.Sbyte:
        case Token.Byte:
        case Token.Short:
        case Token.Ushort:
        case Token.Int:
        case Token.Uint:
        case Token.Long:
        case Token.Ulong:
        case Token.Char:
        case Token.Float:
        case Token.Double:
        case Token.Object:
        case Token.String:
          MemberBinding mb = new MemberBinding(null, this.TypeExpressionFor(this.currentToken), sctx);
          this.GetNextToken();
          expression = this.ParseIndexerCallOrSelector(mb, followers);
          goto done;
        case Token.LeftParenthesis:
          expression = this.ParseParenthesizedExpression(followers|Token.Dot|Token.LeftBracket|Token.Arrow, true);
          break;
        default:
          if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) goto case Token.Identifier;
          if (Parser.InfixOperators[this.currentToken]){
            this.HandleError(Error.InvalidExprTerm, this.scanner.GetTokenSource());
            this.GetNextToken();
          }else
            this.SkipTo(followers|Parser.PrimaryStart, Error.InvalidExprTerm, this.scanner.GetTokenSource());
          if (Parser.PrimaryStart[this.currentToken]) return this.ParsePrimaryExpression(followers);
          goto done;
      }
      if (expression is Base && this.currentToken != Token.Dot && this.currentToken != Token.LeftBracket){
        this.HandleError(expression.SourceContext, Error.BaseIllegal);
        expression = null;
      }

      expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne);
      for(;;){
        switch(this.currentToken){
          case Token.AddOne:
          case Token.SubtractOne:
            SourceContext ctx = expression.SourceContext;
            ctx.EndPos = this.scanner.endPos;
            PostfixExpression pex = new PostfixExpression(expression, Parser.ConvertToBinaryNodeType(this.currentToken), ctx);
            this.GetNextToken();
            expression = pex;
            break;
          case Token.Dot:
            expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne);
            break;
          default:
            goto done;
        }
      }
      done:
        this.SkipTo(followers);
      return expression;
    }
Example #12
0
 public ThisBinding(This/*!*/ boundThis, SourceContext sctx)
 {
     if(boundThis == null)
         throw new ArgumentNullException("boundThis");
     this.BoundThis = boundThis;
     this.SourceContext = sctx;
     this.Type = boundThis.Type;
     this.Name = boundThis.Name;
     this.TypeExpression = boundThis.TypeExpression;
     this.Attributes = boundThis.Attributes;
     this.DefaultValue = boundThis.DefaultValue;
     this.Flags = boundThis.Flags;
     this.MarshallingInformation = boundThis.MarshallingInformation;
     this.DeclaringMethod = boundThis.DeclaringMethod;
     this.ParameterListIndex = boundThis.ParameterListIndex;
     this.ArgumentListIndex = boundThis.ArgumentListIndex;
     //^ base();
 }
Example #13
0
    /// <summary>
    /// Unify all occurrences of This
    /// </summary>
    /// <param name="This"></param>
    /// <returns></returns>
		public override Expression VisitThis(This This)
		{
      if (This is ThisBinding) return This;
			return this.thisNode;
		}
Example #14
0
 public override Expression VisitThis(This thisNode) {
   return thisNode;
 }
Example #15
0
 public override Expression VisitThis(This This)
 {
     Write("this");
     return This;
 }
Example #16
0
 public IEnumerable<MemberBinding> NecessaryResultInitialization(Dictionary<TypeNode, Local> closureLocals)
 {
   if (topLevelStaticResultField != null)
   {
     yield return new MemberBinding(null, topLevelStaticResultField);
   }
   if (topLevelClosureResultField != null)
   {
     // note: this field is the field in the generic context of the closure. For the method to initialize this
     // we need the instantiated form, which we remember in topLevelClosureClassInstance
     Local local;
     if (closureLocals.TryGetValue(topLevelClosureClassInstance, out local))
     {
       yield return new MemberBinding(local, GetInstanceField(this.originalLocalForResult.Type, topLevelClosureResultField, topLevelClosureClassInstance));
     } else
     {
       var access = new This(topLevelClosureClassInstance);
       yield return new MemberBinding(access, GetInstanceField(this.originalLocalForResult.Type, topLevelClosureResultField, topLevelClosureClassInstance));
     }
   }
 }
            public override void VisitThis(This This)
            {
                // F: Should this be a precondition?
                Contract.Assume(This != null);

                // the second test is to avoid complaining about "this" use in closures used in ctors
                if (this.CurrentMethod is InstanceInitializer && This.DeclaringMethod == this.CurrentMethod)
                {
                    this.HandleError("This/Me cannot be used in Requires of a constructor");
                }
            }
 public EventingVisitor(Action<This> visitThis) { VisitedThis += visitThis; } public event Action<This> VisitedThis; public override Expression VisitThis(This This) { if (VisitedThis != null) VisitedThis(This); return base.VisitThis(This); }