SimpleReadonlyDocument (ITextSource readOnlyTextSource, string fileName, string mimeType)
		{
			textSource = readOnlyTextSource;
			FileName = fileName;
			MimeType = mimeType;
			Initalize (readOnlyTextSource.Text);
		}
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();
            Stack<int> startOffsets = new Stack<int>();
            int lastNewLineOffset = 0;
            int len = document.TextLength;

            foreach(var segment in _tokenservice.GetSegments()) {
                if(segment.Token == Token.BlockOpen || segment.Token == Token.BlockClosed) {

                    if(segment.Token == _openingBrace) {
                        startOffsets.Push(segment.Range.Offset);
                    } else if(segment.Token == _closingBrace && startOffsets.Count > 0) {
                        int startOffset = startOffsets.Pop();
                        // don't fold if opening and closing brace are on the same line
                        if(startOffset < lastNewLineOffset) {

                            int endoffset = segment.Range.Offset + 1;
                            if(startOffset < len && endoffset < len) {
                                newFoldings.Add(new NewFolding(startOffset, endoffset));
                            }
                        }
                    }
                } else if(segment.Token == Token.NewLine) {
                    lastNewLineOffset = segment.Range.Offset;
                }
            }

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
Пример #3
0
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            if (document == null)
                throw new ArgumentNullException("document");

            var newFoldings = new List<NewFolding>();

            var startOffsets = new Stack<int>();
            int lastNewLineOffset = 0;
            char openingBrace = OpeningBrace;
            char closingBrace = ClosingBrace;
            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
		void CheckNewLinesForConsistency(object state)
		{
			int numCRLF = 0;
			int numCR = 0;
			int numLF = 0;
			
			int offset = 0;
			while (offset >= 0) {
				string type;
				offset = TextUtilities.FindNextNewLine(snapshot, offset, out type);
				if (type != null) {
					offset += type.Length;
					switch (type) {
						case "\r\n":
							numCRLF++;
							break;
						case "\n":
							numLF++;
							break;
						case "\r":
							numCR++;
							break;
					}
				}
			}
			snapshot = null; // we don't need the snapshot anymore, allow the GC to collect it
			
			// don't allow mac-style newlines; accept either unix or windows-style newlines but avoid mixing them
			bool isConsistent = (numCR == 0) && (numLF == 0 || numCRLF == 0);
			if (!isConsistent) {
				SharpDevelop.Gui.WorkbenchSingleton.SafeThreadAsyncCall(ShowInconsistentWarning, numLF > numCRLF);
			}
		}
Пример #5
0
		/// <summary>
		///     Gets a single indentation segment starting at <paramref name="offset" /> - at most one tab
		///     or <paramref name="indentationSize" /> spaces.
		/// </summary>
		/// <param name="textSource">The text source.</param>
		/// <param name="offset">The offset where the indentation segment starts.</param>
		/// <param name="indentationSize">The size of an indentation unit. See <see cref="TextEditorOptions.IndentationSize" />.</param>
		/// <returns>
		///     The indentation segment.
		///     If there is no indentation character at the specified <paramref name="offset" />,
		///     an empty segment is returned.
		/// </returns>
		public static ISegment GetSingleIndentationSegment(ITextSource textSource, int offset, int indentationSize)
		{
			if (textSource == null)
				throw new ArgumentNullException("textSource");
			var pos = offset;
			while (pos < textSource.TextLength)
			{
				var c = textSource.GetCharAt(pos);
				if (c == '\t')
				{
					if (pos == offset)
						return new SimpleSegment(offset, 1);
					break;
				}
				if (c == ' ')
				{
					if (pos - offset >= indentationSize)
						break;
				}
				else
				{
					break;
				}
				// continue only if c==' ' and (pos-offset)<tabSize
				pos++;
			}
			return new SimpleSegment(offset, pos - offset);
		}
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();

            Stack<int> startOffsets = new Stack<int>();
            int lastNewLineOffset = 0;
            char openingBrace = this.OpeningBrace;
            char closingBrace = this.ClosingBrace;
            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                bool isFirstInLine = IsFirstInLine(document, i);
                if (c == openingBrace && isFirstInLine)
                    startOffsets.Push(i);
                else if (c == closingBrace && isFirstInLine && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
        /// <summary>
        ///     Create <see cref="NewFolding" />s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            var newFoldings = new List<NewFolding>();

            var startOffsets = new Stack<int>();
            var lastNewLineOffset = 0;
            var openingBrace = OpeningBrace;
            var closingBrace = ClosingBrace;
            for (var i = 0; i < document.TextLength; i++)
            {
                var c = document.GetCharAt(i);
                if (c == openingBrace)
                    startOffsets.Push(i);
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    var startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                }
                else if (c == '\n' || c == '\r')
                    lastNewLineOffset = i + 1;
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
Пример #8
0
 /// <summary>
 /// Finds the next new line character starting at offset.
 /// </summary>
 /// <param name="text">The text source to search in.</param>
 /// <param name="offset">The starting offset for the search.</param>
 /// <param name="newLineType">The string representing the new line that was found, or null if no new line was found.</param>
 /// <returns>The position of the first new line starting at or after <paramref name="offset"/>,
 /// or -1 if no new line was found.</returns>
 public static int FindNextNewLine(ITextSource text, int offset, out string newLineType)
 {
     if (text == null)
         throw new ArgumentNullException(nameof(text));
     if (offset < 0 || offset > text.TextLength)
         throw new ArgumentOutOfRangeException(nameof(offset), offset, "offset is outside of text source");
     SimpleSegment s = NewLineFinder.NextNewLine(text, offset);
     if (s == SimpleSegment.Invalid)
     {
         newLineType = null;
         return -1;
     }
     else
     {
         if (s.Length == 2)
         {
             newLineType = "\r\n";
         }
         else if (text.GetCharAt(s.Offset) == '\n')
         {
             newLineType = "\n";
         }
         else
         {
             newLineType = "\r";
         }
         return s.Offset;
     }
 }
Пример #9
0
        public MenuText(ContentManager content, Vector2 position, ITextSource textSource)
        {
            this.position = position;
            this.textSource = textSource;

            font = content.Load<SpriteFont>("Fonts/Menu_Font");
        }
Пример #10
0
 /// <summary>
 /// See 8.2.4 Tokenization
 /// </summary>
 /// <param name="source">The source code manager.</param>
 public HtmlTokenizer(ITextSource source)
     : base(source)
 {
     _state = HtmlParseMode.PCData;
     _acceptsCharacterData = false;
     _buffer = new StringBuilder();
 }
Пример #11
0
 public TagReader(AXmlParser tagSoupParser, ITextSource input, bool collapseProperlyNestedElements)
     : base(input)
 {
     this.tagSoupParser = tagSoupParser;
     if (collapseProperlyNestedElements)
         elementNameStack = new Stack<string>();
 }
Пример #12
0
        /// <summary>
        /// Skips the white space backwards.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">The offset of the first character to check.</param>
        /// <returns>The offset of the first non-whitespace character before <paramref name="offset"/>.</returns>
        public int SkipWhiteSpaceBackwards(ITextSource document, int offset)
        {
            while (offset >= 1 && char.IsWhiteSpace(document.GetCharAt(offset)))
                --offset;

            return offset;
        }
Пример #13
0
		public ParseInformation Parse(
			FileName fileName,
			ITextSource fileContent,
			TypeScriptProject project,
			IEnumerable<TypeScriptFile> files)
		{
			try {
				using (TypeScriptContext context = contextFactory.CreateContext()) {
					context.AddFile(fileName, fileContent.Text);
					context.RunInitialisationScript();
					
					NavigationBarItem[] navigation = context.GetNavigationInfo(fileName);
					var unresolvedFile = new TypeScriptUnresolvedFile(fileName);
					unresolvedFile.AddNavigation(navigation, fileContent);
					
					if (project != null) {
						context.AddFiles(files);
						var document = new TextDocument(fileContent);
						Diagnostic[] diagnostics = context.GetDiagnostics(fileName, project.GetOptions());
						TypeScriptService.TaskService.Update(diagnostics, fileName);
					}
					
					return new ParseInformation(unresolvedFile, fileContent.Version, true);
				}
			} catch (Exception ex) {
				Console.WriteLine(ex.ToString());
				LoggingService.Debug(ex.ToString());
			}
			
			return new ParseInformation(
				new TypeScriptUnresolvedFile(fileName),
				fileContent.Version,
				true);
		}
Пример #14
0
        public DocumentViewModel(ITextSource document)
        {
            Ensure.ArgumentNotNull(document, "document");

            Document = document;
            Document.TextChanged += OnTextChanged;
        }
Пример #15
0
        protected IEnumerable<NewFolding> getOffsets(char opening, char closing, ITextSource document)
        {
            List<NewFolding> ret    = new List<NewFolding>();
            Stack<int> openings     = new Stack<int>();
            bool multiline          = false; //flag of multiline braces

            for(int pos = 0; pos < document.TextLength; ++pos)
            {
                char c = document.GetCharAt(pos);

                if(c == opening) {
                    openings.Push(pos + 1);
                    multiline = false;
                }
                else if(char.IsControl(c)) {
                    multiline = true;
                }
                else if(openings.Count > 0 && c == closing)
                {
                    int offset = openings.Pop();
                    if(multiline) {
                        ret.Add(new NewFolding(offset, pos));
                    }
                }
            }
            return ret;
        }
    public IEnumerable<ISearchResult> FindAllValidating(ITextSource document, int offset, int length)
    {
      using (var stream = document.CreateReader())
      {
        var doc = (IDocument)document;
        var xmlDoc = new XPathDocument(stream); ;
        var navigator = xmlDoc.CreateNavigator();

        XPathExpression expr = null;
        XPathNodeIterator iterator;
        try
        {
          expr = navigator.Compile(_xPath);
          iterator = navigator.Select(expr);
        }
        catch (System.Xml.XPath.XPathException)
        {
          yield break;
        }

        while (iterator.MoveNext())
        {
          var current = iterator.Current;
          var segment = XmlSegment(doc, ((IXmlLineInfo)current).LineNumber, ((IXmlLineInfo)current).LinePosition);
          if (segment != null && segment.Offset >= offset && segment.EndOffset <= (offset + length))
          {
            yield return new XPathSearchResult()
            {
              StartOffset = segment.Offset,
              Length = segment.Length
            };
          }
        }
      }
    }
Пример #17
0
		public ParseInformation Parse(FileName fileName, ITextSource fileContent, bool fullParseInformationRequested,
		                              IProject parentProject, CancellationToken cancellationToken)
		{
			var csharpProject = parentProject as CSharpProject;
			
			CSharpParser parser = new CSharpParser(csharpProject != null ? csharpProject.CompilerSettings : null);
			parser.GenerateTypeSystemMode = !fullParseInformationRequested;
			
			SyntaxTree cu = parser.Parse(fileContent, fileName);
			cu.Freeze();
			
			CSharpUnresolvedFile file = cu.ToTypeSystem();
			ParseInformation parseInfo;
			
			if (fullParseInformationRequested)
				parseInfo = new CSharpFullParseInformation(file, fileContent.Version, cu);
			else
				parseInfo = new ParseInformation(file, fileContent.Version, fullParseInformationRequested);
			
			IDocument document = fileContent as IDocument;
			AddCommentTags(cu, parseInfo.TagComments, fileContent, parseInfo.FileName, ref document);
			if (fullParseInformationRequested) {
				if (document == null)
					document = new ReadOnlyDocument(fileContent, parseInfo.FileName);
				((CSharpFullParseInformation)parseInfo).newFoldings = CreateNewFoldings(cu, document);
			}
			
			return parseInfo;
		}
Пример #18
0
		/// <summary>
		/// Creates a new StringBuilderDocument with the initial text copied from the specified text source.
		/// </summary>
		public StringBuilderDocument(ITextSource textSource)
		{
			if (textSource == null)
				throw new ArgumentNullException("textSource");
			b = new StringBuilder(textSource.TextLength);
			textSource.WriteTextTo(new StringWriter(b));
		}
Пример #19
0
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            var newFoldings = new List<NewFolding>();

            var template = FoldingTemplates[0];
            var regexOpenFolding = new Regex(template.OpeningPhrase);
            var matchesOpenFolding = regexOpenFolding.Matches(document.Text);

            var regexCloseFolding = new Regex(template.ClosingPhrase);
            var matchesCloseFolding = regexCloseFolding.Matches(document.Text);

            var currentOpenIndex = 0;
            for (var i = 0; i < matchesCloseFolding.Count && currentOpenIndex < matchesOpenFolding.Count; i++)
            {
                if (matchesOpenFolding[currentOpenIndex].Index >= matchesCloseFolding[i].Index)
                    continue;
                var folding = new NewFolding(matchesOpenFolding[currentOpenIndex].Index + 1,
                    matchesCloseFolding[i].Index + 10)
                {
                    DefaultClosed = template.IsDefaultFolded,
                    Name = template.Name
                };
                newFoldings.Add(folding);
                while (currentOpenIndex < matchesOpenFolding.Count &&
                    matchesOpenFolding[currentOpenIndex].Index < matchesCloseFolding[i].Index)
                {
                    currentOpenIndex++;
                }
            }
            return newFoldings;
        }
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();

            Stack<int> startOffsets = new Stack<int>();
            int lastNewLineOffset = 0;
            char openingBrace = OpeningBrace;
            char closingBrace = ClosingBrace;

            foreach (var startKeyword in foldingKeywords.Keys)
            {
                int lastKeywordPos = 0;
                int pos = 0;

                while ((pos = document.Text.IndexOf(startKeyword, pos)) > lastKeywordPos)
                {
                    int endOffset = document.Text.IndexOf(foldingKeywords[startKeyword], pos);

                    if (endOffset > pos)
                    {
                        var offset = document.Text.IndexOf("\r\n", pos);
                        var name = document.Text.Substring(pos + 8, offset - (pos + 8));
                        var folding = new NewFolding(pos, endOffset + 10);
                        folding.Name = name;

                        // Add the folding
                        newFoldings.Add(folding);
                    }

                    lastKeywordPos = pos;
                }
            }

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));

            return newFoldings;
        }
Пример #21
0
 protected TextSourceAdapter(ITextSource textSource)
 {
     if (textSource == null)
     {
         throw new ArgumentNullException("textSource");
     }
     TextSource = textSource;
 }
Пример #22
0
		/// <summary>
		/// Creates a new TextChangeEventArgs object.
		/// </summary>
		public TextChangeEventArgs(int offset, ITextSource removedText, ITextSource insertedText)
		{
			if (offset < 0)
				throw new ArgumentOutOfRangeException("offset", offset, "offset must not be negative");
			this.offset = offset;
			this.removedText = removedText ?? StringTextSource.Empty;
			this.insertedText = insertedText ?? StringTextSource.Empty;
		}
Пример #23
0
 public TextScanner(ITextSource textSource)
 {
     if (textSource == null)
     {
         throw new ArgumentNullException(nameof(textSource));
     }
     this.textSource = textSource;
 }
Пример #24
0
		public IEnumerable<ISearchResult> FindAll(ITextSource document, int offset, int length)
		{
			int endOffset = offset + length;
			foreach (Match result in searchPattern.Matches(document.Text)) {
				if (offset <= result.Index && endOffset >= (result.Length + result.Index))
					yield return new SearchResult { StartOffset = result.Index, Length = result.Length, Data = result };
			}
		}
Пример #25
0
		/// <summary>
		/// Parses a document incrementally into a flat list of tags.
		/// </summary>
		/// <param name="oldParserState">The parser state from a previous call to ParseIncremental(). Use null for the first call.</param>
		/// <param name="newTextSource">The text source for the new document version.</param>
		/// <param name="newParserState">Out: the new parser state, pass this to the next ParseIncremental() call.</param>
		/// <param name="cancellationToken">Optional: cancellation token.</param>
		/// <returns>Parsed tag soup.</returns>
		public IList<AXmlObject> ParseTagSoupIncremental(
			IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState,
			CancellationToken cancellationToken = default(CancellationToken))
		{
			if (newTextSource == null)
				throw new ArgumentNullException("newTextSource");
			var internalObjects = InternalParseIncremental(oldParserState, newTextSource, out newParserState, false, cancellationToken);
			return CreatePublic(internalObjects);
		}
Пример #26
0
		/// <summary>
		/// Parses a document into a flat list of tags.
		/// </summary>
		/// <returns>Parsed tag soup.</returns>
		public IList<AXmlObject> ParseTagSoup(ITextSource textSource,
		                                      CancellationToken cancellationToken = default(CancellationToken))
		{
			if (textSource == null)
				throw new ArgumentNullException("textSource");
			var reader = new TagReader(this, textSource, false);
			var internalObjects = reader.ReadAllObjects(cancellationToken);
			return CreatePublic(internalObjects);
		}
Пример #27
0
 public IList<FoldingRegion> GetFolds(ITextSource textSource)
 {
     try {
         GetFolds(textSource.CreateReader());
         return folds;
     } catch (XmlException) {
     }
     return null;
 }
Пример #28
0
 /// <summary>
 /// Parses a document.
 /// </summary>
 public AXmlDocument Parse(ITextSource textSource, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (textSource == null)
         throw new ArgumentNullException("textSource");
     var reader = new TagReader(this, textSource, true);
     var internalObjects = reader.ReadAllObjects(cancellationToken);
     var heuristic = new TagMatchingHeuristics(textSource);
     return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects, cancellationToken));
 }
Пример #29
0
        public void UpdateFoldings(FoldingManager manager, ITextSource document)
        {
            if (manager == null)
                throw new ArgumentNullException("manager");

            int firstErrorOffset;
            IEnumerable<NewFolding> newFoldings = CreateNewFoldings(document, out firstErrorOffset);
            manager.UpdateFoldings(newFoldings, firstErrorOffset);
        }
Пример #30
0
		/// <summary>
		/// Creates a new DocumentationComment.
		/// </summary>
		/// <param name="xml">The XML text.</param>
		/// <param name="context">Context for resolving cref attributes.</param>
		public DocumentationComment(string xml, ITypeResolveContext context)
		{
			if (xml == null)
				throw new ArgumentNullException("xml");
			if (context == null)
				throw new ArgumentNullException("context");
			this.xml = new StringTextSource(xml);
			this.context = context;
		}
Пример #31
0
 public CSharpDocumentationComment(ITextSource xmlDoc, ITypeResolveContext context) : base(xmlDoc, context)
 {
 }
Пример #32
0
        ProjectEntry DoParse(ITextSource fileContent, IProject parentProject, bool fullParseInformationRequested,
                             CancellationToken cancellationToken)
        {
            if (parser == null)
            {
                return(default(ProjectEntry));
            }

            if (fileContent == null)
            {
                // No file content was specified. Because the callers of this method already check for currently open files,
                // we can assume that the file isn't open and simply read it from disk.
                try {
                    fileContent = SD.FileService.GetFileContentFromDisk(fileName, cancellationToken);
                } catch (IOException) {
                    // It is possible that the file gets deleted/becomes inaccessible while a background parse
                    // operation is enqueued, so we have to handle IO exceptions.
                    return(default(ProjectEntry));
                } catch (UnauthorizedAccessException) {
                    return(default(ProjectEntry));
                }
            }

            ProjectEntry result;

            rwLock.EnterUpgradeableReadLock();
            try {
                int index             = FindIndexForProject(parentProject);
                int versionComparison = CompareVersions(fileContent.Version);
                if (versionComparison > 0 || index < 0)
                {
                    // We're going backwards in time, or are requesting a project that is not an owner
                    // for this entry.
                    var parseInfo = ParseWithExceptionHandling(fileContent, fullParseInformationRequested, parentProject, cancellationToken);
                    FreezableHelper.Freeze(parseInfo.UnresolvedFile);
                    return(new ProjectEntry(parentProject, parseInfo.UnresolvedFile, parseInfo));
                }
                else
                {
                    if (versionComparison == 0 && index >= 0)
                    {
                        // Ensure we have parse info for the specified project (entry.UnresolvedFile is null for newly registered projects)
                        // If full parse info is requested, ensure we have full parse info.
                        if (entries[index].UnresolvedFile != null && !(fullParseInformationRequested && entries[index].CachedParseInformation == null))
                        {
                            // We already have the requested version parsed, just return it:
                            return(entries[index]);
                        }
                    }
                }

                ParseInformationEventArgs[] results = new ParseInformationEventArgs[entries.Count];
                for (int i = 0; i < entries.Count; i++)
                {
                    var parseInfo = ParseWithExceptionHandling(fileContent, fullParseInformationRequested, entries[i].Project, cancellationToken);
                    if (parseInfo == null)
                    {
                        throw new NullReferenceException(parser.GetType().Name + ".Parse() returned null");
                    }
                    if (fullParseInformationRequested && !parseInfo.IsFullParseInformation)
                    {
                        throw new InvalidOperationException(parser.GetType().Name + ".Parse() did not return full parse info as requested.");
                    }
                    OnDiskTextSourceVersion onDiskVersion = fileContent.Version as OnDiskTextSourceVersion;
                    if (onDiskVersion != null)
                    {
                        parseInfo.UnresolvedFile.LastWriteTime = onDiskVersion.LastWriteTime;
                    }
                    FreezableHelper.Freeze(parseInfo.UnresolvedFile);
                    results[i] = new ParseInformationEventArgs(entries[i].Project, entries[i].UnresolvedFile, parseInfo);
                }

                // Only if all parse runs succeeded, register the parse information.
                rwLock.EnterWriteLock();
                try {
                    currentVersion = fileContent.Version;
                    for (int i = 0; i < entries.Count; i++)
                    {
                        if (fullParseInformationRequested || (entries[i].CachedParseInformation != null && results[i].NewParseInformation.IsFullParseInformation))
                        {
                            entries[i] = new ProjectEntry(entries[i].Project, results[i].NewUnresolvedFile, results[i].NewParseInformation);
                        }
                        else
                        {
                            entries[i] = new ProjectEntry(entries[i].Project, results[i].NewUnresolvedFile, null);
                        }
                        if (entries[i].Project != null)
                        {
                            entries[i].Project.OnParseInformationUpdated(results[i]);
                        }
                        parserService.RaiseParseInformationUpdated(results[i]);
                    }
                    result = entries[index];
                } finally {
                    rwLock.ExitWriteLock();
                }
            } finally {
                rwLock.ExitUpgradeableReadLock();
            }
            parserService.RegisterForCacheExpiry(this);
            return(result);
        }
Пример #33
0
 void IDocument.Replace(int offset, int length, ITextSource newText)
 {
     throw new NotSupportedException();
 }
Пример #34
0
 void IDocument.Insert(int offset, ITextSource text)
 {
     throw new NotSupportedException();
 }
Пример #35
0
 public void FindLocalReferences(ParseInformation parseInfo, ITextSource fileContent, IVariable variable, ICompilation compilation, Action <SearchResultMatch> callback, CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
Пример #36
0
 // Methods
 public BookMarks(ITextSource Owner)
 {
     this.owner = Owner;
 }
Пример #37
0
 public TokenReader(ITextSource input)
 {
     this.input       = input;
     this.inputLength = input.TextLength;
 }
        public static void Run(ITextSource originalXmlFile)
        {
            int seed;

            lock (sharedRnd) {
                seed = sharedRnd.Next();
            }
            Console.WriteLine(seed);
            Random rnd = new Random(seed);

            AXmlParser             parser      = new AXmlParser();
            StringBuilder          b           = new StringBuilder(originalXmlFile.Text);
            IncrementalParserState parserState = null;
            var       versionProvider          = new TextSourceVersionProvider();
            int       totalCharactersParsed    = 0;
            int       totalCharactersChanged   = originalXmlFile.TextLength;
            TimeSpan  incrementalParseTime     = TimeSpan.Zero;
            TimeSpan  nonIncrementalParseTime  = TimeSpan.Zero;
            Stopwatch w = new Stopwatch();

            for (int iteration = 0; iteration < 100; iteration++)
            {
                totalCharactersParsed += b.Length;
                var textSource = new StringTextSource(b.ToString(), versionProvider.CurrentVersion);
                w.Restart();
                var incrementalResult = parser.ParseIncremental(parserState, textSource, out parserState);
                w.Stop();
                incrementalParseTime += w.Elapsed;
                w.Restart();
                var nonIncrementalResult = parser.Parse(textSource);
                w.Stop();
                nonIncrementalParseTime += w.Elapsed;
                CompareResults(incrementalResult, nonIncrementalResult);

                incrementalResult.AcceptVisitor(new ValidationVisitor(textSource));

                // Randomly mutate the file:

                List <TextChangeEventArgs> changes = new List <TextChangeEventArgs>();
                int modifications = rnd.Next(0, 25);
                int offset        = 0;
                for (int i = 0; i < modifications; i++)
                {
                    if (i == 0 || rnd.Next(0, 10) == 0)
                    {
                        offset = rnd.Next(0, b.Length);
                    }
                    else
                    {
                        offset += rnd.Next(0, Math.Min(10, b.Length - offset));
                    }
                    int originalOffset = rnd.Next(0, originalXmlFile.TextLength);
                    int insertionLength;
                    int removalLength;
                    switch (rnd.Next(0, 21) / 10)
                    {
                    case 0:
                        removalLength   = 0;
                        insertionLength = rnd.Next(0, Math.Min(50, originalXmlFile.TextLength - originalOffset));
                        break;

                    case 1:
                        removalLength   = rnd.Next(0, Math.Min(20, b.Length - offset));
                        insertionLength = rnd.Next(0, Math.Min(20, originalXmlFile.TextLength - originalOffset));
                        break;

                    default:
                        removalLength   = rnd.Next(0, b.Length - offset);
                        insertionLength = rnd.Next(0, originalXmlFile.TextLength - originalOffset);
                        break;
                    }
                    string removedText = b.ToString(offset, removalLength);
                    b.Remove(offset, removalLength);
                    string insertedText = originalXmlFile.GetText(originalOffset, insertionLength);
                    b.Insert(offset, insertedText);
                    versionProvider.AppendChange(new TextChangeEventArgs(offset, removedText, insertedText));
                    totalCharactersChanged += insertionLength;
                }
            }
            Console.WriteLine("Incremental parse time:     " + incrementalParseTime + " for " + totalCharactersChanged + " characters changed");
            Console.WriteLine("Non-Incremental parse time: " + nonIncrementalParseTime + " for " + totalCharactersParsed + " characters");
        }
Пример #39
0
        protected override ITextSource FormatImplementation(PolicyContainer policyParent, string mimeType, ITextSource input, int startOffset, int length)
        {
            var chain      = DesktopService.GetMimeTypeInheritanceChain(mimeType);
            var policy     = policyParent.Get <CSharpFormattingPolicy> (chain);
            var textPolicy = policyParent.Get <TextStylePolicy> (chain);

            return(new StringTextSource(FormatText(policy.CreateOptions(textPolicy), input.Text, startOffset, startOffset + length)));
        }
Пример #40
0
 public ISearchResult FindNext(ITextSource document, int offset, int length)
 {
     return(FindAll(document, offset, length).FirstOrDefault());
 }
Пример #41
0
 static bool IsWordBorder(ITextSource document, int offset)
 {
     return(TextUtilities.GetNextCaretPosition(document, offset - 1, LogicalDirection.Forward, CaretPositioningMode.WordBorder) == offset);
 }
Пример #42
0
        Task RunUpdateTask(ITextSource input, IDocumentLine startLine, int endOffset, CancellationToken token)
        {
            return(Task.Run(delegate {
                var matches = new List <(UrlType, Match, IDocumentLine)> ();
                var line = startLine;
                int o = 0;
                while (line != null && line.Offset <= endOffset)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    string lineText = input.GetTextAt(line.Offset, line.Length);
                    var match = UrlRegex.Match(lineText);
                    while (match.Success)
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }
                        matches.Add((UrlType.Url, match, line));
                        o = match.Index + match.Length;
                        var len = line.Length - o;
                        if (len <= 0)
                        {
                            break;
                        }
                        match = UrlRegex.Match(lineText, o, len);
                    }

                    o = 0;
                    match = MailRegex.Match(lineText);
                    while (match.Success)
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }
                        matches.Add((UrlType.Email, match, line));
                        o = match.Index + match.Length;
                        var len = line.Length - o;
                        if (len <= 0)
                        {
                            break;
                        }
                        match = MailRegex.Match(lineText, o, len);
                    }
                    line = line.NextLine;
                }

                Runtime.RunInMainThread(delegate {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    line = startLine;
                    while (line != null && line.Offset <= endOffset)
                    {
                        foreach (var u in Editor.GetLineMarkers(line).OfType <IUrlTextLineMarker> ())
                        {
                            Editor.RemoveMarker(u);
                            markers.Remove(u);
                        }
                        line = line.NextLine;
                    }

                    foreach (var m in matches)
                    {
                        var startCol = m.Item2.Index;
                        var url = m.Item2.Value;
                        var marker = Editor.TextMarkerFactory.CreateUrlTextMarker(Editor, url, m.Item1, "url", startCol, startCol + m.Item2.Length);
                        markers.Add(marker);
                        Editor.AddMarker(m.Item3, marker);
                    }
                    src.Remove(startLine.Offset);
                });
            }));
 public PrioritizedTextSource(ITextSource source, int priority = 0)
 {
     Source   = source;
     Priority = priority;
 }
Пример #44
0
        /// <summary>
        /// Gets the next caret position.
        /// </summary>
        /// <param name="textSource">The text source.</param>
        /// <param name="offset">The start offset inside the text source.</param>
        /// <param name="direction">The search direction (forwards or backwards).</param>
        /// <param name="mode">The mode for caret positioning.</param>
        /// <returns>The offset of the next caret position, or -1 if there is no further caret position
        /// in the text source.</returns>
        /// <remarks>
        /// This method is NOT equivalent to the actual caret movement when using VisualLine.GetNextCaretPosition.
        /// In real caret movement, there are additional caret stops at line starts and ends. This method
        /// treats linefeeds as simple whitespace.
        /// </remarks>
        public static int GetNextCaretPosition(ITextSource textSource, int offset, LogicalDirection direction, CaretPositioningMode mode)
        {
            if (textSource == null)
            {
                throw new ArgumentNullException("textSource");
            }
            switch (mode)
            {
            case CaretPositioningMode.Normal:
            case CaretPositioningMode.EveryCodepoint:
            case CaretPositioningMode.WordBorder:
            case CaretPositioningMode.WordBorderOrSymbol:
            case CaretPositioningMode.WordStart:
            case CaretPositioningMode.WordStartOrSymbol:
                break;                         // OK

            default:
                throw new ArgumentException("Unsupported CaretPositioningMode: " + mode, "mode");
            }
            if (direction != LogicalDirection.Backward &&
                direction != LogicalDirection.Forward)
            {
                throw new ArgumentException("Invalid LogicalDirection: " + direction, "direction");
            }
            int textLength = textSource.TextLength;

            if (textLength <= 0)
            {
                // empty document? has a normal caret position at 0, though no word borders
                if (IsNormal(mode))
                {
                    if (offset > 0 && direction == LogicalDirection.Backward)
                    {
                        return(0);
                    }
                    if (offset < 0 && direction == LogicalDirection.Forward)
                    {
                        return(0);
                    }
                }
                return(-1);
            }
            while (true)
            {
                int nextPos = (direction == LogicalDirection.Backward) ? offset - 1 : offset + 1;

                // return -1 if there is no further caret position in the text source
                // we also need this to handle offset values outside the valid range
                if (nextPos < 0 || nextPos > textLength)
                {
                    return(-1);
                }

                // check if we've run against the textSource borders.
                // a 'textSource' usually isn't the whole document, but a single VisualLineElement.
                if (nextPos == 0)
                {
                    // at the document start, there's only a word border
                    // if the first character is not whitespace
                    if (IsNormal(mode) || !char.IsWhiteSpace(textSource.GetCharAt(0)))
                    {
                        return(nextPos);
                    }
                }
                else if (nextPos == textLength)
                {
                    // at the document end, there's never a word start
                    if (mode != CaretPositioningMode.WordStart && mode != CaretPositioningMode.WordStartOrSymbol)
                    {
                        // at the document end, there's only a word border
                        // if the last character is not whitespace
                        if (IsNormal(mode) || !char.IsWhiteSpace(textSource.GetCharAt(textLength - 1)))
                        {
                            return(nextPos);
                        }
                    }
                }
                else
                {
                    char charBefore = textSource.GetCharAt(nextPos - 1);
                    char charAfter  = textSource.GetCharAt(nextPos);
                    // Don't stop in the middle of a surrogate pair
                    if (!char.IsSurrogatePair(charBefore, charAfter))
                    {
                        CharacterClass classBefore = GetCharacterClass(charBefore);
                        CharacterClass classAfter  = GetCharacterClass(charAfter);
                        // get correct class for characters outside BMP:
                        if (char.IsLowSurrogate(charBefore) && nextPos >= 2)
                        {
                            classBefore = GetCharacterClass(textSource.GetCharAt(nextPos - 2), charBefore);
                        }
                        if (char.IsHighSurrogate(charAfter) && nextPos + 1 < textLength)
                        {
                            classAfter = GetCharacterClass(charAfter, textSource.GetCharAt(nextPos + 1));
                        }
                        if (StopBetweenCharacters(mode, classBefore, classAfter))
                        {
                            return(nextPos);
                        }
                    }
                }
                // we'll have to continue searching...
                offset = nextPos;
            }
        }
Пример #45
0
 void IDocument.Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType)
 {
     throw new NotSupportedException();
 }
Пример #46
0
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            var         newFoldings       = new List <NewFolding>();
            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            int         CommentMode       = 0; // 0 = None, 1 = Single, 2 = Multi, 3 = String

            for (int i = 0; i < document.TextLength; ++i)
            {
                var c = document.GetCharAt(i);
                if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                    if (CommentMode == 1)
                    {
                        CommentMode = 0;
                    }
                }
                else
                {
                    switch (CommentMode)
                    {
                    case 0:
                    {
                        switch (c)
                        {
                        case '/':
                        {
                            if ((i + 1) < document.TextLength)
                            {
                                char oneCharAfter = document.GetCharAt(i + 1);
                                if (oneCharAfter == '*')
                                {
                                    CommentMode = 2;
                                    startOffsets.Push(i);
                                }
                                else if (oneCharAfter == '/')
                                {
                                    CommentMode = 1;
                                }
                            }
                            break;
                        }

                        case '{':
                        {
                            startOffsets.Push(i);
                            break;
                        }

                        case '}':
                        {
                            if (startOffsets.Count > 0)
                            {
                                int startOffset = startOffsets.Pop();
                                if (startOffset < lastNewLineOffset)
                                {
                                    newFoldings.Add(new NewFolding(startOffset, i + 1));
                                }
                            }
                            break;
                        }

                        case '\"':
                        {
                            CommentMode = 3;
                            break;
                        }
                        }
                        break;
                    }

                    case 2:
                    {
                        if (c == '/')
                        {
                            if (i > 0)
                            {
                                if (document.GetCharAt(i - 1) == '*')
                                {
                                    int startOffset = startOffsets.Pop();
                                    CommentMode = 0;
                                    if (startOffset < lastNewLineOffset)
                                    {
                                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                                    }
                                }
                            }
                        }
                        break;
                    }

                    case 3:
                    {
                        if (c == '\"')
                        {
                            CommentMode = 0;
                        }
                        break;
                    }
                    }
                }
            }

            /*Stack<int> startOffsets = new Stack<int>();
             * int lastNewLineOffset = 0;
             * char openingBrace = this.OpeningBrace;
             * char closingBrace = this.ClosingBrace;
             * for (int i = 0; i < document.TextLength; i++)
             * {
             *  char c = document.GetCharAt(i);
             *  if (c == openingBrace)
             *  {
             *      startOffsets.Push(i);
             *  }
             *  else if (c == closingBrace && startOffsets.Count > 0)
             *  {
             *      int startOffset = startOffsets.Pop();
             *      // don't fold if opening and closing brace are on the same line
             *      if (startOffset < lastNewLineOffset)
             *      {
             *          newFoldings.Add(new NewFolding(startOffset, i + 1));
             *      }
             *  }
             *  else if (c == '\n' || c == '\r')
             *  {
             *      lastNewLineOffset = i + 1;
             *  }
             * }*/

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(newFoldings);
        }
Пример #47
0
 /// <summary>
 /// Creates a new ReadOnlyDocument from the given text source;
 /// and sets IDocument.FileName to the specified file name.
 /// </summary>
 public ReadOnlyDocument(ITextSource textSource, string fileName)
     : this(textSource)
 {
     this.fileName = fileName;
 }
Пример #48
0
        void CreateNewCurrentSnapshot(IList <ITextChange> changes, int?reiteratedVersionNumber = null, ITextSource afterTextSource = null)
        {
            // It's null the first time it's called from the ctor
            if (changes != null)
            {
                currentTextVersion = currentTextVersion.SetChanges(changes, reiteratedVersionNumber);
            }
            var textSource = afterTextSource ?? Document.CreateSnapshot();
            var textImage  = new TextImage(this, textSource, currentTextVersion.ImageVersion);

            CurrentSnapshot = new TextSnapshot(textImage, ContentType, this, currentTextVersion);
        }
Пример #49
0
 public async Task <ParseInformation> ParseAsync(ITextSource fileContent, IProject parentProject, CancellationToken cancellationToken)
 {
     return((await DoParseAsync(fileContent, parentProject, true, cancellationToken)).CachedParseInformation);
 }
        void ParseFiles(List <FileName> filesToParse, IProgressMonitor progressMonitor)
        {
            IProjectContent            cachedPC = TryReadFromCache(cacheFileName);
            ParseableFileContentFinder finder   = new ParseableFileContentFinder();

            object progressLock                   = new object();
            double fileCountInverse               = 1.0 / filesToParse.Count;
            int    fileCountLoadedFromCache       = 0;
            int    fileCountParsed                = 0;
            int    fileCountParsedAndSerializable = 0;

            Parallel.ForEach(
                filesToParse,
                new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount,
                CancellationToken      = progressMonitor.CancellationToken
            },
                fileName => {
                ITextSource content            = finder.CreateForOpenFile(fileName);
                bool wasLoadedFromCache        = false;
                IUnresolvedFile unresolvedFile = null;
                if (content == null && cachedPC != null)
                {
                    unresolvedFile = cachedPC.GetFile(fileName);
                    if (unresolvedFile != null && unresolvedFile.LastWriteTime == File.GetLastWriteTimeUtc(fileName))
                    {
                        parserService.RegisterUnresolvedFile(fileName, project, unresolvedFile);
                        wasLoadedFromCache = true;
                    }
                }
                if (!wasLoadedFromCache)
                {
                    if (content == null)
                    {
                        try {
                            content = SD.FileService.GetFileContentFromDisk(fileName);
                        } catch (IOException) {
                        } catch (UnauthorizedAccessException) {
                        }
                    }
                    if (content != null)
                    {
                        unresolvedFile = parserService.ParseFile(fileName, content, project);
                    }
                }
                lock (progressLock) {
                    if (wasLoadedFromCache)
                    {
                        fileCountLoadedFromCache++;
                    }
                    else
                    {
                        fileCountParsed++;
                        if (IsSerializable(unresolvedFile))
                        {
                            fileCountParsedAndSerializable++;
                        }
                    }
//						SD.MainThread.InvokeAsyncAndForget(delegate { assemblyModel.Update(null, unresolvedFile); });
                    progressMonitor.Progress += fileCountInverse;
                }
            });
            LoggingService.Debug(projectContent.AssemblyName + ": ParseFiles() finished. "
                                 + fileCountLoadedFromCache + " files were re-used from CC cache; "
                                 + fileCountParsed + " files were parsed (" + fileCountParsedAndSerializable + " of those are serializable)");
            lock (lockObj) {
                serializedProjectContentIsUpToDate = (fileCountLoadedFromCache > 0 && fileCountParsedAndSerializable == 0);
            }
        }
Пример #51
0
 public IEnumerable <IEditorScript> GetScripts(ITextSource text, int offset)
 {
     return(Enumerable.Empty <IEditorScript>());
 }
Пример #52
0
        /// <summary>
        /// Fetches text runs.
        /// </summary>
        /// <param name="textSource">The text source.</param>
        /// <param name="firstTextSourceIndex">The first text source index.</param>
        /// <param name="previousLineBreak">Previous line break. Can be null.</param>
        /// <param name="nextLineBreak">Next line break. Can be null.</param>
        /// <returns>
        /// The formatted text runs.
        /// </returns>
        private static IReadOnlyList <ShapedTextCharacters> FetchTextRuns(ITextSource textSource,
                                                                          int firstTextSourceIndex, TextLineBreak previousLineBreak, out TextLineBreak nextLineBreak)
        {
            nextLineBreak = default;

            var currentLength = 0;

            var textRuns = new List <ShapedTextCharacters>();

            if (previousLineBreak != null)
            {
                foreach (var shapedCharacters in previousLineBreak.RemainingCharacters)
                {
                    textRuns.Add(shapedCharacters);

                    if (TryGetLineBreak(shapedCharacters, out var runLineBreak))
                    {
                        var splitResult = SplitTextRuns(textRuns, currentLength + runLineBreak.PositionWrap);

                        nextLineBreak = new TextLineBreak(splitResult.Second);

                        return(splitResult.First);
                    }

                    currentLength += shapedCharacters.Text.Length;
                }
            }

            firstTextSourceIndex += currentLength;

            var textRunEnumerator = new TextRunEnumerator(textSource, firstTextSourceIndex);

            while (textRunEnumerator.MoveNext())
            {
                var textRun = textRunEnumerator.Current;

                switch (textRun)
                {
                case TextCharacters textCharacters:
                {
                    var shapeableRuns = textCharacters.GetShapeableCharacters();

                    foreach (var run in shapeableRuns)
                    {
                        var glyphRun = TextShaper.Current.ShapeText(run.Text, run.Properties.Typeface,
                                                                    run.Properties.FontRenderingEmSize, run.Properties.CultureInfo);

                        var shapedCharacters = new ShapedTextCharacters(glyphRun, textRun.Properties);

                        textRuns.Add(shapedCharacters);
                    }

                    break;
                }
                }

                if (TryGetLineBreak(textRun, out var runLineBreak))
                {
                    var splitResult = SplitTextRuns(textRuns, currentLength + runLineBreak.PositionWrap);

                    nextLineBreak = new TextLineBreak(splitResult.Second);

                    return(splitResult.First);
                }

                currentLength += textRun.Text.Length;
            }

            return(textRuns);
        }
 public abstract IEnumerable <NewFolding> CreateNewFoldings(ITextSource document);
Пример #54
0
 /// <summary>
 /// Formats a text line.
 /// </summary>
 /// <param name="textSource">The text source.</param>
 /// <param name="firstTextSourceIndex">The first character index to start the text line from.</param>
 /// <param name="paragraphWidth">A <see cref="double"/> value that specifies the width of the paragraph that the line fills.</param>
 /// <param name="paragraphProperties">A <see cref="TextParagraphProperties"/> value that represents paragraph properties,
 /// such as TextWrapping, TextAlignment, or TextStyle.</param>
 /// <returns>The formatted line.</returns>
 public abstract TextLine FormatLine(ITextSource textSource, int firstTextSourceIndex, double paragraphWidth,
                                     TextParagraphProperties paragraphProperties);
Пример #55
0
 public ScriptParser(ITextSource source, ParserSettings settings) : base(source, settings)
 {
 }
 internal static Task <ParsedDocumentProjection> ParseProjection(Project project, string fileName, string mimeType, ITextSource content, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(ParseProjection(new ParseOptions {
         FileName = fileName, Project = project, Content = content
     }, mimeType, cancellationToken));
 }
Пример #57
0
        /// <summary>
        /// Gets the next caret position.
        /// </summary>
        /// <param name="textSource">The text source.</param>
        /// <param name="offset">The start offset inside the text source.</param>
        /// <param name="direction">The search direction (forwards or backwards).</param>
        /// <param name="mode">The mode for caret positioning.</param>
        /// <returns>The offset of the next caret position, or -1 if there is no further caret position
        /// in the text source.</returns>
        /// <remarks>
        /// This method is NOT equivalent to the actual caret movement when using VisualLine.GetNextCaretPosition.
        /// In real caret movement, there are additional caret stops at line starts and ends. This method
        /// treats linefeeds as simple whitespace.
        /// </remarks>
        public static int GetNextCaretPosition(ITextSource textSource, int offset, LogicalDirection direction, CaretPositioningMode mode)
        {
            if (textSource == null)
            {
                throw new ArgumentNullException("textSource");
            }
            if (mode != CaretPositioningMode.Normal &&
                mode != CaretPositioningMode.WordBorder &&
                mode != CaretPositioningMode.WordStart &&
                mode != CaretPositioningMode.WordBorderOrSymbol &&
                mode != CaretPositioningMode.WordStartOrSymbol)
            {
                throw new ArgumentException("Unsupported CaretPositioningMode: " + mode, "mode");
            }
            if (direction != LogicalDirection.Backward &&
                direction != LogicalDirection.Forward)
            {
                throw new ArgumentException("Invalid LogicalDirection: " + direction, "direction");
            }
            int textLength = textSource.TextLength;

            if (textLength <= 0)
            {
                // empty document? has a normal caret position at 0, though no word borders
                if (mode == CaretPositioningMode.Normal)
                {
                    if (offset > 0 && direction == LogicalDirection.Backward)
                    {
                        return(0);
                    }
                    if (offset < 0 && direction == LogicalDirection.Forward)
                    {
                        return(0);
                    }
                }
                return(-1);
            }
            while (true)
            {
                int nextPos = (direction == LogicalDirection.Backward) ? offset - 1 : offset + 1;

                // return -1 if there is no further caret position in the text source
                // we also need this to handle offset values outside the valid range
                if (nextPos < 0 || nextPos > textLength)
                {
                    return(-1);
                }

                // stop at every caret position? we can stop immediately.
                if (mode == CaretPositioningMode.Normal)
                {
                    return(nextPos);
                }
                // not normal mode? we're looking for word borders...

                // check if we've run against the textSource borders.
                // a 'textSource' usually isn't the whole document, but a single VisualLineElement.
                if (nextPos == 0)
                {
                    // at the document start, there's only a word border
                    // if the first character is not whitespace
                    if (!char.IsWhiteSpace(textSource.GetCharAt(0)))
                    {
                        return(nextPos);
                    }
                }
                else if (nextPos == textLength)
                {
                    // at the document end, there's never a word start
                    if (mode != CaretPositioningMode.WordStart && mode != CaretPositioningMode.WordStartOrSymbol)
                    {
                        // at the document end, there's only a word border
                        // if the last character is not whitespace
                        if (!char.IsWhiteSpace(textSource.GetCharAt(textLength - 1)))
                        {
                            return(nextPos);
                        }
                    }
                }
                else
                {
                    CharacterClass charBefore = GetCharacterClass(textSource.GetCharAt(nextPos - 1));
                    CharacterClass charAfter  = GetCharacterClass(textSource.GetCharAt(nextPos));
                    if (charBefore == charAfter)
                    {
                        if (charBefore == CharacterClass.Other &&
                            (mode == CaretPositioningMode.WordBorderOrSymbol || mode == CaretPositioningMode.WordStartOrSymbol))
                        {
                            // With the "OrSymbol" modes, there's a word border and start between any two unknown characters
                            return(nextPos);
                        }
                    }
                    else
                    {
                        // this looks like a possible border

                        // if we're looking for word starts, check that this is a word start (and not a word end)
                        // if we're just checking for word borders, accept unconditionally
                        if (!((mode == CaretPositioningMode.WordStart || mode == CaretPositioningMode.WordStartOrSymbol) &&
                              (charAfter == CharacterClass.Whitespace || charAfter == CharacterClass.LineTerminator)))
                        {
                            return(nextPos);
                        }
                    }
                }
                // we'll have to continue searching...
                offset = nextPos;
            }
        }
Пример #58
0
        public static MSBuildRootDocument Parse(
            ITextSource textSource, MSBuildRootDocument previous,
            MSBuildSchemaProvider schemaProvider, IRuntimeInformation runtimeInfo,
            ITaskMetadataBuilder taskBuilder,
            CancellationToken token)
        {
            var xmlParser = new XmlParser(new XmlRootState(), true);

            try {
                xmlParser.Parse(textSource.CreateReader());
            } catch (Exception ex) {
                LoggingService.LogError("Unhandled error parsing xml document", ex);
            }

            var xdocument = xmlParser.Nodes.GetRoot();

            if (xdocument != null && xdocument.RootElement != null)
            {
                if (!xdocument.RootElement.IsEnded)
                {
                    xdocument.RootElement.End(xmlParser.Position);
                }
            }

            var propVals = new PropertyValueCollector(true);

            string filepath = textSource.FileName;

            var doc = new MSBuildRootDocument(filepath)
            {
                XDocument          = xdocument,
                Text               = textSource,
                RuntimeInformation = runtimeInfo
            };

            doc.Errors.AddRange(xmlParser.Diagnostics);

            var importedFiles = new HashSet <string> (StringComparer.OrdinalIgnoreCase);

            if (filepath != null)
            {
                try {
                    doc.Schema = previous?.Schema ?? schemaProvider.GetSchema(filepath, null);
                } catch (Exception ex) {
                    LoggingService.LogError("Error loading schema", ex);
                }
                importedFiles.Add(filepath);
            }

            var parseContext = new MSBuildParserContext(
                runtimeInfo,
                doc,
                previous,
                importedFiles,
                filepath,
                propVals,
                taskBuilder,
                schemaProvider,
                token);

            if (filepath != null)
            {
                doc.FileEvaluationContext = new MSBuildFileEvaluationContext(parseContext.RuntimeEvaluationContext, filepath, filepath);
            }
            else
            {
                doc.FileEvaluationContext = parseContext.RuntimeEvaluationContext;
            }

            string MakeRelativeMSBuildPathAbsolute(string path)
            {
                var dir = Path.GetDirectoryName(doc.Filename);

                path = path.Replace('\\', Path.DirectorySeparatorChar);
                return(Path.GetFullPath(Path.Combine(dir, path)));
            }

            Import TryImportFile(string label, string possibleFile)
            {
                try {
                    var fi = new FileInfo(possibleFile);
                    if (fi.Exists)
                    {
                        var imp = parseContext.GetCachedOrParse(label, possibleFile, null, fi.LastWriteTimeUtc);
                        doc.AddImport(imp);
                        return(imp);
                    }
                } catch (Exception ex) {
                    LoggingService.LogError($"Error importing '{possibleFile}'", ex);
                }
                return(null);
            }

            Import TryImportSibling(string ifHasThisExtension, string thenTryThisExtension)
            {
                if (filepath == null)
                {
                    return(null);
                }
                var extension = Path.GetExtension(filepath);

                if (string.Equals(ifHasThisExtension, extension, StringComparison.OrdinalIgnoreCase))
                {
                    var siblingFilename = Path.ChangeExtension(filepath, thenTryThisExtension);
                    return(TryImportFile("(implicit)", siblingFilename));
                }
                return(null);
            }

            void TryImportIntellisenseImports(MSBuildSchema schema)
            {
                foreach (var intellisenseImport in schema.IntelliSenseImports)
                {
                    TryImportFile("(from schema)", MakeRelativeMSBuildPathAbsolute(intellisenseImport));
                }
            }

            try {
                //if this is a targets file, try to import the props _at the top_
                var propsImport = TryImportSibling(".targets", ".props");

                // this currently only happens in the root file
                // it's a quick hack to allow files to get some basic intellisense by
                // importing the files _that they themselves expect to be imported from_.
                // we also try to load them from the sibling props, as a paired targets/props
                // will likely share a schema file.
                var schema = doc.Schema ?? propsImport?.Document?.Schema;
                if (schema != null)
                {
                    TryImportIntellisenseImports(doc.Schema);
                }

                doc.Build(xdocument, textSource, parseContext);

                //if this is a props file, try to import the targets _at the bottom_
                var targetsImport = TryImportSibling(".props", ".targets");

                //and if we didn't load intellisense import already, try to load them from the sibling targets
                if (schema == null && targetsImport?.Document?.Schema != null)
                {
                    TryImportIntellisenseImports(targetsImport.Document.Schema);
                }
            } catch (Exception ex) {
                LoggingService.LogError($"Error building document '{filepath ?? "[unnamed]"}'", ex);
            }

            try {
                var binpath = parseContext.RuntimeInformation.BinPath;
                foreach (var t in Directory.GetFiles(binpath, "*.tasks"))
                {
                    doc.LoadTasks(parseContext, "(core tasks)", t);
                }
                foreach (var t in Directory.GetFiles(binpath, "*.overridetasks"))
                {
                    doc.LoadTasks(parseContext, "(core overridetasks)", t);
                }
            } catch (Exception ex) {
                LoggingService.LogError("Error resolving tasks", ex);
            }

            try {
                if (previous != null)
                {
                    // try to recover some values that may have been collected from the imports, as they
                    // will not have been re-evaluated
                    var fx = previous.Frameworks.FirstOrDefault();
                    if (fx != null)
                    {
                        propVals.Collect("TargetFramework", fx.GetShortFolderName());
                        propVals.Collect("TargetFrameworkVersion", FrameworkInfoProvider.FormatDisplayVersion(fx.Version));
                        propVals.Collect("TargetFrameworkIdentifier", fx.Framework);
                    }
                }
                doc.Frameworks = propVals.GetFrameworks();
            } catch (Exception ex) {
                LoggingService.LogError("Error determining project framework", ex);
                doc.Frameworks = new List <NuGetFramework> ();
            }

            try {
                //this has to run in a second pass so that it runs after all the schemas are loaded
                var validator = new MSBuildDocumentValidator();
                validator.Run(doc.XDocument, textSource, doc);
            } catch (Exception ex) {
                LoggingService.LogError("Error in validation", ex);
            }

            return(doc);
        }
 public ValidationVisitor(ITextSource textSource)
 {
     this.textSource = textSource;
 }
Пример #60
0
 public TextRunEnumerator(ITextSource textSource, int firstTextSourceIndex)
 {
     _textSource = textSource;
     _pos        = firstTextSourceIndex;
     Current     = null;
 }