-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdescription.txt
More file actions
127 lines (106 loc) · 6.65 KB
/
Copy pathdescription.txt
File metadata and controls
127 lines (106 loc) · 6.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
codeOrchestra.AbstractTreeModificationExtension
saveSyntaxTree(CompilationUnit unit)
сериализует синтаксическое дерево для юнита и сохраняет его на диск
TODO:
сваливать не в одну папку, а в соответствии с пакетами
loadSyntaxTrees()
создаёт инстанс projectNavigator и загружает в него сохранённые предже деревья
TODO:
структура папок, как и при save
performModifications(CompilationUnit unit)
собственно метод, который вызывается после парсинга исходника
parse12, analyze1234, generate
методы которые компилятор вызывает. Кроме parse1 не нужны
addLiveCodingClass(String className, FunctionDefinitionNode functionDefinitionNode, ObjectList<Node> methodBody, boolean incremental)
создаёт ливкодинговый класс, оборачивающий данный метод
className - имя исходного класса, содержащего метод
functionDefinitionNode - сам метод (для поулчения из него имени, контекста, и т.п.)
methodBody - тело метода (предполагается, что метод подаётся уже без тела, так что старое тело идёт отдельно)
incremental - ливкодинговые классы в базовой и инкрементальной фазах немного отличаются
TODO:
добавить обработку аргументов метода - тупо их копировать из исходного метода
codeOrchestra.LCBaseExtension
performModifications(CompilationUnit unit)
при первом проходе базовой компиляции просто сохраняет дерево юнита
при втором проходе загружает сохранённые деревья
добавляет класс ModelDependencies, если такой ещё не добавлен
для каждого ливкодингового метода вызывает оборачивание его в класс
добавляет поле, ссылающееся на ModelDependencies
TODO:
добавить галочку - вытаскивать все методы, или только помеченные аннотацией
extractMethodToLiveCodingClass(FunctionDefinitionNode functionDefinitionNode, ClassDefinitionNode classDefinitionNode)
запускает три действия
меняет тело метода на вызов метода из ливкодингового класса
создаёт ливкодинговый класс для метода
добавляет листнера этого метода в класс
fillStubMethodBody(FunctionDefinitionNode functionDefinitionNode, String className)
собственно, создаёт вызов ливкодингового метода из ливкодингового класса
TODO:
передача аргументов
addListener(FunctionDefinitionNode functionDefinitionNode, ClassDefinitionNode classDefinitionNode)
добавляет метод, который по событию запускает наш метод
TODO:
передача аргументов
addModelDependenciesUnit(String packageName, Context cx)
создаёт класс ModelDependencies
addLiveCodingStarterUnit(String packageName, Context cx)
создаёт класс LiveCodingStarter
codeOrchestra.LCIncrementalExtension
LCIncrementalExtension(String fqClassName)
в конструкторе подаётся имя класса из которого нужно доставать методы
TODO:
расширить до нескольких классов
performModifications(CompilationUnit unit)
работает если имя класса совпадает с тем, который указан при создании
загружает деревья и сохраняет новое дерево класса, чтоб к следующей инкрементальной компиляции иметь обновлённые файлы на диске
запускает поиск изменившихся методов и если их находит, для каждого создаёт ливкодинговый класс
исходных класс очищается от методов, а в его конструктор добавляются ссылки на ливкодинговые классы
в консоль выводятся имена новых классов
TODO:
Что делать в случае, если изменений нет? Или такого быть не может?
Надо как-то убирать из компиляции все юниты кроме инкрементальных. Сейчас это не понятно как делать, поскольку добавление в процессинг новых юнитов происходит через ссылки на них в уже имеющихся
findChangedMethods(ClassDefinitionNode originalClass, ClassDefinitionNode modifiedClass)
ищет изменившиеся с прошлой компиляции методы
codeOrchestra.ProvidedPackages
класс со списком файлов, не относящихся к исходникам, которые надо ливкодить. Нужен для того, чтоб их отличать.
TODO:
поставлять эти исходники в swcшке, тогда список не будет нужен
codeOrchestra.FakeASVirtualFile
реализация VirtualFile, которая используется при создании новых юнитов, поскольку юнит должен иметь ссылку на свой файл.
codeOrchestra.LiveCodingUtil
методы для создания названия ливкодинговых классов и проверки методов на ливкодинговость
codeOrchestra.tree.TreeUtil
полезные методы для модификации флексового дерева
codeOrchestra.tree.TreeNavigator
полезные методы для поиска и проверок во флексовом дереве
codeOrchestra.tree.ProjectNavigator
getLiveCodingClassNames(String packageName)
возвращает список имён ливкодинговых классов для пакета. Используется при создании ModelDependencies
TODO:
Этот метод вызывается ещё до создания ливкодинговых классов, так что предполагается, что классы будут созданы
getClassNames(String packageName)
Ищет классы в пакете
codeOrchestra.tree.RegularNode
Нода из которых строится регулярная структура, отображающая флексовое дерево.
Структура получается похожая на SNode, дающая обратные ссылки и возможность одинаковым образом работать со всеми нодами флексового дерева
Очень должно понадобиться при трансформации тел ливкодинговых методов
TODO:
дописать полезных методов
codeOrchestra.tree.CONode, ClassCONode, MethodCONode, FieldCONode
для упрощения создания классов
идея такая - создаём эти объекты, указываем в них строчки, характеризующие класс/методы/поля, такие как имя, названия аргументов и т.п. После чего вызываем метод "сгенерить" и получаем флексовое дерево
codeOrchestra.tree.visitor
классы для обхода флексового дерева. Они знают какие есть поля у каждой ноды.
используется при создании регулярного дерева по флексовому
так же для сравнения двух флексовых деревьев и для запуска некоторого процессора на каждой ноде дерева (для чего угодно)
TODO:
Листья дерева прописаны только для тех нод, которые могут быть внутри тел методов
Дети прописаны только те, которые не null при парсинге
codeOrchestra.tree.processor
то, что можно подавать в NodeVisitor для выполнения при обходе
Общие проблемы:
1. Не получается сделать модификацию компилятора в виде extension. Хотя бы потому что из расширения невозможно добавить новый юнит компиляции. Так что пользователю придётся использовать именно наш компилятор.
2. Во флексовом дереве нет информации о связях между нодами (например вызов метода - декларация метода), поскольку там такое не нужно. Точнее эта информация получается только при кодогенерации. Это затрудняет анализ тела метода.
3. На данный момент нет способов проверить, правильно ли вообще генерятся флэшки, то есть они нормально компилируются, все нужные методы в них попадают, но запустить нечем.
4. Не полностью решён вопрос с добавлением юнитов. Сейчас это происходит так: Создаём юнит, в существующем юните добавляем на него ссылку и при резолве наш новый юнит подтягивается в процессинг. Надо нацчиться просто добавлять, а так же удалять юниты.
5. Тестирование, отладка, профилировка?