protected override void ScanSpan(ref int i)
            {
                if (CSharpSyntaxMode.DisableConditionalHighlighting)
                {
                    base.ScanSpan(ref i);
                    return;
                }
                int textOffset = i - StartOffset;

                if (CurText.IsAt(textOffset, "#else"))
                {
                    if (!spanStack.Any(s => s is IfBlockSpan  ||  s is ElseIfBlockSpan))
                    {
                        base.ScanSpan(ref i);
                        return;
                    }
                    bool previousResult = false;
                    foreach (Span span in spanStack)
                    {
                        if (span is IfBlockSpan)
                        {
                            previousResult = ((IfBlockSpan)span).IsValid;
                        }
                        if (span is ElseIfBlockSpan)
                        {
                            previousResult |= ((ElseIfBlockSpan)span).IsValid;
                        }
                    }
//					LineSegment line = doc.GetLineByOffset (i);
//					int length = line.Offset + line.EditableLength - i;
                    while (spanStack.Count > 0 && !(CurSpan is IfBlockSpan  ||  CurSpan is ElseIfBlockSpan))
                    {
                        spanStack.Pop();
                    }
                    IfBlockSpan     ifBlock       = CurSpan as IfBlockSpan;
                    ElseIfBlockSpan elseIfBlock   = CurSpan as ElseIfBlockSpan;
                    ElseBlockSpan   elseBlockSpan = new ElseBlockSpan(!previousResult);
                    if (ifBlock != null)
                    {
                        elseBlockSpan.Disabled = ifBlock.Disabled;
                    }
                     else if (elseIfBlock != null)
                    {
                        elseBlockSpan.Disabled = elseIfBlock.Disabled;
                    }
                    FoundSpanBegin(elseBlockSpan, i, "#else".Length);
                    i += "#else".Length;

                    // put pre processor eol span on stack, so that '#elif' gets the correct highlight
                    Span preprocessorSpan = CreatePreprocessorSpan();
                    FoundSpanBegin(preprocessorSpan, i, 0);
                    return;
                }
                if (CurRule.Name == "<root>" && CurText.IsAt(textOffset, "#if"))
                {
                    int    length    = CurText.Length - textOffset;
                    string parameter = CurText.Substring(textOffset + 3, length - 3);
                    ICSharpCode.NRefactory.Parser.CSharp.Lexer lexer = new ICSharpCode.NRefactory.Parser.CSharp.Lexer(new System.IO.StringReader(parameter));
                    ICSharpCode.NRefactory.Ast.Expression      expr  = lexer.PPExpression();
                    bool result = false;
                    if (expr != null && !expr.IsNull)
                    {
                        object o = expr.AcceptVisitor(new ConditinalExpressionEvaluator(doc), null);
                        if (o is bool)
                        {
                            result = (bool)o;
                        }
                    }
                    IfBlockSpan ifBlockSpan = new IfBlockSpan(result);

                    foreach (Span span in spanStack)
                    {
                        if (span is AbstractBlockSpan)
                        {
                            AbstractBlockSpan parentBlock = (AbstractBlockSpan)span;
                            ifBlockSpan.Disabled = parentBlock.Disabled || !parentBlock.IsValid;
                            break;
                        }
                    }

                    FoundSpanBegin(ifBlockSpan, i, length);
                    i += length - 1;
                    return;
                }
                if (CurText.IsAt(textOffset, "#elif") && spanStack.Any(span => span is IfBlockSpan))
                {
                    LineSegment line      = doc.GetLineByOffset(i);
                    int         length    = line.Offset + line.EditableLength - i;
                    string      parameter = doc.GetTextAt(i + 5, length - 5);

                    ICSharpCode.NRefactory.Parser.CSharp.Lexer lexer = new ICSharpCode.NRefactory.Parser.CSharp.Lexer(new System.IO.StringReader(parameter));
                    ICSharpCode.NRefactory.Ast.Expression      expr  = lexer.PPExpression();

                    bool result = !expr.IsNull ? (bool)expr.AcceptVisitor(new ConditinalExpressionEvaluator(doc), null) : false;

                    IfBlockSpan containingIf = null;
                    if (result)
                    {
                        bool previousResult = false;
                        foreach (Span span in spanStack)
                        {
                            if (span is IfBlockSpan)
                            {
                                containingIf   = (IfBlockSpan)span;
                                previousResult = ((IfBlockSpan)span).IsValid;
                                break;
                            }
                            if (span is ElseIfBlockSpan)
                            {
                                previousResult |= ((ElseIfBlockSpan)span).IsValid;
                            }
                        }

                        result = !previousResult;
                    }

                    ElseIfBlockSpan elseIfBlockSpan = new ElseIfBlockSpan(result);
                    if (containingIf != null)
                    {
                        elseIfBlockSpan.Disabled = containingIf.Disabled;
                    }

                    FoundSpanBegin(elseIfBlockSpan, i, 0);

                    // put pre processor eol span on stack, so that '#elif' gets the correct highlight
                    Span preprocessorSpan = CreatePreprocessorSpan();
                    FoundSpanBegin(preprocessorSpan, i, 0);
                    //i += length - 1;
                    return;
                }
                if (CurRule.Name == "<root>" && CurText[textOffset] == '#')
                {
                    Span preprocessorSpan = CreatePreprocessorSpan();
                    FoundSpanBegin(preprocessorSpan, i, 1);
                }
                base.ScanSpan(ref i);
            }
			protected override void ScanSpan (ref int i)
			{
				if (CSharpSyntaxMode.DisableConditionalHighlighting) {
					base.ScanSpan (ref i);
					return;
				}
				int textOffset = i - StartOffset;
				if (CurText.IsAt (textOffset, "#else")) {
					if (!spanStack.Any (s => s is IfBlockSpan || s is ElseIfBlockSpan)) {
						base.ScanSpan (ref i);
						return;
					}
					bool previousResult = false;
					foreach (Span span in spanStack) {
						if (span is IfBlockSpan) {
							previousResult = ((IfBlockSpan)span).IsValid;
						}
						if (span is ElseIfBlockSpan) {
							previousResult |= ((ElseIfBlockSpan)span).IsValid;
						}
					}
//					LineSegment line = doc.GetLineByOffset (i);
//					int length = line.Offset + line.EditableLength - i;
					while (spanStack.Count > 0 && !(CurSpan is IfBlockSpan || CurSpan is ElseIfBlockSpan)) {
						spanStack.Pop ();
					}
					IfBlockSpan ifBlock = CurSpan as IfBlockSpan;
					ElseIfBlockSpan elseIfBlock = CurSpan as ElseIfBlockSpan;
					ElseBlockSpan elseBlockSpan = new ElseBlockSpan (!previousResult);
					if (ifBlock != null) {
						elseBlockSpan.Disabled = ifBlock.Disabled;
					} else if (elseIfBlock != null) {
						elseBlockSpan.Disabled = elseIfBlock.Disabled;
					}
					FoundSpanBegin (elseBlockSpan, i, "#else".Length);
					i += "#else".Length;
					
					// put pre processor eol span on stack, so that '#elif' gets the correct highlight
					Span preprocessorSpan = CreatePreprocessorSpan ();
					FoundSpanBegin (preprocessorSpan, i, 0);
					return;
				}
				if (CurRule.Name == "<root>" && CurText.IsAt (textOffset, "#if")) {
					int length = CurText.Length - textOffset;
					string parameter = CurText.Substring (textOffset + 3, length - 3);
					ICSharpCode.NRefactory.Parser.CSharp.Lexer lexer = new ICSharpCode.NRefactory.Parser.CSharp.Lexer (new System.IO.StringReader (parameter));
					ICSharpCode.NRefactory.Ast.Expression expr = lexer.PPExpression ();
					bool result = false;
					if (expr != null && !expr.IsNull) {
						object o = expr.AcceptVisitor (new ConditinalExpressionEvaluator (doc), null);
						if (o is bool)
							result = (bool)o;
					}
					IfBlockSpan ifBlockSpan = new IfBlockSpan (result);
					
					foreach (Span span in spanStack) {
						if (span is AbstractBlockSpan) {
							AbstractBlockSpan parentBlock = (AbstractBlockSpan)span;
							ifBlockSpan.Disabled = parentBlock.Disabled || !parentBlock.IsValid;
							break;
						}
					}
					
					FoundSpanBegin (ifBlockSpan, i, length);
					i += length - 1;
					return;
				}
				if (CurText.IsAt (textOffset, "#elif") && spanStack.Any (span => span is IfBlockSpan)) {
					LineSegment line = doc.GetLineByOffset (i);
					int length = line.Offset + line.EditableLength - i;
					string parameter = doc.GetTextAt (i + 5, length - 5);
					
					ICSharpCode.NRefactory.Parser.CSharp.Lexer lexer = new ICSharpCode.NRefactory.Parser.CSharp.Lexer (new System.IO.StringReader (parameter));
					ICSharpCode.NRefactory.Ast.Expression expr = lexer.PPExpression ();
				
					bool result = !expr.IsNull ? (bool)expr.AcceptVisitor (new ConditinalExpressionEvaluator (doc), null) : false;
					
					IfBlockSpan containingIf = null;
					if (result) {
						bool previousResult = false;
						foreach (Span span in spanStack) {
							if (span is IfBlockSpan) {
								containingIf = (IfBlockSpan)span;
								previousResult = ((IfBlockSpan)span).IsValid;
								break;
							}
							if (span is ElseIfBlockSpan) {
								previousResult |= ((ElseIfBlockSpan)span).IsValid;
							}
						}
						
						result = !previousResult;
					}
					
					ElseIfBlockSpan elseIfBlockSpan = new ElseIfBlockSpan (result);
					if (containingIf != null)
						elseIfBlockSpan.Disabled = containingIf.Disabled;
					
					FoundSpanBegin (elseIfBlockSpan, i, 0);
					
					// put pre processor eol span on stack, so that '#elif' gets the correct highlight
					Span preprocessorSpan = CreatePreprocessorSpan ();
					FoundSpanBegin (preprocessorSpan, i, 0);
					//i += length - 1;
					return;
				}
				if (CurRule.Name == "<root>" &&  CurText[textOffset] == '#') {
					Span preprocessorSpan = CreatePreprocessorSpan ();
					FoundSpanBegin (preprocessorSpan, i, 1);
				}
				base.ScanSpan (ref i);
			}
Exemple #3
0
		public override ParsedDocument Parse (ProjectDom dom, string fileName, string content)
		{
			lock (CompilerCallableEntryPoint.parseLock) {
				if (string.IsNullOrEmpty (content))
					return null;
				
				List<string> compilerArguments = new List<string> ();
				
				var unit =  new MonoDevelop.Projects.Dom.CompilationUnit (fileName);;
				var result = new ParsedDocument (fileName);
				result.CompilationUnit = unit;
				
				ICSharpCode.NRefactory.Parser.CSharp.Lexer lexer = new ICSharpCode.NRefactory.Parser.CSharp.Lexer (new StringReader (content));
				lexer.SpecialCommentTags = ProjectDomService.SpecialCommentTags.GetNames ();
				lexer.EvaluateConditionalCompilation = true;
				if (dom != null && dom.Project != null && MonoDevelop.Ide.IdeApp.Workspace != null) {
					DotNetProjectConfiguration configuration = dom.Project.GetConfiguration (MonoDevelop.Ide.IdeApp.Workspace.ActiveConfiguration) as DotNetProjectConfiguration;
					CSharpCompilerParameters par = configuration != null ? configuration.CompilationParameters as CSharpCompilerParameters : null;
					if (par != null) {
						lexer.SetConditionalCompilationSymbols (par.DefineSymbols);
						if (!string.IsNullOrEmpty (par.DefineSymbols)) {
							compilerArguments.Add ("-define:" + string.Join (";", par.DefineSymbols.Split (';', ',', ' ', '\t')));
						}
						if (par.UnsafeCode)
							compilerArguments.Add ("-unsafe");
						if (par.TreatWarningsAsErrors)
							compilerArguments.Add ("-warnaserror");
						if (!string.IsNullOrEmpty (par.NoWarnings))
							compilerArguments.Add ("-nowarn:"+ string.Join (",", par.NoWarnings.Split (';', ',', ' ', '\t')));
						compilerArguments.Add ("-warn:" + par.WarningLevel);
						compilerArguments.Add ("-langversion:" + GetLangString (par.LangVersion));
						if (par.GenerateOverflowChecks)
							compilerArguments.Add ("-checked");
					}
				}
	//			compilerArguments.ForEach (arg => Console.WriteLine (arg));
				while (lexer.NextToken ().Kind != ICSharpCode.NRefactory.Parser.CSharp.Tokens.EOF)
					;
				
				CompilerCompilationUnit top;
				ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter ();
				using (var stream = new MemoryStream (Encoding.Default.GetBytes (content))) {
					top = CompilerCallableEntryPoint.ParseFile (compilerArguments.ToArray (), stream, fileName, errorReportPrinter);
				}
				if (top == null)
					return null;
				
				SpecialTracker tracker = new SpecialTracker (result);
				foreach (ICSharpCode.NRefactory.ISpecial special in lexer.SpecialTracker.CurrentSpecials) {
					special.AcceptVisitor (tracker, null);
				}	
				
				
				// convert DOM
				var conversionVisitor = new ConversionVisitor (top.LocationsBag, lexer.SpecialTracker.CurrentSpecials);
				conversionVisitor.Dom = dom;
				conversionVisitor.Unit = unit;
				conversionVisitor.ParsedDocument = result;
				top.UsingsBag.Global.Accept (conversionVisitor);
				
				unit.Tag = top;
				
				// parser errors
				errorReportPrinter.Errors.ForEach (e => conversionVisitor.ParsedDocument.Add (e));
				return result;
			}
		}