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); }
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; } }
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; }
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; } } } }
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; }
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; }
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); }
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; }
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(); }
/// <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; }
public override Expression VisitThis(This thisNode) { return thisNode; }
public override Expression VisitThis(This This) { Write("this"); return This; }
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); }