protected override Symbol CreateSymbol(ISymbol roslynSymbol, AbstractPhaseContext context) { switch (roslynSymbol) { case null: throw new System.NullReferenceException("Source symbol cannot be null"); case IMethodSymbol methodSymbol: if (methodSymbol.IsStatic) { return(new ImportedUdonSharpMethodSymbol(methodSymbol, context)); } return(new UdonSharpBehaviourMethodSymbol(methodSymbol, context)); case IFieldSymbol fieldSymbol: return(new UdonSharpBehaviourFieldSymbol(fieldSymbol, context)); case IPropertySymbol propertySymbol: return(new UdonSharpBehaviourPropertySymbol(propertySymbol, context)); case ILocalSymbol localSymbol: return(new LocalSymbol(localSymbol, context)); case IParameterSymbol parameterSymbol: return(new ParameterSymbol(parameterSymbol, context)); case ITypeSymbol typeSymbol: throw new NotSupportedException("Nested type declarations are not currently supported by U#", typeSymbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax()?.GetLocation()); // return context.GetTypeSymbol(typeSymbol); } throw new System.InvalidOperationException("Failed to construct symbol for type"); }
protected override Symbol CreateSymbol(ISymbol roslynSymbol, AbstractPhaseContext context) { switch (roslynSymbol) { case null: throw new System.NullReferenceException("Source symbol cannot be null"); case IMethodSymbol methodSymbol: return(MakeMethodSymbol(methodSymbol, context)); case IFieldSymbol fieldSymbol: return(new ImportedUdonSharpFieldSymbol(fieldSymbol, context)); case ILocalSymbol localSymbol: return(new LocalSymbol(localSymbol, context)); case IParameterSymbol parameterSymbol: return(new ParameterSymbol(parameterSymbol, context)); case ITypeSymbol typeSymbol: throw new NotSupportedException("Nested type declarations are not currently supported by U#", typeSymbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax()?.GetLocation()); // return context.GetTypeSymbol(typeSymbol); } throw new System.NotImplementedException(); }
private static MethodSymbol BuildMethod(AbstractPhaseContext context, MethodSymbol methodSymbol) { string methodName = methodSymbol.Name; string returnName; if (methodSymbol.ReturnType.IsArray) { returnName = "__TArray"; } else { returnName = "__T"; } string paramStr = ""; if (methodSymbol.Parameters.Length > 0) { paramStr = "__SystemBoolean"; } string methodIdentifier = $"UnityEngineComponent.__{methodName}{paramStr}{returnName}"; var roslynSymbol = methodSymbol.RoslynSymbol; return(new ExternSynthesizedMethodSymbol(context, methodIdentifier, roslynSymbol.Parameters.Select(e => context.GetTypeSymbol(e.Type)).ToArray(), context.GetTypeSymbol(roslynSymbol.ReturnType), false)); }
protected MethodSymbol(IMethodSymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { if (sourceSymbol != null) { ContainingType = context.GetTypeSymbol(sourceSymbol.ContainingType); IsConstructor = sourceSymbol.MethodKind == MethodKind.Constructor; ITypeSymbol returnType = sourceSymbol.ReturnType; if (returnType != context.GetTypeSymbol(SpecialType.System_Void).RoslynSymbol) { ReturnType = context.GetTypeSymbol(returnType); } else if (IsConstructor) { ReturnType = context.GetTypeSymbol(sourceSymbol.ContainingType); } if (sourceSymbol.Parameters != null) { List <ParameterSymbol> parameterSymbols = new List <ParameterSymbol>(); foreach (IParameterSymbol parameterSymbol in sourceSymbol.Parameters) { ParameterSymbol newSymbol = (ParameterSymbol)context.GetSymbol(parameterSymbol); parameterSymbols.Add(newSymbol); } Parameters = ImmutableArray.CreateRange <ParameterSymbol>(parameterSymbols); } else { Parameters = ImmutableArray <ParameterSymbol> .Empty; } if (!IsGenericMethod && RoslynSymbol != RoslynSymbol.OriginalDefinition) { TypeArguments = sourceSymbol.TypeArguments.Length > 0 ? sourceSymbol.TypeArguments.Select(context.GetTypeSymbol).ToImmutableArray() : ImmutableArray <TypeSymbol> .Empty; } else { TypeArguments = sourceSymbol.TypeArguments.Length > 0 ? sourceSymbol.TypeArguments.Select(context.GetTypeSymbolWithoutRedirect).ToImmutableArray() : ImmutableArray <TypeSymbol> .Empty; } if (RoslynSymbol.IsOverride && RoslynSymbol.OverriddenMethod != null) // abstract methods can be overrides, but not have overriden methods { OverridenMethod = (MethodSymbol)context.GetSymbol(RoslynSymbol.OverriddenMethod); } IsOperator = RoslynSymbol.MethodKind == MethodKind.BuiltinOperator || RoslynSymbol.MethodKind == MethodKind.UserDefinedOperator; if (RoslynSymbol.OriginalDefinition != RoslynSymbol) { OriginalSymbol = context.GetSymbolNoRedirect(RoslynSymbol.OriginalDefinition); } } }
public static BoundAccessExpression BindPropertyAccess(AbstractPhaseContext context, SyntaxNode node, PropertySymbol propertySymbol, BoundExpression sourceExpression, BoundExpression[] parameterExpressions = null) { if (propertySymbol is ExternPropertySymbol externProperty) { Type propertyType = externProperty.ContainingType.UdonType.SystemType; if (_allowedConstantPropertyTypes.Contains(propertyType)) { PropertyInfo property = propertyType.GetProperty(externProperty.Name, BindingFlags.Static | BindingFlags.Public); if (property != null) { return(new BoundConstantExpression(property.GetValue(null), propertySymbol.Type)); } } if (propertySymbol.ToString() == "UnityEngine.Behaviour.enabled") { return(new BoundEnabledPropertyExternAccessExpression(context, node, sourceExpression)); } if (propertySymbol.ContainingType.ToString() == "TMPro.TMP_Text") { return(new BoundTMPPropertyExternAccessExpression(context, node, externProperty, sourceExpression)); } return(new BoundExternPropertyAccessExpression(context, node, externProperty, sourceExpression, parameterExpressions)); } return(new BoundUserPropertyAccessExpression(context, node, propertySymbol, sourceExpression, parameterExpressions)); }
public ParameterSymbol(IParameterSymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { Type = context.GetTypeSymbol(RoslynSymbol.Type); if (RoslynSymbol.OriginalDefinition != RoslynSymbol) { OriginalSymbol = context.GetSymbol(RoslynSymbol.OriginalDefinition); } if (RoslynSymbol.HasExplicitDefaultValue) { if (Type.IsEnum) { DefaultValue = (IConstantValue)Activator.CreateInstance( typeof(ConstantValue <>).MakeGenericType(Type.UdonType.SystemType), Enum.ToObject(Type.UdonType.SystemType, RoslynSymbol.ExplicitDefaultValue)); } else { DefaultValue = (IConstantValue)Activator.CreateInstance( typeof(ConstantValue <>).MakeGenericType(Type.UdonType.SystemType), RoslynSymbol.ExplicitDefaultValue); } } }
public BoundCompoundAssignmentExpression(AbstractPhaseContext context, SyntaxNode node, BoundAccessExpression assignmentTarget, MethodSymbol operatorMethod, BoundExpression assignmentSource) : base(node, null, null, null) { TargetExpression = assignmentTarget; AssignmentSource = assignmentSource; OperatorMethod = operatorMethod; }
public ExternMethodSymbol(IMethodSymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { if (sourceSymbol != null) { ExternSignature = CompilerUdonInterface.GetUdonMethodName(this, context); } }
public BoundStringAccessExpression(AbstractPhaseContext context, SyntaxNode node, BoundExpression sourceExpression, BoundExpression indexerExpression) : base(node, sourceExpression) { IndexerExpression = indexerExpression; ValueType = context.GetTypeSymbol(SpecialType.System_Char); _toCharArraySymbol = context.GetTypeSymbol(SpecialType.System_String).GetMembers <MethodSymbol>(nameof(string.ToCharArray), context).First(e => e.Parameters.Length == 2); }
protected Symbol(ISymbol sourceSymbol, AbstractPhaseContext context) { RoslynSymbol = sourceSymbol; if (sourceSymbol?.ContainingType != null && !(sourceSymbol is ITypeParameterSymbol)) { ContainingType = context.GetTypeSymbol(sourceSymbol.ContainingType); } }
public ExternSynthesizedMethodSymbol(AbstractPhaseContext context, string externSignature, TypeSymbol[] parameterTypes, TypeSymbol returnType, bool isStatic, bool isConstructor = false) : base(null, context) { Parameters = parameterTypes.Select(e => new ParameterSymbol(e, context)).ToImmutableArray(); ReturnType = returnType; IsStatic = isStatic; IsConstructor = isConstructor; ExternSignature = externSignature; }
public BoundGetUnityEngineComponentInvocation(AbstractPhaseContext context, SyntaxNode node, MethodSymbol methodSymbol, BoundExpression sourceExpression, BoundExpression[] parametersExpressions) : base(node, context, BuildMethod(context, methodSymbol), sourceExpression, GetParameterExpressions(context, methodSymbol, parametersExpressions)) { ValueType = methodSymbol.TypeArguments[0]; if (methodSymbol.ReturnType.IsArray) { ValueType = ValueType.MakeArrayType(context); } }
public BoundPrefixOperatorExpression(AbstractPhaseContext context, SyntaxNode node, BoundAccessExpression assignmentTarget, MethodSymbol operatorMethod) : base(node, null, null, null) { TargetExpression = assignmentTarget; Type targetType = TargetExpression.ValueType.UdonType.SystemType; IConstantValue incrementValue = (IConstantValue)Activator.CreateInstance( typeof(ConstantValue <>).MakeGenericType(targetType), Convert.ChangeType(1, targetType)); InternalExpression = CreateBoundInvocation(context, null, operatorMethod, null, new BoundExpression[] { assignmentTarget, new BoundConstantExpression(incrementValue, TargetExpression.ValueType, node) }); }
public LocalSymbol(ILocalSymbol sourceSymbol, AbstractPhaseContext bindContext) : base(sourceSymbol, bindContext) { if (!(bindContext is BindContext)) { throw new InvalidOperationException("Local Symbols can only be created during the bind phase"); } ContainingType = bindContext.GetTypeSymbol(sourceSymbol.ContainingType); Type = bindContext.GetTypeSymbol(sourceSymbol.Type); }
public UdonSharpBehaviourTypeSymbol(IArrayTypeSymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { if (sourceSymbol.ElementType.TypeKind == TypeKind.Array) { UdonType = (ExternTypeSymbol)context.GetTypeSymbol(SpecialType.System_Object).MakeArrayType(context); } else { UdonType = (ExternTypeSymbol)context.GetTypeSymbol(typeof(Component[])); } }
public ImportedUdonSharpTypeSymbol(INamedTypeSymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { if (sourceSymbol.TypeKind == TypeKind.Enum) { UdonType = context.GetTypeSymbol(sourceSymbol.EnumUnderlyingType).UdonType; } else { UdonType = context.GetTypeSymbol(typeof(object[])).UdonType; } }
public ImportedUdonSharpTypeSymbol(IArrayTypeSymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { if (sourceSymbol.ElementType.TypeKind == TypeKind.Enum) { UdonType = (ExternTypeSymbol)context.GetTypeSymbol(((INamedTypeSymbol)sourceSymbol.ElementType).EnumUnderlyingType).UdonType.MakeArrayType(context); } else { UdonType = context.GetTypeSymbol(typeof(object[])).UdonType; } }
public ExternTypeSymbol(INamedTypeSymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { TryGetSystemType(sourceSymbol, out Type systemType); SystemType = systemType; Type udonType = UdonSharpUtils.UserTypeToUdonType(SystemType); UdonType = (ExternTypeSymbol)(udonType == SystemType ? this : context.GetUdonTypeSymbol(sourceSymbol)); ExternSignature = CompilerUdonInterface.GetUdonTypeName(this); }
public BoundExternInvocation(SyntaxNode node, AbstractPhaseContext context, MethodSymbol method, BoundExpression instanceExpression, BoundExpression[] parameterExpressions) : base(node, method, instanceExpression, parameterExpressions) { externMethodSymbol = (ExternMethodSymbol)method; if (!CompilerUdonInterface.IsExposedToUdon(externMethodSymbol.ExternSignature)) { externMethodSymbol = FindAlternateInvocation(context, method, instanceExpression, parameterExpressions); if (externMethodSymbol == null) { throw new NotExposedException(LocStr.CE_UdonMethodNotExposed, node, $"{method.RoslynSymbol?.ToDisplayString() ?? method.ToString()}, sig: {((ExternMethodSymbol)method).ExternSignature}"); } } }
public ExternPropertySymbol(IPropertySymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { if (GetMethod != null) { ExternGetSignature = ((ExternMethodSymbol)GetMethod).ExternSignature; } if (SetMethod != null) { ExternSetSignature = ((ExternMethodSymbol)SetMethod).ExternSignature; } }
void FindCandidateInvocationTypes(AbstractPhaseContext context, List <TypeSymbol> candidates, TypeSymbol ty) { foreach (var intf in ty.RoslynSymbol.AllInterfaces) { candidates.Add(context.GetTypeSymbol(intf)); } while (ty != null) { candidates.Add(ty); ty = ty.BaseType; } }
public static TypeSymbol CreateSymbol(ITypeSymbol type, AbstractPhaseContext context) { switch (type) { case INamedTypeSymbol namedType when namedType.IsExternType(): return new ExternTypeSymbol(namedType, context); case INamedTypeSymbol namedType when namedType.IsUdonSharpBehaviour(): return new UdonSharpBehaviourTypeSymbol(namedType, context); case INamedTypeSymbol namedType: return new ImportedUdonSharpTypeSymbol(namedType, context); // This is just used to be able to query all symbols on system/unity types that use pointer types // Udon does not actually support pointer types case IPointerTypeSymbol pointerType when pointerType.PointedAtType.IsExternType(): return new ExternTypeSymbol((INamedTypeSymbol)pointerType.PointedAtType, context); case ITypeParameterSymbol typeParameter: return new TypeParameterSymbol(typeParameter, context); case IArrayTypeSymbol arrayType: { IArrayTypeSymbol currentArrayType = arrayType; while (currentArrayType.ElementType is IArrayTypeSymbol) { currentArrayType = currentArrayType.ElementType as IArrayTypeSymbol; } INamedTypeSymbol rootType; if (currentArrayType.ElementType is INamedTypeSymbol namedSymbol) { rootType = namedSymbol; if (rootType.IsExternType()) return new ExternTypeSymbol(arrayType, context); if (rootType.IsUdonSharpBehaviour()) return new UdonSharpBehaviourTypeSymbol(arrayType, context); } else if (currentArrayType.ElementType is ITypeParameterSymbol) { return new TypeParameterSymbol(arrayType, context); } else { throw new NotImplementedException(); } return new ImportedUdonSharpTypeSymbol(arrayType, context); } default: throw new System.ArgumentException($"Could not construct type for type symbol {type}"); } }
private static BoundExpression[] GetParameterExpressions(AbstractPhaseContext context, MethodSymbol symbol, BoundExpression[] parameters) { BoundExpression typeExpression = new BoundConstantExpression( symbol.TypeArguments[0].UdonType.SystemType, context.GetTypeSymbol(typeof(Type))); if (parameters == null || parameters.Length == 0) { return new [] { typeExpression } } ; return(parameters.Concat(new [] { typeExpression }).ToArray()); }
public ExternBuiltinOperatorSymbol(IMethodSymbol sourceSymbol, AbstractPhaseContext context) : base(sourceSymbol, context) { if (sourceSymbol.Parameters.Length == 1 && (ContainingType == context.GetTypeSymbol(SpecialType.System_Byte) || ContainingType == context.GetTypeSymbol(SpecialType.System_SByte) || ContainingType == context.GetTypeSymbol(SpecialType.System_Int16) || ContainingType == context.GetTypeSymbol(SpecialType.System_UInt16))) { ReturnType = context.GetTypeSymbol(SpecialType.System_Int32); } OperatorType = TranslateOperatorName(sourceSymbol.Name); ExternSignature = GetSignature(context); }
private static bool TryCreateUdonSharpMetadataInvocation(AbstractPhaseContext context, SyntaxNode node, MethodSymbol symbol, BoundExpression instanceExpression, out BoundInvocationExpression createdInvocation) { if (symbol.Name == "GetUdonTypeID" || symbol.Name == "GetUdonTypeName") { if (symbol.IsStatic && symbol.TypeArguments.Length == 1 && symbol.ContainingType == context.GetTypeSymbol(typeof(UdonSharpBehaviour))) { IConstantValue constantValue; TypeSymbol constantType; var typeArgs = symbol.TypeArguments.Select(e => context.GetTypeSymbol(e.RoslynSymbol)).ToArray(); if (symbol.Name == "GetUdonTypeID") { constantValue = new ConstantValue <long>(UdonSharpInternalUtility.GetTypeID(TypeSymbol.GetFullTypeName(typeArgs[0].RoslynSymbol))); constantType = context.GetTypeSymbol(SpecialType.System_Int64); } else { constantValue = new ConstantValue <string>(TypeSymbol.GetFullTypeName(typeArgs[0].RoslynSymbol)); constantType = context.GetTypeSymbol(SpecialType.System_String); } createdInvocation = new BoundConstantInvocationExpression(node, constantValue, constantType); return(true); } if (!symbol.IsStatic && instanceExpression != null && symbol.ContainingType == context.GetTypeSymbol(typeof(UdonSharpBehaviour))) { TypeSymbol methodContainer = context.GetTypeSymbol(typeof(UdonSharpBehaviourMethods)); var shimMethod = methodContainer.GetMember <MethodSymbol>(symbol.Name, context); context.MarkSymbolReferenced(shimMethod); createdInvocation = CreateBoundInvocation(context, node, shimMethod, null, new [] { instanceExpression }); return(true); } } createdInvocation = null; return(false); }
private static PropertySymbol BuildProperty(AbstractPhaseContext context, BoundExpression sourceExpression, PropertySymbol propertySymbol) { TypeSymbol propertyType = sourceExpression.ValueType; if (propertyType.UdonType.ExternSignature == "VRCUdonUdonBehaviour") { propertyType = context.GetTypeSymbol(typeof(IUdonEventReceiver)); } MethodSymbol setMethod = new ExternSynthesizedMethodSymbol(context, $"set_{propertySymbol.Name}", propertyType, new[] { propertySymbol.Type }, null, false); MethodSymbol getMethod = new ExternSynthesizedMethodSymbol(context, $"get_{propertySymbol.Name}", propertyType, new TypeSymbol[] {}, propertySymbol.Type, false); return(new SynthesizedPropertySymbol(context, getMethod, setMethod)); }
private static PropertySymbol BuildProperty(AbstractPhaseContext context, BoundExpression sourceExpression) { TypeSymbol propertyType = sourceExpression.ValueType; if (propertyType.UdonType.ExternSignature == "VRCUdonUdonBehaviour") { propertyType = context.GetTypeSymbol(typeof(IUdonEventReceiver)); } TypeSymbol boolType = context.GetTypeSymbol(SpecialType.System_Boolean); MethodSymbol setMethod = new ExternSynthesizedMethodSymbol(context, "set_enabled", propertyType, new[] { boolType }, null, false); MethodSymbol getMethod = new ExternSynthesizedMethodSymbol(context, "get_enabled", propertyType, new TypeSymbol[] {}, boolType, false); return(new SynthesizedPropertySymbol(context, getMethod, setMethod)); }
private static bool TryCreateShimInvocation(AbstractPhaseContext context, SyntaxNode node, MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions, out BoundInvocationExpression createdInvocation) { if (TryCreateUdonSharpMetadataInvocation(context, node, symbol, instanceExpression, out createdInvocation)) { return(true); } if (TryCreateGetComponentInvocation(context, node, symbol, instanceExpression, parameterExpressions, out createdInvocation)) { return(true); } if (TryCreateInstantiationInvocation(context, node, symbol, instanceExpression, parameterExpressions, out createdInvocation)) { return(true); } if (TryCreateSetProgramVariableInvocation(context, node, symbol, instanceExpression, parameterExpressions, out createdInvocation)) { return(true); } if (TryCreateArrayMethodInvocation(context, node, symbol, instanceExpression, parameterExpressions, out createdInvocation)) { return(true); } if (TryCreateTMPMethodInvocation(context, node, symbol, instanceExpression, parameterExpressions, out createdInvocation)) { return(true); } if (TryCreateBaseEnumMethodInvocation(context, node, symbol, instanceExpression, parameterExpressions, out createdInvocation)) { return(true); } if (TryCreateCompareToInvocation(context, node, symbol, instanceExpression, parameterExpressions, out createdInvocation)) { return(true); } return(false); }
private static bool TryCreateTMPMethodInvocation(AbstractPhaseContext context, SyntaxNode node, MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions, out BoundInvocationExpression createdInvocation) { if (symbol.ContainingType != null && symbol.ContainingType.ToString() == "TMPro.TMP_Text") { createdInvocation = new BoundExternInvocation(node, context, new ExternSynthesizedMethodSymbol(context, symbol.Name, instanceExpression.ValueType, symbol.Parameters.Select(e => e.Type).ToArray(), symbol.ReturnType, symbol.IsStatic), instanceExpression, parameterExpressions); return(true); } createdInvocation = null; return(false); }
private static bool TryCreateBaseEnumMethodInvocation(AbstractPhaseContext context, SyntaxNode node, MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions, out BoundInvocationExpression createdInvocation) { if ((symbol.Name == "ToString" || symbol.Name == "GetHashCode" || symbol.Name == "Equals") && symbol.ContainingType != null && symbol.ContainingType == context.GetTypeSymbol(SpecialType.System_Enum)) { createdInvocation = new BoundExternInvocation(node, context, context.GetTypeSymbol(SpecialType.System_Object).GetMember <MethodSymbol>(symbol.Name, context), instanceExpression, parameterExpressions); return(true); } createdInvocation = null; return(false); }