public Iterator(ParametersBlock block, IMethodData method, TypeDefinition host, TypeSpec iterator_type, bool is_enumerable) : base(block, host, host.Compiler.BuiltinTypes.Bool) { this.OriginalMethod = method; this.OriginalIteratorType = iterator_type; this.IsEnumerable = is_enumerable; this.type = method.ReturnType; }
public static void CreateIterator(IMethodData method, TypeContainer parent, Modifiers modifiers) { bool is_enumerable; TypeSpec iterator_type; TypeSpec ret = method.ReturnType; if (ret == null) { return; } if (!CheckType(ret, parent, out iterator_type, out is_enumerable)) { parent.Compiler.Report.Error(1624, method.Location, "The body of `{0}' cannot be an iterator block " + "because `{1}' is not an iterator interface type", method.GetSignatureForError(), TypeManager.CSharpName(ret)); return; } ParametersCompiled parameters = method.ParameterInfo; for (int i = 0; i < parameters.Count; i++) { Parameter p = parameters [i]; Parameter.Modifier mod = p.ModFlags; if ((mod & Parameter.Modifier.ISBYREF) != 0) { parent.Compiler.Report.Error(1623, p.Location, "Iterators cannot have ref or out parameters"); return; } if (p is ArglistParameter) { parent.Compiler.Report.Error(1636, method.Location, "__arglist is not allowed in parameter list of iterators"); return; } if (parameters.Types [i].IsPointer) { parent.Compiler.Report.Error(1637, p.Location, "Iterators cannot have unsafe parameters or " + "yield types"); return; } } if ((modifiers & Modifiers.UNSAFE) != 0) { parent.Compiler.Report.Error(1629, method.Location, "Unsafe code may not appear in iterators"); } method.Block.WrapIntoIterator(method, parent, iterator_type, is_enumerable); }
// // Our constructor // public Iterator(ParametersBlock block, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable) : base(block, host.Compiler.BuiltinTypes.Bool, block.StartLocation) { this.OriginalMethod = method; this.OriginalIteratorType = iterator_type; this.IsEnumerable = is_enumerable; this.Host = host; this.type = method.ReturnType; }
public static void CreateIterator(IMethodData method, TypeDefinition parent, Modifiers modifiers) { bool is_enumerable; TypeSpec iterator_type; TypeSpec ret = method.ReturnType; if (ret == null) { return; } if (!CheckType(ret, parent, out iterator_type, out is_enumerable)) { parent.Compiler.Report.Error(1624, method.Location, "The body of `{0}' cannot be an iterator block " + "because `{1}' is not an iterator interface type", method.GetSignatureForError(), ret.GetSignatureForError()); return; } ParametersCompiled parameters = method.ParameterInfo; for (int i = 0; i < parameters.Count; i++) { Parameter p = parameters [i]; Parameter.Modifier mod = p.ModFlags; if ((mod & Parameter.Modifier.RefOutMask) != 0) { parent.Compiler.Report.Error(1623, p.Location, "Iterators cannot have ref or out parameters"); return; } if (p is ArglistParameter) { parent.Compiler.Report.Error(1636, method.Location, "__arglist is not allowed in parameter list of iterators"); return; } if (parameters.Types [i].IsPointer) { parent.Compiler.Report.Error(1637, p.Location, "Iterators cannot have unsafe parameters or yield types"); return; } } if ((modifiers & Modifiers.UNSAFE) != 0) { Expression.UnsafeInsideIteratorError(parent.Compiler.Report, method.Location); } method.Block = method.Block.ConvertToIterator(method, parent, iterator_type, is_enumerable); }
// // Our constructor // public Iterator(ParametersBlock block, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable) : base(block, TypeManager.bool_type, block.StartLocation) { this.OriginalMethod = method; this.OriginalIteratorType = iterator_type; this.IsEnumerable = is_enumerable; this.Host = host; this.type = method.ReturnType; }
public static List <string> GetMockMethod(IMethodData method, string className) { return(new List <string> { String.Empty, "public " + method.FullSignature, "{", " return (" + method.ReturnType + ")MockResultSingleton.GetResult(\"" + className + "." + method.MethodName + "\");", "}" }); }
public static List <string> GetEmptyMethod(IMethodData method) { return(new List <string> { String.Empty, "public " + method.FullSignature, "{", " " + GetValidReturnStatement(method.ReturnType), "}" }); }
public MethodDiff(IMethodData oldField, IMethodData newField) { AddedAttributes = new List<IAttributeData>(); RemovedAttributes = new List<IAttributeData>(); if (oldField.MethodSignature != newField.MethodSignature) { throw new NtegrityException("Attempted to diff two different Enums!"); } MethodSignature = oldField.MethodSignature; GetAddedAndRemovedAttributes(oldField, newField); }
// // Our constructor // private Iterator(IMethodData method, TypeContainer host, Type iterator_type, bool is_enumerable) : base( new ToplevelBlock(method.Block, Parameters.EmptyReadOnlyParameters, method.Block.StartLocation), TypeManager.bool_type, method.Location) { this.OriginalMethod = method; this.OriginalIteratorType = iterator_type; this.IsEnumerable = is_enumerable; this.Host = host; IteratorHost = Block.ChangeToIterator(this, method.Block); }
// // Our constructor // private Iterator(CompilerContext ctx, IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable) : base(new ToplevelBlock (ctx, method.Block, ParametersCompiled.EmptyReadOnlyParameters, method.Block.StartLocation), TypeManager.bool_type, method.Location) { this.OriginalMethod = method; this.OriginalIteratorType = iterator_type; this.IsEnumerable = is_enumerable; this.Host = host; this.type = method.ReturnType; IteratorHost = Block.ChangeToIterator (this, method.Block); }
public static List <string> GetProxyMethod(IMethodData method, CloudServiceInfo serviceInfo) { string constName = method.MethodName.ConvertToConstName(); return(new List <string> { String.Empty, "private const string " + constName + " = \"" + serviceInfo.ServiceName + "_" + method.MethodName + "\";", "public " + method.FullSignature, "{", " return Execute<" + method.ReturnType + ">(" + method.ParametersWithoutTypes + ", " + constName + ");", "}" }); }
public ClrmdMethod(ClrType type, IMethodData data) { if (data is null) { throw new ArgumentNullException(nameof(data)); } _helpers = data.Helpers; Type = type; MethodDesc = data.MethodDesc; CompilationType = data.CompilationType; MetadataToken = data.Token; _hotCold = new HotColdRegions(data.HotStart, data.HotSize, data.ColdStart, data.ColdSize); _attrs = type?.Module?.MetadataImport?.GetMethodAttributes(MetadataToken) ?? default; }
public void SymbolRelatedToPreviousError(MemberInfo mi) { if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport) { return; } Type dt = TypeManager.DropGenericTypeArguments(mi.DeclaringType); if (TypeManager.IsDelegateType(dt)) { SymbolRelatedToPreviousError(dt); return; } DeclSpace temp_ds = TypeManager.LookupDeclSpace(dt); if (temp_ds == null) { SymbolRelatedToPreviousError(dt.Assembly.Location, TypeManager.GetFullNameSignature(mi)); } else { MethodBase mb = mi as MethodBase; if (mb != null) { mb = TypeManager.DropGenericMethodArguments(mb); IMethodData md = TypeManager.GetMethod(mb); if (md != null) { SymbolRelatedToPreviousError(md.Location, md.GetSignatureForError()); } return; } // FIXME: Completely wrong, it has to use FindMembers MemberCore mc = temp_ds.GetDefinition(mi.Name); if (mc != null) { SymbolRelatedToPreviousError(mc); } } }
public MethodData (InterfaceMemberBase member, Modifiers modifiers, MethodAttributes flags, IMethodData method, MethodBuilder builder, GenericMethod generic, MethodSpec parent_method) : this (member, modifiers, flags, method) { this.builder = builder; this.GenericMethod = generic; this.parent_method = parent_method; }
public void WrapIntoIterator (IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable) { ParametersBlock pb = new ParametersBlock (this, ParametersCompiled.EmptyReadOnlyParameters, StartLocation); pb.EndLocation = EndLocation; pb.statements = statements; var iterator = new Iterator (pb, method, host, iterator_type, is_enumerable); am_storey = new IteratorStorey (iterator); statements = new List<Statement> (1); AddStatement (new Return (iterator, iterator.Location)); }
// // Our constructor // private Iterator (IMethodData method, TypeContainer host, Type iterator_type, bool is_enumerable) : base ( new ToplevelBlock (method.Block, Parameters.EmptyReadOnlyParameters, method.Block.StartLocation), TypeManager.bool_type, method.Location) { this.OriginalMethod = method; this.OriginalIteratorType = iterator_type; this.IsEnumerable = is_enumerable; this.Host = host; IteratorHost = Block.ChangeToIterator (this, method.Block); }
public static List<string> GetInterfaceSignatureForMethod(IMethodData method) { return new List<string>{ method.FullSignature + ";" }; }
public bool Resolve (FlowBranching parent, BlockContext rc, IMethodData md) { if (resolved) return true; resolved = true; if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= Flags.IsExpressionTree; try { ResolveMeta (rc); using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) { FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent); if (!Resolve (rc)) return false; unreachable = top_level.End (); } } catch (Exception e) { if (e is CompletionResult || rc.Report.IsDisabled) throw; if (rc.CurrentBlock != null) { rc.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message); } else { rc.Report.Error (587, "Internal compiler error: {0}", e.Message); } if (Report.DebugFlags > 0) throw; } if (rc.ReturnType != TypeManager.void_type && !unreachable) { if (rc.CurrentAnonymousMethod == null) { // FIXME: Missing FlowAnalysis for generated iterator MoveNext method if (md is IteratorMethod) { unreachable = true; } else { rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ()); return false; } } else { rc.Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'", rc.CurrentAnonymousMethod.GetSignatureForError ()); return false; } } return true; }
public static List <string> GetInterfaceSignatureForMethod(IMethodData method) { return(new List <string> { method.FullSignature + ";" }); }
public static List<string> GetMockMethod(IMethodData method, string className) { return new List<string> { String.Empty, "public " + method.FullSignature, "{", " return (" + method.ReturnType + ")MockResultSingleton.GetResult(\"" + className + "." + method.MethodName + "\");", "}" }; }
public MethodData (InterfaceMemberBase member, Modifiers modifiers, MethodAttributes flags, IMethodData method) { this.member = member; this.modifiers = modifiers; this.flags = flags; this.method = method; }
public bool ResolveTopBlock (EmitContext anonymous_method_host, ToplevelBlock block, Parameters ip, IMethodData md, out bool unreachable) { if (resolved) { unreachable = this.unreachable; return true; } current_phase = Phase.Resolving; unreachable = false; if (!loc.IsNull) CurrentFile = loc.File; #if PRODUCTION try { #endif if (!block.ResolveMeta (this, ip)) return false; using (this.With (EmitContext.Flags.DoFlowAnalysis, true)) { FlowBranchingToplevel top_level; if (anonymous_method_host != null) top_level = new FlowBranchingToplevel (anonymous_method_host.CurrentBranching, block); else top_level = block.TopLevelBranching; current_flow_branching = top_level; bool ok = block.Resolve (this); current_flow_branching = null; if (!ok) return false; bool flow_unreachable = top_level.End (); if (flow_unreachable) this.unreachable = unreachable = true; } #if PRODUCTION } catch (Exception e) { Console.WriteLine ("Exception caught by the compiler while compiling:"); Console.WriteLine (" Block that caused the problem begin at: " + loc); if (CurrentBlock != null){ Console.WriteLine (" Block being compiled: [{0},{1}]", CurrentBlock.StartLocation, CurrentBlock.EndLocation); } Console.WriteLine (e.GetType ().FullName + ": " + e.Message); throw; } #endif if (return_type != TypeManager.void_type && !unreachable) { if (CurrentAnonymousMethod == null) { Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ()); return false; } else if (!CurrentAnonymousMethod.IsIterator) { Report.Error (1643, CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'", CurrentAnonymousMethod.GetSignatureForError ()); return false; } } resolved = true; return true; }
public static void CreateIterator(IMethodData method, TypeContainer parent, Modifiers modifiers, CompilerContext ctx) { bool is_enumerable; TypeSpec iterator_type; TypeSpec ret = method.ReturnType; if (ret == null) return; if (!CheckType (ret, out iterator_type, out is_enumerable)) { ctx.Report.Error (1624, method.Location, "The body of `{0}' cannot be an iterator block " + "because `{1}' is not an iterator interface type", method.GetSignatureForError (), TypeManager.CSharpName (ret)); return; } ParametersCompiled parameters = method.ParameterInfo; for (int i = 0; i < parameters.Count; i++) { Parameter p = parameters [i]; Parameter.Modifier mod = p.ModFlags; if ((mod & Parameter.Modifier.ISBYREF) != 0) { ctx.Report.Error (1623, p.Location, "Iterators cannot have ref or out parameters"); return; } if (p is ArglistParameter) { ctx.Report.Error (1636, method.Location, "__arglist is not allowed in parameter list of iterators"); return; } if (parameters.Types [i].IsPointer) { ctx.Report.Error (1637, p.Location, "Iterators cannot have unsafe parameters or " + "yield types"); return; } } if ((modifiers & Modifiers.UNSAFE) != 0) { ctx.Report.Error (1629, method.Location, "Unsafe code may not appear in iterators"); return; } // TODO: Ugly leftover new Iterator (ctx, method, parent, iterator_type, is_enumerable); }
private void GetAddedAndRemovedAttributes(IMethodData beforeField, IMethodData afterField) { foreach (var oldAttribute in beforeField.AttributeData) { if (afterField.AttributeData.All(x => x.Name != oldAttribute.Name)) { RemovedAttributes.Add(oldAttribute); HasChanged = true; } } foreach (var newAttribute in afterField.AttributeData) { if (beforeField.AttributeData.All(x => x.Name != newAttribute.Name)) { AddedAttributes.Add(newAttribute); HasChanged = true; } } }
public static List<string> GetEmptyMethod(IMethodData method) { return new List<string> { String.Empty, "public " + method.FullSignature, "{", " " + GetValidReturnStatement(method.ReturnType), "}" }; }
public Expression TryInline(ResolveContext rc) { if (!(Expr is Invocation)) { return Expr; } invocation = (Expr as Invocation); if (invocation.MethodGroup.BestCandidate == null) { return Expr; } methodSpec = invocation.MethodGroup.BestCandidate; if (!(methodSpec.MemberDefinition is MethodCore)) { return Expr; } method = methodSpec.MemberDefinition as MemberCore; methodData = method as IMethodData; if (methodData.IsInlinable) { return Expr; } TypeSpec returnType = methodData.ReturnType; ToplevelBlock block = methodData.Block; if (block.Parameters.Count > 0 || block.TopBlock.NamesCount > 0 && block.TopBlock.LabelsCount > 0) { return Expr; } if (returnType != rc.BuiltinTypes.Void && block.Statements.Count == 1 && block.Statements [0] is Return) { inlineExpr = ((Return)block.Statements [0]).Expr.Clone (new CloneContext()); } else if (returnType == rc.BuiltinTypes.Void) { Block newBlock = new Block (rc.CurrentBlock, block.StartLocation, block.EndLocation); foreach (var st in block.Statements) { newBlock.AddStatement (st.Clone (new CloneContext())); } // inlineExpr = newBlock; } this.rc = rc; this.inlineFailed = false; Expression ret; inlineExpr.Accept (this); ret = inlineExpr; if (inlineFailed) { return Expr; } return ret; }
public bool Resolve (FlowBranching parent, BlockContext rc, ParametersCompiled ip, IMethodData md) { if (resolved) return true; resolved = true; try { if (!ResolveMeta (rc, ip)) return false; using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) { FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent); if (!Resolve (rc)) return false; unreachable = top_level.End (); } } catch (Exception) { #if PRODUCTION if (rc.CurrentBlock != null) { ec.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: Phase Resolve"); } else { ec.Report.Error (587, "Internal compiler error: Phase Resolve"); } #endif throw; } if (rc.ReturnType != TypeManager.void_type && !unreachable) { if (rc.CurrentAnonymousMethod == null) { rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ()); return false; } else if (!rc.CurrentAnonymousMethod.IsIterator) { rc.Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'", rc.CurrentAnonymousMethod.GetSignatureForError ()); return false; } } return true; }
public Expression TryInline(ResolveContext rc) { if (!(Expr is Invocation)) { return(Expr); } invocation = (Expr as Invocation); if (invocation.MethodGroup.BestCandidate == null) { return(Expr); } methodSpec = invocation.MethodGroup.BestCandidate; if (!(methodSpec.MemberDefinition is MethodCore)) { return(Expr); } method = methodSpec.MemberDefinition as MemberCore; methodData = method as IMethodData; if (methodData.IsInlinable) { return(Expr); } TypeSpec returnType = methodData.ReturnType; ToplevelBlock block = methodData.Block; if (block.Parameters.Count > 0 || block.TopBlock.NamesCount > 0 && block.TopBlock.LabelsCount > 0) { return(Expr); } if (returnType != rc.BuiltinTypes.Void && block.Statements.Count == 1 && block.Statements [0] is Return) { inlineExpr = ((Return)block.Statements [0]).Expr.Clone(new CloneContext()); } else if (returnType == rc.BuiltinTypes.Void) { Block newBlock = new Block(rc.CurrentBlock, block.StartLocation, block.EndLocation); foreach (var st in block.Statements) { newBlock.AddStatement(st.Clone(new CloneContext())); } // inlineExpr = newBlock; } this.rc = rc; this.inlineFailed = false; Expression ret; inlineExpr.Accept(this); ret = inlineExpr; if (inlineFailed) { return(Expr); } return(ret); }
/// <remarks> /// If a method in Type `t' (or null to look in all interfaces /// and the base abstract class) with name `Name', return type `ret_type' and /// arguments `args' implements an interface, this method will /// return the MethodInfo that this method implements. /// /// If `name' is null, we operate solely on the method's signature. This is for /// instance used when implementing indexers. /// /// The `Operation op' controls whether to lookup, clear the pending bit, or clear /// all the methods with the given signature. /// /// The `MethodInfo need_proxy' is used when we're implementing an interface's /// indexer in a class. If the new indexer's IndexerName does not match the one /// that was used in the interface, then we always need to create a proxy for it. /// /// </remarks> public MethodInfo InterfaceMethod(string name, Type iType, MethodData method, Operation op) { if (pending_implementations == null) { return(null); } Type ret_type = method.method.ReturnType; Parameters args = method.method.ParameterInfo; int arg_len = args.Count; bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod; foreach (TypeAndMethods tm in pending_implementations) { if (!(iType == null || tm.type == iType)) { continue; } int method_count = tm.methods.Length; MethodInfo m; for (int i = 0; i < method_count; i++) { m = tm.methods [i]; if (m == null) { continue; } // // Check if we have the same parameters // if (tm.args [i] == null && arg_len != 0) { continue; } if (tm.args [i] != null && tm.args [i].Length != arg_len) { continue; } string mname = TypeManager.GetMethodName(m); // // `need_proxy' is not null when we're implementing an // interface indexer and this is Clear(One/All) operation. // // If `name' is null, then we do a match solely based on the // signature and not on the name (this is done in the Lookup // for an interface indexer). // if (is_indexer) { IMethodData md = TypeManager.GetMethod(m); if (md != null) { if (!(md is Indexer.SetIndexerMethod || md is Indexer.GetIndexerMethod)) { continue; } } else { if (TypeManager.GetPropertyFromAccessor(m) == null) { continue; } } } else if (name != mname) { continue; } int j; for (j = 0; j < arg_len; j++) { if (!TypeManager.IsEqual(tm.args [i][j], args.Types [j])) { break; } if (tm.mods [i][j] == args.FixedParameters [j].ModFlags) { continue; } // The modifiers are different, but if one of them // is a PARAMS modifier, and the other isn't, ignore // the difference. if (tm.mods [i][j] != Parameter.Modifier.PARAMS && args.FixedParameters [j].ModFlags != Parameter.Modifier.PARAMS) { break; } } if (j != arg_len) { continue; } if (op != Operation.Lookup) { // If `t != null', then this is an explicitly interface // implementation and we can always clear the method. // `need_proxy' is not null if we're implementing an // interface indexer. In this case, we need to create // a proxy if the implementation's IndexerName doesn't // match the IndexerName in the interface. if (iType == null && name != mname) { tm.need_proxy [i] = method.MethodBuilder; } else { tm.methods [i] = null; } } else { tm.found [i] = method; } Type rt = TypeManager.TypeToCoreType(m.ReturnType); if (!TypeManager.IsEqual(ret_type, rt) && !(ret_type == null && rt == TypeManager.void_type) && !(rt == null && ret_type == TypeManager.void_type)) { continue; } // // Lookups and ClearOne return // if (op != Operation.ClearAll) { return(m); } } // If a specific type was requested, we can stop now. if (tm.type == iType) { return(null); } } return(null); }
public MethodData (InterfaceMemberBase member, Modifiers modifiers, MethodAttributes flags, IMethodData method, MethodSpec parent_method) : this (member, modifiers, flags, method) { this.parent_method = parent_method; }
// // Here until we can fix the problem with Mono.CSharp.Switch, which // currently can not cope with ig == null during resolve (which must // be fixed for switch statements to work on anonymous methods). // public void EmitTopBlock (IMethodData md, ToplevelBlock block) { if (block == null) return; bool unreachable; if (ResolveTopBlock (null, block, md.ParameterInfo, md, out unreachable)){ if (Report.Errors > 0) return; EmitMeta (block); current_phase = Phase.Emitting; #if PRODUCTION try { #endif EmitResolvedTopBlock (block, unreachable); #if PRODUCTION } catch (Exception e){ Console.WriteLine ("Exception caught by the compiler while emitting:"); Console.WriteLine (" Block that caused the problem begin at: " + block.loc); Console.WriteLine (e.GetType ().FullName + ": " + e.Message); throw; } #endif } }