Skip to content

Commit ab1cfd0

Browse files
committed
Editor: fixes for showing autocomplete list for array elements
This includes multi-dimensional arrays parsing. Although old compiler does not support multi-dimensional arrays, but it's good to keep autocomplete parsing consistent between editor branches.
1 parent ead4f2c commit ab1cfd0

File tree

1 file changed

+63
-24
lines changed

1 file changed

+63
-24
lines changed

Editor/AGS.Editor/Panes/ScintillaWrapper.cs

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,21 @@ private ScriptStruct FindGlobalType(string type)
15401540
return null;
15411541
}
15421542

1543+
private ScriptVariable FindGlobalVariableWithName(string name)
1544+
{
1545+
foreach (IScript script in GetAutoCompleteScriptList())
1546+
{
1547+
foreach (ScriptVariable varDef in script.AutoCompleteData.Variables)
1548+
{
1549+
if (varDef.VariableName == name)
1550+
{
1551+
return varDef;
1552+
}
1553+
}
1554+
}
1555+
return null;
1556+
}
1557+
15431558
private ScriptStruct FindGlobalVariableOrType(string type, out bool staticAccess)
15441559
{
15451560
// First try search for a type that has this name
@@ -1551,34 +1566,34 @@ private ScriptStruct FindGlobalVariableOrType(string type, out bool staticAccess
15511566
}
15521567

15531568
// Then, search for a variable that has this name, and try retrieving its type
1554-
foreach (IScript script in GetAutoCompleteScriptList())
1569+
staticAccess = false;
1570+
ScriptVariable var = FindGlobalVariableWithName(type);
1571+
if (var != null)
15551572
{
1556-
foreach (ScriptVariable varDef in script.AutoCompleteData.Variables)
1557-
{
1558-
if (varDef.VariableName == type)
1559-
{
1560-
staticAccess = false;
1561-
return FindGlobalType(varDef.Type);
1562-
}
1563-
}
1573+
return FindGlobalType(var.Type);
15641574
}
1565-
1566-
staticAccess = false;
15671575
return null;
15681576
}
15691577

1570-
private string ReadNextWord(ref string pathedExpression, out bool indexedAccess)
1578+
// FIXME: this function basically parses a variable access, idk why it's called ReadNextWord
1579+
private string ReadNextWord(ref string pathedExpression, out bool indexedAccess, out int dimAccess)
15711580
{
15721581
string thisWord = string.Empty;
15731582
indexedAccess = false;
1583+
dimAccess = 0;
15741584
while ((pathedExpression.Length > 0) &&
1575-
((Char.IsLetterOrDigit(pathedExpression[0])) || (pathedExpression[0] == '_')))
1585+
pathedExpression[0].IsScriptWordChar())
15761586
{
15771587
thisWord += pathedExpression[0];
15781588
pathedExpression = pathedExpression.Substring(1);
15791589
}
1580-
if ((pathedExpression.Length > 0) && (pathedExpression[0] == '['))
1590+
pathedExpression = pathedExpression.TrimStart();
1591+
// TODO: this ugly code parses multi-dimensional array access;
1592+
// probably could be merged with similar parsing in autocomplete?
1593+
while (pathedExpression.Length > 0 && (pathedExpression[0] == '['))
15811594
{
1595+
indexedAccess = true;
1596+
dimAccess++;
15821597
int bracketDepth = 1;
15831598
int cursorPos = 1;
15841599
while ((bracketDepth > 0) && (cursorPos < pathedExpression.Length))
@@ -1589,7 +1604,7 @@ private string ReadNextWord(ref string pathedExpression, out bool indexedAccess)
15891604
cursorPos++;
15901605
}
15911606
pathedExpression = pathedExpression.Substring(cursorPos);
1592-
indexedAccess = true;
1607+
pathedExpression = pathedExpression.TrimStart();
15931608
}
15941609
if ((pathedExpression.Length > 0) && (pathedExpression[0] == '.'))
15951610
{
@@ -1665,8 +1680,9 @@ private ScriptStruct ParsePreviousExpression(int startAtPos, out string characte
16651680
}
16661681

16671682
bool indexedAccess = false;
1683+
int dimAccess = 0;
16681684
staticAccess = false;
1669-
string thisWord = ReadNextWord(ref pathedExpression, out indexedAccess);
1685+
string thisWord = ReadNextWord(ref pathedExpression, out indexedAccess, out dimAccess);
16701686
ScriptStruct foundType;
16711687

16721688
if (thisWord == THIS_STRUCT)
@@ -1679,27 +1695,42 @@ private ScriptStruct ParsePreviousExpression(int startAtPos, out string characte
16791695
}
16801696
else
16811697
{
1682-
foundType = FindGlobalVariableOrType(thisWord, out staticAccess);
1683-
if (staticAccess && indexedAccess)
1684-
return null; // element access of type? bad syntax...
1698+
// First try search for a type that has this name
1699+
foundType = FindGlobalType(thisWord);
1700+
if (foundType != null)
1701+
{
1702+
if (indexedAccess)
1703+
return null; // element access of type? bad syntax...
1704+
staticAccess = true;
1705+
}
1706+
else
1707+
{
1708+
// Then lookup for a global variable of this name
1709+
ScriptVariable var = FindGlobalVariableWithName(thisWord);
1710+
if (var != null)
1711+
{
1712+
foundType = ProcessVariableAccess(var, indexedAccess, dimAccess);
1713+
}
1714+
}
16851715

1716+
// Not a type or global variable? try if that's a local variable
16861717
if ((foundType == null) && (thisWord.Length > 0))
16871718
{
16881719
ScriptVariable var = FindLocalVariableWithName(startAtPos, thisWord);
16891720
if (var != null)
16901721
{
1691-
foundType = ProcessVariableAccess(var, indexedAccess);
1722+
foundType = ProcessVariableAccess(var, indexedAccess, dimAccess);
16921723
}
16931724
}
16941725
}
16951726

16961727
while ((pathedExpression.Length > 0) && (foundType != null))
16971728
{
1698-
thisWord = ReadNextWord(ref pathedExpression, out indexedAccess);
1729+
thisWord = ReadNextWord(ref pathedExpression, out indexedAccess, out dimAccess);
16991730
ScriptVariable memberVar = foundType.FindMemberVariable(thisWord);
17001731
if (memberVar != null)
17011732
{
1702-
foundType = ProcessVariableAccess(memberVar, indexedAccess);
1733+
foundType = ProcessVariableAccess(memberVar, indexedAccess, dimAccess);
17031734
if (foundType == null)
17041735
return null;
17051736
staticAccess = false;
@@ -1712,7 +1743,7 @@ private ScriptStruct ParsePreviousExpression(int startAtPos, out string characte
17121743
return foundType;
17131744
}
17141745

1715-
private ScriptStruct ProcessVariableAccess(ScriptVariable var, bool indexedAccess)
1746+
private ScriptStruct ProcessVariableAccess(ScriptVariable var, bool indexedAccess, int accessDims = 1)
17161747
{
17171748
if (!var.IsArray && indexedAccess)
17181749
return null; // accessing element of non-array, bad syntax...
@@ -1724,8 +1755,16 @@ private ScriptStruct ProcessVariableAccess(ScriptVariable var, bool indexedAcces
17241755
if (foundType == null)
17251756
return null;
17261757

1758+
// Dynamic array variable has a type of T[]; and in case of a
1759+
// indexed access we have to resolve that to the base type,
1760+
// following a number of dimensions.
17271761
if (var.IsDynamicArray && indexedAccess)
1728-
foundType = FindGlobalType(foundType.BaseType);
1762+
{
1763+
for (int i = 0; i < accessDims; ++i)
1764+
{
1765+
foundType = FindGlobalType(foundType.BaseType);
1766+
}
1767+
}
17291768

17301769
return foundType;
17311770
}

0 commit comments

Comments
 (0)