extensionmethod in units
bug fix: unary operator + caused the internal error new tests in test suite
This commit is contained in:
parent
78ba53dea9
commit
e269115ff1
|
|
@ -6,6 +6,6 @@ namespace PascalABCCompiler.PCU
|
||||||
{
|
{
|
||||||
public static class PCUFileFormatVersion
|
public static class PCUFileFormatVersion
|
||||||
{
|
{
|
||||||
public static System.Int16 Version = 104;
|
public static System.Int16 Version = 105;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -269,11 +269,12 @@ namespace PascalABCCompiler.PCU
|
||||||
}
|
}
|
||||||
cur_doc = new document(SourceFileName);
|
cur_doc = new document(SourceFileName);
|
||||||
|
|
||||||
|
AddNamespaces();
|
||||||
AddInterfaceNames();
|
AddInterfaceNames();
|
||||||
//ssyy
|
//ssyy
|
||||||
AddImplementationNames();
|
AddImplementationNames();
|
||||||
//\ssyy
|
//\ssyy
|
||||||
AddNamespaces();
|
|
||||||
//AddInitFinalMethods();
|
//AddInitFinalMethods();
|
||||||
//ProcessWaitedToRestoreFields();
|
//ProcessWaitedToRestoreFields();
|
||||||
unit.State = UnitState.Compiled;
|
unit.State = UnitState.Compiled;
|
||||||
|
|
@ -475,7 +476,9 @@ namespace PascalABCCompiler.PCU
|
||||||
|
|
||||||
type_node tn = GetSpecialTypeRefernce(names[i].offset);
|
type_node tn = GetSpecialTypeRefernce(names[i].offset);
|
||||||
if (tn is compiled_type_node)
|
if (tn is compiled_type_node)
|
||||||
(tn as compiled_type_node).scope.AddSymbol(names[i].name,si);
|
(tn as compiled_type_node).scope.AddSymbol(names[i].name, si);
|
||||||
|
else if (tn is generic_instance_type_node)
|
||||||
|
tn.Scope.AddSymbol(names[i].name, si);
|
||||||
else if (tn is common_type_node)
|
else if (tn is common_type_node)
|
||||||
(tn as common_type_node).scope.AddSymbol(names[i].name, si);
|
(tn as common_type_node).scope.AddSymbol(names[i].name, si);
|
||||||
else
|
else
|
||||||
|
|
@ -2696,6 +2699,7 @@ namespace PascalABCCompiler.PCU
|
||||||
AddMember(cnfn, offset);
|
AddMember(cnfn, offset);
|
||||||
|
|
||||||
type_node ConnectedToType = null;
|
type_node ConnectedToType = null;
|
||||||
|
br.ReadInt32();
|
||||||
if (CanReadObject())
|
if (CanReadObject())
|
||||||
ConnectedToType = GetTypeReference();
|
ConnectedToType = GetTypeReference();
|
||||||
br.ReadBoolean();//пропускаем флаг - интерфейсности
|
br.ReadBoolean();//пропускаем флаг - интерфейсности
|
||||||
|
|
@ -2758,6 +2762,7 @@ namespace PascalABCCompiler.PCU
|
||||||
int pos = (int)br.BaseStream.Position;
|
int pos = (int)br.BaseStream.Position;
|
||||||
br.BaseStream.Seek(start_pos + offset, SeekOrigin.Begin);
|
br.BaseStream.Seek(start_pos + offset, SeekOrigin.Begin);
|
||||||
br.ReadByte();
|
br.ReadByte();
|
||||||
|
br.ReadInt32();
|
||||||
type_node tn = null;
|
type_node tn = null;
|
||||||
if (CanReadObject())
|
if (CanReadObject())
|
||||||
tn = GetTypeReference();
|
tn = GetTypeReference();
|
||||||
|
|
@ -2771,13 +2776,17 @@ namespace PascalABCCompiler.PCU
|
||||||
if (members.TryGetValue(offset, out dn))
|
if (members.TryGetValue(offset, out dn))
|
||||||
return dn as common_namespace_function_node;
|
return dn as common_namespace_function_node;
|
||||||
common_namespace_function_node cnfn = null;
|
common_namespace_function_node cnfn = null;
|
||||||
int pos = (int)br.BaseStream.Position;
|
|
||||||
|
int pos = (int)br.BaseStream.Position;
|
||||||
br.BaseStream.Seek(start_pos+offset,SeekOrigin.Begin);
|
br.BaseStream.Seek(start_pos+offset,SeekOrigin.Begin);
|
||||||
br.ReadByte();
|
br.ReadByte();
|
||||||
|
int func_pos = start_pos + br.ReadInt32();
|
||||||
|
int connected_to_type_pos = (int)br.BaseStream.Position;
|
||||||
|
br.BaseStream.Seek(func_pos, SeekOrigin.Begin);
|
||||||
string name;
|
string name;
|
||||||
type_node ConnectedToType = null;
|
type_node ConnectedToType = null;
|
||||||
if (CanReadObject())
|
/*if (CanReadObject())
|
||||||
ConnectedToType = GetTypeReference();
|
ConnectedToType = GetTypeReference();*/
|
||||||
bool is_interface = br.ReadBoolean();
|
bool is_interface = br.ReadBoolean();
|
||||||
if (is_interface)//пропускаем флаг - интерфейсности
|
if (is_interface)//пропускаем флаг - интерфейсности
|
||||||
{
|
{
|
||||||
|
|
@ -2789,16 +2798,21 @@ namespace PascalABCCompiler.PCU
|
||||||
}
|
}
|
||||||
if (is_interface)
|
if (is_interface)
|
||||||
{
|
{
|
||||||
cnfn = new common_namespace_function_node(name,null,cun.namespaces[0],null);
|
cnfn = new common_namespace_function_node(name,null,cun.namespaces[0],null);
|
||||||
int_members.Add(cnfn);
|
int_members.Add(cnfn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cnfn = new common_namespace_function_node(name,null,cun.namespaces[1],null);
|
cnfn = new common_namespace_function_node(name,null,cun.namespaces[1],null);
|
||||||
impl_members.Add(cnfn);
|
impl_members.Add(cnfn);
|
||||||
}
|
}
|
||||||
ReadGenericFunctionInformation(cnfn);
|
ReadGenericFunctionInformation(cnfn);
|
||||||
AddMember(cnfn, offset);
|
AddMember(cnfn, offset);
|
||||||
|
int cur_pos = (int)br.BaseStream.Position;
|
||||||
|
br.BaseStream.Seek(connected_to_type_pos, SeekOrigin.Begin);
|
||||||
|
if (CanReadObject())
|
||||||
|
ConnectedToType = GetTypeReference();
|
||||||
|
br.BaseStream.Seek(cur_pos, SeekOrigin.Begin);
|
||||||
if (br.ReadByte() == 1)
|
if (br.ReadByte() == 1)
|
||||||
{
|
{
|
||||||
cnfn.return_value_type = GetTypeReference();
|
cnfn.return_value_type = GetTypeReference();
|
||||||
|
|
|
||||||
|
|
@ -2915,9 +2915,14 @@ namespace PascalABCCompiler.PCU
|
||||||
FinalizationMethodOffset = pos;
|
FinalizationMethodOffset = pos;
|
||||||
|
|
||||||
bw.Write((byte)func.semantic_node_type);
|
bw.Write((byte)func.semantic_node_type);
|
||||||
|
int connected_to_type_pos = (int)bw.BaseStream.Position;
|
||||||
|
bw.Write(0);
|
||||||
if (CanWriteObject(func.ConnectedToType))
|
if (CanWriteObject(func.ConnectedToType))
|
||||||
WriteTypeReference(func.ConnectedToType);
|
WriteTypeReference(func.ConnectedToType);
|
||||||
|
int cur_pos = (int)bw.BaseStream.Position;
|
||||||
|
bw.Seek(connected_to_type_pos, SeekOrigin.Begin);
|
||||||
|
bw.Write(cur_pos);
|
||||||
|
bw.Seek(cur_pos, SeekOrigin.Begin);
|
||||||
bw.Write(is_interface);
|
bw.Write(is_interface);
|
||||||
if (is_interface == true)
|
if (is_interface == true)
|
||||||
bw.Write(GetNameIndex(func));
|
bw.Write(GetNameIndex(func));
|
||||||
|
|
|
||||||
|
|
@ -6903,7 +6903,7 @@ namespace PascalABCCompiler.NETGenerator
|
||||||
if (tmp_dot == true)
|
if (tmp_dot == true)
|
||||||
{
|
{
|
||||||
//MethodInfo mi = value.static_method.method_info;
|
//MethodInfo mi = value.static_method.method_info;
|
||||||
if (mi.ReturnType.IsValueType && !NETGeneratorTools.IsPointer(mi.ReturnType))
|
if ((mi.ReturnType.IsValueType || mi.ReturnType.IsGenericParameter) && !NETGeneratorTools.IsPointer(mi.ReturnType))
|
||||||
{
|
{
|
||||||
LocalBuilder lb = il.DeclareLocal(mi.ReturnType);
|
LocalBuilder lb = il.DeclareLocal(mi.ReturnType);
|
||||||
il.Emit(OpCodes.Stloc, lb);
|
il.Emit(OpCodes.Stloc, lb);
|
||||||
|
|
@ -7162,7 +7162,7 @@ namespace PascalABCCompiler.NETGenerator
|
||||||
{
|
{
|
||||||
//if (mi.ReturnType.IsValueType && !NETGeneratorTools.IsPointer(mi.ReturnType))
|
//if (mi.ReturnType.IsValueType && !NETGeneratorTools.IsPointer(mi.ReturnType))
|
||||||
//Для правильной работы шаблонов поменял условие (ssyy, 15.05.2009)
|
//Для правильной работы шаблонов поменял условие (ssyy, 15.05.2009)
|
||||||
if ((value.method.return_value_type != null && value.method.return_value_type.is_value_type || value.method.return_value_type.is_generic_parameter) && !NETGeneratorTools.IsPointer(mi.ReturnType))
|
if ((value.method.return_value_type != null && value.method.return_value_type.is_value_type /*|| value.method.return_value_type != null && value.method.return_value_type.is_generic_parameter*/) && !NETGeneratorTools.IsPointer(mi.ReturnType))
|
||||||
{
|
{
|
||||||
LocalBuilder lb = mi.ReturnType.IsGenericParameter ?
|
LocalBuilder lb = mi.ReturnType.IsGenericParameter ?
|
||||||
il.DeclareLocal(helper.GetTypeReference(value.method.return_value_type).tp) :
|
il.DeclareLocal(helper.GetTypeReference(value.method.return_value_type).tp) :
|
||||||
|
|
|
||||||
|
|
@ -841,15 +841,15 @@ end;
|
||||||
OperatorServices = class
|
OperatorServices = class
|
||||||
// Methods
|
// Methods
|
||||||
public constructor Create;
|
public constructor Create;
|
||||||
public function IsAssigmentOperator(&Operator: Operators): boolean; static;
|
public class function IsAssigmentOperator(&Operator: Operators): boolean;
|
||||||
public function ToString(&Operator: Operators; Language: LanguageId): string; static;
|
public class function ToString(&Operator: Operators; Language: LanguageId): string;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Utils = class
|
Utils = class
|
||||||
// Methods
|
// Methods
|
||||||
public constructor Create;
|
public constructor Create;
|
||||||
public function IdentListToString(list: List<ident>; separator: string): string; static;
|
public class function IdentListToString(list: List<ident>; separator: string): string;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -6839,12 +6839,12 @@ begin
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function OperatorServices.IsAssigmentOperator(&Operator: Operators): boolean;
|
class function OperatorServices.IsAssigmentOperator(&Operator: Operators): boolean;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function OperatorServices.ToString(&Operator: Operators; Language: LanguageId): string;
|
class function OperatorServices.ToString(&Operator: Operators; Language: LanguageId): string;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
@ -6855,7 +6855,7 @@ begin
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function Utils.IdentListToString(list: List<ident>; separator: string): string;
|
class function Utils.IdentListToString(list: List<ident>; separator: string): string;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
|
||||||
7840
TestSuite/CompilationSamples/SyntaxTree.pas
Normal file
7840
TestSuite/CompilationSamples/SyntaxTree.pas
Normal file
File diff suppressed because it is too large
Load diff
10
TestSuite/extensionmethods10.pas
Normal file
10
TestSuite/extensionmethods10.pas
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
uses extensionmethods10u;
|
||||||
|
|
||||||
|
procedure Test(x: integer);
|
||||||
|
begin
|
||||||
|
assert(x=3);
|
||||||
|
end;
|
||||||
|
begin
|
||||||
|
var a := Seq(3,3,3);
|
||||||
|
a.MyForeach(Test);
|
||||||
|
end.
|
||||||
7
TestSuite/extensionmethods10u.pas
Normal file
7
TestSuite/extensionmethods10u.pas
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
unit extensionmethods10u;
|
||||||
|
procedure MyForEach<T>(self: sequence of T; action: T -> ()); extensionmethod;
|
||||||
|
begin
|
||||||
|
foreach x: T in Self do
|
||||||
|
action(x);
|
||||||
|
end;
|
||||||
|
end.
|
||||||
|
|
@ -3,6 +3,7 @@ type
|
||||||
procedure Add(a: T);
|
procedure Add(a: T);
|
||||||
begin
|
begin
|
||||||
assert(a.Equals(5));
|
assert(a.Equals(5));
|
||||||
|
assert(a.ToString()='5');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Add2(a:T);virtual;
|
procedure Add2(a:T);virtual;
|
||||||
|
|
|
||||||
14
TestSuite/generics5.pas
Normal file
14
TestSuite/generics5.pas
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
procedure System.Collections.Generic.IEnumerable<TSource>.Show;
|
||||||
|
begin
|
||||||
|
var qq := self.ElementAt(0).ToString();
|
||||||
|
assert(qq = '2');
|
||||||
|
{var obj := object(self.ElementAt(0));
|
||||||
|
assert(obj.ToString()='2');
|
||||||
|
assert(object(self.ElementAt(0)).ToString()='2');}
|
||||||
|
var t: TSource;
|
||||||
|
assert(t.ToString() = '0');
|
||||||
|
end;
|
||||||
|
begin
|
||||||
|
var a := Arr(2,3,4);
|
||||||
|
a.Show;
|
||||||
|
end.
|
||||||
25
TestSuite/generics6.pas
Normal file
25
TestSuite/generics6.pas
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
type
|
||||||
|
Slc<T> = class
|
||||||
|
l: List<T>;
|
||||||
|
constructor (l: List<T>);
|
||||||
|
begin
|
||||||
|
self.l := l;
|
||||||
|
end;
|
||||||
|
public
|
||||||
|
procedure p;
|
||||||
|
begin
|
||||||
|
assert(l[0].ToString()='666');
|
||||||
|
var t := l[0];
|
||||||
|
assert(t.ToString='666');
|
||||||
|
var arr := Arr(l[0]);
|
||||||
|
assert(arr[0].ToString()='666');
|
||||||
|
//assert(object(l[0]).ToString()='666');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var l := new List<integer>();
|
||||||
|
l.Add(666);
|
||||||
|
var s := new Slc<integer>(l);
|
||||||
|
s.p;
|
||||||
|
end.
|
||||||
|
|
@ -849,6 +849,8 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
{
|
{
|
||||||
vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc);
|
vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc);
|
||||||
}
|
}
|
||||||
|
else if (syntax_tree_visitor.context.converted_type != null)
|
||||||
|
vdn = syntax_tree_visitor.context.add_field(get_temp_arr_name(), loc, pr.type, polymorphic_state.ps_static);
|
||||||
else
|
else
|
||||||
vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
|
vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1020,7 +1020,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
SymbolInfo si = expr.type.find(name, context.CurrentScope);
|
SymbolInfo si = expr.type.find(name, context.CurrentScope);
|
||||||
if (si == null)
|
if (si == null || si.sym_info is wrapped_definition_node)
|
||||||
{
|
{
|
||||||
AddError(new OperatorCanNotBeAppliedToThisType(name, expr));
|
AddError(new OperatorCanNotBeAppliedToThisType(name, expr));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -593,15 +593,15 @@ namespace PascalABCCompiler.TreeRealization
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public abstract class common_function_node : function_node, SemanticTree.ICommonFunctionNode
|
public abstract class common_function_node : function_node, SemanticTree.ICommonFunctionNode
|
||||||
{
|
{
|
||||||
private string _name;
|
protected string _name;
|
||||||
|
|
||||||
private readonly local_variable_list _var_defs = new local_variable_list();
|
protected readonly local_variable_list _var_defs = new local_variable_list();
|
||||||
|
|
||||||
private readonly List<label_node> _label_defs = new List<label_node>();
|
protected readonly List<label_node> _label_defs = new List<label_node>();
|
||||||
|
|
||||||
private readonly function_constant_definition_list _const_defs = new function_constant_definition_list();
|
protected readonly function_constant_definition_list _const_defs = new function_constant_definition_list();
|
||||||
|
|
||||||
private SemanticTree.SpecialFunctionKind specialFunctionKind = SemanticTree.SpecialFunctionKind.None;
|
protected SemanticTree.SpecialFunctionKind specialFunctionKind = SemanticTree.SpecialFunctionKind.None;
|
||||||
|
|
||||||
public SemanticTree.SpecialFunctionKind SpecialFunctionKind
|
public SemanticTree.SpecialFunctionKind SpecialFunctionKind
|
||||||
{
|
{
|
||||||
|
|
@ -1097,6 +1097,10 @@ namespace PascalABCCompiler.TreeRealization
|
||||||
{
|
{
|
||||||
return _namespace;
|
return _namespace;
|
||||||
}
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_namespace = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -407,6 +407,8 @@ namespace PascalABCCompiler.TreeRealization
|
||||||
public static bool is_derived(type_node base_class,type_node derived_class)
|
public static bool is_derived(type_node base_class,type_node derived_class)
|
||||||
{
|
{
|
||||||
if (derived_class == null) //void?
|
if (derived_class == null) //void?
|
||||||
|
return false;
|
||||||
|
if (base_class == null)
|
||||||
return false;
|
return false;
|
||||||
type_node tn=derived_class.base_type;
|
type_node tn=derived_class.base_type;
|
||||||
//TODO: Проверить на ссылочный и размерный тип.
|
//TODO: Проверить на ссылочный и размерный тип.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue