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

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

Issue 2999783002: Initial implementation of the kythe domain (Closed)
Patch Set: Created 3 years, 4 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 import 'dart:io';
7 6
8 import 'package:analyzer/dart/ast/ast.dart'; 7 import 'package:analyzer/dart/ast/ast.dart';
9 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; 8 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
10 import 'package:analyzer/dart/ast/syntactic_entity.dart'; 9 import 'package:analyzer/dart/ast/syntactic_entity.dart';
11 import 'package:analyzer/dart/ast/token.dart'; 10 import 'package:analyzer/dart/ast/token.dart';
12 import 'package:analyzer/dart/ast/visitor.dart'; 11 import 'package:analyzer/dart/ast/visitor.dart';
13 import 'package:analyzer/dart/element/element.dart'; 12 import 'package:analyzer/dart/element/element.dart';
14 import 'package:analyzer/dart/element/type.dart'; 13 import 'package:analyzer/dart/element/type.dart';
15 import 'package:analyzer/dart/element/visitor.dart'; 14 import 'package:analyzer/dart/element/visitor.dart';
16 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; 15 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
16 import 'package:analyzer_plugin/protocol/protocol_common.dart'
17 show KytheEntry, KytheVName;
17 18
18 import 'schema.dart' as schema; 19 import 'schema.dart' as schema;
19 20
20 const int _notFound = -1; 21 const int _notFound = -1;
21 22
22 /// Computes analysis of the given compilation [unit]. 23 /// Computes analysis of the given compilation [unit]. The unit is assumed to
23 /// 24 /// exist in the given [corpus] and to have the given text [contents]. Analysis
24 /// [unit] is the compilation unit to be analyzed; it is assumed to exist in the 25 /// results are returned as a list of [KytheEntry] objects.
25 /// given [corpus] and to have the given text [contents]. Analysis results are 26 List<KytheEntry> computeIndex(
26 /// returned as a list of Kythe [pb_Entry] objects.
27 List<pb_Entry> computeIndex(
28 String corpus, CompilationUnit unit, String contents) { 27 String corpus, CompilationUnit unit, String contents) {
29 final List<pb_Entry> entries = []; 28 final List<KytheEntry> entries = [];
30 var visitor = new KytheDartVisitor( 29 var visitor = new KytheDartVisitor(
31 entries, 30 entries,
32 corpus, 31 corpus,
33 new InheritanceManager( 32 new InheritanceManager(
34 resolutionMap.elementDeclaredByCompilationUnit(unit).library), 33 resolutionMap.elementDeclaredByCompilationUnit(unit).library),
35 contents); 34 contents);
36 unit.accept(visitor); 35 unit.accept(visitor);
37 return entries; 36 return entries;
38 } 37 }
39 38
40 /// Outputs analysis of the given compilation [unit] to the parent process.
41 ///
42 /// [unit] is the compilation unit to be analyzed; it is assumed to exist in the
43 /// given [corpus] and to have the given text [contents]. Analysis results are
44 /// sent do the parent process as raw Kythe [Entry] objects.
45 void writeOutIndex(CompilationUnit unit, String corpus, String contents) {
46 List<pb_Entry> entries = computeIndex(corpus, unit, contents);
47 for (pb_Entry e in entries) {
48 assert(e.source != null);
49 if (e.edgeKind == "") {
50 assert(e.target.toString() == "");
51 }
52 _sendToParentProcess(e);
53 }
54 }
55
56 /// Given some [ConstructorElement], this method returns '<class-name>' as the 39 /// Given some [ConstructorElement], this method returns '<class-name>' as the
57 /// name of the constructor, unless the constructor is a named constructor 40 /// name of the constructor, unless the constructor is a named constructor in
58 /// in which '<class-name>.<constructor-name>' is returned. 41 /// which '<class-name>.<constructor-name>' is returned.
59 String _computeConstructorElementName(ConstructorElement element) { 42 String _computeConstructorElementName(ConstructorElement element) {
60 assert(element != null); 43 assert(element != null);
61 var name = element.enclosingElement.name; 44 var name = element.enclosingElement.name;
62 var constructorName = element.name; 45 var constructorName = element.name;
63 if (!constructorName.isEmpty) { 46 if (!constructorName.isEmpty) {
64 name = name + '.' + constructorName; 47 name = name + '.' + constructorName;
65 } 48 }
66 return name; 49 return name;
67 } 50 }
68 51
69 /// Create an anchor signature of the form '<start>-<end>'. 52 /// Create an anchor signature of the form '<start>-<end>'.
70 String _getAnchorSignature(int start, int end) { 53 String _getAnchorSignature(int start, int end) {
71 return '$start-$end'; 54 return '$start-$end';
72 } 55 }
73 56
74 String _getPath(Element e) { 57 String _getPath(Element e) {
58 // 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.
75 // TODO(jwren) figure out what source generates a e != null, but 60 // TODO(jwren) figure out what source generates a e != null, but
76 // e.source == null to ensure that it is not a bug somewhere in the stack. 61 // e.source == null to ensure that it is not a bug somewhere in the stack.
77 if (e == null || e.source == null) { 62 if (e == null || e.source == null) {
78 // null sometimes when the element is used to generate the node type 63 // null sometimes when the element is used to generate the node type
79 // "dynamic" 64 // "dynamic"
80 return ''; 65 return '';
81 } 66 }
82 var path = e.source.fullName; 67 var path = e.source.fullName;
83 assert(path.lastIndexOf('CORPUS_NAME') != -1); 68 assert(path.lastIndexOf('CORPUS_NAME') != -1);
84 return path.substring(path.lastIndexOf('CORPUS_NAME') + 12); 69 return path.substring(path.lastIndexOf('CORPUS_NAME') + 12);
85 } 70 }
86 71
87 /// If a non-null element is passed, the [SignatureElementVisitor] is used to 72 /// If a non-null element is passed, the [SignatureElementVisitor] is used to
88 /// generate and return a [String] signature, otherwise 73 /// generate and return a [String] signature, otherwise [schema.DYNAMIC_KIND] is
89 /// [schema.DYNAMIC_KIND] is returned. 74 /// returned.
90 String _getSignature(Element element, String nodeKind, String corpus) { 75 String _getSignature(Element element, String nodeKind, String corpus) {
91 assert(nodeKind != schema.ANCHOR_KIND); // Call _getAnchorSignature instead 76 assert(nodeKind != schema.ANCHOR_KIND); // Call _getAnchorSignature instead
92 if (element == null) { 77 if (element == null) {
93 return schema.DYNAMIC_KIND; 78 return schema.DYNAMIC_KIND;
94 } 79 }
95 if (element is CompilationUnitElement) { 80 if (element is CompilationUnitElement) {
96 return _getPath(element); 81 return _getPath(element);
97 } 82 }
98 return '$nodeKind:${element.accept(SignatureElementVisitor.instance)}'; 83 return '$nodeKind:${element.accept(SignatureElementVisitor.instance)}';
99 } 84 }
100 85
101 /// Send a [Reply] message to the parent process via standard output. 86 class CodedBufferWriter {
102 /// 87 CodedBufferWriter(var v);
103 /// The message is formatted as a base-128 encoded length followed by the 88 toBuffer() {}
104 /// serialized message data. The base-128 encoding is in little-endian order,
105 /// with the high bit set on all bytes but the last. This was chosen since
106 /// it's the same as the base-128 encoding used by protobufs, so it allows a
107 /// modest amount of code reuse. Also it parallels the format used by
108 /// [messageGrouper].
109 void _sendToParentProcess(pb_Entry entry) {
110 var rawMessage = entry.writeToBuffer();
111 var encodedLength = (new CodedBufferWriter(rawMessage.length)).toBuffer();
112 stdout..add(encodedLength)..add(rawMessage);
113 } 89 }
114 90
115 // TODO(jwren) This method simply serves to provide the WORKSPACE relative path
116 // for sources in Elements, it needs to be written in a more robust way.
117 /// This visitor writes out Kythe facts and edges as specified by the Kythe 91 /// This visitor writes out Kythe facts and edges as specified by the Kythe
118 /// Schema here https://kythe.io/docs/schema/. This visitor handles all nodes, 92 /// Schema here https://kythe.io/docs/schema/. This visitor handles all nodes,
119 /// facts and edges. 93 /// facts and edges.
120 class KytheDartVisitor extends GeneralizingAstVisitor with OutputUtils { 94 class KytheDartVisitor extends GeneralizingAstVisitor with OutputUtils {
121 final List<pb_Entry> entries; 95 final List<KytheEntry> entries;
122 final String corpus; 96 final String corpus;
123 final InheritanceManager _inheritanceManager; 97 final InheritanceManager _inheritanceManager;
124 String _enclosingFilePath = ''; 98 String _enclosingFilePath = '';
125 Element _enclosingElement; 99 Element _enclosingElement;
126 ClassElement _enclosingClassElement; 100 ClassElement _enclosingClassElement;
127 pb_VName _enclosingVName; 101 KytheVName _enclosingVName;
128 pb_VName _enclosingFileVName; 102 KytheVName _enclosingFileVName;
129 pb_VName _enclosingClassVName; 103 KytheVName _enclosingClassVName;
130 final String _contents; 104 final String _contents;
131 105
132 KytheDartVisitor( 106 KytheDartVisitor(
133 this.entries, this.corpus, this._inheritanceManager, this._contents); 107 this.entries, this.corpus, this._inheritanceManager, this._contents);
134 108
135 @override 109 @override
136 String get enclosingFilePath => _enclosingFilePath; 110 String get enclosingFilePath => _enclosingFilePath;
137 111
138 @override 112 @override
139 visitAnnotation(Annotation node) { 113 visitAnnotation(Annotation node) {
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 return schema.RECORD_KIND; 901 return schema.RECORD_KIND;
928 } 902 }
929 return null; 903 return null;
930 } 904 }
931 905
932 _handleRefCallEdge( 906 _handleRefCallEdge(
933 Element element, { 907 Element element, {
934 SyntacticEntity syntacticEntity: null, 908 SyntacticEntity syntacticEntity: null,
935 start: _notFound, 909 start: _notFound,
936 end: _notFound, 910 end: _notFound,
937 pb_VName enclosingTarget: null, 911 KytheVName enclosingTarget: null,
938 }) { 912 }) {
939 if (element is ExecutableElement && 913 if (element is ExecutableElement &&
940 _enclosingVName != _enclosingFileVName) { 914 _enclosingVName != _enclosingFileVName) {
941 _handleRefEdge( 915 _handleRefEdge(
942 element, 916 element,
943 const <String>[schema.REF_CALL_EDGE, schema.REF_EDGE], 917 const <String>[schema.REF_CALL_EDGE, schema.REF_EDGE],
944 syntacticEntity: syntacticEntity, 918 syntacticEntity: syntacticEntity,
945 start: start, 919 start: start,
946 end: end, 920 end: end,
947 enclosingTarget: enclosingTarget, 921 enclosingTarget: enclosingTarget,
948 enclosingAnchor: _enclosingVName, 922 enclosingAnchor: _enclosingVName,
949 ); 923 );
950 } else { 924 } else {
951 _handleRefEdge( 925 _handleRefEdge(
952 element, 926 element,
953 const <String>[schema.REF_EDGE], 927 const <String>[schema.REF_EDGE],
954 syntacticEntity: syntacticEntity, 928 syntacticEntity: syntacticEntity,
955 start: start, 929 start: start,
956 end: end, 930 end: end,
957 enclosingTarget: enclosingTarget, 931 enclosingTarget: enclosingTarget,
958 ); 932 );
959 } 933 }
960 } 934 }
961 935
962 /// This is a convenience method for adding ref edges. If the [start] and 936 /// This is a convenience method for adding ref edges. If the [start] and
963 /// [end] offsets are provided, they are used, otherwise the offsets are 937 /// [end] offsets are provided, they are used, otherwise the offsets are
964 /// computed by using the [syntacticEntity]. 938 /// computed by using the [syntacticEntity]. The list of edges is assumed to
965 /// The list of edges is assumed to be non-empty, and are added from the 939 /// be non-empty, and are added from the anchor to the target generated using
966 /// anchor to the target generated using the passed [Element]. 940 /// the passed [Element]. The created [KytheVName] is returned, if not `null`
967 /// The created [pb_VName] is returned, if not `null` is returned. 941 /// is returned.
968 pb_VName _handleRefEdge( 942 KytheVName _handleRefEdge(
969 Element element, 943 Element element,
970 List<String> refEdgeTypes, { 944 List<String> refEdgeTypes, {
971 SyntacticEntity syntacticEntity: null, 945 SyntacticEntity syntacticEntity: null,
972 start: _notFound, 946 start: _notFound,
973 end: _notFound, 947 end: _notFound,
974 pb_VName enclosingTarget: null, 948 KytheVName enclosingTarget: null,
975 pb_VName enclosingAnchor: null, 949 KytheVName enclosingAnchor: null,
976 }) { 950 }) {
977 assert(refEdgeTypes.isNotEmpty); 951 assert(refEdgeTypes.isNotEmpty);
978 element = _findNonSyntheticElement(element); 952 element = _findNonSyntheticElement(element);
979 if (element == null) { 953 if (element == null) {
980 return null; 954 return null;
981 } 955 }
982 956
983 // vname 957 // vname
984 var nodeKind = _getNodeKind(element); 958 var nodeKind = _getNodeKind(element);
985 if (nodeKind == null || nodeKind.isEmpty) { 959 if (nodeKind == null || nodeKind.isEmpty) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 addAnchorEdgesContainingEdge( 1028 addAnchorEdgesContainingEdge(
1055 start: start, 1029 start: start,
1056 end: end, 1030 end: end,
1057 edges: [schema.REF_IMPORTS_EDGE], 1031 edges: [schema.REF_IMPORTS_EDGE],
1058 target: packageVName, 1032 target: packageVName,
1059 enclosingTarget: _enclosingFileVName); 1033 enclosingTarget: _enclosingFileVName);
1060 } 1034 }
1061 } 1035 }
1062 1036
1063 _handleVariableDeclarationListAnnotations( 1037 _handleVariableDeclarationListAnnotations(
1064 VariableDeclarationList variableDeclarationList, pb_VName refVName) { 1038 VariableDeclarationList variableDeclarationList, KytheVName refVName) {
1065 assert(refVName != null); 1039 assert(refVName != null);
1066 for (var varDecl in variableDeclarationList.variables) { 1040 for (var varDecl in variableDeclarationList.variables) {
1067 if (varDecl.element != null) { 1041 if (varDecl.element != null) {
1068 var parentVName = 1042 var parentVName =
1069 _vNameFromElement(varDecl.element, schema.VARIABLE_KIND); 1043 _vNameFromElement(varDecl.element, schema.VARIABLE_KIND);
1070 addEdge(parentVName, schema.ANNOTATED_BY_EDGE, refVName); 1044 addEdge(parentVName, schema.ANNOTATED_BY_EDGE, refVName);
1071 } else { 1045 } else {
1072 // The element out of the VarDeclarationList is null 1046 // The element out of the VarDeclarationList is null
1073 assert(false); 1047 assert(false);
1074 } 1048 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 _enclosingElement = outerEnclosingElement; 1087 _enclosingElement = outerEnclosingElement;
1114 _enclosingClassElement = outerEnclosingClassElement; 1088 _enclosingClassElement = outerEnclosingClassElement;
1115 _enclosingClassVName = outerEnclosingClassVName; 1089 _enclosingClassVName = outerEnclosingClassVName;
1116 _enclosingVName = outerEnclosingVName; 1090 _enclosingVName = outerEnclosingVName;
1117 } 1091 }
1118 } 1092 }
1119 } 1093 }
1120 1094
1121 /// 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
1122 /// [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
1123 /// [pb_Entry] protos. 1097 /// [KytheEntry] protos.
1124 abstract class OutputUtils { 1098 abstract class OutputUtils {
1125 /// A set of [String]s which have already had a name [pb_VName] created. 1099 /// A set of [String]s which have already had a name [KytheVName] created.
1126 final Set<String> nameNodes = new Set<String>(); 1100 final Set<String> nameNodes = new Set<String>();
1127 String get corpus; 1101 String get corpus;
1128 pb_VName get dynamicBuiltin => _vName(schema.DYNAMIC_KIND, '', '', ''); 1102 KytheVName get dynamicBuiltin => _vName(schema.DYNAMIC_KIND, '', '', '');
1129 1103
1130 String get enclosingFilePath; 1104 String get enclosingFilePath;
1131 1105
1132 List<pb_Entry> get entries; 1106 List<KytheEntry> get entries;
1133 pb_VName get fnBuiltin => _vName(schema.FN_BUILTIN, '', '', ''); 1107 KytheVName get fnBuiltin => _vName(schema.FN_BUILTIN, '', '', '');
1134 pb_VName get voidBuiltin => _vName(schema.VOID_BUILTIN, '', '', ''); 1108 KytheVName get voidBuiltin => _vName(schema.VOID_BUILTIN, '', '', '');
1135 1109
1136 /// This is a convenience method for adding anchors. If the [start] and [end] 1110 /// This is a convenience method for adding anchors. If the [start] and [end]
1137 /// offsets are provided, they are used, otherwise the offsets are computed by 1111 /// offsets are provided, they are used, otherwise the offsets are computed by
1138 /// using the [syntacticEntity]. If a non-empty list of edges is provided, as 1112 /// using the [syntacticEntity]. If a non-empty list of edges is provided, as
1139 /// well as a target, then this method also adds the edges from the anchor to 1113 /// well as a target, then this method also adds the edges from the anchor to
1140 /// target. The anchor [pb_VName] is returned. 1114 /// target. The anchor [KytheVName] is returned.
1141 /// 1115 ///
1142 /// If a [target] and [enclosingTarget] are provided, a childof edge is 1116 /// If a [target] and [enclosingTarget] are provided, a childof edge is
1143 /// written out from the target to the enclosing target. 1117 /// written out from the target to the enclosing target.
1144 /// 1118 ///
1145 /// If an [enclosingAnchor] is provided a childof edge is written out from the 1119 /// If an [enclosingAnchor] is provided a childof edge is written out from the
1146 /// anchor to the enclosing anchor. In cases where ref/call is an edge, this 1120 /// anchor to the enclosing anchor. In cases where ref/call is an edge, this
1147 /// is required to generate the callgraph. 1121 /// is required to generate the callgraph.
1148 /// 1122 ///
1149 /// Finally, for all anchors, a childof edge with a target of the enclosing 1123 /// Finally, for all anchors, a childof edge with a target of the enclosing
1150 /// file is written out. 1124 /// file is written out.
1151 pb_VName addAnchorEdgesContainingEdge({ 1125 KytheVName addAnchorEdgesContainingEdge({
1152 SyntacticEntity syntacticEntity: null, 1126 SyntacticEntity syntacticEntity: null,
1153 int start: _notFound, 1127 int start: _notFound,
1154 int end: _notFound, 1128 int end: _notFound,
1155 List<String> edges: const [], 1129 List<String> edges: const [],
1156 pb_VName target: null, 1130 KytheVName target: null,
1157 pb_VName enclosingTarget: null, 1131 KytheVName enclosingTarget: null,
1158 pb_VName enclosingAnchor: null, 1132 KytheVName enclosingAnchor: null,
1159 }) { 1133 }) {
1160 if (start == _notFound && end == _notFound) { 1134 if (start == _notFound && end == _notFound) {
1161 if (syntacticEntity != null) { 1135 if (syntacticEntity != null) {
1162 start = syntacticEntity.offset; 1136 start = syntacticEntity.offset;
1163 end = syntacticEntity.end; 1137 end = syntacticEntity.end;
1164 } else { 1138 } else {
1165 throw new Exception('Offset positions were not provided when calling ' 1139 throw new Exception('Offset positions were not provided when calling '
1166 'addAnchorEdgesContainingEdge'); 1140 'addAnchorEdgesContainingEdge');
1167 } 1141 }
1168 } 1142 }
(...skipping 24 matching lines...) Expand all
1193 } 1167 }
1194 1168
1195 // Finally add the childof edge to the enclosing file VName. 1169 // Finally add the childof edge to the enclosing file VName.
1196 addEdge(anchorVName, schema.CHILD_OF_EDGE, _vNameFile()); 1170 addEdge(anchorVName, schema.CHILD_OF_EDGE, _vNameFile());
1197 return anchorVName; 1171 return anchorVName;
1198 } 1172 }
1199 1173
1200 /// TODO(jwren): for cases where the target is a name, we need the same kind 1174 /// TODO(jwren): for cases where the target is a name, we need the same kind
1201 /// of logic as [addNameFact] to prevent the edge from being written out. 1175 /// of logic as [addNameFact] to prevent the edge from being written out.
1202 /// This is a convenience method for visitors to add an edge Entry. 1176 /// This is a convenience method for visitors to add an edge Entry.
1203 pb_Entry addEdge(pb_VName source, String edgeKind, pb_VName target, 1177 KytheEntry addEdge(KytheVName source, String edgeKind, KytheVName target,
1204 {int ordinalIntValue: _notFound}) { 1178 {int ordinalIntValue: _notFound}) {
1205 if (ordinalIntValue == _notFound) { 1179 if (ordinalIntValue == _notFound) {
1206 return addEntry(source, edgeKind, target, "/", new List<int>()); 1180 return addEntry(source, edgeKind, target, "/", new List<int>());
1207 } else { 1181 } else {
1208 return addEntry(source, edgeKind, target, schema.ORDINAL, 1182 return addEntry(source, edgeKind, target, schema.ORDINAL,
1209 _encodeInt(ordinalIntValue)); 1183 _encodeInt(ordinalIntValue));
1210 } 1184 }
1211 } 1185 }
1212 1186
1213 pb_Entry addEntry(pb_VName source, String edgeKind, pb_VName target, 1187 KytheEntry addEntry(KytheVName source, String edgeKind, KytheVName target,
1214 String factName, List<int> factValue) { 1188 String factName, List<int> factValue) {
1215 assert(source != null); 1189 assert(source != null);
1216 assert(factName != null); 1190 assert(factName != null);
1217 assert(factValue != null); 1191 assert(factValue != null);
1218 // factValue may be an empty array, the fact may be that a file text or 1192 // factValue may be an empty array, the fact may be that a file text or
1219 // document text is empty 1193 // document text is empty
1220 var entry = pb_Entry.create() 1194 if (edgeKind == null || edgeKind.isEmpty) {
1221 ..source = source 1195 edgeKind = null;
1222 ..factName = factName 1196 target = null;
1223 ..factValue = factValue;
1224 if (edgeKind != null && edgeKind.isNotEmpty) {
1225 entry.edgeKind = edgeKind;
1226 entry.target = target;
1227 } 1197 }
1198 var entry = new KytheEntry(source, edgeKind, target, factName, factValue);
1228 entries.add(entry); 1199 entries.add(entry);
1229 return entry; 1200 return entry;
1230 } 1201 }
1231 1202
1232 /// This is a convenience method for visitors to add a fact [pb_Entry]. 1203 /// This is a convenience method for visitors to add a fact [KytheEntry].
1233 pb_Entry addFact(pb_VName source, String factName, List<int> factValue) { 1204 KytheEntry addFact(KytheVName source, String factName, List<int> factValue) {
1234 return addEntry(source, null, null, factName, factValue); 1205 return addEntry(source, null, null, factName, factValue);
1235 } 1206 }
1236 1207
1237 /// This is a convenience method for adding function types. 1208 /// This is a convenience method for adding function types.
1238 pb_VName addFunctionType( 1209 KytheVName addFunctionType(
1239 Element functionElement, 1210 Element functionElement,
1240 FormalParameterList paramNodes, 1211 FormalParameterList paramNodes,
1241 pb_VName functionVName, { 1212 KytheVName functionVName, {
1242 AstNode returnNode: null, 1213 AstNode returnNode: null,
1243 }) { 1214 }) {
1244 var i = 0; 1215 var i = 0;
1245 var funcTypeVName = 1216 var funcTypeVName =
1246 addNodeAndFacts(schema.TAPP_KIND, element: functionElement); 1217 addNodeAndFacts(schema.TAPP_KIND, element: functionElement);
1247 addEdge(funcTypeVName, schema.PARAM_EDGE, fnBuiltin, ordinalIntValue: i++); 1218 addEdge(funcTypeVName, schema.PARAM_EDGE, fnBuiltin, ordinalIntValue: i++);
1248 1219
1249 var returnTypeVName; 1220 var returnTypeVName;
1250 if (returnNode is TypeName) { 1221 if (returnNode is TypeName) {
1251 // MethodDeclaration and FunctionDeclaration both return a TypeName from 1222 // MethodDeclaration and FunctionDeclaration both return a TypeName from
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 } 1259 }
1289 addEdge(funcTypeVName, schema.PARAM_EDGE, paramTypeVName, 1260 addEdge(funcTypeVName, schema.PARAM_EDGE, paramTypeVName,
1290 ordinalIntValue: i++); 1261 ordinalIntValue: i++);
1291 } 1262 }
1292 } 1263 }
1293 addEdge(functionVName, schema.TYPED_EDGE, funcTypeVName); 1264 addEdge(functionVName, schema.TYPED_EDGE, funcTypeVName);
1294 return funcTypeVName; 1265 return funcTypeVName;
1295 } 1266 }
1296 1267
1297 /// This is a convenience method for adding nodes with facts. 1268 /// This is a convenience method for adding nodes with facts.
1298 /// If an [pb_VName] is passed, it is used, otherwise an element is required 1269 /// If an [KytheVName] is passed, it is used, otherwise an element is required
1299 /// which is used to create a [pb_VName]. Either [nodeVName] must be non-null or 1270 /// which is used to create a [KytheVName]. Either [nodeVName] must be non-nu ll or
1300 /// [element] must be non-null. Other optional parameters if passed are then 1271 /// [element] must be non-null. Other optional parameters if passed are then
1301 /// used to set the associated facts on the [pb_VName]. This method does not 1272 /// used to set the associated facts on the [KytheVName]. This method does not
1302 /// currently guarantee that the inputs to these fact kinds are valid for the 1273 /// currently guarantee that the inputs to these fact kinds are valid for the
1303 /// associated nodeKind- if a non-null, then it will set. 1274 /// associated nodeKind- if a non-null, then it will set.
1304 pb_VName addNodeAndFacts(String nodeKind, 1275 KytheVName addNodeAndFacts(String nodeKind,
1305 {Element element: null, 1276 {Element element: null,
1306 pb_VName nodeVName: null, 1277 KytheVName nodeVName: null,
1307 String subKind: null, 1278 String subKind: null,
1308 String completeFact: null}) { 1279 String completeFact: null}) {
1309 if (nodeVName == null) { 1280 if (nodeVName == null) {
1310 nodeVName = _vNameFromElement(element, nodeKind); 1281 nodeVName = _vNameFromElement(element, nodeKind);
1311 } 1282 }
1312 addFact(nodeVName, schema.NODE_KIND_FACT, _encode(nodeKind)); 1283 addFact(nodeVName, schema.NODE_KIND_FACT, _encode(nodeKind));
1313 if (subKind != null) { 1284 if (subKind != null) {
1314 addFact(nodeVName, schema.SUBKIND_FACT, _encode(subKind)); 1285 addFact(nodeVName, schema.SUBKIND_FACT, _encode(subKind));
1315 } 1286 }
1316 if (completeFact != null) { 1287 if (completeFact != null) {
1317 addFact(nodeVName, schema.COMPLETE_FACT, _encode(completeFact)); 1288 addFact(nodeVName, schema.COMPLETE_FACT, _encode(completeFact));
1318 } 1289 }
1319 return nodeVName; 1290 return nodeVName;
1320 } 1291 }
1321 1292
1322 List<int> _encode(String str) { 1293 List<int> _encode(String str) {
1323 return UTF8.encode(str); 1294 return UTF8.encode(str);
1324 } 1295 }
1325 1296
1326 List<int> _encodeInt(int i) { 1297 List<int> _encodeInt(int i) {
1327 return UTF8.encode(i.toString()); 1298 return UTF8.encode(i.toString());
1328 } 1299 }
1329 1300
1330 /// Given all parameters for a [pb_VName] this method creates and returns a 1301 /// Given all parameters for a [KytheVName] this method creates and returns a
1331 /// [pb_VName]. 1302 /// [KytheVName].
1332 pb_VName _vName(String signature, String corpus, String root, String path, 1303 KytheVName _vName(String signature, String corpus, String root, String path,
1333 [String language = schema.DART_LANG]) { 1304 [String language = schema.DART_LANG]) {
1334 return pb_VName.create() 1305 return new KytheVName(signature, corpus, root, path, language);
1335 ..signature = signature
1336 ..corpus = corpus
1337 ..root = root
1338 ..path = path
1339 ..language = language;
1340 } 1306 }
1341 1307
1342 /// Returns an anchor [pb_VName] corresponding to the given start and end 1308 /// Returns an anchor [KytheVName] corresponding to the given start and end
1343 /// offsets. 1309 /// offsets.
1344 pb_VName _vNameAnchor(int start, int end) { 1310 KytheVName _vNameAnchor(int start, int end) {
1345 return _vName( 1311 return _vName(
1346 _getAnchorSignature(start, end), corpus, '', enclosingFilePath); 1312 _getAnchorSignature(start, end), corpus, '', enclosingFilePath);
1347 } 1313 }
1348 1314
1349 /// Return the [pb_VName] for this file. 1315 /// Return the [KytheVName] for this file.
1350 pb_VName _vNameFile() { 1316 KytheVName _vNameFile() {
1351 // file vnames, the signature and language are not set 1317 // file vnames, the signature and language are not set
1352 return _vName('', corpus, '', enclosingFilePath, ''); 1318 return _vName('', corpus, '', enclosingFilePath, '');
1353 } 1319 }
1354 1320
1355 /// Given some [Element] and Kythe node kind, this method generates and 1321 /// Given some [Element] and Kythe node kind, this method generates and
1356 /// returns the [pb_VName]. 1322 /// returns the [KytheVName].
1357 pb_VName _vNameFromElement(Element e, String nodeKind) { 1323 KytheVName _vNameFromElement(Element e, String nodeKind) {
1358 assert(nodeKind != schema.FILE_KIND); 1324 assert(nodeKind != schema.FILE_KIND);
1359 // general case 1325 // general case
1360 return _vName(_getSignature(e, nodeKind, corpus), corpus, '', _getPath(e)); 1326 return _vName(_getSignature(e, nodeKind, corpus), corpus, '', _getPath(e));
1361 } 1327 }
1362 1328
1363 /// Returns a [pb_VName] corresponding to the given [DartType]. 1329 /// Returns a [KytheVName] corresponding to the given [DartType].
1364 pb_VName _vNameFromType(DartType type) { 1330 KytheVName _vNameFromType(DartType type) {
1365 if (type == null || type.isDynamic) { 1331 if (type == null || type.isDynamic) {
1366 return dynamicBuiltin; 1332 return dynamicBuiltin;
1367 } else if (type.isVoid) { 1333 } else if (type.isVoid) {
1368 return voidBuiltin; 1334 return voidBuiltin;
1369 } else if (type.element is ClassElement) { 1335 } else if (type.element is ClassElement) {
1370 return _vNameFromElement(type.element, schema.RECORD_KIND); 1336 return _vNameFromElement(type.element, schema.RECORD_KIND);
1371 } else { 1337 } else {
1372 return dynamicBuiltin; 1338 return dynamicBuiltin;
1373 } 1339 }
1374 } 1340 }
1375 } 1341 }
1376 1342
1377 class CodedBufferWriter {
1378 CodedBufferWriter(var v);
1379 toBuffer() {}
1380 }
1381
1382 class pb_Entry {
1383 var source, edgeKind, target, factName, factValue;
1384 static pb_Entry create() => new pb_Entry();
1385 writeToBuffer() {}
1386 }
1387
1388 class pb_VName {
1389 var signature, corpus, root, path, language;
1390 static pb_VName create() => new pb_VName();
1391 }
1392
1393 /// This visitor class should be used by [_getSignature]. 1343 /// This visitor class should be used by [_getSignature].
1394 /// 1344 ///
1395 /// This visitor is an [GeneralizingElementVisitor] which builds up a [String] 1345 /// This visitor is an [GeneralizingElementVisitor] which builds up a [String]
1396 /// signature for a given [Element], uniqueness is guaranteed within the 1346 /// signature for a given [Element], uniqueness is guaranteed within the
1397 /// enclosing file. 1347 /// enclosing file.
1398 class SignatureElementVisitor extends GeneralizingElementVisitor<StringBuffer> { 1348 class SignatureElementVisitor extends GeneralizingElementVisitor<StringBuffer> {
1399 static SignatureElementVisitor instance = new SignatureElementVisitor(); 1349 static SignatureElementVisitor instance = new SignatureElementVisitor();
1400 1350
1401 @override 1351 @override
1402 StringBuffer visitCompilationUnitElement(CompilationUnitElement e) { 1352 StringBuffer visitCompilationUnitElement(CompilationUnitElement e) {
(...skipping 27 matching lines...) Expand all
1430 } 1380 }
1431 1381
1432 @override 1382 @override
1433 StringBuffer visitTypeParameterElement(TypeParameterElement e) { 1383 StringBuffer visitTypeParameterElement(TypeParameterElement e) {
1434 // It is legal to have a named constructor with the same name as a type 1384 // It is legal to have a named constructor with the same name as a type
1435 // parameter. So we distinguish them by using '.' between the class (or 1385 // parameter. So we distinguish them by using '.' between the class (or
1436 // typedef) name and the type parameter name. 1386 // typedef) name and the type parameter name.
1437 return e.enclosingElement.accept(this)..write('.')..write(e.name); 1387 return e.enclosingElement.accept(this)..write('.')..write(e.name);
1438 } 1388 }
1439 } 1389 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/plugin/server_plugin.dart ('k') | pkg/analyzer_plugin/lib/plugin/plugin.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698