Распространение проверки захвата имен на любые вложенные записи (в т.ч.не безымянные)
This commit is contained in:
parent
e48218cd9e
commit
45d177bebc
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
|||
public const string Major = "3";
|
||||
public const string Minor = "6";
|
||||
public const string Build = "2";
|
||||
public const string Revision = "2386";
|
||||
public const string Revision = "2387";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%COREVERSION%=2
|
||||
%REVISION%=2386
|
||||
%MINOR%=6
|
||||
%REVISION%=2387
|
||||
%COREVERSION%=2
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
3.6.2.2386
|
||||
3.6.2.2387
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.6.2.2386'
|
||||
!define VERSION '3.6.2.2387'
|
||||
|
|
|
|||
|
|
@ -1601,7 +1601,7 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return /*""+this.ClassName+" "+this.name+" "+*/this.UnknownID.ToString();
|
||||
return "yui(обраб.на сем.)"+this.ClassName+" "+this.UnknownID.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ namespace SyntaxVisitors.CheckingVisitors
|
|||
foreach (var member in defBlocks[0].members)
|
||||
{
|
||||
var q = member as var_def_statement;
|
||||
if (q == null)
|
||||
continue;
|
||||
var id = q.vars.idents[0]; // это просто имя
|
||||
var type = q.vars_type;
|
||||
var initValue = q.inital_value;
|
||||
|
|
@ -180,52 +182,9 @@ namespace SyntaxVisitors.CheckingVisitors
|
|||
var cd = st as class_definition;
|
||||
if (cd == null)
|
||||
return;
|
||||
if (cd.keyword == class_keyword.Record && cd.Parent is var_def_statement) // безымянная запись
|
||||
if (cd.keyword == class_keyword.Record)
|
||||
{
|
||||
if (cd.class_parents != null && cd.class_parents.Count > 0)
|
||||
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE", cd.class_parents[0].source_context);
|
||||
|
||||
var defBlocks = cd.body.class_def_blocks;
|
||||
|
||||
if (defBlocks[0].access_mod.access_level != access_modifer.public_modifer)
|
||||
{
|
||||
var f = cd.body.class_def_blocks.First();
|
||||
var loc = f.source_context;
|
||||
if (loc == null)
|
||||
loc = cd.source_context;
|
||||
throw new SyntaxVisitorError("UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION", loc);
|
||||
}
|
||||
|
||||
if (defBlocks.Count > 1)
|
||||
{
|
||||
var el1 = cd.body.class_def_blocks.ElementAt(1);
|
||||
var loc = el1.access_mod.source_context;
|
||||
if (loc == null)
|
||||
loc = cd.source_context;
|
||||
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS", loc);
|
||||
}
|
||||
|
||||
// здесь уже известно, что defBlocks.Count = 1 - пройтись по этому блоку и проверить, нет ли методов или свойств
|
||||
|
||||
foreach (var d in defBlocks[0].members)
|
||||
{
|
||||
var pd = d as procedure_definition;
|
||||
if (pd != null)
|
||||
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CONTAIN_METHODS", pd.source_context);
|
||||
var sp = d as simple_property;
|
||||
if (sp != null)
|
||||
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES", sp.source_context);
|
||||
}
|
||||
|
||||
var cdvis = OneUnnamedRecordCaptureNamesVisitor.New(cd);
|
||||
cdvis.CollectNames();
|
||||
// после накопления имен подниматься по внешнему контексту, пропуская эту запись, и искать переменные и типы
|
||||
// Переменные - в var_def_statement. Типы - в type_definition, в типовых параметрах обобщенных процедур и в типовых параметрах имен типов
|
||||
|
||||
// Подняться вверх до program_module и запомнить последнюю class_definition, procedure_definition
|
||||
// или class_definition или type_declaration если это именованный тип
|
||||
// То есть у class_definition проверять Parent - если это type_declaration, то смотреть на имя типа, а если это var_def_statement, то смотреть на имена переменных
|
||||
|
||||
// Проверить, что это неглобальная запись. Если глобальная, то можно всё - и выйти
|
||||
syntax_tree_node MostUpperNodeWithNotGlobalNames = null;
|
||||
|
||||
syntax_tree_node sn = cd;
|
||||
|
|
@ -243,6 +202,59 @@ namespace SyntaxVisitors.CheckingVisitors
|
|||
}
|
||||
}
|
||||
|
||||
if (MostUpperNodeWithNotGlobalNames == null) // то есть, это - глобальный уроень, и захватывать можно всё
|
||||
return;
|
||||
|
||||
// если попали сюда, то запись вложенная
|
||||
|
||||
//if (cd.Parent is var_def_statement) // безымянная запись
|
||||
{
|
||||
if (cd.class_parents != null && cd.class_parents.Count > 0)
|
||||
throw new SyntaxVisitorError("NESTED_RECORD_CANNOT_IMPLEMENT_INTERFACE", cd.class_parents[0].source_context);
|
||||
|
||||
var defBlocks = cd.body.class_def_blocks;
|
||||
|
||||
if (defBlocks[0].access_mod.access_level != access_modifer.public_modifer)
|
||||
{
|
||||
var f = cd.body.class_def_blocks.First();
|
||||
var loc = f.source_context;
|
||||
if (loc == null)
|
||||
loc = cd.source_context;
|
||||
throw new SyntaxVisitorError("NESTED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION", loc);
|
||||
}
|
||||
|
||||
if (defBlocks.Count > 1)
|
||||
{
|
||||
var el1 = cd.body.class_def_blocks.ElementAt(1);
|
||||
var loc = el1.access_mod.source_context;
|
||||
if (loc == null)
|
||||
loc = cd.source_context;
|
||||
throw new SyntaxVisitorError("NESTED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS", loc);
|
||||
}
|
||||
|
||||
// здесь уже известно, что defBlocks.Count = 1 - пройтись по этому блоку и проверить, нет ли методов или свойств
|
||||
|
||||
foreach (var d in defBlocks[0].members)
|
||||
{
|
||||
var pd = d as procedure_definition;
|
||||
if (pd != null)
|
||||
throw new SyntaxVisitorError("NESTED_RECORD_CANNOT_CONTAIN_METHODS", pd.source_context);
|
||||
var sp = d as simple_property;
|
||||
if (sp != null)
|
||||
throw new SyntaxVisitorError("NESTED_RECORD_CANNOT_CONTAIN_PROPERTIES", sp.source_context);
|
||||
}
|
||||
}
|
||||
|
||||
// после накопления имен подниматься по внешнему контексту, пропуская эту запись, и искать переменные и типы
|
||||
// Переменные - в var_def_statement. Типы - в type_definition, в типовых параметрах обобщенных процедур и в типовых параметрах имен типов
|
||||
|
||||
// Подняться вверх до program_module и запомнить последнюю class_definition, procedure_definition
|
||||
// или class_definition или type_declaration если это именованный тип
|
||||
// То есть у class_definition проверять Parent - если это type_declaration, то смотреть на имя типа, а если это var_def_statement, то смотреть на имена переменных
|
||||
|
||||
var cdvis = OneUnnamedRecordCaptureNamesVisitor.New(cd);
|
||||
cdvis.CollectNames();
|
||||
|
||||
var localsvis = CollectDefNamesFromMostUpperLocalContextVisitor.New(cd);
|
||||
if (MostUpperNodeWithNotGlobalNames != null)
|
||||
{
|
||||
|
|
@ -266,7 +278,7 @@ namespace SyntaxVisitors.CheckingVisitors
|
|||
if (string.Compare(s,lname,true)==0 && !b)
|
||||
{
|
||||
// то надо еще проверить cvdi чтобы там как раз не было этих имен
|
||||
throw new SyntaxVisitorError("UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT", id);
|
||||
throw new SyntaxVisitorError("NESTED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
TestSuite/errors/err0355_named_local_record.pas
Normal file
15
TestSuite/errors/err0355_named_local_record.pas
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
type
|
||||
A = class
|
||||
i: integer;
|
||||
procedure p;
|
||||
type b = record
|
||||
x := i;
|
||||
end;
|
||||
begin
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
end.
|
||||
19
TestSuite/errors/err0356_named_local_record2.pas
Normal file
19
TestSuite/errors/err0356_named_local_record2.pas
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
var global: integer;
|
||||
|
||||
type int = integer;
|
||||
|
||||
type Class1<T,T1> = class
|
||||
classfield: integer;
|
||||
const cc = 2;
|
||||
function p<PPT>(pa,pb: real): integer;
|
||||
type int1 = record
|
||||
j: integer := cc;
|
||||
mostinternal1: set of integer := [j];
|
||||
end;
|
||||
begin
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
end.
|
||||
18
TestSuite/errors/err0357_named_local_record3.pas
Normal file
18
TestSuite/errors/err0357_named_local_record3.pas
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
var global: integer;
|
||||
|
||||
type int = integer;
|
||||
|
||||
type Class1<T,T1> = class
|
||||
classfield: integer;
|
||||
const cc = 2;
|
||||
function p(pa,pb: real): integer;
|
||||
type int1 = record
|
||||
j: T := 1;
|
||||
end;
|
||||
begin
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
end.
|
||||
12
TestSuite/errors/err0358_named_local_record4.pas
Normal file
12
TestSuite/errors/err0358_named_local_record4.pas
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
var global: integer;
|
||||
|
||||
function p(pa,pb: real): integer;
|
||||
type int1 = record
|
||||
j: T := pa;
|
||||
end;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
end.
|
||||
|
|
@ -28,10 +28,10 @@ Var_{0}_is_already_defined=Variable {0} is already defined
|
|||
INVALID_INTERFACE_MEMBER=Interfaces cannot contain fields and method implementation
|
||||
INDEXED_AUTO_PROPERTY=Autoproperties cannot be indexed properties
|
||||
|
||||
UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE=Unnamed records can not implement interfaces
|
||||
UNNAMED_RECORD_CANNOT_CONTAIN_METHODS=Unnamed records can not contain methods
|
||||
UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES=Unnamed records can not contain properties
|
||||
UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS=Unnamed records can not contain constructors
|
||||
UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Unnamed records can contain only one section with public visibility
|
||||
UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Unnamed records can not contain several visibility section
|
||||
UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT=Unnamed records cannot catch names from nonglobal context
|
||||
NESTED_RECORD_CANNOT_IMPLEMENT_INTERFACE=Nested records can not implement interfaces
|
||||
NESTED_RECORD_CANNOT_CONTAIN_METHODS=Nested records can not contain methods
|
||||
NESTED_RECORD_CANNOT_CONTAIN_PROPERTIES=Nested records can not contain properties
|
||||
NESTED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS=Nested records can not contain constructors
|
||||
NESTED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Nested records can contain only one section with public visibility
|
||||
NESTED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Nested records can not contain several visibility section
|
||||
UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT=Nested records cannot catch names from nonglobal context
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ Var_{0}_is_already_defined=Переменная {0} уже определена
|
|||
INVALID_INTERFACE_MEMBER=Интерфейсы не могут содержать поля и реализацию методов
|
||||
INDEXED_AUTO_PROPERTY=Автосвойства не могут быть индексными
|
||||
|
||||
UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE=Безымянные записи не могут реализовывать интерфейсы
|
||||
UNNAMED_RECORD_CANNOT_CONTAIN_METHODS=Безымянные записи не могут содержать методы
|
||||
UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES=Безымянные записи не могут содержать свойства
|
||||
UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS=Безымянные записи не могут содержать конструкторы
|
||||
UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Безымянные записи могут содержать лишь одну секцию с public-видимостью
|
||||
UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Безымянные записи не могут содержать несколько секций видимости
|
||||
UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT=Безымянные записи не могут захватывать имена из неглобального контекста
|
||||
NESTED_RECORD_CANNOT_IMPLEMENT_INTERFACE=Вложенные записи не могут реализовывать интерфейсы
|
||||
NESTED_RECORD_CANNOT_CONTAIN_METHODS=Вложенные записи не могут содержать методы
|
||||
NESTED_RECORD_CANNOT_CONTAIN_PROPERTIES=Вложенные записи не могут содержать свойства
|
||||
NESTED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS=Вложенные записи не могут содержать конструкторы
|
||||
NESTED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Вложенные записи могут содержать лишь одну секцию с public-видимостью
|
||||
NESTED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Вложенные записи не могут содержать несколько секций видимости
|
||||
NESTED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT=Вложенные записи не могут захватывать имена из неглобального контекста
|
||||
|
|
|
|||
Loading…
Reference in a new issue