/// <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(); }
/// <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; } }