| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 library dart2js.analyze_helpers.test; |
| 6 |
| 7 import 'dart:io'; |
| 8 |
| 9 import 'package:async_helper/async_helper.dart'; |
| 10 import 'package:compiler/compiler_new.dart' show |
| 11 Diagnostic; |
| 12 import 'package:compiler/src/apiimpl.dart' show |
| 13 Compiler; |
| 14 import 'package:compiler/src/constants/expressions.dart' show |
| 15 ConstructedConstantExpression; |
| 16 import 'package:compiler/src/dart_types.dart' show |
| 17 InterfaceType; |
| 18 import 'package:compiler/src/diagnostics/source_span.dart' show |
| 19 SourceSpan; |
| 20 import 'package:compiler/src/elements/elements.dart'; |
| 21 import 'package:compiler/src/filenames.dart' show |
| 22 nativeToUriPath; |
| 23 import 'package:compiler/src/resolution/semantic_visitor.dart'; |
| 24 import 'package:compiler/src/resolution/tree_elements.dart' show |
| 25 TreeElements; |
| 26 import 'package:compiler/src/source_file_provider.dart' show |
| 27 FormattingDiagnosticHandler; |
| 28 import 'package:compiler/src/tree/tree.dart'; |
| 29 import 'package:compiler/src/universe/universe.dart' show |
| 30 CallStructure; |
| 31 import 'package:expect/expect.dart'; |
| 32 |
| 33 import 'memory_compiler.dart'; |
| 34 |
| 35 main(List<String> arguments) { |
| 36 bool verbose = arguments.contains('-v'); |
| 37 |
| 38 List<String> options = <String>[ |
| 39 '--analyze-only', |
| 40 '--analyze-main', |
| 41 '--categories=Client,Server']; |
| 42 if (verbose) { |
| 43 options.add('--verbose'); |
| 44 } |
| 45 asyncTest(() async { |
| 46 Compiler compiler = compilerFor( |
| 47 options: options, showDiagnostics: verbose); |
| 48 FormattingDiagnosticHandler diagnostics = |
| 49 new FormattingDiagnosticHandler(compiler.provider); |
| 50 HelperAnalyzer analyzer = new HelperAnalyzer(diagnostics); |
| 51 Directory dir = |
| 52 new Directory.fromUri(Uri.base.resolve('pkg/compiler/lib/')); |
| 53 for (FileSystemEntity entity in dir.listSync(recursive: true)) { |
| 54 if (entity is File && entity.path.endsWith('.dart')) { |
| 55 Uri file = Uri.base.resolve(nativeToUriPath(entity.path)); |
| 56 if (verbose) { |
| 57 print('---- analyzing $file ----'); |
| 58 } |
| 59 LibraryElement library = await compiler.analyzeUri(file); |
| 60 if (library != null) { |
| 61 library.forEachLocalMember((Element element) { |
| 62 if (element is ClassElement) { |
| 63 element.forEachLocalMember((AstElement member) { |
| 64 analyzer.analyze(member.resolvedAst); |
| 65 }); |
| 66 } else if (element is MemberElement) { |
| 67 analyzer.analyze(element.resolvedAst); |
| 68 } |
| 69 }); |
| 70 } |
| 71 } |
| 72 } |
| 73 Expect.isTrue(analyzer.errors.isEmpty, "Errors found."); |
| 74 }); |
| 75 } |
| 76 |
| 77 class HelperAnalyzer extends TraversalVisitor { |
| 78 final FormattingDiagnosticHandler diagnostics; |
| 79 List<SourceSpan> errors = <SourceSpan>[]; |
| 80 |
| 81 ResolvedAst resolvedAst; |
| 82 |
| 83 @override |
| 84 TreeElements get elements => resolvedAst.elements; |
| 85 |
| 86 AnalyzableElement get analyzedElement => resolvedAst.element; |
| 87 |
| 88 HelperAnalyzer(this.diagnostics) : super(null); |
| 89 |
| 90 @override |
| 91 void apply(Node node, [_]) { |
| 92 node.accept(this); |
| 93 } |
| 94 |
| 95 void analyze(ResolvedAst resolvedAst) { |
| 96 if (resolvedAst.node == null) { |
| 97 // Skip synthesized members. |
| 98 return; |
| 99 } |
| 100 this.resolvedAst = resolvedAst; |
| 101 apply(resolvedAst.node); |
| 102 this.resolvedAst = null; |
| 103 } |
| 104 |
| 105 bool isHelper(Element element) { |
| 106 Uri uri = element.library.canonicalUri; |
| 107 return uri.path.endsWith('src/helpers/helpers.dart'); |
| 108 } |
| 109 |
| 110 void checkAccess(Node node, MemberElement element) { |
| 111 if (isHelper(element) && !isHelper(analyzedElement)) { |
| 112 Uri uri = analyzedElement.implementation.sourcePosition.uri; |
| 113 SourceSpan span = new SourceSpan.fromNode(uri, node); |
| 114 diagnostics.report(null, span.uri, span.begin, span.end, |
| 115 "Helper used in production code.", |
| 116 Diagnostic.ERROR); |
| 117 errors.add(span); |
| 118 } |
| 119 } |
| 120 |
| 121 @override |
| 122 void visitTopLevelFieldInvoke( |
| 123 Send node, |
| 124 FieldElement field, |
| 125 NodeList arguments, |
| 126 CallStructure callStructure, |
| 127 _) { |
| 128 checkAccess(node, field); |
| 129 apply(arguments); |
| 130 } |
| 131 |
| 132 @override |
| 133 void visitTopLevelGetterInvoke( |
| 134 Send node, |
| 135 GetterElement getter, |
| 136 NodeList arguments, |
| 137 CallStructure callStructure, |
| 138 _) { |
| 139 checkAccess(node, getter); |
| 140 apply(arguments); |
| 141 } |
| 142 |
| 143 @override |
| 144 void visitTopLevelFunctionInvoke( |
| 145 Send node, |
| 146 MethodElement method, |
| 147 NodeList arguments, |
| 148 CallStructure callStructure, |
| 149 _) { |
| 150 checkAccess(node, method); |
| 151 apply(arguments); |
| 152 } |
| 153 |
| 154 @override |
| 155 void visitTopLevelFieldGet( |
| 156 Send node, |
| 157 FieldElement field, |
| 158 _) { |
| 159 checkAccess(node, field); |
| 160 } |
| 161 |
| 162 @override |
| 163 void visitTopLevelGetterGet( |
| 164 Send node, |
| 165 GetterElement getter, |
| 166 _) { |
| 167 checkAccess(node, getter); |
| 168 } |
| 169 |
| 170 @override |
| 171 void visitTopLevelFunctionGet( |
| 172 Send node, |
| 173 MethodElement method, |
| 174 _) { |
| 175 checkAccess(node, method); |
| 176 } |
| 177 |
| 178 @override |
| 179 void visitGenerativeConstructorInvoke( |
| 180 NewExpression node, |
| 181 ConstructorElement constructor, |
| 182 InterfaceType type, |
| 183 NodeList arguments, |
| 184 CallStructure callStructure, |
| 185 _) { |
| 186 checkAccess(node, constructor); |
| 187 apply(arguments); |
| 188 } |
| 189 |
| 190 @override |
| 191 void visitRedirectingGenerativeConstructorInvoke( |
| 192 NewExpression node, |
| 193 ConstructorElement constructor, |
| 194 InterfaceType type, |
| 195 NodeList arguments, |
| 196 CallStructure callStructure, |
| 197 _) { |
| 198 checkAccess(node, constructor); |
| 199 apply(arguments); |
| 200 } |
| 201 |
| 202 @override |
| 203 void visitFactoryConstructorInvoke( |
| 204 NewExpression node, |
| 205 ConstructorElement constructor, |
| 206 InterfaceType type, |
| 207 NodeList arguments, |
| 208 CallStructure callStructure, |
| 209 _) { |
| 210 checkAccess(node, constructor); |
| 211 apply(arguments); |
| 212 } |
| 213 |
| 214 @override |
| 215 void visitRedirectingFactoryConstructorInvoke( |
| 216 NewExpression node, |
| 217 ConstructorElement constructor, |
| 218 InterfaceType type, |
| 219 ConstructorElement effectiveTarget, |
| 220 InterfaceType effectiveTargetType, |
| 221 NodeList arguments, |
| 222 CallStructure callStructure, |
| 223 _) { |
| 224 checkAccess(node, constructor); |
| 225 apply(arguments); |
| 226 } |
| 227 |
| 228 @override |
| 229 void visitConstConstructorInvoke( |
| 230 NewExpression node, |
| 231 ConstructedConstantExpression constant, |
| 232 _) { |
| 233 checkAccess(node, constant.target); |
| 234 } |
| 235 } |
| OLD | NEW |