source: trunk/sources/HeuristicLab.CodeEditor/3.4/LanguageFeatures/CodeCompletion/CSharp/CSharpCodeCompletionStrategy.cs @ 13549

Last change on this file since 13549 was 13549, checked in by jkarder, 5 years ago

#2563: catch and ignore exceptions thrown during code folding/completion

File size: 4.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System.Collections.Generic;
23using System.Linq;
24using ICSharpCode.NRefactory.Completion;
25using ICSharpCode.NRefactory.CSharp;
26using ICSharpCode.NRefactory.CSharp.Completion;
27using ICSharpCode.NRefactory.TypeSystem;
28
29namespace HeuristicLab.CodeEditor {
30  internal class CSharpCodeCompletionStrategy : CodeCompletionStrategy {
31    private IProjectContent projectContent = new CSharpProjectContent();
32
33    public CSharpCodeCompletionStrategy(CodeEditor codeEditor)
34      : base(codeEditor) {
35      codeEditor.InternalAssembliesLoaded += (sender, args) => {
36        projectContent = projectContent.AddAssemblyReferences(args.Value);
37      };
38      codeEditor.InternalAssembliesUnloaded += (sender, args) => {
39        projectContent = projectContent.RemoveAssemblyReferences(args.Value);
40      };
41    }
42
43    protected override CodeCompletionResult GetCodeCompletionResult(bool controlSpace) {
44      var document = codeEditor.TextEditor.Document;
45      int offset = codeEditor.TextEditor.CaretOffset;
46      var result = new CodeCompletionResult();
47
48      try {
49        var completionContext = new CSharpCodeCompletionContext(document, offset, projectContent);
50        var completionFactory = new CSharpCodeCompletionDataFactory(completionContext);
51        var cce = new CSharpCompletionEngine(
52          completionContext.Document,
53          completionContext.CompletionContextProvider,
54          completionFactory,
55          completionContext.ProjectContent,
56          completionContext.TypeResolveContextAtCaret
57          );
58
59        char completionChar = completionContext.Document.GetCharAt(completionContext.Offset - 1);
60        int startPos, triggerWordLength;
61        IEnumerable<ICompletionData> completionData;
62
63        if (controlSpace) {
64          if (!cce.TryGetCompletionWord(completionContext.Offset, out startPos, out triggerWordLength)) {
65            startPos = completionContext.Offset;
66            triggerWordLength = 0;
67          }
68          completionData = cce.GetCompletionData(startPos, true);
69        } else {
70          startPos = completionContext.Offset;
71          if (char.IsLetterOrDigit(completionChar) || completionChar == '_') {
72            if (startPos > 1 && char.IsLetterOrDigit(completionContext.Document.GetCharAt((startPos - 2))))
73              return result;
74            completionData = cce.GetCompletionData(startPos, false);
75            triggerWordLength = 1;
76          } else {
77            completionData = cce.GetCompletionData(startPos, false);
78            triggerWordLength = 0;
79          }
80        }
81
82        result.TriggerWordLength = triggerWordLength;
83        result.TriggerWord = completionContext.Document.GetText(completionContext.Offset - triggerWordLength, triggerWordLength);
84
85        if (completionData.Any() && cce.AutoCompleteEmptyMatch) {
86          foreach (var completion in completionData) {
87            var cast = completion as CompletionData;
88            if (cast != null) {
89              cast.TriggerWord = result.TriggerWord;
90              cast.TriggerWordLength = result.TriggerWordLength;
91              result.CompletionData.Add(cast);
92            }
93          }
94        }
95
96        if (!controlSpace) {
97          var pce = new CSharpParameterCompletionEngine(
98            completionContext.Document,
99            completionContext.CompletionContextProvider,
100            completionFactory,
101            completionContext.ProjectContent,
102            completionContext.TypeResolveContextAtCaret
103            );
104
105          var parameterDataProvider = pce.GetParameterDataProvider(completionContext.Offset, completionChar);
106          result.OverloadProvider = parameterDataProvider as IUpdatableOverloadProvider;
107        }
108      } catch {
109        // ignore exceptions thrown during code completion
110      }
111
112      return result;
113    }
114
115    protected override void DoParseStep() {
116      if (document == null) return;
117      var unresolvedFile = CSharpParsingHelpers.CreateCSharpUnresolvedFile(document);
118      projectContent = projectContent.AddOrUpdateFiles(unresolvedFile);
119    }
120  }
121}
Note: See TracBrowser for help on using the repository browser.