2026-10-18 최신: 실행 오류 수정·24시나리오 양쪽 실행 결과
108개 행의 문서 요구·현재 코드·제한을 검토했습니다. 108개 실행 대조 완료 또는 동기화율 100%를 뜻하지 않습니다. 전체 유사도는 미확인입니다.
부분 명세: 108/108. CA 자체 테스트: 267/267. 완전 동등성 인증: 0/108. 후보 테스트 연결은 해당 기능 전체 통과를 뜻하지 않습니다.
실제 VA·CA 화면 대조 · 공식 146개 문서 목차 · 전체 원본 JSON
부분 대응·제한 기록 / 전체 동등성 미검증
활성 파일 문맥 참조 이동; 전체 의미 분석 미완료
}
public static class ContextReferenceNavigation
{
public static SelectionRange Move(string text,int caret,bool forward)
{
if(text==null||caret<0||caret>text.Length)return null;
var word=IdentifierParser.At(text,caret);if(word.Length==0)return null;
CodeAssist.Core/ContextReferenceNavigation.cs:47 while(start>0&&(char.IsLetterOrDigit(text[start-1])||text[start-1]=='_'))start--;
var context=new CppReferenceContext(text);
if(start<0||start>=context.Code.Length||context.Code.Substring(start,word.Length)!=word)return null;
var matches=context.References(word,context.DeclarationAt(word,start));
if(matches.Count==0)return null;
if(forward){foreach(var offset in matches)if(offset>start)return new SelectionRange(offset,word.Length);return new SelectionRange(matches[0],word.Length);}
for(var i=matches.Count-1;i>=0;i--)if(matches[i]<start)return new SelectionRange(matches[i],word.Length);
CodeAssist.Core/ContextReferenceNavigation.cs:48 var context=new CppReferenceContext(text);
if(start<0||start>=context.Code.Length||context.Code.Substring(start,word.Length)!=word)return null;
var matches=context.References(word,context.DeclarationAt(word,start));
if(matches.Count==0)return null;
if(forward){foreach(var offset in matches)if(offset>start)return new SelectionRange(offset,word.Length);return new SelectionRange(matches[0],word.Length);}
for(var i=matches.Count-1;i>=0;i--)if(matches[i]<start)return new SelectionRange(matches[i],word.Length);
return new SelectionRange(matches[matches.Count-1],word.Length);
CodeAssist.Extension/ToolbarCommands.cs:57 var id = item.Key;
if (!(service?.FindCommand(new CommandID(GoToSymbolCommand.CommandSet,id)) is OleMenuCommand command)) continue;
void UpdateLabel(object sender, EventArgs args)
{
ThreadHelper.ThrowIfNotOnUIThread();
command.Text = UiCommandLabels.Get(id,StartupUi.Preferences.UiLanguage);
}
CodeAssist.Extension/ToolbarCommands.cs:77 var names=new System.Collections.Generic.Dictionary<int,string>{
{0x141,"Settings"},{0x103,"OpenFile"},{0x104,"FindSymbol"},{0x102,"FindReferences"},
{0x150,"PreviousContext"},{0x151,"NextContext"},{0x117,"Snippet"},{0x152,"SpellCheck"},
{0x105,"CorrespondingFile"},{0x153,"SkipBreakpoints"},{0x154,"ThreadBreakpoints"},{0x140,"Welcome"}};
foreach(Microsoft.VisualStudio.CommandBars.CommandBarControl control in bars["CodeAssist"].Controls)
{
if(!names.TryGetValue(control.Id,out var key)) {
CodeAssist.Extension/ToolbarCommands.cs:78 {0x141,"Settings"},{0x103,"OpenFile"},{0x104,"FindSymbol"},{0x102,"FindReferences"},
{0x150,"PreviousContext"},{0x151,"NextContext"},{0x117,"Snippet"},{0x152,"SpellCheck"},
{0x105,"CorrespondingFile"},{0x153,"SkipBreakpoints"},{0x154,"ThreadBreakpoints"},{0x140,"Welcome"}};
foreach(Microsoft.VisualStudio.CommandBars.CommandBarControl control in bars["CodeAssist"].Controls)
{
if(!names.TryGetValue(control.Id,out var key)) {
key=control.Tag as string;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
CA 결과 창은 목록과 결과 수를 제공하며 VA의 D/R/W 필터·프로젝트 트리는 제공하지 않습니다.
{
private readonly ListBox list = new ListBox();
private readonly TextBlock title = new TextBlock { Margin = new System.Windows.Thickness(5) };
private AsyncPackage package;
internal ReferencePane()
{
var panel = new DockPanel(); DockPanel.SetDock(title, Dock.Top); panel.Children.Add(title); panel.Children.Add(list); Content = panel;
CodeAssist.Extension/FindReferencesCommand.cs:13{
internal sealed class FindReferencesCommand
{
public const int CommandId = 0x0102;
private static readonly Guid OutputPaneGuid = new Guid("5725d377-6839-49a5-b9e2-67694bb4594f");
private readonly AsyncPackage package;
private readonly IntelliSenseSquiggleController controller;
CodeAssist.Extension/FindReferencesCommand.cs:22
private FindReferencesCommand(AsyncPackage package, IntelliSenseSquiggleController controller, ProjectIndexService indexService, OleMenuCommandService commandService)
{
this.package = package;
this.controller = controller;
this.indexService = indexService;
commandService.AddCommand(new OleMenuCommand(Execute, new CommandID(GoToSymbolCommand.CommandSet, CommandId)));
CodeAssist.Extension/FindReferencesCommand.cs:34 var commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;
if (commandService != null) _ = new FindReferencesCommand(package, controller, indexService, commandService);
}
private void Execute(object sender, EventArgs e)
{
pendingSearch?.Cancel(); pendingSearch?.Dispose();
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
동일 fixture의 19개 심볼 결과는 실제 일치했습니다. 순서·이름 표기·필터 UI는 다릅니다.
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
var tagPicker = new NavigationPicker("CodeAssist: Hashtags", tags, package.JoinableTaskFactory);
new System.Windows.Interop.WindowInteropHelper(tagPicker).Owner = (IntPtr)dte.MainWindow.HWnd;
if (tagPicker.ShowDialog() == true) Open(dte, tagPicker.Selected);
return;
}
if (command == 0x0111)
CodeAssist.Extension/NavigationCommands.cs:231 }).ToArray();
var includePicker = new NavigationPicker("CodeAssist: Include Files", includes, package.JoinableTaskFactory);
new System.Windows.Interop.WindowInteropHelper(includePicker).Owner = (IntPtr)dte.MainWindow.HWnd;
if (includePicker.ShowDialog() == true) Open(dte, includePicker.Selected);
return;
}
var symbol = selection == null ? "" : IdentifierParser.At(selection.ActivePoint.CreateEditPoint().GetLines(selection.ActivePoint.Line, selection.ActivePoint.Line + 1), selection.ActivePoint.LineCharOffset - 1);
CodeAssist.Extension/NavigationCommands.cs:263 var title = command == 0x0103 ? "CodeAssist: 파일 찾기" : command == 0x0105 ? "CodeAssist: 대응 파일" : command == 0x0106 ? "CodeAssist: 현재 파일 메서드" : command == 0x0107 ? "CodeAssist: 관련 심볼 후보" : "CodeAssist: 심볼 찾기";
var picker = new NavigationPicker(title, entries, package.JoinableTaskFactory, indexes.ProjectRoot, command == 0x0104);
new System.Windows.Interop.WindowInteropHelper(picker).Owner = (IntPtr)dte.MainWindow.HWnd;
if (picker.ShowDialog() == true && picker.Selected != null) { Open(dte, picker.Selected); if(picker.FindReferencesRequested) StartupUi.Execute(0x0102); }
}
private static bool IsImplementation(string path) => new[]{".cpp",".cxx",".cc",".c"}.Contains(Path.GetExtension(path).ToLowerInvariant());
private static NavigationEntry Entry(IndexedSymbol item) => new NavigationEntry((item.OwnerType.Length > 0 ? item.OwnerType + "::" : "") +
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
clangd 정의 조회 후 인덱스 또는 VS 명령으로 이동합니다. 모든 VA 언어·문맥에서의 목적지 일치는 미검증입니다.
var semanticText = semanticDocument?.StartPoint.CreateEditPoint().GetText(semanticDocument.EndPoint);
var compilerResults = await CompilerSemanticService.Instance.FindAsync("textDocument/definition", solutionDirectory,
dte.FullName, dte.ActiveDocument.FullName, semanticText, selection.ActivePoint.Line, selection.ActivePoint.LineCharOffset, package.DisposalToken);
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
var results = compilerResults != null && compilerResults.Length > 0 ? compilerResults.Select(item =>
new SourceSymbol(symbolName, item.File, item.Line, item.Column, SymbolKind.Unknown)).ToArray() : indexService?.Index.FindDefinitions(symbolName);
if (results == null || results.Count == 0)
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
인덱스 기반 멤버 선택·이동; 실제 IDE·VA 비교 미검증
try{await owner.ExecuteAsync(captured);}catch(Exception error){await package.JoinableTaskFactory.SwitchToMainThreadAsync();MessageBox.Show(error.Message,"CodeAssist",MessageBoxButton.OK,MessageBoxImage.Warning);}
}).FileAndForget("CodeAssist/EditorFeature"),new CommandID(GoToSymbolCommand.CommandSet,id)));
}
}
private async System.Threading.Tasks.Task ExecuteAsync(int id)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
CodeAssist.Extension/EditorFeatureCommands.cs:68 var type=word.Length==0?CppExpressionContext.FindEnclosingFunctionOwner(text,caret):new CppReferenceContext(text).ResolveVariableType(word,caret)??indexes.Index.ResolveVariableType(word)??word;
var entries=indexes.Index.CompleteMembers(type,"",2000).Where(s=>File.Exists(s.FilePath)).Select(s=>new NavigationEntry((s.OwnerType.Length>0?s.OwnerType+"::":"")+(s.Signature.Length>0?s.Signature:s.Name),s.FilePath,s.Line,s.Column)).ToArray();
var picker=new NavigationPicker("CodeAssist: Go To Member",entries,package.JoinableTaskFactory);new System.Windows.Interop.WindowInteropHelper(picker).Owner=(IntPtr)dte.MainWindow.HWnd;
if(picker.ShowDialog()==true&&picker.Selected!=null){dte.ItemOperations.OpenFile(picker.Selected.File,EnvDTE.Constants.vsViewKindTextView);(dte.ActiveDocument.Selection as EnvDTE.TextSelection)?.MoveToLineAndOffset(picker.Selected.Line,picker.Selected.Column,false);}return;
}
if(id==0x175){if(selected.Length==0)return;SnippetInsertion.Show(view,file,indexes.ProjectRoot,(IntPtr)dte.MainWindow.HWnd,null,dte.Solution?.FullName,true);return;}
if(id==0x176)
CodeAssist.Extension/EditorFeatureCommands.cs:69 var entries=indexes.Index.CompleteMembers(type,"",2000).Where(s=>File.Exists(s.FilePath)).Select(s=>new NavigationEntry((s.OwnerType.Length>0?s.OwnerType+"::":"")+(s.Signature.Length>0?s.Signature:s.Name),s.FilePath,s.Line,s.Column)).ToArray();
var picker=new NavigationPicker("CodeAssist: Go To Member",entries,package.JoinableTaskFactory);new System.Windows.Interop.WindowInteropHelper(picker).Owner=(IntPtr)dte.MainWindow.HWnd;
if(picker.ShowDialog()==true&&picker.Selected!=null){dte.ItemOperations.OpenFile(picker.Selected.File,EnvDTE.Constants.vsViewKindTextView);(dte.ActiveDocument.Selection as EnvDTE.TextSelection)?.MoveToLineAndOffset(picker.Selected.Line,picker.Selected.Column,false);}return;
}
if(id==0x175){if(selected.Length==0)return;SnippetInsertion.Show(view,file,indexes.ProjectRoot,(IntPtr)dte.MainWindow.HWnd,null,dte.Solution?.FullName,true);return;}
if(id==0x176)
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
service.AddCommand(new OleMenuCommand((s, e) => package.JoinableTaskFactory.RunAsync(() => commands.ExecuteAsync(command))
.FileAndForget("CodeAssist/Navigation"), new CommandID(GoToSymbolCommand.CommandSet, id)));
}
}
private async System.Threading.Tasks.Task ExecuteAsync(int command)
{
CodeAssist.Extension/NavigationCommands.cs:256 var owner = text == null || selection == null ? null : CppExpressionContext.FindEnclosingFunctionOwner(text, selection.ActivePoint.AbsoluteCharOffset - 1);
entries = await System.Threading.Tasks.Task.Run(() => (command == 0x0107 ? indexes.Index.RelatedSymbols(symbol, owner) :
indexes.Index.SearchSymbols("", limit: int.MaxValue))
.GroupBy(item=>item.Kind+"|"+item.OwnerType+"|"+item.Name+"|"+item.Signature+"|"+item.ValueType)
.Select(group=>group.OrderBy(item=>!string.IsNullOrEmpty(indexes.ProjectRoot)&&item.FilePath.StartsWith(indexes.ProjectRoot.TrimEnd(Path.DirectorySeparatorChar)+Path.DirectorySeparatorChar,StringComparison.OrdinalIgnoreCase)?0:1).ThenBy(item=>IsImplementation(item.FilePath)?0:1).First()).Select(Entry).ToArray());
}
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
CodeAssist.Extension/NavigationCommands.cs:333 var buttons=new StackPanel {Orientation=Orientation.Horizontal,HorizontalAlignment=HorizontalAlignment.Right};DockPanel.SetDock(buttons,Dock.Right);footer.Children.Add(buttons);
var go=ProductTheme.Button("Goto",()=>{if(Selected!=null)DialogResult=true;},true);go.IsDefault=true;buttons.Children.Add(go);
if(symbols) buttons.Children.Add(ProductTheme.Button("Find References",()=>{if(Selected!=null){FindReferencesRequested=true;DialogResult=true;}}));
var cancel=ProductTheme.Button("Cancel",()=>DialogResult=false);cancel.IsCancel=true;buttons.Children.Add(cancel);
var brand=new StackPanel {Orientation=Orientation.Horizontal,VerticalAlignment=VerticalAlignment.Center};
var brandFile=Path.Combine(Path.GetDirectoryName(typeof(NavigationPicker).Assembly.Location),"Resources","CodeAssist16.png");
if(File.Exists(brandFile))brand.Children.Add(new Image {Source=new System.Windows.Media.Imaging.BitmapImage(new Uri(brandFile)),Width=16,Height=16,Margin=new Thickness(0,0,5,0)});
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
VS 현재 줄 강조 옵션 연결; 실제 IDE·VA 비교 미검증
if(!map.At(position,out partner)){position=caret-1;if(!map.At(position,out partner))yield break;}
var p=StartupUi.Preferences;if(partner<0&&!p.HighlightMismatchingBraces||partner>=0&&!p.HighlightMatchingBraces)yield break;
var tag=new TextMarkerTag(partner<0?"CodeAssist Mismatched Brace":"CodeAssist Matched Brace");
foreach(var offset in partner<0?new[]{position}:new[]{position,partner}){var span=new SnapshotSpan(snapshot,offset,1);foreach(var requested in spans)if(requested.IntersectsWith(span)){yield return new TagSpan<TextMarkerTag>(span,tag);break;}}
}
}
[Export(typeof(IWpfTextViewCreationListener))][ContentType("C/C++")][TextViewRole(PredefinedTextViewRoles.Document)]
CodeAssist.Extension/EditorGuides.cs:60 if(view.IsClosed)return;layer.RemoveAllAdornments();var p=StartupUi.Preferences;
if(view.Options.GetOptionValue(DefaultWpfViewOptions.EnableHighlightCurrentLineId)!=p.HighlightCurrentLine)view.Options.SetOptionValue(DefaultWpfViewOptions.EnableHighlightCurrentLineId,p.HighlightCurrentLine);
if(!p.ColumnIndicatorEnabled||view.ViewportHeight<=0)return;
var x=view.FormattedLineSource.BaseIndentation+view.FormattedLineSource.ColumnWidth*p.ColumnIndicator-view.ViewportLeft;
if(x<0||x>view.ViewportWidth)return;
var line=new Line {X1=x,X2=x,Y1=0,Y2=view.ViewportHeight,Stroke=Brushes.Gray,Opacity=.5,StrokeThickness=1,IsHitTestVisible=false};
layer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative,null,null,line,null);
CodeAssist.Extension/EditorGuides.cs:62 if(!p.ColumnIndicatorEnabled||view.ViewportHeight<=0)return;
var x=view.FormattedLineSource.BaseIndentation+view.FormattedLineSource.ColumnWidth*p.ColumnIndicator-view.ViewportLeft;
if(x<0||x>view.ViewportWidth)return;
var line=new Line {X1=x,X2=x,Y1=0,Y2=view.ViewportHeight,Stroke=Brushes.Gray,Opacity=.5,StrokeThickness=1,IsHitTestVisible=false};
layer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative,null,null,line,null);
}
private void Closed(object sender,EventArgs e){view.LayoutChanged-=Layout;view.Closed-=Closed;StartupUi.SettingsApplied-=Update;}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
CA는 현재 파일 함수 5개를 별도 검색창에 표시합니다. VA는 탐색 바 드롭다운입니다.
entries = await System.Threading.Tasks.Task.Run(() => PersistentSymbolIndex.ReadDocumentSymbols(file, text)
.Where(item => item.Kind == SymbolKind.Function).Select(Entry).ToArray());
}
else
{
var owner = text == null || selection == null ? null : CppExpressionContext.FindEnclosingFunctionOwner(text, selection.ActivePoint.AbsoluteCharOffset - 1);
entries = await System.Threading.Tasks.Task.Run(() => (command == 0x0107 ? indexes.Index.RelatedSymbols(symbol, owner) :
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
view.Selection.Select(new SnapshotSpan(updated, change.Start, change.Text.Length), false);
view.Caret.MoveTo(new SnapshotPoint(updated, change.Start + change.Text.Length));
}
}
else if (command == 0x011d)
{
if (!view.TextBuffer.ContentType.IsOfType("C/C++")) return;
CodeAssist.Extension/NavigationCommands.cs:150 view.Selection.Select(new SnapshotSpan(view.TextSnapshot, range.Start, range.Length), false);
view.Caret.MoveTo(new SnapshotPoint(view.TextSnapshot, range.End));
view.ViewScroller.EnsureSpanVisible(new SnapshotSpan(view.TextSnapshot, range.Start, range.Length));
}
}
}
return;
CodeAssist.Extension/NavigationCommands.cs:187 var position = selection.ActivePoint.AbsoluteCharOffset - 1;
var target = CppScopeNavigation.Move(text, position, command == 0x010d);
if (target >= 0) selection.MoveToAbsoluteOffset(target + 1, false);
return;
}
controller?.Refresh();
var projectMarker=controller?.UnrealProjectPath;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
{
var native = new[] { "View.NavigateBackward", "View.NavigateForward", "Refactor.Rename", "View.QuickActions", "View.QuickActions" }[command - 0x0108];
try
{
if (!dte.Commands.Item(native).IsAvailable) { ShowUnavailable(native); return; }
dte.ExecuteCommand(native);
}
CodeAssist.Extension/NavigationCommands.cs:317 public object Convert(object[] values,Type targetType,object parameter,System.Globalization.CultureInfo culture) => ProductTheme.Palette.Convert(values.Length>1?values[1]:null,targetType,values.Length>0?values[0]:null,culture);
public object[] ConvertBack(object value,Type[] types,object parameter,System.Globalization.CultureInfo culture)=>throw new NotSupportedException();
}
public NavigationPicker(string title, NavigationEntry[] entries, Microsoft.VisualStudio.Threading.JoinableTaskFactory tasks, string solutionRoot=null, bool symbols=false)
{
this.entries = entries; Title=title; Width=886; Height=396; MinWidth=640; MinHeight=300; WindowStartupLocation=WindowStartupLocation.CenterOwner;
ProductTheme.Apply(this); FontSize=12;
CodeAssist.Extension/NavigationCommands.cs:342 var template=new DataTemplate(typeof(NavigationEntry));var label=new FrameworkElementFactory(typeof(TextBlock));label.SetBinding(TextBlock.TextProperty,new Binding("Name"));
var colors=new MultiBinding {Converter=new SymbolInkConverter()};colors.Bindings.Add(new Binding("Kind"));colors.Bindings.Add(new Binding("Background"){RelativeSource=new RelativeSource(RelativeSourceMode.FindAncestor,typeof(ListView),1)});label.SetBinding(TextBlock.ForegroundProperty,colors);var icon=new FrameworkElementFactory(typeof(Microsoft.VisualStudio.Imaging.CrispImage));icon.SetValue(FrameworkElement.WidthProperty,16.0);icon.SetValue(FrameworkElement.HeightProperty,16.0);icon.SetValue(FrameworkElement.MarginProperty,new Thickness(0,0,5,0));icon.SetBinding(Microsoft.VisualStudio.Imaging.CrispImage.MonikerProperty,new Binding("Icon"));icon.SetValue(DockPanel.DockProperty,Dock.Left);var symbolCell=new FrameworkElementFactory(typeof(DockPanel));symbolCell.AppendChild(icon);symbolCell.AppendChild(label);template.VisualTree=symbolCell;
columns.Columns.Add(new GridViewColumn {Header=UiText.Get(symbols?"Symbol":"File",StartupUi.Preferences.UiLanguage),Width=290,CellTemplate=template});
columns.Columns.Add(new GridViewColumn {Header=UiText.Get(symbols?"Definition":"Path",StartupUi.Preferences.UiLanguage),Width=510,DisplayMemberBinding=new Binding("Definition")});
var rows=new Style(typeof(ListViewItem));rows.Setters.Add(new Setter(Control.PaddingProperty,new Thickness(3,2,3,2)));rows.Setters.Add(new Setter(FrameworkElement.ToolTipProperty,new Binding("File")));
rows.Setters.Add(new Setter(Control.BackgroundProperty,Brushes.Transparent));
rows.Setters.Add(new Setter(Control.ForegroundProperty,new System.Windows.DynamicResourceExtension(EnvironmentColors.ToolWindowTextBrushKey)));
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
var position = selection.ActivePoint.AbsoluteCharOffset - 1;
var target = CppScopeNavigation.Move(text, position, command == 0x010d);
if (target >= 0) selection.MoveToAbsoluteOffset(target + 1, false);
return;
}
controller?.Refresh();
var projectMarker=controller?.UnrealProjectPath;
CodeAssist.Extension/NavigationCommands.cs:216 new System.Windows.Interop.WindowInteropHelper(tagPicker).Owner = (IntPtr)dte.MainWindow.HWnd;
if (tagPicker.ShowDialog() == true) Open(dte, tagPicker.Selected);
return;
}
if (command == 0x0111)
{
if (text == null || file == null) return;
CodeAssist.Extension/NavigationCommands.cs:233 new System.Windows.Interop.WindowInteropHelper(includePicker).Owner = (IntPtr)dte.MainWindow.HWnd;
if (includePicker.ShowDialog() == true) Open(dte, includePicker.Selected);
return;
}
var symbol = selection == null ? "" : IdentifierParser.At(selection.ActivePoint.CreateEditPoint().GetLines(selection.ActivePoint.Line, selection.ActivePoint.Line + 1), selection.ActivePoint.LineCharOffset - 1);
NavigationEntry[] entries;
if (command == 0x0103 || command == 0x0105)
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
실행 2개 검색 사례와 과거 관찰 10개 결과 집합은 일치합니다. Solution only 및 표시 UI는 다릅니다.
{
var files = indexes.Index.SourceFiles().Concat(file != null && text != null ? new[] { file } : Array.Empty<string>()).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
var activeFile = file; var activeText = text;
var tags = await System.Threading.Tasks.Task.Run(() => files.SelectMany(path =>
{
try
{
CodeAssist.Extension/NavigationCommands.cs:222 if (text == null || file == null) return;
var files = indexes.Index.SourceFiles();
var includes = CppDocumentNavigation.Includes(text).SelectMany(include =>
{
var relative = include.Name.Replace('/', Path.DirectorySeparatorChar);
var local = Path.Combine(Path.GetDirectoryName(file), relative);
return files.Where(path => path.EndsWith(Path.DirectorySeparatorChar + relative, StringComparison.OrdinalIgnoreCase))
CodeAssist.Extension/NavigationCommands.cs:240 {
entries = await System.Threading.Tasks.Task.Run(() => indexes.Index.SourceFiles().Select(path => new NavigationEntry(Path.GetFileName(path), path, 1, 1)).ToArray());
if (command == 0x0105)
{
entries = entries.Where(entry => !string.Equals(entry.File, file, StringComparison.OrdinalIgnoreCase) &&
string.Equals(Path.GetFileNameWithoutExtension(entry.File), Path.GetFileNameWithoutExtension(file), StringComparison.OrdinalIgnoreCase)).ToArray();
if (entries.Length == 1) { Open(dte, entries[0]); return; }
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
var contents = string.Equals(path, activeFile, StringComparison.OrdinalIgnoreCase) && activeText != null ? activeText : File.ReadAllText(path);
return CppDocumentNavigation.Hashtags(contents).Select(tag => new NavigationEntry(tag.Name, path, tag.Line, 1)).ToArray();
}
catch (IOException) { return Array.Empty<NavigationEntry>(); }
catch (UnauthorizedAccessException) { return Array.Empty<NavigationEntry>(); }
}).OrderBy(item => item.Name).ThenBy(item => item.File).ToArray());
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
CodeAssist.Extension/NavigationCommands.cs:214 await package.JoinableTaskFactory.SwitchToMainThreadAsync();
var tagPicker = new NavigationPicker("CodeAssist: Hashtags", tags, package.JoinableTaskFactory);
new System.Windows.Interop.WindowInteropHelper(tagPicker).Owner = (IntPtr)dte.MainWindow.HWnd;
if (tagPicker.ShowDialog() == true) Open(dte, tagPicker.Selected);
return;
}
if (command == 0x0111)
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
경로와 메서드 탐색; Context/Definition 필드 전체 미완료
[Import] internal ProjectIndexService Indexes=null;
public IWpfTextViewMargin CreateMargin(IWpfTextViewHost host,IWpfTextViewMargin parent)
{
Documents.TryGetTextDocument(host.TextView.TextDataModel.DocumentBuffer,out var document);
return new ContextBarMargin(host.TextView,document?.FilePath,Indexes);
}
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
<Commands package="guidCodeAssistPackage">
<Menus>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenu" priority="0x0100" type="Menu"><Parent guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenuGroup" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistContextMenu" priority="0x0700" type="Menu"><Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolbar" priority="0x0100" type="Toolbar">
<CommandFlag>DefaultDocked</CommandFlag><Strings><ButtonText>CodeAssist</ButtonText><CommandName>CodeAssist</CommandName></Strings>
CodeAssist.Extension/CodeAssistCommands.vsct:9 <Menus>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenu" priority="0x0100" type="Menu"><Parent guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenuGroup" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistContextMenu" priority="0x0700" type="Menu"><Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolbar" priority="0x0100" type="Toolbar">
<CommandFlag>DefaultDocked</CommandFlag><Strings><ButtonText>CodeAssist</ButtonText><CommandName>CodeAssist</CommandName></Strings>
</Menu>
</Menus>
CodeAssist.Extension/CodeAssistCommands.vsct:10 <Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenu" priority="0x0100" type="Menu"><Parent guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenuGroup" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistContextMenu" priority="0x0700" type="Menu"><Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolbar" priority="0x0100" type="Toolbar">
<CommandFlag>DefaultDocked</CommandFlag><Strings><ButtonText>CodeAssist</ButtonText><CommandName>CodeAssist</CommandName></Strings>
</Menu>
</Menus>
<Groups>
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
VA는 시그니처 각 부분 변경을 제공하지만 CA 명령은 순서 변경만 받습니다. 완전 일치가 아닙니다.
{
var input=EditorFeatureCommands.Prompt(dte,"New parameter order (one-based, e.g. 2,1; reorder only)","2,1");if(input==null)return;
var order=input.Split(',').Select(v=>int.Parse(v.Trim(),System.Globalization.CultureInfo.InvariantCulture)-1).ToArray();
var declarations=Locations(await Query("textDocument/declaration",active,caret)).Concat(Locations(await Query("textDocument/definition",active,caret))).ToArray();
if(declarations.Length==0)throw new NotSupportedException("The compiler did not resolve a callable declaration.");
var references=Locations(await Query("textDocument/references",active,caret,new JObject {["context"]=new JObject {["includeDeclaration"]=true}})).Concat(declarations).ToArray();
var declarationKeys=new HashSet<string>(StringComparer.OrdinalIgnoreCase);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
지역 변수의 멤버 접근 전용 포인터↔인스턴스 변환; 주소 유출·delete·포인터 연산 거부; VA 동등성 미검증
case 0x18b:
result=CppDocumentTransforms.ConvertLocalPointer(snapshot.GetText(),start,length);start=0;length=snapshot.Length;title="Convert Local Pointer / Instance";break;
case 0x18c:
if(selected.Length==0)throw new ArgumentException("Select statements to extract.");var signature=Ask("New free-function signature (use reference parameters for outputs)","void Extracted()");if(signature==null)return;
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
CodeAssist.Extension/RefactoringCommands.cs:42 result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
CA 함수는 필드 선언과 getter/setter 문자열만 생성합니다. VA의 프로젝트 참조 갱신과 같지 않습니다.
}
public static string EncapsulateField(string declaration,string propertyName,string newline="\n")
{
var m=Match(declaration??"",@"^\s*(?<type>(?:const\s+)?[A-Za-z_]\w*(?:::[A-Za-z_]\w*)*(?:\s*[*&])?)\s+(?<field>[A-Za-z_]\w*)\s*;\s*$");
if(!m.Success||!QualifiedIdentifier(propertyName)||propertyName.Contains("::"))return null;
var type=m.Groups["type"].Value;var field=m.Groups["field"].Value;
return "private:"+newline+" "+declaration.Trim()+newline+"public:"+newline+" "+type+" Get"+propertyName+"() const { return "+field+"; }"+newline+(type.StartsWith("const ",StringComparison.Ordinal)?"":" void Set"+propertyName+"("+type+" value) { "+field+" = value; }"+newline);
CodeAssist.Extension/RefactoringCommands.cs:44 case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
전역 void 함수로 선택 문장 추출; 입력·출력 매개변수는 사용자 지정, 클래스·템플릿·제어 이전 제외; VA 동등성 미검증
case 0x18c:
if(selected.Length==0)throw new ArgumentException("Select statements to extract.");var signature=Ask("New free-function signature (use reference parameters for outputs)","void Extracted()");if(signature==null)return;
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
CodeAssist.Extension/RefactoringCommands.cs:41 if(selected.Length==0)throw new ArgumentException("Select statements to extract.");var signature=Ask("New free-function signature (use reference parameters for outputs)","void Extracted()");if(signature==null)return;
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
CodeAssist.Extension/RefactoringCommands.cs:46 case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
clangd 변수 추출 변경 미리보기; 실제 IDE·VA 비교 미검증
{
private sealed class ActionItem {internal JObject Action;public override string ToString()=>(string)Action["title"];}
internal static async Task<bool> TryAsync(AsyncPackage package,EnvDTE80.DTE2 dte,bool quickFix=false,bool toolWindow=false)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
var file=dte.ActiveDocument?.FullName;if(string.IsNullOrEmpty(file))return false;
var root=Path.GetDirectoryName(file);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
clangd 소스→헤더 구현 이동 미리보기; 실제 IDE·VA 비교 미검증
{
private sealed class ActionItem {internal JObject Action;public override string ToString()=>(string)Action["title"];}
internal static async Task<bool> TryAsync(AsyncPackage package,EnvDTE80.DTE2 dte,bool quickFix=false,bool toolWindow=false)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
var file=dte.ActiveDocument?.FullName;if(string.IsNullOrEmpty(file))return false;
var root=Path.GetDirectoryName(file);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
clangd 헤더→소스 구현 이동 미리보기; 실제 IDE·VA 비교 미검증
if(actions==null||actions.Length==0)return false;
var list=new ListBox {ItemsSource=actions,SelectedIndex=0,Margin=new Thickness(14)};
var rootPanel=new DockPanel();ProductTheme.Apply(rootPanel);rootPanel.Children.Add(list);
var dialog=new Window {Title="CodeAssist: Compiler Refactorings",Content=rootPanel,Width=650,Height=400,WindowStartupLocation=WindowStartupLocation.CenterOwner};
new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;
dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;if(e.Key==System.Windows.Input.Key.Enter&&list.SelectedItem!=null)dialog.DialogResult=true;};
list.MouseDoubleClick+=(s,e)=>{if(!toolWindow&&list.SelectedItem!=null)dialog.DialogResult=true;};
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
clangd out-of-line 수정을 메모리에서 순차 합성 후 일괄 미리보기; 기존 대응 파일 필요, 200회·30초 한도; VA 동등성 미검증
var deadline=DateTime.UtcNow.AddSeconds(30);
Task<JToken> Query(string method,string text,int offset,JObject args=null,IDictionary<string,string> documents=null)
{if(DateTime.UtcNow>deadline)throw new TimeoutException("Semantic refactoring exceeded 30 seconds; no files were changed.");var p=Position(text,offset);return CompilerSemanticService.Instance.QueryAsync(method,root,dte.FullName,file,text,(int)p["line"]+1,(int)p["character"]+1,token,args,documents??before);}
if(command==0x1c0)
{
var input=EditorFeatureCommands.Prompt(dte,"New parameter order (one-based, e.g. 2,1; reorder only)","2,1");if(input==null)return;
var order=input.Split(',').Select(v=>int.Parse(v.Trim(),System.Globalization.CultureInfo.InvariantCulture)-1).ToArray();
CodeAssist.Extension/SemanticRefactoringCommands.cs:44 Task<JToken> Query(string method,string text,int offset,JObject args=null,IDictionary<string,string> documents=null)
{if(DateTime.UtcNow>deadline)throw new TimeoutException("Semantic refactoring exceeded 30 seconds; no files were changed.");var p=Position(text,offset);return CompilerSemanticService.Instance.QueryAsync(method,root,dte.FullName,file,text,(int)p["line"]+1,(int)p["character"]+1,token,args,documents??before);}
if(command==0x1c0)
{
var input=EditorFeatureCommands.Prompt(dte,"New parameter order (one-based, e.g. 2,1; reorder only)","2,1");if(input==null)return;
var order=input.Split(',').Select(v=>int.Parse(v.Trim(),System.Globalization.CultureInfo.InvariantCulture)-1).ToArray();
var declarations=Locations(await Query("textDocument/declaration",active,caret)).Concat(Locations(await Query("textDocument/definition",active,caret))).ToArray();
CodeAssist.Extension/SemanticRefactoringCommands.cs:64 }
var working=new Dictionary<string,string>(before,StringComparer.OrdinalIgnoreCase);var moved=0;
try
{
for(var pass=0;pass<200;pass++)
{
token.ThrowIfCancellationRequested();var current=working[file];JToken selectedEdit=null;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 텍스트 새 파일 이동; include·프로젝트 추가 자동화 없음; 실제 IDE·VA 비교 미검증
var view=components.GetService<IVsEditorAdaptersFactoryService>().GetWpfTextView(adapter);if(view==null||view.IsClosed)return;
var snapshot=view.TextSnapshot;var selected=view.Selection.StreamSelectionSpan.SnapshotSpan;var caret=view.Caret.Position.BufferPosition.Position;var text=snapshot.GetText();
var line=snapshot.GetLineFromPosition(caret);var word=IdentifierParser.At(line.GetText(),caret-line.Start.Position);
if(id==0x17b)
{
var links=SourceLinks.Find(line.GetText(),StartupUi.Preferences.SourceLinkRules).Where(candidate=>caret-line.Start.Position>=candidate.Start&&caret-line.Start.Position<=candidate.Start+candidate.Length).ToArray();
if(links.Length==0)throw new InvalidOperationException(UiText.Get("No source link matches the caret. Configure Navigation / Source Links.",StartupUi.Preferences.UiLanguage));
CodeAssist.Extension/EditorFeatureCommands.cs:70 var picker=new NavigationPicker("CodeAssist: Go To Member",entries,package.JoinableTaskFactory);new System.Windows.Interop.WindowInteropHelper(picker).Owner=(IntPtr)dte.MainWindow.HWnd;
if(picker.ShowDialog()==true&&picker.Selected!=null){dte.ItemOperations.OpenFile(picker.Selected.File,EnvDTE.Constants.vsViewKindTextView);(dte.ActiveDocument.Selection as EnvDTE.TextSelection)?.MoveToLineAndOffset(picker.Selected.Line,picker.Selected.Column,false);}return;
}
if(id==0x175){if(selected.Length==0)return;SnippetInsertion.Show(view,file,indexes.ProjectRoot,(IntPtr)dte.MainWindow.HWnd,null,dte.Solution?.FullName,true);return;}
if(id==0x176)
{
if(selected.Length==0)return;
CodeAssist.Extension/EditorFeatureCommands.cs:76 if(selected.Length==0)return;
var title=Prompt(dte,"Snippet title","Selection");if(title==null)return;
var shortcut=Prompt(dte,"Snippet shortcut","snippet");if(shortcut==null)return;
var root=!string.IsNullOrEmpty(dte.Solution?.FullName)?Path.GetDirectoryName(dte.Solution.FullName):indexes.ProjectRoot;
if(string.IsNullOrEmpty(root))throw new InvalidOperationException("Open a solution before saving a project snippet.");
var path=Path.Combine(root,".codeassist","snippets.tpl");var existing=File.Exists(path)?File.ReadAllText(path):"";
if(existing.Length>1024*1024)throw new InvalidOperationException("Snippet library exceeds 1 MiB.");
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
clangd rename 작업 편집을 사용합니다. 실제 다중 파일 변경·Undo 및 VA 비교는 미검증입니다.
}
var result = await CompilerSemanticService.Instance.QueryAsync("textDocument/rename", root, dte.FullName, file, text, line, column,
package.DisposalToken, new JObject { ["newName"] = name.Text }, open);
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
if (result == null) { MessageBox.Show("변경 계획을 만들지 못했습니다. " + CompilerSemanticService.Instance.LastError, "CodeAssist"); return true; }
var plans = new List<Plan>();
try
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
프로젝트 항목 이름 변경; include 갱신 없음; 실제 IDE·VA 비교 미검증
ThreadHelper.ThrowIfNotOnUIThread();
var dialog=new Microsoft.Win32.SaveFileDialog {Title=UiText.Get("Create file",StartupUi.Preferences.UiLanguage),InitialDirectory=string.IsNullOrEmpty(source)?null:Path.GetDirectoryName(source),FileName="NewFile.cpp",Filter="C/C++ files|*.cpp;*.h;*.hpp;*.c|All files|*.*",OverwritePrompt=false};
return dialog.ShowDialog()==true?dialog.FileName:null;
}
private static void WriteNew(string path,string contents)
{using(var stream=new FileStream(path,FileMode.CreateNew,FileAccess.Write,FileShare.None))using(var writer=new StreamWriter(stream,new System.Text.UTF8Encoding(false)))writer.Write(contents);}
internal static string Prompt(EnvDTE80.DTE2 dte,string label,string initial)
CodeAssist.Extension/EditorFeatureCommands.cs:145 private static void WriteNew(string path,string contents)
{using(var stream=new FileStream(path,FileMode.CreateNew,FileAccess.Write,FileShare.None))using(var writer=new StreamWriter(stream,new System.Text.UTF8Encoding(false)))writer.Write(contents);}
internal static string Prompt(EnvDTE80.DTE2 dte,string label,string initial)
{
ThreadHelper.ThrowIfNotOnUIThread();
var panel=new StackPanel {Margin=new Thickness(16)};ProductTheme.Apply(panel);panel.Children.Add(ProductTheme.Text(label));var input=new TextBox {Text=initial,Margin=new Thickness(0,0,0,16)};panel.Children.Add(input);
var button=ProductTheme.Button("저장",()=>{},true);button.IsDefault=true;panel.Children.Add(button);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
동일 타입 생성자 재초기화 단순화; 지원 문법 제한; 실제 IDE 및 VA 비교 미검증
case 0x18b:
result=CppDocumentTransforms.ConvertLocalPointer(snapshot.GetText(),start,length);start=0;length=snapshot.Length;title="Convert Local Pointer / Instance";break;
case 0x18c:
if(selected.Length==0)throw new ArgumentException("Select statements to extract.");var signature=Ask("New free-function signature (use reference parameters for outputs)","void Extracted()");if(signature==null)return;
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
CodeAssist.Extension/RefactoringCommands.cs:42 result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
CodeAssist.Extension/RefactoringCommands.cs:44 case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
명시적으로 입력한 클래스·구조체 전방 선언; 실제 IDE·VA 비교 미검증
var comment=CppGeneration.DocumentMethod(signature,text.Contains("\r\n")?"\r\n":"\n",indent);
if(comment==null)throw new InvalidOperationException(UiText.Get("Select a method declaration or its signature line.",StartupUi.Preferences.UiLanguage));
change=new EditorTextChange(signatureLine.Start,0,comment,signatureLine.Start.Position+comment.Length,0);
}
if(id==0x179)
{
var header=Prompt(dte,"Header name (use <...> for system headers)","");if(header==null)return;header=header.Trim();var system=header.StartsWith("<",StringComparison.Ordinal)&&header.EndsWith(">",StringComparison.Ordinal);
CodeAssist.Extension/EditorFeatureCommands.cs:120 var name=Prompt(dte,"Qualified type name (class or struct)",word);if(name==null)return;var structure=name.StartsWith("struct ",StringComparison.Ordinal);name=name.StartsWith("class ",StringComparison.Ordinal)?name.Substring(6):structure?name.Substring(7):name;
var declaration=CppGeneration.ForwardDeclaration(name.Trim(),structure)+(text.Contains("\r\n")?"\r\n":"\n");change=new EditorTextChange(line.Start,0,declaration,line.Start.Position+declaration.Length,0);
}
if(change!=null)Apply(view,snapshot,change,components,"Code Generation");
}
internal static void Apply(IWpfTextView view,ITextSnapshot expected,EditorTextChange change,IComponentModel components,string name)
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
현재 줄에 사용자 지정 멤버 선언 추가; 클래스 자동 탐색 없음; 실제 IDE 및 VA 비교 미검증
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
CodeAssist.Extension/RefactoringCommands.cs:47 var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
var ns=Ask("Namespace","std");if(ns==null)return;var directive=CppRefactoring.UsingNamespace(ns);if(directive!=null)result=directive+nl;start=line.Start;length=0;title="Add Using Directive at Current Line";break;
CodeAssist.Extension/RefactoringCommands.cs:48 if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
var ns=Ask("Namespace","std");if(ns==null)return;var directive=CppRefactoring.UsingNamespace(ns);if(directive!=null)result=directive+nl;start=line.Start;length=0;title="Add Using Directive at Current Line";break;
case 0x185:result=CppRefactoring.ToggleBraces(source);title="Add / Remove Braces";break;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 switch와 사용자가 입력한 scoped enum에서 누락 case 추가; 복합 enum 표현식 제한; 실제 IDE 및 VA 비교 미검증
{
case 0x18b:
result=CppDocumentTransforms.ConvertLocalPointer(snapshot.GetText(),start,length);start=0;length=snapshot.Length;title="Convert Local Pointer / Instance";break;
case 0x18c:
if(selected.Length==0)throw new ArgumentException("Select statements to extract.");var signature=Ask("New free-function signature (use reference parameters for outputs)","void Extracted()");if(signature==null)return;
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
CodeAssist.Extension/RefactoringCommands.cs:39 result=CppDocumentTransforms.ConvertLocalPointer(snapshot.GetText(),start,length);start=0;length=snapshot.Length;title="Convert Local Pointer / Instance";break;
case 0x18c:
if(selected.Length==0)throw new ArgumentException("Select statements to extract.");var signature=Ask("New free-function signature (use reference parameters for outputs)","void Extracted()");if(signature==null)return;
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
CodeAssist.Extension/RefactoringCommands.cs:40 case 0x18c:
if(selected.Length==0)throw new ArgumentException("Select statements to extract.");var signature=Ask("New free-function signature (use reference parameters for outputs)","void Extracted()");if(signature==null)return;
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 선언 복제 및 멤버명 교체; 실제 IDE 및 VA 비교 미검증
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
CodeAssist.Extension/RefactoringCommands.cs:47 var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
var ns=Ask("Namespace","std");if(ns==null)return;var directive=CppRefactoring.UsingNamespace(ns);if(directive!=null)result=directive+nl;start=line.Start;length=0;title="Add Using Directive at Current Line";break;
CodeAssist.Extension/RefactoringCommands.cs:48 if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
var ns=Ask("Namespace","std");if(ns==null)return;var directive=CppRefactoring.UsingNamespace(ns);if(directive!=null)result=directive+nl;start=line.Start;length=0;title="Add Using Directive at Current Line";break;
case 0x185:result=CppRefactoring.ToggleBraces(source);title="Add / Remove Braces";break;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
현재 줄에 using namespace 지시문 추가; 참조 축약 없음; 실제 IDE 및 VA 비교 미검증
using CodeAssist.Core; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor;CodeAssist.Extension/RefactoringCommands.cs:2
using CodeAssist.Core; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.TextManager.Interop;CodeAssist.Extension/RefactoringCommands.cs:3
using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.TextManager.Interop; using System;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
중복 방지 include 추가; 실제 IDE·VA 비교 미검증
var header=Prompt(dte,"Header name (use <...> for system headers)","");if(header==null)return;header=header.Trim();var system=header.StartsWith("<",StringComparison.Ordinal)&&header.EndsWith(">",StringComparison.Ordinal);
change=CppGeneration.Include(text,system?header.Substring(1,header.Length-2):header,system);
}
if(id==0x17a)
{
var name=Prompt(dte,"Qualified type name (class or struct)",word);if(name==null)return;var structure=name.StartsWith("struct ",StringComparison.Ordinal);name=name.StartsWith("class ",StringComparison.Ordinal)?name.Substring(6):structure?name.Substring(7):name;
var declaration=CppGeneration.ForwardDeclaration(name.Trim(),structure)+(text.Contains("\r\n")?"\r\n":"\n");change=new EditorTextChange(line.Start,0,declaration,line.Start.Position+declaration.Length,0);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 문장 괄호 추가; 단일 함수 호출 문장만 제거 허용; 실제 IDE 및 VA 비교 미검증
var ns=Ask("Namespace","std");if(ns==null)return;var directive=CppRefactoring.UsingNamespace(ns);if(directive!=null)result=directive+nl;start=line.Start;length=0;title="Add Using Directive at Current Line";break;
case 0x185:result=CppRefactoring.ToggleBraces(source);title="Add / Remove Braces";break;
case 0x186:
var declaration=CppRefactoring.CreateDeclaration(source);if(declaration!=null)result=declaration+nl;
start=selected.Length==0?line.Start.Position:selected.Start.Position;length=0;title="Create Declaration before Selection";break;
case 0x187:case 0x188:
var owner=Ask("Qualified owner type (empty for free function)",CppExpressionContext.FindEnclosingFunctionOwner(snapshot.GetText(),caret));if(owner==null)return;
CodeAssist.Extension/RefactoringCommands.cs:70 if(result==null)throw new InvalidOperationException(UiText.Get("The selected syntax is unsupported. Select the complete declaration or expression.",StartupUi.Preferences.UiLanguage));
var after=snapshot.GetText().Remove(start,length).Insert(start,result);
var tabs=new TabControl();tabs.Items.Add(new TabItem {Header=UiText.Get("Before",StartupUi.Preferences.UiLanguage),Content=Text(snapshot.GetText())});tabs.Items.Add(new TabItem {Header=UiText.Get("After",StartupUi.Preferences.UiLanguage),Content=Text(after)});tabs.SelectedIndex=1;
var panel=new DockPanel();ProductTheme.Apply(panel);var apply=ProductTheme.Button("Apply changes",()=>{},true);DockPanel.SetDock(apply,Dock.Bottom);panel.Children.Add(apply);panel.Children.Add(tabs);
var dialog=new Window {Title=title,Content=panel,Width=950,Height=650,WindowStartupLocation=WindowStartupLocation.CenterOwner};new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;
apply.Click+=(s,e)=>dialog.DialogResult=true;dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;};
if(dialog.ShowDialog()==true)EditorFeatureCommands.Apply(view,snapshot,new EditorTextChange(start,length,result,start,result.Length),model,title);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 정의의 선언 생성·삽입; 헤더 자동 선택 없음; 실제 IDE 및 VA 비교 미검증
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
CodeAssist.Extension/RefactoringCommands.cs:44 case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
CodeAssist.Extension/RefactoringCommands.cs:46 case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
새 파일 생성·열기; 실제 IDE·VA 비교 미검증
if(SnippetTemplate.Parse(existing).Any(t=>t.Shortcut==shortcut))throw new InvalidOperationException("Snippet shortcut already exists.");
var entry=CppGeneration.SnippetFromSelection(title,shortcut,selected.GetText());Directory.CreateDirectory(Path.GetDirectoryName(path));
var temporary=path+"."+Guid.NewGuid().ToString("N")+".tmp";
try{File.WriteAllText(temporary,existing+(existing.Length==0?"":"\f\n")+entry);if(File.Exists(path))File.Replace(temporary,path,path+".bak");else File.Move(temporary,path);}finally{if(File.Exists(temporary))File.Delete(temporary);}return;
}
if(id==0x177)
{
CodeAssist.Extension/EditorFeatureCommands.cs:129 components.GetService<ITextUndoHistoryRegistry>().TryGetHistory(view.TextBuffer,out var history);var operations=components.GetService<IEditorOperationsFactoryService>().GetEditorOperations(view);
using(var transaction=history?.CreateTransaction("CodeAssist "+name))using(var edit=view.TextBuffer.CreateEdit())
{
if(transaction!=null)operations.AddBeforeTextBufferChangePrimitive();
if(!edit.Replace(change.Start,change.Length,change.Text))throw new InvalidOperationException("The selected range is read-only.");
var updated=edit.Apply();if(edit.Canceled)throw new InvalidOperationException("Editor rejected the edit.");
view.Selection.Select(new SnapshotSpan(updated,change.SelectionStart,change.SelectionLength),false);view.Caret.MoveTo(new SnapshotPoint(updated,change.SelectionStart+change.SelectionLength));
CodeAssist.Extension/EditorFeatureCommands.cs:141 ThreadHelper.ThrowIfNotOnUIThread();
var dialog=new Microsoft.Win32.SaveFileDialog {Title=UiText.Get("Create file",StartupUi.Preferences.UiLanguage),InitialDirectory=string.IsNullOrEmpty(source)?null:Path.GetDirectoryName(source),FileName="NewFile.cpp",Filter="C/C++ files|*.cpp;*.h;*.hpp;*.c|All files|*.*",OverwritePrompt=false};
return dialog.ShowDialog()==true?dialog.FileName:null;
}
private static void WriteNew(string path,string contents)
{using(var stream=new FileStream(path,FileMode.CreateNew,FileAccess.Write,FileShare.None))using(var writer=new StreamWriter(stream,new System.Text.UTF8Encoding(false)))writer.Write(contents);}
internal static string Prompt(EnvDTE80.DTE2 dte,string label,string initial)
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
if (dialog.ShowDialog() != true || view.IsClosed || !ReferenceEquals(snapshot, view.TextSnapshot)) return;
var change = SelectedLineSort.Create(snapshot.GetText(), selected.Start.Position, selected.Length, descending.IsChecked == true, ignoreCase.IsChecked == true);
using (var edit = view.TextBuffer.CreateEdit())
{
if (!edit.Replace(new Span(change.Start, change.Length), change.Text)) return;
var updated = edit.Apply();
view.Selection.Select(new SnapshotSpan(updated, change.Start, change.Text.Length), false);
CodeAssist.Extension/NavigationCommands.cs:82 var change = SelectedLineSort.Create(snapshot.GetText(), selected.Start.Position, selected.Length, descending.IsChecked == true, ignoreCase.IsChecked == true);
using (var edit = view.TextBuffer.CreateEdit())
{
if (!edit.Replace(new Span(change.Start, change.Length), change.Text)) return;
var updated = edit.Apply();
view.Selection.Select(new SnapshotSpan(updated, change.Start, change.Text.Length), false);
view.Caret.MoveTo(new SnapshotPoint(updated, change.Start + change.Text.Length));
CodeAssist.Extension/NavigationCommands.cs:97 {
tracker = view.TextBuffer.Properties.GetOrCreateSingletonProperty(() =>
new LiveDocumentTracker(view.TextBuffer, document.FilePath, indexes));
tracker.Attach(view);
}
}
else if (command == 0x010f) view.ZoomLevel = 100;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 선언에서 파일 끝에 구현 틀 생성; throw 미구현 본문; 실제 IDE 및 VA 비교 미검증
case 0x186:
var declaration=CppRefactoring.CreateDeclaration(source);if(declaration!=null)result=declaration+nl;
start=selected.Length==0?line.Start.Position:selected.Start.Position;length=0;title="Create Declaration before Selection";break;
case 0x187:case 0x188:
var owner=Ask("Qualified owner type (empty for free function)",CppExpressionContext.FindEnclosingFunctionOwner(snapshot.GetText(),caret));if(owner==null)return;
result=id==0x187?CppRefactoring.CreateImplementation(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate):CppRefactoring.CreateImplementations(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate);
if(result!=null)result=nl+result;start=snapshot.Length;length=0;title="Generate Method Implementation(s) at End of File";break;
CodeAssist.Extension/RefactoringCommands.cs:56 var declaration=CppRefactoring.CreateDeclaration(source);if(declaration!=null)result=declaration+nl;
start=selected.Length==0?line.Start.Position:selected.Start.Position;length=0;title="Create Declaration before Selection";break;
case 0x187:case 0x188:
var owner=Ask("Qualified owner type (empty for free function)",CppExpressionContext.FindEnclosingFunctionOwner(snapshot.GetText(),caret));if(owner==null)return;
result=id==0x187?CppRefactoring.CreateImplementation(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate):CppRefactoring.CreateImplementations(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate);
if(result!=null)result=nl+result;start=snapshot.Length;length=0;title="Generate Method Implementation(s) at End of File";break;
case 0x189:
CodeAssist.Extension/RefactoringCommands.cs:59 var owner=Ask("Qualified owner type (empty for free function)",CppExpressionContext.FindEnclosingFunctionOwner(snapshot.GetText(),caret));if(owner==null)return;
result=id==0x187?CppRefactoring.CreateImplementation(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate):CppRefactoring.CreateImplementations(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate);
if(result!=null)result=nl+result;start=snapshot.Length;length=0;title="Generate Method Implementation(s) at End of File";break;
case 0x189:
var virtuals=Ask("Virtual declarations to implement in the derived class","virtual void Update() = 0;");if(virtuals==null)return;
result=CppRefactoring.CreateImplementations(virtuals,"",nl,true,StartupUi.Preferences.MethodBodyTemplate);start=caret;length=0;title="Implement Virtual Methods at Caret";break;
case 0x18a:
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택한 여러 선언의 구현 틀 생성; 지원 문법 제한; 실제 IDE 및 VA 비교 미검증
if(selected.Length==0)throw new ArgumentException("Select statements to extract.");var signature=Ask("New free-function signature (use reference parameters for outputs)","void Extracted()");if(signature==null)return;
result=CppDocumentTransforms.ExtractGlobalMethod(snapshot.GetText(),start,length,signature);start=0;length=snapshot.Length;title="Extract Method";break;
case 0x180:result=CppRefactoring.SimplifyInstance(source);title="Simplify Instance Declaration";break;
case 0x181:
var property=Ask("Accessor name suffix","Value");if(property==null)return;result=CppRefactoring.EncapsulateField(source,property,nl);title="Encapsulate Field (declaration and accessors)";break;
case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
CodeAssist.Extension/RefactoringCommands.cs:46 case 0x182:
var member=Ask("Member declaration","void NewMethod();");if(member==null)return;
if(!member.TrimEnd().EndsWith(";",StringComparison.Ordinal))throw new ArgumentException("A member declaration must end with a semicolon.");
result=member+nl;start=line.Start;length=0;title="Add Member at Current Line";break;
case 0x183:
var name=Ask("New member name","NewMember");if(name==null)return;var similar=CppRefactoring.SimilarMember(source,name);if(similar!=null)result=source+nl+similar;title="Add Similar Member";break;
case 0x184:
CodeAssist.Extension/RefactoringCommands.cs:55 case 0x186:
var declaration=CppRefactoring.CreateDeclaration(source);if(declaration!=null)result=declaration+nl;
start=selected.Length==0?line.Start.Position:selected.Start.Position;length=0;title="Create Declaration before Selection";break;
case 0x187:case 0x188:
var owner=Ask("Qualified owner type (empty for free function)",CppExpressionContext.FindEnclosingFunctionOwner(snapshot.GetText(),caret));if(owner==null)return;
result=id==0x187?CppRefactoring.CreateImplementation(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate):CppRefactoring.CreateImplementations(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate);
if(result!=null)result=nl+result;start=snapshot.Length;length=0;title="Generate Method Implementation(s) at End of File";break;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
메서드 Doxygen 주석 생성; 실제 IDE·VA 비교 미검증
var dte=await package.GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;if(dte==null)return;
var file=dte.ActiveDocument?.FullName;
if(id==0x172){var path=ChooseNewFile(file);if(path==null)return;WriteNew(path,"");dte.ItemOperations.OpenFile(path,EnvDTE.Constants.vsViewKindTextView);return;}
if(id==0x173)
{
var document=dte.ActiveDocument;var item=document?.ProjectItem;
if(document==null||item==null)throw new InvalidOperationException(UiText.Get("Select a project file first.",StartupUi.Preferences.UiLanguage));
CodeAssist.Extension/EditorFeatureCommands.cs:44 {
var document=dte.ActiveDocument;var item=document?.ProjectItem;
if(document==null||item==null)throw new InvalidOperationException(UiText.Get("Select a project file first.",StartupUi.Preferences.UiLanguage));
if(!document.Saved)throw new InvalidOperationException(UiText.Get("Save the document before renaming it.",StartupUi.Preferences.UiLanguage));
var name=Prompt(dte,"New file name",Path.GetFileName(file));if(name==null)return;
if(string.IsNullOrWhiteSpace(name)||Path.GetFileName(name)!=name||name.IndexOfAny(Path.GetInvalidFileNameChars())>=0)throw new ArgumentException("Invalid file name");
item.Name=name;return;
CodeAssist.Extension/EditorFeatureCommands.cs:45 var document=dte.ActiveDocument;var item=document?.ProjectItem;
if(document==null||item==null)throw new InvalidOperationException(UiText.Get("Select a project file first.",StartupUi.Preferences.UiLanguage));
if(!document.Saved)throw new InvalidOperationException(UiText.Get("Save the document before renaming it.",StartupUi.Preferences.UiLanguage));
var name=Prompt(dte,"New file name",Path.GetFileName(file));if(name==null)return;
if(string.IsNullOrWhiteSpace(name)||Path.GetFileName(name)!=name||name.IndexOfAny(Path.GetInvalidFileNameChars())>=0)throw new ArgumentException("Invalid file name");
item.Name=name;return;
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
사용자가 입력한 가상 선언의 override 구현 틀 삽입; 기저 클래스 자동 열거 없음; 실제 IDE 및 VA 비교 미검증
var owner=Ask("Qualified owner type (empty for free function)",CppExpressionContext.FindEnclosingFunctionOwner(snapshot.GetText(),caret));if(owner==null)return;
result=id==0x187?CppRefactoring.CreateImplementation(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate):CppRefactoring.CreateImplementations(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate);
if(result!=null)result=nl+result;start=snapshot.Length;length=0;title="Generate Method Implementation(s) at End of File";break;
case 0x189:
var virtuals=Ask("Virtual declarations to implement in the derived class","virtual void Update() = 0;");if(virtuals==null)return;
result=CppRefactoring.CreateImplementations(virtuals,"",nl,true,StartupUi.Preferences.MethodBodyTemplate);start=caret;length=0;title="Implement Virtual Methods at Caret";break;
case 0x18a:
CodeAssist.Extension/RefactoringCommands.cs:60 result=id==0x187?CppRefactoring.CreateImplementation(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate):CppRefactoring.CreateImplementations(source,owner,nl,false,StartupUi.Preferences.MethodBodyTemplate);
if(result!=null)result=nl+result;start=snapshot.Length;length=0;title="Generate Method Implementation(s) at End of File";break;
case 0x189:
var virtuals=Ask("Virtual declarations to implement in the derived class","virtual void Update() = 0;");if(virtuals==null)return;
result=CppRefactoring.CreateImplementations(virtuals,"",nl,true,StartupUi.Preferences.MethodBodyTemplate);start=caret;length=0;title="Implement Virtual Methods at Caret";break;
case 0x18a:
var enumName=Ask("Qualified scoped enum name","State");if(enumName==null)return;
CodeAssist.Extension/RefactoringCommands.cs:62 case 0x189:
var virtuals=Ask("Virtual declarations to implement in the derived class","virtual void Update() = 0;");if(virtuals==null)return;
result=CppRefactoring.CreateImplementations(virtuals,"",nl,true,StartupUi.Preferences.MethodBodyTemplate);start=caret;length=0;title="Implement Virtual Methods at Caret";break;
case 0x18a:
var enumName=Ask("Qualified scoped enum name","State");if(enumName==null)return;
var definition=Ask("Enum declaration","enum class State { Ready, Running, Done };");if(definition==null)return;
result=CppRefactoring.MissingCases(source,definition,enumName,nl);title="Add Missing Case Statements";break;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
머리글자 약어 추천 후보; IDE 필터 통과 미검증; 실제 IDE·VA 비교 미검증
public ICompletionSource TryCreateCompletionSource(ITextBuffer textBuffer)
{
if (DocumentFactory.TryGetTextDocument(textBuffer, out var document))
{
IndexService.InitializeFromDocument(document.FilePath);
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
주석 이어쓰기; 원본 비교 미완료
var value=text.Substring(start,length);
if(key=='/'&&(value.IndexOf('\n')>=0||WholeLine(text,start,length)))return ToggleLines(text,start,length,spaceAfterSlash);
if(key=='/'||key=='*')
{
if(value.StartsWith("/*",StringComparison.Ordinal)&&value.EndsWith("*/",StringComparison.Ordinal)&&value.Length>=4)
{var inner=value.Substring(2,value.Length-4);return new EditorTextChange(start,length,inner,start,inner.Length);}
if(value.Contains("*/"))return null;
CodeAssist.Core/CppEditing.cs:30 }
private static bool WholeLine(string text,int start,int length)
{
var left=start==0?0:text.LastIndexOf('\n',start-1)+1;
var right=text.IndexOf('\n',start+length);
if(right<0)right=text.Length;
return string.IsNullOrWhiteSpace(text.Substring(left,start-left))&&string.IsNullOrWhiteSpace(text.Substring(start+length,right-start-length));
CodeAssist.Core/CppEditing.cs:37 }
private static EditorTextChange ToggleLines(string text,int start,int length,bool space)
{
var left=start==0?0:text.LastIndexOf('\n',start-1)+1;
var selectedEnd=start+length;
var right=selectedEnd>0&&text[selectedEnd-1]=='\n'?selectedEnd:text.IndexOf('\n',selectedEnd);
if(right<0)right=text.Length;
CodeAssist.Extension/CompletionCommandFilter.cs:112 if(EditorInputTrace.Enabled && tracedInputs++<24)WelcomeDocumentWindow.RecordEvent("EditorInput group="+commandGroup+" id="+commandId+" typed="+(hasTypedCharacter?(int)typedCharacter:-1)+" selection="+view.Selection.StreamSelectionSpan.SnapshotSpan.Length+" surround="+StartupUi.Preferences.SurroundSelectionEnabled);
if(hasTypedCharacter&&view.Selection.IsEmpty&&TryAutomaticInput(typedCharacter))return VSConstants.S_OK;
if (hasTypedCharacter && TrySurroundSelection(typedCharacter)) return VSConstants.S_OK;
if(hasTypedCharacter && TrySkipClosing(typedCharacter))return VSConstants.S_OK;
if(hasTypedCharacter && StartupUi.Preferences.PairCompletionEnabled && CppPairing.Opening(typedCharacter))
{
var selected=view.Selection.StreamSelectionSpan.SnapshotSpan;
CodeAssist.Extension/CompletionCommandFilter.cs:123 if (commandGroup==VSConstants.VSStd2K && commandId==(uint)VSConstants.VSStd2KCmdID.RETURN &&
StartupUi.Preferences.ExtendCommentsEnabled && view.Selection.IsEmpty && !broker.IsCompletionActive(view))
{
var prefix=CppEditing.CommentContinuation(view.TextSnapshot.GetText(),view.Caret.Position.BufferPosition.Position);
if(prefix!=null)return ContinueComment(ref commandGroup,commandId,commandOptions,input,output,prefix);
}
var pasteSpan=StartupUi.Preferences.FormatAfterPasteEnabled && commandGroup==VSConstants.GUID_VSStandardCommandSet97 && commandId==(uint)VSConstants.VSStd97CmdID.Paste && view.Selection.SelectedSpans.Count==1
CodeAssist.Extension/CompletionCommandFilter.cs:162 var result = Next.Exec(ref commandGroup, commandId, commandOptions, input, output);
if(ErrorHandler.Succeeded(result) && pasteSpan!=null) FormatPastedLines(pasteSpan);
if (ErrorHandler.Succeeded(result) && copiedText != null) EditorClipboardHistory.History.Record(copiedText);
if (ErrorHandler.Succeeded(result) && (hasTypedCharacter || isDeletion))
{
RefreshCodeAssistSessions();
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
추천 색상·자체 아이콘·VS 기본색 복원; 원본 필터/UI 전체 미완료
internal SymbolKind Kind { get; }
internal ColoredCompletion(SymbolKind kind,string display,string insert,string description,ImageMoniker icon,string automation,IEnumerable<CompletionIcon2> attributes,string suffix)
: base(display,insert,description,icon,automation,attributes,suffix) { Kind=kind; }
}
[Export(typeof(IUIElementProvider<Completion,ICompletionSession>))]
[Name("CodeAssist Completion Colors")]
[ContentType("C/C++")]
CodeAssist.Extension/CodeAssistCompletionSource.cs:35
public ICompletionSource TryCreateCompletionSource(ITextBuffer textBuffer)
{
if (DocumentFactory.TryGetTextDocument(textBuffer, out var document))
{
IndexService.InitializeFromDocument(document.FilePath);
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
다중 줄 붙여넣기 후 VS 선택 서식 명령; 별도 Undo 가능
}
var pasteSpan=StartupUi.Preferences.FormatAfterPasteEnabled && commandGroup==VSConstants.GUID_VSStandardCommandSet97 && commandId==(uint)VSConstants.VSStd97CmdID.Paste && view.Selection.SelectedSpans.Count==1
?view.Selection.StreamSelectionSpan.SnapshotSpan.Snapshot.CreateTrackingSpan(view.Selection.StreamSelectionSpan.SnapshotSpan.Span,SpanTrackingMode.EdgeInclusive):null;
var isDeletion = IsDeletion(commandGroup, commandId);
var isExplicitCompletion = IsExplicitCompletion(commandGroup, commandId);
// Handle our explicit list before VC++ can expand the word on its own.
// Otherwise COMPLETEWORD edits the buffer, then our fallback opens a
CodeAssist.Extension/CompletionCommandFilter.cs:162 var result = Next.Exec(ref commandGroup, commandId, commandOptions, input, output);
if(ErrorHandler.Succeeded(result) && pasteSpan!=null) FormatPastedLines(pasteSpan);
if (ErrorHandler.Succeeded(result) && copiedText != null) EditorClipboardHistory.History.Record(copiedText);
if (ErrorHandler.Succeeded(result) && (hasTypedCharacter || isDeletion))
{
RefreshCodeAssistSessions();
}
CodeAssist.Extension/CompletionCommandFilter.cs:370 }
private void FormatPastedLines(ITrackingSpan inserted)
{
ThreadHelper.ThrowIfNotOnUIThread();
if(view.IsClosed)return;
var snapshot=view.TextSnapshot;var span=inserted.GetSpan(snapshot);
if(span.Length==0||span.GetText().IndexOf('\n')<0)return;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
괄호·따옴표·중괄호 위치·함수 괄호; 원본 비교 미완료
{
public enum ClosingBracePlacement { BlankLine, NextLine, SameLine }
public sealed class PairInsertion
{
public PairInsertion(string text,int caretOffset,int closingOffset){Text=text;CaretOffset=caretOffset;ClosingOffset=closingOffset;}
public string Text{get;} public int CaretOffset{get;} public int ClosingOffset{get;}
}
CodeAssist.Core/CppPairing.cs:6 public enum ClosingBracePlacement { BlankLine, NextLine, SameLine }
public sealed class PairInsertion
{
public PairInsertion(string text,int caretOffset,int closingOffset){Text=text;CaretOffset=caretOffset;ClosingOffset=closingOffset;}
public string Text{get;} public int CaretOffset{get;} public int ClosingOffset{get;}
}
public static class CppPairing
CodeAssist.Core/CppPairing.cs:8 {
public PairInsertion(string text,int caretOffset,int closingOffset){Text=text;CaretOffset=caretOffset;ClosingOffset=closingOffset;}
public string Text{get;} public int CaretOffset{get;} public int ClosingOffset{get;}
}
public static class CppPairing
{
public static bool Opening(char key)=>key=='('||key=='['||key=='{'||key=='\''||key=='"';
CodeAssist.Extension/CompletionCommandFilter.cs:60 private bool liveCompletionQueued;
private sealed class OwnedPair { internal ITrackingPoint Open,Close;internal char Opening,Closing; }
private readonly List<OwnedPair> pairs=new List<OwnedPair>();
private int tracedInputs;
public CompletionCommandFilter(IWpfTextView view, ICompletionBroker broker, ITextUndoHistoryRegistry undoHistories, IEditorOperations editorOperations, ProjectIndexService indexes=null)
{
CodeAssist.Extension/CompletionCommandFilter.cs:104 copiedText = view.Selection.SelectedSpans[0].GetText();
if(commandGroup==VSConstants.VSStd2K&&commandId==(uint)VSConstants.VSStd2KCmdID.TAB&&!broker.IsCompletionActive(view)&&SnippetInsertion.TryShortcut(view))return VSConstants.S_OK;
if (IsCommitCommand(commandGroup, commandId) && TryCommitCodeAssistSelection())
{
return VSConstants.S_OK;
}
CodeAssist.Extension/CompletionCommandFilter.cs:114 if (hasTypedCharacter && TrySurroundSelection(typedCharacter)) return VSConstants.S_OK;
if(hasTypedCharacter && TrySkipClosing(typedCharacter))return VSConstants.S_OK;
if(hasTypedCharacter && StartupUi.Preferences.PairCompletionEnabled && CppPairing.Opening(typedCharacter))
{
var selected=view.Selection.StreamSelectionSpan.SnapshotSpan;
var text=view.TextSnapshot.GetText();
if(text.Length<=2*1024*1024&&CppPairing.CanOpen(text.Remove(selected.Start,selected.Length),selected.Start,typedCharacter))
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
m 다음 짧은 Shift 입력으로 밑줄 추가; 옵션 기본 꺼짐; 실제 IDE 및 VA 비교 미검증
private readonly ProjectIndexService indexes;
private long shiftStarted;private int shiftCaret=-1;
private readonly IWpfTextView view;
private readonly ICompletionBroker broker;
private readonly ITextUndoHistoryRegistry undoHistories;
private readonly IEditorOperations editorOperations;
private readonly SynchronizationContext uiContext;
CodeAssist.Extension/CompletionCommandFilter.cs:104 copiedText = view.Selection.SelectedSpans[0].GetText();
if(commandGroup==VSConstants.VSStd2K&&commandId==(uint)VSConstants.VSStd2KCmdID.TAB&&!broker.IsCompletionActive(view)&&SnippetInsertion.TryShortcut(view))return VSConstants.S_OK;
if (IsCommitCommand(commandGroup, commandId) && TryCommitCodeAssistSelection())
{
return VSConstants.S_OK;
}
CodeAssist.Extension/CompletionCommandFilter.cs:217 {
if(e.Key!=System.Windows.Input.Key.LeftShift&&e.Key!=System.Windows.Input.Key.RightShift){shiftCaret=-1;return;}
if(!StartupUi.Preferences.InsertUnderscoreAfterM||!view.Selection.IsEmpty||view.IsClosed)return;
var caret=view.Caret.Position.BufferPosition;var line=caret.GetContainingLine();var before=line.GetText().Substring(0,caret.Position-line.Start.Position);
if(System.Text.RegularExpressions.Regex.IsMatch(before,@"(?:^|\W)m$")){shiftCaret=caret;shiftStarted=System.Diagnostics.Stopwatch.GetTimestamp();}
}
private void OnKeyUp(object sender,System.Windows.Input.KeyEventArgs e)
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
{
internal static readonly ClipboardHistory History = new ClipboardHistory();
}
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.TextManager.Interop; using Microsoft.VisualStudio.Text; using System; using System.Collections.Generic; using System.ComponentModel.Design;CodeAssist.Extension/NavigationCommands.cs:63
{
var view = components?.GetService<IVsEditorAdaptersFactoryService>()?.GetWpfTextView(adapter);
if (view != null && !view.IsClosed)
{
if (command == 0x011e)
{
var snapshot = view.TextSnapshot;
CodeAssist.Extension/NavigationCommands.cs:102 }
else if (command == 0x010f) view.ZoomLevel = 100;
else if (command == 0x011a) WordHighlights.For(view).Activate();
else if (command == 0x0117)
{
var snippetDte = await package.GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
if (snippetDte == null) return;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
축약어 추천 후보; IDE 필터 통과 미검증; 실제 IDE·VA 비교 미검증
candidates = MergeCandidates(
indexService.Index.Complete(prefix, 200,StartupUi.Preferences.AcronymCompletionEnabled,StartupUi.Preferences.ShorthandCompletionEnabled),
indexService.CompleteLive(prefix, 200, filePath).Where(item => !item.IsLocal ||
ResolveLocalVariableType(snapshot, item.Name, point.Value.Position) != null).ToArray());
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
var snapshot = view.TextSnapshot;
var selected = view.Selection.StreamSelectionSpan.SnapshotSpan;
if (selected.Length == 0) return;
var descending = new CheckBox { Content = "내림차순", Margin = new Thickness(10) };
var ignoreCase = new CheckBox { Content = "대소문자 무시", Margin = new Thickness(10) };
var sort = new Button { Content = "정렬", IsDefault = true, Margin = new Thickness(10) };
var panel = new StackPanel(); panel.Children.Add(descending); panel.Children.Add(ignoreCase); panel.Children.Add(sort);
CodeAssist.Extension/NavigationCommands.cs:70 var selected = view.Selection.StreamSelectionSpan.SnapshotSpan;
if (selected.Length == 0) return;
var descending = new CheckBox { Content = "내림차순", Margin = new Thickness(10) };
var ignoreCase = new CheckBox { Content = "대소문자 무시", Margin = new Thickness(10) };
var sort = new Button { Content = "정렬", IsDefault = true, Margin = new Thickness(10) };
var panel = new StackPanel(); panel.Children.Add(descending); panel.Children.Add(ignoreCase); panel.Children.Add(sort);
var dialog = new Window { Title = "CodeAssist: Sort Selected Lines", Content = panel, Width = 350, Height = 220, WindowStartupLocation = WindowStartupLocation.CenterOwner };
CodeAssist.Extension/NavigationCommands.cs:75 var panel = new StackPanel(); panel.Children.Add(descending); panel.Children.Add(ignoreCase); panel.Children.Add(sort);
var dialog = new Window { Title = "CodeAssist: Sort Selected Lines", Content = panel, Width = 350, Height = 220, WindowStartupLocation = WindowStartupLocation.CenterOwner };
var sortDte = await package.GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
if (sortDte != null) new System.Windows.Interop.WindowInteropHelper(dialog).Owner = (IntPtr)sortDte.MainWindow.HWnd;
sort.Click += (s, e) => dialog.DialogResult = true;
dialog.PreviewKeyDown += (s, e) => { if (e.Key == Key.Escape) dialog.DialogResult = false; };
if (dialog.ShowDialog() != true || view.IsClosed || !ReferenceEquals(snapshot, view.TextSnapshot)) return;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
bool·포인터 선언의 예상 타입 리터럴 추천; 전체 문맥 추천 아님; VA 동등성 미검증
if(!StartupUi.Preferences.SuggestionListsEnabled)return;
var snippetItems=StartupUi.Preferences.SnippetSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success?SnippetInsertion.Suggestions(indexService.ProjectRoot,prefix).Select(t=>(Completion)new SnippetCompletion(t)).ToList():new List<Completion>();
if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
!string.Equals(set.Moniker, "CodeAssistPreview", StringComparison.Ordinal) &&
CodeAssist.Extension/CodeAssistCompletionSource.cs:144 var snippetItems=StartupUi.Preferences.SnippetSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success?SnippetInsertion.Suggestions(indexService.ProjectRoot,prefix).Select(t=>(Completion)new SnippetCompletion(t)).ToList():new List<Completion>();
if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
!string.Equals(set.Moniker, "CodeAssistPreview", StringComparison.Ordinal) &&
set.Completions != null && set.Completions.Count > 0);
CodeAssist.Extension/CodeAssistCompletionSource.cs:145 if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
!string.Equals(set.Moniker, "CodeAssistPreview", StringComparison.Ordinal) &&
set.Completions != null && set.Completions.Count > 0);
var start = point.Value.Position - prefix.Length;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
var ignoreCase = new CheckBox { Content = "대소문자 무시", Margin = new Thickness(10) };
var sort = new Button { Content = "정렬", IsDefault = true, Margin = new Thickness(10) };
var panel = new StackPanel(); panel.Children.Add(descending); panel.Children.Add(ignoreCase); panel.Children.Add(sort);
var dialog = new Window { Title = "CodeAssist: Sort Selected Lines", Content = panel, Width = 350, Height = 220, WindowStartupLocation = WindowStartupLocation.CenterOwner };
var sortDte = await package.GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
if (sortDte != null) new System.Windows.Interop.WindowInteropHelper(dialog).Owner = (IntPtr)sortDte.MainWindow.HWnd;
sort.Click += (s, e) => dialog.DialogResult = true;
CodeAssist.Extension/NavigationCommands.cs:74 var sort = new Button { Content = "정렬", IsDefault = true, Margin = new Thickness(10) };
var panel = new StackPanel(); panel.Children.Add(descending); panel.Children.Add(ignoreCase); panel.Children.Add(sort);
var dialog = new Window { Title = "CodeAssist: Sort Selected Lines", Content = panel, Width = 350, Height = 220, WindowStartupLocation = WindowStartupLocation.CenterOwner };
var sortDte = await package.GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
if (sortDte != null) new System.Windows.Interop.WindowInteropHelper(dialog).Owner = (IntPtr)sortDte.MainWindow.HWnd;
sort.Click += (s, e) => dialog.DialogResult = true;
dialog.PreviewKeyDown += (s, e) => { if (e.Key == Key.Escape) dialog.DialogResult = false; };
CodeAssist.Extension/NavigationCommands.cs:75 var panel = new StackPanel(); panel.Children.Add(descending); panel.Children.Add(ignoreCase); panel.Children.Add(sort);
var dialog = new Window { Title = "CodeAssist: Sort Selected Lines", Content = panel, Width = 350, Height = 220, WindowStartupLocation = WindowStartupLocation.CenterOwner };
var sortDte = await package.GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
if (sortDte != null) new System.Windows.Interop.WindowInteropHelper(dialog).Owner = (IntPtr)sortDte.MainWindow.HWnd;
sort.Click += (s, e) => dialog.DialogResult = true;
dialog.PreviewKeyDown += (s, e) => { if (e.Key == Key.Escape) dialog.DialogResult = false; };
if (dialog.ShowDialog() != true || view.IsClosed || !ReferenceEquals(snapshot, view.TextSnapshot)) return;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
추천 목록 사용 토글 및 C++·스니펫·컴파일러 후보 연결; VA 동등성 미검증
if(!StartupUi.Preferences.SuggestionListsEnabled)return;
var snippetItems=StartupUi.Preferences.SnippetSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success?SnippetInsertion.Suggestions(indexService.ProjectRoot,prefix).Select(t=>(Completion)new SnippetCompletion(t)).ToList():new List<Completion>();
if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
CodeAssist.Extension/CodeAssistCompletionSource.cs:143 if(!StartupUi.Preferences.SuggestionListsEnabled)return;
var snippetItems=StartupUi.Preferences.SnippetSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success?SnippetInsertion.Suggestions(indexService.ProjectRoot,prefix).Select(t=>(Completion)new SnippetCompletion(t)).ToList():new List<Completion>();
if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
!string.Equals(set.Moniker, "CodeAssistPreview", StringComparison.Ordinal) &&
CodeAssist.Extension/CodeAssistCompletionSource.cs:144 var snippetItems=StartupUi.Preferences.SnippetSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success?SnippetInsertion.Suggestions(indexService.ProjectRoot,prefix).Select(t=>(Completion)new SnippetCompletion(t)).ToList():new List<Completion>();
if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
!string.Equals(set.Moniker, "CodeAssistPreview", StringComparison.Ordinal) &&
set.Completions != null && set.Completions.Count > 0);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
/, *, (, { 감싸기; #·Snippet 문자 토글 미완료
{
public EditorTextChange(int start,int length,string text,int selectionStart,int selectionLength)
{Start=start;Length=length;Text=text;SelectionStart=selectionStart;SelectionLength=selectionLength;}
public int Start{get;} public int Length{get;} public string Text{get;}
public int SelectionStart{get;} public int SelectionLength{get;}
}
public static class CppEditing
CodeAssist.Core/CppEditing.cs:9 public EditorTextChange(int start,int length,string text,int selectionStart,int selectionLength)
{Start=start;Length=length;Text=text;SelectionStart=selectionStart;SelectionLength=selectionLength;}
public int Start{get;} public int Length{get;} public string Text{get;}
public int SelectionStart{get;} public int SelectionLength{get;}
}
public static class CppEditing
{
CodeAssist.Core/CppEditing.cs:11 public int Start{get;} public int Length{get;} public string Text{get;}
public int SelectionStart{get;} public int SelectionLength{get;}
}
public static class CppEditing
{
public static EditorTextChange Surround(string text,int start,int length,char key,bool spaceAfterSlash)
{
CodeAssist.Extension/CompletionCommandFilter.cs:102 (commandId == (uint)VSConstants.VSStd97CmdID.Copy || commandId == (uint)VSConstants.VSStd97CmdID.Cut) &&
!view.Selection.IsEmpty && view.Selection.SelectedSpans.Count == 1 && view.Selection.SelectedSpans[0].Length <= 1024 * 1024)
copiedText = view.Selection.SelectedSpans[0].GetText();
if(commandGroup==VSConstants.VSStd2K&&commandId==(uint)VSConstants.VSStd2KCmdID.TAB&&!broker.IsCompletionActive(view)&&SnippetInsertion.TryShortcut(view))return VSConstants.S_OK;
if (IsCommitCommand(commandGroup, commandId) && TryCommitCodeAssistSelection())
{
return VSConstants.S_OK;
CodeAssist.Extension/CompletionCommandFilter.cs:103 !view.Selection.IsEmpty && view.Selection.SelectedSpans.Count == 1 && view.Selection.SelectedSpans[0].Length <= 1024 * 1024)
copiedText = view.Selection.SelectedSpans[0].GetText();
if(commandGroup==VSConstants.VSStd2K&&commandId==(uint)VSConstants.VSStd2KCmdID.TAB&&!broker.IsCompletionActive(view)&&SnippetInsertion.TryShortcut(view))return VSConstants.S_OK;
if (IsCommitCommand(commandGroup, commandId) && TryCommitCodeAssistSelection())
{
return VSConstants.S_OK;
}
CodeAssist.Extension/CompletionCommandFilter.cs:105 if(commandGroup==VSConstants.VSStd2K&&commandId==(uint)VSConstants.VSStd2KCmdID.TAB&&!broker.IsCompletionActive(view)&&SnippetInsertion.TryShortcut(view))return VSConstants.S_OK;
if (IsCommitCommand(commandGroup, commandId) && TryCommitCodeAssistSelection())
{
return VSConstants.S_OK;
}
var hasTypedCharacter = TryGetTypedCharacter(commandGroup, commandId, input, out var typedCharacter);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 영역 스니펫 감싸기; 실제 IDE·VA 비교 미검증
}
internal static void Show(IWpfTextView view, string file, string projectRoot, IntPtr owner, string projectFile = null, string solutionFile = null, bool surroundOnly = false, string shortcut = null, SnapshotSpan? replacement = null)
{
ThreadHelper.ThrowIfNotOnUIThread();
var snapshot = view.TextSnapshot;
var selection = replacement ?? view.Selection.StreamSelectionSpan.SnapshotSpan;
var templates = new List<SnippetTemplate>(BuiltIns);
CodeAssist.Extension/SnippetInsertion.cs:82 if(shortcut!=null)templates=templates.Where(t=>string.Equals(t.Shortcut,shortcut,StringComparison.Ordinal)).ToList();
if(surroundOnly)templates=templates.Where(t=>t.Variables().Contains("selected")).ToList();
if(templates.Count==0)return;
CaptureEnvironment();
templates = templates.Select(template => template.WithEnvironment(name => environment.TryGetValue(name, out var value) ? value : "")).ToList();
var reserved = SnippetReservedValues.Create(file, shortcut==null?selection.GetText():"", DateTime.Now, System.Globalization.CultureInfo.CurrentCulture);
SnippetReservedValues.AddWorkspace(reserved, projectFile, solutionFile, Guid.NewGuid(), System.Globalization.CultureInfo.CurrentCulture);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
설정 가능한 컬럼 기준선; 실제 IDE·VA 비교 미검증
[Export(typeof(IWpfTextViewCreationListener))][ContentType("C/C++")][TextViewRole(PredefinedTextViewRoles.Document)]
internal sealed class ColumnGuideProvider:IWpfTextViewCreationListener
{
[Export(typeof(AdornmentLayerDefinition))][Name("CodeAssist Column Guide")][Order(After=PredefinedAdornmentLayers.Selection,Before=PredefinedAdornmentLayers.Text)]
internal AdornmentLayerDefinition Layer=null;
public void TextViewCreated(IWpfTextView view)=>view.Properties.GetOrCreateSingletonProperty(()=>new ColumnGuide(view));
}
CodeAssist.Extension/EditorGuides.cs:48 {
[Export(typeof(AdornmentLayerDefinition))][Name("CodeAssist Column Guide")][Order(After=PredefinedAdornmentLayers.Selection,Before=PredefinedAdornmentLayers.Text)]
internal AdornmentLayerDefinition Layer=null;
public void TextViewCreated(IWpfTextView view)=>view.Properties.GetOrCreateSingletonProperty(()=>new ColumnGuide(view));
}
internal sealed class ColumnGuide
{
CodeAssist.Extension/EditorGuides.cs:50 internal AdornmentLayerDefinition Layer=null;
public void TextViewCreated(IWpfTextView view)=>view.Properties.GetOrCreateSingletonProperty(()=>new ColumnGuide(view));
}
internal sealed class ColumnGuide
{
private readonly IWpfTextView view;private readonly IAdornmentLayer layer;
internal ColumnGuide(IWpfTextView view){this.view=view;layer=view.GetAdornmentLayer("CodeAssist Column Guide");view.LayoutChanged+=Layout;view.Closed+=Closed;StartupUi.SettingsApplied+=Update;Update();}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
지연 갱신 소유 타입 문맥 필드; 전체 VA 문맥 UI와 다름; 실제 IDE 및 VA 비교 미검증
[Export(typeof(IWpfTextViewMarginProvider))]
[Name("CodeAssist Context Bar")]
[MarginContainer(PredefinedMarginNames.Top)]
[ContentType("C/C++")]
[TextViewRole(PredefinedTextViewRoles.Document)]
internal sealed class ContextBarProvider : IWpfTextViewMarginProvider
{
CodeAssist.Extension/ContextBar.cs:21 [TextViewRole(PredefinedTextViewRoles.Document)]
internal sealed class ContextBarProvider : IWpfTextViewMarginProvider
{
[Import] internal ITextDocumentFactoryService Documents=null;
[Import] internal ProjectIndexService Indexes=null;
public IWpfTextViewMargin CreateMargin(IWpfTextViewHost host,IWpfTextViewMargin parent)
{
CodeAssist.Extension/ContextBar.cs:28 Documents.TryGetTextDocument(host.TextView.TextDataModel.DocumentBuffer,out var document);
return new ContextBarMargin(host.TextView,document?.FilePath,Indexes);
}
}
internal sealed class ContextBarMargin : IWpfTextViewMargin
{
private const string Name="CodeAssist Context Bar";
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
커서 단어의 인덱스 서명 표시; 오버로드 의미 선택 미구현; 실제 IDE 및 VA 비교 미검증
private readonly string filePath;
private ITextSnapshot definitionSnapshot;
private System.Collections.Generic.IReadOnlyList<IndexedSymbol> documentSymbols;
private readonly DockPanel panel=new DockPanel { Height=28,LastChildFill=true };
private readonly ComboBox methods=CreateMethodSelector();
internal static ComboBox CreateMethodSelector()
{
CodeAssist.Extension/ContextBar.cs:49 private readonly ProjectIndexService indexes;
private readonly TextBlock contextField=new TextBlock {Margin=new Thickness(8,0,12,0),TextTrimming=TextTrimming.CharacterEllipsis};
private readonly TextBlock definitionField=new TextBlock {Margin=new Thickness(8,0,0,0),TextTrimming=TextTrimming.CharacterEllipsis};
private readonly System.Windows.Threading.DispatcherTimer refresh=new System.Windows.Threading.DispatcherTimer {Interval=TimeSpan.FromMilliseconds(180)};
private bool disposed;
private ITextSnapshot methodSnapshot;
internal ContextBarMargin(IWpfTextView view,string path,ProjectIndexService indexes=null)
CodeAssist.Extension/ContextBar.cs:50 private readonly TextBlock contextField=new TextBlock {Margin=new Thickness(8,0,12,0),TextTrimming=TextTrimming.CharacterEllipsis};
private readonly TextBlock definitionField=new TextBlock {Margin=new Thickness(8,0,0,0),TextTrimming=TextTrimming.CharacterEllipsis};
private readonly System.Windows.Threading.DispatcherTimer refresh=new System.Windows.Threading.DispatcherTimer {Interval=TimeSpan.FromMilliseconds(180)};
private bool disposed;
private ITextSnapshot methodSnapshot;
internal ContextBarMargin(IWpfTextView view,string path,ProjectIndexService indexes=null)
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
분류기 구현과 현재 화면의 색상은 확인했습니다. 범용 문법·테마·기본색 전수 동등성은 미검증입니다.
{
internal static class CppSemanticClassification
{
public const string TypeName = "CodeAssist C++ Type";
public const string VariableName = "CodeAssist C++ Variable";
public const string FunctionName = "CodeAssist C++ Function";
CodeAssist.Extension/CppSemanticClassifier.cs:36 [Order(After = Priority.High)]
internal sealed class TypeFormat : ClassificationFormatDefinition
{
public TypeFormat()
{
DisplayName = "CodeAssist C++ Type";
ForegroundColor = Color.FromRgb(255, 215, 0);
CodeAssist.Extension/CppSemanticClassifier.cs:50 [Order(After = Priority.High)]
internal sealed class VariableFormat : ClassificationFormatDefinition
{
public VariableFormat()
{
DisplayName = "CodeAssist C++ Variable";
ForegroundColor = Color.FromRgb(189, 183, 107);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
렉시컬 지역 변수 식별자를 굵게 표시; 실제 IDE 및 VA 비교 미검증
private readonly IClassificationType functionClassification;
private readonly IClassificationTypeRegistryService registry;private readonly ProjectIndexService indexes;private CppReferenceContext localContext;
private ITextSnapshot cachedSnapshot;
private IReadOnlyList<SemanticToken> cachedTokens = Array.Empty<SemanticToken>();
public CppSemanticClassifier(ITextBuffer textBuffer, IClassificationType typeClassification, IClassificationType variableClassification, IClassificationType functionClassification,IClassificationTypeRegistryService registry=null,ProjectIndexService indexes=null)
{
CodeAssist.Extension/CppSemanticClassifier.cs:143 : variableClassification;
if(StartupUi.Preferences.LocalSymbolsBold&&token.Kind==SemanticTokenKind.Variable&&localContext?.DeclarationAt(token.Name,token.Start)!=null)classification=registry?.GetClassificationType("CodeAssist Local Bold")??classification;
else if(StartupUi.Preferences.SystemSymbolsItalic&&indexes!=null&®istry!=null)
{
var definitions=indexes.Index.FindDefinitions(token.Name);
if(definitions.Count>0&&definitions.All(item=>SystemPath(item.FilePath)))classification=registry.GetClassificationType(token.Kind==SemanticTokenKind.Type?"CodeAssist System Type":token.Kind==SemanticTokenKind.Function?"CodeAssist System Function":"CodeAssist System Variable")??classification;
}
CodeAssist.Extension/CppSemanticClassifier.cs:164 cachedTokens = CppSemanticParser.Parse(text);
localContext=StartupUi.Preferences.LocalSymbolsBold&&snapshot.Length<=512*1024?new CppReferenceContext(text):null;
cachedSnapshot = snapshot;
}
private static bool SystemPath(string path)=>!string.IsNullOrEmpty(path)&&(path.IndexOf(@"\Program Files",StringComparison.OrdinalIgnoreCase)>=0||path.IndexOf("/usr/include/",StringComparison.Ordinal)>=0||path.IndexOf(@"\Engine\Source\",StringComparison.OrdinalIgnoreCase)>=0);
private void OnBufferChanged(object sender, TextContentChangedEventArgs e)
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
검색 결과 버퍼에서 VS FindWhat 리터럴 강조; 정규식 검색·정확한 콘텐츠 타입 동작 미검증; VA 동등성 미검증
{
internal static class ResultStyles
{
[Export(typeof(ClassificationTypeDefinition))][Name("CodeAssist Output File")]internal static ClassificationTypeDefinition File=null;
[Export(typeof(ClassificationTypeDefinition))][Name("CodeAssist Find Match")]internal static ClassificationTypeDefinition Match=null;
[Export(typeof(EditorFormatDefinition))][ClassificationType(ClassificationTypeNames="CodeAssist Output File")][Name("CodeAssist Output File")][UserVisible(true)]
internal sealed class FileFormat:ClassificationFormatDefinition {public FileFormat(){DisplayName="CodeAssist Output File";ForegroundColor=Color.FromRgb(80,170,255);}}
CodeAssist.Extension/ResultHighlighting.cs:16 [Export(typeof(ClassificationTypeDefinition))][Name("CodeAssist Output File")]internal static ClassificationTypeDefinition File=null;
[Export(typeof(ClassificationTypeDefinition))][Name("CodeAssist Find Match")]internal static ClassificationTypeDefinition Match=null;
[Export(typeof(EditorFormatDefinition))][ClassificationType(ClassificationTypeNames="CodeAssist Output File")][Name("CodeAssist Output File")][UserVisible(true)]
internal sealed class FileFormat:ClassificationFormatDefinition {public FileFormat(){DisplayName="CodeAssist Output File";ForegroundColor=Color.FromRgb(80,170,255);}}
[Export(typeof(EditorFormatDefinition))][ClassificationType(ClassificationTypeNames="CodeAssist Find Match")][Name("CodeAssist Find Match")][UserVisible(true)]
internal sealed class MatchFormat:ClassificationFormatDefinition {public MatchFormat(){DisplayName="CodeAssist Find Match";BackgroundColor=Color.FromRgb(105,85,30);}}
}
CodeAssist.Extension/ResultHighlighting.cs:19 internal sealed class FileFormat:ClassificationFormatDefinition {public FileFormat(){DisplayName="CodeAssist Output File";ForegroundColor=Color.FromRgb(80,170,255);}}
[Export(typeof(EditorFormatDefinition))][ClassificationType(ClassificationTypeNames="CodeAssist Find Match")][Name("CodeAssist Find Match")][UserVisible(true)]
internal sealed class MatchFormat:ClassificationFormatDefinition {public MatchFormat(){DisplayName="CodeAssist Find Match";BackgroundColor=Color.FromRgb(105,85,30);}}
}
[Export(typeof(IClassifierProvider))][ContentType("text")]
internal sealed class ResultHighlightProvider:IClassifierProvider
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
[Export(typeof(EditorFormatDefinition))]
[Name(WordHighlights.Marker)]
[UserVisible(true)]
internal sealed class WordHighlightFormat : MarkerFormatDefinition
{
public WordHighlightFormat() { DisplayName = "CodeAssist Find Selected"; BackgroundColor = Color.FromRgb(95, 85, 35); }
}
CodeAssist.Extension/WordHighlights.cs:19 [UserVisible(true)]
internal sealed class WordHighlightFormat : MarkerFormatDefinition
{
public WordHighlightFormat() { DisplayName = "CodeAssist Find Selected"; BackgroundColor = Color.FromRgb(95, 85, 35); }
}
[Export(typeof(IViewTaggerProvider))]
[ContentType("C/C++")]
CodeAssist.Extension/WordHighlights.cs:21 {
public WordHighlightFormat() { DisplayName = "CodeAssist Find Selected"; BackgroundColor = Color.FromRgb(95, 85, 35); }
}
[Export(typeof(IViewTaggerProvider))]
[ContentType("C/C++")]
[TagType(typeof(TextMarkerTag))]
internal sealed class WordHighlightProvider : IViewTaggerProvider
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
지연·단일 작업·캐시를 적용한 커서 심볼 렉시컬 참조 강조; 컴파일러 동등성 미검증; 실제 IDE 및 VA 비교 미검증
[Export(typeof(IViewTaggerProvider))][ContentType("C/C++")][TagType(typeof(TextMarkerTag))]
internal sealed class ReferenceHighlightProvider:IViewTaggerProvider
{
public ITagger<T> CreateTagger<T>(ITextView view,ITextBuffer buffer) where T:ITag=>view.TextBuffer==buffer?view.Properties.GetOrCreateSingletonProperty(()=>new ReferenceHighlighting(view)) as ITagger<T>:null;
}
internal sealed class ReferenceHighlighting:ITagger<TextMarkerTag>
{
CodeAssist.Extension/ReferenceHighlighting.cs:19 {
public ITagger<T> CreateTagger<T>(ITextView view,ITextBuffer buffer) where T:ITag=>view.TextBuffer==buffer?view.Properties.GetOrCreateSingletonProperty(()=>new ReferenceHighlighting(view)) as ITagger<T>:null;
}
internal sealed class ReferenceHighlighting:ITagger<TextMarkerTag>
{
private readonly ITextView view;private readonly DispatcherTimer timer=new DispatcherTimer {Interval=TimeSpan.FromMilliseconds(220)};
private ITextSnapshot parsed,published;private CppReferenceContext context;private int[] offsets=Array.Empty<int>();private int length;private bool closed,running;
CodeAssist.Extension/ReferenceHighlighting.cs:21 }
internal sealed class ReferenceHighlighting:ITagger<TextMarkerTag>
{
private readonly ITextView view;private readonly DispatcherTimer timer=new DispatcherTimer {Interval=TimeSpan.FromMilliseconds(220)};
private ITextSnapshot parsed,published;private CppReferenceContext context;private int[] offsets=Array.Empty<int>();private int length;private bool closed,running;
internal ReferenceHighlighting(ITextView view){this.view=view;view.Caret.PositionChanged+=Caret;view.TextBuffer.Changed+=Changed;view.Closed+=Closed;timer.Tick+=Tick;StartupUi.SettingsApplied+=Schedule;if(view is IWpfTextView wpf)wpf.VisualElement.PreviewMouseLeftButtonUp+=Mouse;Schedule();}
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
컴파일러 signatureHelp 결과 및 현재 인수 번호 표시; 타이핑 자동 팝업 없음; 실제 IDE 및 VA 비교 미검증
var picker=new Microsoft.Win32.OpenFileDialog {Title="CodeAssist: Preview File",Filter="C/C++ files|*.h;*.hpp;*.cpp;*.c;*.cc;*.inl|All files|*.*"};if(picker.ShowDialog()!=true)return;
if(new FileInfo(picker.FileName).Length>2*1024*1024)throw new InvalidOperationException("Preview is limited to 2 MiB.");var text=await System.Threading.Tasks.Task.Run(()=>File.ReadAllText(picker.FileName));await ShowAsync(package,Path.GetFileName(picker.FileName),new FlowDocumentScrollViewer {Document=ColoredDocument(text),IsToolBarVisible=true});return;
}
if(id==0x194)
{
var document=dte.ActiveDocument?.Object("TextDocument") as EnvDTE.TextDocument;if(document==null)return;var text=document.StartPoint.CreateEditPoint().GetText(document.EndPoint);
if(text.Length>2*1024*1024)throw new InvalidOperationException("Color printing is limited to 2 MiB.");var dialog=new PrintDialog();if(dialog.ShowDialog()==true){var documentToPrint=ColoredDocument(text);documentToPrint.PageWidth=dialog.PrintableAreaWidth;documentToPrint.ColumnWidth=dialog.PrintableAreaWidth;dialog.PrintDocument(((IDocumentPaginatorSource)documentToPrint).DocumentPaginator,"CodeAssist: "+dte.ActiveDocument.Name);}return;
CodeAssist.Extension/UtilityCommands.cs:71 if(!(help?["signatures"] is JArray signatures)||signatures.Count==0)throw new InvalidOperationException("No compiler signature is available at the caret. Configure a compilation database and place the caret in an argument list.");
var lines=new StringBuilder("Active parameter: "+((int?)help["activeParameter"]+1)+Environment.NewLine);
foreach(var signature in signatures)lines.AppendLine((string)signature["label"]).AppendLine((string)(signature["documentation"] is JObject documentation?documentation["value"]:signature["documentation"]));
await ShowAsync(package,"Parameter Info",new TextBox {Text=lines.ToString(),IsReadOnly=true,AcceptsReturn=true,FontFamily=new FontFamily("Consolas"),VerticalScrollBarVisibility=ScrollBarVisibility.Auto});
}
}
internal static FlowDocument ColoredDocument(string text)
CodeAssist.Extension/UtilityCommands.cs:73 foreach(var signature in signatures)lines.AppendLine((string)signature["label"]).AppendLine((string)(signature["documentation"] is JObject documentation?documentation["value"]:signature["documentation"]));
await ShowAsync(package,"Parameter Info",new TextBox {Text=lines.ToString(),IsReadOnly=true,AcceptsReturn=true,FontFamily=new FontFamily("Consolas"),VerticalScrollBarVisibility=ScrollBarVisibility.Auto});
}
}
internal static FlowDocument ColoredDocument(string text)
{
var document=new FlowDocument {FontFamily=new FontFamily("Consolas"),FontSize=12,PagePadding=new Thickness(24),Background=Brushes.White,Foreground=Brushes.Black};var paragraph=new Paragraph {Margin=new Thickness(0)};document.Blocks.Add(paragraph);var cursor=0;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
CodeAssist 분류색을 이용한 사용자 확인 후 컬러 인쇄; 주석·문자열 전체 VS 색상 재현 아님; 실제 IDE 및 VA 비교 미검증
var picker=new Microsoft.Win32.OpenFileDialog {Title="CodeAssist: Preview File",Filter="C/C++ files|*.h;*.hpp;*.cpp;*.c;*.cc;*.inl|All files|*.*"};if(picker.ShowDialog()!=true)return;
if(new FileInfo(picker.FileName).Length>2*1024*1024)throw new InvalidOperationException("Preview is limited to 2 MiB.");var text=await System.Threading.Tasks.Task.Run(()=>File.ReadAllText(picker.FileName));await ShowAsync(package,Path.GetFileName(picker.FileName),new FlowDocumentScrollViewer {Document=ColoredDocument(text),IsToolBarVisible=true});return;
}
if(id==0x194)
{
var document=dte.ActiveDocument?.Object("TextDocument") as EnvDTE.TextDocument;if(document==null)return;var text=document.StartPoint.CreateEditPoint().GetText(document.EndPoint);
if(text.Length>2*1024*1024)throw new InvalidOperationException("Color printing is limited to 2 MiB.");var dialog=new PrintDialog();if(dialog.ShowDialog()==true){var documentToPrint=ColoredDocument(text);documentToPrint.PageWidth=dialog.PrintableAreaWidth;documentToPrint.ColumnWidth=dialog.PrintableAreaWidth;dialog.PrintDocument(((IDocumentPaginatorSource)documentToPrint).DocumentPaginator,"CodeAssist: "+dte.ActiveDocument.Name);}return;
CodeAssist.Extension/UtilityCommands.cs:60 var document=dte.ActiveDocument?.Object("TextDocument") as EnvDTE.TextDocument;if(document==null)return;var text=document.StartPoint.CreateEditPoint().GetText(document.EndPoint);
if(text.Length>2*1024*1024)throw new InvalidOperationException("Color printing is limited to 2 MiB.");var dialog=new PrintDialog();if(dialog.ShowDialog()==true){var documentToPrint=ColoredDocument(text);documentToPrint.PageWidth=dialog.PrintableAreaWidth;documentToPrint.ColumnWidth=dialog.PrintableAreaWidth;dialog.PrintDocument(((IDocumentPaginatorSource)documentToPrint).DocumentPaginator,"CodeAssist: "+dte.ActiveDocument.Name);}return;
}
if(id==0x195)
{
var document=dte.ActiveDocument;var selection=document?.Selection as EnvDTE.TextSelection;var textDocument=document?.Object("TextDocument") as EnvDTE.TextDocument;if(selection==null||textDocument==null)return;
var root=Path.GetDirectoryName(document.FullName);while(root!=null&&!File.Exists(Path.Combine(root,"compile_commands.json"))&&!File.Exists(Path.Combine(root,"compile_flags.txt")))root=Path.GetDirectoryName(root);
CodeAssist.Extension/UtilityCommands.cs:76 }
internal static FlowDocument ColoredDocument(string text)
{
var document=new FlowDocument {FontFamily=new FontFamily("Consolas"),FontSize=12,PagePadding=new Thickness(24),Background=Brushes.White,Foreground=Brushes.Black};var paragraph=new Paragraph {Margin=new Thickness(0)};document.Blocks.Add(paragraph);var cursor=0;
foreach(var token in CppSemanticParser.Parse(text).OrderBy(t=>t.Start))
{if(token.Start<cursor)continue;if(token.Start>cursor)paragraph.Inlines.Add(new Run(text.Substring(cursor,token.Start-cursor)));var color=token.Kind==SemanticTokenKind.Type?StartupUi.Preferences.TypeColor:token.Kind==SemanticTokenKind.Function?StartupUi.Preferences.FunctionColor:StartupUi.Preferences.VariableColor;paragraph.Inlines.Add(new Run(text.Substring(token.Start,token.Length)){Foreground=(Brush)new BrushConverter().ConvertFromString(color)});cursor=token.Start+token.Length;}
if(cursor<text.Length)paragraph.Inlines.Add(new Run(text.Substring(cursor)));return document;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
인덱스 후보 툴팁; 컴파일러 문맥 선택 미완료
{
[Export(typeof(IAsyncQuickInfoSourceProvider))]
[Name("CodeAssist Symbol Quick Info")]
[ContentType("C/C++")]
[Order(After=Priority.Default)]
internal sealed class SymbolQuickInfoProvider : IAsyncQuickInfoSourceProvider
{
CodeAssist.Extension/SymbolQuickInfo.cs:15 [Export(typeof(IAsyncQuickInfoSourceProvider))]
[Name("CodeAssist Symbol Quick Info")]
[ContentType("C/C++")]
[Order(After=Priority.Default)]
internal sealed class SymbolQuickInfoProvider : IAsyncQuickInfoSourceProvider
{
[Import] internal ProjectIndexService Indexes=null;
CodeAssist.Extension/SymbolQuickInfo.cs:18 [Order(After=Priority.Default)]
internal sealed class SymbolQuickInfoProvider : IAsyncQuickInfoSourceProvider
{
[Import] internal ProjectIndexService Indexes=null;
public IAsyncQuickInfoSource TryCreateQuickInfoSource(ITextBuffer buffer) => new SymbolQuickInfoSource(buffer,Indexes);
}
internal sealed class SymbolQuickInfoSource : IAsyncQuickInfoSource
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
외부 SDK·엔진 경로 심볼 기울임; SDK 경로 휴리스틱; 실제 IDE 및 VA 비교 미검증
using System.Linq; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Utilities; using System; using System.Collections.Generic;CodeAssist.Extension/CppSemanticClassifier.cs:5
using Microsoft.VisualStudio.Utilities; using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Windows.Media; using CodeAssist.Core;CodeAssist.Extension/CppSemanticClassifier.cs:6
using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Windows.Media; using CodeAssist.Core; namespace CodeAssist.Extension
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
확정 포인터 타입에서 점 입력을 화살표로 변환; 오버로드 operator-> 제외; 실제 IDE 및 VA 비교 미검증
var text=snapshot.GetText();var caret=view.Caret.Position.BufferPosition.Position;var word=CppAutomaticEdits.WordBefore(text,caret);
if(key=='.'&&preferences.ConvertDotToArrow&&word.Length>0)
{var type=new CppReferenceContext(text).ResolveVariableType(word,caret)??indexes?.Index.ResolveVariableType(word);return ApplyAutomatic(CppAutomaticEdits.DotToArrow(text,caret,type),"CodeAssist Dot to Arrow");}
if(preferences.RepairTypeCase&&word.Length>0&&new CppReferenceContext(text).ResolveVariableType(word,caret)==null)ApplyAutomatic(CppAutomaticEdits.RepairCase(text,caret,indexes?.Index.FindCorrectTypeCasing(word)),"CodeAssist Repair Type Case");
return false;
}
private void OnKeyDown(object sender,System.Windows.Input.KeyEventArgs e)
CodeAssist.Extension/CompletionCommandFilter.cs:287 var caret=view.Caret.Position.BufferPosition.Position;var snapshot=view.TextSnapshot;
var indent=(!view.Options.GetOptionValue(DefaultOptions.ConvertTabsToSpacesOptionId))?"\t":new string(' ',Math.Max(1,Math.Min(16,view.Options.GetOptionValue(DefaultOptions.IndentSizeOptionId))));
var contents=snapshot.GetText();
var freshNativePair=CppPairing.IsFreshPair(before.GetText(),selected.Start,selected.Length,contents,caret,key);
var planned=CppPairing.AfterOpening(freshNativePair?contents.Remove(caret,1):contents,caret,key,StartupUi.Preferences.ClosingBracePlacement,indent);
if(EditorInputTrace.Enabled)WelcomeDocumentWindow.RecordEvent("PairInsertion owned="+(planned!=null)+" freshNative="+freshNativePair+" caret="+caret);
if(planned!=null)
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
출력·검색 버퍼의 C/C++ 파일 경로 분류색; 클릭 탐색은 VS 제공; VA 동등성 미검증
using System.Text.RegularExpressions; using System.Windows.Media; using CodeAssist.Core; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Utilities;CodeAssist.Extension/ResultHighlighting.cs:15
{
[Export(typeof(ClassificationTypeDefinition))][Name("CodeAssist Output File")]internal static ClassificationTypeDefinition File=null;
[Export(typeof(ClassificationTypeDefinition))][Name("CodeAssist Find Match")]internal static ClassificationTypeDefinition Match=null;
[Export(typeof(EditorFormatDefinition))][ClassificationType(ClassificationTypeNames="CodeAssist Output File")][Name("CodeAssist Output File")][UserVisible(true)]
internal sealed class FileFormat:ClassificationFormatDefinition {public FileFormat(){DisplayName="CodeAssist Output File";ForegroundColor=Color.FromRgb(80,170,255);}}
[Export(typeof(EditorFormatDefinition))][ClassificationType(ClassificationTypeNames="CodeAssist Find Match")][Name("CodeAssist Find Match")][UserVisible(true)]
internal sealed class MatchFormat:ClassificationFormatDefinition {public MatchFormat(){DisplayName="CodeAssist Find Match";BackgroundColor=Color.FromRgb(105,85,30);}}
CodeAssist.Extension/ResultHighlighting.cs:17 [Export(typeof(ClassificationTypeDefinition))][Name("CodeAssist Find Match")]internal static ClassificationTypeDefinition Match=null;
[Export(typeof(EditorFormatDefinition))][ClassificationType(ClassificationTypeNames="CodeAssist Output File")][Name("CodeAssist Output File")][UserVisible(true)]
internal sealed class FileFormat:ClassificationFormatDefinition {public FileFormat(){DisplayName="CodeAssist Output File";ForegroundColor=Color.FromRgb(80,170,255);}}
[Export(typeof(EditorFormatDefinition))][ClassificationType(ClassificationTypeNames="CodeAssist Find Match")][Name("CodeAssist Find Match")][UserVisible(true)]
internal sealed class MatchFormat:ClassificationFormatDefinition {public MatchFormat(){DisplayName="CodeAssist Find Match";BackgroundColor=Color.FromRgb(105,85,30);}}
}
[Export(typeof(IClassifierProvider))][ContentType("text")]
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
문자열·주석 제외 괄호 짝 강조; 실제 IDE·VA 비교 미검증
if(!map.At(position,out partner)){position=caret-1;if(!map.At(position,out partner))yield break;}
var p=StartupUi.Preferences;if(partner<0&&!p.HighlightMismatchingBraces||partner>=0&&!p.HighlightMatchingBraces)yield break;
var tag=new TextMarkerTag(partner<0?"CodeAssist Mismatched Brace":"CodeAssist Matched Brace");
foreach(var offset in partner<0?new[]{position}:new[]{position,partner}){var span=new SnapshotSpan(snapshot,offset,1);foreach(var requested in spans)if(requested.IntersectsWith(span)){yield return new TagSpan<TextMarkerTag>(span,tag);break;}}
}
}
[Export(typeof(IWpfTextViewCreationListener))][ContentType("C/C++")][TextViewRole(PredefinedTextViewRoles.Document)]
CodeAssist.Extension/EditorGuides.cs:60 if(view.IsClosed)return;layer.RemoveAllAdornments();var p=StartupUi.Preferences;
if(view.Options.GetOptionValue(DefaultWpfViewOptions.EnableHighlightCurrentLineId)!=p.HighlightCurrentLine)view.Options.SetOptionValue(DefaultWpfViewOptions.EnableHighlightCurrentLineId,p.HighlightCurrentLine);
if(!p.ColumnIndicatorEnabled||view.ViewportHeight<=0)return;
var x=view.FormattedLineSource.BaseIndentation+view.FormattedLineSource.ColumnWidth*p.ColumnIndicator-view.ViewportLeft;
if(x<0||x>view.ViewportWidth)return;
var line=new Line {X1=x,X2=x,Y1=0,Y2=view.ViewportHeight,Stroke=Brushes.Gray,Opacity=.5,StrokeThickness=1,IsHitTestVisible=false};
layer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative,null,null,line,null);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
불일치·미닫힘 괄호 강조; 실제 IDE·VA 비교 미검증
if(!map.At(position,out partner)){position=caret-1;if(!map.At(position,out partner))yield break;}
var p=StartupUi.Preferences;if(partner<0&&!p.HighlightMismatchingBraces||partner>=0&&!p.HighlightMatchingBraces)yield break;
var tag=new TextMarkerTag(partner<0?"CodeAssist Mismatched Brace":"CodeAssist Matched Brace");
foreach(var offset in partner<0?new[]{position}:new[]{position,partner}){var span=new SnapshotSpan(snapshot,offset,1);foreach(var requested in spans)if(requested.IntersectsWith(span)){yield return new TagSpan<TextMarkerTag>(span,tag);break;}}
}
}
[Export(typeof(IWpfTextViewCreationListener))][ContentType("C/C++")][TextViewRole(PredefinedTextViewRoles.Document)]
CodeAssist.Extension/EditorGuides.cs:60 if(view.IsClosed)return;layer.RemoveAllAdornments();var p=StartupUi.Preferences;
if(view.Options.GetOptionValue(DefaultWpfViewOptions.EnableHighlightCurrentLineId)!=p.HighlightCurrentLine)view.Options.SetOptionValue(DefaultWpfViewOptions.EnableHighlightCurrentLineId,p.HighlightCurrentLine);
if(!p.ColumnIndicatorEnabled||view.ViewportHeight<=0)return;
var x=view.FormattedLineSource.BaseIndentation+view.FormattedLineSource.ColumnWidth*p.ColumnIndicator-view.ViewportLeft;
if(x<0||x>view.ViewportWidth)return;
var line=new Line {X1=x,X2=x,Y1=0,Y2=view.ViewportHeight,Stroke=Brushes.Gray,Opacity=.5,StrokeThickness=1,IsHitTestVisible=false};
layer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative,null,null,line,null);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
인덱스 기반 타입명 대소문자 교정; 지역 변수 교정 제외; 실제 IDE 및 VA 비교 미검증
var preferences=StartupUi.Preferences;var snapshot=view.TextSnapshot;if(snapshot.Length>512*1024)return false;
if(key!='.'&&(!preferences.RepairTypeCase||char.IsLetterOrDigit(key)||key=='_'))return false;
var text=snapshot.GetText();var caret=view.Caret.Position.BufferPosition.Position;var word=CppAutomaticEdits.WordBefore(text,caret);
if(key=='.'&&preferences.ConvertDotToArrow&&word.Length>0)
{var type=new CppReferenceContext(text).ResolveVariableType(word,caret)??indexes?.Index.ResolveVariableType(word);return ApplyAutomatic(CppAutomaticEdits.DotToArrow(text,caret,type),"CodeAssist Dot to Arrow");}
if(preferences.RepairTypeCase&&word.Length>0&&new CppReferenceContext(text).ResolveVariableType(word,caret)==null)ApplyAutomatic(CppAutomaticEdits.RepairCase(text,caret,indexes?.Index.FindCorrectTypeCasing(word)),"CodeAssist Repair Type Case");
return false;
CodeAssist.Extension/CompletionCommandFilter.cs:212 {var type=new CppReferenceContext(text).ResolveVariableType(word,caret)??indexes?.Index.ResolveVariableType(word);return ApplyAutomatic(CppAutomaticEdits.DotToArrow(text,caret,type),"CodeAssist Dot to Arrow");}
if(preferences.RepairTypeCase&&word.Length>0&&new CppReferenceContext(text).ResolveVariableType(word,caret)==null)ApplyAutomatic(CppAutomaticEdits.RepairCase(text,caret,indexes?.Index.FindCorrectTypeCasing(word)),"CodeAssist Repair Type Case");
return false;
}
private void OnKeyDown(object sender,System.Windows.Input.KeyEventArgs e)
{
if(e.Key!=System.Windows.Input.Key.LeftShift&&e.Key!=System.Windows.Input.Key.RightShift){shiftCaret=-1;return;}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
WPF 사전 기반 주석·문자열 소문자 단어 밑줄; OS 사전 유무·IDE 실행 미검증; VA 동등성 미검증
[Export(typeof(ITaggerProvider))][ContentType("C/C++")][TagType(typeof(IErrorTag))]
internal sealed class SpellingProvider:ITaggerProvider
{public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T:ITag=>buffer.Properties.GetOrCreateSingletonProperty(()=>new SpellingTagger(buffer)) as ITagger<T>;}
internal sealed class SpellingTagger:ITagger<IErrorTag>
{
private readonly ITextBuffer buffer;private ITextSnapshot parsed;private string mask;private TextBox checker;private string language;
private readonly Dictionary<string,string> cache=new Dictionary<string,string>(StringComparer.Ordinal);
CodeAssist.Extension/SpellingTagger.cs:18 internal sealed class SpellingProvider:ITaggerProvider
{public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T:ITag=>buffer.Properties.GetOrCreateSingletonProperty(()=>new SpellingTagger(buffer)) as ITagger<T>;}
internal sealed class SpellingTagger:ITagger<IErrorTag>
{
private readonly ITextBuffer buffer;private ITextSnapshot parsed;private string mask;private TextBox checker;private string language;
private readonly Dictionary<string,string> cache=new Dictionary<string,string>(StringComparer.Ordinal);
internal SpellingTagger(ITextBuffer buffer){this.buffer=buffer;buffer.Changed+=(s,e)=>{parsed=null;TagsChanged?.Invoke(this,new SnapshotSpanEventArgs(new SnapshotSpan(e.After,0,e.After.Length)));};}
CodeAssist.Extension/SpellingTagger.cs:19 {public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T:ITag=>buffer.Properties.GetOrCreateSingletonProperty(()=>new SpellingTagger(buffer)) as ITagger<T>;}
internal sealed class SpellingTagger:ITagger<IErrorTag>
{
private readonly ITextBuffer buffer;private ITextSnapshot parsed;private string mask;private TextBox checker;private string language;
private readonly Dictionary<string,string> cache=new Dictionary<string,string>(StringComparer.Ordinal);
internal SpellingTagger(ITextBuffer buffer){this.buffer=buffer;buffer.Changed+=(s,e)=>{parsed=null;TagsChanged?.Invoke(this,new SnapshotSpanEventArgs(new SnapshotSpan(e.After,0,e.After.Length)));};}
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
제한된 식별자 밑줄; 전체 언어 해석 미완료
public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
{
return buffer.Properties.GetOrCreateSingletonProperty(
() => new SymbolTypoTagger(buffer, IndexService)) as ITagger<T>;
}
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
끄기·파일·프로젝트 검사; 전체 checker set 미완료
Page(editor,"Editor","Underlining",()=> {
Toggle(UiText.Get("파일 내 기본 코드 진단 사용", StartupUi.Preferences.UiLanguage),draft.InspectionMode!=InspectionMode.Disabled,v=>draft.InspectionMode=v?InspectionMode.PerFile:InspectionMode.Disabled);
content.Children.Add(ProductTheme.Text(UiText.Get("확정 구문·스코프 오류 후보를 표시합니다. 컴파일러 전체 진단과 동일하지 않습니다.", StartupUi.Preferences.UiLanguage)));
});
Page(editor,"Editor","Highlighting",()=>{
Toggle("Highlight references under caret",draft.AutomaticReferenceHighlights,v=>draft.AutomaticReferenceHighlights=v);
Toggle("Highlight current line",draft.HighlightCurrentLine,v=>draft.HighlightCurrentLine=v);
CodeAssist.Extension/ProductOptions.cs:374 content.Children.Add(ProductTheme.Text("Additional C/C++ file extensions"));var input=new TextBox {Text=draft.CustomFileExtensions};content.Children.Add(input);
input.TextChanged+=(s,e)=>{try{FileExtensionSettings.Parse(input.Text);draft.CustomFileExtensions=input.Text;errors.Remove("extensions");status.Text=UiText.Get("설정은 저장할 때 적용됩니다.",draft.UiLanguage);}catch(ArgumentException error){errors.Add("extensions");status.Text=error.Message;}save.IsEnabled=errors.Count==0;};
content.Children.Add(ProductTheme.Text("Example: .ipp;.tpp;.cuh. Changes are applied to the next index build and cache fingerprint. Language-service associations remain Visual Studio settings."));
});
Page(projects,"Projects","Compilation Database",()=>{
content.Children.Add(ProductTheme.Text("Compilation database directory"));var input=new TextBox {Text=draft.CompilationDatabaseDirectory};content.Children.Add(input);
input.TextChanged+=(s,e)=>{var value=input.Text.Trim();if(value.Length==0||System.IO.Directory.Exists(value)&&System.IO.File.Exists(System.IO.Path.Combine(value,"compile_commands.json"))){draft.CompilationDatabaseDirectory=value;errors.Remove("database");status.Text=UiText.Get("설정은 저장할 때 적용됩니다.",draft.UiLanguage);}else{errors.Add("database");status.Text="Select a directory containing compile_commands.json.";}save.IsEnabled=errors.Count==0;};
CodeAssist.Extension/ProductOptions.cs:375 input.TextChanged+=(s,e)=>{try{FileExtensionSettings.Parse(input.Text);draft.CustomFileExtensions=input.Text;errors.Remove("extensions");status.Text=UiText.Get("설정은 저장할 때 적용됩니다.",draft.UiLanguage);}catch(ArgumentException error){errors.Add("extensions");status.Text=error.Message;}save.IsEnabled=errors.Count==0;};
content.Children.Add(ProductTheme.Text("Example: .ipp;.tpp;.cuh. Changes are applied to the next index build and cache fingerprint. Language-service associations remain Visual Studio settings."));
});
Page(projects,"Projects","Compilation Database",()=>{
content.Children.Add(ProductTheme.Text("Compilation database directory"));var input=new TextBox {Text=draft.CompilationDatabaseDirectory};content.Children.Add(input);
input.TextChanged+=(s,e)=>{var value=input.Text.Trim();if(value.Length==0||System.IO.Directory.Exists(value)&&System.IO.File.Exists(System.IO.Path.Combine(value,"compile_commands.json"))){draft.CompilationDatabaseDirectory=value;errors.Remove("database");status.Text=UiText.Get("설정은 저장할 때 적용됩니다.",draft.UiLanguage);}else{errors.Add("database");status.Text="Select a directory containing compile_commands.json.";}save.IsEnabled=errors.Count==0;};
content.Children.Add(ProductTheme.Text("CMake, Ninja, Make and other build systems can export compile_commands.json. Select a target-specific directory to use its compiler, flags, target architecture and include paths. CodeAssist reads the database; it does not execute build commands."));
CodeAssist.Extension/ProjectInspection.cs:13{
internal sealed class ProjectInspection : IDisposable
{
private readonly AsyncPackage package;
private readonly ProjectIndexService index;
private readonly ErrorListProvider errors;
private CancellationTokenSource run;
CodeAssist.Extension/ProjectInspection.cs:19 private CancellationTokenSource run;
internal ProjectInspection(AsyncPackage package, ProjectIndexService index)
{
ThreadHelper.ThrowIfNotOnUIThread();
this.package=package;this.index=index;errors=new ErrorListProvider(package);
}
internal void Start()
CodeAssist.Extension/ProjectInspection.cs:37 if(string.IsNullOrEmpty(root)) return;
var findings=await System.Threading.Tasks.Task.Run(()=>ProjectSyntaxInspection.Scan(root,token),token);
await package.JoinableTaskFactory.SwitchToMainThreadAsync(token);
errors.Tasks.Clear();
foreach(var finding in findings)
{
var task=new ErrorTask { Document=finding.File,Line=finding.Line-1,Column=finding.Column-1,Text="CodeAssist: "+finding.Message,Category=TaskCategory.CodeSense,ErrorCategory=TaskErrorCategory.Warning };
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
기본 구문·스코프 후보 진단; 원본 검사 엔진 미완료
}
foreach (var issue in CppDelimiterParser.FindDefiniteIssues(snapshot.GetText()))
{
var span = new SnapshotSpan(snapshot, issue.Start, issue.Length);
tags.Add(new TagSpan<IErrorTag>(span,
new ErrorTag(PredefinedErrorTypeNames.SyntaxError, issue.Message + " (CodeAssist)")));
}
CodeAssist.Extension/ProjectInspection.cs:19 private CancellationTokenSource run;
internal ProjectInspection(AsyncPackage package, ProjectIndexService index)
{
ThreadHelper.ThrowIfNotOnUIThread();
this.package=package;this.index=index;errors=new ErrorListProvider(package);
}
internal void Start()
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
커서·선택 범위의 clangd quickfix 선택과 미리보기; 자체 전구 UI 미구현; VA 동등성 미검증
using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.TextManager.Interop; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic;CodeAssist.Extension/CompilerActions.cs:20
private sealed class ActionItem {internal JObject Action;public override string ToString()=>(string)Action["title"];}
internal static async Task<bool> TryAsync(AsyncPackage package,EnvDTE80.DTE2 dte,bool quickFix=false,bool toolWindow=false)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
var file=dte.ActiveDocument?.FullName;if(string.IsNullOrEmpty(file))return false;
var root=Path.GetDirectoryName(file);
while(root!=null&&!File.Exists(Path.Combine(root,"compile_commands.json"))&&!File.Exists(Path.Combine(root,"compile_flags.txt")))root=Path.GetDirectoryName(root);
CodeAssist.Extension/CompilerActions.cs:31 if(manager==null||components==null||manager.GetActiveView(1,null,out var adapter)<0)return false;
var view=components.GetService<IVsEditorAdaptersFactoryService>().GetWpfTextView(adapter);
if(view==null||view.IsClosed||!view.TextBuffer.ContentType.IsOfType("C/C++"))return false;
var snapshot=view.TextSnapshot;var span=view.Selection.StreamSelectionSpan.SnapshotSpan;
var first=snapshot.GetLineFromPosition(span.Start);var last=snapshot.GetLineFromPosition(span.End);
var range=new JObject {["start"]=new JObject {["line"]=first.LineNumber,["character"]=span.Start.Position-first.Start.Position},["end"]=new JObject {["line"]=last.LineNumber,["character"]=span.End.Position-last.Start.Position}};
var open=new Dictionary<string,string>(StringComparer.OrdinalIgnoreCase);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
도구 창에서 clangd quickfix 선택·미리보기·적용; 프로젝트 전체 수정 목록 아님; VA 동등성 미검증
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace CodeAssist.Extension
{
internal static class CompilerActions
{
CodeAssist.Extension/CompilerActions.cs:14using System.Windows;
using System.Windows.Controls;
namespace CodeAssist.Extension
{
internal static class CompilerActions
{
private sealed class ActionItem {internal JObject Action;public override string ToString()=>(string)Action["title"];}
CodeAssist.Extension/CompilerActions.cs:20 private sealed class ActionItem {internal JObject Action;public override string ToString()=>(string)Action["title"];}
internal static async Task<bool> TryAsync(AsyncPackage package,EnvDTE80.DTE2 dte,bool quickFix=false,bool toolWindow=false)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
var file=dte.ActiveDocument?.FullName;if(string.IsNullOrEmpty(file))return false;
var root=Path.GetDirectoryName(file);
while(root!=null&&!File.Exists(Path.Combine(root,"compile_commands.json"))&&!File.Exists(Path.Combine(root,"compile_flags.txt")))root=Path.GetDirectoryName(root);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
{
var path=Path.Combine(root,".codeassist","snippets.tpl");
try {var info=new FileInfo(path);if(info.Exists&&info.Length<=1024*1024){if(!cachedLibraries.TryGetValue(path,out var cached)||cached.Item1!=info.LastWriteTimeUtc){cached=Tuple.Create(info.LastWriteTimeUtc,SnippetTemplate.Parse(File.ReadAllText(path)).ToArray());if(cachedLibraries.Count>=32)cachedLibraries.Clear();cachedLibraries[path]=cached;}templates=templates.Concat(cached.Item2).ToArray();}}
catch(IOException){}catch(UnauthorizedAccessException){}
}
return templates.Where(t=>!string.IsNullOrEmpty(prefix)&&t.Shortcut.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).GroupBy(t=>t.Shortcut,StringComparer.Ordinal).Select(g=>g.Last()).Take(30).ToArray();
}
CodeAssist.Extension/SnippetInsertion.cs:55 ThreadHelper.ThrowIfNotOnUIThread();
if(!StartupUi.Preferences.SnippetShortcutsEnabled||!view.Selection.IsEmpty)return false;
var point=view.Caret.Position.BufferPosition;var line=point.GetContainingLine();var before=line.GetText().Substring(0,point.Position-line.Start.Position);
var match=System.Text.RegularExpressions.Regex.Match(before,@"[A-Za-z_][A-Za-z_0-9]*$");if(!match.Success)return false;
var file=view.TextBuffer.Properties.TryGetProperty(typeof(ITextDocument),out ITextDocument document)?document.FilePath:null;
var dte=Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
var solution=dte?.Solution?.FullName;var root=string.IsNullOrEmpty(solution)?null:Path.GetDirectoryName(solution);
CodeAssist.Extension/SnippetInsertion.cs:62 var templates=new List<SnippetTemplate>(BuiltIns);
try{var path=root==null?null:Path.Combine(root,".codeassist","snippets.tpl");if(path!=null&&File.Exists(path)&&new FileInfo(path).Length<=1024*1024)templates.AddRange(SnippetTemplate.Parse(File.ReadAllText(path)));}catch(IOException){}catch(UnauthorizedAccessException){}
if(!templates.Any(t=>t.Shortcut==match.Value))return false;
Show(view,file,root,dte==null?IntPtr.Zero:(IntPtr)dte.MainWindow.HWnd,null,solution,false,match.Value,new SnapshotSpan(point.Snapshot,line.Start.Position+match.Index,match.Length));return true;
}
internal static void Show(IWpfTextView view, string file, string projectRoot, IntPtr owner, string projectFile = null, string solutionFile = null, bool surroundOnly = false, string shortcut = null, SnapshotSpan? replacement = null)
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
메서드 구현 생성의 사용자 본문 템플릿과 예약 변수; 모든 리팩터링 템플릿 아님; VA 동등성 미검증
{
internal static class RefactoringCommands
{
internal static async System.Threading.Tasks.Task InitializeAsync(AsyncPackage package)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();var service=await package.GetServiceAsync(typeof(IMenuCommandService)) as IMenuCommandService;
if(service==null)return;
CodeAssist.Extension/RefactoringCommands.cs:22 if(service==null)return;
for(var id=0x180;id<=0x18c;id++){var command=id;service.AddCommand(new OleMenuCommand((s,e)=>package.JoinableTaskFactory.RunAsync(async()=>{try{await ExecuteAsync(package,command);}catch(Exception error){await package.JoinableTaskFactory.SwitchToMainThreadAsync();MessageBox.Show(error.Message,"CodeAssist",MessageBoxButton.OK,MessageBoxImage.Warning);}}).FileAndForget("CodeAssist/Refactoring"),new CommandID(GoToSymbolCommand.CommandSet,command)));}
}
private static async System.Threading.Tasks.Task ExecuteAsync(AsyncPackage package,int id)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();var dte=await package.GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
var model=await package.GetServiceAsync(typeof(SComponentModel)) as IComponentModel;var manager=await package.GetServiceAsync(typeof(SVsTextManager)) as IVsTextManager;
CodeAssist.Extension/RefactoringCommands.cs:33 var start=selected.Length==0?line.Start.Position:selected.Start.Position;var length=selected.Length==0?line.Length:selected.Length;
string result=null;var title="CodeAssist Refactoring";
string Ask(string label,string initial="")=>EditorFeatureCommands.Prompt(dte,label,initial);
switch(id)
{
case 0x18b:
result=CppDocumentTransforms.ConvertLocalPointer(snapshot.GetText(),start,length);start=0;length=snapshot.Length;title="Convert Local Pointer / Instance";break;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
기본·프로젝트 스니펫 추천과 Tab·Enter·마우스 커밋 연결; 실제 IDE 입력 검증 미완료; VA 동등성 미검증
if(!StartupUi.Preferences.SuggestionListsEnabled)return;
var snippetItems=StartupUi.Preferences.SnippetSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success?SnippetInsertion.Suggestions(indexService.ProjectRoot,prefix).Select(t=>(Completion)new SnippetCompletion(t)).ToList():new List<Completion>();
if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
!string.Equals(set.Moniker, "CodeAssistPreview", StringComparison.Ordinal) &&
CodeAssist.Extension/CodeAssistCompletionSource.cs:144 var snippetItems=StartupUi.Preferences.SnippetSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success?SnippetInsertion.Suggestions(indexService.ProjectRoot,prefix).Select(t=>(Completion)new SnippetCompletion(t)).ToList():new List<Completion>();
if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
!string.Equals(set.Moniker, "CodeAssistPreview", StringComparison.Ordinal) &&
set.Completions != null && set.Completions.Count > 0);
CodeAssist.Extension/CodeAssistCompletionSource.cs:145 if(StartupUi.Preferences.SmartSuggestionsEnabled&&!hasResolvedMemberContext&&!includeMatch.Success)
snippetItems.AddRange(SmartSuggestions.At(snapshot.GetText(),point.Value.Position).Where(value=>value.StartsWith(prefix,StringComparison.OrdinalIgnoreCase)).Select(value=>(Completion)new Completion(value,value,"CodeAssist expected-type literal",null,"literal")));
if (candidates.Count == 0&&snippetItems.Count==0) return;
var builtInSet = completionSets.FirstOrDefault(set =>
!string.Equals(set.Moniker, "CodeAssistPreview", StringComparison.Ordinal) &&
set.Completions != null && set.Completions.Count > 0);
var start = point.Value.Position - prefix.Length;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
selected 템플릿만 필터해 감싸기; 실제 IDE·VA 비교 미검증
}
internal static void Show(IWpfTextView view, string file, string projectRoot, IntPtr owner, string projectFile = null, string solutionFile = null, bool surroundOnly = false, string shortcut = null, SnapshotSpan? replacement = null)
{
ThreadHelper.ThrowIfNotOnUIThread();
var snapshot = view.TextSnapshot;
var selection = replacement ?? view.Selection.StreamSelectionSpan.SnapshotSpan;
var templates = new List<SnippetTemplate>(BuiltIns);
CodeAssist.Extension/SnippetInsertion.cs:82 if(shortcut!=null)templates=templates.Where(t=>string.Equals(t.Shortcut,shortcut,StringComparison.Ordinal)).ToList();
if(surroundOnly)templates=templates.Where(t=>t.Variables().Contains("selected")).ToList();
if(templates.Count==0)return;
CaptureEnvironment();
templates = templates.Select(template => template.WithEnvironment(name => environment.TryGetValue(name, out var value) ? value : "")).ToList();
var reserved = SnippetReservedValues.Create(file, shortcut==null?selection.GetText():"", DateTime.Now, System.Globalization.CultureInfo.CurrentCulture);
SnippetReservedValues.AddWorkspace(reserved, projectFile, solutionFile, Guid.NewGuid(), System.Globalization.CultureInfo.CurrentCulture);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
단축어+Tab 확장; 추천 목록 활성 중에는 기존 처리 우선; 실제 IDE·VA 비교 미검증
ThreadHelper.ThrowIfNotOnUIThread();
if(!StartupUi.Preferences.SnippetShortcutsEnabled||!view.Selection.IsEmpty)return false;
var point=view.Caret.Position.BufferPosition;var line=point.GetContainingLine();var before=line.GetText().Substring(0,point.Position-line.Start.Position);
var match=System.Text.RegularExpressions.Regex.Match(before,@"[A-Za-z_][A-Za-z_0-9]*$");if(!match.Success)return false;
var file=view.TextBuffer.Properties.TryGetProperty(typeof(ITextDocument),out ITextDocument document)?document.FilePath:null;
var dte=Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
var solution=dte?.Solution?.FullName;var root=string.IsNullOrEmpty(solution)?null:Path.GetDirectoryName(solution);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 영역 스니펫 저장; 실제 IDE·VA 비교 미검증
var view=components.GetService<IVsEditorAdaptersFactoryService>().GetWpfTextView(adapter);if(view==null||view.IsClosed)return;
var snapshot=view.TextSnapshot;var selected=view.Selection.StreamSelectionSpan.SnapshotSpan;var caret=view.Caret.Position.BufferPosition.Position;var text=snapshot.GetText();
var line=snapshot.GetLineFromPosition(caret);var word=IdentifierParser.At(line.GetText(),caret-line.Start.Position);
if(id==0x17b)
{
var links=SourceLinks.Find(line.GetText(),StartupUi.Preferences.SourceLinkRules).Where(candidate=>caret-line.Start.Position>=candidate.Start&&caret-line.Start.Position<=candidate.Start+candidate.Length).ToArray();
if(links.Length==0)throw new InvalidOperationException(UiText.Get("No source link matches the caret. Configure Navigation / Source Links.",StartupUi.Preferences.UiLanguage));
CodeAssist.Extension/EditorFeatureCommands.cs:70 var picker=new NavigationPicker("CodeAssist: Go To Member",entries,package.JoinableTaskFactory);new System.Windows.Interop.WindowInteropHelper(picker).Owner=(IntPtr)dte.MainWindow.HWnd;
if(picker.ShowDialog()==true&&picker.Selected!=null){dte.ItemOperations.OpenFile(picker.Selected.File,EnvDTE.Constants.vsViewKindTextView);(dte.ActiveDocument.Selection as EnvDTE.TextSelection)?.MoveToLineAndOffset(picker.Selected.Line,picker.Selected.Column,false);}return;
}
if(id==0x175){if(selected.Length==0)return;SnippetInsertion.Show(view,file,indexes.ProjectRoot,(IntPtr)dte.MainWindow.HWnd,null,dte.Solution?.FullName,true);return;}
if(id==0x176)
{
if(selected.Length==0)return;
CodeAssist.Extension/EditorFeatureCommands.cs:76 if(selected.Length==0)return;
var title=Prompt(dte,"Snippet title","Selection");if(title==null)return;
var shortcut=Prompt(dte,"Snippet shortcut","snippet");if(shortcut==null)return;
var root=!string.IsNullOrEmpty(dte.Solution?.FullName)?Path.GetDirectoryName(dte.Solution.FullName):indexes.ProjectRoot;
if(string.IsNullOrEmpty(root))throw new InvalidOperationException("Open a solution before saving a project snippet.");
var path=Path.Combine(root,".codeassist","snippets.tpl");var existing=File.Exists(path)?File.ReadAllText(path):"";
if(existing.Length>1024*1024)throw new InvalidOperationException("Snippet library exceeds 1 MiB.");
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
{
public static Dictionary<string, string> Create(string file, string selected, DateTime now, CultureInfo culture)
{
culture = culture ?? CultureInfo.CurrentCulture;
var english = CultureInfo.GetCultureInfo("en-US");
var values = new Dictionary<string, string>(StringComparer.Ordinal)
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
}
public SnippetInput[] Inputs(IReadOnlyDictionary<string, string> reserved = null)
{
var fields = new Dictionary<string, SnippetInput>(StringComparer.Ordinal);
var names = new List<string>();
foreach (var token in Tokens())
{
CodeAssist.Core/SnippetTemplate.cs:58 {
var fields = new Dictionary<string, SnippetInput>(StringComparer.Ordinal);
var names = new List<string>();
foreach (var token in Tokens())
{
var name = BaseName(token, out _, out var initial);
if (name.Length == 0 || name == "end" || reserved != null && (reserved.ContainsKey(token) || reserved.ContainsKey(name))) continue;
CodeAssist.Core/SnippetTemplate.cs:65 if (!fields.TryGetValue(name, out var field))
{ fields[name] = new SnippetInput(name, initial); names.Add(name); }
else if (field.DefaultValue == null && initial != null) fields[name] = new SnippetInput(name, initial);
}
return names.Select(name => fields[name]).ToArray();
}
public string[] Variables() => Inputs().Select(field => field.Name).ToArray();
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
{
public static class SnippetReservedValues
{
public static Dictionary<string, string> Create(string file, string selected, DateTime now, CultureInfo culture)
{
culture = culture ?? CultureInfo.CurrentCulture;
var english = CultureInfo.GetCultureInfo("en-US");
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
LLVM symbolizer를 이용한 바이너리 RVA 해석; 절대 주소·런타임 모듈 자동 매핑 없음; 실제 IDE 및 VA 비교 미검증
{
var picker=new Microsoft.Win32.OpenFileDialog {Title=id==0x190?"CodeAssist: PDB Explorer":"CodeAssist: Address Resolver",Filter=id==0x190?"PDB files|*.pdb":"Binary images|*.exe;*.dll|All files|*.*"};if(picker.ShowDialog()!=true)return;
var tool=id==0x190?"llvm-pdbutil.exe":"llvm-symbolizer.exe";var executable=Path.GetFullPath(Path.Combine(Path.GetDirectoryName(dte.FullName),"../../VC/Tools/Llvm/x64/bin",tool));
if(!File.Exists(executable))throw new FileNotFoundException("LLVM tool not found. Install the Visual Studio C++ LLVM tools.",executable);
var arguments=id==0x190?"dump --publics --globals "+Quote(picker.FileName):"--obj="+Quote(picker.FileName)+" --relative-address --functions --inlines ";
if(id==0x191){var address=EditorFeatureCommands.Prompt(dte,"Relative virtual address (RVA), hexadecimal","0x1000");if(address==null)return;if(!System.Text.RegularExpressions.Regex.IsMatch(address,@"^(?:0[xX])?[0-9a-fA-F]{1,16}$"))throw new ArgumentException("Invalid RVA");arguments+=(address.StartsWith("0x",StringComparison.OrdinalIgnoreCase)?address:"0x"+address);}
var output=await RunToolAsync(executable,arguments,package.DisposalToken);await ShowAsync(package,Path.GetFileName(picker.FileName),new TextBox {Text=output,IsReadOnly=true,AcceptsReturn=true,FontFamily=new FontFamily("Consolas"),HorizontalScrollBarVisibility=ScrollBarVisibility.Auto,VerticalScrollBarVisibility=ScrollBarVisibility.Auto});return;
CodeAssist.Extension/UtilityCommands.cs:40 if(!File.Exists(executable))throw new FileNotFoundException("LLVM tool not found. Install the Visual Studio C++ LLVM tools.",executable);
var arguments=id==0x190?"dump --publics --globals "+Quote(picker.FileName):"--obj="+Quote(picker.FileName)+" --relative-address --functions --inlines ";
if(id==0x191){var address=EditorFeatureCommands.Prompt(dte,"Relative virtual address (RVA), hexadecimal","0x1000");if(address==null)return;if(!System.Text.RegularExpressions.Regex.IsMatch(address,@"^(?:0[xX])?[0-9a-fA-F]{1,16}$"))throw new ArgumentException("Invalid RVA");arguments+=(address.StartsWith("0x",StringComparison.OrdinalIgnoreCase)?address:"0x"+address);}
var output=await RunToolAsync(executable,arguments,package.DisposalToken);await ShowAsync(package,Path.GetFileName(picker.FileName),new TextBox {Text=output,IsReadOnly=true,AcceptsReturn=true,FontFamily=new FontFamily("Consolas"),HorizontalScrollBarVisibility=ScrollBarVisibility.Auto,VerticalScrollBarVisibility=ScrollBarVisibility.Auto});return;
}
if(id==0x192)
{
CodeAssist.Extension/UtilityCommands.cs:41 var arguments=id==0x190?"dump --publics --globals "+Quote(picker.FileName):"--obj="+Quote(picker.FileName)+" --relative-address --functions --inlines ";
if(id==0x191){var address=EditorFeatureCommands.Prompt(dte,"Relative virtual address (RVA), hexadecimal","0x1000");if(address==null)return;if(!System.Text.RegularExpressions.Regex.IsMatch(address,@"^(?:0[xX])?[0-9a-fA-F]{1,16}$"))throw new ArgumentException("Invalid RVA");arguments+=(address.StartsWith("0x",StringComparison.OrdinalIgnoreCase)?address:"0x"+address);}
var output=await RunToolAsync(executable,arguments,package.DisposalToken);await ShowAsync(package,Path.GetFileName(picker.FileName),new TextBox {Text=output,IsReadOnly=true,AcceptsReturn=true,FontFamily=new FontFamily("Consolas"),HorizontalScrollBarVisibility=ScrollBarVisibility.Auto,VerticalScrollBarVisibility=ScrollBarVisibility.Auto});return;
}
if(id==0x192)
{
if(dte.Debugger.CurrentMode!=EnvDTE.dbgDebugMode.dbgBreakMode)throw new InvalidOperationException("Pause at a breakpoint before reading memory.");
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
LLVM pdbutil publics/globals 결과 열람; 형식 트리·전체 PDB 옵션 없음; 실제 IDE 및 VA 비교 미검증
{
var picker=new Microsoft.Win32.OpenFileDialog {Title=id==0x190?"CodeAssist: PDB Explorer":"CodeAssist: Address Resolver",Filter=id==0x190?"PDB files|*.pdb":"Binary images|*.exe;*.dll|All files|*.*"};if(picker.ShowDialog()!=true)return;
var tool=id==0x190?"llvm-pdbutil.exe":"llvm-symbolizer.exe";var executable=Path.GetFullPath(Path.Combine(Path.GetDirectoryName(dte.FullName),"../../VC/Tools/Llvm/x64/bin",tool));
if(!File.Exists(executable))throw new FileNotFoundException("LLVM tool not found. Install the Visual Studio C++ LLVM tools.",executable);
var arguments=id==0x190?"dump --publics --globals "+Quote(picker.FileName):"--obj="+Quote(picker.FileName)+" --relative-address --functions --inlines ";
if(id==0x191){var address=EditorFeatureCommands.Prompt(dte,"Relative virtual address (RVA), hexadecimal","0x1000");if(address==null)return;if(!System.Text.RegularExpressions.Regex.IsMatch(address,@"^(?:0[xX])?[0-9a-fA-F]{1,16}$"))throw new ArgumentException("Invalid RVA");arguments+=(address.StartsWith("0x",StringComparison.OrdinalIgnoreCase)?address:"0x"+address);}
var output=await RunToolAsync(executable,arguments,package.DisposalToken);await ShowAsync(package,Path.GetFileName(picker.FileName),new TextBox {Text=output,IsReadOnly=true,AcceptsReturn=true,FontFamily=new FontFamily("Consolas"),HorizontalScrollBarVisibility=ScrollBarVisibility.Auto,VerticalScrollBarVisibility=ScrollBarVisibility.Auto});return;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
중단 모드에서 명시 주소의 64바이트 디버거 표현식 읽기; 라이브 실행 미검증; 실제 IDE 및 VA 비교 미검증
{
if(dte.Debugger.CurrentMode!=EnvDTE.dbgDebugMode.dbgBreakMode)throw new InvalidOperationException("Pause at a breakpoint before reading memory.");
var address=EditorFeatureCommands.Prompt(dte,"Memory address (hexadecimal), reads 64 bytes","0x0");if(address==null)return;if(!System.Text.RegularExpressions.Regex.IsMatch(address,@"^0[xX][0-9a-fA-F]{1,16}$"))throw new ArgumentException("Invalid address");
var value=dte.Debugger.GetExpression("*(unsigned char (*)[64])"+address,false,1000);if(value==null||!value.IsValidValue)throw new InvalidOperationException(value?.Value??"Memory is unavailable");
var text=new StringBuilder(address+Environment.NewLine+value.Value+Environment.NewLine);foreach(EnvDTE.Expression child in value.DataMembers)text.AppendLine(child.Name+" : "+child.Value);
await ShowAsync(package,"Memory "+address,new TextBox {Text=text.ToString(),IsReadOnly=true,FontFamily=new FontFamily("Consolas"),VerticalScrollBarVisibility=ScrollBarVisibility.Auto});return;
}
CodeAssist.Extension/UtilityCommands.cs:47 if(dte.Debugger.CurrentMode!=EnvDTE.dbgDebugMode.dbgBreakMode)throw new InvalidOperationException("Pause at a breakpoint before reading memory.");
var address=EditorFeatureCommands.Prompt(dte,"Memory address (hexadecimal), reads 64 bytes","0x0");if(address==null)return;if(!System.Text.RegularExpressions.Regex.IsMatch(address,@"^0[xX][0-9a-fA-F]{1,16}$"))throw new ArgumentException("Invalid address");
var value=dte.Debugger.GetExpression("*(unsigned char (*)[64])"+address,false,1000);if(value==null||!value.IsValidValue)throw new InvalidOperationException(value?.Value??"Memory is unavailable");
var text=new StringBuilder(address+Environment.NewLine+value.Value+Environment.NewLine);foreach(EnvDTE.Expression child in value.DataMembers)text.AppendLine(child.Name+" : "+child.Value);
await ShowAsync(package,"Memory "+address,new TextBox {Text=text.ToString(),IsReadOnly=true,FontFamily=new FontFamily("Consolas"),VerticalScrollBarVisibility=ScrollBarVisibility.Auto});return;
}
if(id==0x193)
CodeAssist.Extension/UtilityCommands.cs:48 var address=EditorFeatureCommands.Prompt(dte,"Memory address (hexadecimal), reads 64 bytes","0x0");if(address==null)return;if(!System.Text.RegularExpressions.Regex.IsMatch(address,@"^0[xX][0-9a-fA-F]{1,16}$"))throw new ArgumentException("Invalid address");
var value=dte.Debugger.GetExpression("*(unsigned char (*)[64])"+address,false,1000);if(value==null||!value.IsValidValue)throw new InvalidOperationException(value?.Value??"Memory is unavailable");
var text=new StringBuilder(address+Environment.NewLine+value.Value+Environment.NewLine);foreach(EnvDTE.Expression child in value.DataMembers)text.AppendLine(child.Name+" : "+child.Value);
await ShowAsync(package,"Memory "+address,new TextBox {Text=text.ToString(),IsReadOnly=true,FontFamily=new FontFamily("Consolas"),VerticalScrollBarVisibility=ScrollBarVisibility.Auto});return;
}
if(id==0x193)
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
함수 wildcard 기반 step 이벤트의 최대 20회 step-out; 중단점 이벤트 제외, 실제 디버깅 검증 미완료; VA 동등성 미검증
private readonly ReversibleOverrides<EnvDTE80.Breakpoint2,string> threads=new ReversibleOverrides<EnvDTE80.Breakpoint2,string>();
private string spellCommand;private int filteredSteps;private DateTime lastFilteredStep;
private EnvDTE.DebuggerEvents debuggerEvents;
private ToolbarCommands(AsyncPackage package,EnvDTE80.DTE2 dte){this.package=package;this.dte=dte;}
internal static async System.Threading.Tasks.Task InitializeAsync(AsyncPackage package)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();
CodeAssist.Extension/ToolbarCommands.cs:124 {
if(threads.Active)threads.Restore(ReadFilter,WriteFilter);
else {
if(dte.Debugger.CurrentMode!=EnvDTE.dbgDebugMode.dbgBreakMode||dte.Debugger.CurrentThread==null)return;
var thread=dte.Debugger.CurrentThread.ID.ToString(System.Globalization.CultureInfo.InvariantCulture);
threads.Apply(dte.Debugger.Breakpoints.Cast<EnvDTE.Breakpoint>().OfType<EnvDTE80.Breakpoint2>().ToArray(),ReadFilter,WriteFilter,
filter=>string.IsNullOrWhiteSpace(filter)?"ThreadId = "+thread:"("+filter+") & (ThreadId = "+thread+")");
CodeAssist.Extension/ToolbarCommands.cs:128 var thread=dte.Debugger.CurrentThread.ID.ToString(System.Globalization.CultureInfo.InvariantCulture);
threads.Apply(dte.Debugger.Breakpoints.Cast<EnvDTE.Breakpoint>().OfType<EnvDTE80.Breakpoint2>().ToArray(),ReadFilter,WriteFilter,
filter=>string.IsNullOrWhiteSpace(filter)?"ThreadId = "+thread:"("+filter+") & (ThreadId = "+thread+")");
}
WelcomeDocumentWindow.RecordEvent("ThreadBreakpoints="+threads.Active);return;
}
var manager=await package.GetServiceAsync(typeof(SVsTextManager)) as IVsTextManager;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
현재 파일 심볼 트리입니다. VA Outline의 전체 편집·정렬·드래그 기능 동등성은 미검증입니다.
{
public OutlineToolWindow() : base(null) { Caption = "CodeAssist Outline"; Content = new SymbolPane(false); }
}
[Guid("e4c882bf-d127-4272-b93c-febd6a79f502")]
public sealed class WorkspaceToolWindow : ToolWindowPane
{
public WorkspaceToolWindow() : base(null) { Caption = "CodeAssist Workspace"; Content = new SymbolPane(true); }
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
작업 영역 심볼 트리입니다. VA View의 파일·HCB 구성 전체와 같은 구현은 아닙니다.
{
public WorkspaceToolWindow() : base(null) { Caption = "CodeAssist Workspace"; Content = new SymbolPane(true); }
}
internal sealed class SymbolPane : UserControl
{
private readonly bool workspace;
private readonly TreeView tree = new TreeView();
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
단순 소스 링크 규칙과 커서 위치 열기; 실제 IDE·VA 비교 미검증
{
var links=SourceLinks.Find(line.GetText(),StartupUi.Preferences.SourceLinkRules).Where(candidate=>caret-line.Start.Position>=candidate.Start&&caret-line.Start.Position<=candidate.Start+candidate.Length).ToArray();
if(links.Length==0)throw new InvalidOperationException(UiText.Get("No source link matches the caret. Configure Navigation / Source Links.",StartupUi.Preferences.UiLanguage));
var link=links[0];
if(links.Length>1){var box=new ListBox {ItemsSource=links,SelectedIndex=0};var dialog=new Window {Title="CodeAssist: Source Links",Content=box,Width=750,Height=320,WindowStartupLocation=WindowStartupLocation.CenterOwner};new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;box.MouseDoubleClick+=(s,e)=>dialog.DialogResult=true;dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Enter)dialog.DialogResult=true;if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;};if(dialog.ShowDialog()!=true)return;link=box.SelectedItem as SourceLinkMatch;if(link==null)return;}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(link.Uri.AbsoluteUri){UseShellExecute=true});return;
}
CodeAssist.Extension/EditorFeatureCommands.cs:60 var links=SourceLinks.Find(line.GetText(),StartupUi.Preferences.SourceLinkRules).Where(candidate=>caret-line.Start.Position>=candidate.Start&&caret-line.Start.Position<=candidate.Start+candidate.Length).ToArray();
if(links.Length==0)throw new InvalidOperationException(UiText.Get("No source link matches the caret. Configure Navigation / Source Links.",StartupUi.Preferences.UiLanguage));
var link=links[0];
if(links.Length>1){var box=new ListBox {ItemsSource=links,SelectedIndex=0};var dialog=new Window {Title="CodeAssist: Source Links",Content=box,Width=750,Height=320,WindowStartupLocation=WindowStartupLocation.CenterOwner};new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;box.MouseDoubleClick+=(s,e)=>dialog.DialogResult=true;dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Enter)dialog.DialogResult=true;if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;};if(dialog.ShowDialog()!=true)return;link=box.SelectedItem as SourceLinkMatch;if(link==null)return;}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(link.Uri.AbsoluteUri){UseShellExecute=true});return;
}
if(id==0x171)
CodeAssist.Extension/EditorFeatureCommands.cs:61 if(links.Length==0)throw new InvalidOperationException(UiText.Get("No source link matches the caret. Configure Navigation / Source Links.",StartupUi.Preferences.UiLanguage));
var link=links[0];
if(links.Length>1){var box=new ListBox {ItemsSource=links,SelectedIndex=0};var dialog=new Window {Title="CodeAssist: Source Links",Content=box,Width=750,Height=320,WindowStartupLocation=WindowStartupLocation.CenterOwner};new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;box.MouseDoubleClick+=(s,e)=>dialog.DialogResult=true;dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Enter)dialog.DialogResult=true;if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;};if(dialog.ShowDialog()!=true)return;link=box.SelectedItem as SourceLinkMatch;if(link==null)return;}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(link.Uri.AbsoluteUri){UseShellExecute=true});return;
}
if(id==0x171)
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
정규식·이름 있는 캡처·타임아웃 소스 링크; 실제 IDE·VA 비교 미검증
{
var links=SourceLinks.Find(line.GetText(),StartupUi.Preferences.SourceLinkRules).Where(candidate=>caret-line.Start.Position>=candidate.Start&&caret-line.Start.Position<=candidate.Start+candidate.Length).ToArray();
if(links.Length==0)throw new InvalidOperationException(UiText.Get("No source link matches the caret. Configure Navigation / Source Links.",StartupUi.Preferences.UiLanguage));
var link=links[0];
if(links.Length>1){var box=new ListBox {ItemsSource=links,SelectedIndex=0};var dialog=new Window {Title="CodeAssist: Source Links",Content=box,Width=750,Height=320,WindowStartupLocation=WindowStartupLocation.CenterOwner};new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;box.MouseDoubleClick+=(s,e)=>dialog.DialogResult=true;dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Enter)dialog.DialogResult=true;if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;};if(dialog.ShowDialog()!=true)return;link=box.SelectedItem as SourceLinkMatch;if(link==null)return;}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(link.Uri.AbsoluteUri){UseShellExecute=true});return;
}
CodeAssist.Extension/EditorFeatureCommands.cs:60 var links=SourceLinks.Find(line.GetText(),StartupUi.Preferences.SourceLinkRules).Where(candidate=>caret-line.Start.Position>=candidate.Start&&caret-line.Start.Position<=candidate.Start+candidate.Length).ToArray();
if(links.Length==0)throw new InvalidOperationException(UiText.Get("No source link matches the caret. Configure Navigation / Source Links.",StartupUi.Preferences.UiLanguage));
var link=links[0];
if(links.Length>1){var box=new ListBox {ItemsSource=links,SelectedIndex=0};var dialog=new Window {Title="CodeAssist: Source Links",Content=box,Width=750,Height=320,WindowStartupLocation=WindowStartupLocation.CenterOwner};new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;box.MouseDoubleClick+=(s,e)=>dialog.DialogResult=true;dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Enter)dialog.DialogResult=true;if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;};if(dialog.ShowDialog()!=true)return;link=box.SelectedItem as SourceLinkMatch;if(link==null)return;}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(link.Uri.AbsoluteUri){UseShellExecute=true});return;
}
if(id==0x171)
CodeAssist.Extension/EditorFeatureCommands.cs:61 if(links.Length==0)throw new InvalidOperationException(UiText.Get("No source link matches the caret. Configure Navigation / Source Links.",StartupUi.Preferences.UiLanguage));
var link=links[0];
if(links.Length>1){var box=new ListBox {ItemsSource=links,SelectedIndex=0};var dialog=new Window {Title="CodeAssist: Source Links",Content=box,Width=750,Height=320,WindowStartupLocation=WindowStartupLocation.CenterOwner};new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;box.MouseDoubleClick+=(s,e)=>dialog.DialogResult=true;dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Enter)dialog.DialogResult=true;if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;};if(dialog.ShowDialog()!=true)return;link=box.SelectedItem as SourceLinkMatch;if(link==null)return;}
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(link.Uri.AbsoluteUri){UseShellExecute=true});return;
}
if(id==0x171)
{
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
GitHub·FogBugz URL 규칙 예제; 서비스 API 연동 없음; 실제 IDE·VA 비교 미검증
buttons.Children.Add(ProductTheme.Button("Delete",()=>{if(list.SelectedItem is SourceLinkRule rule){rules.Remove(rule);draft.SourceLinkRules=rules.ToList();}}));
buttons.Children.Add(ProductTheme.Button("GitHub example",()=>{list.SelectedItem=null;name.Text="GitHub issues";pattern.Text="issue #{id}";target.Text="https://github.com/OWNER/REPOSITORY/issues/{id}";complex.IsChecked=false;}));
buttons.Children.Add(ProductTheme.Button("FogBugz example",()=>{list.SelectedItem=null;name.Text="FogBugz cases";pattern.Text="case {id}";target.Text="https://YOUR-SITE.fogbugz.com/f/cases/{id}";complex.IsChecked=false;}));
content.Children.Add(ProductTheme.Text("Simple: issue #{id}. Regex: BUG-(?<id>[0-9]+). Target: https://example.com/issues/{id}. Open a matching link with CodeAssist: Open Source Link."));
});
Page(navigation,"Navigation","CodeAssist Hashtags",()=>content.Children.Add(ProductTheme.Text(UiText.Get("주석의 #태그를 Alt+Shift+H로 검색합니다.", StartupUi.Preferences.UiLanguage))));
var suggestions = Group("Suggestions",()=>{
CodeAssist.Extension/ProductOptions.cs:348 buttons.Children.Add(ProductTheme.Button("GitHub example",()=>{list.SelectedItem=null;name.Text="GitHub issues";pattern.Text="issue #{id}";target.Text="https://github.com/OWNER/REPOSITORY/issues/{id}";complex.IsChecked=false;}));
buttons.Children.Add(ProductTheme.Button("FogBugz example",()=>{list.SelectedItem=null;name.Text="FogBugz cases";pattern.Text="case {id}";target.Text="https://YOUR-SITE.fogbugz.com/f/cases/{id}";complex.IsChecked=false;}));
content.Children.Add(ProductTheme.Text("Simple: issue #{id}. Regex: BUG-(?<id>[0-9]+). Target: https://example.com/issues/{id}. Open a matching link with CodeAssist: Open Source Link."));
});
Page(navigation,"Navigation","CodeAssist Hashtags",()=>content.Children.Add(ProductTheme.Text(UiText.Get("주석의 #태그를 Alt+Shift+H로 검색합니다.", StartupUi.Preferences.UiLanguage))));
var suggestions = Group("Suggestions",()=>{
Toggle(UiText.Get("Acronym completion",draft.UiLanguage),draft.AcronymCompletionEnabled,v=>draft.AcronymCompletionEnabled=v);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
2 MiB 이하 파일의 읽기 전용 색상 미리보기 도구 창; 실제 IDE 및 VA 비교 미검증
{
var picker=new Microsoft.Win32.OpenFileDialog {Title=id==0x190?"CodeAssist: PDB Explorer":"CodeAssist: Address Resolver",Filter=id==0x190?"PDB files|*.pdb":"Binary images|*.exe;*.dll|All files|*.*"};if(picker.ShowDialog()!=true)return;
var tool=id==0x190?"llvm-pdbutil.exe":"llvm-symbolizer.exe";var executable=Path.GetFullPath(Path.Combine(Path.GetDirectoryName(dte.FullName),"../../VC/Tools/Llvm/x64/bin",tool));
if(!File.Exists(executable))throw new FileNotFoundException("LLVM tool not found. Install the Visual Studio C++ LLVM tools.",executable);
var arguments=id==0x190?"dump --publics --globals "+Quote(picker.FileName):"--obj="+Quote(picker.FileName)+" --relative-address --functions --inlines ";
if(id==0x191){var address=EditorFeatureCommands.Prompt(dte,"Relative virtual address (RVA), hexadecimal","0x1000");if(address==null)return;if(!System.Text.RegularExpressions.Regex.IsMatch(address,@"^(?:0[xX])?[0-9a-fA-F]{1,16}$"))throw new ArgumentException("Invalid RVA");arguments+=(address.StartsWith("0x",StringComparison.OrdinalIgnoreCase)?address:"0x"+address);}
var output=await RunToolAsync(executable,arguments,package.DisposalToken);await ShowAsync(package,Path.GetFileName(picker.FileName),new TextBox {Text=output,IsReadOnly=true,AcceptsReturn=true,FontFamily=new FontFamily("Consolas"),HorizontalScrollBarVisibility=ScrollBarVisibility.Auto,VerticalScrollBarVisibility=ScrollBarVisibility.Auto});return;
CodeAssist.Extension/UtilityCommands.cs:54 {
var picker=new Microsoft.Win32.OpenFileDialog {Title="CodeAssist: Preview File",Filter="C/C++ files|*.h;*.hpp;*.cpp;*.c;*.cc;*.inl|All files|*.*"};if(picker.ShowDialog()!=true)return;
if(new FileInfo(picker.FileName).Length>2*1024*1024)throw new InvalidOperationException("Preview is limited to 2 MiB.");var text=await System.Threading.Tasks.Task.Run(()=>File.ReadAllText(picker.FileName));await ShowAsync(package,Path.GetFileName(picker.FileName),new FlowDocumentScrollViewer {Document=ColoredDocument(text),IsToolBarVisible=true});return;
}
if(id==0x194)
{
var document=dte.ActiveDocument?.Object("TextDocument") as EnvDTE.TextDocument;if(document==null)return;var text=document.StartPoint.CreateEditPoint().GetText(document.EndPoint);
CodeAssist.Extension/UtilityCommands.cs:55 var picker=new Microsoft.Win32.OpenFileDialog {Title="CodeAssist: Preview File",Filter="C/C++ files|*.h;*.hpp;*.cpp;*.c;*.cc;*.inl|All files|*.*"};if(picker.ShowDialog()!=true)return;
if(new FileInfo(picker.FileName).Length>2*1024*1024)throw new InvalidOperationException("Preview is limited to 2 MiB.");var text=await System.Threading.Tasks.Task.Run(()=>File.ReadAllText(picker.FileName));await ShowAsync(package,Path.GetFileName(picker.FileName),new FlowDocumentScrollViewer {Document=ColoredDocument(text),IsToolBarVisible=true});return;
}
if(id==0x194)
{
var document=dte.ActiveDocument?.Object("TextDocument") as EnvDTE.TextDocument;if(document==null)return;var text=document.StartPoint.CreateEditPoint().GetText(document.EndPoint);
if(text.Length>2*1024*1024)throw new InvalidOperationException("Color printing is limited to 2 MiB.");var dialog=new PrintDialog();if(dialog.ShowDialog()==true){var documentToPrint=ColoredDocument(text);documentToPrint.PageWidth=dialog.PrintableAreaWidth;documentToPrint.ColumnWidth=dialog.PrintableAreaWidth;dialog.PrintDocument(((IDocumentPaginatorSource)documentToPrint).DocumentPaginator,"CodeAssist: "+dte.ActiveDocument.Name);}return;
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
http·https 링크 외부 열기; 실제 IDE·VA 비교 미검증
var file=dte.ActiveDocument?.FullName;
if(id==0x172){var path=ChooseNewFile(file);if(path==null)return;WriteNew(path,"");dte.ItemOperations.OpenFile(path,EnvDTE.Constants.vsViewKindTextView);return;}
if(id==0x173)
{
var document=dte.ActiveDocument;var item=document?.ProjectItem;
if(document==null||item==null)throw new InvalidOperationException(UiText.Get("Select a project file first.",StartupUi.Preferences.UiLanguage));
if(!document.Saved)throw new InvalidOperationException(UiText.Get("Save the document before renaming it.",StartupUi.Preferences.UiLanguage));
CodeAssist.Extension/EditorFeatureCommands.cs:70 var picker=new NavigationPicker("CodeAssist: Go To Member",entries,package.JoinableTaskFactory);new System.Windows.Interop.WindowInteropHelper(picker).Owner=(IntPtr)dte.MainWindow.HWnd;
if(picker.ShowDialog()==true&&picker.Selected!=null){dte.ItemOperations.OpenFile(picker.Selected.File,EnvDTE.Constants.vsViewKindTextView);(dte.ActiveDocument.Selection as EnvDTE.TextSelection)?.MoveToLineAndOffset(picker.Selected.Line,picker.Selected.Column,false);}return;
}
if(id==0x175){if(selected.Length==0)return;SnippetInsertion.Show(view,file,indexes.ProjectRoot,(IntPtr)dte.MainWindow.HWnd,null,dte.Solution?.FullName,true);return;}
if(id==0x176)
{
if(selected.Length==0)return;
CodeAssist.Extension/EditorFeatureCommands.cs:79 var root=!string.IsNullOrEmpty(dte.Solution?.FullName)?Path.GetDirectoryName(dte.Solution.FullName):indexes.ProjectRoot;
if(string.IsNullOrEmpty(root))throw new InvalidOperationException("Open a solution before saving a project snippet.");
var path=Path.Combine(root,".codeassist","snippets.tpl");var existing=File.Exists(path)?File.ReadAllText(path):"";
if(existing.Length>1024*1024)throw new InvalidOperationException("Snippet library exceeds 1 MiB.");
if(SnippetTemplate.Parse(existing).Any(t=>t.Shortcut==shortcut))throw new InvalidOperationException("Snippet shortcut already exists.");
var entry=CppGeneration.SnippetFromSelection(title,shortcut,selected.GetText());Directory.CreateDirectory(Path.GetDirectoryName(path));
var temporary=path+"."+Guid.NewGuid().ToString("N")+".tmp";
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
설치된 VSIX MEF ICodeAssistPlugin 계약·문서 편집·미리보기·Undo; 별도 플러그인 SDK 배포·호환성 검증 없음; VA 동등성 미검증
{
internal static class PluginCommands
{
internal static async System.Threading.Tasks.Task InitializeAsync(AsyncPackage package)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();var commands=await package.GetServiceAsync(typeof(IMenuCommandService)) as IMenuCommandService;
commands?.AddCommand(new OleMenuCommand((s,e)=>package.JoinableTaskFactory.RunAsync(async()=>{try{await ExecuteAsync(package);}catch(Exception error){await package.JoinableTaskFactory.SwitchToMainThreadAsync();MessageBox.Show(error.Message,"CodeAssist Plugins");}}).FileAndForget("CodeAssist/Plugins"),new CommandID(GoToSymbolCommand.CommandSet,0x1b0)));
CodeAssist.Extension/PluginCommands.cs:20 await package.JoinableTaskFactory.SwitchToMainThreadAsync();var commands=await package.GetServiceAsync(typeof(IMenuCommandService)) as IMenuCommandService;
commands?.AddCommand(new OleMenuCommand((s,e)=>package.JoinableTaskFactory.RunAsync(async()=>{try{await ExecuteAsync(package);}catch(Exception error){await package.JoinableTaskFactory.SwitchToMainThreadAsync();MessageBox.Show(error.Message,"CodeAssist Plugins");}}).FileAndForget("CodeAssist/Plugins"),new CommandID(GoToSymbolCommand.CommandSet,0x1b0)));
}
private static async System.Threading.Tasks.Task ExecuteAsync(AsyncPackage package)
{
await package.JoinableTaskFactory.SwitchToMainThreadAsync();var model=await package.GetServiceAsync(typeof(SComponentModel)) as IComponentModel;var manager=await package.GetServiceAsync(typeof(SVsTextManager)) as IVsTextManager;var dte=await package.GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE80.DTE2;
if(model==null||manager==null||dte==null||manager.GetActiveView(1,null,out var adapter)<0)return;var view=model.GetService<IVsEditorAdaptersFactoryService>().GetWpfTextView(adapter);if(view==null||view.IsClosed)return;
CodeAssist.Extension/PluginCommands.cs:27 var snapshot=view.TextSnapshot;var selection=view.Selection.StreamSelectionSpan.SnapshotSpan;var caret=view.Caret.Position.BufferPosition.Position;
var context=new PluginDocument(dte.ActiveDocument?.FullName,snapshot.GetText(),caret,selection.Start,selection.Length);var providers=model.GetExtensions<ICodeAssistPlugin>().ToArray();
var actions=await System.Threading.Tasks.Task.Run(()=>providers.SelectMany(provider=>provider.GetActions(context)??Enumerable.Empty<PluginAction>()).Take(1000).ToArray());
await package.JoinableTaskFactory.SwitchToMainThreadAsync();if(actions.Length==0){MessageBox.Show("No installed VSIX exports CodeAssist.Core.ICodeAssistPlugin actions for this document.","CodeAssist Plugins");return;}
var list=new ListBox {ItemsSource=actions,SelectedIndex=0};var dialog=new Window {Title="CodeAssist Plugins",Content=list,Width=650,Height=400,WindowStartupLocation=WindowStartupLocation.CenterOwner};new System.Windows.Interop.WindowInteropHelper(dialog).Owner=(IntPtr)dte.MainWindow.HWnd;
list.MouseDoubleClick+=(s,e)=>dialog.DialogResult=true;dialog.PreviewKeyDown+=(s,e)=>{if(e.Key==System.Windows.Input.Key.Enter)dialog.DialogResult=true;if(e.Key==System.Windows.Input.Key.Escape)dialog.DialogResult=false;};if(dialog.ShowDialog()!=true||!(list.SelectedItem is PluginAction action))return;
var after=await System.Threading.Tasks.Task.Run(()=>PluginEdits.Apply(context.Text,action.Edits()));await package.JoinableTaskFactory.SwitchToMainThreadAsync();
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
실제 명령을 편집기 우클릭 메뉴에 배치; 실제 IDE·VA 비교 미검증
<Commands package="guidCodeAssistPackage">
<Menus>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenu" priority="0x0100" type="Menu"><Parent guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenuGroup" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistContextMenu" priority="0x0700" type="Menu"><Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolbar" priority="0x0100" type="Toolbar">
<CommandFlag>DefaultDocked</CommandFlag><Strings><ButtonText>CodeAssist</ButtonText><CommandName>CodeAssist</CommandName></Strings>
</Menu>
CodeAssist.Extension/CodeAssistCommands.vsct:10 <Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenu" priority="0x0100" type="Menu"><Parent guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenuGroup" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistContextMenu" priority="0x0700" type="Menu"><Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN" /><Strings><ButtonText>CodeAssist</ButtonText></Strings></Menu>
<Menu guid="guidCodeAssistCommandSet" id="CodeAssistToolbar" priority="0x0100" type="Toolbar">
<CommandFlag>DefaultDocked</CommandFlag><Strings><ButtonText>CodeAssist</ButtonText><CommandName>CodeAssist</CommandName></Strings>
</Menu>
</Menus>
<Groups>
CodeAssist.Extension/CodeAssistCommands.vsct:14 </Menu>
</Menus>
<Groups>
<Group guid="guidCodeAssistCommandSet" id="CodeAssistToolsMenuGroup" priority="0x0600"><Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS" /></Group>
<Group guid="guidCodeAssistCommandSet" id="CodeAssistContextGroup" priority="0x0100"><Parent guid="guidCodeAssistCommandSet" id="CodeAssistContextMenu" /></Group>
<Group guid="guidCodeAssistCommandSet" id="CodeAssistToolbarGroup" priority="0x0100"><Parent guid="guidCodeAssistCommandSet" id="CodeAssistToolbar" /></Group>
<Group guid="guidCodeAssistCommandSet" id="CodeAssistCommandGroup" priority="0x0600">
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
사용자 확장자 인덱싱·작업자·캐시 fingerprint; VS 언어 서비스 연결은 사용자 설정; 실제 IDE 및 VA 비교 미검증
{
private string[] configuredExtensions=Array.Empty<string>();
private readonly object gate = new object();
private Task buildTask;
private TaskCompletionSource<bool> projectReady;
private readonly CancellationTokenSource shutdown = new CancellationTokenSource();
private string initializedProjectRoot;
CodeAssist.Extension/ProjectIndexService.cs:52 {
target.ParseConcurrency=StartupUi.Preferences.ParseConcurrency;target.AdditionalSourceExtensions=configuredExtensions;
return IndexBuildRunner.Build(target, mode, root, project,
Path.Combine(Path.GetDirectoryName(typeof(ProjectIndexService).Assembly.Location), "CodeAssist.Worker.exe"),
Environment.GetEnvironmentVariable("CODEASSIST_USE_INDEX_WORKER") == "1", shutdown.Token);
}
public void Dispose() { shutdown.Cancel(); }
CodeAssist.Extension/ProjectIndexService.cs:101 if (string.IsNullOrWhiteSpace(unrealProjectPath)) return;
var extensions=FileExtensionSettings.Parse(StartupUi.Preferences.CustomFileExtensions);
var projectRoot = Path.GetDirectoryName(unrealProjectPath);
var engineRoot = string.Equals(Path.GetExtension(unrealProjectPath),".uproject",StringComparison.OrdinalIgnoreCase) ? FindEngineRoot(unrealProjectPath) : null;
var projectCachePath = GetProjectCachePath(projectRoot);
var engineCachePath = GetEngineCachePath(engineRoot);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
실행 동등성 미검증
기존 장부에 구체적인 구현 범위 설명 누락. 후보 파일 존재만 확인함.
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
선택 옵션 Alt+클릭 정의 이동; VA 전체 마우스 제스처 미구현; 실제 IDE 및 VA 비교 미검증
private ITextSnapshot parsed,published;private CppReferenceContext context;private int[] offsets=Array.Empty<int>();private int length;private bool closed,running;
internal ReferenceHighlighting(ITextView view){this.view=view;view.Caret.PositionChanged+=Caret;view.TextBuffer.Changed+=Changed;view.Closed+=Closed;timer.Tick+=Tick;StartupUi.SettingsApplied+=Schedule;if(view is IWpfTextView wpf)wpf.VisualElement.PreviewMouseLeftButtonUp+=Mouse;Schedule();}
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
private void Caret(object sender,CaretPositionChangedEventArgs e)=>Schedule();private void Changed(object sender,TextContentChangedEventArgs e)=>Schedule();
private void Schedule(){timer.Stop();if(!closed)timer.Start();}
private void Tick(object sender,EventArgs e){timer.Stop();if(closed)return;if(running){Schedule();return;}ExtensionPackage.Current?.JoinableTaskFactory.RunAsync(UpdateAsync).FileAndForget("CodeAssist/ReferenceHighlighting");}
private async System.Threading.Tasks.Task UpdateAsync()
CodeAssist.Extension/ReferenceHighlighting.cs:43 }
private void Mouse(object sender,MouseButtonEventArgs e){ThreadHelper.ThrowIfNotOnUIThread();if(!closed&&StartupUi.Preferences.AltClickGoToDefinition&&Keyboard.Modifiers==ModifierKeys.Alt){e.Handled=true;StartupUi.Execute(0x100);}}
private void Raise(){if(!closed)TagsChanged?.Invoke(this,new SnapshotSpanEventArgs(new SnapshotSpan(view.TextSnapshot,0,view.TextSnapshot.Length)));}
public IEnumerable<ITagSpan<TextMarkerTag>> GetTags(NormalizedSnapshotSpanCollection spans)
{if(closed||spans.Count==0||spans[0].Snapshot!=published)yield break;foreach(var offset in offsets){var span=new SnapshotSpan(published,offset,length);if(spans.Any(requested=>requested.IntersectsWith(span)))yield return new TagSpan<TextMarkerTag>(span,new TextMarkerTag(WordHighlights.Marker));}}
private void Closed(object sender,EventArgs e){closed=true;timer.Stop();timer.Tick-=Tick;view.Caret.PositionChanged-=Caret;view.TextBuffer.Changed-=Changed;view.Closed-=Closed;StartupUi.SettingsApplied-=Schedule;if(view is IWpfTextView wpf)wpf.VisualElement.PreviewMouseLeftButtonUp-=Mouse;context=null;offsets=Array.Empty<int>();}
}
CodeAssist.Extension/ReferenceHighlighting.cs:47 {if(closed||spans.Count==0||spans[0].Snapshot!=published)yield break;foreach(var offset in offsets){var span=new SnapshotSpan(published,offset,length);if(spans.Any(requested=>requested.IntersectsWith(span)))yield return new TagSpan<TextMarkerTag>(span,new TextMarkerTag(WordHighlights.Marker));}}
private void Closed(object sender,EventArgs e){closed=true;timer.Stop();timer.Tick-=Tick;view.Caret.PositionChanged-=Caret;view.TextBuffer.Changed-=Changed;view.Closed-=Closed;StartupUi.SettingsApplied-=Schedule;if(view is IWpfTextView wpf)wpf.VisualElement.PreviewMouseLeftButtonUp-=Mouse;context=null;offsets=Array.Empty<int>();}
}
}
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
타깃별 compilation database 디렉터리 선택; 원격 플랫폼 디버깅 없음; 실제 IDE 및 VA 비교 미검증
{
internal static readonly CompilerSemanticService Instance = new CompilerSemanticService();
private readonly SemaphoreSlim gate = new SemaphoreSlim(1, 1);
private readonly CancellationTokenSource shutdown = new CancellationTokenSource();
private ClangdClient client;
private string currentRoot;private string currentDatabase;
internal string LastError { get; private set; }
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
외부 빌드 시스템 compile_commands.json을 clangd에 지정; 빌드 명령은 실행 안 함; 실제 IDE 및 VA 비교 미검증
{
internal static readonly CompilerSemanticService Instance = new CompilerSemanticService();
private readonly SemaphoreSlim gate = new SemaphoreSlim(1, 1);
private readonly CancellationTokenSource shutdown = new CancellationTokenSource();
private ClangdClient client;
private string currentRoot;private string currentDatabase;
internal string LastError { get; private set; }
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
파서 스레드 수 설정과 작업자 전달; 실제 IDE·VA 비교 미검증
{
target.ParseConcurrency=StartupUi.Preferences.ParseConcurrency;target.AdditionalSourceExtensions=configuredExtensions;
return IndexBuildRunner.Build(target, mode, root, project,
Path.Combine(Path.GetDirectoryName(typeof(ProjectIndexService).Assembly.Location), "CodeAssist.Worker.exe"),
Environment.GetEnvironmentVariable("CODEASSIST_USE_INDEX_WORKER") == "1", shutdown.Token);
}
public void Dispose() { shutdown.Cancel(); }
CodeAssist.Extension/ProjectIndexService.cs:101 if (string.IsNullOrWhiteSpace(unrealProjectPath)) return;
var extensions=FileExtensionSettings.Parse(StartupUi.Preferences.CustomFileExtensions);
var projectRoot = Path.GetDirectoryName(unrealProjectPath);
var engineRoot = string.Equals(Path.GetExtension(unrealProjectPath),".uproject",StringComparison.OrdinalIgnoreCase) ? FindEngineRoot(unrealProjectPath) : null;
var projectCachePath = GetProjectCachePath(projectRoot);
var engineCachePath = GetEngineCachePath(engineRoot);
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.
부분 대응·제한 기록 / 전체 동등성 미검증
작동하는 옵션과 미지원 범주 표시가 공존합니다. 모든 VA 옵션 및 기본값이 구현된 상태가 아닙니다.
content.Children.Add(new Border { Background = new SolidColorBrush(Color.FromArgb(30,255,211,70)), Padding = new Thickness(12),
Child = ProductTheme.Text(UiText.Get("이 범주는 현재 지원하지 않습니다. 제공되는 기능은 관련 설정에서 사용할 수 있습니다.", StartupUi.Preferences.UiLanguage)) });
}
void Page(TreeViewItem parent, string section, string title, Action body)
{
var item = new TreeViewItem { Header = UiText.Get(title, StartupUi.Preferences.UiLanguage), Tag = section + " / " + title, Padding = new Thickness(4,5,0,5) };
parent.Items.Add(item); pages[(string)item.Tag] = () => { Heading(section,title); body(); };
CodeAssist.Extension/ProductOptions.cs:290 });
Page(editor,"Editor","Floating Elements",()=>Unavailable(UiText.Get("빠른 작업은 Alt+Shift+Q로 엽니다. 부동 빠른 작업 툴바는 현재 지원하지 않습니다.", StartupUi.Preferences.UiLanguage)));
Page(editor,"Editor","Smart Select",()=> {
Toggle(UiText.Get("Start and grow selections by relatively small increments",StartupUi.Preferences.UiLanguage),draft.SmartSelectSmallIncrements,v=>draft.SmartSelectSmallIncrements=v);
var word=Toggle(UiText.Get("Start non-block selections with the current word",StartupUi.Preferences.UiLanguage),draft.SmartSelectStartWithWord,v=>draft.SmartSelectStartWithWord=v);
var casing=Toggle(UiText.Get("Changes in case delimit current word",StartupUi.Preferences.UiLanguage),draft.SmartSelectSplitCase,v=>draft.SmartSelectSplitCase=v);
var underscore=Toggle(UiText.Get("Underscores delimit current word",StartupUi.Preferences.UiLanguage),draft.SmartSelectSplitUnderscores,v=>draft.SmartSelectSplitUnderscores=v);
CodeAssist.Core/Localization/ui.xml:431 </entry>
<entry key="ui.d0db8b5e364b" source="Options">
<text lang="ko">설정</text>
<text lang="en">Options</text>
</entry>
<entry key="ui.c205924de0fe" source="Documentation">
<text lang="ko">문서</text>
CodeAssist.Core/Localization/ui.xml:433 <text lang="ko">설정</text>
<text lang="en">Options</text>
</entry>
<entry key="ui.c205924de0fe" source="Documentation">
<text lang="ko">문서</text>
<text lang="en">Documentation</text>
</entry>
CodeAssist.Core/Localization/ui.xml:439 </entry>
<entry key="ui.700fe314615c" source="CodeAssist Options">
<text lang="ko">CodeAssist 설정</text>
<text lang="en">CodeAssist Options</text>
</entry>
<entry key="ui.completion.native.colors" source="Visual Studio 기본 추천 색상 사용">
<text lang="ko">Visual Studio 기본 추천 색상 사용</text>
Undo·설정 기본값·언어/VS 버전·성능 전체 검증이 남아 있습니다.