| Index: pkg/analyzer/lib/src/lint/pub.dart
|
| diff --git a/pkg/analyzer/lib/src/lint/pub.dart b/pkg/analyzer/lib/src/lint/pub.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8d12e134bb54aa213c11ad6633cf85897e1a69ce
|
| --- /dev/null
|
| +++ b/pkg/analyzer/lib/src/lint/pub.dart
|
| @@ -0,0 +1,430 @@
|
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +import 'dart:collection';
|
| +
|
| +import 'package:source_span/source_span.dart';
|
| +import 'package:yaml/yaml.dart';
|
| +
|
| +PSEntry _findEntry(YamlMap map, String key) {
|
| + PSEntry entry;
|
| + map.nodes.forEach((k, v) {
|
| + if (k is YamlScalar && key == k.toString()) {
|
| + entry = _processScalar(k, v);
|
| + }
|
| + });
|
| + return entry;
|
| +}
|
| +
|
| +PSDependencyList _processDependencies(YamlScalar key, YamlNode v) {
|
| + if (v is! YamlMap) {
|
| + return null;
|
| + }
|
| + YamlMap depsMap = v;
|
| +
|
| + _PSDependencyList deps = new _PSDependencyList(new _PSNode(key));
|
| + depsMap.nodes.forEach((k, v) => deps.add(new _PSDependency(k, v)));
|
| + return deps;
|
| +}
|
| +
|
| +PSGitRepo _processGitRepo(YamlScalar key, YamlNode v) {
|
| + if (v is! YamlMap) {
|
| + return null;
|
| + }
|
| + YamlMap hostMap = v;
|
| + // url: git://github.com/munificent/kittens.git
|
| + // ref: some-branch
|
| + _PSGitRepo repo = new _PSGitRepo();
|
| + repo.token = new _PSNode(key);
|
| + repo.ref = _findEntry(hostMap, 'ref');
|
| + repo.url = _findEntry(hostMap, 'url');
|
| + return repo;
|
| +}
|
| +
|
| +PSHost _processHost(YamlScalar key, YamlNode v) {
|
| + if (v is! YamlMap) {
|
| + return null;
|
| + }
|
| + YamlMap hostMap = v;
|
| + // name: transmogrify
|
| + // url: http://your-package-server.com
|
| + _PSHost host = new _PSHost();
|
| + host.token = new _PSNode(key);
|
| + host.name = _findEntry(hostMap, 'name');
|
| + host.url = _findEntry(hostMap, 'url');
|
| + return host;
|
| +}
|
| +
|
| +PSNodeList _processList(YamlScalar key, YamlNode v) {
|
| + if (v is! YamlList) {
|
| + return null;
|
| + }
|
| + YamlList nodeList = v;
|
| +
|
| + return new _PSNodeList(
|
| + new _PSNode(key), nodeList.nodes.map((n) => new _PSNode(n)));
|
| +}
|
| +
|
| +PSEntry _processScalar(YamlScalar key, YamlNode value) {
|
| + if (value is! YamlScalar) {
|
| + return null;
|
| + //WARN?
|
| + }
|
| + return new PSEntry(new _PSNode(key), new _PSNode(value));
|
| +}
|
| +
|
| +abstract class PSDependency {
|
| + PSGitRepo get git;
|
| + PSHost get host;
|
| + PSNode get name;
|
| + PSEntry get version;
|
| +}
|
| +
|
| +abstract class PSDependencyList extends Object
|
| + with IterableMixin<PSDependency> {}
|
| +
|
| +class PSEntry {
|
| + final PSNode key;
|
| + final PSNode value;
|
| + PSEntry(this.key, this.value);
|
| +
|
| + @override
|
| + String toString() => '${key != null ? (key.toString() + ': ') : ''}$value';
|
| +}
|
| +
|
| +abstract class PSGitRepo {
|
| + PSEntry get ref;
|
| + PSNode get token;
|
| + PSEntry get url;
|
| +}
|
| +
|
| +abstract class PSHost {
|
| + PSEntry get name;
|
| + PSNode get token;
|
| + PSEntry get url;
|
| +}
|
| +
|
| +abstract class PSNode {
|
| + SourceSpan get span;
|
| + String get text;
|
| +}
|
| +
|
| +abstract class PSNodeList extends Object with IterableMixin<PSNode> {
|
| + @override
|
| + Iterator<PSNode> get iterator;
|
| + PSNode get token;
|
| +}
|
| +
|
| +abstract class Pubspec {
|
| + factory Pubspec.parse(String source, {Uri sourceUrl}) =>
|
| + new _Pubspec(source, sourceUrl: sourceUrl);
|
| + PSEntry get author;
|
| + PSNodeList get authors;
|
| + PSDependencyList get dependencies;
|
| + PSEntry get description;
|
| + PSDependencyList get devDependencies;
|
| + PSEntry get documentation;
|
| + PSEntry get homepage;
|
| + PSEntry get name;
|
| + PSEntry get version;
|
| + accept(PubspecVisitor visitor);
|
| +}
|
| +
|
| +abstract class PubspecVisitor<T> {
|
| + T visitPackageAuthor(PSEntry author) => null;
|
| + T visitPackageAuthors(PSNodeList authors) => null;
|
| + T visitPackageDependencies(PSDependencyList dependencies) => null;
|
| + T visitPackageDependency(PSDependency dependency) => null;
|
| + T visitPackageDescription(PSEntry description) => null;
|
| + T visitPackageDevDependencies(PSDependencyList dependencies) => null;
|
| + T visitPackageDevDependency(PSDependency dependency) => null;
|
| + T visitPackageDocumentation(PSEntry documentation) => null;
|
| + T visitPackageHomepage(PSEntry homepage) => null;
|
| + T visitPackageName(PSEntry name) => null;
|
| + T visitPackageVersion(PSEntry version) => null;
|
| +}
|
| +
|
| +class _PSDependency extends PSDependency {
|
| + @override
|
| + PSNode name;
|
| + @override
|
| + PSEntry version;
|
| + @override
|
| + PSHost host;
|
| + @override
|
| + PSGitRepo git;
|
| +
|
| + factory _PSDependency(dynamic k, YamlNode v) {
|
| + if (k is! YamlScalar) {
|
| + return null;
|
| + }
|
| + YamlScalar key = k;
|
| +
|
| + _PSDependency dep = new _PSDependency._();
|
| +
|
| + dep.name = new _PSNode(key);
|
| +
|
| + if (v is YamlScalar) {
|
| + // Simple version
|
| + dep.version = new PSEntry(null, new _PSNode(v));
|
| + } else if (v is YamlMap) {
|
| + // hosted:
|
| + // name: transmogrify
|
| + // url: http://your-package-server.com
|
| + // version: '>=0.4.0 <1.0.0'
|
| + YamlMap details = v;
|
| + details.nodes.forEach((k, v) {
|
| + if (k is! YamlScalar) {
|
| + return;
|
| + }
|
| + YamlScalar key = k;
|
| + switch (key.toString()) {
|
| + case 'version':
|
| + dep.version = _processScalar(key, v);
|
| + break;
|
| + case 'hosted':
|
| + dep.host = _processHost(key, v);
|
| + break;
|
| + case 'git':
|
| + dep.git = _processGitRepo(key, v);
|
| + break;
|
| + }
|
| + });
|
| + }
|
| + return dep;
|
| + }
|
| +
|
| + _PSDependency._();
|
| +
|
| + @override
|
| + String toString() {
|
| + var sb = new StringBuffer();
|
| + if (name != null) {
|
| + sb.write('$name:');
|
| + }
|
| + var versionInfo = '';
|
| + if (version != null) {
|
| + if (version.key == null) {
|
| + versionInfo = ' $version';
|
| + } else {
|
| + versionInfo = '\n $version';
|
| + }
|
| + }
|
| + sb.writeln(versionInfo);
|
| + if (host != null) {
|
| + sb.writeln(host);
|
| + }
|
| + if (git != null) {
|
| + sb.writeln(git);
|
| + }
|
| + return sb.toString();
|
| + }
|
| +}
|
| +
|
| +class _PSDependencyList extends PSDependencyList {
|
| + final dependencies = <PSDependency>[];
|
| + final PSNode token;
|
| +
|
| + _PSDependencyList(this.token);
|
| +
|
| + @override
|
| + Iterator<PSDependency> get iterator => dependencies.iterator;
|
| +
|
| + add(PSDependency dependency) {
|
| + if (dependency != null) {
|
| + dependencies.add(dependency);
|
| + }
|
| + }
|
| +
|
| + @override
|
| + String toString() => '$token\n${dependencies.join(' ')}';
|
| +}
|
| +
|
| +class _PSGitRepo implements PSGitRepo {
|
| + @override
|
| + PSNode token;
|
| + @override
|
| + PSEntry ref;
|
| + @override
|
| + PSEntry url;
|
| + @override
|
| + String toString() => '''
|
| + $token:
|
| + $url
|
| + $ref''';
|
| +}
|
| +
|
| +class _PSHost implements PSHost {
|
| + @override
|
| + PSNode token;
|
| + @override
|
| + PSEntry name;
|
| + @override
|
| + PSEntry url;
|
| + @override
|
| + String toString() => '''
|
| + $token:
|
| + $name
|
| + $url''';
|
| +}
|
| +
|
| +class _PSNode implements PSNode {
|
| + @override
|
| + final String text;
|
| + @override
|
| + final SourceSpan span;
|
| +
|
| + _PSNode(YamlNode node)
|
| + : text = node.value?.toString(),
|
| + span = node.span;
|
| +
|
| + @override
|
| + String toString() => '$text';
|
| +}
|
| +
|
| +class _PSNodeList extends PSNodeList {
|
| + @override
|
| + final PSNode token;
|
| + final Iterable<PSNode> nodes;
|
| +
|
| + _PSNodeList(this.token, this.nodes);
|
| +
|
| + @override
|
| + Iterator<PSNode> get iterator => nodes.iterator;
|
| +
|
| + @override
|
| + String toString() => '''
|
| +$token:
|
| + - ${nodes.join('\n - ')}''';
|
| +}
|
| +
|
| +class _Pubspec implements Pubspec {
|
| + @override
|
| + PSEntry author;
|
| + @override
|
| + PSNodeList authors;
|
| + @override
|
| + PSEntry description;
|
| + @override
|
| + PSEntry documentation;
|
| + @override
|
| + PSEntry homepage;
|
| + @override
|
| + PSEntry name;
|
| + @override
|
| + PSEntry version;
|
| + @override
|
| + PSDependencyList dependencies;
|
| + @override
|
| + PSDependencyList devDependencies;
|
| +
|
| + _Pubspec(String src, {Uri sourceUrl}) {
|
| + try {
|
| + _parse(src, sourceUrl: sourceUrl);
|
| + } on Exception {
|
| + // ignore
|
| + }
|
| + }
|
| +
|
| + @override
|
| + void accept(PubspecVisitor visitor) {
|
| + if (author != null) {
|
| + visitor.visitPackageAuthor(author);
|
| + }
|
| + if (authors != null) {
|
| + visitor.visitPackageAuthors(authors);
|
| + }
|
| + if (description != null) {
|
| + visitor.visitPackageDescription(description);
|
| + }
|
| + if (documentation != null) {
|
| + visitor.visitPackageDocumentation(documentation);
|
| + }
|
| + if (homepage != null) {
|
| + visitor.visitPackageHomepage(homepage);
|
| + }
|
| + if (name != null) {
|
| + visitor.visitPackageName(name);
|
| + }
|
| + if (version != null) {
|
| + visitor.visitPackageVersion(version);
|
| + }
|
| + if (dependencies != null) {
|
| + visitor.visitPackageDependencies(dependencies);
|
| + dependencies.forEach((d) => visitor.visitPackageDependency(d));
|
| + }
|
| + if (devDependencies != null) {
|
| + visitor.visitPackageDevDependencies(devDependencies);
|
| + devDependencies.forEach((d) => visitor.visitPackageDevDependency(d));
|
| + }
|
| + }
|
| +
|
| + @override
|
| + String toString() {
|
| + var sb = new _StringBuilder();
|
| + sb.writelin(name);
|
| + sb.writelin(version);
|
| + sb.writelin(author);
|
| + sb.writelin(authors);
|
| + sb.writelin(description);
|
| + sb.writelin(homepage);
|
| + sb.writelin(dependencies);
|
| + sb.writelin(devDependencies);
|
| + return sb.toString();
|
| + }
|
| +
|
| + _parse(String src, {Uri sourceUrl}) {
|
| + var yaml = loadYamlNode(src, sourceUrl: sourceUrl);
|
| + if (yaml is! YamlMap) {
|
| + return;
|
| + }
|
| + YamlMap yamlMap = yaml;
|
| + yamlMap.nodes.forEach((k, v) {
|
| + if (k is! YamlScalar) {
|
| + return;
|
| + }
|
| + YamlScalar key = k;
|
| + switch (key.toString()) {
|
| + case 'author':
|
| + author = _processScalar(key, v);
|
| + break;
|
| + case 'authors':
|
| + authors = _processList(key, v);
|
| + break;
|
| + case 'homepage':
|
| + homepage = _processScalar(key, v);
|
| + break;
|
| + case 'name':
|
| + name = _processScalar(key, v);
|
| + break;
|
| + case 'description':
|
| + description = _processScalar(key, v);
|
| + break;
|
| + case 'documentation':
|
| + documentation = _processScalar(key, v);
|
| + break;
|
| + case 'dependencies':
|
| + dependencies = _processDependencies(key, v);
|
| + break;
|
| + case 'dev_dependencies':
|
| + devDependencies = _processDependencies(key, v);
|
| + break;
|
| + case 'version':
|
| + version = _processScalar(key, v);
|
| + break;
|
| + }
|
| + });
|
| + }
|
| +}
|
| +
|
| +class _StringBuilder {
|
| + StringBuffer buffer = new StringBuffer();
|
| + @override
|
| + String toString() => buffer.toString();
|
| + writelin(Object value) {
|
| + if (value != null) {
|
| + buffer.writeln(value);
|
| + }
|
| + }
|
| +}
|
|
|