Exemple #1
0
        /// <summary>
        /// Convert from DottedIdentifier
        /// </summary>
        public static PartialSymbol FromDottedIdentifier(SymbolTable symbolTable, DottedIdentifier identifier)
        {
            using (var pooledStringIds = Pools.GetStringIdList())
            {
                var stringIds = pooledStringIds.Instance;
                while (identifier != null)
                {
                    stringIds.Add(identifier.Head.StringId);
                    identifier = identifier.GetTail(symbolTable);
                }

                var components = stringIds.AsArray();
                return(new PartialSymbol(components));
            }
        }
Exemple #2
0
        /// <summary>
        /// Internal api to try to create a RelativePath from a string.
        /// </summary>
        /// <remarks>This function serves as an internal overload for tryCreate when called from AbsolutePath so we do not get the DotDotOutOfScope error when traversing beyond the root.</remarks>
        /// <param name="table">StringTable instance.</param>
        /// <param name="relativePath">Relative path to pass in.</param>
        /// <param name="result">Output relative path after parsing.</param>
        /// <param name="characterWithError">Output the character that had the error.</param>
        /// <param name="allowDotDotOutOfScope">Whether to allow the function to parse .. beyond the root.</param>
        /// <returns>Return the parser result indicating success, or what was wrong with the parsing.</returns>
        internal static ParseResult TryCreateInternal <T>(StringTable table, T relativePath, out RelativePath result, out int characterWithError, bool allowDotDotOutOfScope = false)
            where T : struct, ICharSpan <T>
        {
            Contract.RequiresNotNull(table);
            Contract.Ensures((Contract.Result <ParseResult>() == ParseResult.Success) == Contract.ValueAtReturn(out result).IsValid);

            using (var wrap = Pools.GetStringIdList())
            {
                List <StringId> components = wrap.Instance;

                int index = 0;
                int start = 0;
                while (index < relativePath.Length)
                {
                    var ch = relativePath[index];

                    // trivial reject of invalid characters
                    if (!IsValidRelativePathChar(ch))
                    {
                        characterWithError = index;
                        result             = Invalid;
                        return(ParseResult.FailureDueToInvalidCharacter);
                    }

                    if (ch == '\\' || ch == '/')
                    {
                        // found a component separator
                        if (index > start)
                        {
                            // make a path atom out of [start..index]
                            PathAtom.ParseResult papr = PathAtom.TryCreate(
                                table,
                                relativePath.Subsegment(start, index - start),
                                out PathAtom atom,
                                out int charError);

                            if (papr != PathAtom.ParseResult.Success)
                            {
                                characterWithError = index + charError;
                                result             = Invalid;
                                return(ParseResult.FailureDueToInvalidCharacter);
                            }

                            components.Add(atom.StringId);
                        }

                        // skip over the slash
                        index++;
                        start = index;
                        continue;
                    }

                    if (ch == '.' && index == start)
                    {
                        // component starts with a .
                        if ((index == relativePath.Length - 1) ||
                            (relativePath[index + 1] == '\\') ||
                            (relativePath[index + 1] == '/'))
                        {
                            // component is a sole . so skip it
                            index += 2;
                            start  = index;
                            continue;
                        }

                        if (relativePath[index + 1] == '.')
                        {
                            // component starts with ..
                            if ((index == relativePath.Length - 2) ||
                                (relativePath[index + 2] == '\\') ||
                                (relativePath[index + 2] == '/'))
                            {
                                // component is a sole .. so try to go up
                                if (components.Count == 0 && !allowDotDotOutOfScope)
                                {
                                    characterWithError = index;
                                    result             = Invalid;
                                    return(ParseResult.FailureDueToDotDotOutOfScope);
                                }

                                if (components.Count != 0)
                                {
                                    components.RemoveAt(components.Count - 1);
                                }

                                index += 3;
                                start  = index;
                                continue;
                            }
                        }
                    }

                    index++;
                }

                if (index > start)
                {
                    // make a path atom out of [start..index]
                    PathAtom.ParseResult papr = PathAtom.TryCreate(
                        table,
                        relativePath.Subsegment(start, index - start),
                        out PathAtom atom,
                        out int charError);

                    if (papr != PathAtom.ParseResult.Success)
                    {
                        characterWithError = index + charError;
                        result             = Invalid;
                        return(ParseResult.FailureDueToInvalidCharacter);
                    }

                    components.Add(atom.StringId);
                }

                result = new RelativePath(components.ToArray());

                characterWithError = -1;
                return(ParseResult.Success);
            }
        }
Exemple #3
0
        /// <summary>
        /// Try to create a PartialSymbol from a string.
        /// </summary>
        /// <returns>Return the parser result indicating success, or what was wrong with the parsing.</returns>
        public static ParseResult TryCreate <T>(StringTable table, T partialSymbol, out PartialSymbol result, out int characterWithError)
            where T : struct, ICharSpan <T>
        {
            Contract.RequiresNotNull(table);

            using (var wrap = Pools.GetStringIdList())
            {
                List <StringId> components = wrap.Instance;

                int index = 0;
                int start = 0;
                int last  = partialSymbol.Length - 1;
                while (index < partialSymbol.Length)
                {
                    var ch = partialSymbol[index];

                    // trivial reject of invalid characters
                    if (!SymbolCharacters.IsValidDottedIdentifierChar(ch))
                    {
                        characterWithError = index;
                        result             = Invalid;
                        return(ParseResult.FailureDueToInvalidCharacter);
                    }

                    if (ch == SymbolCharacters.DottedIdentifierSeparatorChar)
                    {
                        // found a component separator
                        if (index == start || index == last)
                        {
                            characterWithError = index;
                            result             = Invalid;
                            return(ParseResult.LeadingOrTrailingDot);
                        }
                        else if (index > start)
                        {
                            // make a identifier atom out of [start..index]
                            SymbolAtom             atom;
                            int                    charError;
                            SymbolAtom.ParseResult papr = SymbolAtom.TryCreate(
                                table,
                                partialSymbol.Subsegment(start, index - start),
                                out atom,
                                out charError);

                            if (papr != SymbolAtom.ParseResult.Success)
                            {
                                characterWithError = index + charError;
                                result             = Invalid;
                                return(ParseResult.FailureDueToInvalidCharacter);
                            }

                            components.Add(atom.StringId);
                        }

                        // skip over the dot
                        index++;
                        start = index;
                        continue;
                    }

                    index++;
                }

                if (index > start)
                {
                    // make a identifier atom out of [start..index]
                    SymbolAtom             atom;
                    int                    charError;
                    SymbolAtom.ParseResult papr = SymbolAtom.TryCreate(
                        table,
                        partialSymbol.Subsegment(start, index - start),
                        out atom,
                        out charError);

                    if (papr != SymbolAtom.ParseResult.Success)
                    {
                        characterWithError = index + charError;
                        result             = Invalid;
                        return(ParseResult.FailureDueToInvalidCharacter);
                    }

                    components.Add(atom.StringId);
                }

                result = new PartialSymbol(components.ToArray());

                characterWithError = -1;
                return(ParseResult.Success);
            }
        }