Делаю игровой движок, при попытке компиляции файлика Interpolators вылетает:
() : Внутренняя ошибка компилятора в модуле [pabcnetc.exe] :'System.Exception: System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
в SyntaxVisitors.CollectClassFieldsVisitor.visit(class_definition cd)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.DefaultVisit(syntax_tree_node n)
в SyntaxVisitors.ProcessYieldCapturedVarsVisitor.CollectClassFieldsNames(procedure_definition pd, ISet1 collectedFields) в SyntaxVisitors.ProcessYieldCapturedVarsVisitor.ReplaceCapturedVariables(procedure_definition pd, IEnumerable
1 deletedLocals, IDictionary2& capturedLocalsNamesMap, IDictionary
2& capturedFormalParamsNamesMap)
в SyntaxVisitors.ProcessYieldCapturedVarsVisitor.visit(procedure_definition pd)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.BaseChangeVisitor.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.BaseChangeVisitor.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.BaseChangeVisitor.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.BaseChangeVisitor.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.BaseChangeVisitor.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.BaseChangeVisitor.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.BaseChangeVisitor.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTree.BaseChangeVisitor.DefaultVisit(syntax_tree_node n)
в PascalABCCompiler.SyntaxTree.WalkingVisitorNew.ProcessNode(syntax_tree_node Node)
в PascalABCCompiler.SyntaxTreeConverters.StandardSyntaxTreeConverter.Convert(syntax_tree_node root)
в PascalABCCompiler.SyntaxTreeConverters.SyntaxTreeConvertersController.Convert(syntax_tree_node root)
в PascalABCCompiler.Compiler.CompileUnit(unit_node_list Units, unit_or_namespace SyntaxUsesUnit)
в PascalABCCompiler.Compiler.Compile()
Движок.rar (2,4 МБ)
Описание и реализация класса в разных type
сейчас запрещена:
type
t1 = class;//Ошибка: Отсутствует описание типа t1
type
t1 = class
end;
begin end.
Конечно, компилятор ломаться не должен, но тут ваша ошибка, TInterpolator
описан и реализован в разных type
.
1 лайк
Поместил в одну секцию type:
Ах вот как… Что ж issue
исправил… В общем не обязательно в разных type
, главное чтоб у касса было пред описание. В общем попытайтесь без пред описания обойтись… Может сделать пред описание другому классу. Совета получше, я, пожалуй, не придумаю… Можно ещё конечно теперь ждать фикса, но это идея хуже…
В классе TModifier должны быть ссылки на TInterpolator, что без предописания сделать никак. Тем более TInterpolator использует TModifier.
Но можно ведь сделать наоборот, от того что сейчас. Сейчас так:
[пред описание TInterpolator]
[описание TModifier]
[описание TInterpolator]
Значит можно сделать так:
[пред описание TModifier]
[описание TInterpolator]
[описание TModifier]
А вообще лучше обычно делать пред описания всем классам, чтоб можно было реализовывать их в любом порядке, не зависимо от того в какой какой используется (ну, кроме наследования, там пред описание не пройдёт)
1 лайк
А вообще есть 1 способ… Вам нужно именно yield
или может список подойдёт? Отличия:
function GetList:List<byte>;
begin
writeln('Создаю список');
Result := new List<byte>;//кстати можно сразу ещё и размер указать
Result.Add(0);
Result.Add(1);
Result.Add(2);
end;
function GetSequence:sequence of byte;
begin
writeln('Создаю последовательность');
yield 0;
yield 1;
yield 2;
end;
begin
var l := GetList;//"Создаю список" выведет тут
var s := GetSequence;
writeln(l);
writeln(l);
writeln(s);//"Создаю последовательность" выведет тут, а не там где была вызвана функция GetSequence
writeln(s);//и тут ещё раз
end.
Когда речь заходит про sequence.ToArray
(и ему подобных) - создаётся пустой массив и в него добавляются элементы по тому же алгоритму что и в List.Add
.
А точнее
Создаётся пустой массив на 4 элемента, эти 4 элемента заполняет, если места не хватило - создаёт массив на 8 элементов, копирует в него элементы из предыдущего и продолжает. Если снова не хватило - снова создаёт в 2 раза больший массив и т.д. В самом конце (если вызвано как раз ToArray
а не ToList
) создаёт массив, по размеру совпадающий с количеством элементов и копирует в него элементы из последнего, типо отрезает лишнее.
Зато когда речь идёт о, к примеру, foreach
- он не создаёт готовый массив, вместо этого он берёт по 1 значению, что то выполняет над ним, и удаляет. Ну и extensionmethod
-ы типа TakeWhile
не создают массив.
1 лайк
В последней версии не компилируется также…
А классы наследники TModifier тоже должны иметь предописание?
Не представляю как в вашей программе, но как я и сказал, это желательно, чтоб не важно было в каком порядке делать нормальное описание классов.
Сделал так, но я не могу использовать свойства объекта TModifier, так как его описание ниже TInterpolator.
Реализуйте функции использующие свойства TModifier
- после его описания. Удобно сделать что то типа:
{$region TInterpolator}
//тут реализовывать методы TInterpolator
{$endregion TInterpolator}
В самом низу файла. Я лично делаю так для всех методов больших классов, чтоб, опять же, можно было не волноваться в каком порядке построены описания.
1 лайк
Для разных классов свои регионы?
Ну да. Если надо ещё под регионы можно делать. К примеру если класс очень большой - можно его описание и регион реализации методов разделить ещё несколькими регионами.
1 лайк
Что это за ошибка и почему она возникает:
Interpolators.pas(403) : SYNTAXTREEVISITORSERROR_Possible extension-method definintion without extensionmethod keyword. Please use extensionmethod syntax
?
Engine 5.2.5.rar (2,6 МБ)
Мда, конечно хорошо видно что yield
не очень много использовали)) Иначе такие примитивные ошибки давно нашли бы…
interface-implementation
в данном случае имеет только эстетический вид (в implementation
можно добавить переменные, подпрограммы и типы, сделав их этим приватными, а раз у вас их нет - оно и не нужно), поэтому пока ошибку не исправят - уберите их.
1 лайк
Да, тут больше эстетика - во всех более менее больших или средних размеров модулях я использую interface-implementation. Баг, к счастью, выявился не в день сдачи проекта.