private static void ReportBadNotNullMemberIfNeeded( TypeSymbol type, DecodeWellKnownAttributeArguments < AttributeSyntax, CSharpAttributeData, AttributeLocation > arguments, string memberName ) { foreach (Symbol foundMember in type.GetMembers(memberName)) { if (foundMember.Kind == SymbolKind.Field || foundMember.Kind == SymbolKind.Property) { return; } } Debug.Assert(arguments.AttributeSyntaxOpt is object); ((BindingDiagnosticBag)arguments.Diagnostics).Add( ErrorCode.WRN_MemberNotNullBadMember, arguments.AttributeSyntaxOpt.Location, memberName ); }
private MethodSymbol DelegateConstructor(SyntaxNode syntax, TypeSymbol delegateType) { foreach (var possibleCtor in delegateType.GetMembers(WellKnownMemberNames.InstanceConstructorName)) { var m = possibleCtor as MethodSymbol; if ((object)m == null) { continue; } var parameters = m.Parameters; if (parameters.Length != 2) { continue; } if (parameters[0].Type.SpecialType != SpecialType.System_Object) { continue; } var p1t = parameters[1].Type.SpecialType; if (p1t == SpecialType.System_IntPtr || p1t == SpecialType.System_UIntPtr) { return(m); } } // The delegate '{0}' does not have a valid constructor _diagnostics.Add(ErrorCode.ERR_BadDelegateConstructor, syntax.Location, delegateType); return(null); }
private static FieldSymbol FindFieldBySignature( TypeSymbol targetTypeSymbol, string targetMemberName, ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers, TypeSymbol type ) { foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName)) { var field = member as FieldSymbol; TypeWithAnnotations fieldType; if ( (object)field != null && TypeSymbol.Equals( (fieldType = field.TypeWithAnnotations).Type, type, TypeCompareKind.CLRSignatureCompareOptions ) && CustomModifiersMatch(fieldType.CustomModifiers, customModifiers) ) { // Behavior in the face of multiple matching signatures is // implementation defined - we'll just pick the first one. return(field); } } return(null); }
private static MethodSymbol FindMethodBySignature( TypeSymbol targetTypeSymbol, string targetMemberName, SignatureHeader targetMemberSignatureHeader, int targetMemberTypeParamCount, ParamInfo <TypeSymbol>[] targetParamInfo ) { foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName)) { var method = member as MethodSymbol; if ( (object)method != null && ((byte)method.CallingConvention == targetMemberSignatureHeader.RawValue) && (targetMemberTypeParamCount == method.Arity) && MethodSymbolMatchesParamInfo(method, targetParamInfo) ) { // Behavior in the face of multiple matching signatures is // implementation defined - we'll just pick the first one. return(method); } } return(null); }
public void CheckTypes(TypeSymbol a, TypeSymbol b) { Assert.Equal(a.Name, b.Name); CheckSymbols(a.BaseType(), b.BaseType(), false); CheckSymbols(a.Interfaces(), b.Interfaces(), false); CheckSymbols(a.GetMembers(), b.GetMembers(), true); }
public override OutputFileAbstraction GetAbstraction() { //If external if (this.HasCustomMap) { return(null); } var result = new EnumAbstraction { Path = AbstractPath, Name = TypeSymbol.Name, Values = TypeSymbol .GetMembers() .Where(m => m.Kind == SymbolKind.Field) .Select(m => m as IFieldSymbol) .Select(f => new EnumValueAbstraction { Name = f.Name, Value = (int)f.ConstantValue }).ToList() }; return(result); }
private MethodSymbol FindMethod(TypeSymbol receiver, string name, ImmutableArray <TypeSymbol> typeArgs, ImmutableArray <BoundExpression> args) { MethodSymbol found = null; bool ambiguous = false; ImmutableArray <Symbol> candidates = receiver.GetMembers(name); foreach (var candidate in candidates) { var method = candidate as MethodSymbol; if ((object)method == null || method.Arity != typeArgs.Length || method.ParameterCount != args.Length) { continue; } if (method.Arity != 0) { method = method.Construct(typeArgs); } var parameters = method.Parameters; bool exact = true; for (int i = 0; i < args.Length; i++) { HashSet <DiagnosticInfo> useSiteDiagnostics = null; if (parameters[i].RefKind != RefKind.None || !((object)args[i].Type == null && parameters[i].Type.IsReferenceType || Compilation.Conversions.ClassifyConversion(args[i].Type, parameters[i].Type, ref useSiteDiagnostics).IsImplicit)) { Debug.Assert(useSiteDiagnostics.IsNullOrEmpty()); goto nextCandidate; } Debug.Assert(useSiteDiagnostics.IsNullOrEmpty()); exact = exact && args[i].Type == parameters[i].Type; } if (exact) { return(method); } if ((object)found != null) { ambiguous = true; } found = method; nextCandidate :; } if (ambiguous) { ReportLibraryProblem(ErrorCode.ERR_LibraryMethodNotUnique, receiver, name, typeArgs, args); } else if ((object)found == null) { ReportLibraryProblem(ErrorCode.ERR_LibraryMethodNotFound, receiver, name, typeArgs, args); } return(found); }
private static MethodSymbol GetRequiredMethod(TypeSymbol type, string methodName, DiagnosticBag diagnostics) { var method = type.GetMembers(methodName).SingleOrDefault() as MethodSymbol; if ((object)method == null) { diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, NoLocation.Singleton, type, methodName); } return method; }
/// <summary> /// Descends through Rest fields of a tuple if "symbol" is an extended field /// As a result the "symbol" will be adjusted to be the field of the innermost tuple /// and a corresponding containingSlot is returned. /// Return value -1 indicates a failure which could happen for the following reasons /// a) Rest field does not exist, which could happen in rare error scenarios involving broken ValueTuple types /// b) Rest is not tracked already and forceSlotsToExist is false (otherwise we create slots on demand) /// </summary> private int DescendThroughTupleRestFields( ref Symbol symbol, int containingSlot, bool forceContainingSlotsToExist ) { if (symbol is TupleElementFieldSymbol fieldSymbol) { TypeSymbol containingType = symbol.ContainingType; // for tuple fields the variable identifier represents the underlying field symbol = fieldSymbol.TupleUnderlyingField; // descend through Rest fields // force corresponding slots if do not exist while ( !TypeSymbol.Equals( containingType, symbol.ContainingType, TypeCompareKind.ConsiderEverything ) ) { var restField = containingType .GetMembers(NamedTypeSymbol.ValueTupleRestFieldName) .FirstOrDefault() as FieldSymbol; if (restField is null) { return(-1); } if (forceContainingSlotsToExist) { containingSlot = GetOrCreateSlot(restField, containingSlot); } else { if ( !TryGetVariable( new VariableIdentifier(restField, containingSlot), out containingSlot ) ) { return(-1); } } containingType = restField.Type; } } return(containingSlot); }
static bool IsAPairValue(TypeSymbol type, out Symbol key, out Symbol value) { key = value = default; if (type.IsValueType) { if (type.Name == "ValueTuple" && ((NamedTypeSymbol)type).Arity == 2) { key = type.GetMembers("Item1").Single(); value = type.GetMembers("Item2").Single(); } else if (type.Name == "KeyValuePair" && ((NamedTypeSymbol)type).Arity == 2) { key = type.GetMembers("Key").Single(); value = type.GetMembers("Value").Single(); } } // return(key != null && value != null);; }
private MethodSymbol getExplicitOperator(TypeSymbol srcType, TypeSymbol destType) { var members = srcType.GetMembers("op_Explicit"); foreach (MethodSymbol m in members) { if (m.ReturnType == destType) { return(m); } } return(null); }
public static bool HasMembers(this TypeSymbol type, string name) { TypeSymbol sym; sym = type; while (sym != null) { if (sym.GetMembers(name).Length > 0) { return(true); } sym = sym.BaseTypeNoUseSiteDiagnostics; } return(false); }
public override (string file, string content)? GenerateOutput() { //If external if (this.HasCustomMap) { return(null); } var subClasses = new List <INamedTypeSymbol>(); var sb = new StringBuilder(); var level = 0; //var hasModule = false; //if (!string.IsNullOrEmpty(Module) && Options.TypingsScope == TypingsScope.Global) { // hasModule = true; // sb.AppendLine($"declare module {Module} {{"); // level++; //} //var declaration = "declare "; //if (hasModule) { declaration = ""; } //if(Options.TypingsScope == TypingsScope.Module) { // declaration = "export "; //} //sb.AppendLine(level, $"export const enum {TypeSymbol.Name} {{"); sb.AppendLine(level, $"export enum {TypeSymbol.Name} {{"); foreach (var m in TypeSymbol.GetMembers()) { if (m.Kind == SymbolKind.Field) { var f = m as IFieldSymbol; sb.AppendLine(level + 1, $"{f.Name} = {f.ConstantValue},"); } } sb.AppendLine(level, "}"); //if (!string.IsNullOrEmpty(Module) && Options.TypingsScope == TypingsScope.Global) { // sb.AppendLine("}"); //} AppendKeysAndNames(sb); //File.WriteAllText(FileHelper.PathCombine(Options.ModelsDir, Filename), sb.ToString()); //string file = FileHelper.PathCombine(Options.TypingsDir, Filename); string content = sb.ToString(); return(OutputFilePath, content); //await FileHelper.WriteAsync(file, content); //return file; }
/// <summary> /// Builds a layout for a given type. /// First traverses all base types and builds their layouts when needed since the base type layouts inform the layout of derived types. /// </summary> private void BuildLayout(TypeSymbol typeSymbol, AbstractPhaseContext context) { Stack <TypeSymbol> typesToBuild = new Stack <TypeSymbol>(); while (typeSymbol.BaseType != null && !_builtLayouts.ContainsKey(typeSymbol)) { typesToBuild.Push(typeSymbol); if (typeSymbol == _udonSharpBehaviourType) { break; } typeSymbol = typeSymbol.BaseType; } while (typesToBuild.Count > 0) { TypeSymbol currentBuildType = typesToBuild.Pop(); Dictionary <string, int> idCounters; if (currentBuildType.BaseType != null && _builtLayouts.TryGetValue(currentBuildType.BaseType, out TypeLayout parentLayout)) { idCounters = new Dictionary <string, int>(parentLayout.SymbolCounters); } else { idCounters = new Dictionary <string, int>(); } Dictionary <MethodSymbol, MethodExportLayout> layouts = new Dictionary <MethodSymbol, MethodExportLayout>(); foreach (Symbol symbol in currentBuildType.GetMembers(context)) { if (symbol is MethodSymbol methodSymbol && (methodSymbol.OverridenMethod == null || methodSymbol.OverridenMethod.ContainingType == _udonSharpBehaviourType || methodSymbol.OverridenMethod.ContainingType.IsExtern)) { layouts.Add(methodSymbol, BuildMethodLayout(methodSymbol, idCounters)); } } _builtLayouts.Add(currentBuildType, new TypeLayout(layouts, idCounters)); } }
private MetadataReference GenerateShallowReference() { ShallowCompilation = CSharpCompilation.Create( assemblyName: AssemblyName, options: Worker.OriginalCompilation.Options, references: Worker.OriginalCompilation.References); foreach (var other in Requires) { if (other.Value == AssemblyNeutralWorker.OrderingState.StrengthKind.DeepUsage) { ShallowCompilation = ShallowCompilation.AddReferences(other.Key.RealOrShallowReference()); } } foreach (var syntaxReference in TypeSymbol.DeclaringSyntaxReferences) { var node = syntaxReference.GetSyntax(); var tree = syntaxReference.SyntaxTree; var root = tree.GetRoot(); var nodesToRemove = GetNodesToRemove(root, node); foreach (var member in TypeSymbol.GetMembers()) { foreach (var memberSyntaxReference in member.DeclaringSyntaxReferences) { if (memberSyntaxReference.SyntaxTree == tree) { nodesToRemove = nodesToRemove.Concat(new[] { memberSyntaxReference.GetSyntax() }); } } } var newRoot = root.RemoveNodes(nodesToRemove.ToArray(), SyntaxRemoveOptions.KeepDirectives); var newTree = SyntaxFactory.SyntaxTree(newRoot, options: tree.Options, path: tree.FilePath, encoding: Encoding.UTF8); ShallowCompilation = ShallowCompilation.AddSyntaxTrees(newTree); } ShallowOutputStream = new MemoryStream(); ShallowEmitResult = ShallowCompilation.Emit(ShallowOutputStream); ShallowOutputStream.Position = 0; ShallowReference = new MetadataImageReference(ShallowOutputStream); ShallowOutputStream.Position = 0; return(ShallowReference); }
private static FieldSymbol FindFieldBySignature(TypeSymbol targetTypeSymbol, string targetMemberName, ImmutableArray <ModifierInfo> customModifiers, TypeSymbol type) { foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName)) { var field = member as FieldSymbol; if ((object)field != null && field.Type == type && CustomModifiersMatch(field.CustomModifiers, customModifiers)) { // Behavior in the face of multiple matching signatures is // implementation defined - we'll just pick the first one. return(field); } } return(null); }
/// <summary> /// Gets the most derived method of a given method symbol in the current emit type's context. /// </summary> /// <param name="methodSymbol"></param> /// <returns></returns> private MethodSymbol GetMostDerivedMethod(MethodSymbol methodSymbol) { if (!methodSymbol.HasOverrides) { return(methodSymbol); } TypeSymbol currentSearchType = EmitType; MethodSymbol derivedSymbol = null; while (currentSearchType != null) { foreach (var symbol in currentSearchType.GetMembers <MethodSymbol>(methodSymbol.Name, this)) { if (symbol.Parameters.Length != methodSymbol.Parameters.Length) // early out when the method obviously doesn't overload this { continue; } MethodSymbol currentMethod = symbol; while (currentMethod != null && currentMethod != methodSymbol) { currentMethod = currentMethod.OverridenMethod; } if (currentMethod == methodSymbol) { derivedSymbol = symbol; break; } } if (derivedSymbol != null) { break; } currentSearchType = currentSearchType.BaseType; } return(derivedSymbol); }
private static bool TryCreateInstantiationInvocation(AbstractPhaseContext context, SyntaxNode node, MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions, out BoundInvocationExpression createdInvocation) { switch (symbol.Name) { case "Instantiate_Extern" when symbol.ContainingType == context.GetTypeSymbol(typeof(InstantiationShim)): createdInvocation = new BoundExternInvocation(node, context, new ExternSynthesizedMethodSymbol(context, "VRCInstantiate.__Instantiate__UnityEngineGameObject__UnityEngineGameObject", parameterExpressions.Select(e => e.ValueType).ToArray(), context.GetTypeSymbol(typeof(GameObject)), true), instanceExpression, parameterExpressions); return(true); case "VRCInstantiate" when symbol.ContainingType == context.GetTypeSymbol(typeof(UdonSharpBehaviour)): // Backwards compatibility for UdonSharpBehaviour.VRCInstantiate case "Instantiate" when symbol.ContainingType == context.GetTypeSymbol(typeof(UnityEngine.Object)): { if (symbol.Name != "VRCInstantiate" && (symbol.TypeArguments.Length != 1 || symbol.TypeArguments[0] != context.GetTypeSymbol(typeof(GameObject)))) { throw new NotSupportedException("Udon does not support instantiating non-GameObject types"); } TypeSymbol instantiateShim = context.GetTypeSymbol(typeof(InstantiationShim)); MethodSymbol instantiateMethod = instantiateShim.GetMembers <MethodSymbol>("Instantiate", context) .First(e => e.Parameters .Select(p => p.Type) .SequenceEqual(parameterExpressions .Select(p => p.ValueType))); context.MarkSymbolReferenced(instantiateMethod); createdInvocation = new BoundStaticUserMethodInvocation(node, instantiateMethod, parameterExpressions); return(true); } } createdInvocation = null; return(false); }
public void SymbolUsage(Action <ISymbol> shallowUsage, Action <ISymbol> deepUsage) { DoTypeSymbol(deepUsage, TypeSymbol.BaseType); foreach (var symbol in TypeSymbol.AllInterfaces) { DoTypeSymbol(deepUsage, symbol); } AttributeDataSymbolUsage(TypeSymbol.GetAttributes(), deepUsage); foreach (var member in TypeSymbol.GetMembers()) { AttributeDataSymbolUsage(member.GetAttributes(), deepUsage); var propertyMember = member as IPropertySymbol; var fieldMember = member as IFieldSymbol; var methodMember = member as IMethodSymbol; if (propertyMember != null) { DoTypeSymbol(shallowUsage, propertyMember.Type); } if (fieldMember != null) { DoTypeSymbol(shallowUsage, fieldMember.Type); } if (methodMember != null) { DoTypeSymbol(shallowUsage, methodMember.ReturnType); AttributeDataSymbolUsage(methodMember.GetReturnTypeAttributes(), deepUsage); foreach (var parameter in methodMember.Parameters) { DoTypeSymbol(shallowUsage, parameter.Type); AttributeDataSymbolUsage(parameter.GetAttributes(), deepUsage); } } } }
/// <summary> /// Descends through Rest fields of a tuple if "symbol" is an extended field /// As a result the "symbol" will be adjusted to be the field of the innermost tuple /// and a corresponding containingSlot is returned. /// Return value -1 indicates a failure which could happen for the following reasons /// a) Rest field does not exist, which could happen in rare error scenarios involving broken ValueTuple types /// b) Rest is not tracked already and forceSlotsToExist is false (otherwise we create slots on demand) /// </summary> private int DescendThroughTupleRestFields(ref Symbol symbol, int containingSlot, bool forceContainingSlotsToExist) { var fieldSymbol = symbol as TupleFieldSymbol; if ((object)fieldSymbol != null) { TypeSymbol containingType = ((TupleTypeSymbol)symbol.ContainingType).UnderlyingNamedType; // for tuple fields the variable identifier represents the underlying field symbol = fieldSymbol.TupleUnderlyingField; // descend through Rest fields // force corresponding slots if do not exist while (containingType != symbol.ContainingType) { var restField = containingType.GetMembers(TupleTypeSymbol.RestFieldName).FirstOrDefault() as FieldSymbol; if ((object)restField == null) { return(-1); } if (forceContainingSlotsToExist) { containingSlot = GetOrCreateSlot(restField, containingSlot); } else { if (!_variableSlot.TryGetValue(new VariableIdentifier(restField, containingSlot), out containingSlot)) { return(-1); } } containingType = restField.Type.TypeSymbol.TupleUnderlyingTypeOrSelf(); } } return(containingSlot); }
/// <summary> /// Might the given type be, or contain, managed references? This is used to determine which /// fields allocated to temporaries should be cleared when the underlying variable goes out of scope, so /// that they do not cause unnecessary object retention. /// </summary> private bool MightContainReferences(TypeSymbol type) { if (type.IsReferenceType || type.TypeKind == TypeKind.TypeParameter) { return(true); // type parameter or reference type } if (type.TypeKind != TypeKind.Struct) { return(false); // enums, etc } if (type.SpecialType == SpecialType.System_TypedReference) { return(true); } if (type.SpecialType != SpecialType.None) { return(false); // int, etc } CSharpCompilation Compilation = this.CompilationState.ModuleBuilderOpt.Compilation; if (type.DeclaringCompilation != Compilation) { return(true); // perhaps from ref assembly } if (emptyStructTypeCache.IsEmptyStructType(type)) { return(false); } foreach (var f in type.GetMembers()) { if (f.Kind == SymbolKind.Field && !f.IsStatic && MightContainReferences(((FieldSymbol)f).Type)) { return(true); } } return(false); }
private static bool ClearGlobals(CSharpCompilation compilation, SyntaxNode node, TypeSymbol functionClass, List <BoundStatement> statements) { var members = functionClass.GetMembers(); bool added = false; foreach (var member in members) { if (member.IsStatic && member.Kind == SymbolKind.Field) { var field = member as FieldSymbol; var fldtype = field.Type; if (field.DeclaredAccessibility == Accessibility.Public && fldtype.TypeKind == TypeKind.Class && !field.IsReadOnly && !field.IsConst ) { statements.Add(ClearGlobal(compilation, node, field)); added = true; } } } return(added); }
// Does a member lookup in a single type, without considering inheritance. private LookupResult MemberLookupWithoutInheritance(TypeSymbol type, string name, int arity, bool invoked) { LookupResult result = new LookupResult(); IEnumerable <Symbol> members = type.GetMembers(name); foreach (Symbol member in members) { LookupResult resultOfThisMember; // Do we need to exclude override members, or is that done later by overload resolution. It seems like // not excluding them here can't lead to problems, because we will always find the overridden method as well. SymbolKind memberKind = member.Kind; DiagnosticInfo diagInfo; if (WrongArity(member, arity, out diagInfo)) { resultOfThisMember = LookupResult.WrongArity(member, diagInfo); } else if (invoked && !IsInvocable(member)) { resultOfThisMember = LookupResult.Bad(member, new CSDiagnosticInfo(ErrorCode.ERR_NonInvocableMemberCalled, member.GetFullName())); } else if (!IsMemberAccessible(member)) { resultOfThisMember = LookupResult.Inaccessible(member); } else { resultOfThisMember = LookupResult.Good(member); } result = MergeLookupsInSameScope(result, resultOfThisMember); } return(result); }
public OutputFileAbstraction GetAbstraction() { var context = new ResolutionContext(this); var serviceAbstraction = new ServiceAbstraction(); serviceAbstraction.Path = AbstractPath; serviceAbstraction.ClassName = ClassName; serviceAbstraction.ControllerName = TypeSymbol.Name; serviceAbstraction.Actions = new List <ActionAbstraction>(); //Resolve endpoint var routeAttr = TypeSymbol.GetAttributes().FirstOrDefault(a => a.AttributeClass.Name == "Route" || a.AttributeClass.Name.ToString() == "RoutePrefix"); var arg = (routeAttr.ApplicationSyntaxReference.GetSyntax() as AttributeSyntax).ArgumentList.Arguments[0].ToString().Replace("\"", ""); var path = arg.Replace("[controller]", ControllerName.ToCamelCase()); serviceAbstraction.Endpoint = path; //Actions var existingMethods = new Dictionary <string, int>(); foreach (var m in TypeSymbol.GetMembers()) { if (m.Kind == SymbolKind.NamedType) { continue; } if (m.DeclaredAccessibility != Accessibility.Public) { continue; } if (m.IsStatic) { continue; } if (m.Kind != SymbolKind.Method) { continue; } if (m.IsImplicitlyDeclared) { continue; } if (!m.IsDefinition) { continue; } var mtd = m as IMethodSymbol; if (m.Name == ".ctor") { continue; } var actionAbstraction = new ActionAbstraction(); serviceAbstraction.Actions.Add(actionAbstraction); var mtdAttrs = mtd.GetAttributes(); var returnType = TypeResolver.Resolve(mtd.ReturnType as ITypeSymbol, context); var returnTypeName = returnType.Declaration; //Not marked actions will accept posts var httpMethod = "Post"; string action = ""; //Get http method from method name pattern if (mtd.Name.StartsWith("Get")) { httpMethod = "Get"; } if (mtd.Name.StartsWith("Post")) { httpMethod = "Post"; } if (mtd.Name.StartsWith("Put")) { httpMethod = "Put"; } if (mtd.Name.StartsWith("Delete")) { httpMethod = "Delete"; } if (mtd.Name.StartsWith("Patch")) { httpMethod = "Patch"; } var methodName = mtd.Name.ToCamelCase(); if (existingMethods.ContainsKey(methodName)) { existingMethods[methodName]++; methodName = $"{methodName}_{existingMethods[methodName]}"; } else { existingMethods.Add(methodName, 0); } actionAbstraction.FunctionName = methodName; var httpAttr = mtdAttrs.FirstOrDefault(a => a.AttributeClass.Name.StartsWith("Http")); var routeMethodAttr = mtdAttrs.FirstOrDefault(a => a.AttributeClass.Name.StartsWith("Route")); //If has Http attribute if (httpAttr != null) { httpMethod = httpAttr.AttributeClass.Name.Substring(4); //Check if it contains route info var args = (httpAttr.ApplicationSyntaxReference.GetSyntax() as AttributeSyntax)?.ArgumentList?.Arguments; if (args != null && args.Value.Count > 0) { action = args.Value[0].ToString().Replace("\"", ""); } } //Check if contains route attr if (routeMethodAttr != null) { var args = (routeMethodAttr.ApplicationSyntaxReference.GetSyntax() as AttributeSyntax).ArgumentList.Arguments; if (args.Count > 0) { action = args[0].ToString().Replace("\"", ""); } } //Replace route variables action = action.Replace("[action]", methodName); var regex = new Regex(@"\{(?<paramName>\w+)(:\w+(\(.*?\))?)?\??}"); action = regex.Replace(action, match => { return($"${{{match.Groups["paramName"].Value}}}"); }); //Resolve how parameters are sent var pendingParameters = new List <ParameterResolution>(); var parameterResolutions = mtd.Parameters.Select(p => new ParameterResolution(p, TypeResolver, context, Options)).Where(p => !p.Ignore); foreach (var pr in parameterResolutions) { //[FromRoute] if (action.Contains($"{{{pr.Name}}}")) { //Casting to any because encodeURIComponent expects string action = action.Replace($"{{{pr.Name}}}", $"{{encodeURIComponent(<any>{pr.Name})}}"); continue; } //[FromBody] if (pr.From == ParameterFromKind.FromBody) { actionAbstraction.BodyParameterName = pr.Name; continue; } pendingParameters.Add(pr); } var strParameters = string.Join(", ", parameterResolutions.Select(pr => pr.Signature)); actionAbstraction.Parameters = parameterResolutions.Select(p => new ParameterAbstraction { Name = p.Name, IsOptional = p.IsOptional, //TypeDescription = p.TypeDescription Type = p.Type }).ToList(); actionAbstraction.ReturnType = returnType; //action actionAbstraction.ActionName = action; //httpMethod actionAbstraction.HttpMethod = httpMethod; actionAbstraction.SearchParametersNames = new List <string>(); //Body switch (httpMethod) { case "Put": case "Patch": case "Post": break; default: actionAbstraction.BodyParameterName = null; break; } //Search actionAbstraction.SearchParametersNames = pendingParameters.Select(pr => pr.Name).ToList(); } serviceAbstraction.Imports = context.GetImports(); return(serviceAbstraction); }
/// <summary> /// Might the given type be, or contain, managed references? This is used to determine which /// fields allocated to temporaries should be cleared when the underlying variable goes out of scope, so /// that they do not cause unnecessary object retention. /// </summary> /// <param name="type"></param> /// <returns></returns> private bool MightContainReferences(TypeSymbol type) { if (type.IsReferenceType || type.TypeKind == TypeKind.TypeParameter) return true; // type parameter or reference type if (type.TypeKind != TypeKind.Struct) return false; // enums, etc if (type.SpecialType == SpecialType.System_TypedReference) return true; if (type.SpecialType != SpecialType.None) return false; // int, etc CSharpCompilation Compilation = this.CompilationState.ModuleBuilderOpt.Compilation; if (type.DeclaringCompilation != Compilation) return true; // perhaps from ref assembly if (emptyStructTypeCache.IsEmptyStructType(type)) return false; foreach (var f in type.GetMembers()) { if (f.Kind == SymbolKind.Field && !f.IsStatic && MightContainReferences(((FieldSymbol)f).Type)) return true; } return false; }
public static BoundStatement RewriteAppExit( MethodSymbol method, BoundStatement statement, DiagnosticBag diagnostics) { if (method.Name != XSharpSpecialNames.AppExit) { return(statement); } var refMan = method.DeclaringCompilation.GetBoundReferenceManager(); var vcla = method.DeclaringCompilation.ClassLibraryType(); var newstatements = new List <BoundStatement>(); foreach (var rkv in refMan.GetReferencedAssemblies()) { var r = rkv.Value; foreach (var attr in r.GetAttributes()) { if ((Symbol)attr.AttributeClass.ConstructedFrom == vcla) { var attargs = attr.CommonConstructorArguments; if (attargs.Length == 2) { var functionsClassName = attargs[0].Value.ToString(); if (!string.IsNullOrEmpty(functionsClassName)) { TypeSymbol type = r.GetTypeByMetadataName(functionsClassName) as TypeSymbol; // If we can find the $Exit method then call that method // Otherwise find the public globals and clear them from our code if (type != null) { var members = type.GetMembers(XSharpSpecialNames.ExitProc); if (members.Length > 0) { foreach (MethodSymbol sym in members) { CreateMethodCall(method.DeclaringCompilation, statement.Syntax, sym, newstatements); } } else { ClearGlobals(method.DeclaringCompilation, statement.Syntax, type, newstatements); } } } } break; } } } // Now clear the globals in this assembly by calling $Exit var symbols = FindMembers(method.DeclaringCompilation, XSharpSpecialNames.ExitProc); foreach (MethodSymbol sym in symbols) { CreateMethodCall(method.DeclaringCompilation, statement.Syntax, sym, newstatements); } newstatements.Add(new BoundReturnStatement(statement.Syntax, RefKind.None, null)); var oldbody = statement as BoundBlock; var newbody = oldbody.Update(oldbody.Locals, ImmutableArray <LocalFunctionSymbol> .Empty, newstatements.ToImmutableArray <BoundStatement>()); return(newbody); }
private MethodSymbol FindMethod(TypeSymbol receiver, string name, ImmutableArray<TypeSymbol> typeArgs, ImmutableArray<BoundExpression> args) { MethodSymbol found = null; bool ambiguous = false; ImmutableArray<Symbol> candidates = receiver.GetMembers(name); foreach (var candidate in candidates) { var method = candidate as MethodSymbol; if ((object)method == null || method.Arity != typeArgs.Length || method.ParameterCount != args.Length) continue; if (method.Arity != 0) method = method.Construct(typeArgs); var parameters = method.Parameters; bool exact = true; for (int i = 0; i < args.Length; i++) { HashSet<DiagnosticInfo> useSiteDiagnostics = null; if (parameters[i].RefKind != RefKind.None || !((object)args[i].Type == null && parameters[i].Type.IsReferenceType || Compilation.Conversions.ClassifyConversion(args[i].Type, parameters[i].Type, ref useSiteDiagnostics).IsImplicit)) { Debug.Assert(useSiteDiagnostics.IsNullOrEmpty()); goto nextCandidate; } Debug.Assert(useSiteDiagnostics.IsNullOrEmpty()); exact = exact && args[i].Type == parameters[i].Type; } if (exact) return method; if ((object)found != null) { ambiguous = true; } found = method; nextCandidate: ; } if (ambiguous) ReportLibraryProblem(ErrorCode.ERR_LibraryMethodNotUnique, receiver, name, typeArgs, args); else if ((object)found == null) ReportLibraryProblem(ErrorCode.ERR_LibraryMethodNotFound, receiver, name, typeArgs, args); return found; }
private static FieldSymbol FindFieldBySignature(TypeSymbol targetTypeSymbol, string targetMemberName, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers, TypeSymbol type) { foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName)) { var field = member as FieldSymbol; if ((object)field != null && field.Type == type && CustomModifiersMatch(field.CustomModifiers, customModifiers)) { // Behavior in the face of multiple matching signatures is // implementation defined - we'll just pick the first one. return field; } } return null; }
private MethodSymbol DelegateConstructor(CSharpSyntaxNode syntax, TypeSymbol delegateType) { foreach (var possibleCtor in delegateType.GetMembers(WellKnownMemberNames.InstanceConstructorName)) { var m = possibleCtor as MethodSymbol; if ((object)m == null) continue; var parameters = m.Parameters; if (parameters.Length != 2) continue; if (parameters[0].Type.SpecialType != SpecialType.System_Object) continue; var p1t = parameters[1].Type.SpecialType; if (p1t == SpecialType.System_IntPtr || p1t == SpecialType.System_UIntPtr) { return m; } } // The delegate '{0}' does not have a valid constructor diagnostics.Add(ErrorCode.ERR_BadDelegateConstructor, syntax.Location, delegateType); return null; }
public override IEnumerable <Symbol> GetMembers() { return(referencedType.GetMembers()); }
// Does a member lookup in a single type, without considering inheritance. private LookupResult MemberLookupWithoutInheritance(TypeSymbol type, string name, int arity, bool invoked) { LookupResult result = new LookupResult(); IEnumerable<Symbol> members = type.GetMembers(name); foreach (Symbol member in members) { LookupResult resultOfThisMember; // Do we need to exclude override members, or is that done later by overload resolution. It seems like // not excluding them here can't lead to problems, because we will always find the overridden method as well. SymbolKind memberKind = member.Kind; DiagnosticInfo diagInfo; if (WrongArity(member, arity, out diagInfo)) resultOfThisMember = LookupResult.WrongArity(member, diagInfo); else if (invoked && !IsInvocable(member)) resultOfThisMember = LookupResult.Bad(member, new CSDiagnosticInfo(ErrorCode.ERR_NonInvocableMemberCalled, member.GetFullName())); else if (!IsMemberAccessible(member)) resultOfThisMember = LookupResult.Inaccessible(member); else resultOfThisMember = LookupResult.Good(member); result = MergeLookupsInSameScope(result, resultOfThisMember); } return result; }
public void Emit() { _returnValue = RootTable.CreateInternalValue(GetTypeSymbol(SpecialType.System_UInt32), "returnJump"); CurrentNode = EmitType.RoslynSymbol.DeclaringSyntaxReferences.First().GetSyntax(); DefaultExecutionOrder executionOrder = EmitType.GetAttribute <DefaultExecutionOrder>(); if (executionOrder != null) { if (executionOrder.order < (int.MinValue + 1000000)) { throw new CompilerException($"Execution orders below int.MinValue + 1000000 are reserved for internal use in U#"); } Module.ExecutionOrder = executionOrder.order; } TypeSymbol udonSharpBehaviourType = GetTypeSymbol(typeof(UdonSharpBehaviour)); Stack <TypeSymbol> emitTypeBases = new Stack <TypeSymbol>(); TypeSymbol currentEmitType = EmitType; while (currentEmitType.BaseType != null) { emitTypeBases.Push(currentEmitType); currentEmitType = currentEmitType.BaseType; if (currentEmitType == udonSharpBehaviourType) { break; } } if (currentEmitType != udonSharpBehaviourType) { throw new NotSupportedException("U# behaviour must inherit from UdonSharpBehaviour", currentEmitType.RoslynSymbol.DeclaringSyntaxReferences.First().GetSyntax().GetLocation()); } List <MethodSymbol> rootMethods = new List <MethodSymbol>(); List <FieldSymbol> userFields = new List <FieldSymbol>(); HashSet <FieldSymbol> visitedFields = new HashSet <FieldSymbol>(); // Visits each base class and searches for the most derived version of a method if it is overriden // The intention with this is to ensure a consistent ordering between all inheritors of a base class // This means that we can know that all inheritors of a class have the same method names and parameter symbol allocations // which allows people to call virtual methods on UdonSharpBehaviours and have Udon just make it work while (emitTypeBases.Count > 0) { TypeSymbol currentBase = emitTypeBases.Pop(); // Make sure fields get emitted foreach (FieldSymbol field in currentBase.GetMembers <FieldSymbol>(this)) { if (field.IsConst) { continue; } if (!visitedFields.Contains(field)) { userFields.Add(field); visitedFields.Add(field); } GetUserValue(field); } foreach (MethodSymbol methodSymbol in currentBase.GetMembers <MethodSymbol>(this)) { if (methodSymbol.RoslynSymbol.IsImplicitlyDeclared || methodSymbol.RoslynSymbol.IsStatic) { continue; } if (methodSymbol.HasOverrides) { MethodSymbol derivedMethod = GetMostDerivedMethod(methodSymbol); if (derivedMethod.RoslynSymbol.IsAbstract) { continue; } if (!rootMethods.Contains(derivedMethod)) { rootMethods.Add(derivedMethod); } } else if (!rootMethods.Contains(methodSymbol)) { if (methodSymbol.RoslynSymbol.IsAbstract) { continue; } rootMethods.Add(methodSymbol); } } } DeclaredFields = userFields.ToImmutableArray(); InitConstFields(); HashSet <MethodSymbol> emittedSet = new HashSet <MethodSymbol>(); HashSet <MethodSymbol> setToEmit = new HashSet <MethodSymbol>(); // Do not roll this into the while loop, the order must be maintained for the root symbols so calls across behaviours work consistently foreach (MethodSymbol methodSymbol in rootMethods) { using (new MethodEmitScope(methodSymbol, this)) { methodSymbol.Emit(this); } emittedSet.Add(methodSymbol); setToEmit.UnionWith(methodSymbol.DirectDependencies.OfType <MethodSymbol>()); } while (setToEmit.Count > 0) { HashSet <MethodSymbol> newEmitSet = new HashSet <MethodSymbol>(); foreach (var methodSymbol in setToEmit) { if (emittedSet.Contains(methodSymbol)) { continue; } if (methodSymbol.RoslynSymbol != null) { if (methodSymbol.RoslynSymbol.IsAbstract || methodSymbol.IsUntypedGenericMethod) { continue; } } if (!methodSymbol.IsStatic && methodSymbol.ContainingType.IsUdonSharpBehaviour) // Prevent other behaviour type's methods from leaking into this type from calls across behaviours { TypeSymbol topType = EmitType; bool foundType = false; while (topType != udonSharpBehaviourType) { if (methodSymbol.ContainingType == topType) { foundType = true; break; } topType = topType.BaseType; } if (!foundType) { continue; } } using (new MethodEmitScope(methodSymbol, this)) { methodSymbol.Emit(this); } emittedSet.Add(methodSymbol); newEmitSet.UnionWith(methodSymbol.DirectDependencies.OfType <MethodSymbol>()); } setToEmit = newEmitSet; } if (_recursiveStackVal != null) { _recursiveStackVal.DefaultValue = new object[_maxRecursiveStackPush]; } DebugInfo.FinalizeAssemblyInfo(); }
private static MethodSymbol FindMethodBySignature(TypeSymbol targetTypeSymbol, string targetMemberName, SignatureHeader targetMemberSignatureHeader, int targetMemberTypeParamCount, ParamInfo<TypeSymbol>[] targetParamInfo) { foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName)) { var method = member as MethodSymbol; if ((object)method != null && ((byte)method.CallingConvention == targetMemberSignatureHeader.RawValue) && (targetMemberTypeParamCount == method.Arity) && MethodSymbolMatchesParamInfo(method, targetParamInfo)) { // Behavior in the face of multiple matching signatures is // implementation defined - we'll just pick the first one. return method; } } return null; }
IEnumerable <Cci.MethodImplementation> Cci.ITypeDefinition.GetExplicitImplementationOverrides(EmitContext context) { CheckDefinitionInvariant(); if (this.IsInterface) { yield break; } PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module; foreach (var member in this.GetMembers()) { if (member.Kind == SymbolKind.Method) { var method = (MethodSymbol)member; Debug.Assert((object)method.PartialDefinitionPart == null); // must be definition var explicitImplementations = method.ExplicitInterfaceImplementations; if (explicitImplementations.Length != 0) { foreach (var implemented in method.ExplicitInterfaceImplementations) { yield return(new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(implemented, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics))); } } if (method.RequiresExplicitOverride()) { // If C# and the runtime don't agree on the overridden method, then // we will mark the method as newslot (see MethodSymbolAdapter) and // specify the override explicitly. // This mostly affects accessors - C# ignores method interactions // between accessors and non-accessors, whereas the runtime does not. yield return(new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(method.OverriddenMethod, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics))); } else if (method.MethodKind == MethodKind.Destructor && this.SpecialType != SpecialType.System_Object) { // New in Roslyn: all destructors explicitly override (or are) System.Object.Finalize so that // they are guaranteed to be runtime finalizers. As a result, it is no longer possible to create // a destructor that will never be invoked by the runtime. // NOTE: If System.Object doesn't contain a destructor, you're on your own - this destructor may // or not be called by the runtime. TypeSymbol objectType = this.DeclaringCompilation.GetSpecialType(CodeAnalysis.SpecialType.System_Object); foreach (Symbol objectMember in objectType.GetMembers(WellKnownMemberNames.DestructorName)) { MethodSymbol objectMethod = objectMember as MethodSymbol; if ((object)objectMethod != null && objectMethod.MethodKind == MethodKind.Destructor) { yield return(new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(objectMethod, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics))); } } } } } var syntheticMethods = moduleBeingBuilt.GetSynthesizedMethods(this); if (syntheticMethods != null) { foreach (var m in syntheticMethods) { var method = m as MethodSymbol; if ((object)method != null) { foreach (var implemented in method.ExplicitInterfaceImplementations) { Debug.Assert((object)method.PartialDefinitionPart == null); // must be definition yield return(new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(implemented, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics))); } Debug.Assert(!method.RequiresExplicitOverride()); } } } }
private (string file, string content) GenerateOutputModule() { //var hasConsts = false; //var subClasses = new List<INamedTypeSymbol>(); var sb = new StringBuilder(); var context = new ResolutionContext(this); var level = 0; if (!TypeSymbol.IsStatic) { string inheritance = ""; if (TypeSymbol.BaseType != null && TypeSymbol.BaseType.SpecialType != SpecialType.System_Object) { var inheritanceTypeResolution = TypeResolver.Resolve(TypeSymbol.BaseType, context); if (inheritanceTypeResolution.IsAny) { if (inheritanceTypeResolution.Declaration.Contains("/*")) { inheritance = $"/*extends {inheritanceTypeResolution.Declaration.Replace("any/*", "").Replace("*/", "")}*/"; } } else { inheritance = $"extends {inheritanceTypeResolution.Declaration} "; } } string genericArguments = ""; if (TypeSymbol.TypeArguments.Any()) { genericArguments = $"<{string.Join(", ", TypeSymbol.TypeArguments.Select(t => t.Name))}>"; } sb.AppendLine(level, $"export interface {ClassName}{genericArguments} {inheritance}{{"); foreach (var m in TypeSymbol.GetMembers()) { if (m.Kind == SymbolKind.NamedType) { //subClasses.Add(m as INamedTypeSymbol); continue; } if (m.IsStatic) { //if (m.Kind == SymbolKind.Field && (m as IFieldSymbol).IsConst) //{ // hasConsts = true; //} continue; } if (m.Kind != SymbolKind.Property) { continue; } if (m.DeclaredAccessibility != Accessibility.Public) { continue; } var prop = m as IPropertySymbol; var isNullable = TypeResolver.IsNullable(prop.Type) || !prop.Type.IsValueType; var name = Options.KeepPropsCase ? m.Name : m.Name.ToCamelCase(); var summary = prop.GetDocumentationCommentXml(); if (!string.IsNullOrWhiteSpace(summary)) { summary = summary.Split("<summary>").Last().Split("</summary>").First().Trim(); sb.AppendLine(level + 1, "/**"); var lines = summary.Split(System.Environment.NewLine); foreach (var l in lines) { sb.AppendLine(level + 1, $"*{l.Trim()}"); } sb.AppendLine(level + 1, "**/"); } sb.AppendLine(level + 1, $"{name}{(isNullable ? "?" : "")}: {TypeResolver.Resolve(prop.Type, context).Declaration};"); } sb.AppendLine(level, "}"); //if (hasConsts) //{ // sb.AppendLine(); //} } //else //{ // hasConsts = true; //} ////Static part //if (hasConsts // //removing const support for now // //If we enable it again, we should merge these members with KeysAndNames... // && false // ) { // //https://github.com/Microsoft/TypeScript/issues/17372 // //Currently we can't merge namespaces and const enums. // //This is supposed to be a bug. // //Besides, even if this is fixed, I think enums will never be mergeable with interfaces, // //so I think it will be always necessary to discriminate with something like $. // //$ can't be used in C# classes, so will never happen a conflict. // //We transpile C# Consts to TypeScript const enums because this is currently // //the only way to inline values. Consts values direclty inside namespaces/modules are not inlined... // //---R: Now, supporting only scoped types, maybe values dont need to be inlined... // sb.AppendLine(level, $"export class {ClassName} {{"); // level++; // foreach (var m in TypeSymbol.GetMembers()) { // var fieldSymbol = (m as IFieldSymbol); // if (fieldSymbol != null && fieldSymbol.IsConst) { // //Consts names should not be changed, they are commonly uppercased both in client and server... // var name = m.Name; // sb.AppendLine(level, $"static readonly {name} = {JsonConvert.SerializeObject(fieldSymbol.ConstantValue)};"); // } // } // level--; // sb.AppendLine(level, "}"); //} level--; AppendKeysAndNames(sb); sb.Insert(0, context.GetImportsText()); string content = sb.ToString(); return(OutputFilePath, content); }
internal static bool AreEquivalent(TypeSymbol a, TypeSymbol b, Compilation comp) { var aMembers = a.GetMembers().OfType<PropertySymbol>().ToList(); var bMembers = b.GetMembers().OfType<PropertySymbol>().ToList(); if (aMembers.Count != bMembers.Count) return false; for (var i = 0; i < aMembers.Count; i++) { var aMember = aMembers[i]; var bMember = bMembers[i]; if (aMember.Name != bMember.Name) return false; if (aMember.DeclaredAccessibility != bMember.DeclaredAccessibility) return false; var aType = aMember.Type; var bType = bMember.Type; var aName = aType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); var bName = bType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); if (aName == bName) continue; var conv = comp.ClassifyConversion(aType, bType); if (!conv.IsIdentity) return false; } return true; }
protected void CheckStackSize(Value valueCount, EmitContext context) { using (context.InterruptAssignmentScope()) { Value stack = context.RecursiveStackValue; BoundAccessExpression stackAccess = BoundAccessExpression.BindAccess(stack); Value stackAddr = context.RecursiveStackAddressValue; BoundAccessExpression stackAddrAccess = BoundAccessExpression.BindAccess(stackAddr); TypeSymbol arrayType = context.GetTypeSymbol(SpecialType.System_Array); context.Module.AddCommentTag("Stack size check"); // Check stack size and double it if it's not enough // We know that doubling once will always be enough since the default size of the stack is the max number of stack values pushed in any method PropertySymbol arraySizeProperty = arrayType.GetMember <PropertySymbol>("Length", context); TypeSymbol intType = context.GetTypeSymbol(SpecialType.System_Int32); Value arraySize = context.EmitValue(BoundAccessExpression.BindAccess(context, SyntaxNode, arraySizeProperty, stackAccess)); BoundAccessExpression arraySizeAccess = BoundAccessExpression.BindAccess(arraySize); Value targetSize = context.EmitValue(CreateBoundInvocation(context, SyntaxNode, new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.Addition, intType, context), null, new BoundExpression[] { stackAddrAccess, BoundAccessExpression.BindAccess(valueCount) })); Value isSizeGreaterThan = context.EmitValue(CreateBoundInvocation(context, SyntaxNode, new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.GreaterThanOrEqual, intType, context), null, new BoundExpression[] { BoundAccessExpression.BindAccess(targetSize), arraySizeAccess, })); JumpLabel skipResizeLabel = context.Module.CreateLabel(); context.Module.AddJumpIfFalse(skipResizeLabel, isSizeGreaterThan); // Resize logic Value constantTwo = context.GetConstantValue(intType, 2); Value newSize = context.EmitValue(CreateBoundInvocation(context, SyntaxNode, new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.Multiplication, intType, context), null, new BoundExpression[] { arraySizeAccess, BoundAccessExpression.BindAccess(constantTwo), })); Value newArray = context.EmitValue(new BoundArrayCreationExpression(SyntaxNode, context, context.GetTypeSymbol(SpecialType.System_Object).MakeArrayType(context), new BoundExpression[] { BoundAccessExpression.BindAccess(newSize) }, null)); MethodSymbol arrayCopyMethod = arrayType.GetMembers <MethodSymbol>("Copy", context) .First(e => e.Parameters.Length == 3 && e.Parameters[2].Type == intType); context.Emit(CreateBoundInvocation(context, null, arrayCopyMethod, null, new BoundExpression[] { stackAccess, BoundAccessExpression.BindAccess(newArray), BoundAccessExpression.BindAccess(arraySize) })); context.Module.AddCopy(newArray, stack); context.Module.LabelJump(skipResizeLabel); context.Module.AddCommentTag("Stack size check end"); } }