Merge branch 'master' of https://github.com/pascalabcnet/pascalabcnet
This commit is contained in:
commit
85a81c8cb2
|
|
@ -88,9 +88,13 @@ namespace CodeCompletion
|
|||
}
|
||||
else if (returned_scope != null && returned_scope is ElementScope && (returned_scope as ElementScope).sc is ProcScope)
|
||||
{
|
||||
if (by_dot)
|
||||
if (((returned_scope as ElementScope).sc as ProcScope).return_type != null)
|
||||
returned_scope = new ElementScope(((returned_scope as ElementScope).sc as ProcScope).return_type);
|
||||
ProcScope ps = (returned_scope as ElementScope).sc as ProcScope;
|
||||
TypeScope return_type = ps.return_type;
|
||||
if (ps.is_constructor)
|
||||
return_type = ps.declaringType;
|
||||
if (by_dot)
|
||||
if (return_type != null)
|
||||
returned_scope = new ElementScope(return_type);
|
||||
else
|
||||
returned_scope = null;
|
||||
}
|
||||
|
|
@ -101,14 +105,18 @@ namespace CodeCompletion
|
|||
returned_scope = new ElementScope(invoke_meth.return_type);
|
||||
}
|
||||
else if (returned_scope != null && returned_scope is ProcScope)
|
||||
if ((returned_scope as ProcScope).return_type == null)
|
||||
{
|
||||
ProcScope ps = returned_scope as ProcScope;
|
||||
TypeScope return_type = ps.return_type;
|
||||
if (ps.is_constructor)
|
||||
return_type = ps.declaringType;
|
||||
if (return_type == null)
|
||||
{
|
||||
if (by_dot) returned_scope = null;
|
||||
}
|
||||
else if (by_dot)
|
||||
returned_scope = new ElementScope((returned_scope as ProcScope).return_type);
|
||||
|
||||
//else ret_scope = (ret_scope as ElementScope).sc as ProcScope;
|
||||
else if (by_dot)
|
||||
returned_scope = new ElementScope(return_type);
|
||||
}
|
||||
return returned_scope;
|
||||
}
|
||||
|
||||
|
|
@ -723,9 +731,13 @@ namespace CodeCompletion
|
|||
}
|
||||
else if (returned_scope != null && returned_scope is ProcScope)
|
||||
{
|
||||
if ((returned_scope as ProcScope).return_type == null)
|
||||
ProcScope ps = returned_scope as ProcScope;
|
||||
if (ps.return_type == null)
|
||||
{
|
||||
returned_scope = null;
|
||||
if (ps.is_constructor)
|
||||
returned_scope = new ElementScope(ps.declaringType);
|
||||
else
|
||||
returned_scope = null;
|
||||
}
|
||||
else
|
||||
returned_scope = new ElementScope((returned_scope as ProcScope).return_type);
|
||||
|
|
@ -924,9 +936,12 @@ namespace CodeCompletion
|
|||
ps = returned_scope as ProcScope;
|
||||
if (by_dot)
|
||||
{
|
||||
if (ps.return_type != null)
|
||||
returned_scope = new ElementScope(ps.return_type);
|
||||
else returned_scope = null;
|
||||
if (ps.return_type != null)
|
||||
returned_scope = new ElementScope(ps.return_type);
|
||||
else if (ps.is_constructor)
|
||||
returned_scope = new ElementScope(ps.declaringType);
|
||||
else
|
||||
returned_scope = null;
|
||||
}
|
||||
else
|
||||
returned_scope = new ElementScope(ps);
|
||||
|
|
|
|||
|
|
@ -3576,8 +3576,6 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
DefaultVisit(_yield_unknown_ident);
|
||||
pre_do_visit(_yield_unknown_ident);
|
||||
visit(yield_unknown_ident.UnknownID);
|
||||
visit(yield_unknown_ident.ClassName);
|
||||
post_do_visit(_yield_unknown_ident);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3786,8 +3786,6 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
public void read_yield_unknown_ident(yield_unknown_ident _yield_unknown_ident)
|
||||
{
|
||||
read_ident(_yield_unknown_ident);
|
||||
_yield_unknown_ident.UnknownID = _read_node() as ident;
|
||||
_yield_unknown_ident.ClassName = _read_node() as ident;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5932,24 +5932,6 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
public void write_yield_unknown_ident(yield_unknown_ident _yield_unknown_ident)
|
||||
{
|
||||
write_ident(_yield_unknown_ident);
|
||||
if (_yield_unknown_ident.UnknownID == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_yield_unknown_ident.UnknownID.visit(this);
|
||||
}
|
||||
if (_yield_unknown_ident.ClassName == null)
|
||||
{
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.Write((byte)1);
|
||||
_yield_unknown_ident.ClassName.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31542,80 +31542,24 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public yield_unknown_ident(ident _UnknownID,ident _ClassName)
|
||||
{
|
||||
this._UnknownID=_UnknownID;
|
||||
this._ClassName=_ClassName;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public yield_unknown_ident(ident _UnknownID,ident _ClassName,SourceContext sc)
|
||||
{
|
||||
this._UnknownID=_UnknownID;
|
||||
this._ClassName=_ClassName;
|
||||
source_context = sc;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public yield_unknown_ident(string _name,ident _UnknownID,ident _ClassName)
|
||||
public yield_unknown_ident(string _name)
|
||||
{
|
||||
this._name=_name;
|
||||
this._UnknownID=_UnknownID;
|
||||
this._ClassName=_ClassName;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public yield_unknown_ident(string _name,ident _UnknownID,ident _ClassName,SourceContext sc)
|
||||
public yield_unknown_ident(string _name,SourceContext sc)
|
||||
{
|
||||
this._name=_name;
|
||||
this._UnknownID=_UnknownID;
|
||||
this._ClassName=_ClassName;
|
||||
source_context = sc;
|
||||
}
|
||||
|
||||
protected ident _UnknownID;
|
||||
protected ident _ClassName;
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public ident UnknownID
|
||||
{
|
||||
get
|
||||
{
|
||||
return _UnknownID;
|
||||
}
|
||||
set
|
||||
{
|
||||
_UnknownID=value;
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///
|
||||
///</summary>
|
||||
public ident ClassName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ClassName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_ClassName=value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///<summary>
|
||||
///Свойство для получения количества всех подузлов без элементов поля типа List
|
||||
///</summary>
|
||||
|
|
@ -31623,7 +31567,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
|
|
@ -31633,7 +31577,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
|
|
@ -31645,28 +31589,12 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
|
||||
throw new IndexOutOfRangeException();
|
||||
switch(ind)
|
||||
{
|
||||
case 0:
|
||||
return UnknownID;
|
||||
case 1:
|
||||
return ClassName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
|
||||
throw new IndexOutOfRangeException();
|
||||
switch(ind)
|
||||
{
|
||||
case 0:
|
||||
UnknownID = (ident)value;
|
||||
break;
|
||||
case 1:
|
||||
ClassName = (ident)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
///<summary>
|
||||
|
|
|
|||
|
|
@ -1447,6 +1447,45 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
}
|
||||
|
||||
public partial class yield_unknown_ident : ident
|
||||
{
|
||||
protected ident _UnknownID;
|
||||
protected ident _ClassName;
|
||||
|
||||
public ident UnknownID
|
||||
{
|
||||
get { return _UnknownID; }
|
||||
set { _UnknownID = value; }
|
||||
}
|
||||
|
||||
public ident ClassName
|
||||
{
|
||||
get { return _ClassName; }
|
||||
set { _ClassName = value; }
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public yield_unknown_ident(ident _UnknownID, ident _ClassName)
|
||||
{
|
||||
this._name = _UnknownID.name;
|
||||
this._UnknownID = _UnknownID;
|
||||
this._ClassName = _ClassName;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Конструктор с параметрами.
|
||||
///</summary>
|
||||
public yield_unknown_ident(ident _UnknownID, ident _ClassName, SourceContext sc)
|
||||
{
|
||||
this._name = _UnknownID.name;
|
||||
this._UnknownID = _UnknownID;
|
||||
this._ClassName = _ClassName;
|
||||
source_context = sc;
|
||||
}
|
||||
}
|
||||
|
||||
// end frninja
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
9
TestSuite/intellisense_tests/create1.pas
Normal file
9
TestSuite/intellisense_tests/create1.pas
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
type A = class
|
||||
f: sequence of integer;
|
||||
end;
|
||||
|
||||
begin
|
||||
A.Create{@constructor A();@}.f{@var A.f: sequence of integer;@}.Println;
|
||||
A.Create().f{@var A.f: sequence of integer;@}.Println;
|
||||
StringBuilder.Create{@constructor StringBuilder();@}.ToString{@function StringBuilder.ToString(): string; virtual;@};
|
||||
end.
|
||||
|
|
@ -914,12 +914,6 @@ namespace PascalABCCompiler.TreeConverter
|
|||
|
||||
public void leave_type_method()
|
||||
{
|
||||
// frninja 03/06/16 - убираем мусорные методы-хелперы yield
|
||||
if (_ctn != null && (top_function is common_method_node) && (top_function as common_method_node).is_yield_helper)
|
||||
{
|
||||
_ctn.methods.remove(top_function as common_method_node);
|
||||
}
|
||||
// end frninja
|
||||
if (_explicit_interface_type != null)
|
||||
{
|
||||
function_node fn = top_function;
|
||||
|
|
|
|||
|
|
@ -11507,6 +11507,12 @@ namespace PascalABCCompiler.TreeConverter
|
|||
{
|
||||
if (_procedure_definition.proc_header.name.class_name != null)
|
||||
{
|
||||
// frninja 03/06/16 - убираем мусорные методы-хелперы yield
|
||||
if (context._ctn != null && (context.top_function is common_method_node) && (context.top_function as common_method_node).is_yield_helper)
|
||||
{
|
||||
context._ctn.methods.remove(context.top_function as common_method_node);
|
||||
}
|
||||
// end frninja
|
||||
context.leave_type_method();
|
||||
}
|
||||
context.is_order_independed_method_description = false;
|
||||
|
|
|
|||
|
|
@ -324,9 +324,13 @@ namespace SyntaxVisitors
|
|||
var endtemp = new ident(newNames.VarEndName); //new ident(newVarName());
|
||||
|
||||
//var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
|
||||
var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
|
||||
//var ass1 = new var_statement(fn.loop_variable, fn.type_name, fn.initial_value);
|
||||
//var ass2 = new var_statement(endtemp, fn.type_name, fn.finish_value);
|
||||
|
||||
// frninja 05/06/16 - фиксим для !fn.create_variable
|
||||
var ass1 = fn.create_loop_variable
|
||||
? new var_statement(fn.loop_variable, fn.type_name, fn.initial_value) as statement
|
||||
: new assign(fn.loop_variable, fn.initial_value) as statement;
|
||||
|
||||
|
||||
var if0 = new if_node((fn.cycle_type == for_cycle_type.to) ?
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ namespace SyntaxVisitors
|
|||
{
|
||||
this.CurrentMethod = pd;
|
||||
|
||||
HasYields = false;
|
||||
|
||||
base.visit(pd);
|
||||
pd.has_yield = HasYields;
|
||||
|
||||
|
|
|
|||
|
|
@ -254,9 +254,16 @@ namespace SyntaxVisitors
|
|||
interfaces1.Add(IEnumerableT).Add(IEnumeratorT);
|
||||
|
||||
// frninja 24/04/16 - поддержка шаблонных классов
|
||||
var td1 = new type_declaration(className, this.CreateHelperClassDefinition(className, pd, interfaces1, cm1));
|
||||
|
||||
// frninja 05/06/16 - фикс. Поддержка where секции
|
||||
var helperClassDefinition = this.CreateHelperClassDefinition(className, pd, interfaces1, cm1);
|
||||
helperClassDefinition.where_section = this.GetMethodWhereSection(pd);
|
||||
|
||||
var td1 = new type_declaration(className, helperClassDefinition);
|
||||
//SyntaxTreeBuilder.BuildClassDefinition(interfaces1, cm1));
|
||||
|
||||
|
||||
|
||||
var cct = new type_declarations(/*td*/);
|
||||
cct.Add(td1);
|
||||
|
||||
|
|
@ -356,6 +363,67 @@ namespace SyntaxVisitors
|
|||
return null;
|
||||
}
|
||||
|
||||
private class_definition GetMethodClassDefinition(procedure_definition pd)
|
||||
{
|
||||
if (!IsClassMethod(pd))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var cd = UpperTo<class_definition>();
|
||||
if (cd != null)
|
||||
{
|
||||
// Метод класса описан в классе
|
||||
return cd;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Метод класса описан вне класса
|
||||
|
||||
return UpperTo<declarations>().list
|
||||
.OfType<type_declarations>()
|
||||
.SelectMany(tdecls => tdecls.types_decl)
|
||||
.Where(td => td.type_name.name == GetClassName(pd).name)
|
||||
.Select(td => td.type_def as class_definition)
|
||||
.Where(_cd => _cd != null)
|
||||
.DefaultIfEmpty()
|
||||
.First();
|
||||
}
|
||||
}
|
||||
|
||||
private where_definition_list GetMethodWhereSection(procedure_definition pd)
|
||||
{
|
||||
if (!IsClassMethod(pd))
|
||||
{
|
||||
if (pd.proc_header.where_defs != null)
|
||||
{
|
||||
return ObjectCopier.Clone(pd.proc_header.where_defs);
|
||||
}
|
||||
else
|
||||
{
|
||||
var pdPredefs = UpperTo<declarations>().defs
|
||||
.OfType<procedure_definition>()
|
||||
.Where(lpd => lpd.proc_body == null
|
||||
&& lpd.proc_header.name.meth_name.name == pd.proc_header.name.meth_name.name
|
||||
&& lpd.proc_header.proc_attributes.proc_attributes.FindIndex(attr => attr.attribute_type == proc_attribute.attr_forward) != -1);
|
||||
if (pdPredefs.Count() > 0)
|
||||
{
|
||||
return ObjectCopier.Clone(pdPredefs.First().proc_header.where_defs);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
class_definition cd = GetMethodClassDefinition(pd);
|
||||
if (cd != null)
|
||||
{
|
||||
return ObjectCopier.Clone(cd.where_section);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Определяет описан ли метод-итератор в некотором классе
|
||||
/// </summary>
|
||||
|
|
@ -503,11 +571,14 @@ namespace SyntaxVisitors
|
|||
{
|
||||
// Клонируем исходный метод для проверок ошибок бэкендом
|
||||
var pdCloned = ObjectCopier.Clone(pd);
|
||||
|
||||
pdCloned.has_yield = false;
|
||||
|
||||
|
||||
// Добавляем в класс метод с обертками для локальных переменных
|
||||
pdCloned.proc_header.name.meth_name = new ident(YieldConsts.YieldHelperMethodPrefix + "_error_checkerr>" + pd.proc_header.name.meth_name.name); // = new method_name("<yield_helper_locals_type_detector>" + pd.proc_header.className.meth_name.className);
|
||||
pdCloned.proc_header.name.meth_name = new ident(YieldConsts.YieldHelperMethodPrefix + "_error_checkerr>" + pd.proc_header.name.meth_name.name,
|
||||
// frninja 05/06/16 - фиксим source_context
|
||||
pd.proc_header.name.meth_name.source_context); // = new method_name("<yield_helper_locals_type_detector>" + pd.proc_header.className.meth_name.className);
|
||||
//pdCloned.is_yield_helper = true;
|
||||
|
||||
InsertHelperMethod(pd, pdCloned);
|
||||
|
|
@ -524,6 +595,7 @@ namespace SyntaxVisitors
|
|||
|
||||
// Клонируем исходный метод для вставки оберток-хелперов для локальных переменных и дальнейшей обработки на семантике
|
||||
var pdCloned = ObjectCopier.Clone(pd);
|
||||
|
||||
pdCloned.has_yield = false;
|
||||
|
||||
// Заменяем локальные переменные с неизвестным типом на обертки-хелперы (откладываем до семантики)
|
||||
|
|
@ -538,7 +610,9 @@ namespace SyntaxVisitors
|
|||
localsClonesCollection = localsTypeDetectorHelperVisitor.LocalDeletedDefs.ToArray();
|
||||
|
||||
// Добавляем в класс метод с обертками для локальных переменных
|
||||
pdCloned.proc_header.name.meth_name = new ident(YieldConsts.YieldHelperMethodPrefix+ "_locals_type_detector>" + pd.proc_header.name.meth_name.name); // = new method_name("<yield_helper_locals_type_detector>" + pd.proc_header.className.meth_name.className);
|
||||
pdCloned.proc_header.name.meth_name = new ident(YieldConsts.YieldHelperMethodPrefix+ "_locals_type_detector>" + pd.proc_header.name.meth_name.name,
|
||||
// frninja 05/06/16 - фиксим source_context
|
||||
pd.proc_header.name.meth_name.source_context); // = new method_name("<yield_helper_locals_type_detector>" + pd.proc_header.className.meth_name.className);
|
||||
//pdCloned.is_yield_helper = true;
|
||||
|
||||
InsertHelperMethod(pd, pdCloned);
|
||||
|
|
@ -726,7 +800,42 @@ namespace SyntaxVisitors
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Вставляет предописание метода-итератора для рекурсивных вызовов, если метод описан вне класса
|
||||
/// </summary>
|
||||
private bool InsertGlobalIteratorMethodPredefinition(procedure_definition pd)
|
||||
{
|
||||
if (IsClassMethod(pd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var pdPredefs = UpperTo<declarations>().defs
|
||||
.OfType<procedure_definition>()
|
||||
.Where(lpd => lpd.proc_body == null
|
||||
&& lpd.proc_header.name.meth_name.name == pd.proc_header.name.meth_name.name
|
||||
&& lpd.proc_header.proc_attributes.proc_attributes.FindIndex(attr => attr.attribute_type == proc_attribute.attr_forward) != -1);
|
||||
|
||||
|
||||
bool isPredefined = pdPredefs.Count() > 0;
|
||||
|
||||
if (!isPredefined)
|
||||
{
|
||||
|
||||
var fh = ObjectCopier.Clone(pd.proc_header as function_header);
|
||||
fh.proc_attributes.Add(new procedure_attribute(proc_attribute.attr_forward));
|
||||
|
||||
procedure_definition predef = new procedure_definition() { proc_header = fh };
|
||||
// frninja 05/06/16 - для шаблонов с where
|
||||
predef.proc_header.where_defs = ObjectCopier.Clone(pd.proc_header.where_defs);
|
||||
|
||||
UpperTo<declarations>().AddFirst(predef);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void visit(procedure_definition pd)
|
||||
{
|
||||
|
|
@ -751,6 +860,9 @@ namespace SyntaxVisitors
|
|||
|
||||
// frninja 31/05/16 - добавляем метод-хелпер, возьмет на себя проверку разных ошибок уже существующим бэкендом
|
||||
CreateErrorCheckerHelper(pd);
|
||||
|
||||
// frninja 05/06/16 - вставляем предописание если метод-итератор описан не в классе (обычная функция) чтоб работали рекурсивные вызовы
|
||||
bool methodPredefCreated = InsertGlobalIteratorMethodPredefinition(pd);
|
||||
|
||||
// frninja 24/05/16 - оборачиваем одиночные операторы в begin..end
|
||||
AddBeginEndsVisitor addBeginEndsVis = new AddBeginEndsVisitor();
|
||||
|
|
@ -821,6 +933,12 @@ namespace SyntaxVisitors
|
|||
// frninja 20/05/16 - фикс для повторного обхода
|
||||
pd.has_yield = false;
|
||||
|
||||
// frninja 05/06/16 - убираем where-секцию у описания метода. Они уже скопированы куда надо
|
||||
if (methodPredefCreated)
|
||||
{
|
||||
pd.proc_header.where_defs = null;
|
||||
}
|
||||
|
||||
//mids = null; // вдруг мы выйдем из процедуры, не зайдем в другую, а там - оператор! Такого конечно не может быть
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue