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); } }
private void resolveGetIdentifier(Context ctx, GetIdentifierNode node) { var nameInfo = ctx.CurrentScope.FindName(node.Identifier); if (nameInfo != null) { resolveExpression(ctx, node); return; } try { m_Method = ctx.ResolveMethod(ctx.MainType.TypeInfo, node.Identifier, m_ArgTypes); if (m_Method == null) throw new KeyNotFoundException(); if(m_ArgTypes.Length == 0 && EnumerableExtensions.IsAnyOf(node.Identifier, EntityNames.RunMethodName, EntityNames.EntryPointMethodName)) Error(CompilerMessages.ReservedFunctionInvocation, node.Identifier); } catch (KeyNotFoundException) { Error(CompilerMessages.FunctionNotFound, node.Identifier); } catch (AmbiguousMatchException) { Error(CompilerMessages.FunctionInvocationAmbiguous, node.Identifier); } }
private void resolveExpression(Context ctx, NodeBase node) { var exprType = node.GetExpressionType(ctx); if (!exprType.IsCallableType()) Error(CompilerMessages.TypeNotCallable, exprType); m_Method = ctx.ResolveMethod(exprType, "Invoke"); var argTypes = m_Method.ArgumentTypes; if (argTypes.Length != m_ArgTypes.Length) Error(CompilerMessages.DelegateArgumentsCountMismatch, exprType, argTypes.Length, m_ArgTypes.Length); for (var idx = 0; idx < argTypes.Length; idx++) { var fromType = m_ArgTypes[idx]; var toType = argTypes[idx]; if (!toType.IsExtendablyAssignableFrom(fromType)) Error(Arguments[idx], CompilerMessages.ArgumentTypeMismatch, fromType, toType); } m_InvocationSource = node; }
protected override Type resolveExpressionType(Context ctx, bool mustReturn = true) { var exprType = Expression.GetExpressionType(ctx); if (exprType.IsArray) return exprType.GetElementType(); var idxType = Index.GetExpressionType(ctx); try { m_Getter = ctx.ResolveIndexer(exprType, idxType, true); return m_Getter.ReturnType; } catch (LensCompilerException ex) { ex.BindToLocation(this); throw; } }
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(); }
private bool checkMethodArgs(Context ctx, Type[] argTypes, MethodWrapper method) { if(argTypes.Length == 0) return true; if (method.ArgumentTypes.Length != argTypes.Length) return false; return !method.ArgumentTypes.Where((p, idx) => argTypes[idx] != null && p != argTypes[idx]).Any(); }