~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooParser.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.Collections.Generic;
 
6
using System.IO;
 
7
using System.Text;
 
8
 
 
9
using Boo.Lang.Compiler;
 
10
using Boo.Lang.Compiler.IO;
 
11
using Boo.Lang.Compiler.Pipelines;
 
12
using Boo.Lang.Compiler.Steps;
 
13
using Boo.Lang.Parser;
 
14
using ICSharpCode.Core;
 
15
using ICSharpCode.SharpDevelop;
 
16
using ICSharpCode.SharpDevelop.Dom;
 
17
using ICSharpCode.SharpDevelop.Project;
 
18
 
 
19
namespace Grunwald.BooBinding.CodeCompletion
 
20
{
 
21
        public class BooParser : IParser
 
22
        {
 
23
                string[] lexerTags;
 
24
                
 
25
                public string[] LexerTags {
 
26
                        get {
 
27
                                return lexerTags;
 
28
                        }
 
29
                        set {
 
30
                                lexerTags = value;
 
31
                        }
 
32
                }
 
33
                
 
34
                public LanguageProperties Language {
 
35
                        get {
 
36
                                return BooLanguageProperties.Instance;
 
37
                        }
 
38
                }
 
39
                
 
40
                public IExpressionFinder CreateExpressionFinder(string fileName)
 
41
                {
 
42
                        return new ExpressionFinder(fileName);
 
43
                }
 
44
                
 
45
                public bool CanParse(string fileName)
 
46
                {
 
47
                        return string.Equals(Path.GetExtension(fileName), ".boo", StringComparison.OrdinalIgnoreCase);
 
48
                }
 
49
                
 
50
                public bool CanParse(IProject project)
 
51
                {
 
52
                        return project.Language == BooProjectBinding.LanguageName;
 
53
                }
 
54
                
 
55
                public ICompilationUnit Parse(IProjectContent projectContent, string fileName, ITextBuffer fileContentBuffer)
 
56
                {
 
57
                        string fileContent = fileContentBuffer.Text;
 
58
                        LoggingService.Debug("Parse " + fileName);
 
59
                        int lineCount = 1;
 
60
                        foreach (char c in fileContent) {
 
61
                                if (c == '\n') {
 
62
                                        lineCount++;
 
63
                                }
 
64
                        }
 
65
                        int[] lineLength = new int[lineCount];
 
66
                        int length = 0;
 
67
                        int i = 0;
 
68
                        foreach (char c in fileContent) {
 
69
                                if (c == '\n') {
 
70
                                        lineLength[i] = length;
 
71
                                        i += 1;
 
72
                                        length = 0;
 
73
                                } else if (c != '\r') {
 
74
                                        length += 1;
 
75
                                }
 
76
                        }
 
77
                        lineLength[i] = length;
 
78
                        ICompilationUnit cu;
 
79
                        lock (typeof(BooCompiler)) {
 
80
                                BooCompiler compiler = new BooCompiler();
 
81
                                compiler.Parameters.Input.Add(new StringInput(fileName, fileContent));
 
82
                                cu = Parse(projectContent, fileName, lineLength, compiler);
 
83
                        }
 
84
                        AddCommentsAndRegions(cu, fileContent, fileName);
 
85
                        return cu;
 
86
                }
 
87
                
 
88
                void AddCommentsAndRegions(ICompilationUnit cu, string fileContent, string fileName)
 
89
                {
 
90
                        ExpressionFinder ef = new ExpressionFinder(fileName);
 
91
                        ef.ResetStateMachine();
 
92
                        int state = 0;
 
93
                        StringBuilder commentBuilder = null;
 
94
                        char commentStartChar = '\0';
 
95
                        int commentStartColumn = 0;
 
96
                        
 
97
                        Stack<string> regionTitleStack  = new Stack<string>();
 
98
                        Stack<int>    regionLineStack   = new Stack<int>();
 
99
                        Stack<int>    regionColumnStack = new Stack<int>();
 
100
                        
 
101
                        int line = 1;
 
102
                        int column = 0;
 
103
                        for (int i = 0; i < fileContent.Length; i++) {
 
104
                                column += 1;
 
105
                                char c = fileContent[i];
 
106
                                if (c == '\n') {
 
107
                                        column = 0;
 
108
                                        line += 1;
 
109
                                }
 
110
                                state = ef.FeedStateMachine(state, c);
 
111
                                if (state == ExpressionFinder.PossibleRegexStart) {
 
112
                                        // after / could be a regular expression, do a special check for that
 
113
                                        int regexEnd = ef.SkipRegularExpression(fileContent, i, fileContent.Length - 1);
 
114
                                        if (regexEnd > 0) {
 
115
                                                i = regexEnd;
 
116
                                        } else if (regexEnd == -1) {
 
117
                                                // end of file is in regex
 
118
                                                return;
 
119
                                        } // else: regexEnd is 0 if its not a regex
 
120
                                }
 
121
                                if (state == ExpressionFinder.LineCommentState) {
 
122
                                        if (commentBuilder == null) {
 
123
                                                commentStartChar = c;
 
124
                                                commentStartColumn = column;
 
125
                                                commentBuilder = new StringBuilder();
 
126
                                        } else {
 
127
                                                if (commentBuilder.Length > 0) {
 
128
                                                        commentBuilder.Append(c);
 
129
                                                } else if (!char.IsWhiteSpace(c)) {
 
130
                                                        commentStartColumn = column;
 
131
                                                        commentBuilder.Append(c);
 
132
                                                }
 
133
                                        }
 
134
                                } else if (commentBuilder != null) {
 
135
                                        string text = commentBuilder.ToString();
 
136
                                        commentBuilder = null;
 
137
                                        if (commentStartChar == '#' && text.StartsWith("region ")) {
 
138
                                                regionTitleStack.Push(text.Substring(7));
 
139
                                                regionLineStack.Push(line);
 
140
                                                regionColumnStack.Push(commentStartColumn - 1);
 
141
                                        } else if (commentStartChar == '#' && text.StartsWith("endregion") && regionTitleStack.Count > 0) {
 
142
                                                // Add folding region
 
143
                                                cu.FoldingRegions.Add(new FoldingRegion(regionTitleStack.Pop(),
 
144
                                                                                        new DomRegion(regionLineStack.Pop(),
 
145
                                                                                                      regionColumnStack.Pop(),
 
146
                                                                                                      line, column)));
 
147
                                        } else {
 
148
                                                foreach (string tag in lexerTags) {
 
149
                                                        if (text.StartsWith(tag)) {
 
150
                                                                string commentString = text.Substring(tag.Length);
 
151
                                                                cu.TagComments.Add(new TagComment(tag, new DomRegion(line, commentStartColumn), commentString));
 
152
                                                                break;
 
153
                                                        }
 
154
                                                }
 
155
                                        }
 
156
                                }
 
157
                        }
 
158
                }
 
159
                
 
160
                private ICompilationUnit Parse(IProjectContent projectContent, string fileName, int[] lineLength, BooCompiler compiler)
 
161
                {
 
162
                        compiler.Parameters.OutputWriter = new StringWriter();
 
163
                        compiler.Parameters.TraceLevel = System.Diagnostics.TraceLevel.Off;
 
164
                        
 
165
                        // Compile pipeline as of Boo 0.9.4:
 
166
                        // Boo.Lang.Compiler.Pipelines.Parse:
 
167
                        //   Boo.Lang.Compiler.Steps.Parsing
 
168
                        // Boo.Lang.Compiler.Pipelines.ExpandMacros:
 
169
                        //   Boo.Lang.Compiler.Steps.PreErrorChecking
 
170
                        //   Boo.Lang.Compiler.Steps.MergePartialClasses
 
171
                        //   Boo.Lang.Compiler.Steps.InitializeNameResolutionService
 
172
                        //   Boo.Lang.Compiler.Steps.IntroduceGlobalNamespaces
 
173
                        //   Boo.Lang.Compiler.Steps.TransformCallableDefinitions
 
174
                        //   Boo.Lang.Compiler.Steps.BindTypeDefinitions
 
175
                        //   Boo.Lang.Compiler.Steps.BindGenericParameters
 
176
                        //   Boo.Lang.Compiler.Steps.ResolveImports
 
177
                        //   Boo.Lang.Compiler.Steps.BindBaseTypes
 
178
                        //   Boo.Lang.Compiler.Steps.MacroAndAttributeExpansion
 
179
                        // Boo.Lang.Compiler.Pipelines.ResolveExpressions:
 
180
                        //   Boo.Lang.Compiler.Steps.ExpandAstLiterals
 
181
                        //   Boo.Lang.Compiler.Steps.IntroduceModuleClasses
 
182
                        //   Boo.Lang.Compiler.Steps.NormalizeStatementModifiers
 
183
                        //   Boo.Lang.Compiler.Steps.NormalizeTypeAndMemberDefinitions
 
184
                        //   Boo.Lang.Compiler.Steps.NormalizeExpressions
 
185
                        //   Boo.Lang.Compiler.Steps.BindTypeDefinitions
 
186
                        //   Boo.Lang.Compiler.Steps.BindGenericParameters
 
187
                        //   Boo.Lang.Compiler.Steps.BindEnumMembers
 
188
                        //   Boo.Lang.Compiler.Steps.BindBaseTypes
 
189
                        //   Boo.Lang.Compiler.Steps.CheckMemberTypes
 
190
                        //   Boo.Lang.Compiler.Steps.BindMethods
 
191
                        //   Boo.Lang.Compiler.Steps.ResolveTypeReferences
 
192
                        //   Boo.Lang.Compiler.Steps.BindTypeMembers
 
193
                        //   Boo.Lang.Compiler.Steps.CheckGenericConstraints
 
194
                        //   Boo.Lang.Compiler.Steps.ProcessInheritedAbstractMembers
 
195
                        //   Boo.Lang.Compiler.Steps.CheckMemberNames
 
196
                        //   Boo.Lang.Compiler.Steps.ProcessMethodBodiesWithDuckTyping
 
197
                        //   Boo.Lang.Compiler.Steps.ReifyTypes
 
198
                        //   Boo.Lang.Compiler.Steps.VerifyExtensionMethods
 
199
                        //   Boo.Lang.Compiler.Steps.TypeInference
 
200
                        // Boo.Lang.Compiler.Pipelines.Compile:
 
201
                        //   Boo.Lang.Compiler.Steps.ConstantFolding
 
202
                        //   Boo.Lang.Compiler.Steps.CheckLiteralValues
 
203
                        //   Boo.Lang.Compiler.Steps.OptimizeIterationStatements
 
204
                        //   Boo.Lang.Compiler.Steps.BranchChecking
 
205
                        //   Boo.Lang.Compiler.Steps.CheckIdentifiers
 
206
                        //   Boo.Lang.Compiler.Steps.StricterErrorChecking
 
207
                        //   Boo.Lang.Compiler.Steps.CheckAttributesUsage
 
208
                        //   Boo.Lang.Compiler.Steps.ExpandDuckTypedExpressions
 
209
                        //   Boo.Lang.Compiler.Steps.ProcessAssignmentsToValueTypeMembers
 
210
                        //   Boo.Lang.Compiler.Steps.ExpandPropertiesAndEvents
 
211
                        //   Boo.Lang.Compiler.Steps.CheckMembersProtectionLevel
 
212
                        //   Boo.Lang.Compiler.Steps.NormalizeIterationStatements
 
213
                        //   Boo.Lang.Compiler.Steps.ProcessSharedLocals
 
214
                        //   Boo.Lang.Compiler.Steps.ProcessClosures
 
215
                        //   Boo.Lang.Compiler.Steps.ProcessGenerators
 
216
                        //   Boo.Lang.Compiler.Steps.ExpandVarArgsMethodInvocations
 
217
                        //   Boo.Lang.Compiler.Steps.InjectCallableConversions
 
218
                        //   Boo.Lang.Compiler.Steps.ImplementICallableOnCallableDefinitions
 
219
                        //   Boo.Lang.Compiler.Steps.RemoveDeadCode
 
220
                        //   Boo.Lang.Compiler.Steps.CheckNeverUsedMembers
 
221
                        // Boo.Lang.Compiler.Pipelines.CompileToMemory:
 
222
                        //   Boo.Lang.Compiler.Steps.EmitAssembly
 
223
                        // Boo.Lang.Compiler.Pipelines.CompileToFile:
 
224
                        //   Boo.Lang.Compiler.Steps.SaveAssembly
 
225
                        
 
226
                        
 
227
                        CompilerPipeline compilePipe = new Parse();
 
228
                        compilePipe.Add(new PreErrorChecking());
 
229
                        compilePipe.Add(new MergePartialClasses());
 
230
                        compilePipe.Add(new InitializeNameResolutionService());
 
231
                        compilePipe.Add(new IntroduceGlobalNamespaces());
 
232
                        // TransformCallableDefinitions: not used for CC
 
233
                        compilePipe.Add(new BindTypeDefinitions());
 
234
                        compilePipe.Add(new BindGenericParameters());
 
235
                        compilePipe.Add(new ResolveImports());
 
236
                        compilePipe.Add(new BindBaseTypes());
 
237
                        compilePipe.Add(new MacroAndAttributeExpansion());
 
238
                        compilePipe.Add(new IntroduceModuleClasses());
 
239
                        
 
240
                        var parsingStep = compilePipe[0];
 
241
                        //compiler.Parameters.Environment.Provide<ParserSettings>().TabSize = 1;
 
242
                        
 
243
                        ConvertVisitor visitor = new ConvertVisitor(lineLength, projectContent);
 
244
                        visitor.Cu.FileName = fileName;
 
245
                        compilePipe.Add(visitor);
 
246
                        
 
247
                        compilePipe.BreakOnErrors = false;
 
248
                        compiler.Parameters.Pipeline = compilePipe;
 
249
                        compiler.Parameters.References.Add(typeof(Boo.Lang.Useful.Attributes.SingletonAttribute).Assembly);
 
250
                        
 
251
                        int errorCount = 0;
 
252
                        compilePipe.AfterStep += delegate(object sender, CompilerStepEventArgs args) {
 
253
                                if (args.Step == parsingStep)
 
254
                                        errorCount = args.Context.Errors.Count;
 
255
                        };
 
256
                        try {
 
257
                                compiler.Run();
 
258
                                visitor.Cu.ErrorsDuringCompile = errorCount > 0;
 
259
                        } catch (Exception ex) {
 
260
                                MessageService.ShowException(ex);
 
261
                        }
 
262
                        return visitor.Cu;
 
263
                }
 
264
                
 
265
                public IResolver CreateResolver()
 
266
                {
 
267
                        return new BooResolver();
 
268
                }
 
269
        }
 
270
}