DataType TryResolveDataTypeIdentifier(AstIdentifier identifier)
        {
            var pi = NameResolver.TryResolveMemberRecursive(Namescope, identifier, null) ??
                     NameResolver.TryResolveUsingNamespace(Namescope, identifier, null);

            return((pi as PartialType)?.Type);
        }
        public PartialExpression ResolveIdentifier(AstIdentifier id, int?typeParamCount)
        {
            if (typeParamCount == null)
            {
                var pi = TryResolveLocalIdentifier(id);
                if (pi != null)
                {
                    return(pi);
                }
            }

            // Parent scope is resolved later
            Namescope parentScope;

            if (IsFunctionScope)
            {
                var dt = Namescope as DataType;

                // Should not happen
                if (dt == null)
                {
                    return(PartialError(id.Source, ErrorCode.I0000, "Namescope was a Function without DataType in ResolveIdentifier()"));
                }

                // Check if it as a member of the class
                var obj = Function != null && !Function.IsStatic
                    ? new This(id.Source, TypeBuilder.Parameterize(Function.DeclaringType)).Address
                    : null;

                var p = TryResolveTypeMember(dt, id, typeParamCount, null, obj);
                if (p != null)
                {
                    return(p);
                }

                // Check if it is a member of the parent class
                parentScope = dt.Parent;
                var parentType = dt.ParentType;

                while (parentType != null)
                {
                    p = TryResolveTypeMember(parentType, id, typeParamCount, null, obj);
                    if (p != null)
                    {
                        return(p);
                    }

                    parentScope = parentType.Parent;
                    parentType  = parentType.ParentType;
                }
            }
            else
            {
                // Check if it is a meta property protected by a req statement
                if (MetaProperty != null && typeParamCount == null)
                {
                    foreach (var req in ReqStatements)
                    {
                        if (req is ReqProperty)
                        {
                            var rmp = req as ReqProperty;
                            if (rmp.PropertyName == id.Symbol && rmp.PropertyType != null)
                            {
                                return(new PartialValue(new GetMetaProperty(id.Source, rmp.PropertyType, rmp.PropertyName)));
                            }
                        }
                    }
                }

                var block = Namescope as BlockBase;

                if (block != null)
                {
                    if (typeParamCount == null)
                    {
                        var p  = TryResolveCapturedLocalIdentifier(block, id);
                        var mp = NameResolver.TryGetMetaProperty(id.Source, block, block, id.Symbol, true);

                        if (p != null && mp != null)
                        {
                            Log.Error(id.Source, ErrorCode.E0000, id.Symbol.Quote() + " is an ambiguous match between meta property and captured local variable. Use 'meta " + id.Symbol + "' or 'local::" + id.Symbol + "' to disambiguate");
                        }
                        if (p != null)
                        {
                            return(p);
                        }
                        if (mp != null)
                        {
                            return(new PartialValue(new GetMetaProperty(id.Source, mp.ReturnType, mp.Name)));
                        }
                    }

                    var dt = block.TryFindTypeParent();

                    if (dt != null)
                    {
                        var p = TryResolveTypeMember(dt, id, typeParamCount, null, new GetMetaObject(id.Source, TypeBuilder.Parameterize(dt)));
                        if (p != null)
                        {
                            return(p);
                        }
                    }
                }

                parentScope = Namescope;
            }

            if (parentScope != null)
            {
                // Check if it is a member of the parent namespace
                var p = NameResolver.TryResolveMemberRecursive(parentScope, id, typeParamCount);
                if (p != null)
                {
                    return(p);
                }

                // Check if it is a member in a namespace referenced from a using-directive
                p = NameResolver.TryResolveUsingNamespace(parentScope, id, typeParamCount);
                if (p != null)
                {
                    return(p);
                }

                // Check if it is a static method in a class referenced from a using static-directive
                p = NameResolver.TryResolveUsingType(parentScope, id, typeParamCount);
                if (p != null)
                {
                    return(p);
                }
            }

            return(PartialError(id.Source, ErrorCode.E3102, this.GetUnresolvedIdentifierError(id, typeParamCount)));
        }