Объявил класс
using Nemerle;
using Nemerle.Collections;
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
using Nemerle.Compiler.Typedtree;
using Nemerle.Text;
using Nemerle.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
// Alias
using nc = Nemerle.Compiler;
using pe = Nemerle.Compiler.Parsetree.PExpr;
namespace sampleApplication
{
// Class
class TestDeclarations{}
}
namespace sampleApplication.TestDeclarationsNS
{
// Macro
macro testMacro(param1, param2){<[]>}
// Class
internal class TestDeclarations{}
// Interface
public interface AInterface{}
// Variant
public variant WorkingClass1
{
| Variant1 {val: string;}
| Variant2 {val: int;}
public static staticMethod(): void
{
}
public method(): void
{
}
}
// Delegate
delegate testDelegate(a: System.Int32, b: PExpr): int;
// Enum
enum TestEnum {| test1 = 1 | test2 | test3 = 10};
// VariantOption?
}
Написал макрос
using Nemerle;
using Nemerle.Collections;
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
using Nemerle.Compiler.Typedtree;
using Nemerle.Text;
using Nemerle.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
namespace sampleMacroLibrary
{
[MacroUsage(MacroPhase.WithTypedMembers, MacroTargets.Assembly)]
macro PrintTopDeclaration()
{
PrintTopDeclarationImpl.DoTransform(Macros.ImplicitCTX(), )
}
module PrintTopDeclarationImpl
{
public static logFile: LogFile = LogFile("D:/logFile_tops.txt");
// Выводим все декларации верхнего уровня в сборке
public printTopDecls(typeBuilders: list[TypeBuilder]): void
{
def printDecl(tb: TypeBuilder)
{
// Подготавливаем к выводу локацию имени класса и его имена, полученные разными способами
def LocationString = tb.NameLocation.ToString(); // Объект, декларирующий локацию имени типа
def (fullName, typeName, parsedTypeName) = (tb.Ast.FullName, tb.Name, tb.ParsedName.Id);
// Узнаём, какая именно декларация:
// передаём tb.Ast типа TopDeclaration и узнаём, какой именно это вариант TopDeclaration (Class, Alias и т.п)
def printDeclType(_: Nemerle.Compiler.Parsetree.TopDeclaration)
{
| TopDeclaration.Class => "Class"
| TopDeclaration.Alias => "Alias" // Не получим
| TopDeclaration.Interface => "Interface"
| TopDeclaration.Variant => "Variant"
| TopDeclaration.VariantOption => "VariantOption"
| TopDeclaration.Macro => "Macro" // Не получим
| TopDeclaration.Delegate => "Delegate" // Не получим
| TopDeclaration.Enum => "Enum"
| _ => "Unknown"
}
// Собственно, выводим
logFile.write($"\r\n\$fullName\r\n\t\t$typeName\r\n\t\t$parsedTypeName\r\n\t\t$LocationString\r\n\t\t$(printDeclType(tb.Ast))");
}
// Рекурсивно обходим список деклараций
match (typeBuilders)
{
| head::tail => printDecl(head); printTopDecls(tail);
| [] => ()
}
}
public DoTransform(typer : Typer, ) : void
{
Macros.DefineCTX(typer);
// Вызываем вывод всех деклараций в сборке, декларации объявлены в typer.Manager.Hierarchy.infos
printTopDecls(typer.Manager.Hierarchy.infos);
}
}
}
Получаю результат
sampleApplication.TestDeclarationsNS.TestEnum
TestEnum
TestEnum
TestDeclarations.n:49:10:49:18:
Enum
sampleApplication.TestDeclarationsNS.testDelegate
testDelegate
testDelegate
TestDeclarations.n:47:14:47:26:
Class
sampleApplication.TestDeclarationsNS.WorkingClass1.Variant2
Variant2
Variant2
TestDeclarations.n:36:11:36:19:
VariantOption
sampleApplication.TestDeclarationsNS.WorkingClass1.Variant1
Variant1
Variant1
TestDeclarations.n:35:11:35:19:
VariantOption
sampleApplication.TestDeclarationsNS.WorkingClass1
WorkingClass1
WorkingClass1
TestDeclarations.n:33:20:33:33:
Variant
sampleApplication.TestDeclarationsNS.AInterface
AInterface
AInterface
TestDeclarations.n:31:22:31:32:
Interface
sampleApplication.TestDeclarationsNS.TestDeclarations
TestDeclarations
TestDeclarations
TestDeclarations.n:29:20:29:36:
Class
sampleApplication.TestDeclarationsNS.testMacroMacro
testMacroMacro
testMacroMacro
TestDeclarations.n:26:36:26:42:
Class
sampleApplication.TestDeclarations
TestDeclarations
TestDeclarations
TestDeclarations.n:20:11:20:27:
Class
sampleApplication.Program
Program
Program
Program.n:7:16:7:23:
Class
sampleApplication.WorkingClass.ClassEnumeration
ClassEnumeration
ClassEnumeration
MainForm.n:86:14:86:30:
Enum
sampleApplication.WorkingClass.InnerClass
InnerClass
InnerClass
MainForm.n:70:22:70:32:
Class
sampleApplication.WorkingClass
WorkingClass
WorkingClass
MainForm.n:51:27:51:39:
Class
sampleApplication.MainForm
MainForm
MainForm
MainForm.n:28:26:28:34:
Class
sampleApplication.TestDeclarations
TestDeclarations
TestDeclarations
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:20:11:20:27:
Class
sampleApplication.TestDeclarationsNS.testMacroMacro
testMacroMacro
testMacroMacro
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:26:36:26:42:
Class
sampleApplication.TestDeclarationsNS.TestDeclarations
TestDeclarations
TestDeclarations
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:29:20:29:36:
Class
sampleApplication.TestDeclarationsNS.AInterface
AInterface
AInterface
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:31:22:31:32:
Interface
sampleApplication.TestDeclarationsNS.WorkingClass1.Variant2
Variant2
Variant2
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:36:11:36:19:
VariantOption
sampleApplication.TestDeclarationsNS.WorkingClass1.Variant1
Variant1
Variant1
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:35:11:35:19:
VariantOption
sampleApplication.TestDeclarationsNS.WorkingClass1
WorkingClass1
WorkingClass1
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:33:20:33:33:
Variant
sampleApplication.TestDeclarationsNS.testDelegate
testDelegate
testDelegate
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:47:14:47:26:
Class
sampleApplication.TestDeclarationsNS.TestEnum
TestEnum
TestEnum
D:\works\статьи\простые\AST\article\sampleApplication\TestDeclarations.n:49:10:49:18:
Enum
sampleApplication.Program
Program
Program
D:\works\статьи\простые\AST\article\sampleApplication\Program.n:7:16:7:23:
Class
sampleApplication.MainForm
MainForm
MainForm
D:\works\статьи\простые\AST\article\sampleApplication\MainForm.n:28:26:28:34:
Class
sampleApplication.WorkingClass.ClassEnumeration
ClassEnumeration
ClassEnumeration
D:\works\статьи\простые\AST\article\sampleApplication\MainForm.n:86:14:86:30:
Enum
sampleApplication.WorkingClass.InnerClass
InnerClass
InnerClass
D:\works\статьи\простые\AST\article\sampleApplication\MainForm.n:70:22:70:32:
Class
sampleApplication.WorkingClass
WorkingClass
WorkingClass
D:\works\статьи\простые\AST\article\sampleApplication\MainForm.n:89:27:89:39:
Class
По выделенному жирным возникает вопрос:
Как получить тип TopDeclaration.Alias
Почему макрос и делегат были внесены в дерево типом TopDeclaration.Class, а не Macro и Delegate, как можно было бы подразумевать?
Здравствуйте, FDSC, Вы писали:
FDS>
FDS>Как получить тип TopDeclaration.Alias
FDS>Почему макрос и делегат были внесены в дерево типом TopDeclaration.Class, а не Macro и Delegate, как можно было бы подразумевать?
FDS>
alias добывается так:
type Integer = int;
насчет Macro і Delegate — довольно странно.
Здравствуйте, hardcase, Вы писали:
H>Это особая польская магия. Объявления макры и делегата превращаются в специального вида классы, при том их оригинальный TopDeclaration затирается.
Магия происходит тут — в
ScanTypeHierarchy.n
Здравствуйте, FDSC, Вы писали:
FDS>По выделенному жирным возникает вопрос:
FDS>Как получить тип TopDeclaration.Alias
Так:
def alias = <[ decl: type DynArray[Y] = System.Collections.Generic.List[Y]; ]>;
match (alias)
{
| ClassMember.TypeDeclaration(TopDeclaration.Alias as a) =>
Message.Warning(a.ToString());
| _ => ()
}
FDS>Почему макрос и делегат были внесены в дерево типом TopDeclaration.Class, а не Macro и Delegate, как можно было бы подразумевать?
Это уже Хардкейс сказал.
Поляки много подобных ошибок наделали. Видимо думали, что так оптимальнее. Они сворачивали АСТ раньше времени. Например, АСТ для пространств имен и юсингов вообще нет.