示例#1
0
        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);
            }
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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;
        }
示例#4
0
        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;
            }
        }
示例#5
0
        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();
        }
示例#6
0
        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();
        }