Skip to content

Commit d133766

Browse files
committed
copied from Matrix repo
1 parent 8d3553c commit d133766

File tree

149 files changed

+577355
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+577355
-0
lines changed

.clojuredart/analyzer.dart

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
import 'dart:io';
2+
import 'dart:convert';
3+
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
4+
import 'package:analyzer/dart/analysis/results.dart';
5+
import 'package:analyzer/error/error.dart';
6+
import 'package:analyzer/file_system/physical_file_system.dart';
7+
import 'package:analyzer/file_system/overlay_file_system.dart';
8+
import 'package:analyzer/dart/element/visitor.dart';
9+
import 'package:analyzer/dart/element/element.dart';
10+
import 'package:analyzer/dart/element/type.dart';
11+
import 'package:analyzer/dart/element/nullability_suffix.dart';
12+
13+
final Set<String> libsToDo = {};
14+
15+
final Set<String> libsDone = {};
16+
17+
final Map<String, String> packages = {};
18+
19+
String libPathToPackageName(String path) {
20+
if (packages[path] != null) return packages[path] as String;
21+
for (final pname in packages.keys) {
22+
if (path.startsWith(pname)) {
23+
String pack = packages[pname] as String;
24+
String result = path.replaceRange(0, pname.length, pack);
25+
packages[path] = result;
26+
return result;
27+
}
28+
}
29+
return path;
30+
}
31+
32+
bool isPublic(Element e) => e.isPublic;
33+
34+
R fnil<R,E>(R f(E e), E? x, R fallback) => x != null ? f(x) : fallback;
35+
36+
String M(Map<String,dynamic> m) {
37+
final sb = StringBuffer("{");
38+
var first = true;
39+
m.forEach((k, v) {
40+
if (v == null || v == false || v is Iterable && v.isEmpty) return;
41+
if (first) first=false; else sb.write("\n");
42+
sb..write(k)..write(" ");
43+
if (v is Iterable) {
44+
sb..write("[")
45+
..writeAll(v, " ")
46+
..write("]");
47+
return;
48+
}
49+
sb.write(v);
50+
});
51+
sb.write("}");
52+
return sb.toString();
53+
}
54+
55+
String emitType(DartType t) {
56+
final lib = t.element?.library?.identifier;
57+
if (lib != null) libsToDo.add(lib);
58+
if (t is FunctionType) {
59+
return M({':type': "\"Function\"",
60+
':return-type': emitType(t.returnType),
61+
':parameters': t.parameters.map(emitParameter),
62+
':type-parameters': t.typeFormals.map(emitTypeParameter)});
63+
}
64+
var name = t.displayName;
65+
final i = name.indexOf("<");
66+
if (i >= 0) name = name.substring(0, i);
67+
final isParam = t is TypeParameterType;
68+
//if (!isParam || lib != null) addLibIdentifierIfNotContains(libsToDo, lib as String);
69+
return M({':type': "\"${name}\"",
70+
':nullable': t.isDartCoreNull || t.nullabilitySuffix == NullabilitySuffix.question,
71+
':is-param': isParam,
72+
':lib': (isParam || lib == null ? null : "\"${libPathToPackageName(lib)}\""),
73+
':type-parameters': t is ParameterizedType ? t.typeArguments.map(emitType) : null
74+
});
75+
}
76+
77+
String emitTypeParameter(TypeParameterElement tp) =>
78+
M({':type': "\"${tp.displayName}\"",
79+
':is-param': true,
80+
':bound': fnil(emitType,tp.bound,null)});
81+
82+
String emitParameter(ParameterElement p) {
83+
final name = p.displayName;
84+
return M({":name": name.isEmpty ? null : name, ":kind": p.isNamed ? ':named' : ':positional', ':type': emitType(p.type), ':optional': p.isOptional});
85+
}
86+
87+
class TopLevelVisitor extends ThrowingElementVisitor {
88+
void visitImportElement(ImportElement e) {
89+
print(e.displayName);
90+
throw "coucou";
91+
}
92+
93+
void visitClassElement(ClassElement e) {
94+
print("\"${e.displayName}\"");
95+
Map<String,dynamic> classData =
96+
{':kind': ':class',
97+
':lib': '"${libPathToPackageName(e.library.identifier)}"',
98+
':private': e.isPrivate,
99+
':internal': e.hasInternal,
100+
':const': e.unnamedConstructor?.isConst,
101+
':type-parameters': e.typeParameters.map(emitTypeParameter),
102+
':super': fnil(emitType,e.supertype,null),
103+
':mixins': e.mixins.map(emitType),
104+
':interfaces': e.interfaces.map(emitType),
105+
':on': e.superclassConstraints.map(emitType)};
106+
for(final m in e.methods.where(isPublic)) {
107+
final name = m.displayName;
108+
classData["\"${name == '-' && m.parameters.isEmpty ? 'unary-' : name}\""]=
109+
M({':kind': ':method', ':operator': m.isOperator,
110+
':static': m.isStatic,
111+
':return-type': emitType(m.returnType),
112+
':parameters': m.parameters.map(emitParameter),
113+
':type-parameters': m.typeParameters.map(emitTypeParameter)
114+
});
115+
}
116+
for(final c in e.constructors.where(isPublic)) {
117+
classData["\"${c.displayName}\""]=
118+
M({':kind': ':constructor',
119+
':return-type': emitType(c.returnType),
120+
':parameters': c.parameters.map(emitParameter),
121+
':type-parameters': c.typeParameters.map(emitTypeParameter)
122+
});
123+
}
124+
for(final f in e.fields.where(isPublic)) {
125+
classData["\"${f.displayName}\""]=
126+
M({':kind': ':field',
127+
':static': f.isStatic,
128+
':getter': f.getter!=null,
129+
':setter': f.setter!=null,
130+
':type': emitType(f.type)
131+
});
132+
}
133+
print(M(classData));
134+
}
135+
void visitPropertyAccessorElement(PropertyAccessorElement e) {
136+
print("; getter/setter ${e.displayName}");
137+
}
138+
void visitTopLevelVariableElement(TopLevelVariableElement e) {
139+
print("\"${e.displayName}\"");
140+
print(M({':kind': ':field',
141+
':const': e.isConst,
142+
':getter': e.getter!=null,
143+
':setter': e.setter!=null,
144+
':type': emitType(e.type)
145+
}));
146+
}
147+
void visitTypeAliasElement(TypeAliasElement e) {
148+
print("; typedef ${e.displayName}");
149+
}
150+
void visitFunctionElement(FunctionElement e) {
151+
print("\"${e.displayName}\"");
152+
Map<String,dynamic> classData =
153+
{':kind': ':function',
154+
':lib': '"${libPathToPackageName(e.library.identifier)}"',
155+
':parameters': e.parameters.map(emitParameter),
156+
':return-type': emitType(e.returnType),
157+
':type-parameters': e.typeParameters.map(emitTypeParameter)};
158+
print(M(classData));
159+
}
160+
void visitExtensionElement(ExtensionElement e) {
161+
print("; extension ${e.displayName}");
162+
}
163+
}
164+
165+
Future<void> analyzePaths (session, List<String> paths) async {
166+
for (final p in paths) {
167+
final libraryElementResult = await session.getLibraryByUri(p);
168+
if (!libsDone.add(p)) continue;
169+
if (libraryElementResult is LibraryElementResult) {
170+
final libraryElement = (libraryElementResult as LibraryElementResult).element;
171+
final packageName = libPathToPackageName(libraryElement.identifier);
172+
if (packageName != p) {
173+
libsToDo.add(packageName);
174+
continue;
175+
}
176+
print("\"$p\" {"); // open 1
177+
for (final top in libraryElement.topLevelElements) {
178+
if (top.isPublic) top.accept(TopLevelVisitor());
179+
}
180+
var exs = libraryElement.exports;
181+
if (exs.isNotEmpty) {
182+
print(":exports [");
183+
for (final ex in libraryElement.exports) {
184+
if (ex.exportedLibrary != null) {
185+
var n = ex.exportedLibrary?.identifier as String;
186+
libsToDo.add(n);
187+
for (final comb in ex.combinators) {
188+
if (comb is ShowElementCombinator) {
189+
print(M({":lib": "\"${libPathToPackageName(n)}\"", ':shown': comb.shownNames.map((name) => "\"${name}\"").toList()}));
190+
}
191+
if (comb is HideElementCombinator) {
192+
print(M({":lib": "\"${libPathToPackageName(n)}\"", ':hidden': comb.hiddenNames.map((name) => "\"${name}\"").toList()}));
193+
}
194+
}
195+
if (ex.combinators.isEmpty) {
196+
print(M({":lib": "\"${n}\""}));
197+
}
198+
}
199+
}
200+
print("]");
201+
}
202+
print(":private ${libraryElement.isPrivate}");
203+
print(":internal ${libraryElement.hasInternal}");
204+
print("}"); // close 1
205+
}
206+
}
207+
}
208+
209+
void main(args) async {
210+
final resourceProvider = OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
211+
var ctx = resourceProvider.pathContext;
212+
late Directory dir;
213+
if (args.isEmpty) dir = Directory.current;
214+
else dir = Directory(args.first);
215+
Uri projectDirectoryUri = dir.uri;
216+
final collection = AnalysisContextCollection(
217+
includedPaths: [ctx.normalize(projectDirectoryUri.path)],
218+
resourceProvider: resourceProvider
219+
);
220+
final includedDependenciesPaths = <String>[];
221+
for (final context in collection.contexts) {
222+
final currentSession = context.currentSession;
223+
var packageFileJsonString = context.contextRoot.packagesFile?.readAsStringSync();
224+
// TODO throw when package file does not exist
225+
if (packageFileJsonString != null) {
226+
var jsonContent = json.decode(packageFileJsonString);
227+
for (final jc in jsonContent["packages"]) {
228+
var rootUri = jc["rootUri"];
229+
if (jc.containsKey("packageUri")) {
230+
rootUri = ctx.join(rootUri, jc["packageUri"]);
231+
}
232+
packages[rootUri] = 'package:' + jc["name"] + '/';
233+
String normalizedPath = ctx.normalize(ctx.fromUri(rootUri));
234+
if (!ctx.isRelative(normalizedPath)) {
235+
includedDependenciesPaths.add(normalizedPath);
236+
} else {
237+
stderr.write("WARNING: could not analyze '" + jc["name"] + "' package \n");
238+
// TODO: better message on consequences
239+
}
240+
};
241+
}
242+
}
243+
// NOTE : deps analysis
244+
final collectionDeps = AnalysisContextCollection(
245+
includedPaths: includedDependenciesPaths as List<String>,
246+
resourceProvider: resourceProvider
247+
);
248+
print("{"); // open 2
249+
for (final context in collectionDeps.contexts) {
250+
final currentSession = context.currentSession;
251+
var files = context.contextRoot.analyzedFiles().map((n) => ctx.toUri(n).toString()).toList();
252+
files.removeWhere((p) => ctx.extension(p) != '.dart');
253+
await analyzePaths(currentSession, files);
254+
}
255+
/// Only necessary for dart:* libs
256+
do {
257+
var libs = libsToDo.difference(libsDone);
258+
libsToDo..clear()..addAll(libs);
259+
await analyzePaths(collection.contexts.first.currentSession, libsToDo.toList());
260+
}
261+
while(libsToDo.isNotEmpty);
262+
print("}"); // close 2
263+
}

0 commit comments

Comments
 (0)