1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Fixit improvements, remove namespace

This commit is contained in:
Brian Fiete 2020-02-07 08:44:06 -08:00
parent 7a5dd90cff
commit 61bd31836d
10 changed files with 304 additions and 157 deletions

View file

@ -215,7 +215,6 @@ namespace IDE
Add("New File", new => gApp.Cmd_NewFile); Add("New File", new => gApp.Cmd_NewFile);
Add("New Project", new => gApp.Cmd_NewProject); Add("New Project", new => gApp.Cmd_NewProject);
Add("New Workspace", new => gApp.Cmd_NewWorkspace); Add("New Workspace", new => gApp.Cmd_NewWorkspace);
Add("New View Into File", new => gApp.Cmd_NewFileView);
Add("Next Document Panel", new => gApp.[Friend]DoShowNextDocumentPanel); Add("Next Document Panel", new => gApp.[Friend]DoShowNextDocumentPanel);
Add("Open Corresponding", new => gApp.[Friend]OpenCorresponding); Add("Open Corresponding", new => gApp.[Friend]OpenCorresponding);
Add("Open Crash Dump", new => gApp.OpenCrashDump); Add("Open Crash Dump", new => gApp.OpenCrashDump);
@ -264,7 +263,6 @@ namespace IDE
Add("Show Threads", new => gApp.ShowThreads); Add("Show Threads", new => gApp.ShowThreads);
Add("Show Watches", new => gApp.ShowWatches); Add("Show Watches", new => gApp.ShowWatches);
Add("Show Workspace Explorer", new => gApp.ShowWorkspacePanel); Add("Show Workspace Explorer", new => gApp.ShowWorkspacePanel);
Add("Split View", new => gApp.[Friend]SplitView);
Add("Start Debugging", new => gApp.[Friend]RunWithCompiling); Add("Start Debugging", new => gApp.[Friend]RunWithCompiling);
Add("Start Without Debugging", new => gApp.[Friend]RunWithoutCompiling); Add("Start Without Debugging", new => gApp.[Friend]RunWithoutCompiling);
Add("Step Into", new => gApp.[Friend]StepInto); Add("Step Into", new => gApp.[Friend]StepInto);
@ -275,6 +273,8 @@ namespace IDE
Add("Tab Last", new => gApp.[Friend]TabLast); Add("Tab Last", new => gApp.[Friend]TabLast);
Add("Tab Next", new => gApp.[Friend]TabNext); Add("Tab Next", new => gApp.[Friend]TabNext);
Add("Tab Prev", new => gApp.[Friend]TabPrev); Add("Tab Prev", new => gApp.[Friend]TabPrev);
Add("View New", new => gApp.Cmd_ViewNew);
Add("View Split", new => gApp.[Friend]ViewSplit);
Add("View White Space", new => gApp.Cmd_ViewWhiteSpace); Add("View White Space", new => gApp.Cmd_ViewWhiteSpace);
Add("Zoom In", new => gApp.Cmd_ZoomIn); Add("Zoom In", new => gApp.Cmd_ZoomIn);
Add("Zoom Out", new => gApp.Cmd_ZoomOut); Add("Zoom Out", new => gApp.Cmd_ZoomOut);

View file

@ -751,7 +751,7 @@ namespace IDE
base.Run(); base.Run();
} }
public void Cmd_NewFileView() public void Cmd_ViewNew()
{ {
var sourceViewPanel = GetActiveSourceViewPanel(); var sourceViewPanel = GetActiveSourceViewPanel();
if (sourceViewPanel != null) if (sourceViewPanel != null)
@ -4824,7 +4824,6 @@ namespace IDE
AddMenuItem(subMenu, "&Save File","Save File"); AddMenuItem(subMenu, "&Save File","Save File");
AddMenuItem(subMenu, "Save &As...", "Save As"); AddMenuItem(subMenu, "Save &As...", "Save As");
AddMenuItem(subMenu, "Save A&ll", "Save All"); AddMenuItem(subMenu, "Save A&ll", "Save All");
AddMenuItem(subMenu, "N&ew View into File", "New View Into File");
let prefMenu = subMenu.AddMenuItem("&Preferences"); let prefMenu = subMenu.AddMenuItem("&Preferences");
//prefMenu.AddMenuItem("&Keyboard Shortcuts", null, new (evt) => { ShowKeyboardShortcuts(); }); //prefMenu.AddMenuItem("&Keyboard Shortcuts", null, new (evt) => { ShowKeyboardShortcuts(); });
AddMenuItem(prefMenu, "&Settings", "Settings"); AddMenuItem(prefMenu, "&Settings", "Settings");
@ -5028,7 +5027,8 @@ namespace IDE
mWindowMenu = root.AddMenuItem("&Window"); mWindowMenu = root.AddMenuItem("&Window");
AddMenuItem(mWindowMenu, "&Close", "Close Window"); AddMenuItem(mWindowMenu, "&Close", "Close Window");
AddMenuItem(mWindowMenu, "&Close All", "Close All Windows"); AddMenuItem(mWindowMenu, "&Close All", "Close All Windows");
AddMenuItem(mWindowMenu, "&Split View", "Split View"); AddMenuItem(mWindowMenu, "&New View into File", "View New");
AddMenuItem(mWindowMenu, "&Split View", "View Split");
subMenu = root.AddMenuItem("&Help"); subMenu = root.AddMenuItem("&Help");
AddMenuItem(subMenu, "&About", "About"); AddMenuItem(subMenu, "&About", "About");
@ -6155,7 +6155,7 @@ namespace IDE
DocumentCloseClicked(docPanel); DocumentCloseClicked(docPanel);
} }
void SplitView() void ViewSplit()
{ {
var sourceViewPanel = GetActiveSourceViewPanel(); var sourceViewPanel = GetActiveSourceViewPanel();
if (sourceViewPanel != null) if (sourceViewPanel != null)

View file

@ -2126,35 +2126,47 @@ namespace IDE.ui
return mInsertStartIdx == mInsertEndIdx; return mInsertStartIdx == mInsertEndIdx;
} }
/*void ApplyFixit(String fixitType, String fileName, String fixitParam)
{
var projectSource = IDEApp.sApp.FindProjectSourceItem(fileName);
var editData = IDEApp.sApp.GetEditData(projectSource);
var sourceEditWidgetContent = (SourceEditWidgetContent)editData.mEditWidget.Content;
//cursorPositions.Add(sourceEditWidgetContent.CursorTextPos);
var bfSystem = IDEApp.sApp.mBfResolveSystem;
var parser = bfSystem.CreateEmptyParser(null);
defer:: delete parser;
var text = scope String();
editData.mEditWidget.GetText(text);
parser.SetSource(text, fileName);
var passInstance = bfSystem.CreatePassInstance();
defer:: delete passInstance;
parser.Parse(passInstance, false);
parser.Reduce(passInstance);
parser.Ref
}*/
void ApplyFixit(String data) void ApplyFixit(String data)
{ {
var parts = String.StackSplit!(data, '|'); UndoBatchStart undoBatchStart = null;
//String fixitType = parts[0];
String fixitFileName = parts[1];
int32 fixitIdx = int32.Parse(parts[2]).GetValueOrDefault();
var parts = String.StackSplit!(data, '|');
String fixitFileName = parts[1];
SourceViewPanel sourceViewPanel = IDEApp.sApp.ShowSourceFile(fixitFileName);
var targetSourceEditWidgetContent = mTargetEditWidget.Content as SourceEditWidgetContent;
var historyEntry = targetSourceEditWidgetContent.RecordHistoryLocation();
historyEntry.mNoMerge = true;
var sourceEditWidgetContent = targetSourceEditWidgetContent;
if (sourceEditWidgetContent.mSourceViewPanel != sourceViewPanel)
{
sourceEditWidgetContent = (SourceEditWidgetContent)sourceViewPanel.GetActivePanel().EditWidget.mEditWidgetContent;
undoBatchStart = new UndoBatchStart("autocomplete");
sourceEditWidgetContent.mData.mUndoManager.Add(undoBatchStart);
}
int32 fixitIdx = 0;
int32 fixitLen = 0;
StringView fixitLocStr = parts[2];
int dashPos = fixitLocStr.IndexOf('-');
if (dashPos != -1)
{
fixitLen = int32.Parse(fixitLocStr.Substring(dashPos + 1));
fixitLocStr.RemoveToEnd(dashPos);
}
if (fixitLocStr.Contains(':'))
{
var splitItr = fixitLocStr.Split(':');
int32 line = int32.Parse(splitItr.GetNext().Value).Value;
int32 col = int32.Parse(splitItr.GetNext().Value).Value;
fixitIdx = (.)sourceEditWidgetContent.GetTextIdx(line, col);
}
else
fixitIdx = int32.Parse(fixitLocStr).GetValueOrDefault();
int insertCount = 0;
int dataIdx = 3; int dataIdx = 3;
while (dataIdx < parts.Count) while (dataIdx < parts.Count)
@ -2178,7 +2190,6 @@ namespace IDE.ui
#unwarn #unwarn
bool hasMore = dataIdx < parts.Count; bool hasMore = dataIdx < parts.Count;
SourceViewPanel sourceViewPanel = IDEApp.sApp.ShowSourceFile(fixitFileName);
if (sourceViewPanel != null) if (sourceViewPanel != null)
{ {
if (sourceViewPanel.IsReadOnly) if (sourceViewPanel.IsReadOnly)
@ -2186,50 +2197,48 @@ namespace IDE.ui
gApp.Fail(scope String()..AppendF("The selected fixit cannot be applied to locked file '{}'", sourceViewPanel.mFilePath)); gApp.Fail(scope String()..AppendF("The selected fixit cannot be applied to locked file '{}'", sourceViewPanel.mFilePath));
return; return;
} }
var targetSourceEditWidgetContent = mTargetEditWidget.Content as SourceEditWidgetContent;
var history = targetSourceEditWidgetContent.RecordHistoryLocation();
history.mNoMerge = true;
var editWidgetContent = (SourceEditWidgetContent)sourceViewPanel.mEditWidget.mEditWidgetContent; sourceEditWidgetContent.CursorTextPos = fixitIdx;
editWidgetContent.CursorTextPos = fixitIdx; sourceEditWidgetContent.EnsureCursorVisible(true, true);
editWidgetContent.EnsureCursorVisible(true, true);
if (fixitLen > 0)
{
sourceEditWidgetContent.mSelection = EditSelection(fixitIdx, fixitIdx + fixitLen);
sourceEditWidgetContent.DeleteSelection();
fixitLen = 0;
}
if (fixitInsert.StartsWith('\n')) if (fixitInsert.StartsWith('\n'))
editWidgetContent.PasteText(fixitInsert, fixitInsert.StartsWith("\n")); sourceEditWidgetContent.PasteText(fixitInsert, fixitInsert.StartsWith("\n"));
else else
InsertImplText(fixitInsert); InsertImplText(sourceEditWidgetContent, fixitInsert);
fixitIdx = (.)editWidgetContent.CursorTextPos; fixitIdx = (.)sourceEditWidgetContent.CursorTextPos;
insertCount++;
} }
} }
/*switch (parts[0]) if (historyEntry != null)
{ {
case "using": // Make sure when we go back that we'll go back to the insert position
//ApplyFixit(parts[0], parts[1], parts[2]); int idx = gApp.mHistoryManager.mHistoryList.LastIndexOf(historyEntry);
if (idx != -1)
break; gApp.mHistoryManager.mHistoryIdx = (.)idx;
case "addMethod": }
break;
}*/ if (undoBatchStart != null)
sourceEditWidgetContent.mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
} }
void InsertImplText(String implText) void InsertImplText(SourceEditWidgetContent sourceEditWidgetContent, String implText)
{ {
var sourceEditWidgetContent = mTargetEditWidget.Content as SourceEditWidgetContent;
/*sourceEditWidgetContent.ClearLine();
sourceEditWidgetContent.InsertAtCursor("ABC\nDEF\nGHI");
return;*/
String implSect = scope .(); String implSect = scope .();
int startIdx = 0; int startIdx = 0;
for (int i < implText.Length) for (int i < implText.Length)
{ {
char8 c = implText[i]; char8 c = implText[i];
if ((c == '\t') || (c == '\b') || (c == '\r') || (c == '\f')) if ((c == '\a') || (c == '\t') || (c == '\b') || (c == '\r') || (c == '\f'))
{ {
implSect.Clear(); implSect.Clear();
implSect.Append(implText, startIdx, i - startIdx); implSect.Append(implText, startIdx, i - startIdx);
@ -2238,7 +2247,30 @@ namespace IDE.ui
sourceEditWidgetContent.InsertAtCursor(implSect); sourceEditWidgetContent.InsertAtCursor(implSect);
} }
if (c == '\f') if (c == '\a') // Ensure we have spacing or an open brace on the previous line
{
int lineNum = sourceEditWidgetContent.CursorLineAndColumn.mLine;
if (lineNum > 0)
{
sourceEditWidgetContent.GetLinePosition(lineNum - 1, var lineStart, var lineEnd);
for (int idx = lineEnd; idx >= lineStart; idx--)
{
let charData = sourceEditWidgetContent.mData.mText[idx];
if (charData.mDisplayTypeId == (.)SourceElementType.Comment)
continue;
if (charData.mChar.IsWhiteSpace)
continue;
if (charData.mChar == '{')
break;
// Add new line
sourceEditWidgetContent.InsertAtCursor("\n");
sourceEditWidgetContent.CursorToLineEnd();
break;
}
}
}
else if (c == '\f') // Make sure we're on an empty line
{ {
if (!sourceEditWidgetContent.IsLineWhiteSpace(sourceEditWidgetContent.CursorLineAndColumn.mLine)) if (!sourceEditWidgetContent.IsLineWhiteSpace(sourceEditWidgetContent.CursorLineAndColumn.mLine))
{ {
@ -2251,29 +2283,19 @@ namespace IDE.ui
sourceEditWidgetContent.CursorTextPos = prevPos; sourceEditWidgetContent.CursorTextPos = prevPos;
} }
sourceEditWidgetContent.CursorToLineEnd(); sourceEditWidgetContent.CursorToLineEnd();
/*if (!sourceEditWidgetContent.IsLineWhiteSpace(sourceEditWidgetContent.CursorLineAndColumn.mLine))
{
sourceEditWidgetContent.InsertText(sourceEditWidgetContent.CursorTextPos + 1, "\n");
sourceEditWidgetContent.ContentChanged();
}*/
//return;
//sourceEditWidgetContent.GetLineText(sourceEditWidgetContent.CursorLineAndColumn.mLine, )
//sourceEditWidgetContent.InsertAtCursor("ABC\n");
} }
else if (c == '\t') else if (c == '\t') // Open block
{ {
sourceEditWidgetContent.InsertAtCursor("\n"); sourceEditWidgetContent.InsertAtCursor("\n");
sourceEditWidgetContent.CursorToLineEnd(); sourceEditWidgetContent.CursorToLineEnd();
sourceEditWidgetContent.OpenCodeBlock(); sourceEditWidgetContent.OpenCodeBlock();
} }
else if (c == '\r') else if (c == '\r') // Newline
{ {
sourceEditWidgetContent.InsertAtCursor("\n"); sourceEditWidgetContent.InsertAtCursor("\n");
sourceEditWidgetContent.CursorToLineEnd(); sourceEditWidgetContent.CursorToLineEnd();
} }
else if (c == '\b') else if (c == '\b') // Close block
{ {
int cursorPos = sourceEditWidgetContent.CursorTextPos; int cursorPos = sourceEditWidgetContent.CursorTextPos;
while (cursorPos < sourceEditWidgetContent.mData.mTextLength) while (cursorPos < sourceEditWidgetContent.mData.mTextLength)
@ -2406,7 +2428,7 @@ namespace IDE.ui
UpdateAsyncInfo();*/ UpdateAsyncInfo();*/
if (implText != null) if (implText != null)
InsertImplText(implText); InsertImplText(sourceEditWidgetContent, implText);
if (persistentInvokeSrcPositons != null) if (persistentInvokeSrcPositons != null)
{ {

View file

@ -1489,7 +1489,7 @@ namespace IDE.ui
base.InsertAtCursor(theString, insertFlags); base.InsertAtCursor(theString, insertFlags);
mInsertDisplayFlags = 0; mInsertDisplayFlags = 0;
if ((!mIgnoreSetHistory) && (!insertFlags.HasFlag(.NoMoveCursor))) if ((!mIgnoreSetHistory) && (!insertFlags.HasFlag(.NoMoveCursor)) && (!insertFlags.HasFlag(.NoRecordHistory)))
RecordHistoryLocation(); RecordHistoryLocation();
} }

View file

@ -236,22 +236,12 @@ namespace IDE.ui
if (activeDocument is SourceViewPanel) if (activeDocument is SourceViewPanel)
{ {
var sourceViewPanel = (SourceViewPanel)activeDocument; var sourceViewPanel = (SourceViewPanel)activeDocument;
sourceViewPanel = sourceViewPanel.GetActivePanel();
int32 line; int32 line;
int32 column; int32 column;
sourceViewPanel.GetCursorPosition(out line, out column); sourceViewPanel.GetCursorPosition(out line, out column);
/*var ewc = sourceViewPanel.mEditWidget.Content;
int cursorPos = ewc.CursorTextPos;
if (cursorPos < ewc.mData.mTextLength)
{
ewc.mData.mTextIdData.Prepare();
g.DrawString(StackStringFormat!("Id {0}", ewc.mData.mTextIdData.GetIdAtIndex(cursorPos)), mWidth - GS!(310), 0);
}*/
/*line = 8'888'888;
column = 8'888'888;*/
if (gApp.mSettings.mEnableDevMode) if (gApp.mSettings.mEnableDevMode)
g.DrawString(StackStringFormat!("Idx {0}", sourceViewPanel.mEditWidget.Content.CursorTextPos), mWidth - GS!(240), 0); g.DrawString(StackStringFormat!("Idx {0}", sourceViewPanel.mEditWidget.Content.CursorTextPos), mWidth - GS!(240), 0);
g.DrawString(StackStringFormat!("Ln {0}", line + 1), mWidth - GS!(150), 0); g.DrawString(StackStringFormat!("Ln {0}", line + 1), mWidth - GS!(150), 0);

View file

@ -1906,7 +1906,7 @@ void BfAutoComplete::CheckNode(BfAstNode* node)
} }
} }
bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* showString, StringImpl* insertString, bool isExplicitInterface) bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* showString, StringImpl* insertString, bool isImplementing, bool isExplicitInterface)
{ {
auto methodDef = methodInst->mMethodDef; auto methodDef = methodInst->mMethodDef;
bool isInterface = methodInst->GetOwner()->IsInterface(); bool isInterface = methodInst->GetOwner()->IsInterface();
@ -1917,24 +1917,21 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho
StringT<128> methodName; StringT<128> methodName;
StringT<256> impString; StringT<256> impString;
bool isAbstract = (methodDef->mIsAbstract) && (!isInterface); bool isAbstract = methodDef->mIsAbstract || isInterface;// (methodDef->mIsAbstract) && (!isInterface);
if (!isAbstract) if (isAbstract)
{ {
if (isInterface) if (!methodInst->mReturnType->IsVoid())
{ impString += "return default;";
if (!methodInst->mReturnType->IsVoid()) }
impString += "return default;"; else if (!isAbstract)
} {
else if (!methodInst->mReturnType->IsVoid())
{ impString = "return ";
if (!methodInst->mReturnType->IsVoid())
impString = "return ";
impString += "base."; impString += "base.";
impString += methodDef->mName; impString += methodDef->mName;
impString += "("; impString += "(";
}
} }
auto methodDeclaration = methodDef->GetMethodDeclaration(); auto methodDeclaration = methodDef->GetMethodDeclaration();
@ -1963,19 +1960,19 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho
if (paramIdx > 0) if (paramIdx > 0)
{ {
methodName += ", "; methodName += ", ";
if ((!isAbstract) && (!isInterface)) if (!isAbstract)
impString += ", "; impString += ", ";
} }
methodName += mModule->TypeToString(methodInst->GetParamType(paramIdx), BfTypeNameFlag_ReduceName); methodName += mModule->TypeToString(methodInst->GetParamType(paramIdx), BfTypeNameFlag_ReduceName);
methodName += " "; methodName += " ";
methodName += methodDef->mParams[paramIdx]->mName; methodName += methodDef->mParams[paramIdx]->mName;
if ((!isAbstract) && (!isInterface)) if (!isAbstract)
impString += methodDef->mParams[paramIdx]->mName; impString += methodDef->mParams[paramIdx]->mName;
} }
methodName += ")"; methodName += ")";
if ((!isAbstract) && (!isInterface)) if (!isAbstract)
impString += ");"; impString += ");";
if (showString != NULL) if (showString != NULL)
@ -2115,7 +2112,7 @@ void BfAutoComplete::AddOverrides(const StringImpl& filter)
continue; continue;
StringT<512> insertString; StringT<512> insertString;
GetMethodInfo(methodInst, &insertString, &insertString, false); GetMethodInfo(methodInst, &insertString, &insertString, true, false);
if (insertString.IsEmpty()) if (insertString.IsEmpty())
continue; continue;
AddEntry(AutoCompleteEntry("override", insertString, NULL), filter); AddEntry(AutoCompleteEntry("override", insertString, NULL), filter);
@ -2475,7 +2472,37 @@ bool BfAutoComplete::CheckFixit(BfAstNode* node)
return true; return true;
} }
void BfAutoComplete::ChcekInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode* node) int BfAutoComplete::FixitGetMemberInsertPos(BfTypeDef* typeDef)
{
BfTypeDeclaration* typeDecl = typeDef->mTypeDeclaration;
BfTokenNode* openNode = NULL;
BfTokenNode* closeNode = NULL;
if (auto blockNode = BfNodeDynCast<BfBlock>(typeDecl->mDefineNode))
{
openNode = blockNode->mOpenBrace;
closeNode = blockNode->mCloseBrace;
}
int insertPos = -1;
BfParserData* parser = typeDef->mTypeDeclaration->GetSourceData()->ToParserData();
if ((parser != NULL) && (closeNode != NULL))
{
int startPos = openNode->mSrcStart + 1;
insertPos = closeNode->mSrcStart;
while (insertPos > startPos)
{
char prevC = parser->mSrc[insertPos - 1];
if (prevC == '\n')
break;
insertPos--;
}
if (insertPos > startPos)
insertPos--;
}
return insertPos;
}
void BfAutoComplete::CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode* node)
{ {
if (!CheckFixit(node)) if (!CheckFixit(node))
return; return;
@ -2529,30 +2556,11 @@ void BfAutoComplete::ChcekInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode
} }
if (!missingMethods.IsEmpty()) if (!missingMethods.IsEmpty())
{ {
BfTypeDeclaration* typeDecl = declTypeDef->mTypeDeclaration;
BfTokenNode* openNode = NULL;
BfTokenNode* closeNode = NULL;
if (auto blockNode = BfNodeDynCast<BfBlock>(typeDecl->mDefineNode))
{
openNode = blockNode->mOpenBrace;
closeNode = blockNode->mCloseBrace;
}
BfParserData* parser = declTypeDef->mTypeDeclaration->GetSourceData()->ToParserData(); BfParserData* parser = declTypeDef->mTypeDeclaration->GetSourceData()->ToParserData();
if ((parser != NULL) && (closeNode != NULL)) if (parser != NULL)
{ {
int startPos = openNode->mSrcStart + 1; int insertPos = FixitGetMemberInsertPos(declTypeDef);
int insertPos = closeNode->mSrcStart;
while (insertPos > startPos)
{
char prevC = parser->mSrc[insertPos - 1];
if (prevC == '\n')
break;
insertPos--;
}
if (insertPos > startPos)
insertPos--;
bool wantsBreak = false; bool wantsBreak = false;
String insertStr = "\f"; String insertStr = "\f";
@ -2563,7 +2571,7 @@ void BfAutoComplete::ChcekInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode
insertStr += "\r\r"; insertStr += "\r\r";
wantsBreak = false; wantsBreak = false;
} }
if (GetMethodInfo(methodInst, NULL, &insertStr, false)) if (GetMethodInfo(methodInst, NULL, &insertStr, true, false))
{ {
insertStr += "\b"; insertStr += "\b";
wantsBreak = true; wantsBreak = true;
@ -2579,20 +2587,87 @@ void BfAutoComplete::ChcekInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode
explicitInsertStr += "\r\r"; explicitInsertStr += "\r\r";
wantsBreak = false; wantsBreak = false;
} }
if (GetMethodInfo(methodInst, NULL, &explicitInsertStr, true)) if (GetMethodInfo(methodInst, NULL, &explicitInsertStr, true, true))
{ {
explicitInsertStr += "\b"; explicitInsertStr += "\b";
wantsBreak = true; wantsBreak = true;
} }
} }
if (insertPos != -1)
mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Implement interface '%s'\tusing|%s|%d|%s", {
mModule->TypeToString(ifaceInst).c_str(), parser->mFileName.c_str(), insertPos, insertStr.c_str()).c_str())); mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Implement interface '%s'\tusing|%s|%s",
mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Implement interface '%s' explicitly\tusing|%s|%d|%s", mModule->TypeToString(ifaceInst).c_str(), FixitGetLocation(parser, insertPos).c_str(), insertStr.c_str()).c_str()));
mModule->TypeToString(ifaceInst).c_str(), parser->mFileName.c_str(), insertPos, explicitInsertStr.c_str()).c_str())); mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Implement interface '%s' explicitly\tusing|%s|%s",
mModule->TypeToString(ifaceInst).c_str(), FixitGetLocation(parser, insertPos).c_str(), explicitInsertStr.c_str()).c_str()));
}
} }
} }
}
if ((!typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedTypeVariation()) && (!typeInstance->IsBoxed()))
{
if (!typeInstance->mTypeDef->mIsAbstract)
{
Array<BfMethodInstance*> missingMethods;
for (int methodIdx = 0; methodIdx < (int)typeInstance->mVirtualMethodTable.size(); methodIdx++)
{
auto& methodRef = typeInstance->mVirtualMethodTable[methodIdx].mImplementingMethod;
if (methodRef.mMethodNum == -1)
{
BF_ASSERT(mCompiler->mOptions.mHasVDataExtender);
if (methodRef.mTypeInstance == typeInstance)
{
if (typeInstance->GetImplBaseType() != NULL)
BF_ASSERT(methodIdx == (int)typeInstance->GetImplBaseType()->mVirtualMethodTableSize);
}
continue;
}
auto methodInstance = (BfMethodInstance*)methodRef;
if ((methodInstance != NULL) && (methodInstance->mMethodDef->mIsAbstract))
{
if (methodInstance->mMethodDef->mIsAbstract)
{
if (!typeInstance->IsUnspecializedTypeVariation())
missingMethods.Add(methodInstance);
}
}
}
if (!missingMethods.IsEmpty())
{
auto declTypeDef = typeInstance->mTypeDef;
BfParserData* parser = declTypeDef->mTypeDeclaration->GetSourceData()->ToParserData();
if (parser != NULL)
{
int insertPos = FixitGetMemberInsertPos(declTypeDef);
bool wantsBreak = false;
String insertStr = "\f";
for (auto methodInst : missingMethods)
{
if (wantsBreak)
{
insertStr += "\r\r";
wantsBreak = false;
}
if (GetMethodInfo(methodInst, NULL, &insertStr, true, false))
{
insertStr += "\b";
wantsBreak = true;
}
}
if (insertPos != -1)
{
mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Implement abstract methods\tmethod|%s|%s",
FixitGetLocation(parser, insertPos).c_str(), insertStr.c_str()).c_str()));
}
}
}
}
} }
} }
@ -2644,7 +2719,8 @@ void BfAutoComplete::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType,
} }
} }
AddEntry(AutoCompleteEntry("fixit", StrFormat("Create field '%s' in '%s'\taddField|%s|%d||%s", fieldName.c_str(), fullName.c_str(), parser->mFileName.c_str(), fileLoc, fieldStr.c_str()).c_str())); AddEntry(AutoCompleteEntry("fixit", StrFormat("Create field '%s' in '%s'\taddField|%s||%s", fieldName.c_str(), fullName.c_str(),
FixitGetLocation(parser->mParserData, fileLoc).c_str(), fieldStr.c_str()).c_str()));
} }
void BfAutoComplete::FixitAddCase(BfTypeInstance* typeInst, const StringImpl& caseName, const BfTypeVector& fieldTypes) void BfAutoComplete::FixitAddCase(BfTypeInstance* typeInst, const StringImpl& caseName, const BfTypeVector& fieldTypes)
@ -2728,7 +2804,8 @@ void BfAutoComplete::FixitAddCase(BfTypeInstance* typeInst, const StringImpl& ca
fieldStr += ";"; fieldStr += ";";
} }
AddEntry(AutoCompleteEntry("fixit", StrFormat("Create case '%s' in '%s'\taddField|%s|%d|%s", caseName.c_str(), fullName.c_str(), parser->mFileName.c_str(), fileLoc, fieldStr.c_str()).c_str())); AddEntry(AutoCompleteEntry("fixit", StrFormat("Create case '%s' in '%s'\taddField|%s|%s", caseName.c_str(), fullName.c_str(),
FixitGetLocation(parser->mParserData, fileLoc).c_str(), fieldStr.c_str()).c_str()));
} }
void BfAutoComplete::FixitGetParamString(const BfTypeVector& paramTypes, StringImpl& outStr) void BfAutoComplete::FixitGetParamString(const BfTypeVector& paramTypes, StringImpl& outStr)
@ -2772,7 +2849,16 @@ void BfAutoComplete::FixitGetParamString(const BfTypeVector& paramTypes, StringI
if (isOut) if (isOut)
checkName = "out" + checkName; checkName = "out" + checkName;
else if (isupper(checkName[0])) else if (isupper(checkName[0]))
{
checkName[0] = tolower(checkName[0]); checkName[0] = tolower(checkName[0]);
for (int i = 1; i < (int)checkName.length(); i++)
{
if ((i + 1 < (int)checkName.length()) &&
(islower(checkName[i + 1])))
break;
checkName[i] = tolower(checkName[i]);
}
}
if (isArr) if (isArr)
checkName += "Arr"; checkName += "Arr";
break; break;
@ -2803,6 +2889,14 @@ void BfAutoComplete::FixitGetParamString(const BfTypeVector& paramTypes, StringI
} }
} }
String BfAutoComplete::FixitGetLocation(BfParserData* parser, int insertPos)
{
int line = 0;
int lineChar = 0;
parser->GetLineCharAtIdx(insertPos, line, lineChar);
return StrFormat("%s|%d:%d", parser->mFileName.c_str(), line, lineChar);
}
void BfAutoComplete::FixitAddMethod(BfTypeInstance* typeInst, const StringImpl& methodName, BfType* returnType, const BfTypeVector& paramTypes, bool wantStatic) void BfAutoComplete::FixitAddMethod(BfTypeInstance* typeInst, const StringImpl& methodName, BfType* returnType, const BfTypeVector& paramTypes, bool wantStatic)
{ {
if ((typeInst->IsEnum()) && (returnType == typeInst) && (wantStatic)) if ((typeInst->IsEnum()) && (returnType == typeInst) && (wantStatic))
@ -2819,6 +2913,8 @@ void BfAutoComplete::FixitAddMethod(BfTypeInstance* typeInst, const StringImpl&
String fullName = typeInst->mTypeDef->mFullName.ToString(); String fullName = typeInst->mTypeDef->mFullName.ToString();
String methodStr; String methodStr;
methodStr += "\f\a";
if (typeInst == mModule->mCurTypeInstance) if (typeInst == mModule->mCurTypeInstance)
{ {
// Implicitly private // Implicitly private
@ -2844,12 +2940,40 @@ void BfAutoComplete::FixitAddMethod(BfTypeInstance* typeInst, const StringImpl&
FixitGetParamString(paramTypes, methodStr); FixitGetParamString(paramTypes, methodStr);
int fileLoc = typeInst->mTypeDef->mTypeDeclaration->GetSrcEnd(); int insertPos = FixitGetMemberInsertPos(typeInst->mTypeDef);
if (auto defineBlock = BfNodeDynCast<BfBlock>(typeInst->mTypeDef->mTypeDeclaration->mDefineNode))
fileLoc = defineBlock->mCloseBrace->GetSrcStart();
methodStr += ")"; methodStr += ")";
AddEntry(AutoCompleteEntry("fixit", StrFormat("Create method '%s' in '%s'\taddMethod|%s|%d|||%s|{||}", methodName.c_str(), fullName.c_str(), parser->mFileName.c_str(), fileLoc, methodStr.c_str()).c_str())); methodStr += "\t";
AddEntry(AutoCompleteEntry("fixit", StrFormat("Create method '%s' in '%s'\taddMethod|%s|%s", methodName.c_str(), fullName.c_str(), FixitGetLocation(parser->mParserData, insertPos).c_str(), methodStr.c_str()).c_str()));
} }
} }
} }
void BfAutoComplete::FixitCheckNamespace(BfTypeDef* activeTypeDef, BfTypeReference* typeRef, BfTokenNode* nextDotToken)
{
if (nextDotToken == NULL)
return;
auto parserData = typeRef->GetParserData();
BfSizedAtomComposite namespaceComposite;
String namespaceString = typeRef->ToString();
bool isValid = mSystem->ParseAtomComposite(namespaceString, namespaceComposite);
bool hasNamespace = false;
if (activeTypeDef != NULL)
hasNamespace = activeTypeDef->mNamespaceSearch.Contains(namespaceComposite);
if (hasNamespace)
{
AddEntry(AutoCompleteEntry("fixit", StrFormat("Remove unneeded '%s'\taddMethod|%s-%d|", typeRef->ToString().c_str(),
FixitGetLocation(parserData, typeRef->GetSrcStart()).c_str(), nextDotToken->GetSrcEnd() - typeRef->GetSrcStart()).c_str()));
}
else
{
BfUsingFinder usingFinder;
usingFinder.VisitMembers(typeRef->GetSourceData()->mRootNode);
mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("using %s;\tusing|%s|%d||using %s;", namespaceString.c_str(), parserData->mFileName.c_str(),
usingFinder.mLastIdx, namespaceString.c_str()).c_str()));
}
}

View file

@ -218,8 +218,10 @@ public:
void UpdateReplaceData(); void UpdateReplaceData();
void AddTypeInstanceEntry(BfTypeInstance* typeInst); void AddTypeInstanceEntry(BfTypeInstance* typeInst);
void CheckDocumentation(AutoCompleteEntry* entry, BfCommentNode* documentation); void CheckDocumentation(AutoCompleteEntry* entry, BfCommentNode* documentation);
bool GetMethodInfo(BfMethodInstance* methodInst, StringImpl* methodName, StringImpl* insertString, bool isExplicitInterface); bool GetMethodInfo(BfMethodInstance* methodInst, StringImpl* methodName, StringImpl* insertString, bool isImplementing, bool isExplicitInterface);
void FixitGetParamString(const BfTypeVector& paramTypes, StringImpl& outStr); void FixitGetParamString(const BfTypeVector& paramTypes, StringImpl& outStr);
int FixitGetMemberInsertPos(BfTypeDef* typeDef);
String FixitGetLocation(BfParserData* parserData, int insertPos);
public: public:
BfAutoComplete(BfResolveType resolveType = BfResolveType_Autocomplete); BfAutoComplete(BfResolveType resolveType = BfResolveType_Autocomplete);
@ -247,12 +249,12 @@ public:
void CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode = NULL); void CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode = NULL);
void CheckEmptyStart(BfAstNode* prevNode, BfType* type); void CheckEmptyStart(BfAstNode* prevNode, BfType* type);
bool CheckFixit(BfAstNode* node); bool CheckFixit(BfAstNode* node);
void ChcekInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode* node); void CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode* node);
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic, BfTypeInstance* referencedFrom); void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic, BfTypeInstance* referencedFrom);
void FixitAddCase(BfTypeInstance * typeInst, const StringImpl & caseName, const BfTypeVector & fieldTypes); void FixitAddCase(BfTypeInstance * typeInst, const StringImpl & caseName, const BfTypeVector & fieldTypes);
void FixitAddMethod(BfTypeInstance* typeInst, const StringImpl& methodName, BfType* returnType, const BfTypeVector& paramTypes, bool wantStatic); void FixitAddMethod(BfTypeInstance* typeInst, const StringImpl& methodName, BfType* returnType, const BfTypeVector& paramTypes, bool wantStatic);
void FixitCheckNamespace(BfTypeDef* activeTypeDef, BfTypeReference* typeRef, BfTokenNode* nextDotToken);
}; };
NS_BF_END NS_BF_END

View file

@ -3768,7 +3768,7 @@ void BfCompiler::ProcessAutocompleteTempType()
autoComplete->mInsertEndIdx = nameNode->GetSrcEnd(); autoComplete->mInsertEndIdx = nameNode->GetSrcEnd();
} }
} }
autoComplete->ChcekInterfaceFixit(typeInst, tempTypeDef->mTypeDeclaration->mNameNode); autoComplete->CheckInterfaceFixit(typeInst, tempTypeDef->mTypeDeclaration->mNameNode);
if (tempTypeDef->mTypeCode == BfTypeCode_TypeAlias) if (tempTypeDef->mTypeCode == BfTypeCode_TypeAlias)
{ {

View file

@ -5632,6 +5632,11 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
{ {
if (mCompiler->mIsResolveOnly) if (mCompiler->mIsResolveOnly)
{ {
bool isGetDefinition = false;
BfAutoComplete* autoComplete = NULL;
if (mCompiler->IsAutocomplete())
autoComplete = mCompiler->mResolvePassData->mAutoComplete;
BfSourceData* typeRefSource = NULL; BfSourceData* typeRefSource = NULL;
if (typeRef->IsTemporary()) if (typeRef->IsTemporary())
{ {
@ -5680,7 +5685,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
{ {
StringView leftString = qualifiedTypeRef->mLeft->ToStringView(); StringView leftString = qualifiedTypeRef->mLeft->ToStringView();
BfSizedAtomComposite leftComposite; BfSizedAtomComposite leftComposite;
bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite); bool isValid = mSystem->ParseAtomComposite(leftString, leftComposite);
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedTypeRef->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef); mCompiler->mResolvePassData->mSourceClassifier->SetElementType(qualifiedTypeRef->mRight, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef);
if (resolvedTypeInstance == NULL) if (resolvedTypeInstance == NULL)
{ {
@ -5688,7 +5693,11 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
isNamespace = true; isNamespace = true;
} }
else if ((isValid) && (resolvedTypeInstance->mTypeDef->mNamespace.EndsWith(leftComposite))) else if ((isValid) && (resolvedTypeInstance->mTypeDef->mNamespace.EndsWith(leftComposite)))
{
if ((autoComplete != NULL) && (autoComplete->CheckFixit(typeRef)))
autoComplete->FixitCheckNamespace(GetActiveTypeDef(), qualifiedTypeRef->mLeft, qualifiedTypeRef->mDot);
isNamespace = true; isNamespace = true;
}
checkTypeRef = qualifiedTypeRef->mLeft; checkTypeRef = qualifiedTypeRef->mLeft;
} }
@ -5714,11 +5723,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
mCompiler->mResolvePassData->mSourceClassifier->SetElementType(checkNameNode, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef); mCompiler->mResolvePassData->mSourceClassifier->SetElementType(checkNameNode, isNamespace ? BfSourceElementType_Namespace : BfSourceElementType_TypeRef);
} }
} }
bool isGetDefinition = false;
BfAutoComplete* autoComplete = NULL;
if (mCompiler->IsAutocomplete())
autoComplete = mCompiler->mResolvePassData->mAutoComplete;
if (autoComplete != NULL) if (autoComplete != NULL)
{ {
isGetDefinition = autoComplete->mIsGetDefinition; isGetDefinition = autoComplete->mIsGetDefinition;

View file

@ -503,7 +503,11 @@ BfImportKind BfMethodInstance::GetImportKind()
return mMethodDef->mImportKind; return mMethodDef->mImportKind;
auto module = GetOwner()->mModule; auto module = GetOwner()->mModule;
BfCustomAttribute* customAttribute = GetCustomAttributes()->Get(module->mCompiler->mImportAttributeTypeDef); auto customAttributes = GetCustomAttributes();
if (customAttributes == NULL)
return BfImportKind_None;
BfCustomAttribute* customAttribute = customAttributes->Get(module->mCompiler->mImportAttributeTypeDef);
if (customAttribute == NULL) if (customAttribute == NULL)
return BfImportKind_Import_Static; return BfImportKind_Import_Static;