Сделать l3Items_NoClear.
И возможно сделать l3Items_NoDelete etc.
Чтобы список мог ТОЛЬКО ПОПОЛНЯТЬСЯ, но не уменьшаться.
Такой ImmutableAddOnDemand что ли.
----
Сделать Dictionary.UseDictionary(Dictionary) и вызывать его в CloseDictionary.
Ну чтобы "веером" не искать в словарях, а копировать к СЕБЕ все УЖЕ ОПРЕДЕЛЁННЫЕ слова.
Ну и..
Проверять ЦИКЛИЧЕСКИЕ связи. Возможно понадобится метод UsesDictionary: Boolean.
Возможно - НЕ ПОНАДОБИТСЯ. Потому что копируем ДО "циклического" USES с проверкой IndexOf.
----
Разобраться с необходимостью Dictionary Prim, PrimPrim, PrimPrimPrim.
----
Перенести ParentFinder с Il3Finder на ItfwFinder.
----
Убрать всю красоту с '$' под IfDef NewGen, а потом и вообще ИЗЖИТЬ. Аналогично с %CHILDREN
procedure TtfwNewWord.BeforeCompile(const aPrevContext: TtfwContext;
var theNewContext: TtfwContext);
//#UC START# *4DB6CDDA038B_4DB9B6D20168_var*
function locName : AnsiString;
begin//locName
if (Self.Key <> nil) then
Result := Self.Key.AsString
else
Result := '';
end;//locName
var
l_N : Il3CString;
l_W : TtfwKeyWord;
l_Stereotype : AnsiString;
l_Stereotype2 : AnsiString;
l_C : ItfwNewWordDefinitor;
l_CanBeMerged : Boolean;
l_TI : TtfwTypeInfo;
//#UC END# *4DB6CDDA038B_4DB9B6D20168_var*
begin
//#UC START# *4DB6CDDA038B_4DB9B6D20168_impl*
inherited;
l_N := GetNewWordName(aPrevContext);
if (aPrevContext.rCompiler = nil) then
l_C := aPrevContext.rEngine.As_ItfwNewWordDefinitor
else
l_C := aPrevContext.rCompiler.NewWordDefinitor;
l_W := l_C.CheckWord(l_N);
l_CanBeMerged := false;
if (l_W.Word <> nil) AND not l_W.Word.IsForwardDeclaration then
begin
l_Stereotype := locName;
CompilerAssertFmt(l_Stereotype <> '',
'Не задан стереотип у дублирующегося элемента %s: %s (%s)',
[
l_W.AsString,
l_W.Word.ClassName,
l_W.ClassName
],
aPrevContext);
if (l_W.Word.WordProducer <> nil) then
begin
l_StereoType2 := l_W.Word.WordProducer.Key.AsString;
if (l_Stereotype = l_StereoType2) then
begin
l_TI := l_W.Word.ResultTypeInfo[theNewContext];
if (tfw_wmCanBeMerged in l_TI.Modifiers) then
l_CanBeMerged := true
else
CompilerAssertFmt(false,
'Совпадают стереотипы %s и %s', [l_Stereotype, l_StereoType2],
aPrevContext);
end;//l_Stereotype = l_StereoType2
end;//l_W.Word.WordProducer
// - хорошая проверка, но для hResult и HResult - не работает !!!
if l_CanBeMerged then
begin
l_W.Word.SetRefTo(theNewContext.rWordCompilingNow);
// - подменяем текущее компилируемое слово
theNewContext.rCompiler := theNewContext.rWordCompilingNow.GetCompiler(aPrevContext);
// - подменяем компилятор
end//tfw_wmCanBeMerged in l_W.Word.Modifiers
else
begin
l_N := l3Cat(l_N, '$' + l_Stereotype);
// - прибавляем имя стереотипа к имени элемента и таким образом пытаемся разрешить коллизию
// это для того, чтобы нормально разобрать то, что вылили из Розы
l_W := l_C.CheckWord(l_N);
end;//tfw_wmCanBeMerged in l_W.Word.Modifiers
end;//l_W.Word <> nil
theNewContext.rKeyWordCompilingNow := l_W;
theNewContext.rKeyWordDefiningNow := l_W;
theNewContext.rWordDefiningNow := theNewContext.rWordCompilingNow;
if not l_CanBeMerged then
begin
if (l_W.Word <> nil) then
begin
if l_W.Word.IsForwardDeclaration then
begin
if (TkwForwardDeclaration(l_W.Word).RealWord <> nil) then
CompilerAssertFmt(false,
'Предварительное определение слова %s: %s/%s (%s) уже было завершено',
[
l_W.AsString,
l_W.Word.ClassName,
TkwForwardDeclaration(l_W.Word).RealWord.ClassName,
l_W.ClassName
],
aPrevContext)
end//l_W.Word.IsForwardDeclaration
else
CompilerAssertFmt(false,
'Слово %s: %s (%s) уже есть в словаре',
[
l_W.AsString,
l_W.Word.ClassName,
l_W.ClassName
],
aPrevContext);
end;//l_W.Word <> nil
end;//l_CanBeMerged
//#UC END# *4DB6CDDA038B_4DB9B6D20168_impl*
end;//TtfwNewWord.BeforeCompile
И проверить - надо ли кому-нибудь Includes, а не %Includes.
И возможно сделать l3Items_NoDelete etc.
Чтобы список мог ТОЛЬКО ПОПОЛНЯТЬСЯ, но не уменьшаться.
Такой ImmutableAddOnDemand что ли.
----
Сделать Dictionary.UseDictionary(Dictionary) и вызывать его в CloseDictionary.
Ну чтобы "веером" не искать в словарях, а копировать к СЕБЕ все УЖЕ ОПРЕДЕЛЁННЫЕ слова.
Ну и..
Проверять ЦИКЛИЧЕСКИЕ связи. Возможно понадобится метод UsesDictionary: Boolean.
Возможно - НЕ ПОНАДОБИТСЯ. Потому что копируем ДО "циклического" USES с проверкой IndexOf.
----
Разобраться с необходимостью Dictionary Prim, PrimPrim, PrimPrimPrim.
----
Перенести ParentFinder с Il3Finder на ItfwFinder.
----
Убрать всю красоту с '$' под IfDef NewGen, а потом и вообще ИЗЖИТЬ. Аналогично с %CHILDREN
procedure TtfwNewWord.BeforeCompile(const aPrevContext: TtfwContext;
var theNewContext: TtfwContext);
//#UC START# *4DB6CDDA038B_4DB9B6D20168_var*
function locName : AnsiString;
begin//locName
if (Self.Key <> nil) then
Result := Self.Key.AsString
else
Result := '';
end;//locName
var
l_N : Il3CString;
l_W : TtfwKeyWord;
l_Stereotype : AnsiString;
l_Stereotype2 : AnsiString;
l_C : ItfwNewWordDefinitor;
l_CanBeMerged : Boolean;
l_TI : TtfwTypeInfo;
//#UC END# *4DB6CDDA038B_4DB9B6D20168_var*
begin
//#UC START# *4DB6CDDA038B_4DB9B6D20168_impl*
inherited;
l_N := GetNewWordName(aPrevContext);
if (aPrevContext.rCompiler = nil) then
l_C := aPrevContext.rEngine.As_ItfwNewWordDefinitor
else
l_C := aPrevContext.rCompiler.NewWordDefinitor;
l_W := l_C.CheckWord(l_N);
l_CanBeMerged := false;
if (l_W.Word <> nil) AND not l_W.Word.IsForwardDeclaration then
begin
l_Stereotype := locName;
CompilerAssertFmt(l_Stereotype <> '',
'Не задан стереотип у дублирующегося элемента %s: %s (%s)',
[
l_W.AsString,
l_W.Word.ClassName,
l_W.ClassName
],
aPrevContext);
if (l_W.Word.WordProducer <> nil) then
begin
l_StereoType2 := l_W.Word.WordProducer.Key.AsString;
if (l_Stereotype = l_StereoType2) then
begin
l_TI := l_W.Word.ResultTypeInfo[theNewContext];
if (tfw_wmCanBeMerged in l_TI.Modifiers) then
l_CanBeMerged := true
else
CompilerAssertFmt(false,
'Совпадают стереотипы %s и %s', [l_Stereotype, l_StereoType2],
aPrevContext);
end;//l_Stereotype = l_StereoType2
end;//l_W.Word.WordProducer
// - хорошая проверка, но для hResult и HResult - не работает !!!
if l_CanBeMerged then
begin
l_W.Word.SetRefTo(theNewContext.rWordCompilingNow);
// - подменяем текущее компилируемое слово
theNewContext.rCompiler := theNewContext.rWordCompilingNow.GetCompiler(aPrevContext);
// - подменяем компилятор
end//tfw_wmCanBeMerged in l_W.Word.Modifiers
else
begin
l_N := l3Cat(l_N, '$' + l_Stereotype);
// - прибавляем имя стереотипа к имени элемента и таким образом пытаемся разрешить коллизию
// это для того, чтобы нормально разобрать то, что вылили из Розы
l_W := l_C.CheckWord(l_N);
end;//tfw_wmCanBeMerged in l_W.Word.Modifiers
end;//l_W.Word <> nil
theNewContext.rKeyWordCompilingNow := l_W;
theNewContext.rKeyWordDefiningNow := l_W;
theNewContext.rWordDefiningNow := theNewContext.rWordCompilingNow;
if not l_CanBeMerged then
begin
if (l_W.Word <> nil) then
begin
if l_W.Word.IsForwardDeclaration then
begin
if (TkwForwardDeclaration(l_W.Word).RealWord <> nil) then
CompilerAssertFmt(false,
'Предварительное определение слова %s: %s/%s (%s) уже было завершено',
[
l_W.AsString,
l_W.Word.ClassName,
TkwForwardDeclaration(l_W.Word).RealWord.ClassName,
l_W.ClassName
],
aPrevContext)
end//l_W.Word.IsForwardDeclaration
else
CompilerAssertFmt(false,
'Слово %s: %s (%s) уже есть в словаре',
[
l_W.AsString,
l_W.Word.ClassName,
l_W.ClassName
],
aPrevContext);
end;//l_W.Word <> nil
end;//l_CanBeMerged
//#UC END# *4DB6CDDA038B_4DB9B6D20168_impl*
end;//TtfwNewWord.BeforeCompile
И проверить - надо ли кому-нибудь Includes, а не %Includes.
Комментариев нет:
Отправить комментарий