internal SSMethodInfo(Runner runner, string id, HybType declaringType, BaseMethodDeclarationSyntax declaration) { this.Id = id; this.Signature = MemberSignature.GetSignature( runner.Resolver, id, declaration); this.DeclaringType = declaringType; this.Target = new Invokable(this, runner, declaration); if (declaration is MethodDeclarationSyntax md) { this.ReturnType = runner.Resolver.GetType($"{md.ReturnType}"); } this.IsVaArg = declaration.ParameterList.Parameters.LastOrDefault() ?.Modifiers.IsParams() ?? false; this.Parameters = new SSParamInfo[declaration.ParameterList.Parameters.Count]; for (int i = 0; i < this.Parameters.Length; i++) { var p = declaration.ParameterList.Parameters[i]; this.Parameters[i] = new SSParamInfo() { Id = p.Identifier.Text, DefaultValue = p.Default != null?runner.RunExpression(p.Default.Value) : null, IsParams = p.Modifiers.IsParams() }; } }
internal HybInstance(Runner runner, HybType type, Class klass, object parentObject = null) { if (klass == null) { throw new ArgumentNullException(nameof(klass)); } this.Runner = runner; this.Type = type; this.Klass = klass; if (klass.Parent != null) { if (parentObject != null) { Parent = HybInstance.Object(parentObject); } else { InstantiateParent(); } } InitializeFields(); InitializeProperties(); }
internal HybType(Class klass, HybType elementType, int arrayRank) : this(klass) { this.IsArray = true; this.ElementType = elementType; this.ArrayRank = arrayRank; }
public static Type Unwrap(this HybType _this) { if (_this.IsCompiledType) { return(_this.CompiledType); } return(typeof(HybInstance)); }
public bool Is(HybType type) { if (type.IsCompiledType) { return(Is(type.CompiledType)); } return(false); }
public static bool IsSubclassOf(this Type _this, HybType type) { if (type.IsCompiledType == false) { return(false); } return(_this.IsSubclassOf(type.CompiledType)); }
public Class(Runner runner, string id, HybType parent, HybType[] interfaces) : this(runner, id) { this.Parent = parent; this.Interfaces = interfaces; if (parent != null) { InheritFrom(parent); } }
public override bool TryGetType(string id, out HybType type, Assembly hintAssembly = null) { var ret = resolver.TryGetType(id, out type, hintAssembly); if (type != null && type.IsCompiledType == false) { if (initializedTypes.Add(type)) { runner.RunStaticInitializer(type.InterpretKlass); } } return(ret); }
public bool IsSubclassOf(HybType other) { if (other.IsCompiledType) { if (IsCompiledType) { return(CompiledType .IsSubclassOf(other.CompiledType)); } return(false); } return(false); }
public HybType GetType(string id, Assembly hintAssembly = null) { HybType type = null; if (cache.TryGetValue(id, out type)) { return(type); } type = FindType(id, hintAssembly); cache[id] = type; return(type); }
private HybInstance RunObjectCreation(ObjectCreationExpressionSyntax node) { HybType type = null; var args = new HybInstance[node.ArgumentList.Arguments.Count]; var count = 0; foreach (var arg in node.ArgumentList.Arguments) { args[count++] = RunExpression(arg.Expression); } if (node.Type is GenericNameSyntax gn) { type = Resolver.GetGenericType( $"{gn.Identifier}", gn.TypeArgumentList.Arguments.Count); var genericArgs = new HybType[gn.TypeArgumentList.Arguments.Count]; count = 0; foreach (var arg in gn.TypeArgumentList.Arguments) { genericArgs[count++] = Resolver.GetType($"{arg}"); } type = type.MakeGenericType(genericArgs); } else { type = Resolver.GetType($"{node.Type}"); } if (type.IsCompiledType) { if (type.CompiledType == typeof(Action)) { return(args[0]); } if (type.CompiledType == typeof(Func <int>)) { return(args[0]); } } var inst = type.CreateInstance(this, args); if (node.Initializer != null) { ProcessInitializer(inst, node.Initializer); } return(inst); }
private HybType[] ResolveGenericArgumentsFromName(SimpleNameSyntax name) { if (name is GenericNameSyntax gn) { var result = new HybType[gn.TypeArgumentList.Arguments.Count]; var count = 0; foreach (var genericType in gn.TypeArgumentList.Arguments) { result[count++] = Resolver.GetType($"{genericType}"); } return(result); } return(new HybType[] { }); }
public static HybType GetHybType(Type type) { var cache = CompiledTypes.Value; HybType result = null; if (cache.TryGetValue(type, out result)) { return(result); } result = new HybType(type); cache[type] = result; return(result); }
public HybInstance Cast(HybType type) { if (IsCompiledType) { if (type.IsCompiledType) { var casted = Convert.ChangeType(Obj, type.CompiledType); return(HybInstance.Object(casted)); } throw new InvalidCastException( $"{Obj} cannot be casted to {type.InterpretKlass.Id}"); } throw new NotImplementedException(); }
public bool IsSafeType(HybType type) { // Interpret type is always safe if (type.IsCompiledType == false) { return(true); } var ct = type.CompiledType; if (IsAllowedNamespace(ct.Namespace) == false) { return(false); } return(klassFilters.Contains(ct.FullName)); }
private void AddClass(ClassDeclarationSyntax node) { var id = $"{node.Identifier}"; if (node.Modifiers.Contains("partial")) { throw new SemanticViolationException($"partial keyword is not supported: {id}"); } if (Ctx.Types.ContainsKey(id)) { throw new SemanticViolationException($"Class redefination is not supported: {id}"); } HybType parentType = null; var interfaceTypes = new List <HybType>(); if (node.BaseList != null) { foreach (var b in node.BaseList.Types) { var type = Resolver.GetType($"{b.Type}"); if (type.IsInterface == false) { if (parentType != null) { throw new SemanticViolationException($"Cannot be derived from more than 2 base classes."); } if (type.IsSealed) { throw new SemanticViolationException($"Sealed class cannot be inherited."); } parentType = type; } else { interfaceTypes.Add(type); } } } Klass = new Class(this, id, parentType, interfaceTypes.ToArray()); Ctx.Types.Add(id, Klass); }
public bool IsAssignableFrom(HybType other) { if (other.IsCompiledType) { if (IsCompiledType) { if (CompiledType.IsPrimitive && other.CompiledType.IsPrimitive) { return(TypeDescriptor.GetConverter(other.CompiledType) .CanConvertTo(CompiledType)); } return(CompiledType .IsAssignableFrom(other.CompiledType)); } return(false); } return(false); }
public virtual bool TryGetType(string id, out HybType type, Assembly hintAssembly = null) { var sig = GetPureName(id); var rank = GetArrayRank(id); var isGeneric = IsGeneric(id); string[] genericArgs = null; if (isGeneric) { sig = GetSignatureName(id, out genericArgs); } type = TypeCache.GetType(sig, hintAssembly); if (type == null) { return(false); } var ac = Ctx.Config.AccessControl; if (ac.IsSafeType(type) == false) { throw new SandboxException($"{id} is not allowed to use."); } if (isGeneric) { var genericArgTypes = new HybType[genericArgs.Length]; for (int i = 0; i < genericArgTypes.Length; i++) { genericArgTypes[i] = GetType(genericArgs[i]); } type = type.MakeGenericType(genericArgTypes); } if (rank > 0) { type = type.MakeArrayType(rank); } return(true); }
private HybInstance RunStaticMemberAccess(MemberAccessExpressionSyntax node, HybType leftType) { var right = node.Name.Identifier.Text; var accessLevel = AccessLevel.Outside; if (Ctx.Method.DeclaringType == leftType) { accessLevel = AccessLevel.This; } HybInstance value; if (leftType.GetStaticPropertyOrField(right, out value, accessLevel)) { return(value); } throw new SemanticViolationException($"No such static member: {right}"); }
internal SSMethodInfo(Runner runner, string id, HybType declaringType, Invokable body, HybType[] parameterTypes, HybType returnType) { this.Id = id; this.Signature = id; // ?? this.DeclaringType = declaringType; this.Target = body; this.ReturnType = returnType; this.IsVaArg = false; // for now this.Parameters = new SSParamInfo[parameterTypes.Length]; for (int i = 0; i < this.Parameters.Length; i++) { this.Parameters[i] = new SSParamInfo() { Id = $"{i}", DefaultValue = null, IsParams = false }; } }
private void InheritFrom(HybType parent) { if (parent.IsSealed) { throw new SemanticViolationException($"Sealed class cannot be inherited."); } if (parent.IsCompiledType) { foreach (var m in parent.GetMethods()) { if (m.AccessModifier == AccessModifier.Private) { continue; } if (Methods.ContainsKey(m.Id) == false) { Methods[m.Id] = new List <SSMethodInfo>(); } Methods[m.Id].Add(m); } } else { var klass = parent.InterpretKlass; foreach (var f in klass.Fields .Where(x => x.Value.AccessModifier != AccessModifier.Private)) { Fields.Add(f.Key, f.Value); } foreach (var m in klass.Methods) { var nonPrivateMethods = m.Value .Where(x => x.AccessModifier != AccessModifier.Private) .ToList(); Methods.Add(m.Key, nonPrivateMethods); } } }
private void InitializeStaticField(VariableDeclaratorSyntax field, string id, HybType type) { if (field.Initializer == null) { Globals.SetStaticField(Klass, id, type.GetDefault()); } else { var capturedKlass = Klass; AddLazyInitializer(() => { Globals.SetStaticField( capturedKlass, id, RunExpression(field.Initializer.Value)); }); } }
public bool IsSafeType(HybType type) => true;
/// <summary> /// Runs invocation expression. /// [Syntax] Console.WriteLine("Hello World"); /// Foo(1234); /// </summary> private HybInstance RunInvocation(InvocationExpressionSyntax node) { string calleeId = ""; string targetId = ""; HybInstance callee = null; SSMethodInfo[] callsite = null; HybType[] implicitGenericArgs = null; var(args, hasRefOrOut) = ResolveArgumentList(node.ArgumentList); if (node.Expression is MemberAccessExpressionSyntax ma) { var leftIsType = false; var rightName = $"{ma.Name.Identifier}"; implicitGenericArgs = ResolveGenericArgumentsFromName(ma.Name); if (ma.Expression is PredefinedTypeSyntax pd) { HybType leftType = null; leftIsType = true; leftType = Resolver.GetType($"{pd}"); callsite = leftType.GetStaticMethods(rightName); } else if (ma.Expression is IdentifierNameSyntax id) { HybType leftType = null; if (Resolver.TryGetType($"{id.Identifier}", out leftType)) { leftIsType = true; callsite = leftType.GetStaticMethods(rightName); } else { callee = ResolveId(id); callsite = callee.GetMethods(rightName); } calleeId = $"{id.Identifier}"; } else if (ma.Expression is ExpressionSyntax expr) { callee = RunExpression(expr); callsite = callee.GetMethods($"{ma.Name}"); } if (leftIsType == false && callsite.Length == 0) { callsite = ExtResolver.GetCallablegExtensions(callee, $"{ma.Name}"); args = (new HybInstance[] { callee }).Concat(args).ToArray(); } targetId = $"{ma.Name}"; //callsite = ResolveMemberAccess(node.Expression as MemberAccessExpressionSyntax); } else if (node.Expression is SimpleNameSyntax || node.Expression is MemberBindingExpressionSyntax) { SimpleNameSyntax id = node.Expression as SimpleNameSyntax; if (id == null) { id = (node.Expression as MemberBindingExpressionSyntax)?.Name; callee = Ctx._bound; } else { callee = Ctx._this; } implicitGenericArgs = ResolveGenericArgumentsFromName(id); callsite = ResolveLocalMember(id) .Concat(Ctx.Method.DeclaringType.GetStaticMethods(id.Identifier.Text)) .ToArray(); targetId = id.Identifier.Text; } if (callsite.Length == 0) { throw new NoSuchMethodException($"{calleeId}", targetId); } var method = OverloadingResolver.FindMethodWithArguments( Resolver, callsite, implicitGenericArgs.ToArray(), ref args); if (method == null) { throw new SemanticViolationException($"No matching override for `{targetId}`"); } if (callee != null && method.DeclaringType.Parent == callee.GetHybType()) { callee = callee.Parent; } var ret = method.Target.Invoke(callee, args, hasRefOrOut); // post-invoke if (hasRefOrOut) { var count = 0; foreach (var arg in node.ArgumentList.Arguments) { if (arg.RefKindKeyword != null) { RunAssign(arg.Expression, args[count]); } count++; } } return(ret); }
internal HybInstance(HybType type, object obj) { this.Type = type; this.Obj = obj; }
public static bool IsAssignableFrom(this Type _this, HybType type) { return(IsAssignableFromEx(_this, type, null)); }
/// <summary> /// Returns whether type implements the given interface or not. /// </summary> public bool HasInterface(HybType type) => Interfaces.Any(x => x == type);
public static bool IsAssignableFromEx( this Type _this, HybType type, Dictionary <string, Type> genericBound) { if (_this == typeof(object)) { return(true); } if (type.IsCompiledType == false) { return(false); } var cType = type.CompiledType; if (_this.IsGenericType) { var gs = _this.GetGenericArguments(); if (cType.IsGenericType && gs.Length == cType.GetGenericArguments().Length) { try { var genericDefinition = _this.GetGenericTypeDefinition(); var cTypeGenericArgs = cType.GetGenericArguments(); if (genericBound != null) { var thisGenericArgs = _this.GetGenericArguments(); for (int i = 0; i < thisGenericArgs.Length; i++) { genericBound[thisGenericArgs[i].Name] = cTypeGenericArgs[i]; } } _this = genericDefinition .MakeGenericType(cTypeGenericArgs); } catch (ArgumentException e) { return(false); } } else if (gs.Length == 1) { var firstGenericArg = _this.GetGenericArguments().First(); _this = _this.GetGenericTypeDefinition(); Type[] genericArgs = new Type[] { cType }; if (_this == typeof(IEnumerable <>)) { if (cType.IsArray) { var elemType = cType.GetElementType(); genericArgs = new Type[] { elemType }; if (genericBound != null) { genericBound[firstGenericArg.Name] = elemType; } } } else if (genericBound != null) { genericBound[firstGenericArg.Name] = cType; } try { _this = _this.MakeGenericType(genericArgs); } catch (ArgumentException e) { return(false); } } } return(_this.IsAssignableFrom(type.CompiledType)); }
public Class(Runner runner, string id) { this.Runner = runner; this.Id = id; this.Type = new HybType(this); }