public static ISyntaxRegion FindCurrentCaretContext(IEditorData editor, out ParserTrackerVariables trackerVariables, ref IBlockNode currentScope, out IStatement currentStatement) { if(currentScope == null) currentScope = DResolver.SearchBlockAt (editor.SyntaxTree, editor.CaretLocation, out currentStatement); if (currentScope == null) { trackerVariables = null; currentStatement = null; return null; } bool ParseDecl = false; int blockStart = 0; var blockStartLocation = currentScope != null ? currentScope.BlockStartLocation : editor.CaretLocation; if (currentScope is DMethod) { var block = (currentScope as DMethod).GetSubBlockAt(editor.CaretLocation); if (block != null) blockStart = DocumentHelper.GetOffsetByRelativeLocation (editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, blockStartLocation = block.Location); else { currentScope = currentScope.Parent as IBlockNode; return FindCurrentCaretContext (editor, out trackerVariables, ref currentScope, out currentStatement); } } else if (currentScope != null) { if (currentScope.BlockStartLocation.IsEmpty || (editor.CaretLocation < currentScope.BlockStartLocation && editor.CaretLocation > currentScope.Location)) { ParseDecl = true; blockStart = DocumentHelper.GetOffsetByRelativeLocation(editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, blockStartLocation = currentScope.Location); } else blockStart = DocumentHelper.GetOffsetByRelativeLocation(editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, currentScope.BlockStartLocation); } if (blockStart >= 0 && editor.CaretOffset - blockStart > 0) using (var sr = new Misc.StringView(editor.ModuleCode, blockStart, editor.CaretOffset - blockStart)) { var psr = DParser.Create(sr); /* Deadly important! For correct resolution behaviour, * it is required to set the parser virtually to the blockStart position, * so that everything using the returned object is always related to * the original code file, not our code extraction! */ psr.Lexer.SetInitialLocation(blockStartLocation); ISyntaxRegion ret = null; if (currentScope == null) ret = psr.Parse(); else if (currentScope is DMethod) { psr.Step(); var dm = currentScope as DMethod; dm.Clear(); if ((dm.SpecialType & DMethod.MethodType.Lambda) != 0 && psr.Lexer.LookAhead.Kind != DTokens.OpenCurlyBrace) { psr.LambdaSingleStatementBody (dm); ret = dm.Body; } else { var methodRegion = DTokens.Body; if (dm.In != null && blockStartLocation == dm.In.Location) methodRegion = DTokens.In; if (dm.Out != null && blockStartLocation == dm.Out.Location) methodRegion = DTokens.Out; var newBlock = psr.BlockStatement (currentScope); ret = newBlock; switch (methodRegion) { case DTokens.Body: newBlock.EndLocation = dm.Body.EndLocation; dm.Body = newBlock; break; case DTokens.In: newBlock.EndLocation = dm.In.EndLocation; dm.In = newBlock; break; case DTokens.Out: newBlock.EndLocation = dm.Out.EndLocation; dm.Out = newBlock; break; } } } else if (currentScope is DModule) ret = psr.Root(); else { psr.Step(); if (ParseDecl) { var ret2 = psr.Declaration(currentScope); if (ret2 != null && ret2.Length > 0) ret = ret2[0]; } else if (currentScope is DClassLike) { var t = new DClassLike((currentScope as DClassLike).ClassType); t.AssignFrom(currentScope); t.Clear(); psr.ClassBody(t); ret = t; } else if (currentScope is DEnum) { var t = new DEnum(); t.AssignFrom(currentScope); t.Clear(); psr.EnumBody(t); ret = t; } } currentScope = DResolver.SearchBlockAt (currentScope, psr.Lexer.CurrentToken != null ? psr.Lexer.CurrentToken.EndLocation : editor.CaretLocation, out currentStatement); trackerVariables = psr.TrackerVariables; return ret; } trackerVariables = null; currentStatement = null; return null; }
public static ISyntaxRegion FindCurrentCaretContext(IEditorData editor, out ParserTrackerVariables trackerVariables, ref IBlockNode currentScope, out IStatement currentStatement) { if (currentScope == null) { currentScope = DResolver.SearchBlockAt(editor.SyntaxTree, editor.CaretLocation, out currentStatement); } if (currentScope == null) { trackerVariables = null; currentStatement = null; return(null); } bool ParseDecl = false; int blockStart = 0; var blockStartLocation = currentScope != null ? currentScope.BlockStartLocation : editor.CaretLocation; if (currentScope is DMethod) { var block = (currentScope as DMethod).GetSubBlockAt(editor.CaretLocation); if (block != null) { blockStart = DocumentHelper.GetOffsetByRelativeLocation(editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, blockStartLocation = block.Location); } else { currentScope = currentScope.Parent as IBlockNode; return(FindCurrentCaretContext(editor, out trackerVariables, ref currentScope, out currentStatement)); } } else if (currentScope != null) { if (currentScope.BlockStartLocation.IsEmpty || (editor.CaretLocation < currentScope.BlockStartLocation && editor.CaretLocation > currentScope.Location)) { ParseDecl = true; blockStart = DocumentHelper.GetOffsetByRelativeLocation(editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, blockStartLocation = currentScope.Location); } else { blockStart = DocumentHelper.GetOffsetByRelativeLocation(editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, currentScope.BlockStartLocation); } } if (blockStart >= 0 && editor.CaretOffset - blockStart > 0) { using (var sr = new Misc.StringView(editor.ModuleCode, blockStart, editor.CaretOffset - blockStart)) { var psr = DParser.Create(sr); /* Deadly important! For correct resolution behaviour, * it is required to set the parser virtually to the blockStart position, * so that everything using the returned object is always related to * the original code file, not our code extraction! */ psr.Lexer.SetInitialLocation(blockStartLocation); ISyntaxRegion ret = null; if (currentScope == null) { ret = psr.Parse(); } else if (currentScope is DMethod) { psr.Step(); var dm = currentScope as DMethod; dm.Clear(); if ((dm.SpecialType & DMethod.MethodType.Lambda) != 0 && psr.Lexer.LookAhead.Kind != DTokens.OpenCurlyBrace) { psr.LambdaSingleStatementBody(dm); ret = dm.Body; } else { var methodRegion = DTokens.Body; if (dm.In != null && blockStartLocation == dm.In.Location) { methodRegion = DTokens.In; } if (dm.Out != null && blockStartLocation == dm.Out.Location) { methodRegion = DTokens.Out; } var newBlock = psr.BlockStatement(currentScope); ret = newBlock; switch (methodRegion) { case DTokens.Body: newBlock.EndLocation = dm.Body.EndLocation; dm.Body = newBlock; break; case DTokens.In: newBlock.EndLocation = dm.In.EndLocation; dm.In = newBlock; break; case DTokens.Out: newBlock.EndLocation = dm.Out.EndLocation; dm.Out = newBlock; break; } } } else if (currentScope is DModule) { ret = psr.Root(); } else { psr.Step(); if (ParseDecl) { var ret2 = psr.Declaration(currentScope); if (ret2 != null && ret2.Length > 0) { ret = ret2[0]; } } else if (currentScope is DClassLike) { var t = new DClassLike((currentScope as DClassLike).ClassType); t.AssignFrom(currentScope); t.Clear(); psr.ClassBody(t); ret = t; } else if (currentScope is DEnum) { var t = new DEnum(); t.AssignFrom(currentScope); t.Clear(); psr.EnumBody(t); ret = t; } } currentScope = DResolver.SearchBlockAt(currentScope, psr.Lexer.CurrentToken != null ? psr.Lexer.CurrentToken.EndLocation : editor.CaretLocation, out currentStatement); trackerVariables = psr.TrackerVariables; return(ret); } } trackerVariables = null; currentStatement = null; return(null); }