Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart

Issue 3006693002: Add an integration test for kythe support with bug fixes (Closed)
Patch Set: Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:convert'; 5 import 'dart:convert';
6 6
7 import 'package:analyzer/dart/ast/ast.dart'; 7 import 'package:analyzer/dart/ast/ast.dart';
8 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; 8 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
9 import 'package:analyzer/dart/ast/syntactic_entity.dart'; 9 import 'package:analyzer/dart/ast/syntactic_entity.dart';
10 import 'package:analyzer/dart/ast/token.dart'; 10 import 'package:analyzer/dart/ast/token.dart';
11 import 'package:analyzer/dart/ast/visitor.dart'; 11 import 'package:analyzer/dart/ast/visitor.dart';
12 import 'package:analyzer/dart/element/element.dart'; 12 import 'package:analyzer/dart/element/element.dart';
13 import 'package:analyzer/dart/element/type.dart'; 13 import 'package:analyzer/dart/element/type.dart';
14 import 'package:analyzer/dart/element/visitor.dart'; 14 import 'package:analyzer/dart/element/visitor.dart';
15 import 'package:analyzer/file_system/file_system.dart';
15 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; 16 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
17 import 'package:analyzer/src/generated/bazel.dart';
18 import 'package:analyzer/src/generated/gn.dart';
16 import 'package:analyzer_plugin/protocol/protocol_common.dart' 19 import 'package:analyzer_plugin/protocol/protocol_common.dart'
17 show KytheEntry, KytheVName; 20 show KytheEntry, KytheVName;
18 21
19 import 'schema.dart' as schema; 22 import 'schema.dart' as schema;
20 23
21 const int _notFound = -1; 24 const int _notFound = -1;
22 25
23 /// Computes analysis of the given compilation [unit]. The unit is assumed to
24 /// exist in the given [corpus] and to have the given text [contents]. Analysis
25 /// results are returned as a list of [KytheEntry] objects.
26 List<KytheEntry> computeIndex(
27 String corpus, CompilationUnit unit, String contents) {
28 final List<KytheEntry> entries = [];
29 var visitor = new KytheDartVisitor(
30 entries,
31 corpus,
32 new InheritanceManager(
33 resolutionMap.elementDeclaredByCompilationUnit(unit).library),
34 contents);
35 unit.accept(visitor);
36 return entries;
37 }
38
39 /// Given some [ConstructorElement], this method returns '<class-name>' as the 26 /// Given some [ConstructorElement], this method returns '<class-name>' as the
40 /// name of the constructor, unless the constructor is a named constructor in 27 /// name of the constructor, unless the constructor is a named constructor in
41 /// which '<class-name>.<constructor-name>' is returned. 28 /// which '<class-name>.<constructor-name>' is returned.
42 String _computeConstructorElementName(ConstructorElement element) { 29 String _computeConstructorElementName(ConstructorElement element) {
43 assert(element != null); 30 assert(element != null);
44 var name = element.enclosingElement.name; 31 var name = element.enclosingElement.name;
45 var constructorName = element.name; 32 var constructorName = element.name;
46 if (!constructorName.isEmpty) { 33 if (!constructorName.isEmpty) {
47 name = name + '.' + constructorName; 34 name = name + '.' + constructorName;
48 } 35 }
49 return name; 36 return name;
50 } 37 }
51 38
52 /// Create an anchor signature of the form '<start>-<end>'. 39 /// Create an anchor signature of the form '<start>-<end>'.
53 String _getAnchorSignature(int start, int end) { 40 String _getAnchorSignature(int start, int end) {
54 return '$start-$end'; 41 return '$start-$end';
55 } 42 }
56 43
57 String _getPath(Element e) { 44 String _getPath(ResourceProvider provider, Element e) {
58 // TODO(jwren) This method simply serves to provide the WORKSPACE relative 45 // TODO(jwren) This method simply serves to provide the WORKSPACE relative
59 // path for sources in Elements, it needs to be written in a more robust way. 46 // path for sources in Elements, it needs to be written in a more robust way.
60 // TODO(jwren) figure out what source generates a e != null, but 47 // TODO(jwren) figure out what source generates a e != null, but
61 // e.source == null to ensure that it is not a bug somewhere in the stack. 48 // e.source == null to ensure that it is not a bug somewhere in the stack.
62 if (e == null || e.source == null) { 49 if (e == null || e.source == null) {
63 // null sometimes when the element is used to generate the node type 50 // null sometimes when the element is used to generate the node type
64 // "dynamic" 51 // "dynamic"
65 return ''; 52 return '';
66 } 53 }
67 var path = e.source.fullName; 54 String path = e.source.fullName;
68 assert(path.lastIndexOf('CORPUS_NAME') != -1); 55 BazelWorkspace bazelWorkspace = BazelWorkspace.find(provider, path);
69 return path.substring(path.lastIndexOf('CORPUS_NAME') + 12); 56 if (bazelWorkspace != null) {
57 return provider.pathContext.relative(path, from: bazelWorkspace.root);
58 }
59 GnWorkspace gnWorkspace = GnWorkspace.find(provider, path);
60 if (gnWorkspace != null) {
61 return provider.pathContext.relative(path, from: gnWorkspace.root);
62 }
63 if (path.lastIndexOf('CORPUS_NAME') != -1) {
64 return path.substring(path.lastIndexOf('CORPUS_NAME') + 12);
65 }
66 return path;
70 } 67 }
71 68
72 /// If a non-null element is passed, the [SignatureElementVisitor] is used to 69 /// If a non-null element is passed, the [SignatureElementVisitor] is used to
73 /// generate and return a [String] signature, otherwise [schema.DYNAMIC_KIND] is 70 /// generate and return a [String] signature, otherwise [schema.DYNAMIC_KIND] is
74 /// returned. 71 /// returned.
75 String _getSignature(Element element, String nodeKind, String corpus) { 72 String _getSignature(ResourceProvider provider, Element element,
73 String nodeKind, String corpus) {
76 assert(nodeKind != schema.ANCHOR_KIND); // Call _getAnchorSignature instead 74 assert(nodeKind != schema.ANCHOR_KIND); // Call _getAnchorSignature instead
77 if (element == null) { 75 if (element == null) {
78 return schema.DYNAMIC_KIND; 76 return schema.DYNAMIC_KIND;
79 } 77 }
80 if (element is CompilationUnitElement) { 78 if (element is CompilationUnitElement) {
81 return _getPath(element); 79 return _getPath(provider, element);
82 } 80 }
83 return '$nodeKind:${element.accept(SignatureElementVisitor.instance)}'; 81 return '$nodeKind:${element.accept(SignatureElementVisitor.instance)}';
84 } 82 }
85 83
86 class CodedBufferWriter { 84 class CodedBufferWriter {
87 CodedBufferWriter(var v); 85 CodedBufferWriter(var v);
88 toBuffer() {} 86 toBuffer() {}
89 } 87 }
90 88
91 /// This visitor writes out Kythe facts and edges as specified by the Kythe 89 /// This visitor writes out Kythe facts and edges as specified by the Kythe
92 /// Schema here https://kythe.io/docs/schema/. This visitor handles all nodes, 90 /// Schema here https://kythe.io/docs/schema/. This visitor handles all nodes,
93 /// facts and edges. 91 /// facts and edges.
94 class KytheDartVisitor extends GeneralizingAstVisitor with OutputUtils { 92 class KytheDartVisitor extends GeneralizingAstVisitor with OutputUtils {
93 final ResourceProvider resourceProvider;
95 final List<KytheEntry> entries; 94 final List<KytheEntry> entries;
96 final String corpus; 95 final String corpus;
97 final InheritanceManager _inheritanceManager; 96 final InheritanceManager _inheritanceManager;
97 final String _contents;
98
98 String _enclosingFilePath = ''; 99 String _enclosingFilePath = '';
99 Element _enclosingElement; 100 Element _enclosingElement;
100 ClassElement _enclosingClassElement; 101 ClassElement _enclosingClassElement;
101 KytheVName _enclosingVName; 102 KytheVName _enclosingVName;
102 KytheVName _enclosingFileVName; 103 KytheVName _enclosingFileVName;
103 KytheVName _enclosingClassVName; 104 KytheVName _enclosingClassVName;
104 final String _contents;
105 105
106 KytheDartVisitor( 106 KytheDartVisitor(this.resourceProvider, this.entries, this.corpus,
107 this.entries, this.corpus, this._inheritanceManager, this._contents); 107 this._inheritanceManager, this._contents);
108 108
109 @override 109 @override
110 String get enclosingFilePath => _enclosingFilePath; 110 String get enclosingFilePath => _enclosingFilePath;
111 111
112 @override 112 @override
113 visitAnnotation(Annotation node) { 113 visitAnnotation(Annotation node) {
114 // TODO(jwren) To get the full set of cross refs correct, additional ref 114 // TODO(jwren) To get the full set of cross refs correct, additional ref
115 // edges are needed, example: from "A" in "A.namedConstructor()" 115 // edges are needed, example: from "A" in "A.namedConstructor()"
116 116
117 var start = node.name.offset; 117 var start = node.name.offset;
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 _safelyVisit(node.documentationComment); 331 _safelyVisit(node.documentationComment);
332 _safelyVisitList(node.metadata); 332 _safelyVisitList(node.metadata);
333 _safelyVisit(node.typeParameters); 333 _safelyVisit(node.typeParameters);
334 _safelyVisit(node.withClause); 334 _safelyVisit(node.withClause);
335 _safelyVisit(node.implementsClause); 335 _safelyVisit(node.implementsClause);
336 }); 336 });
337 } 337 }
338 338
339 @override 339 @override
340 visitCompilationUnit(CompilationUnit node) { 340 visitCompilationUnit(CompilationUnit node) {
341 _enclosingFilePath = _getPath(node.element); 341 _enclosingFilePath = _getPath(resourceProvider, node.element);
342 return _withEnclosingElement(node.element, () { 342 return _withEnclosingElement(node.element, () {
343 addFact(_enclosingFileVName, schema.NODE_KIND_FACT, 343 addFact(_enclosingFileVName, schema.NODE_KIND_FACT,
344 _encode(schema.FILE_KIND)); 344 _encode(schema.FILE_KIND));
345 addFact(_enclosingFileVName, schema.TEXT_FACT, _encode(_contents)); 345 addFact(_enclosingFileVName, schema.TEXT_FACT, _encode(_contents));
346 addFact(_enclosingFileVName, schema.TEXT_ENCODING_FACT, 346 addFact(_enclosingFileVName, schema.TEXT_ENCODING_FACT,
347 _encode(schema.DEFAULT_TEXT_ENCODING)); 347 _encode(schema.DEFAULT_TEXT_ENCODING));
348 348
349 // handle LibraryDirective: 349 // handle LibraryDirective:
350 350
351 // A "package" VName in Kythe, schema.PACKAGE_KIND, is a Dart "library". 351 // A "package" VName in Kythe, schema.PACKAGE_KIND, is a Dart "library".
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 } 1091 }
1092 } 1092 }
1093 } 1093 }
1094 1094
1095 /// This class is meant to be a mixin to concrete visitor methods to walk the 1095 /// This class is meant to be a mixin to concrete visitor methods to walk the
1096 /// [Element] or [AstNode]s produced by the Dart Analyzer to output Kythe 1096 /// [Element] or [AstNode]s produced by the Dart Analyzer to output Kythe
1097 /// [KytheEntry] protos. 1097 /// [KytheEntry] protos.
1098 abstract class OutputUtils { 1098 abstract class OutputUtils {
1099 /// A set of [String]s which have already had a name [KytheVName] created. 1099 /// A set of [String]s which have already had a name [KytheVName] created.
1100 final Set<String> nameNodes = new Set<String>(); 1100 final Set<String> nameNodes = new Set<String>();
1101
1101 String get corpus; 1102 String get corpus;
1103
1102 KytheVName get dynamicBuiltin => _vName(schema.DYNAMIC_KIND, '', '', ''); 1104 KytheVName get dynamicBuiltin => _vName(schema.DYNAMIC_KIND, '', '', '');
1103 1105
1104 String get enclosingFilePath; 1106 String get enclosingFilePath;
1105 1107
1106 List<KytheEntry> get entries; 1108 List<KytheEntry> get entries;
1109
1107 KytheVName get fnBuiltin => _vName(schema.FN_BUILTIN, '', '', ''); 1110 KytheVName get fnBuiltin => _vName(schema.FN_BUILTIN, '', '', '');
1111
1112 ResourceProvider get resourceProvider;
1113
1108 KytheVName get voidBuiltin => _vName(schema.VOID_BUILTIN, '', '', ''); 1114 KytheVName get voidBuiltin => _vName(schema.VOID_BUILTIN, '', '', '');
1109 1115
1110 /// This is a convenience method for adding anchors. If the [start] and [end] 1116 /// This is a convenience method for adding anchors. If the [start] and [end]
1111 /// offsets are provided, they are used, otherwise the offsets are computed by 1117 /// offsets are provided, they are used, otherwise the offsets are computed by
1112 /// using the [syntacticEntity]. If a non-empty list of edges is provided, as 1118 /// using the [syntacticEntity]. If a non-empty list of edges is provided, as
1113 /// well as a target, then this method also adds the edges from the anchor to 1119 /// well as a target, then this method also adds the edges from the anchor to
1114 /// target. The anchor [KytheVName] is returned. 1120 /// target. The anchor [KytheVName] is returned.
1115 /// 1121 ///
1116 /// If a [target] and [enclosingTarget] are provided, a childof edge is 1122 /// If a [target] and [enclosingTarget] are provided, a childof edge is
1117 /// written out from the target to the enclosing target. 1123 /// written out from the target to the enclosing target.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 String factName, List<int> factValue) { 1194 String factName, List<int> factValue) {
1189 assert(source != null); 1195 assert(source != null);
1190 assert(factName != null); 1196 assert(factName != null);
1191 assert(factValue != null); 1197 assert(factValue != null);
1192 // factValue may be an empty array, the fact may be that a file text or 1198 // factValue may be an empty array, the fact may be that a file text or
1193 // document text is empty 1199 // document text is empty
1194 if (edgeKind == null || edgeKind.isEmpty) { 1200 if (edgeKind == null || edgeKind.isEmpty) {
1195 edgeKind = null; 1201 edgeKind = null;
1196 target = null; 1202 target = null;
1197 } 1203 }
1198 var entry = new KytheEntry(source, edgeKind, target, factName, factValue); 1204 var entry = new KytheEntry(source, factName,
1205 kind: edgeKind, target: target, value: factValue);
1199 entries.add(entry); 1206 entries.add(entry);
1200 return entry; 1207 return entry;
1201 } 1208 }
1202 1209
1203 /// This is a convenience method for visitors to add a fact [KytheEntry]. 1210 /// This is a convenience method for visitors to add a fact [KytheEntry].
1204 KytheEntry addFact(KytheVName source, String factName, List<int> factValue) { 1211 KytheEntry addFact(KytheVName source, String factName, List<int> factValue) {
1205 return addEntry(source, null, null, factName, factValue); 1212 return addEntry(source, null, null, factName, factValue);
1206 } 1213 }
1207 1214
1208 /// This is a convenience method for adding function types. 1215 /// This is a convenience method for adding function types.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 KytheVName _vNameFile() { 1323 KytheVName _vNameFile() {
1317 // file vnames, the signature and language are not set 1324 // file vnames, the signature and language are not set
1318 return _vName('', corpus, '', enclosingFilePath, ''); 1325 return _vName('', corpus, '', enclosingFilePath, '');
1319 } 1326 }
1320 1327
1321 /// Given some [Element] and Kythe node kind, this method generates and 1328 /// Given some [Element] and Kythe node kind, this method generates and
1322 /// returns the [KytheVName]. 1329 /// returns the [KytheVName].
1323 KytheVName _vNameFromElement(Element e, String nodeKind) { 1330 KytheVName _vNameFromElement(Element e, String nodeKind) {
1324 assert(nodeKind != schema.FILE_KIND); 1331 assert(nodeKind != schema.FILE_KIND);
1325 // general case 1332 // general case
1326 return _vName(_getSignature(e, nodeKind, corpus), corpus, '', _getPath(e)); 1333 return _vName(_getSignature(resourceProvider, e, nodeKind, corpus), corpus,
1334 '', _getPath(resourceProvider, e));
1327 } 1335 }
1328 1336
1329 /// Returns a [KytheVName] corresponding to the given [DartType]. 1337 /// Returns a [KytheVName] corresponding to the given [DartType].
1330 KytheVName _vNameFromType(DartType type) { 1338 KytheVName _vNameFromType(DartType type) {
1331 if (type == null || type.isDynamic) { 1339 if (type == null || type.isDynamic) {
1332 return dynamicBuiltin; 1340 return dynamicBuiltin;
1333 } else if (type.isVoid) { 1341 } else if (type.isVoid) {
1334 return voidBuiltin; 1342 return voidBuiltin;
1335 } else if (type.element is ClassElement) { 1343 } else if (type.element is ClassElement) {
1336 return _vNameFromElement(type.element, schema.RECORD_KIND); 1344 return _vNameFromElement(type.element, schema.RECORD_KIND);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1380 } 1388 }
1381 1389
1382 @override 1390 @override
1383 StringBuffer visitTypeParameterElement(TypeParameterElement e) { 1391 StringBuffer visitTypeParameterElement(TypeParameterElement e) {
1384 // It is legal to have a named constructor with the same name as a type 1392 // It is legal to have a named constructor with the same name as a type
1385 // parameter. So we distinguish them by using '.' between the class (or 1393 // parameter. So we distinguish them by using '.' between the class (or
1386 // typedef) name and the type parameter name. 1394 // typedef) name and the type parameter name.
1387 return e.enclosingElement.accept(this)..write('.')..write(e.name); 1395 return e.enclosingElement.accept(this)..write('.')..write(e.name);
1388 } 1396 }
1389 } 1397 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/domain_kythe.dart ('k') | pkg/analysis_server/test/integration/coverage.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698