protected override void emitCode(Context ctx, bool mustReturn) { var type = Type ?? ctx.ResolveType(TypeSignature); var gen = ctx.CurrentMethod.Generator; gen.EmitConstant(type); gen.EmitCall(_HandleMethod); }
protected override void compile(Context ctx, bool mustReturn) { var type = Type ?? ctx.ResolveType(TypeSignature); var gen = ctx.CurrentILGenerator; var method = typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }); gen.EmitConstant(type); gen.EmitCall(method); }
protected override Type resolve(Context ctx, bool mustReturn) { if (Type == null) Type = ctx.ResolveType(TypeSignature); var idxType = Size.Resolve(ctx); if (!typeof (int).IsExtendablyAssignableFrom(idxType)) error(Size, CompilerMessages.ArraySizeNotInt, idxType); return Type.MakeArrayType(); }
public override void ProcessClosures(Context ctx) { base.ProcessClosures(ctx); var type = ExceptionType != null ? ctx.ResolveType(ExceptionType) : typeof(Exception); if (type != typeof(Exception) && !type.IsSubclassOf(typeof(Exception))) error(CompilerMessages.CatchTypeNotException, type); if(!string.IsNullOrEmpty(ExceptionVariable)) _ExceptionVariable = ctx.Scope.DeclareLocal(ExceptionVariable, type, false); }
public override IEnumerable<PatternNameBinding> Resolve(Context ctx, Type expressionType) { if (!IsWildcard) yield return new PatternNameBinding(Name, expressionType); if (Type != null) { var specifiedType = ctx.ResolveType(Type); if(!specifiedType.IsExtendablyAssignableFrom(expressionType) && !expressionType.IsExtendablyAssignableFrom(specifiedType)) Error(CompilerMessages.PatternTypeMatchImpossible, specifiedType, expressionType); } }
/// <summary> /// Calculates argument type. /// </summary> public Type GetArgumentType(Context ctx) { if (Type == null) { Type = ctx.ResolveType(TypeSignature); if (IsRefArgument) { Type = Type.MakeByRefType(); } else if (IsVariadic) { Type = Type.MakeArrayType(); } } return(Type); }
public override IEnumerable<PatternNameBinding> Resolve(Context ctx, Type expressionType) { var typeEntity = ctx.FindType(Identifier.FullSignature); if(typeEntity == null || (!typeEntity.Kind.IsAnyOf(TypeEntityKind.Type, TypeEntityKind.TypeLabel))) Error(Identifier, CompilerMessages.PatternNotValidType, Identifier.FullSignature); Type = ctx.ResolveType(Identifier); if (!Type.IsExtendablyAssignableFrom(expressionType) && !expressionType.IsExtendablyAssignableFrom(Type)) Error(CompilerMessages.PatternTypeMatchImpossible, Type, expressionType); try { var field = typeEntity.ResolveField("Tag"); return LabelRule.Resolve(ctx, field.Type); } catch(KeyNotFoundException) { Error(CompilerMessages.PatternTypeNoTag, Identifier.FullSignature); return NoBindings(); } }
protected override void compile(Context ctx, bool mustReturn) { var gen = ctx.CurrentILGenerator; var exprType = Expression.GetExpressionType(ctx); var desiredType = ctx.ResolveType(TypeSignature); SafeModeCheckType(ctx, desiredType); // types are identical if (exprType == desiredType) { gen.EmitConstant(true); return; } // valuetype can only be cast to object if (exprType.IsValueType) { gen.EmitConstant(desiredType == typeof(object)); return; } Expression.Compile(ctx, true); // check if not null if (desiredType == typeof (object)) { gen.EmitNull(); gen.EmitCompareEqual(); gen.EmitConstant(false); gen.EmitCompareEqual(); } else { gen.EmitCast(desiredType, false); gen.EmitNull(); gen.EmitCompareGreater(false); } }
protected override void compile(Context ctx, bool mustReturn) { var gen = ctx.CurrentILGenerator; var backup = ctx.CurrentTryBlock; ctx.CurrentTryBlock = this; EndLabel = gen.BeginExceptionBlock(); Code.Compile(ctx, false); gen.EmitLeave(EndLabel); var catchTypes = new Dictionary<Type, bool>(); var catchAll = false; foreach (var curr in CatchClauses) { if(catchAll) Error(curr, CompilerMessages.CatchClauseUnreachable); var currType = curr.ExceptionType != null ? ctx.ResolveType(curr.ExceptionType) : typeof (Exception); if(catchTypes.ContainsKey(currType)) Error(curr, CompilerMessages.CatchTypeDuplicate, currType); if (currType == typeof (Exception)) catchAll = true; curr.Compile(ctx, false); } if (Finally != null) { gen.BeginFinallyBlock(); Finally.Compile(ctx, false); } gen.EndExceptionBlock(); ctx.CurrentTryBlock = backup; }
protected override Type resolve(Context ctx, bool mustReturn) { var prevTypes = new List<Type>(); foreach(var curr in CatchClauses) { var currType = curr.ExceptionType != null ? ctx.ResolveType(curr.ExceptionType) : typeof(Exception); foreach (var prevType in prevTypes) { if(currType == prevType) error(curr, CompilerMessages.CatchTypeDuplicate, currType); else if(prevType.IsExtendablyAssignableFrom(currType)) error(curr, CompilerMessages.CatchClauseUnreachable, currType, prevType); } prevTypes.Add(currType); } return base.resolve(ctx, mustReturn); }
private void resolve(Context ctx) { Action check = () => { if (Expression == null && !m_IsStatic) Error(CompilerMessages.DynamicMemberFromStaticContext, MemberName); if(m_Method == null && TypeHints.Count > 0) Error(CompilerMessages.TypeArgumentsForNonMethod, m_Type, MemberName); m_IsResolved = true; }; m_Type = StaticType != null ? ctx.ResolveType(StaticType) : Expression.GetExpressionType(ctx); // special case: array length if (m_Type.IsArray && MemberName == "Length") { check(); return; } // check for field try { m_Field = ctx.ResolveField(m_Type, MemberName); m_IsStatic = m_Field.IsStatic; check(); return; } catch (KeyNotFoundException) { } // check for property try { m_Property = ctx.ResolveProperty(m_Type, MemberName); if(!m_Property.CanGet) Error(CompilerMessages.PropertyNoGetter, m_Type, MemberName); m_IsStatic = m_Property.IsStatic; check(); return; } catch (KeyNotFoundException) { } var argTypes = TypeHints.Select(t => t.FullSignature == "_" ? null : ctx.ResolveType(t)).ToArray(); var methods = ctx.ResolveMethodGroup(m_Type, MemberName).Where(m => checkMethodArgs(ctx, argTypes, m)).ToArray(); if (methods.Length == 0) Error(argTypes.Length == 0 ? CompilerMessages.TypeIdentifierNotFound : CompilerMessages.TypeMethodNotFound, m_Type.Name, MemberName); if (methods.Length > 1) Error(CompilerMessages.TypeMethodAmbiguous, m_Type.Name, MemberName); m_Method = methods[0]; if (m_Method.ArgumentTypes.Length > 16) Error(CompilerMessages.CallableTooManyArguments); m_IsStatic = m_Method.IsStatic; check(); }
protected override Type resolve(Context ctx, bool mustReturn) { var type = Value != null ? Value.Resolve(ctx) : ctx.ResolveType(Type); ctx.CheckTypedExpression(Value, type); if (Local == null) { if (Name == "_") error(CompilerMessages.UnderscoreName); try { var name = ctx.Scope.DeclareLocal(Name, type, IsImmutable); if (Value != null && Value.IsConstant && ctx.Options.UnrollConstants) { name.IsConstant = true; name.ConstantValue = Value.ConstantValue; } } catch (LensCompilerException ex) { ex.BindToLocation(this); throw; } } return base.resolve(ctx, mustReturn); }
/// <summary> /// Attempts to resolve member reference to a field or a property. /// </summary> private void resolveSelf(Context ctx) { var type = StaticType != null ? ctx.ResolveType(StaticType) : Expression.Resolve(ctx); checkTypeInSafeMode(ctx, type); // check for field try { _Field = ctx.ResolveField(type, MemberName); _IsStatic = _Field.IsStatic; if (Expression == null && !_IsStatic) error(CompilerMessages.DynamicMemberFromStaticContext, type, MemberName); } catch (KeyNotFoundException) { try { _Property = ctx.ResolveProperty(type, MemberName); if (!_Property.CanSet) error(CompilerMessages.PropertyNoSetter, MemberName, type); _IsStatic = _Property.IsStatic; if (Expression == null && !_IsStatic) error(CompilerMessages.DynamicMemberFromStaticContext, type, MemberName); } catch (KeyNotFoundException) { error(CompilerMessages.TypeSettableIdentifierNotFound, type, MemberName); } } var destType = _Field != null ? _Field.FieldType : _Property.PropertyType; ensureLambdaInferred(ctx, Value, destType); var valType = Value.Resolve(ctx); ctx.CheckTypedExpression(Value, valType, true); if (!destType.IsExtendablyAssignableFrom(valType)) error(CompilerMessages.ImplicitCastImpossible, valType, destType); }
public override IEnumerable<PatternNameBinding> Resolve(Context ctx, Type expressionType) { var typeEntity = ctx.FindType(Identifier.FullSignature); if (typeEntity == null || (!typeEntity.Kind.IsAnyOf(TypeEntityKind.Record))) Error(Identifier, CompilerMessages.PatternNotValidRecord, Identifier.FullSignature); Type = ctx.ResolveType(Identifier); if (!Type.IsExtendablyAssignableFrom(expressionType) && !expressionType.IsExtendablyAssignableFrom(Type)) Error(CompilerMessages.PatternTypeMatchImpossible, Type, expressionType); var duplicate = FieldRules.GroupBy(x => x.Name).FirstOrDefault(x => x.Count() > 1); if(duplicate != null) Error(CompilerMessages.PatternRecordFieldDuplicated, duplicate.Key); var subBindings = new List<PatternNameBinding>(); foreach (var fieldRule in FieldRules) { try { var field = typeEntity.ResolveField(fieldRule.Name.FullSignature); subBindings.AddRange(fieldRule.Rule.Resolve(ctx, field.Type)); } catch (KeyNotFoundException) { Error(fieldRule.Name, CompilerMessages.PatternRecordNoField, Identifier.FullSignature, fieldRule.Name.FullSignature); } } return subBindings; }
/// <summary> /// Calculates argument type. /// </summary> public Type GetArgumentType(Context ctx) { if (Type != null) return Type; var type = ctx.ResolveType(TypeSignature); if (IsRefArgument) type = type.MakeByRefType(); return type; }
private void resolveGetMember(Context ctx, GetMemberNode node) { m_InvocationSource = node.Expression; var type = m_InvocationSource != null ? m_InvocationSource.GetExpressionType(ctx) : ctx.ResolveType(node.StaticType); SafeModeCheckType(ctx, type); if (node.TypeHints.Any()) m_TypeHints = node.TypeHints.Select(x => x.FullSignature == "_" ? null : ctx.ResolveType(x)).ToArray(); try { // resolve a normal method try { m_Method = ctx.ResolveMethod(type, node.MemberName, m_ArgTypes, m_TypeHints); if (m_Method.IsStatic) m_InvocationSource = null; return; } catch (KeyNotFoundException) { if (m_InvocationSource == null) throw; } // resolve a callable field try { ctx.ResolveField(type, node.MemberName); resolveExpression(ctx, node); return; } catch (KeyNotFoundException) { } // resolve a callable field try { ctx.ResolveProperty(type, node.MemberName); resolveExpression(ctx, node); return; } catch (KeyNotFoundException) { } // resolve a local function that is implicitly used as an extension method // move invocation source to arguments if (Arguments[0] is UnitNode) Arguments[0] = m_InvocationSource; else Arguments.Insert(0, m_InvocationSource); var oldArgTypes = m_ArgTypes; m_ArgTypes = Arguments.Select(a => a.GetExpressionType(ctx)).ToArray(); m_InvocationSource = null; try { m_Method = ctx.ResolveMethod(ctx.MainType.TypeInfo, node.MemberName, m_ArgTypes); } catch (KeyNotFoundException) { // resolve a declared extension method // most time-consuming operation, therefore is last checked if(ctx.Options.AllowExtensionMethods) m_Method = ctx.ResolveExtensionMethod(type, node.MemberName, oldArgTypes, m_TypeHints); } } catch (AmbiguousMatchException) { Error(CompilerMessages.TypeMethodInvocationAmbiguous, type, node.MemberName); } catch (KeyNotFoundException) { var msg = node.StaticType != null ? CompilerMessages.TypeStaticMethodNotFound : CompilerMessages.TypeMethodNotFound; Error(msg, type, node.MemberName); } }
/// <summary> /// Attempts to resolve current node and sets either of the following fields: /// _Field, _Method, _Property /// /// The following fields are also set: /// _Type, _Static /// </summary> private void resolveSelf(Context ctx) { Action check = () => { if (Expression == null && !_IsStatic) error(CompilerMessages.DynamicMemberFromStaticContext, _Type, MemberName); if (_Method == null && TypeHints.Count > 0) error(CompilerMessages.TypeArgumentsForNonMethod, _Type, MemberName); }; _Type = StaticType != null ? ctx.ResolveType(StaticType) : Expression.Resolve(ctx); // special case: array length if (_Type.IsArray && MemberName == "Length") { check(); return; } // check for field try { _Field = ctx.ResolveField(_Type, MemberName); _IsStatic = _Field.IsStatic; check(); return; } catch (KeyNotFoundException) { } // check for property try { _Property = ctx.ResolveProperty(_Type, MemberName); if(!_Property.CanGet) error(CompilerMessages.PropertyNoGetter, _Type, MemberName); _IsStatic = _Property.IsStatic; check(); return; } catch (KeyNotFoundException) { } // check for event: events are only allowed at the left side of += and -= try { ctx.ResolveEvent(_Type, MemberName); error(CompilerMessages.EventAsExpr); } catch (KeyNotFoundException) { } // find method var argTypes = TypeHints.Select(t => t.FullSignature == "_" ? null : ctx.ResolveType(t)).ToArray(); var methods = ctx.ResolveMethodGroup(_Type, MemberName).Where(m => checkMethodArgs(argTypes, m)).ToArray(); if (methods.Length == 0) error(argTypes.Length == 0 ? CompilerMessages.TypeIdentifierNotFound : CompilerMessages.TypeMethodNotFound, _Type.Name, MemberName); if (methods.Length > 1) error(CompilerMessages.TypeMethodAmbiguous, _Type.Name, MemberName); _Method = methods[0]; if (_Method.ArgumentTypes.Length > 16) error(CompilerMessages.CallableTooManyArguments); _IsStatic = _Method.IsStatic; check(); }
protected override Type resolveExpressionType(Context ctx, bool mustReturn = true) { var retType = Body.GetExpressionType(ctx); var argTypes = Arguments.Select(a => a.Type ?? ctx.ResolveType(a.TypeSignature)).ToArray(); return FunctionalHelper.CreateDelegateType(retType, argTypes); }
/// <summary> /// Resolves the method if the expression was a member getter (obj.field or type::field). /// </summary> private void resolveGetMember(Context ctx, GetMemberNode node) { _InvocationSource = node.Expression; var type = _InvocationSource != null ? _InvocationSource.Resolve(ctx) : ctx.ResolveType(node.StaticType); checkTypeInSafeMode(ctx, type); if (node.TypeHints != null && node.TypeHints.Count > 0) _TypeHints = node.TypeHints.Select(x => ctx.ResolveType(x, true)).ToArray(); try { // resolve a normal method try { _Method = ctx.ResolveMethod( type, node.MemberName, _ArgTypes, _TypeHints, (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types) ); if (_Method.IsStatic) _InvocationSource = null; return; } catch (KeyNotFoundException) { if (_InvocationSource == null) throw; } // resolve a callable field try { ctx.ResolveField(type, node.MemberName); resolveExpression(ctx, node); return; } catch (KeyNotFoundException) { } // resolve a callable property try { ctx.ResolveProperty(type, node.MemberName); resolveExpression(ctx, node); return; } catch (KeyNotFoundException) { } Arguments = (Arguments[0] is UnitNode) ? new List<NodeBase> {_InvocationSource} : new[] {_InvocationSource}.Union(Arguments).ToList(); var oldArgTypes = _ArgTypes; _ArgTypes = Arguments.Select(a => a.Resolve(ctx)).ToArray(); _InvocationSource = null; try { // resolve a local function that is implicitly used as an extension method _Method = ctx.ResolveMethod( ctx.MainType.TypeInfo, node.MemberName, _ArgTypes, resolver: (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types) ); return; } catch (KeyNotFoundException) { } // resolve a declared extension method // most time-consuming operation, therefore is last checked try { if(!ctx.Options.AllowExtensionMethods) throw new KeyNotFoundException(); _Method = ctx.ResolveExtensionMethod( type, node.MemberName, oldArgTypes, _TypeHints, (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types) ); } catch (KeyNotFoundException) { var msg = node.StaticType != null ? CompilerMessages.TypeStaticMethodNotFound : CompilerMessages.TypeMethodNotFound; error(msg, type, node.MemberName); } } catch (AmbiguousMatchException) { error(CompilerMessages.TypeMethodInvocationAmbiguous, type, node.MemberName); } }
/// <summary> /// Calculates argument type. /// </summary> public Type GetArgumentType(Context ctx) { if (Type == null) { Type = ctx.ResolveType(TypeSignature); if (IsRefArgument) Type = Type.MakeByRefType(); else if (IsVariadic) Type = Type.MakeArrayType(); } return Type; }
/// <summary> /// Attempts to expand the expression to an event (un)subscription. /// </summary> private NodeBase expandEvent(Context ctx, SetMemberNode node) { // incorrect operator if (!_OperatorType.IsAnyOf(LexemType.Plus, LexemType.Minus)) return null; var type = node.StaticType != null ? ctx.ResolveType(node.StaticType) : node.Expression.Resolve(ctx); try { var evt = ctx.ResolveEvent(type, node.MemberName); // node.Value = Expr.CastTransparent(node.Value, evt.EventHandlerType); return new EventNode(evt, node, _OperatorType == LexemType.Plus); } catch (KeyNotFoundException) { return null; } }
protected override Type resolveExpressionType(Context ctx, bool mustReturn = true) { return Type ?? ctx.ResolveType(TypeSignature); }
/// <summary> /// Register arguments as local variables. /// </summary> public void InitializeScope(Context ctx) { var method = ctx.CurrentMethod; if (method.Arguments == null) return; for(var idx = 0; idx < method.Arguments.Count; idx++) { var arg = method.Arguments[idx]; try { var name = DeclareName(arg.Name, arg.Type ?? ctx.ResolveType(arg.TypeSignature), false, arg.IsRefArgument); name.ArgumentId = method.IsStatic ? idx : idx + 1; } catch (LensCompilerException ex) { ex.BindToLocation(arg); throw; } } }
protected override Type resolve(Context ctx, bool mustReturn) { ctx.CheckTypedExpression(Expression, allowNull: true); var stmtTypes = new List<Type>(MatchStatements.Count); Type commonType = null; foreach (var stmt in MatchStatements) { stmt.ParentNode = this; stmtTypes.Add(stmt.Resolve(ctx, mustReturn)); foreach (var rule in stmt.MatchRules) { var nameRule = rule as MatchNameRule; // detect catch-all expression for a type if (nameRule != null && stmt.Condition == null) { var nameType = nameRule.Type == null ? typeof (object) : ctx.ResolveType(nameRule.Type); if (commonType != null && commonType.IsExtendablyAssignableFrom(nameType)) error(CompilerMessages.PatternUnreachable); commonType = nameType; } } } return stmtTypes.Any(x => x.IsVoid()) ? typeof(UnitType) : stmtTypes.ToArray().GetMostCommonType(); }
protected override Type resolve(Context ctx, bool mustReturn) { var type = Type ?? ctx.ResolveType(TypeSignature); ensureLambdaInferred(ctx, Expression, type); return type; }
public override void ProcessClosures(Context ctx) { base.ProcessClosures(ctx); var type = Value != null ? Value.GetExpressionType(ctx) : ctx.ResolveType(Type); ctx.CheckTypedExpression(Value, type); if(LocalName != null) return; if(Name == "_") Error(CompilerMessages.UnderscoreName); try { var name = ctx.CurrentScope.DeclareName(Name, type, IsImmutable); if (Value != null && Value.IsConstant && ctx.Options.UnrollConstants) { name.IsConstant = true; name.ConstantValue = Value.ConstantValue; } } catch (LensCompilerException ex) { ex.BindToLocation(this); throw; } }
protected override Type resolve(Context ctx, bool mustReturn) { base.resolve(ctx, true); var type = Type ?? ctx.ResolveType(TypeSignature); if (type.IsVoid()) error(CompilerMessages.VoidTypeDefault); if (type.IsAbstract) error(CompilerMessages.TypeAbstract, TypeSignature.FullSignature); if (type.IsInterface) error(CompilerMessages.TypeInterface, TypeSignature.FullSignature); if (Arguments.Count == 0) error(CompilerMessages.ParameterlessConstructorParens); try { _Constructor = ctx.ResolveConstructor(type, _ArgTypes); } catch (AmbiguousMatchException) { error(CompilerMessages.TypeConstructorAmbiguos, TypeSignature.FullSignature); } catch (KeyNotFoundException) { if (_ArgTypes.Length > 0 || !type.IsValueType) error(CompilerMessages.TypeConstructorNotFound, TypeSignature.FullSignature); _IsDefault = true; return type; } applyLambdaArgTypes(ctx); return resolvePartial(_Constructor, type, _ArgTypes); }
protected override void emitCode(Context ctx, bool mustReturn) { var gen = ctx.CurrentMethod.Generator; var backup = ctx.CurrentCatchBlock; ctx.CurrentCatchBlock = this; var type = ExceptionType != null ? ctx.ResolveType(ExceptionType) : typeof(Exception); gen.BeginCatchBlock(type); if (_ExceptionVariable == null) gen.EmitPop(); else gen.EmitSaveLocal(_ExceptionVariable.LocalBuilder); Code.Emit(ctx, false); gen.EmitLeave(ctx.CurrentTryBlock.EndLabel); ctx.CurrentCatchBlock = backup; }
private void resolve(Context ctx) { var type = StaticType != null ? ctx.ResolveType(StaticType) : Expression.GetExpressionType(ctx); SafeModeCheckType(ctx, type); // check for field try { m_Field = ctx.ResolveField(type, MemberName); m_IsStatic = m_Field.IsStatic; if (Expression == null && !m_IsStatic) Error(CompilerMessages.DynamicMemberFromStaticContext, type, MemberName); return; } catch (KeyNotFoundException) { } try { m_Property = ctx.ResolveProperty(type, MemberName); if(!m_Property.CanSet) Error(CompilerMessages.PropertyNoSetter, MemberName, type); m_IsStatic = m_Property.IsStatic; if (Expression == null && !m_IsStatic) Error(CompilerMessages.DynamicMemberFromStaticContext, MemberName, type); } catch (KeyNotFoundException) { Error(CompilerMessages.TypeSettableIdentifierNotFound, type, MemberName); } }