parent
a6a3d8369e
commit
2bb4d307a6
|
|
@ -6668,7 +6668,6 @@ namespace PascalABCCompiler.NETGenerator
|
|||
MethodBuilder methb = null;
|
||||
bool is_prop_acc = IsPropertyAccessor(value);
|
||||
MethodAttributes attrs = GetMethodAttributes(value, is_prop_acc);
|
||||
|
||||
IRuntimeManagedMethodBody irmmb = value.function_code as IRuntimeManagedMethodBody;
|
||||
if (irmmb != null)
|
||||
{
|
||||
|
|
|
|||
30
TestSuite/explicitinterface.pas
Normal file
30
TestSuite/explicitinterface.pas
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
type
|
||||
IEnr = System.Collections.IEnumerator;
|
||||
IEnb = System.Collections.IEnumerable;
|
||||
|
||||
var a : integer;
|
||||
type My = class(IEnumerable<integer>)
|
||||
public
|
||||
function IEnb.GetEnumerator(): IEnr;
|
||||
begin
|
||||
a := 1;
|
||||
end;
|
||||
function GetEnumerator(): IEnumerator<integer>;
|
||||
begin
|
||||
a := 2;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
var ien: IEnb := new My;
|
||||
ien.GetEnumerator;
|
||||
assert(a=1);
|
||||
var ien2: IEnumerable<integer> := new My;
|
||||
ien2.GetEnumerator;
|
||||
assert(a=2);
|
||||
a := 0;
|
||||
var mc := new My;
|
||||
mc.GetEnumerator();
|
||||
assert(a=2);
|
||||
end.
|
||||
|
|
@ -164,7 +164,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
//TODO: Можно сделать возможность объявления вложенных типов.
|
||||
public common_type_node _ctn; // SSM - пытаюсь выходить из класса и входить заново
|
||||
private common_function_node_stack _func_stack=new common_function_node_stack();
|
||||
|
||||
private type_node _explicit_interface_type;
|
||||
|
||||
internal common_function_node_stack func_stack
|
||||
{
|
||||
get
|
||||
|
|
@ -584,7 +585,21 @@ namespace PascalABCCompiler.TreeConverter
|
|||
return (_func_stack.top());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public type_node converted_explicit_interface_type
|
||||
{
|
||||
get
|
||||
{
|
||||
return _explicit_interface_type;
|
||||
}
|
||||
//ssyy
|
||||
set
|
||||
{
|
||||
_explicit_interface_type = value;
|
||||
}
|
||||
//\ssyy
|
||||
}
|
||||
|
||||
public common_type_node converted_type
|
||||
{
|
||||
get
|
||||
|
|
@ -894,7 +909,22 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
public void leave_type_method()
|
||||
{
|
||||
if (_compiled_tn != null)
|
||||
if (_explicit_interface_type != null)
|
||||
{
|
||||
function_node fn = top_function;
|
||||
SymbolInfo si = _ctn.Scope.FindOnlyInType(fn.name, null);
|
||||
function_node compar;
|
||||
while (si != null)
|
||||
{
|
||||
compar = si.sym_info as function_node;
|
||||
if (fn != compar && convertion_data_and_alghoritms.function_eq_params(fn, compar, false))
|
||||
//if (fn is common_namespace_function_node && compar is common_namespace_function_node && (fn as common_namespace_function_node).comprehensive_namespace == (compar as common_namespace_function_node).comprehensive_namespace)
|
||||
|
||||
AddError(new FunctionDuplicateDefinition(compar, fn));
|
||||
si = si.Next;
|
||||
}
|
||||
}
|
||||
else if (_compiled_tn != null)
|
||||
{
|
||||
function_node fn = top_function;
|
||||
SymbolInfo si = _compiled_tn.scope.FindOnlyInType(fn.name, null);
|
||||
|
|
@ -909,8 +939,10 @@ namespace PascalABCCompiler.TreeConverter
|
|||
si = si.Next;
|
||||
}
|
||||
}
|
||||
_ctn = null;
|
||||
if (_explicit_interface_type == null)
|
||||
_ctn = null;
|
||||
_compiled_tn = null;
|
||||
_explicit_interface_type = null;
|
||||
}
|
||||
|
||||
private readonly System.Collections.Generic.Stack<common_type_node> type_stack = new System.Collections.Generic.Stack<common_type_node>();
|
||||
|
|
@ -2701,12 +2733,26 @@ _cmn.types.AddElement(tctn);*/
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Проверка типа на наличие функции из интерфейса
|
||||
private void check_implement_function(common_type_node cnode, function_node meth, type_node interf)
|
||||
{
|
||||
//Ищем все функции с нужным именем в типе и его предках
|
||||
SymbolInfo si = cnode.find_in_type(meth.name, cnode.Scope);
|
||||
SymbolInfo tmp_si = null;
|
||||
if (meth is compiled_function_node)
|
||||
tmp_si = cnode.find_in_type((meth as compiled_function_node).cont_type.BaseFullName + "." + meth.name, cnode.Scope);
|
||||
else if (meth is common_method_node)
|
||||
tmp_si = cnode.find_in_type((meth as common_method_node).cont_type.BaseFullName + "." + meth.name, cnode.Scope);
|
||||
if (tmp_si != null)
|
||||
{
|
||||
SymbolInfo tmp_si2 = tmp_si;
|
||||
while (tmp_si2.Next != null)
|
||||
tmp_si2 = tmp_si2.Next;
|
||||
tmp_si.Next = si;
|
||||
si = tmp_si;
|
||||
}
|
||||
|
||||
function_node fn = null;
|
||||
while (si != null)
|
||||
{
|
||||
|
|
@ -2724,7 +2770,7 @@ _cmn.types.AddElement(tctn);*/
|
|||
{
|
||||
if (fn_common.name != meth.name)
|
||||
{
|
||||
syntax_tree_visitor.AddError(fn_common.loc, "AMBIGUITY_BETWEEN_NAMES_{0}_AND_{1}" ,fn_common.name, meth.name);
|
||||
syntax_tree_visitor.AddError(fn_common.loc, "AMBIGUITY_BETWEEN_NAMES_{0}_AND_{1}", fn_common.name, meth.name);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2732,7 +2778,7 @@ _cmn.types.AddElement(tctn);*/
|
|||
fn_common.SetName(meth.name);
|
||||
fn_common.name_case_fixed = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2781,7 +2827,7 @@ _cmn.types.AddElement(tctn);*/
|
|||
{
|
||||
AddError(new DerivedFromInterfaceMethodMustBePublicAndNonStatic(
|
||||
cnode.name, interf.name,
|
||||
Tools.GetFullMethodHeaderString(meth),cnode.is_value_type, cnode.loc));
|
||||
Tools.GetFullMethodHeaderString(meth), cnode.is_value_type, cnode.loc));
|
||||
}
|
||||
//Проверка пройдена!
|
||||
|
||||
|
|
@ -3022,7 +3068,11 @@ _cmn.types.AddElement(tctn);*/
|
|||
bool in_unit = false;
|
||||
if (_func_stack.size<=1)
|
||||
{
|
||||
if (_ctn!=null)
|
||||
if (_explicit_interface_type != null)
|
||||
{
|
||||
si = _explicit_interface_type.find_in_type(fn.name);
|
||||
}
|
||||
else if (_ctn!=null)
|
||||
{
|
||||
si=_ctn.Scope.FindOnlyInScope(fn.name);
|
||||
if (_ctn is compiled_generic_instance_type_node && fn is common_namespace_function_node)
|
||||
|
|
@ -3115,7 +3165,17 @@ _cmn.types.AddElement(tctn);*/
|
|||
AddError(new FunctionDuplicateDefinition(compar, fn));
|
||||
}
|
||||
else
|
||||
AddError(new FunctionDuplicateDefinition(compar, fn));
|
||||
{
|
||||
if (fn is common_method_node && compar is common_method_node)
|
||||
{
|
||||
common_method_node cmn1 = fn as common_method_node;
|
||||
common_method_node cmn2 = compar as common_method_node;
|
||||
if (cmn1.explicit_interface == cmn2.explicit_interface)
|
||||
AddError(new FunctionDuplicateDefinition(compar, fn));
|
||||
}
|
||||
else
|
||||
AddError(new FunctionDuplicateDefinition(compar, fn));
|
||||
}
|
||||
}
|
||||
si = si.Next;
|
||||
continue;
|
||||
|
|
@ -3349,7 +3409,7 @@ _cmn.types.AddElement(tctn);*/
|
|||
//si.sym_info=fn;
|
||||
break;
|
||||
}
|
||||
if (fn is common_method_node && !predef_find && syntax_tree_visitor.current_converted_method_not_in_class_defined)
|
||||
if (fn is common_method_node && !predef_find && syntax_tree_visitor.current_converted_method_not_in_class_defined && _explicit_interface_type == null)
|
||||
{
|
||||
AddError(new NoMethodInClassWithThisParams(fn as common_method_node, (fn as common_method_node).cont_type, fn.loc));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,15 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
internal void AddError(location loc, string ErrResourceString, params object[] values)
|
||||
{
|
||||
ErrorsList.Add(new SimpleSemanticError(loc, ErrResourceString, values));
|
||||
Errors.Error err = new SimpleSemanticError(loc, ErrResourceString, values);
|
||||
if (ThrowCompilationError)
|
||||
{
|
||||
throw err;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorsList.Add(err);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddWarning(Errors.CompilerWarning err)
|
||||
|
|
@ -9102,11 +9110,12 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if(is_operator)
|
||||
op=(_method_name.meth_name as SyntaxTree.operator_name_ident).operator_type;
|
||||
_method_name.meth_name = ConvertOperatorNameToIdent(_method_name.meth_name);
|
||||
|
||||
bool explicit_impl = false;
|
||||
if ((context.converting_block() != block_type.namespace_block) && (_method_name.class_name != null))
|
||||
{
|
||||
AddError(new OnlyProcedureNameAllowedInClassFunctionDefinition(_method_name.class_name.name,
|
||||
get_location(_method_name.class_name)));
|
||||
/*AddError(new OnlyProcedureNameAllowedInClassFunctionDefinition(_method_name.class_name.name,
|
||||
get_location(_method_name.class_name)));*/
|
||||
explicit_impl = true;
|
||||
}
|
||||
if (is_operator && op==SyntaxTree.Operators.AddressOf && SemanticRules.AddressOfOperatorNonOverloaded)
|
||||
{
|
||||
|
|
@ -9123,7 +9132,22 @@ namespace PascalABCCompiler.TreeConverter
|
|||
{
|
||||
num_template_args = ttn.template_args.idents.Count;
|
||||
}
|
||||
common_type_node current_conv_type = context.converted_type;
|
||||
def_temp = context.enter_in_type_method(_method_name, _method_name.class_name.name, loc_type_name, num_template_args);
|
||||
if (explicit_impl)
|
||||
{
|
||||
context.converted_type = current_conv_type;
|
||||
if (def_temp is type_node && (def_temp as type_node).IsInterface)
|
||||
{
|
||||
context.converted_explicit_interface_type = def_temp as type_node;
|
||||
SymbolInfo si = context.converted_explicit_interface_type.find_in_type(_method_name.meth_name.name);
|
||||
if (si == null)
|
||||
AddError(new UndefinedNameReference(_method_name.meth_name.name, get_location(_method_name.meth_name)));
|
||||
}
|
||||
else
|
||||
AddError(new OnlyProcedureNameAllowedInClassFunctionDefinition(_method_name.class_name.name,
|
||||
get_location(_method_name.class_name)));
|
||||
}
|
||||
tp = def_temp as common_type_node;
|
||||
template_class tc = def_temp as template_class;
|
||||
//SyntaxTree.template_type_name ttn = _method_name.class_name as SyntaxTree.template_type_name;
|
||||
|
|
@ -9256,7 +9280,12 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (current_function_header != null && current_function_header.proc_attributes != null && has_extensionmethod_attr(current_function_header.proc_attributes.proc_attributes))
|
||||
context.create_function(_method_name.meth_name.name, loc_name, false);
|
||||
else
|
||||
context.create_function(_method_name.meth_name.name, loc_name);
|
||||
{
|
||||
if (!explicit_impl)
|
||||
context.create_function(_method_name.meth_name.name, loc_name);
|
||||
else
|
||||
context.create_function(context.converted_explicit_interface_type.BaseFullName+"."+_method_name.meth_name.name, loc_name);
|
||||
}
|
||||
}
|
||||
context.extension_method = false;
|
||||
context.top_function.IsOperator = is_operator;
|
||||
|
|
@ -11242,6 +11271,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
hard_node_test_and_visit(_procedure_definition.proc_header);
|
||||
}
|
||||
//\lroman//
|
||||
|
||||
|
||||
//ssyy
|
||||
if (context.converted_template_type != null)
|
||||
|
|
@ -11260,6 +11290,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
{
|
||||
return;
|
||||
}
|
||||
if (context.converted_explicit_interface_type != null)
|
||||
(context.top_function as common_method_node).explicit_interface = context.converted_explicit_interface_type;
|
||||
if (has_dll_import_attribute(context.top_function))
|
||||
{
|
||||
if (_procedure_definition.proc_body != null)
|
||||
|
|
@ -18506,6 +18538,8 @@ namespace PascalABCCompiler.TreeConverter
|
|||
public override void visit(SyntaxTree.same_type_node st) // SSM 22/06/13
|
||||
{
|
||||
expression_node en = convert_strong(st.ex);
|
||||
if (en == null)
|
||||
AddError(get_location(st.ex),"CANNOT_EVALUATE_FUNCTION_TYPE");
|
||||
return_value(en.type);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1283,6 +1283,7 @@ namespace PascalABCCompiler.TreeRealization
|
|||
private SemanticTree.field_access_level _field_access_level;
|
||||
private SemanticTree.polymorphic_state _polymorphic_state;
|
||||
|
||||
private type_node _explicit_interface;
|
||||
private bool _is_constructor;
|
||||
public bool first_statement = true;
|
||||
public bool inherited_ctor_called = false;
|
||||
|
|
@ -1290,6 +1291,18 @@ namespace PascalABCCompiler.TreeRealization
|
|||
|
||||
private bool _is_final = false;
|
||||
|
||||
public type_node explicit_interface
|
||||
{
|
||||
get
|
||||
{
|
||||
return _explicit_interface;
|
||||
}
|
||||
set
|
||||
{
|
||||
_explicit_interface = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsStatic
|
||||
{
|
||||
get
|
||||
|
|
@ -1597,6 +1610,7 @@ namespace PascalABCCompiler.TreeRealization
|
|||
private int _num_of_default_parameters;
|
||||
private bool _is_extension_method=false;
|
||||
private compiled_type_node connected_to_type;
|
||||
private List<compiled_type_node> _generic_params;
|
||||
private static System.Collections.Generic.Dictionary<System.Reflection.MethodInfo, compiled_function_node> compiled_methods =
|
||||
new System.Collections.Generic.Dictionary<System.Reflection.MethodInfo, compiled_function_node>();
|
||||
|
||||
|
|
|
|||
|
|
@ -342,6 +342,14 @@ namespace PascalABCCompiler.TreeRealization
|
|||
}
|
||||
}
|
||||
|
||||
public virtual string BaseFullName
|
||||
{
|
||||
get
|
||||
{
|
||||
return full_name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Свойство по умолчанию.
|
||||
/// </summary>
|
||||
|
|
@ -1732,6 +1740,14 @@ namespace PascalABCCompiler.TreeRealization
|
|||
}
|
||||
}
|
||||
|
||||
public override string BaseFullName
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.comprehensive_namespace.namespace_full_name + "." + name;
|
||||
}
|
||||
}
|
||||
|
||||
public override string PrintableName
|
||||
{
|
||||
get
|
||||
|
|
@ -3451,6 +3467,17 @@ namespace PascalABCCompiler.TreeRealization
|
|||
return base.PrintableName;
|
||||
}
|
||||
}
|
||||
|
||||
public override string BaseFullName
|
||||
{
|
||||
get
|
||||
{
|
||||
Type t = _compiled_type;
|
||||
if (t.IsGenericType)
|
||||
t = t.GetGenericTypeDefinition();
|
||||
return t.FullName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ ILLEGAL_LAMBDA_PARAMETERS_NUMBER=Illegal lambda parameters number
|
|||
IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA=Unable to infer types in lambda
|
||||
ANONYMOUS_DELEGATE_IN_INTERFACE_NOT_ALLOWED=Using of anonymous delegate in interface is not allowed. Declare the delegate type explicitly.
|
||||
PARAMETER_REFERENCE_IN_DEFAULT_PARAMETER_NOT_ALLOWED=Parameter references in default parameter value are not allowed
|
||||
CANNOT_EVALUATE_FUNCTION_TYPE=Cannot infer the return type of function
|
||||
TYPE_NAME_EXPECTED=Type name expected
|
||||
%PREFIX%=COMPILATIONERROR_
|
||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Unit expected, library found
|
||||
ASSEMBLY_{0}_READING_ERROR=Error by reading assembly '{0}'
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ FIRST_PARAMETER_MUST_HAVE_NAME_SELF=Первый параметр должен
|
|||
EXTENSION_METHODS_FOR_CONSTRUCTED_TYPES_NOT_ALLOWED=Нельзя расширять этот тип
|
||||
EXTENSION_METHODS_IN_INTERFACE_PART_NOT_ALLOWED=Объявление extension-методов в интерфейсной части модуля недопустимо
|
||||
OPERATOR_SHOULD_BE_EXTENSION_METHOD=Оператор должен быть помечен модификатором extensionmethod
|
||||
CANNOT_EVALUATE_FUNCTION_TYPE=Невозможно вывести тип функции
|
||||
TYPE_NAME_EXPECTED=Ожидался тип
|
||||
%PREFIX%=COMPILATIONERROR_
|
||||
UNIT_MODULE_EXPECTED_LIBRARY_FOUND=Ожидался модуль, а встречена библиотека
|
||||
ASSEMBLY_{0}_READING_ERROR=Ошибка при чтении сборки '{0}'
|
||||
|
|
|
|||
Loading…
Reference in a new issue