/// <summary> /// Create a symbol given a name. At the moment assumes that only internal symbols get incremented, this means there's no masking at the moment for local variables. /// </summary> /// <param name="symbolName"></param> /// <param name="resolvedSymbolType"></param> /// <param name="declType"></param> /// <param name="appendType">Used to disable redundant type append from unnamed variable allocations</param> /// <returns></returns> private SymbolDefinition CreateNamedSymbolInternal(string symbolName, System.Type resolvedSymbolType, SymbolDeclTypeFlags declType, bool appendType = true) { if (resolvedSymbolType == null || symbolName == null) { throw new System.ArgumentNullException(); } if (!declType.HasFlag(SymbolDeclTypeFlags.Internal) && symbolName.StartsWith("__")) { throw new System.ArgumentException($"Symbol {symbolName} cannot have name starting with \"__\", this naming is reserved for internal variables."); } string uniqueSymbolName = symbolName; bool hasGlobalDeclaration = false; if (declType.HasFlag(SymbolDeclTypeFlags.Internal)) { uniqueSymbolName = $"intnl_{uniqueSymbolName}"; } if (declType.HasFlag(SymbolDeclTypeFlags.Constant)) { uniqueSymbolName = $"const_{uniqueSymbolName}"; hasGlobalDeclaration = true; } if (declType.HasFlag(SymbolDeclTypeFlags.This)) { uniqueSymbolName = $"this_{uniqueSymbolName}"; hasGlobalDeclaration = true; } if (declType.HasFlag(SymbolDeclTypeFlags.Reflection)) { uniqueSymbolName = $"__refl_{uniqueSymbolName}"; hasGlobalDeclaration = true; } if (!declType.HasFlag(SymbolDeclTypeFlags.Public) && !declType.HasFlag(SymbolDeclTypeFlags.Private) && !declType.HasFlag(SymbolDeclTypeFlags.Reflection)) { if (appendType) { string sanitizedName = resolver.SanitizeTypeName(resolvedSymbolType.Name); uniqueSymbolName += $"_{sanitizedName}"; } if (hasGlobalDeclaration) { uniqueSymbolName = $"__{IncrementGlobalNameCounter(uniqueSymbolName)}_{uniqueSymbolName}"; } else { uniqueSymbolName = $"__{IncrementUniqueNameCounter(uniqueSymbolName)}_{uniqueSymbolName}"; } } System.Type typeForName = UdonSharpUtils.UserTypeToUdonType(resolvedSymbolType); string udonTypeName = resolver.GetUdonTypeName(typeForName); if (udonTypeName == null) { throw new System.ArgumentException($"Could not locate Udon type for system type {resolvedSymbolType.FullName}"); } udonTypeName = udonTypeName.Replace("VRCUdonCommonInterfacesIUdonEventReceiver", "VRCUdonUdonBehaviour"); SymbolDefinition symbolDefinition = new SymbolDefinition(); symbolDefinition.declarationType = declType; symbolDefinition.symbolCsType = resolvedSymbolType; symbolDefinition.symbolOriginalName = symbolName; symbolDefinition.symbolResolvedTypeName = udonTypeName; symbolDefinition.symbolUniqueName = uniqueSymbolName; if (hasGlobalDeclaration) { GetGlobalSymbolTable().symbolDefinitions.Add(symbolDefinition); } else { symbolDefinitions.Add(symbolDefinition); } return(symbolDefinition); }