bug fix: can not override virtual methods of abstract class

performance improvements
This commit is contained in:
Бондарев Иван 2015-10-18 13:35:44 +02:00
parent 248da671c3
commit a40483346b
3 changed files with 63 additions and 12 deletions

View file

@ -44,6 +44,21 @@ begin
end; end;
end; end;
TClass7 = abstract class
a: integer;
procedure Test; virtual;
begin
a := 5;
end;
end;
TClass8 = class(TClass7)
procedure Test; override;
begin
a := 3;
end;
end;
var t : TClass; var t : TClass;
t2 : TClass3; t2 : TClass3;
t3 : TClass5; t3 : TClass5;
@ -55,4 +70,7 @@ t2 := new TClass4;
t2.Test2(2.3); t2.Test2(2.3);
t3 := new TClass6; t3 := new TClass6;
t3.Test3; t3.Test3;
var t4 := new TClass8;
t4.Test;
assert(t4.a=3);
end. end.

View file

@ -40,7 +40,7 @@ namespace PascalABCCompiler.TreeConverter
private T AddError<T>(Errors.Error err) private T AddError<T>(Errors.Error err)
{ {
syntax_tree_visitor.AddError(err); syntax_tree_visitor.AddError(err, true);
return default(T); return default(T);
} }
@ -1789,7 +1789,7 @@ namespace PascalABCCompiler.TreeConverter
if (set_of_possible_functions.Count==0 && indefinits.Count == 0) if (set_of_possible_functions.Count==0 && indefinits.Count == 0)
{ {
AddError(new NoFunctionWithSameParametresNum(loc, is_alone_method_defined, first_function)); return AddError<function_node>(new NoFunctionWithSameParametresNum(loc, is_alone_method_defined, first_function));
} }
//(ssyy) Инициализируем is_alone_defined //(ssyy) Инициализируем is_alone_defined
@ -1866,10 +1866,10 @@ namespace PascalABCCompiler.TreeConverter
if (set_of_possible_functions.Count==0 && indefinits.Count == 0) if (set_of_possible_functions.Count==0 && indefinits.Count == 0)
{ {
if (_is_assigment && parameters.Count == 2) if (_is_assigment && parameters.Count == 2)
AddError(new CanNotConvertTypes(parameters[1], parameters[1].type, parameters[0].type, parameters[1].location)); return AddError<function_node>(new CanNotConvertTypes(parameters[1], parameters[1].type, parameters[0].type, parameters[1].location));
if (_tmp_bfn != null && parameters.Count == 2) if (_tmp_bfn != null && parameters.Count == 2)
AddError(new OperatorCanNotBeAppliedToThisTypes(_tmp_bfn.name, parameters[0], parameters[1],loc)); return AddError<function_node>(new OperatorCanNotBeAppliedToThisTypes(_tmp_bfn.name, parameters[0], parameters[1],loc));
AddError(new NoFunctionWithSameArguments(loc,is_alone_method_defined)); return AddError<function_node>(new NoFunctionWithSameArguments(loc,is_alone_method_defined));
} }
bool remove=true; bool remove=true;
@ -2001,9 +2001,8 @@ namespace PascalABCCompiler.TreeConverter
indefinits.AddRange(set_of_possible_functions); indefinits.AddRange(set_of_possible_functions);
return new indefinite_functions_set(indefinits); return new indefinite_functions_set(indefinits);
} }
AddError(new SeveralFunctionsCanBeCalled(loc,set_of_possible_functions)); return AddError<function_node>(new SeveralFunctionsCanBeCalled(loc,set_of_possible_functions));
return null;
} }
private function_node is_exist_eq_return_value_method(function_node fn, function_node_list funcs) private function_node is_exist_eq_return_value_method(function_node fn, function_node_list funcs)

View file

@ -86,9 +86,21 @@ namespace PascalABCCompiler.TreeConverter
return num.ToString(); return num.ToString();
} }
internal void AddError(Errors.Error err) internal Errors.Error LastError()
{ {
if (ThrowCompilationError || err.MustThrow) Errors.Error err = ErrorsList[ErrorsList.Count-1];
ErrorsList.RemoveAt(ErrorsList.Count - 1);
return err;
}
internal void RemoveLastError()
{
ErrorsList.RemoveAt(ErrorsList.Count - 1);
}
internal void AddError(Errors.Error err, bool shouldReturn=false)
{
if (ThrowCompilationError || !shouldReturn /*|| err.MustThrow && !shouldReturn*/)
{ {
throw err; throw err;
} }
@ -5283,10 +5295,32 @@ namespace PascalABCCompiler.TreeConverter
{ {
try try
{ {
ThrowCompilationError = false;
fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
if (fn == null && skip_first_parameter)
{
if (si.Next == null)
{
ThrowCompilationError = true;
throw LastError();
}
RemoveLastError();
skip_first_parameter = false;
si = tmp_si;
exprs.remove_at(0);
fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters);
if (fn == null)
{
ThrowCompilationError = true;
throw LastError();
}
else
RemoveLastError();
}
} }
catch (Exception ex) catch (Exception ex)
{ {
ThrowCompilationError = true;
if (skip_first_parameter) if (skip_first_parameter)
{ {
si = tmp_si; si = tmp_si;
@ -5296,6 +5330,7 @@ namespace PascalABCCompiler.TreeConverter
else else
throw ex; throw ex;
} }
ThrowCompilationError = true;
} }
SemanticTree.IGenericInstance igi = fn as SemanticTree.IGenericInstance; SemanticTree.IGenericInstance igi = fn as SemanticTree.IGenericInstance;
if (igi != null) if (igi != null)
@ -11616,14 +11651,13 @@ namespace PascalABCCompiler.TreeConverter
{ {
AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "USING_MODIFIERS{0}_{1}_TOGETHER_NOT_ALLOWED", cmn,_procedure_attributes_list.proc_attributes[i].name,override_proc_attr); AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "USING_MODIFIERS{0}_{1}_TOGETHER_NOT_ALLOWED", cmn,_procedure_attributes_list.proc_attributes[i].name,override_proc_attr);
} }
if (!context.converted_type.IsAbstract) if (!context.converted_type.IsAbstract || true)
{ {
is_virtual = true; is_virtual = true;
virtual_proc_attr = _procedure_attributes_list.proc_attributes[i].name; virtual_proc_attr = _procedure_attributes_list.proc_attributes[i].name;
if (!is_abstract) if (!is_abstract)
context.set_virtual(cmn); context.set_virtual(cmn);
} }
break; break;
} }
case SyntaxTree.proc_attribute.attr_override: case SyntaxTree.proc_attribute.attr_override: