public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { // TODO should be unified with RppFuncCall and rethink how types for closures are figureout. // we should use constraints and type inference only, not this kind of hacks when we check target // closure signature and use types from there // Skip closures because they may have missing types _arguments = NodeUtils.AnalyzeWithPredicate(scope, _arguments, node => !(node is RppClosure), diagnostic); Type.Resolve(scope); RType targetType = Type.Value; if (NeedToInferGenericArguments(targetType)) { RType inferredTargetType; Constructor = FindGenericConstructor(targetType, out inferredTargetType); Type = new ResolvableType(inferredTargetType); } else { Constructor = FindConstructor(targetType); } _arguments = RppFuncCall.ReplaceUndefinedClosureTypesIfNeeded(_arguments, Constructor.Parameters, new List<RType>()); NodeUtils.AnalyzeWithPredicate(scope, _arguments, node => node is RppClosure, diagnostic); return this; }
public static IList<RType> TypesAsList(RppMethodInfo methodInfo) { List<RType> list = new List<RType>(); methodInfo.GenericParameters.Select(gp => gp.Type).ForEach(list.Add); methodInfo.Parameters?.Select(p => p.Type).ForEach(list.Add); list.Add(methodInfo.ReturnType); return list; }
public void QueryOneToOneOverload() { var args = new List<RType> {IntTy}; var func1 = new RppMethodInfo("create", null, RMethodAttributes.None, UnitTy, new[] {new RppParameterInfo("x", IntTy)}); var results = OverloadQuery.Find(args, new List<RppMethodInfo> {func1}).ToList(); Assert.AreEqual(1, results.Count()); Assert.AreEqual(func1, results.First()); var func2 = new RppMethodInfo("create", null, RMethodAttributes.None, UnitTy, new RppParameterInfo[] {}); results = OverloadQuery.Find(Enumerable.Empty<RType>(), new List<RppMethodInfo> {func2}).ToList(); Assert.AreEqual(1, results.Count()); Assert.AreEqual(func2, results.First()); }
public static void DefineNativeTypeFor(TypeBuilder typeBuilder, RppMethodInfo rppMethod) { MethodAttributes attr = GetMethodAttributes(rppMethod.Attributes, constructor: false); MethodBuilder method = typeBuilder.DefineMethod(rppMethod.Name, attr, CallingConventions.Standard); if (rppMethod.HasGenericParameters()) { var genericParameters = rppMethod.GenericParameters; CreateNativeGenericParameters(genericParameters, genericParameterNames => method.DefineGenericParameters(genericParameterNames)); } DefineReturnType(method, rppMethod.ReturnType); DefineParameters(method, rppMethod.Parameters); if (rppMethod.Attributes.HasFlag(RMethodAttributes.Synthesized)) { method.SetCustomAttribute(CreateCompilerGeneratedAttribute()); } rppMethod.Native = method; }
public static void DefineNativeTypeForConstructor(TypeBuilder typeBuilder, RppMethodInfo rppConstructor) { MethodAttributes attr = GetMethodAttributes(rppConstructor.Attributes, constructor: true); Type[] parametersTypes = ParametersTypes(rppConstructor.Parameters); ConstructorBuilder constructor = typeBuilder.DefineConstructor(attr, CallingConventions.Standard, parametersTypes); DefineParams(constructor, rppConstructor.Parameters); AssignConstructorParamIndex(rppConstructor.Parameters); rppConstructor.Native = constructor; }
public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic) { _type.Resolve(scope); _patterns = NodeUtils.Analyze(scope, _patterns, diagnostic).ToArray(); TypeSymbol companionObjectSymbol = scope.LookupObject(_type.Name.Name); if (companionObjectSymbol != null) { RppMethodInfo unapplyMethod = FindUnapply(companionObjectSymbol.Type); if (unapplyMethod == null) { throw new Exception("Can't find unapply method or amount of parameters is wrong"); } _unapplyMethod = unapplyMethod; } else { throw new Exception("Can't find companion object!"); } return this; }
private static RppMethodInfo Convert(MethodInfo method) { Type declaringType = method.DeclaringType; Debug.Assert(declaringType != null, "declaringType != null"); RType returnType = GetOrCreateType(method.ReturnType.Name, method.ReturnType); var rMethodAttributes = RTypeUtils.GetRMethodAttributes(method.Attributes); var parameters = method.GetParameters().Select(p => new RppParameterInfo(GetOrCreateType(p.ParameterType.Name, p.ParameterType))).ToArray(); RppMethodInfo rppConstructor = new RppMethodInfo(method.Name, GetOrCreateType(declaringType.Name, declaringType), rMethodAttributes, returnType, parameters) { Native = method }; return rppConstructor; }
private static void UpdateReturnType(RppFunc node, RppMethodInfo method) { if (!node.IsConstructor) { method.ReturnType = node.ReturnType.Value; } }
private void CodegenForStub(RppMethodInfo function) { if (function.DeclaringType.Name == "Array") { RType elementType = function.DeclaringType.GenericArguments.First(); switch (function.Name) { case "ctor": _body.Emit(OpCodes.Newarr, elementType.NativeType); break; case "length": _body.Emit(OpCodes.Ldlen); break; case "apply": { if (elementType.IsGenericParameter) { _body.Emit(OpCodes.Ldelem, elementType.NativeType); } else { OpCode ldOpCode = ClrCodegenUtils.ArrayLoadOpCodeByType(elementType.NativeType); _body.Emit(ldOpCode); } break; } case "update": { OpCode? ldOpCode = ClrCodegenUtils.ArrayStoreOpCodeByType(elementType.NativeType); if (ldOpCode.HasValue) { _body.Emit(ldOpCode.Value); } else { _body.Emit(OpCodes.Stelem, elementType.NativeType); } break; } default: throw new NotImplementedException("Other funcs are not implemented"); } } }
private static string MethodString(RppMethodInfo method) { if (method.Name == "ctor") { return method.ToString().Replace("ctor", "constructor").Replace("constrparam", ""); } return method.ToString(); }
public static SemanticException NotEnoughArguments(IToken token, RppMethodInfo targetMethod) { string methodString = MethodString(targetMethod); return new SemanticException(107, FormatErrorAndPointAtToken(token, $"not enough arguments for method {methodString}")); }
public RppMethodInfo DefineConstructor(RMethodAttributes attributes, RppParameterInfo[] parameterTypes) { RppMethodInfo constructor = new RppMethodInfo("ctor", this, attributes, UnitTy, parameterTypes); _constructors.Add(constructor); return constructor; }
public RppMethodInfo DefineMethod([NotNull] string name, RMethodAttributes attributes, [CanBeNull] RType returnType, [NotNull] RppParameterInfo[] parameterTypes, [NotNull] RppGenericParameter[] genericParameters) { RppMethodInfo method = new RppMethodInfo(name, this, attributes, returnType, parameterTypes); if (name == "ctor") { _constructors.Add(method); } else { _methods.Add(method); } return method; }
private static RppMethodInfo Convert(ConstructorInfo constructor) { Type declaringType = constructor.DeclaringType; Debug.Assert(declaringType != null, "declaringType != null"); var rMethodAttributes = RTypeUtils.GetRMethodAttributes(constructor.Attributes); var parameters = constructor.GetParameters().Select(p => new RppParameterInfo(GetOrCreateType(p.ParameterType.Name, p.ParameterType))).ToArray(); RppMethodInfo rppConstructor = new RppMethodInfo("ctor", GetOrCreateType(declaringType.Name, declaringType), rMethodAttributes, UnitTy, parameters) { Native = constructor }; return rppConstructor; }
public static IEnumerable<RppGenericParameter> CreateGenericParameters(IEnumerable<string> genericParameterName, RType declaringType, RppMethodInfo declaringMethod = null) { int genericArgumentPosition = 0; foreach (var genericParamName in genericParameterName) { RppGenericParameter genericParameter = CreateGenericParameter(genericParamName, genericArgumentPosition++, declaringType, declaringMethod); yield return genericParameter; } }
private static RppGenericParameter CreateGenericParameter(string name, int genericArgumentPosition, RType declaringType, RppMethodInfo declaringMethod) { RppGenericParameter genericParameter = new RppGenericParameter(name); RType type = new RType(name, RTypeAttributes.None, null, declaringType) { IsGenericParameter = true, GenericParameterPosition = genericArgumentPosition, GenericParameterDeclaringMethod = declaringMethod }; genericParameter.Type = type; genericParameter.Position = genericArgumentPosition; return genericParameter; }
private IEnumerable<RType> InferTypes(RppMethodInfo candidate, IEnumerable<IRppExpr> args) { var argTypes = args.Select(a => a.Type.Value).ToList(); List<RType> targetTypes = candidate.GenericParameters.Select(gp => gp.Type) .Concat(candidate.Parameters.Select(p => p.Type)) .Concat(candidate.ReturnType).ToList(); List<RType> sourceTypes = GetGenericArgumentsOrUndefinedTypes(_typeArgs, candidate.GenericParameters.Length) .Concat(argTypes).Concat(RppTypeSystem.Undefined).ToList(); IEnumerable<RType> inferredTypes = TypeInference.InferTypes(sourceTypes, targetTypes).ToList(); if (inferredTypes.Any(t => RppTypeSystem.Undefined.Equals(t))) { return null; } return inferredTypes.Take(candidate.GenericParameters.Length); }
public ResolveResults(RppMethodInfo resolvedFunc) { Method = resolvedFunc; }
public ResolveResults(RppMethodInfo resolvedFunc, IEnumerable<RType> typeArguments, bool isInsideClosure) { Method = resolvedFunc; TypeArguments = typeArguments; _isInsideClosure = isInsideClosure; }
private static void UpdateParameters(RppFunc node, RppMethodInfo method) { IRppParam[] funcParams = node.Params; if (funcParams.Length != 0) { RppParameterInfo[] funcParamsTypes = funcParams.Select(p => new RppParameterInfo(p.Name, ResolveType(p))).ToArray(); method.Parameters = funcParamsTypes; } }
public ClosureResolveResults(RppMember expr, RppMethodInfo resolvedFunc) : base(resolvedFunc) { _expr = expr; }
private RppMethodInfo InflateMethod(RppMethodInfo method) { return new RppInflatedMethodInfo(method, _genericArguments, this); }
private EmptyTypeDefinition() { TypeParameters = new RppTypeParameterInfo[0]; Constructors = new RppMethodInfo[0]; Fields = new RppFieldInfo[0]; Methods = new RppMethodInfo[0]; }