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)
5
using System.Collections.Generic;
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;
19
namespace Grunwald.BooBinding.CodeCompletion
21
public class BooParser : IParser
25
public string[] LexerTags {
34
public LanguageProperties Language {
36
return BooLanguageProperties.Instance;
40
public IExpressionFinder CreateExpressionFinder(string fileName)
42
return new ExpressionFinder(fileName);
45
public bool CanParse(string fileName)
47
return string.Equals(Path.GetExtension(fileName), ".boo", StringComparison.OrdinalIgnoreCase);
50
public bool CanParse(IProject project)
52
return project.Language == BooProjectBinding.LanguageName;
55
public ICompilationUnit Parse(IProjectContent projectContent, string fileName, ITextBuffer fileContentBuffer)
57
string fileContent = fileContentBuffer.Text;
58
LoggingService.Debug("Parse " + fileName);
60
foreach (char c in fileContent) {
65
int[] lineLength = new int[lineCount];
68
foreach (char c in fileContent) {
70
lineLength[i] = length;
73
} else if (c != '\r') {
77
lineLength[i] = length;
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);
84
AddCommentsAndRegions(cu, fileContent, fileName);
88
void AddCommentsAndRegions(ICompilationUnit cu, string fileContent, string fileName)
90
ExpressionFinder ef = new ExpressionFinder(fileName);
91
ef.ResetStateMachine();
93
StringBuilder commentBuilder = null;
94
char commentStartChar = '\0';
95
int commentStartColumn = 0;
97
Stack<string> regionTitleStack = new Stack<string>();
98
Stack<int> regionLineStack = new Stack<int>();
99
Stack<int> regionColumnStack = new Stack<int>();
103
for (int i = 0; i < fileContent.Length; i++) {
105
char c = fileContent[i];
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);
116
} else if (regexEnd == -1) {
117
// end of file is in regex
119
} // else: regexEnd is 0 if its not a regex
121
if (state == ExpressionFinder.LineCommentState) {
122
if (commentBuilder == null) {
123
commentStartChar = c;
124
commentStartColumn = column;
125
commentBuilder = new StringBuilder();
127
if (commentBuilder.Length > 0) {
128
commentBuilder.Append(c);
129
} else if (!char.IsWhiteSpace(c)) {
130
commentStartColumn = column;
131
commentBuilder.Append(c);
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(),
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));
160
private ICompilationUnit Parse(IProjectContent projectContent, string fileName, int[] lineLength, BooCompiler compiler)
162
compiler.Parameters.OutputWriter = new StringWriter();
163
compiler.Parameters.TraceLevel = System.Diagnostics.TraceLevel.Off;
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
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());
240
var parsingStep = compilePipe[0];
241
//compiler.Parameters.Environment.Provide<ParserSettings>().TabSize = 1;
243
ConvertVisitor visitor = new ConvertVisitor(lineLength, projectContent);
244
visitor.Cu.FileName = fileName;
245
compilePipe.Add(visitor);
247
compilePipe.BreakOnErrors = false;
248
compiler.Parameters.Pipeline = compilePipe;
249
compiler.Parameters.References.Add(typeof(Boo.Lang.Useful.Attributes.SingletonAttribute).Assembly);
252
compilePipe.AfterStep += delegate(object sender, CompilerStepEventArgs args) {
253
if (args.Step == parsingStep)
254
errorCount = args.Context.Errors.Count;
258
visitor.Cu.ErrorsDuringCompile = errorCount > 0;
259
} catch (Exception ex) {
260
MessageService.ShowException(ex);
265
public IResolver CreateResolver()
267
return new BooResolver();