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 System.Int16 Version = 104;
|
||||
public static System.Int16 Version = 105;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,11 +269,12 @@ namespace PascalABCCompiler.PCU
|
|||
}
|
||||
cur_doc = new document(SourceFileName);
|
||||
|
||||
AddNamespaces();
|
||||
AddInterfaceNames();
|
||||
//ssyy
|
||||
AddImplementationNames();
|
||||
//\ssyy
|
||||
AddNamespaces();
|
||||
|
||||
//AddInitFinalMethods();
|
||||
//ProcessWaitedToRestoreFields();
|
||||
unit.State = UnitState.Compiled;
|
||||
|
|
@ -475,7 +476,9 @@ namespace PascalABCCompiler.PCU
|
|||
|
||||
type_node tn = GetSpecialTypeRefernce(names[i].offset);
|
||||
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)
|
||||
(tn as common_type_node).scope.AddSymbol(names[i].name, si);
|
||||
else
|
||||
|
|
@ -2696,6 +2699,7 @@ namespace PascalABCCompiler.PCU
|
|||
AddMember(cnfn, offset);
|
||||
|
||||
type_node ConnectedToType = null;
|
||||
br.ReadInt32();
|
||||
if (CanReadObject())
|
||||
ConnectedToType = GetTypeReference();
|
||||
br.ReadBoolean();//пропускаем флаг - интерфейсности
|
||||
|
|
@ -2758,6 +2762,7 @@ namespace PascalABCCompiler.PCU
|
|||
int pos = (int)br.BaseStream.Position;
|
||||
br.BaseStream.Seek(start_pos + offset, SeekOrigin.Begin);
|
||||
br.ReadByte();
|
||||
br.ReadInt32();
|
||||
type_node tn = null;
|
||||
if (CanReadObject())
|
||||
tn = GetTypeReference();
|
||||
|
|
@ -2771,13 +2776,17 @@ namespace PascalABCCompiler.PCU
|
|||
if (members.TryGetValue(offset, out dn))
|
||||
return dn as common_namespace_function_node;
|
||||
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.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;
|
||||
type_node ConnectedToType = null;
|
||||
if (CanReadObject())
|
||||
ConnectedToType = GetTypeReference();
|
||||
/*if (CanReadObject())
|
||||
ConnectedToType = GetTypeReference();*/
|
||||
bool is_interface = br.ReadBoolean();
|
||||
if (is_interface)//пропускаем флаг - интерфейсности
|
||||
{
|
||||
|
|
@ -2789,16 +2798,21 @@ namespace PascalABCCompiler.PCU
|
|||
}
|
||||
if (is_interface)
|
||||
{
|
||||
cnfn = new common_namespace_function_node(name,null,cun.namespaces[0],null);
|
||||
int_members.Add(cnfn);
|
||||
cnfn = new common_namespace_function_node(name,null,cun.namespaces[0],null);
|
||||
int_members.Add(cnfn);
|
||||
}
|
||||
else
|
||||
{
|
||||
cnfn = new common_namespace_function_node(name,null,cun.namespaces[1],null);
|
||||
impl_members.Add(cnfn);
|
||||
cnfn = new common_namespace_function_node(name,null,cun.namespaces[1],null);
|
||||
impl_members.Add(cnfn);
|
||||
}
|
||||
ReadGenericFunctionInformation(cnfn);
|
||||
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)
|
||||
{
|
||||
cnfn.return_value_type = GetTypeReference();
|
||||
|
|
|
|||
|
|
@ -2915,9 +2915,14 @@ namespace PascalABCCompiler.PCU
|
|||
FinalizationMethodOffset = pos;
|
||||
|
||||
bw.Write((byte)func.semantic_node_type);
|
||||
|
||||
int connected_to_type_pos = (int)bw.BaseStream.Position;
|
||||
bw.Write(0);
|
||||
if (CanWriteObject(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);
|
||||
if (is_interface == true)
|
||||
bw.Write(GetNameIndex(func));
|
||||
|
|
|
|||
|
|
@ -6903,7 +6903,7 @@ namespace PascalABCCompiler.NETGenerator
|
|||
if (tmp_dot == true)
|
||||
{
|
||||
//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);
|
||||
il.Emit(OpCodes.Stloc, lb);
|
||||
|
|
@ -7162,7 +7162,7 @@ namespace PascalABCCompiler.NETGenerator
|
|||
{
|
||||
//if (mi.ReturnType.IsValueType && !NETGeneratorTools.IsPointer(mi.ReturnType))
|
||||
//Для правильной работы шаблонов поменял условие (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 ?
|
||||
il.DeclareLocal(helper.GetTypeReference(value.method.return_value_type).tp) :
|
||||
|
|
|
|||
|
|
@ -841,15 +841,15 @@ end;
|
|||
OperatorServices = class
|
||||
// Methods
|
||||
public constructor Create;
|
||||
public function IsAssigmentOperator(&Operator: Operators): boolean; static;
|
||||
public function ToString(&Operator: Operators; Language: LanguageId): string; static;
|
||||
public class function IsAssigmentOperator(&Operator: Operators): boolean;
|
||||
public class function ToString(&Operator: Operators; Language: LanguageId): string;
|
||||
|
||||
end;
|
||||
|
||||
Utils = class
|
||||
// Methods
|
||||
public constructor Create;
|
||||
public function IdentListToString(list: List<ident>; separator: string): string; static;
|
||||
public class function IdentListToString(list: List<ident>; separator: string): string;
|
||||
|
||||
end;
|
||||
|
||||
|
|
@ -6839,12 +6839,12 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
function OperatorServices.IsAssigmentOperator(&Operator: Operators): boolean;
|
||||
class function OperatorServices.IsAssigmentOperator(&Operator: Operators): boolean;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
function OperatorServices.ToString(&Operator: Operators; Language: LanguageId): string;
|
||||
class function OperatorServices.ToString(&Operator: Operators; Language: LanguageId): string;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
|
@ -6855,7 +6855,7 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
function Utils.IdentListToString(list: List<ident>; separator: string): string;
|
||||
class function Utils.IdentListToString(list: List<ident>; separator: string): string;
|
||||
begin
|
||||
|
||||
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);
|
||||
begin
|
||||
assert(a.Equals(5));
|
||||
assert(a.ToString()='5');
|
||||
end;
|
||||
|
||||
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);
|
||||
}
|
||||
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
|
||||
vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
|
||||
|
||||
|
|
|
|||
|
|
@ -1020,7 +1020,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
//#endif
|
||||
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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -593,15 +593,15 @@ namespace PascalABCCompiler.TreeRealization
|
|||
[Serializable]
|
||||
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
|
||||
{
|
||||
|
|
@ -638,7 +638,7 @@ namespace PascalABCCompiler.TreeRealization
|
|||
get { return _generic_params; }
|
||||
set { _generic_params = value; }
|
||||
}
|
||||
|
||||
|
||||
public override List<type_node> get_generic_params_list()
|
||||
{
|
||||
if (_generic_params == null)
|
||||
|
|
@ -1097,6 +1097,10 @@ namespace PascalABCCompiler.TreeRealization
|
|||
{
|
||||
return _namespace;
|
||||
}
|
||||
set
|
||||
{
|
||||
_namespace = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -407,6 +407,8 @@ namespace PascalABCCompiler.TreeRealization
|
|||
public static bool is_derived(type_node base_class,type_node derived_class)
|
||||
{
|
||||
if (derived_class == null) //void?
|
||||
return false;
|
||||
if (base_class == null)
|
||||
return false;
|
||||
type_node tn=derived_class.base_type;
|
||||
//TODO: Проверить на ссылочный и размерный тип.
|
||||
|
|
|
|||
Loading…
Reference in a new issue