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

Side by Side Diff: pkg/analyzer/lib/src/lint/project.dart

Issue 2559773002: Reapply "Move the linter core to the analyzer package" (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « pkg/analyzer/lib/src/lint/linter.dart ('k') | pkg/analyzer/lib/src/lint/pub.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 import 'dart:io';
6
7 import 'package:analyzer/dart/element/element.dart';
8 import 'package:analyzer/src/generated/engine.dart';
9 import 'package:analyzer/src/generated/resolver.dart';
10 import 'package:analyzer/src/generated/source.dart';
11 import 'package:analyzer/src/lint/io.dart';
12 import 'package:analyzer/src/lint/pub.dart';
13 import 'package:path/path.dart' as p;
14
15 Pubspec _findAndParsePubspec(Directory root) {
16 if (root.existsSync()) {
17 File pubspec = root
18 .listSync(followLinks: false)
19 .firstWhere((f) => isPubspecFile(f), orElse: () => null);
20 if (pubspec != null) {
21 return new Pubspec.parse(pubspec.readAsStringSync(),
22 sourceUrl: p.toUri(pubspec.path));
23 }
24 }
25 return null;
26 }
27
28 /// A semantic representation of a Dart project.
29 ///
30 /// Projects provide a semantic model of a Dart project based on the
31 /// [pub package layout conventions](https://www.dartlang.org/tools/pub/package- layout.html).
32 /// This model allows clients to traverse project contents in a convenient and
33 /// standardized way, access global information (such as whether elements are
34 /// in the "public API") and resources that have special meanings in the
35 /// context of pub package layout conventions.
36 class DartProject {
37 _ApiModel _apiModel;
38 String _name;
39 Pubspec _pubspec;
40
41 /// Project root.
42 final Directory root;
43
44 /// Create a Dart project for the corresponding [context] and [sources].
45 /// If a [dir] is unspecified the current working directory will be
46 /// used.
47 DartProject(AnalysisContext context, List<Source> sources, {Directory dir})
48 : root = dir ?? Directory.current {
49 _pubspec = _findAndParsePubspec(root);
50 _apiModel = new _ApiModel(context, sources, root);
51 }
52
53 /// The project's name.
54 ///
55 /// Project names correspond to the package name as specified in the project's
56 /// [pubspec]. The pubspec is found relative to the project [root]. If no
57 /// pubspec can be found, the name defaults to the project root basename.
58 String get name => _name ??= _calculateName();
59
60 /// The project's pubspec.
61 Pubspec get pubspec => _pubspec;
62
63 /// Returns `true` if the given element is part of this project's public API.
64 ///
65 /// Public API elements are defined as all elements that are in the packages's
66 /// `lib` directory, *less* those in `lib/src` (which are treated as private
67 /// *implementation files*), plus elements having been explicitly exported
68 /// via an `export` directive.
69 bool isApi(Element element) => _apiModel.contains(element);
70
71 String _calculateName() {
72 if (pubspec != null) {
73 var nameEntry = pubspec.name;
74 if (nameEntry != null) {
75 return nameEntry.value.text;
76 }
77 }
78 return p.basename(root.path);
79 }
80 }
81
82 /// An object that can be used to visit Dart project structure.
83 abstract class ProjectVisitor<T> {
84 T visit(DartProject project) => null;
85 }
86
87 /// Captures the project's API as defined by pub package layout standards.
88 class _ApiModel {
89 final AnalysisContext context;
90 final List<Source> sources;
91 final Directory root;
92 final Set<LibraryElement> elements = new Set();
93
94 _ApiModel(this.context, this.sources, this.root) {
95 _calculate();
96 }
97
98 /// Return `true` if this element is part of the public API for this package.
99 bool contains(Element element) {
100 while (element != null) {
101 if (!element.isPrivate && elements.contains(element)) {
102 return true;
103 }
104 element = element.enclosingElement;
105 }
106 return false;
107 }
108
109 _calculate() {
110 if (sources == null || sources.isEmpty) {
111 return;
112 }
113
114 var libDir = root.path + '/lib';
115 var libSrcDir = libDir + '/src';
116
117 for (Source source in sources) {
118 var path = source.uri.path;
119 if (path.startsWith(libDir) && !path.startsWith(libSrcDir)) {
120 var library = context.computeLibraryElement(source);
121 var namespaceBuilder = new NamespaceBuilder();
122 var exports = namespaceBuilder.createExportNamespaceForLibrary(library);
123 var public = namespaceBuilder.createPublicNamespaceForLibrary(library);
124 elements.addAll(exports.definedNames.values);
125 elements.addAll(public.definedNames.values);
126 }
127 }
128 }
129 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/lint/linter.dart ('k') | pkg/analyzer/lib/src/lint/pub.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698