From 40d8d53e7e5a73ad5d0b61bf75e51092508bccef Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Sat, 14 Jan 2023 19:05:32 -0500 Subject: [PATCH 01/29] docs: Hello World full tutorial example. --- .../data_rules/.dart_tool/package_config.json | 150 ++-- .../communication/responses.freezed.dart | 32 +- .../models/analysis_result.freezed.dart | 174 ++--- .../models/assist_result.freezed.dart | 641 ------------------ .../lib/src/lints/avoid_string_literal.dart | 2 +- .../sidecar/.dart_tool/package_config.json | 2 +- website/sidecar/.packages | 2 +- .../docs/tutorials/bloc_file_structure.mdx | 3 +- .../sidecar/docs/tutorials/hello_world.mdx | 189 +++++- .../sidecar/docs/tutorials/string_locator.mdx | 7 +- .../.dart_tool/sidecar_logs/latest.log | 1 + .../tutorials/design_system_insets/.gitignore | 6 - .../design_system_insets/CHANGELOG.md | 3 - .../tutorials/design_system_insets/README.md | 2 - .../analysis_options.yaml | 30 - .../bin/design_system_insets.dart | 5 - .../lib/design_system_insets.dart | 3 - .../design_system_insets/pubspec.yaml | 14 - .../test/design_system_insets_test.dart | 8 - 19 files changed, 335 insertions(+), 939 deletions(-) delete mode 100644 packages/sidecar/lib/src/protocol/models/assist_result.freezed.dart create mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log delete mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/.gitignore delete mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/CHANGELOG.md delete mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/README.md delete mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/analysis_options.yaml delete mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/bin/design_system_insets.dart delete mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/lib/design_system_insets.dart delete mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/pubspec.yaml delete mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/test/design_system_insets_test.dart diff --git a/examples/data_rules/.dart_tool/package_config.json b/examples/data_rules/.dart_tool/package_config.json index 0fec98ea..815d76fe 100644 --- a/examples/data_rules/.dart_tool/package_config.json +++ b/examples/data_rules/.dart_tool/package_config.json @@ -3,247 +3,247 @@ "packages": [ { "name": "_fe_analyzer_shared", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "analyzer", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/analyzer-4.7.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "analyzer_plugin", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "args", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/args-2.3.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "async", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/async-2.10.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.14" }, { "name": "boolean_selector", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/boolean_selector-2.1.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.1", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "characters", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/characters-1.2.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "checked_yaml", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/checked_yaml-2.0.2", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.12" }, { "name": "cli_util", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/cli_util-0.3.5", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "collection", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/collection-1.17.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.17.0", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "convert", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/convert-3.1.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.12" }, { "name": "coverage", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/coverage-1.6.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.1", "packageUri": "lib/", "languageVersion": "2.15" }, { "name": "crypto", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/crypto-3.0.2", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2", "packageUri": "lib/", "languageVersion": "2.14" }, { "name": "dart_style", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/dart_style-2.2.4", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "file", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/file-6.1.4", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "freezed_annotation", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "frontend_server_client", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "glob", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/glob-2.1.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1", "packageUri": "lib/", "languageVersion": "2.15" }, { "name": "hotreloader", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/hotreloader-3.0.5", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "http_multi_server", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/http_multi_server-3.2.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_multi_server-3.2.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "http_parser", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/http_parser-4.0.2", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "io", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/io-1.0.3", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/io-1.0.3", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "js", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/js-0.6.5", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/js-0.6.5", "packageUri": "lib/", "languageVersion": "2.16" }, { "name": "json_annotation", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/json_annotation-4.7.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "lints", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/lints-2.0.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/lints-2.0.1", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "logging", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/logging-1.1.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "matcher", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/matcher-0.12.14", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.12" }, { "name": "meta", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/meta-1.8.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "mime", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/mime-1.0.4", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/mime-1.0.3", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.12" }, { "name": "node_preamble", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/node_preamble-2.0.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/node_preamble-2.0.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "package_config", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/package_config-2.1.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "path", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/path-1.8.3", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "pool", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/pool-1.5.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pool-1.5.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "pub_semver", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/pub_semver-2.1.3", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "pubspec_parse", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1", "packageUri": "lib/", "languageVersion": "2.14" }, { "name": "recase", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/recase-4.1.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "riverpod", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/riverpod-2.1.3", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.1", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "shelf", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/shelf-1.4.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0", "packageUri": "lib/", "languageVersion": "2.17" }, { "name": "shelf_packages_handler", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1", "packageUri": "lib/", "languageVersion": "2.14" }, { "name": "shelf_static", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/shelf_static-1.1.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1", "packageUri": "lib/", "languageVersion": "2.14" }, { "name": "shelf_web_socket", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3", "packageUri": "lib/", "languageVersion": "2.17" }, @@ -255,127 +255,127 @@ }, { "name": "sidecar_annotations", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "sidecar_package_utilities", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "source_map_stack_trace", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "source_maps", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/source_maps-0.10.11", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.10", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.12" }, { "name": "source_span", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/source_span-1.9.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1", "packageUri": "lib/", "languageVersion": "2.14" }, { "name": "stack_trace", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/stack_trace-1.11.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.12" }, { "name": "state_notifier", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "stream_channel", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/stream_channel-2.1.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.1", "packageUri": "lib/", "languageVersion": "2.14" }, { "name": "stream_transform", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/stream_transform-2.1.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0", "packageUri": "lib/", "languageVersion": "2.14" }, { "name": "string_scanner", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/string_scanner-1.2.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.12" }, { "name": "term_glyph", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/term_glyph-1.2.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "test", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/test-1.22.2", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test-1.21.4", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.14" }, { "name": "test_api", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/test_api-0.4.18", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.12" }, { "name": "test_core", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/test_core-0.4.22", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_core-0.4.16", "packageUri": "lib/", - "languageVersion": "2.18" + "languageVersion": "2.14" }, { "name": "typed_data", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/typed_data-1.3.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "uuid", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/uuid-3.0.7", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "vm_service", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/vm_service-9.4.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0", "packageUri": "lib/", "languageVersion": "2.15" }, { "name": "watcher", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/watcher-1.0.2", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2", "packageUri": "lib/", "languageVersion": "2.14" }, { "name": "web_socket_channel", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/web_socket_channel-2.3.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-2.2.0", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "webkit_inspection_protocol", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0", "packageUri": "lib/", "languageVersion": "2.12" }, { "name": "yaml", - "rootUri": "file:///C:/Users/pattobrien/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/yaml-3.1.1", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1", "packageUri": "lib/", "languageVersion": "2.12" }, @@ -386,7 +386,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-12T03:31:25.958025Z", + "generated": "2023-01-14T21:01:26.976686Z", "generator": "pub", - "generatorVersion": "2.18.6" + "generatorVersion": "2.17.6" } diff --git a/packages/sidecar/lib/src/protocol/communication/responses.freezed.dart b/packages/sidecar/lib/src/protocol/communication/responses.freezed.dart index be178c7b..0a959d58 100644 --- a/packages/sidecar/lib/src/protocol/communication/responses.freezed.dart +++ b/packages/sidecar/lib/src/protocol/communication/responses.freezed.dart @@ -50,8 +50,8 @@ mixin _$SidecarResponse { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? contextCollection, - TResult? Function(Set results)? assist, - TResult? Function(List results)? quickFix, + TResult? Function(Set results)? assist, + TResult? Function(List results)? quickFix, TResult? Function(List lints)? lint, TResult? Function()? updateFiles, TResult? Function()? setPriorityFiles, @@ -181,8 +181,8 @@ class _$SetWorkspaceResponse extends SetWorkspaceResponse { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? contextCollection, - TResult? Function(Set results)? assist, - TResult? Function(List results)? quickFix, + TResult? Function(Set results)? assist, + TResult? Function(List results)? quickFix, TResult? Function(List lints)? lint, TResult? Function()? updateFiles, TResult? Function()? setPriorityFiles, @@ -272,7 +272,7 @@ abstract class _$$AssistResponseCopyWith<$Res> { _$AssistResponse value, $Res Function(_$AssistResponse) then) = __$$AssistResponseCopyWithImpl<$Res>; @useResult - $Res call({Set results}); + $Res call({Set results}); } /// @nodoc @@ -360,8 +360,8 @@ class _$AssistResponse extends AssistResponse { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? contextCollection, - TResult? Function(Set results)? assist, - TResult? Function(List results)? quickFix, + TResult? Function(Set results)? assist, + TResult? Function(List results)? quickFix, TResult? Function(List lints)? lint, TResult? Function()? updateFiles, TResult? Function()? setPriorityFiles, @@ -457,7 +457,7 @@ abstract class _$$QuickFixResponseCopyWith<$Res> { _$QuickFixResponse value, $Res Function(_$QuickFixResponse) then) = __$$QuickFixResponseCopyWithImpl<$Res>; @useResult - $Res call({List results}); + $Res call({List results}); } /// @nodoc @@ -545,8 +545,8 @@ class _$QuickFixResponse extends QuickFixResponse { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? contextCollection, - TResult? Function(Set results)? assist, - TResult? Function(List results)? quickFix, + TResult? Function(Set results)? assist, + TResult? Function(List results)? quickFix, TResult? Function(List lints)? lint, TResult? Function()? updateFiles, TResult? Function()? setPriorityFiles, @@ -729,8 +729,8 @@ class _$LintResponse extends LintResponse { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? contextCollection, - TResult? Function(Set results)? assist, - TResult? Function(List results)? quickFix, + TResult? Function(Set results)? assist, + TResult? Function(List results)? quickFix, TResult? Function(List lints)? lint, TResult? Function()? updateFiles, TResult? Function()? setPriorityFiles, @@ -880,8 +880,8 @@ class _$UpdateFilesResponse extends UpdateFilesResponse { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? contextCollection, - TResult? Function(Set results)? assist, - TResult? Function(List results)? quickFix, + TResult? Function(Set results)? assist, + TResult? Function(List results)? quickFix, TResult? Function(List lints)? lint, TResult? Function()? updateFiles, TResult? Function()? setPriorityFiles, @@ -1027,8 +1027,8 @@ class _$SetPriorityFilesResponse extends SetPriorityFilesResponse { @optionalTypeArgs TResult? whenOrNull({ TResult? Function()? contextCollection, - TResult? Function(Set results)? assist, - TResult? Function(List results)? quickFix, + TResult? Function(Set results)? assist, + TResult? Function(List results)? quickFix, TResult? Function(List lints)? lint, TResult? Function()? updateFiles, TResult? Function()? setPriorityFiles, diff --git a/packages/sidecar/lib/src/protocol/models/analysis_result.freezed.dart b/packages/sidecar/lib/src/protocol/models/analysis_result.freezed.dart index 5769cde0..e50dcb36 100644 --- a/packages/sidecar/lib/src/protocol/models/analysis_result.freezed.dart +++ b/packages/sidecar/lib/src/protocol/models/analysis_result.freezed.dart @@ -80,9 +80,9 @@ mixin _$AnalysisResult { }) => throw _privateConstructorUsedError; @optionalTypeArgs - TResult? whenOrNull( + TResult? whenOrNull({ TResult? Function( - RuleCode rule, + RuleCode code, @Assert('span.sourceUrl != null') @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) SourceSpan span, @@ -91,9 +91,9 @@ mixin _$AnalysisResult { String? correction, @JsonKey(ignore: true) EditsComputer? editsComputer)? - $default, { + lint, TResult? Function( - RuleCode rule, + RuleCode code, @Assert('span.sourceUrl != null') @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) SourceSpan span, @@ -173,9 +173,13 @@ mixin _$AnalysisResult { }) => throw _privateConstructorUsedError; @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(LintResult value)? $default, { - TResult? Function(LintResultWithEdits value)? withEdits, + TResult? mapOrNull({ + TResult? Function(LintResult value)? lint, + TResult? Function(LintWithEditsResult value)? lintWithEdits, + TResult? Function(TotalDataResult value)? totalData, + TResult? Function(SingleDataResult value)? singleData, + TResult? Function(AssistResult value)? assist, + TResult? Function(AssistWithEditsResult value)? assistWithEdits, }) => throw _privateConstructorUsedError; @optionalTypeArgs @@ -201,14 +205,7 @@ abstract class $AnalysisResultCopyWith<$Res> { AnalysisResult value, $Res Function(AnalysisResult) then) = _$AnalysisResultCopyWithImpl<$Res, AnalysisResult>; @useResult - $Res call( - {RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - String message, - LintSeverity severity, - String? correction}); + $Res call({RuleCode code}); $RuleCodeCopyWith<$Res> get code; } @@ -226,41 +223,21 @@ class _$AnalysisResultCopyWithImpl<$Res, $Val extends AnalysisResult> @pragma('vm:prefer-inline') @override $Res call({ - Object? rule = null, - Object? span = null, - Object? message = null, - Object? severity = null, - Object? correction = freezed, + Object? code = null, }) { return _then(_value.copyWith( - rule: null == rule - ? _value.rule - : rule // ignore: cast_nullable_to_non_nullable + code: null == code + ? _value.code + : code // ignore: cast_nullable_to_non_nullable as RuleCode, - span: null == span - ? _value.span - : span // ignore: cast_nullable_to_non_nullable - as SourceSpan, - message: null == message - ? _value.message - : message // ignore: cast_nullable_to_non_nullable - as String, - severity: null == severity - ? _value.severity - : severity // ignore: cast_nullable_to_non_nullable - as LintSeverity, - correction: freezed == correction - ? _value.correction - : correction // ignore: cast_nullable_to_non_nullable - as String?, ) as $Val); } @override @pragma('vm:prefer-inline') - $RuleCodeCopyWith<$Res> get rule { - return $RuleCodeCopyWith<$Res>(_value.rule, (value) { - return _then(_value.copyWith(rule: value) as $Val); + $RuleCodeCopyWith<$Res> get code { + return $RuleCodeCopyWith<$Res>(_value.code, (value) { + return _then(_value.copyWith(code: value) as $Val); }); } } @@ -299,7 +276,7 @@ class __$$LintResultCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? rule = null, + Object? code = null, Object? span = null, Object? message = null, Object? severity = null, @@ -307,9 +284,9 @@ class __$$LintResultCopyWithImpl<$Res> Object? editsComputer = freezed, }) { return _then(_$LintResult( - rule: null == rule - ? _value.rule - : rule // ignore: cast_nullable_to_non_nullable + code: null == code + ? _value.code + : code // ignore: cast_nullable_to_non_nullable as RuleCode, span: null == span ? _value.span @@ -376,30 +353,9 @@ class _$LintResult extends LintResult { @override String toString() { - return 'AnalysisResult(rule: $rule, span: $span, message: $message, severity: $severity, correction: $correction, editsComputer: $editsComputer)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$LintResult && - (identical(other.rule, rule) || other.rule == rule) && - (identical(other.span, span) || other.span == span) && - (identical(other.message, message) || other.message == message) && - (identical(other.severity, severity) || - other.severity == severity) && - (identical(other.correction, correction) || - other.correction == correction) && - (identical(other.editsComputer, editsComputer) || - other.editsComputer == editsComputer)); + return 'AnalysisResult.lint(code: $code, span: $span, message: $message, severity: $severity, correction: $correction, editsComputer: $editsComputer)'; } - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, rule, span, message, severity, correction, editsComputer); - @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') @@ -452,9 +408,9 @@ class _$LintResult extends LintResult { @override @optionalTypeArgs - TResult? whenOrNull( + TResult? whenOrNull({ TResult? Function( - RuleCode rule, + RuleCode code, @Assert('span.sourceUrl != null') @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) SourceSpan span, @@ -463,9 +419,9 @@ class _$LintResult extends LintResult { String? correction, @JsonKey(ignore: true) EditsComputer? editsComputer)? - $default, { + lint, TResult? Function( - RuleCode rule, + RuleCode code, @Assert('span.sourceUrl != null') @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) SourceSpan span, @@ -557,9 +513,13 @@ class _$LintResult extends LintResult { @override @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(LintResult value)? $default, { - TResult? Function(LintResultWithEdits value)? withEdits, + TResult? mapOrNull({ + TResult? Function(LintResult value)? lint, + TResult? Function(LintWithEditsResult value)? lintWithEdits, + TResult? Function(TotalDataResult value)? totalData, + TResult? Function(SingleDataResult value)? singleData, + TResult? Function(AssistResult value)? assist, + TResult? Function(AssistWithEditsResult value)? assistWithEdits, }) { return lint?.call(this); } @@ -645,27 +605,27 @@ abstract class _$$LintWithEditsResultCopyWith<$Res> } /// @nodoc -class __$$LintResultWithEditsCopyWithImpl<$Res> - extends _$AnalysisResultCopyWithImpl<$Res, _$LintResultWithEdits> - implements _$$LintResultWithEditsCopyWith<$Res> { - __$$LintResultWithEditsCopyWithImpl( - _$LintResultWithEdits _value, $Res Function(_$LintResultWithEdits) _then) +class __$$LintWithEditsResultCopyWithImpl<$Res> + extends _$AnalysisResultCopyWithImpl<$Res, _$LintWithEditsResult> + implements _$$LintWithEditsResultCopyWith<$Res> { + __$$LintWithEditsResultCopyWithImpl( + _$LintWithEditsResult _value, $Res Function(_$LintWithEditsResult) _then) : super(_value, _then); @pragma('vm:prefer-inline') @override $Res call({ - Object? rule = null, + Object? code = null, Object? span = null, Object? message = null, Object? severity = null, Object? correction = freezed, Object? edits = null, }) { - return _then(_$LintResultWithEdits( - rule: null == rule - ? _value.rule - : rule // ignore: cast_nullable_to_non_nullable + return _then(_$LintWithEditsResult( + code: null == code + ? _value.code + : code // ignore: cast_nullable_to_non_nullable as RuleCode, span: null == span ? _value.span @@ -735,34 +695,14 @@ class _$LintWithEditsResult extends LintWithEditsResult { @override String toString() { - return 'AnalysisResult.withEdits(rule: $rule, span: $span, message: $message, severity: $severity, correction: $correction, edits: $edits)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$LintResultWithEdits && - (identical(other.rule, rule) || other.rule == rule) && - (identical(other.span, span) || other.span == span) && - (identical(other.message, message) || other.message == message) && - (identical(other.severity, severity) || - other.severity == severity) && - (identical(other.correction, correction) || - other.correction == correction) && - const DeepCollectionEquality().equals(other._edits, _edits)); + return 'AnalysisResult.lintWithEdits(code: $code, span: $span, message: $message, severity: $severity, correction: $correction, edits: $edits)'; } - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, rule, span, message, severity, - correction, const DeepCollectionEquality().hash(_edits)); - @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$LintResultWithEditsCopyWith<_$LintResultWithEdits> get copyWith => - __$$LintResultWithEditsCopyWithImpl<_$LintResultWithEdits>( + _$$LintWithEditsResultCopyWith<_$LintWithEditsResult> get copyWith => + __$$LintWithEditsResultCopyWithImpl<_$LintWithEditsResult>( this, _$identity); @override @@ -811,9 +751,9 @@ class _$LintWithEditsResult extends LintWithEditsResult { @override @optionalTypeArgs - TResult? whenOrNull( + TResult? whenOrNull({ TResult? Function( - RuleCode rule, + RuleCode code, @Assert('span.sourceUrl != null') @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) SourceSpan span, @@ -822,9 +762,9 @@ class _$LintWithEditsResult extends LintWithEditsResult { String? correction, @JsonKey(ignore: true) EditsComputer? editsComputer)? - $default, { + lint, TResult? Function( - RuleCode rule, + RuleCode code, @Assert('span.sourceUrl != null') @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) SourceSpan span, @@ -917,9 +857,13 @@ class _$LintWithEditsResult extends LintWithEditsResult { @override @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(LintResult value)? $default, { - TResult? Function(LintResultWithEdits value)? withEdits, + TResult? mapOrNull({ + TResult? Function(LintResult value)? lint, + TResult? Function(LintWithEditsResult value)? lintWithEdits, + TResult? Function(TotalDataResult value)? totalData, + TResult? Function(SingleDataResult value)? singleData, + TResult? Function(AssistResult value)? assist, + TResult? Function(AssistWithEditsResult value)? assistWithEdits, }) { return lintWithEdits?.call(this); } diff --git a/packages/sidecar/lib/src/protocol/models/assist_result.freezed.dart b/packages/sidecar/lib/src/protocol/models/assist_result.freezed.dart deleted file mode 100644 index b081630d..00000000 --- a/packages/sidecar/lib/src/protocol/models/assist_result.freezed.dart +++ /dev/null @@ -1,641 +0,0 @@ -// coverage:ignore-file -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: type=lint -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target - -part of 'assist_result.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; - -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); - -AssistResult _$AssistResultFromJson(Map json) { - switch (json['runtimeType']) { - case 'default': - return AssistFilterResult.fromJson(json); - case 'withEdits': - return AssistResultWithEdits.fromJson(json); - - default: - throw CheckedFromJsonException(json, 'runtimeType', 'AssistResult', - 'Invalid union type "${json['runtimeType']}"!'); - } -} - -/// @nodoc -mixin _$AssistResult { - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan get span => throw _privateConstructorUsedError; - @optionalTypeArgs - TResult when( - TResult Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer) - $default, { - required TResult Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits) - withEdits, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer)? - $default, { - TResult? Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits)? - withEdits, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen( - TResult Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer)? - $default, { - TResult Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits)? - withEdits, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map( - TResult Function(AssistFilterResult value) $default, { - required TResult Function(AssistResultWithEdits value) withEdits, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(AssistFilterResult value)? $default, { - TResult? Function(AssistResultWithEdits value)? withEdits, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap( - TResult Function(AssistFilterResult value)? $default, { - TResult Function(AssistResultWithEdits value)? withEdits, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - Map toJson() => throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $AssistResultCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $AssistResultCopyWith<$Res> { - factory $AssistResultCopyWith( - AssistResult value, $Res Function(AssistResult) then) = - _$AssistResultCopyWithImpl<$Res, AssistResult>; - @useResult - $Res call( - {@Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span}); -} - -/// @nodoc -class _$AssistResultCopyWithImpl<$Res, $Val extends AssistResult> - implements $AssistResultCopyWith<$Res> { - _$AssistResultCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? span = null, - }) { - return _then(_value.copyWith( - span: null == span - ? _value.span - : span // ignore: cast_nullable_to_non_nullable - as SourceSpan, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$AssistFilterResultCopyWith<$Res> - implements $AssistResultCopyWith<$Res> { - factory _$$AssistFilterResultCopyWith(_$AssistFilterResult value, - $Res Function(_$AssistFilterResult) then) = - __$$AssistFilterResultCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer}); - - $RuleCodeCopyWith<$Res> get rule; -} - -/// @nodoc -class __$$AssistFilterResultCopyWithImpl<$Res> - extends _$AssistResultCopyWithImpl<$Res, _$AssistFilterResult> - implements _$$AssistFilterResultCopyWith<$Res> { - __$$AssistFilterResultCopyWithImpl( - _$AssistFilterResult _value, $Res Function(_$AssistFilterResult) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? rule = null, - Object? span = null, - Object? editsComputer = freezed, - }) { - return _then(_$AssistFilterResult( - rule: null == rule - ? _value.rule - : rule // ignore: cast_nullable_to_non_nullable - as RuleCode, - span: null == span - ? _value.span - : span // ignore: cast_nullable_to_non_nullable - as SourceSpan, - editsComputer: freezed == editsComputer - ? _value.editsComputer - : editsComputer // ignore: cast_nullable_to_non_nullable - as EditsComputer?, - )); - } - - @override - @pragma('vm:prefer-inline') - $RuleCodeCopyWith<$Res> get rule { - return $RuleCodeCopyWith<$Res>(_value.rule, (value) { - return _then(_value.copyWith(rule: value)); - }); - } -} - -/// @nodoc -@JsonSerializable() -class _$AssistFilterResult extends AssistFilterResult { - const _$AssistFilterResult( - {required this.rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - required this.span, - @JsonKey(ignore: true) - this.editsComputer, - final String? $type}) - : $type = $type ?? 'default', - super._(); - - factory _$AssistFilterResult.fromJson(Map json) => - _$$AssistFilterResultFromJson(json); - - @override - final RuleCode rule; - @override - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - final SourceSpan span; - @override - @JsonKey(ignore: true) - final EditsComputer? editsComputer; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'AssistResult(rule: $rule, span: $span, editsComputer: $editsComputer)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$AssistFilterResult && - (identical(other.rule, rule) || other.rule == rule) && - (identical(other.span, span) || other.span == span) && - (identical(other.editsComputer, editsComputer) || - other.editsComputer == editsComputer)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash(runtimeType, rule, span, editsComputer); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$AssistFilterResultCopyWith<_$AssistFilterResult> get copyWith => - __$$AssistFilterResultCopyWithImpl<_$AssistFilterResult>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer) - $default, { - required TResult Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits) - withEdits, - }) { - return $default(rule, span, editsComputer); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer)? - $default, { - TResult? Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits)? - withEdits, - }) { - return $default?.call(rule, span, editsComputer); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer)? - $default, { - TResult Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits)? - withEdits, - required TResult orElse(), - }) { - if ($default != null) { - return $default(rule, span, editsComputer); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(AssistFilterResult value) $default, { - required TResult Function(AssistResultWithEdits value) withEdits, - }) { - return $default(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(AssistFilterResult value)? $default, { - TResult? Function(AssistResultWithEdits value)? withEdits, - }) { - return $default?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(AssistFilterResult value)? $default, { - TResult Function(AssistResultWithEdits value)? withEdits, - required TResult orElse(), - }) { - if ($default != null) { - return $default(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$AssistFilterResultToJson( - this, - ); - } -} - -abstract class AssistFilterResult extends AssistResult { - const factory AssistFilterResult( - {required final RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - required final SourceSpan span, - @JsonKey(ignore: true) - final EditsComputer? editsComputer}) = _$AssistFilterResult; - const AssistFilterResult._() : super._(); - - factory AssistFilterResult.fromJson(Map json) = - _$AssistFilterResult.fromJson; - - RuleCode get rule; - @override - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan get span; - @JsonKey(ignore: true) - EditsComputer? get editsComputer; - @override - @JsonKey(ignore: true) - _$$AssistFilterResultCopyWith<_$AssistFilterResult> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class _$$AssistResultWithEditsCopyWith<$Res> - implements $AssistResultCopyWith<$Res> { - factory _$$AssistResultWithEditsCopyWith(_$AssistResultWithEdits value, - $Res Function(_$AssistResultWithEdits) then) = - __$$AssistResultWithEditsCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits}); - - $RuleCodeCopyWith<$Res> get code; -} - -/// @nodoc -class __$$AssistResultWithEditsCopyWithImpl<$Res> - extends _$AssistResultCopyWithImpl<$Res, _$AssistResultWithEdits> - implements _$$AssistResultWithEditsCopyWith<$Res> { - __$$AssistResultWithEditsCopyWithImpl(_$AssistResultWithEdits _value, - $Res Function(_$AssistResultWithEdits) _then) - : super(_value, _then); - - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? code = null, - Object? span = null, - Object? edits = null, - }) { - return _then(_$AssistResultWithEdits( - code: null == code - ? _value.code - : code // ignore: cast_nullable_to_non_nullable - as RuleCode, - span: null == span - ? _value.span - : span // ignore: cast_nullable_to_non_nullable - as SourceSpan, - edits: null == edits - ? _value._edits - : edits // ignore: cast_nullable_to_non_nullable - as List, - )); - } - - @override - @pragma('vm:prefer-inline') - $RuleCodeCopyWith<$Res> get code { - return $RuleCodeCopyWith<$Res>(_value.code, (value) { - return _then(_value.copyWith(code: value)); - }); - } -} - -/// @nodoc -@JsonSerializable() -class _$AssistResultWithEdits extends AssistResultWithEdits { - const _$AssistResultWithEdits( - {required this.code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - required this.span, - final List edits = const [], - final String? $type}) - : _edits = edits, - $type = $type ?? 'withEdits', - super._(); - - factory _$AssistResultWithEdits.fromJson(Map json) => - _$$AssistResultWithEditsFromJson(json); - - @override - final RuleCode code; - @override - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - final SourceSpan span; - final List _edits; - @override - @JsonKey() - List get edits { - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_edits); - } - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'AssistResult.withEdits(code: $code, span: $span, edits: $edits)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$AssistResultWithEdits && - (identical(other.code, code) || other.code == code) && - (identical(other.span, span) || other.span == span) && - const DeepCollectionEquality().equals(other._edits, _edits)); - } - - @JsonKey(ignore: true) - @override - int get hashCode => Object.hash( - runtimeType, code, span, const DeepCollectionEquality().hash(_edits)); - - @JsonKey(ignore: true) - @override - @pragma('vm:prefer-inline') - _$$AssistResultWithEditsCopyWith<_$AssistResultWithEdits> get copyWith => - __$$AssistResultWithEditsCopyWithImpl<_$AssistResultWithEdits>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when( - TResult Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer) - $default, { - required TResult Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits) - withEdits, - }) { - return withEdits(code, span, edits); - } - - @override - @optionalTypeArgs - TResult? whenOrNull( - TResult? Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer)? - $default, { - TResult? Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits)? - withEdits, - }) { - return withEdits?.call(code, span, edits); - } - - @override - @optionalTypeArgs - TResult maybeWhen( - TResult Function( - RuleCode rule, - @Assert('span.sourceUrl != null') - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - @JsonKey(ignore: true) - EditsComputer? editsComputer)? - $default, { - TResult Function( - RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan span, - List edits)? - withEdits, - required TResult orElse(), - }) { - if (withEdits != null) { - return withEdits(code, span, edits); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map( - TResult Function(AssistFilterResult value) $default, { - required TResult Function(AssistResultWithEdits value) withEdits, - }) { - return withEdits(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull( - TResult? Function(AssistFilterResult value)? $default, { - TResult? Function(AssistResultWithEdits value)? withEdits, - }) { - return withEdits?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap( - TResult Function(AssistFilterResult value)? $default, { - TResult Function(AssistResultWithEdits value)? withEdits, - required TResult orElse(), - }) { - if (withEdits != null) { - return withEdits(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$AssistResultWithEditsToJson( - this, - ); - } -} - -abstract class AssistResultWithEdits extends AssistResult { - const factory AssistResultWithEdits( - {required final RuleCode code, - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - required final SourceSpan span, - final List edits}) = _$AssistResultWithEdits; - const AssistResultWithEdits._() : super._(); - - factory AssistResultWithEdits.fromJson(Map json) = - _$AssistResultWithEdits.fromJson; - - RuleCode get code; - @override - @JsonKey(toJson: sourceSpanToJson, fromJson: sourceSpanFromJson) - SourceSpan get span; - List get edits; - @override - @JsonKey(ignore: true) - _$$AssistResultWithEditsCopyWith<_$AssistResultWithEdits> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/packages/sidecar_lints/lib/src/lints/avoid_string_literal.dart b/packages/sidecar_lints/lib/src/lints/avoid_string_literal.dart index d3e2e15b..978b255e 100644 --- a/packages/sidecar_lints/lib/src/lints/avoid_string_literal.dart +++ b/packages/sidecar_lints/lib/src/lints/avoid_string_literal.dart @@ -6,7 +6,7 @@ import '../constants.dart'; /// Locates all strings. /// /// Used as a simple lint rule for running automated tests on Sidecar package. -class AvoidStringLiteral extends Rule with Lint, QuickFix { +class AvoidStringLiteral extends LintRule with QuickFix { static const _id = 'avoid_string_literal'; static const _message = 'Avoid any hardcoded Strings in Text widgets'; static const _correction = 'Prefer to use a translated Intl message instead.'; diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index 34a0f61a..698f96dd 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -476,7 +476,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-09T06:26:19.624577Z", + "generated": "2023-01-14T21:01:52.972159Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index e744ede7..e6bf5f4e 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-09 01:26:19.616588. +# Generated by pub on 2023-01-14 16:01:52.964758. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index 190ecf53..4edff89b 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -1,6 +1,6 @@ --- title: Bloc File Structure -sidebar_position: 2 +sidebar_position: 3 --- import CodeBlock from '@theme/CodeBlock'; @@ -18,6 +18,7 @@ Prevent developers from putting bloc code in UI files. ### Learning Objectives +- Why would we want to create a Lint Rule ? Ans: to enforce some rules on our codebase - Conditional lint rule - Inspects path of ResolvedUnitResult - Using context variables (like ```unit```) diff --git a/website/sidecar/docs/tutorials/hello_world.mdx b/website/sidecar/docs/tutorials/hello_world.mdx index 0afd3615..61a7d4e8 100644 --- a/website/sidecar/docs/tutorials/hello_world.mdx +++ b/website/sidecar/docs/tutorials/hello_world.mdx @@ -14,7 +14,7 @@ import { ## Overview -This tutorial will give you a brief introduction to creating rules. +This tutorial will give you an in-depth introduction to creating a basic rule. At the conclusion of the tutorial, we will have the following code showing a lint message. @@ -24,27 +24,186 @@ At the conclusion of the tutorial, we will have the following code showing a lin After completion, we will know how to do the following: -- Explore the base ```Rule``` class which every rule must extend +- Explore the base ```LintRule``` class which every lint rule must extend +- Create Analyzer Logic for our particular use case - Declaring the rule in a way that allows it to be discovered by Sidecar -- Create a Lint Rule that appears in our IDE +- Validating a Lint Rule within our IDE Let's get started. -## Creating a Rule Package +## Defining a Rule -- rule packages can contain 1 or more rules -- ```dart create hello_world_rules``` -- import Sidecar and analyzer packages +### Creating a Rule Package + +First, we must create a package for our lints to reside in as well as add the necessary dependencies to it. + +```bash +# create our package and open the directory +dart create hello_world_rules && cd hello_world_rules + +# add sidecar dependency +dart pub add sidecar + +# add official package:analyzer +dart pub add analyzer +``` + +> NOTE: version conflicts will arise if using a Dart SDK version thats not v2.17.0 + +Though a rule package can contain one or more rules, for this example we'll create a single Lint Rule. + +``` +import 'package:sidecar/sidecar.dart'; + +class HelloWorld extends LintRule { + @override + LintCode get code => const LintCode('hello_world', package: 'hello_world_rules'); + + ... + +} +``` + +The summary of all Sidecar Rule requirements are: + +- [ ] every rule must have a unique rule ID (in snake_case) +- [ ] the class name of the Rule must match the rule ID (in PascalCase) +- [ ] the `code.package` parameter must match the name given to our rule package + + +### Defining the Logic for our use case + +For our paricular rule, we want to create a lint that simply outputs 'Hello world!' +any time we create code that has a string containing 'Is there anybody there?'. +Our requirements are therefore: + +- Analyze all Strings +- If the String value is equal to the text 'Is there anybody there?' then report a lint with the message 'Hello world!' + +In order to analyze all Strings in a particular file, we must override the `visitSimpleStringLiteral` method. + In later tutorials, we will cover how to determine which visit method(s) to use for a given use case. + + ``` +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:sidecar/sidecar.dart'; + +class HelloWorld extends LintRule { + ... + @override + void visitSimpleStringLiteral(SimpleStringLiteral node) { + // TODO: implement visitSimpleStringLiteral + super.visitSimpleStringLiteral(node); + } +} +``` + +The takeaway here is that the logic we write within this method will be executed for every String literal that appears in our codebase, +and the information of this code will be delivered via the `node` parameter of all visit methods. + +For our use case, we want to check if the particular String contains the code 'Is there anybody there?'. We do so easily by writing the following logic: + +``` +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:sidecar/sidecar.dart'; + +class HelloWorld extends LintRule { + ... + @override + void visitSimpleStringLiteral(SimpleStringLiteral node) { + final stringValue = node.value; + if (stringValue == 'Is there anybody there?') { + reportAstNode(node, message: 'Hello world!'); + } + } +} +``` + +The last thing we must do for our newly created Rule class is add our rule's `visitSimpleStringLiteral` method to Sidecar's NodeRegistry; +without this step, our visitor method will never be executed. + +``` +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:sidecar/sidecar.dart'; + +class HelloWorld extends LintRule { + + @override + LintCode get code => const LintCode('hello_world', package: 'hello_world_rules'); + + @override + void initializeVisitor(NodeRegistry registry) { + registry.addSimpleStringLiteral(this); + } + + @override + void visitSimpleStringLiteral(SimpleStringLiteral node) { + final stringValue = node.value; + if (stringValue == 'Is there anybody there?') { + reportAstNode(node, message: 'Hello world!'); + } + super.visitSimpleStringLiteral(node); + } +} +``` + +We've now fully defined our `HelloWorld` rule class! + +### Making our Rule Visible to Sidecar -## Defining our Rule -- explain the thought-process behind what we want the lint to do -- extend Rule base class and Lint -- use Simple String literal visitor -- LintCode explanation - adding lint code to package's pubspec.yaml file +- ensuring the rule is available from lib/hello_world_rules.dart + +## Validating our LintRule in an IDE + +The best way to visually test if our lint is working is by creating an example package: + +```bash +# within directory hello_world_rules +dart create example && cd hello_world_rules + +# add your rule package from path +dart pub add hello_world_rules --path ../ +``` + + +- Add lint rule to sidecar.yaml +- Enable sidecar in our analysis_options.yaml + +Lastly, add our 'Is there anybody there?' string into a dart file. + +{trimSnippet(example)} + +After waiting a couple seconds for the Sidecar plugin to boot up, you should see a lint appear over the string. + +Congrats! You've created your first lint rule. 🎉 + +## Conclusion + +This is a simple example of what it takes to create a Lint Rule using Sidecar. +On one hand, creating the logic to analyze code can be relatively straightforward, +only taking a few lines of code to write: + +``` + void visitSimpleStringLiteral(SimpleStringLiteral node) { + final stringValue = node.value; + if (stringValue == 'Is there anybody there?') { + reportAstNode(node, message: 'Hello world!'); + } + } +``` +On the otherhand, there are many individual requirements to abide by, and forgetting any +of them results in no lint appearing at all. + +- Rule Checklist (core concepts?) + +In the next tutorials, we will cover ways to help remember all of the rule requirements by using the package `sidecar_lints`. + +- Link to next tutorial +- Link to hello_world rule in github -## Validating our LintRule in IDE +## Save for next tutorials: -- Create an example app (dart command) -- add string \ No newline at end of file +- When creating a rule that is meant to inspect some code, it's important for us to think about AstNode and Tokens. +- Rules are run for each CompilationUnit (Core Concept) +- How can we determine which visitor method to use? \ No newline at end of file diff --git a/website/sidecar/docs/tutorials/string_locator.mdx b/website/sidecar/docs/tutorials/string_locator.mdx index 25061f9e..61d77450 100644 --- a/website/sidecar/docs/tutorials/string_locator.mdx +++ b/website/sidecar/docs/tutorials/string_locator.mdx @@ -1,6 +1,6 @@ --- title: String Locator -sidebar_position: 3 +sidebar_position: 2 --- import CodeBlock from '@theme/CodeBlock'; @@ -25,4 +25,7 @@ Find all string literals used in 'Text' widgets ### Notes: -- I dont love this example; without Refactoring features it may seem half-baked \ No newline at end of file +- I dont love this example; without Refactoring features it may seem half-baked +- However, we could use this as an opportunity to compare to existing packages that try to satisfy the same goal +- E.g. string_literal_finder (https://github.com/hpoul/string_literal_finder/issues?q=is%3Aissue+) +- e.g. localizely \ No newline at end of file diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log new file mode 100644 index 00000000..e0f4f331 --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log @@ -0,0 +1 @@ +2023-01-14T16:26:52.777265 diff --git a/website/sidecar/lib/src/tutorials/design_system_insets/.gitignore b/website/sidecar/lib/src/tutorials/design_system_insets/.gitignore deleted file mode 100644 index 3c8a1572..00000000 --- a/website/sidecar/lib/src/tutorials/design_system_insets/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Files and directories created by pub. -.dart_tool/ -.packages - -# Conventional directory for build output. -build/ diff --git a/website/sidecar/lib/src/tutorials/design_system_insets/CHANGELOG.md b/website/sidecar/lib/src/tutorials/design_system_insets/CHANGELOG.md deleted file mode 100644 index effe43c8..00000000 --- a/website/sidecar/lib/src/tutorials/design_system_insets/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.0 - -- Initial version. diff --git a/website/sidecar/lib/src/tutorials/design_system_insets/README.md b/website/sidecar/lib/src/tutorials/design_system_insets/README.md deleted file mode 100644 index 3816eca3..00000000 --- a/website/sidecar/lib/src/tutorials/design_system_insets/README.md +++ /dev/null @@ -1,2 +0,0 @@ -A sample command-line application with an entrypoint in `bin/`, library code -in `lib/`, and example unit test in `test/`. diff --git a/website/sidecar/lib/src/tutorials/design_system_insets/analysis_options.yaml b/website/sidecar/lib/src/tutorials/design_system_insets/analysis_options.yaml deleted file mode 100644 index dee8927a..00000000 --- a/website/sidecar/lib/src/tutorials/design_system_insets/analysis_options.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# This file configures the static analysis results for your project (errors, -# warnings, and lints). -# -# This enables the 'recommended' set of lints from `package:lints`. -# This set helps identify many issues that may lead to problems when running -# or consuming Dart code, and enforces writing Dart using a single, idiomatic -# style and format. -# -# If you want a smaller set of lints you can change this to specify -# 'package:lints/core.yaml'. These are just the most critical lints -# (the recommended set includes the core lints). -# The core lints are also what is used by pub.dev for scoring packages. - -include: package:lints/recommended.yaml - -# Uncomment the following section to specify additional rules. - -# linter: -# rules: -# - camel_case_types - -# analyzer: -# exclude: -# - path/to/excluded/files/** - -# For more information about the core and recommended set of lints, see -# https://dart.dev/go/core-lints - -# For additional information about configuring this file, see -# https://dart.dev/guides/language/analysis-options diff --git a/website/sidecar/lib/src/tutorials/design_system_insets/bin/design_system_insets.dart b/website/sidecar/lib/src/tutorials/design_system_insets/bin/design_system_insets.dart deleted file mode 100644 index 842b0044..00000000 --- a/website/sidecar/lib/src/tutorials/design_system_insets/bin/design_system_insets.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:design_system_insets/design_system_insets.dart' as design_system_insets; - -void main(List arguments) { - print('Hello world: ${design_system_insets.calculate()}!'); -} diff --git a/website/sidecar/lib/src/tutorials/design_system_insets/lib/design_system_insets.dart b/website/sidecar/lib/src/tutorials/design_system_insets/lib/design_system_insets.dart deleted file mode 100644 index f64ad726..00000000 --- a/website/sidecar/lib/src/tutorials/design_system_insets/lib/design_system_insets.dart +++ /dev/null @@ -1,3 +0,0 @@ -int calculate() { - return 6 * 7; -} diff --git a/website/sidecar/lib/src/tutorials/design_system_insets/pubspec.yaml b/website/sidecar/lib/src/tutorials/design_system_insets/pubspec.yaml deleted file mode 100644 index f847bc9b..00000000 --- a/website/sidecar/lib/src/tutorials/design_system_insets/pubspec.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: design_system_insets -description: A sample command-line application. -version: 1.0.0 -# homepage: https://www.example.com - -environment: - sdk: '>=2.17.6 <3.0.0' - -# dependencies: -# path: ^1.8.0 - -dev_dependencies: - lints: ^2.0.0 - test: ^1.16.0 diff --git a/website/sidecar/lib/src/tutorials/design_system_insets/test/design_system_insets_test.dart b/website/sidecar/lib/src/tutorials/design_system_insets/test/design_system_insets_test.dart deleted file mode 100644 index e7e5113a..00000000 --- a/website/sidecar/lib/src/tutorials/design_system_insets/test/design_system_insets_test.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:design_system_insets/design_system_insets.dart'; -import 'package:test/test.dart'; - -void main() { - test('calculate', () { - expect(calculate(), 42); - }); -} From 5fa5d1b6295c934b460006ad526a5585995b45d1 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Mon, 16 Jan 2023 15:28:59 -0500 Subject: [PATCH 02/29] docs: Hello world code snippets. --- .../sidecar/.dart_tool/package_config.json | 2 +- website/sidecar/.packages | 2 +- .../docs/tutorials/bloc_file_structure.mdx | 3 + .../sidecar/docs/tutorials/hello_world.mdx | 69 +---- website/sidecar/docs/usage/configuration.md | 1 + website/sidecar/docs/usage/intial_setup.mdx | 12 +- website/sidecar/docs/usage/playground.md | 1 + .../snippets/.dart_tool/package_config.json | 284 ++++++++++++++++++ .../snippets/.dart_tool/package_config_subset | 185 ++++++++++++ .../docs/usage/snippets/.dart_tool/version | 1 + website/sidecar/docs/usage/snippets/.packages | 52 ++++ website/sidecar/docs/usage/troubleshooting.md | 22 +- .../lib/src/tutorials/hello_world/.gitignore | 6 + .../lib/src/tutorials/hello_world/README.md | 2 + .../hello_world/analysis_options.yaml | 30 ++ .../src/tutorials/hello_world/lib/step0.dart | 16 + .../src/tutorials/hello_world/lib/step1.dart | 22 ++ .../src/tutorials/hello_world/lib/step2.dart | 24 ++ .../src/tutorials/hello_world/lib/step3.dart | 22 ++ .../src/tutorials/hello_world/pubspec.yaml | 17 ++ 20 files changed, 703 insertions(+), 70 deletions(-) create mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/package_config.json create mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset create mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/version create mode 100644 website/sidecar/docs/usage/snippets/.packages create mode 100644 website/sidecar/lib/src/tutorials/hello_world/.gitignore create mode 100644 website/sidecar/lib/src/tutorials/hello_world/README.md create mode 100644 website/sidecar/lib/src/tutorials/hello_world/analysis_options.yaml create mode 100644 website/sidecar/lib/src/tutorials/hello_world/lib/step0.dart create mode 100644 website/sidecar/lib/src/tutorials/hello_world/lib/step1.dart create mode 100644 website/sidecar/lib/src/tutorials/hello_world/lib/step2.dart create mode 100644 website/sidecar/lib/src/tutorials/hello_world/lib/step3.dart create mode 100644 website/sidecar/lib/src/tutorials/hello_world/pubspec.yaml diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index 698f96dd..1867e8c5 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -476,7 +476,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-14T21:01:52.972159Z", + "generated": "2023-01-16T19:36:01.584882Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index e6bf5f4e..2932d77e 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-14 16:01:52.964758. +# Generated by pub on 2023-01-16 14:36:01.576617. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index 4edff89b..6804e6f6 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -19,6 +19,9 @@ Prevent developers from putting bloc code in UI files. ### Learning Objectives - Why would we want to create a Lint Rule ? Ans: to enforce some rules on our codebase + +Let's say we want to enforce all developers on our Flutter app to use a feature-first project structure. + - Conditional lint rule - Inspects path of ResolvedUnitResult - Using context variables (like ```unit```) diff --git a/website/sidecar/docs/tutorials/hello_world.mdx b/website/sidecar/docs/tutorials/hello_world.mdx index 61a7d4e8..d6db54cb 100644 --- a/website/sidecar/docs/tutorials/hello_world.mdx +++ b/website/sidecar/docs/tutorials/hello_world.mdx @@ -6,6 +6,10 @@ sidebar_position: 1 import CodeBlock from '@theme/CodeBlock'; import ruleDefintion from "!!raw-loader!../../../../examples/hello_world_rules/lib/hello_world_rules.dart"; import example from "!!raw-loader!../../../../examples/hello_world_rules/example/lib/example.dart"; +import step0 from "!!raw-loader!../../lib/src/tutorials/hello_world/lib/step0.dart"; +import step1 from "!!raw-loader!../../lib/src/tutorials/hello_world/lib/step1.dart"; +import step2 from "!!raw-loader!../../lib/src/tutorials/hello_world/lib/step2.dart"; +import step3 from "!!raw-loader!../../lib/src/tutorials/hello_world/lib/step3.dart"; import pubspec from "!!raw-loader!../../../../examples/hello_world_rules/pubspec.yaml"; import { trimSnippet, @@ -52,17 +56,7 @@ dart pub add analyzer Though a rule package can contain one or more rules, for this example we'll create a single Lint Rule. -``` -import 'package:sidecar/sidecar.dart'; - -class HelloWorld extends LintRule { - @override - LintCode get code => const LintCode('hello_world', package: 'hello_world_rules'); - - ... - -} -``` +{trimSnippet(step0)} The summary of all Sidecar Rule requirements are: @@ -83,68 +77,21 @@ Our requirements are therefore: In order to analyze all Strings in a particular file, we must override the `visitSimpleStringLiteral` method. In later tutorials, we will cover how to determine which visit method(s) to use for a given use case. - ``` -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:sidecar/sidecar.dart'; -class HelloWorld extends LintRule { - ... - @override - void visitSimpleStringLiteral(SimpleStringLiteral node) { - // TODO: implement visitSimpleStringLiteral - super.visitSimpleStringLiteral(node); - } -} -``` +{trimSnippet(step1)} The takeaway here is that the logic we write within this method will be executed for every String literal that appears in our codebase, and the information of this code will be delivered via the `node` parameter of all visit methods. For our use case, we want to check if the particular String contains the code 'Is there anybody there?'. We do so easily by writing the following logic: -``` -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:sidecar/sidecar.dart'; - -class HelloWorld extends LintRule { - ... - @override - void visitSimpleStringLiteral(SimpleStringLiteral node) { - final stringValue = node.value; - if (stringValue == 'Is there anybody there?') { - reportAstNode(node, message: 'Hello world!'); - } - } -} -``` +{trimSnippet(step2)} The last thing we must do for our newly created Rule class is add our rule's `visitSimpleStringLiteral` method to Sidecar's NodeRegistry; without this step, our visitor method will never be executed. -``` -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:sidecar/sidecar.dart'; - -class HelloWorld extends LintRule { - - @override - LintCode get code => const LintCode('hello_world', package: 'hello_world_rules'); - - @override - void initializeVisitor(NodeRegistry registry) { - registry.addSimpleStringLiteral(this); - } - @override - void visitSimpleStringLiteral(SimpleStringLiteral node) { - final stringValue = node.value; - if (stringValue == 'Is there anybody there?') { - reportAstNode(node, message: 'Hello world!'); - } - super.visitSimpleStringLiteral(node); - } -} -``` +{trimSnippet(step3)} We've now fully defined our `HelloWorld` rule class! diff --git a/website/sidecar/docs/usage/configuration.md b/website/sidecar/docs/usage/configuration.md index abe75d9c..afba2813 100644 --- a/website/sidecar/docs/usage/configuration.md +++ b/website/sidecar/docs/usage/configuration.md @@ -1,6 +1,7 @@ --- sidebar_position: 3 sidebar_label: 'Configuration' +description: Walkthrough of the sidecar.yaml file. --- # Configuration (sidecar.yaml) diff --git a/website/sidecar/docs/usage/intial_setup.mdx b/website/sidecar/docs/usage/intial_setup.mdx index 3918670c..adc46662 100644 --- a/website/sidecar/docs/usage/intial_setup.mdx +++ b/website/sidecar/docs/usage/intial_setup.mdx @@ -1,5 +1,6 @@ --- sidebar_position: 2 +description: Setup rules for use within an IDE or CLI. --- import CodeBlock from '@theme/CodeBlock'; @@ -14,18 +15,21 @@ import { # Initial Setup -There are 2 modes which Sidecar packages can be run within a Dart or Flutter Project: IDE Server or Cli mode. +Sidecar is used via Sidecar-based rule packages like [design_system_lints](https://pub.dev/packages/design_system_lints). + +There are 2 modes which these packages can be run within a Dart or Flutter Project: IDE Server or Cli mode. ## IDE Server Mode ### Requirements -- Dart SDK v2.17.0+ - Supported IDE with Extension for Dart Language Server +- Dart SDK v2.17.0+ ### Setup Instructions -To enable any Sidecar-based package (like [design_system_lints](https://pub.dev/packages/design_system_lints)) to display lints and assist recommendations within your IDE, perform the following setup steps: +To enable any Sidecar-based package like [design_system_lints](https://pub.dev/packages/design_system_lints) +to display lints and assist recommendations within your IDE, perform the following setup steps: 1. Depend on the lint package: @@ -35,7 +39,7 @@ To enable any Sidecar-based package (like [design_system_lints](https://pub.dev/ {trimSnippet(main)} -3. Enable the plugin to run by adding ```sidecar``` to the list of plugins in ```analysis_options.yaml``` +3. Enable the Sidecar plugin to run by adding ```sidecar``` to the list of plugins in ```analysis_options.yaml``` {trimSnippet(analysisOptions)} diff --git a/website/sidecar/docs/usage/playground.md b/website/sidecar/docs/usage/playground.md index 3e923b38..3dab7a2e 100644 --- a/website/sidecar/docs/usage/playground.md +++ b/website/sidecar/docs/usage/playground.md @@ -1,5 +1,6 @@ --- sidebar_position: 4 +description: Try out Sidecar. --- # Playground \ No newline at end of file diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json b/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json new file mode 100644 index 00000000..12493fbf --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json @@ -0,0 +1,284 @@ +{ + "configVersion": 2, + "packages": [ + { + "name": "_fe_analyzer_shared", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "analyzer", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "analyzer_plugin", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "args", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "async", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "characters", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "checked_yaml", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "cli_util", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "collection", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "convert", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "crypto", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "dart_style", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "design_system_lints", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.9", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "file", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "flutter", + "rootUri": "file:///Users/pattobrien/fvm/versions/3.0.5/packages/flutter", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "freezed_annotation", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "frontend_server_client", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "glob", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1", + "packageUri": "lib/", + "languageVersion": "2.15" + }, + { + "name": "hotreloader", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "json_annotation", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "logging", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "material_color_utilities", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4", + "packageUri": "lib/", + "languageVersion": "2.13" + }, + { + "name": "meta", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "package_config", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "path", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "pub_semver", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "pubspec_parse", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "recase", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "riverpod", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "sidecar", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.18", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "sidecar_annotations", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "sidecar_package_utilities", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "sky_engine", + "rootUri": "file:///Users/pattobrien/fvm/versions/3.0.5/bin/cache/pkg/sky_engine", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "source_span", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "stack_trace", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "state_notifier", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "stream_transform", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "string_scanner", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "term_glyph", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "typed_data", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "uuid", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "vector_math", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "vm_service", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0", + "packageUri": "lib/", + "languageVersion": "2.15" + }, + { + "name": "watcher", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "yaml", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "counter_app", + "rootUri": "../", + "packageUri": "lib/", + "languageVersion": "2.17" + } + ], + "generated": "2023-01-16T17:46:57.926930Z", + "generator": "pub", + "generatorVersion": "2.17.6" +} diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset b/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset new file mode 100644 index 00000000..bc0cc2da --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset @@ -0,0 +1,185 @@ +_fe_analyzer_shared +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ +analyzer +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ +analyzer_plugin +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ +args +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib/ +async +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib/ +characters +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/lib/ +checked_yaml +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib/ +cli_util +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib/ +collection +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib/ +convert +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0/lib/ +crypto +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib/ +dart_style +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4/lib/ +design_system_lints +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.9/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.9/lib/ +file +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib/ +freezed_annotation +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0/lib/ +frontend_server_client +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3/lib/ +glob +2.15 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1/lib/ +hotreloader +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5/lib/ +json_annotation +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib/ +logging +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib/ +material_color_utilities +2.13 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/lib/ +meta +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/ +package_config +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0/lib/ +path +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3/lib/ +pub_semver +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3/lib/ +pubspec_parse +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1/lib/ +recase +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0/lib/ +riverpod +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3/lib/ +sidecar +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.18/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.18/lib/ +sidecar_annotations +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/lib/ +sidecar_package_utilities +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/lib/ +source_span +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1/lib/ +stack_trace +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/ +state_notifier +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1/lib/ +stream_transform +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0/lib/ +string_scanner +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib/ +term_glyph +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib/ +typed_data +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib/ +uuid +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7/lib/ +vector_math +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib/ +vm_service +2.15 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0/lib/ +watcher +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2/lib/ +yaml +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib/ +counter_app +2.17 +file:///Users/pattobrien/Development/sidecar/website/sidecar/docs/usage/snippets/ +file:///Users/pattobrien/Development/sidecar/website/sidecar/docs/usage/snippets/lib/ +sky_engine +2.12 +file:///Users/pattobrien/fvm/versions/3.0.5/bin/cache/pkg/sky_engine/ +file:///Users/pattobrien/fvm/versions/3.0.5/bin/cache/pkg/sky_engine/lib/ +flutter +2.12 +file:///Users/pattobrien/fvm/versions/3.0.5/packages/flutter/ +file:///Users/pattobrien/fvm/versions/3.0.5/packages/flutter/lib/ +2 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/version b/website/sidecar/docs/usage/snippets/.dart_tool/version new file mode 100644 index 00000000..7da3c168 --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.dart_tool/version @@ -0,0 +1 @@ +3.0.5 \ No newline at end of file diff --git a/website/sidecar/docs/usage/snippets/.packages b/website/sidecar/docs/usage/snippets/.packages new file mode 100644 index 00000000..90d29cad --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.packages @@ -0,0 +1,52 @@ +# This file is deprecated. Tools should instead consume +# `.dart_tool/package_config.json`. +# +# For more info see: https://dart.dev/go/dot-packages-deprecation +# +# Generated by pub on 2023-01-16 12:46:57.923027. +_fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ +analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ +analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ +args:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib/ +async:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib/ +characters:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/lib/ +checked_yaml:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib/ +cli_util:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib/ +collection:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib/ +convert:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0/lib/ +crypto:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib/ +dart_style:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4/lib/ +design_system_lints:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.9/lib/ +file:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib/ +flutter:file:///Users/pattobrien/fvm/versions/3.0.5/packages/flutter/lib/ +freezed_annotation:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0/lib/ +frontend_server_client:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3/lib/ +glob:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1/lib/ +hotreloader:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5/lib/ +json_annotation:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib/ +logging:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib/ +material_color_utilities:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/lib/ +meta:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/ +package_config:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0/lib/ +path:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3/lib/ +pub_semver:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3/lib/ +pubspec_parse:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1/lib/ +recase:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0/lib/ +riverpod:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3/lib/ +sidecar:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.18/lib/ +sidecar_annotations:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/lib/ +sidecar_package_utilities:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/lib/ +sky_engine:file:///Users/pattobrien/fvm/versions/3.0.5/bin/cache/pkg/sky_engine/lib/ +source_span:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1/lib/ +stack_trace:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/ +state_notifier:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1/lib/ +stream_transform:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0/lib/ +string_scanner:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib/ +term_glyph:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib/ +typed_data:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib/ +uuid:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7/lib/ +vector_math:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib/ +vm_service:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0/lib/ +watcher:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2/lib/ +yaml:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib/ +counter_app:lib/ diff --git a/website/sidecar/docs/usage/troubleshooting.md b/website/sidecar/docs/usage/troubleshooting.md index 85800306..cb569312 100644 --- a/website/sidecar/docs/usage/troubleshooting.md +++ b/website/sidecar/docs/usage/troubleshooting.md @@ -1,10 +1,26 @@ --- sidebar_position: 4 +description: What to do when lints no longer update, RAM usage, etc. --- # Troubleshooting -In IDE-Server mode, Sidecar boots up using the ```analyzer_plugin``` APIs created by the Dart team. Due to the experimental nature of that package, there are some limitations that users should be aware of. +In IDE-Server mode, Sidecar boots up using the ```analyzer_plugin``` APIs created by the Dart team. +Due to the experimental nature of both Sidecar and analyzer_plugin, there are some limitations that users should be aware of. + +## Lints stop updating + +When using a lint package, its possible that you experience unexpected problems, such as: + +- A particular file does not show lints +- Lints stop updating or are seen appearing over the wrong code + +While the remaining bugs are being ironed out, the recommended fix is to restart the analyzer server and/or restart your IDE +(can be done via Dart official extensions). +## Increased RAM resources + +Since the official Dart lints do not themselves use the analyzer_plugin architecture, +they are run on a separate isolate than Sidecar rules. Because both Dart programs must analyze the entire +Dart package and dependencies, enabling Sidecar is expected to have some increase in RAM resources +(expect around 25% increase, but no more than a 50% increase). -- Performance (duplicated RAM resources) -- Lints stop updating (reboot server) diff --git a/website/sidecar/lib/src/tutorials/hello_world/.gitignore b/website/sidecar/lib/src/tutorials/hello_world/.gitignore new file mode 100644 index 00000000..3c8a1572 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/hello_world/.gitignore @@ -0,0 +1,6 @@ +# Files and directories created by pub. +.dart_tool/ +.packages + +# Conventional directory for build output. +build/ diff --git a/website/sidecar/lib/src/tutorials/hello_world/README.md b/website/sidecar/lib/src/tutorials/hello_world/README.md new file mode 100644 index 00000000..3816eca3 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/hello_world/README.md @@ -0,0 +1,2 @@ +A sample command-line application with an entrypoint in `bin/`, library code +in `lib/`, and example unit test in `test/`. diff --git a/website/sidecar/lib/src/tutorials/hello_world/analysis_options.yaml b/website/sidecar/lib/src/tutorials/hello_world/analysis_options.yaml new file mode 100644 index 00000000..dee8927a --- /dev/null +++ b/website/sidecar/lib/src/tutorials/hello_world/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/website/sidecar/lib/src/tutorials/hello_world/lib/step0.dart b/website/sidecar/lib/src/tutorials/hello_world/lib/step0.dart new file mode 100644 index 00000000..4c2baf21 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/hello_world/lib/step0.dart @@ -0,0 +1,16 @@ +/* SNIPPET START */ +import 'package:sidecar/sidecar.dart'; + +class HelloWorld extends LintRule { + @override + LintCode get code => + const LintCode('hello_world', package: 'hello_world_rules'); + /* SKIP */ + + @override + void initializeVisitor(NodeRegistry registry) { + // TODO: implement initializeVisitor + } + /* SKIP END */ +} +/* SNIPPET END */ \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/hello_world/lib/step1.dart b/website/sidecar/lib/src/tutorials/hello_world/lib/step1.dart new file mode 100644 index 00000000..27b7e3f2 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/hello_world/lib/step1.dart @@ -0,0 +1,22 @@ +/* SNIPPET START */ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:sidecar/sidecar.dart'; + +class HelloWorld extends LintRule { + @override + void visitSimpleStringLiteral(SimpleStringLiteral node) { + // TODO: implement visitSimpleStringLiteral + super.visitSimpleStringLiteral(node); + } /* SKIP */ + + @override + // TODO: implement code + LintCode get code => throw UnimplementedError(); + + @override + void initializeVisitor(NodeRegistry registry) { + // TODO: implement initializeVisitor + } + /* SKIP END */ +} +/* SNIPPET END */ \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/hello_world/lib/step2.dart b/website/sidecar/lib/src/tutorials/hello_world/lib/step2.dart new file mode 100644 index 00000000..937fb97c --- /dev/null +++ b/website/sidecar/lib/src/tutorials/hello_world/lib/step2.dart @@ -0,0 +1,24 @@ +/* SNIPPET START */ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:sidecar/sidecar.dart'; + +class HelloWorld extends LintRule { + @override + void visitSimpleStringLiteral(SimpleStringLiteral node) { + final stringValue = node.value; + if (stringValue == 'Is there anybody there?') { + reportAstNode(node, message: 'Hello world!'); + } + } /* SKIP */ + + @override + // TODO: implement code + LintCode get code => throw UnimplementedError(); + + @override + void initializeVisitor(NodeRegistry registry) { + // TODO: implement initializeVisitor + } + /* SKIP END */ +} +/* SNIPPET END */ \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/hello_world/lib/step3.dart b/website/sidecar/lib/src/tutorials/hello_world/lib/step3.dart new file mode 100644 index 00000000..24410ce6 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/hello_world/lib/step3.dart @@ -0,0 +1,22 @@ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:sidecar/sidecar.dart'; + +class HelloWorld extends LintRule { + @override + LintCode get code => + const LintCode('hello_world', package: 'hello_world_rules'); + + @override + void initializeVisitor(NodeRegistry registry) { + registry.addSimpleStringLiteral(this); + } + + @override + void visitSimpleStringLiteral(SimpleStringLiteral node) { + final stringValue = node.value; + if (stringValue == 'Is there anybody there?') { + reportAstNode(node, message: 'Hello world!'); + } + super.visitSimpleStringLiteral(node); + } +} diff --git a/website/sidecar/lib/src/tutorials/hello_world/pubspec.yaml b/website/sidecar/lib/src/tutorials/hello_world/pubspec.yaml new file mode 100644 index 00000000..dfac75af --- /dev/null +++ b/website/sidecar/lib/src/tutorials/hello_world/pubspec.yaml @@ -0,0 +1,17 @@ +name: hello_world +description: A sample command-line application. +version: 1.0.0 +publish_to: none +# homepage: https://www.example.com + +environment: + sdk: ">=2.17.6 <3.0.0" + +dependencies: + analyzer: ^4.7.0 + sidecar: + path: ../../../../../../packages/sidecar/ + +dev_dependencies: + lints: ^2.0.0 + test: ^1.16.0 From 063379c0fb94b556b46036f41dfa7445395a138d Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Mon, 16 Jan 2023 18:16:00 -0500 Subject: [PATCH 03/29] docs: Application layer example code. --- .../lib/src/lints/rule_is_not_accessible.dart | 24 ++++++--- .../sidecar/.dart_tool/package_config.json | 2 +- website/sidecar/.packages | 2 +- website/sidecar/.vscode/launch.json | 49 +++++++++++++++++++ .../docs/tutorials/bloc_file_structure.mdx | 49 +++++++++++++++++-- .../bloc_feature_structure/.gitignore | 6 +++ .../bloc_feature_structure/CHANGELOG.md | 3 ++ .../bloc_feature_structure/README.md | 2 + .../analysis_options.yaml | 5 ++ .../bloc_feature_structure/example/.gitignore | 6 +++ .../example/CHANGELOG.md | 3 ++ .../bloc_feature_structure/example/README.md | 2 + .../example/analysis_options.yaml | 5 ++ .../features/cart/application/cart_bloc.dart | 5 ++ .../src/features/cart/presentation/view.dart | 5 ++ .../example/pubspec.yaml | 20 ++++++++ .../example/sidecar.yaml | 7 +++ .../lib/bloc_feature_structure.dart | 1 + .../bloc_feature_structure/lib/step0.dart | 47 ++++++++++++++++++ .../bloc_feature_structure/pubspec.yaml | 28 +++++++++++ 20 files changed, 257 insertions(+), 14 deletions(-) create mode 100644 website/sidecar/.vscode/launch.json create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/.gitignore create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/CHANGELOG.md create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/README.md create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/example/.gitignore create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/example/CHANGELOG.md create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/example/README.md create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/example/analysis_options.yaml create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/example/lib/src/features/cart/application/cart_bloc.dart create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/example/lib/src/features/cart/presentation/view.dart create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/example/pubspec.yaml create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/example/sidecar.yaml create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_feature_structure.dart create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml diff --git a/packages/sidecar_lints/lib/src/lints/rule_is_not_accessible.dart b/packages/sidecar_lints/lib/src/lints/rule_is_not_accessible.dart index 097eaf9d..cace035c 100644 --- a/packages/sidecar_lints/lib/src/lints/rule_is_not_accessible.dart +++ b/packages/sidecar_lints/lib/src/lints/rule_is_not_accessible.dart @@ -26,16 +26,24 @@ class RuleIsNotAccessible extends LintRule { @override void visitClassDeclaration(ClassDeclaration node) { if (!isSidecarRule(node)) return; + // final libPath = ''; + // final libUnit = await context.currentSession.getResolvedUnit(libPath); - final data = context.data - .firstWhereOrNull((element) => element.code == kPublicRulesCode) - ?.data; + reportAstNode(node.name, message: _message); + } + // @override + // void visitClassDeclaration(ClassDeclaration node) { + // if (!isSidecarRule(node)) return; - if (data == null) return; - final classes = data.first as List; + // final data = context.data + // .firstWhereOrNull((element) => element.code == kPublicRulesCode) + // ?.data; - if (classes.any((clazz) => clazz == node.declaredElement2)) return; + // if (data == null) return; + // final classes = data.first as List; - reportAstNode(node.name, message: _message); - } + // if (classes.any((clazz) => clazz == node.declaredElement2)) return; + + // reportAstNode(node.name, message: _message); + // } } diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index 1867e8c5..766d606e 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -476,7 +476,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-16T19:36:01.584882Z", + "generated": "2023-01-16T22:57:40.785908Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index 2932d77e..4182252d 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-16 14:36:01.576617. +# Generated by pub on 2023-01-16 17:57:40.777691. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ diff --git a/website/sidecar/.vscode/launch.json b/website/sidecar/.vscode/launch.json new file mode 100644 index 00000000..fa3ae764 --- /dev/null +++ b/website/sidecar/.vscode/launch.json @@ -0,0 +1,49 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "sidecar", + "request": "launch", + "type": "dart" + }, + { + "name": "snippets", + "cwd": "docs/usage/snippets", + "request": "launch", + "type": "dart" + }, + { + "name": "snippets (profile mode)", + "cwd": "docs/usage/snippets", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "snippets (release mode)", + "cwd": "docs/usage/snippets", + "request": "launch", + "type": "dart", + "flutterMode": "release" + }, + { + "name": "bloc_feature_structure", + "program": "lib/src/tutorials/bloc_feature_structure/example/.dart_tool/sidecar/debug.dart", + "request": "launch", + "type": "dart", + "args": [ + "--enable-vm-service", + "--debug", + ] + }, + { + "name": "hello_world", + "cwd": "lib/src/tutorials/hello_world", + "request": "launch", + "type": "dart" + } + ] +} \ No newline at end of file diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index 6804e6f6..7902889e 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -14,14 +14,55 @@ import { ## Overview -Prevent developers from putting bloc code in UI files. +Let's say we want to enforce all developers on our Flutter app to use a feature-first project structure. -### Learning Objectives +A typical feature-first folder structure for a Flutter app may look something like the following: -- Why would we want to create a Lint Rule ? Ans: to enforce some rules on our codebase +``` +├── core +├── features +│ ├── cart +│ │ ├── data +│ │ │ ├── models +│ │ │ ├── repositories +│ │ │ ├── services +│ │ ├── domain +│ │ │ ├── entities +│ │ │ ├── repositories +│ │ ├── presentation +│ │ │ ├── controller +│ │ │ ├── view +``` -Let's say we want to enforce all developers on our Flutter app to use a feature-first project structure. +Since each layer category will have its own definition of what code should be allowed in it, +this tutorial will focus on disallowing the creation of BLoC classes in any folder besides +the presentation > controller layer. +### Learning Objectives + +- Why would we want to create a Lint Rule ? Ans: to enforce some rules on our codebase - Conditional lint rule - Inspects path of ResolvedUnitResult - Using context variables (like ```unit```) + + +## Define Requirements + +Determining the logic of a Lint rule can be tricky. For this feature-first BLoC rule, we want to prevent a developer from +creating a bloc class outside of presentation > controller, but this can possibly be done in different ways. +Additionally, we want to be mindful that the performance of all of our lints could be negatively affected if +one lint rule is written in an inefficient way, so we need to write our lint in an efficient way. + +Therefore, the logic of our rule will be: + +1. Use the `includes` getter of LintRule to restrict our rule from executing on anything besides `/presentation/controller/` folders. +2. Check if a given unit imports package:bloc; if not, we exit. +3. Check if any particular class declaration extends `BlocBase`. + +With requirements defined, we can move onto the build phase. + + +## Notes + +- Mention packages that try to solve folder structure (but dont do so) +- Include steps to set up `sidecar_lints` to assist with rule creation \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/.gitignore b/website/sidecar/lib/src/tutorials/bloc_feature_structure/.gitignore new file mode 100644 index 00000000..3c8a1572 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/.gitignore @@ -0,0 +1,6 @@ +# Files and directories created by pub. +.dart_tool/ +.packages + +# Conventional directory for build output. +build/ diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/CHANGELOG.md b/website/sidecar/lib/src/tutorials/bloc_feature_structure/CHANGELOG.md new file mode 100644 index 00000000..effe43c8 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/README.md b/website/sidecar/lib/src/tutorials/bloc_feature_structure/README.md new file mode 100644 index 00000000..3816eca3 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/README.md @@ -0,0 +1,2 @@ +A sample command-line application with an entrypoint in `bin/`, library code +in `lib/`, and example unit test in `test/`. diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml new file mode 100644 index 00000000..341d5688 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:lints/recommended.yaml + +analyzer: + plugins: + - sidecar diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/.gitignore b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/.gitignore new file mode 100644 index 00000000..3c8a1572 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/.gitignore @@ -0,0 +1,6 @@ +# Files and directories created by pub. +.dart_tool/ +.packages + +# Conventional directory for build output. +build/ diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/CHANGELOG.md b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/CHANGELOG.md new file mode 100644 index 00000000..effe43c8 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/README.md b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/README.md new file mode 100644 index 00000000..3816eca3 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/README.md @@ -0,0 +1,2 @@ +A sample command-line application with an entrypoint in `bin/`, library code +in `lib/`, and example unit test in `test/`. diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/analysis_options.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/analysis_options.yaml new file mode 100644 index 00000000..341d5688 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:lints/recommended.yaml + +analyzer: + plugins: + - sidecar diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/lib/src/features/cart/application/cart_bloc.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/lib/src/features/cart/application/cart_bloc.dart new file mode 100644 index 00000000..e56a265d --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/lib/src/features/cart/application/cart_bloc.dart @@ -0,0 +1,5 @@ +import 'package:bloc/bloc.dart'; + +class SomeBlocClass extends BlocBase { + SomeBlocClass(super.state); +} diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/lib/src/features/cart/presentation/view.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/lib/src/features/cart/presentation/view.dart new file mode 100644 index 00000000..e56a265d --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/lib/src/features/cart/presentation/view.dart @@ -0,0 +1,5 @@ +import 'package:bloc/bloc.dart'; + +class SomeBlocClass extends BlocBase { + SomeBlocClass(super.state); +} diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/pubspec.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/pubspec.yaml new file mode 100644 index 00000000..3c2e54ab --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/pubspec.yaml @@ -0,0 +1,20 @@ +name: example +description: A sample command-line application. +version: 1.0.0 +publish_to: none + +environment: + sdk: ">=2.17.6 <3.0.0" + +dependencies: + bloc: ^8.1.0 + bloc_feature_structure: + path: ../ + +dev_dependencies: + lints: ^2.0.0 + test: ^1.16.0 + +dependency_overrides: + sidecar: + path: ../../../../../../../packages/sidecar/ diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/sidecar.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/sidecar.yaml new file mode 100644 index 00000000..4f44c957 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/sidecar.yaml @@ -0,0 +1,7 @@ +includes: + - "lib/**/*.dart" + +lints: + bloc_feature_structure: + rules: + bloc_outside_controller_layer: diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_feature_structure.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_feature_structure.dart new file mode 100644 index 00000000..03798f28 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_feature_structure.dart @@ -0,0 +1 @@ +export 'step0.dart'; diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart new file mode 100644 index 00000000..49cd00dc --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart @@ -0,0 +1,47 @@ +/* SNIPPET START */ +import 'package:analyzer/dart/element/element.dart'; +import 'package:glob/glob.dart'; +import 'package:sidecar/sidecar.dart'; +import 'package:analyzer/dart/ast/ast.dart'; + +class BlocOutsideControllerLayer extends LintRule { + static const _id = 'bloc_outside_controller_layer'; + static const _package = 'bloc_feature_structure'; + static const _message = 'Logic should only be created in application folders'; + + @override + LintCode get code => const LintCode(_id, package: _package); + /* SKIP */ + + @override + void initializeVisitor(NodeRegistry registry) => registry + ..addCompilationUnit(this) + ..addClassDeclaration(this); + /* SKIP END */ + + @override + void visitCompilationUnit(CompilationUnit node) { + if (applicationFolderGlob.matches(unit.path)) return; + final imports = node.directives.whereType(); + final uris = + imports.map((i) => i.element2?.uri).whereType(); + final blocUris = uris + .where((element) => element.relativeUri.pathSegments.first == 'bloc'); + if (blocUris.isNotEmpty) hasBlocImport = true; + } + + bool hasBlocImport = false; + + @override + void visitClassDeclaration(ClassDeclaration node) { + if (!hasBlocImport) return; + if (!blocBase.isAssignableFromType(node.declaredElement2?.thisType)) return; + + reportAstNode(node.name, message: _message); + } +} + +/* SNIPPET END */ + +final blocBase = TypeChecker.fromName('BlocBase', packageName: 'bloc'); +final applicationFolderGlob = Glob('**/features/**/application/**'); diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml new file mode 100644 index 00000000..c081fd65 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml @@ -0,0 +1,28 @@ +name: bloc_feature_structure +description: A sample command-line application. +version: 1.0.0 +publish_to: none +# homepage: https://www.example.com + +environment: + sdk: ">=2.17.6 <3.0.0" + +dependencies: + analyzer: ^4.7.0 + glob: ^2.1.1 + sidecar: ^0.1.0-dev.18 + +dev_dependencies: + lints: ^2.0.0 + sidecar_lints: ^0.1.0-dev.1 + test: ^1.16.0 + +dependency_overrides: + sidecar: + path: ../../../../../../packages/sidecar/ + sidecar_lints: + path: ../../../../../../packages/sidecar_lints/ + +sidecar: + lints: + - bloc_outside_controller_layer From 40fc2c49fa6dc6710b192ce4b1cb0c67f9095f9c Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Tue, 17 Jan 2023 15:37:22 -0500 Subject: [PATCH 04/29] docs: Bloc feature-first snippets. --- .../sidecar/.dart_tool/package_config.json | 2 +- website/sidecar/.packages | 2 +- .../docs/tutorials/bloc_file_structure.mdx | 61 ++++++++++++++++--- .../docs/tutorials/design_system_insets.mdx | 8 +++ .../sidecar/docs/tutorials/string_locator.mdx | 8 ++- .../analysis_options.yaml | 2 - .../bloc_feature_structure/lib/step0.dart | 48 ++++++++------- .../bloc_feature_structure/lib/step1.dart | 19 ++++++ .../bloc_feature_structure/lib/step1a.yaml | 12 ++++ .../bloc_feature_structure/lib/step2.dart | 38 ++++++++++++ .../bloc_feature_structure/lib/step3.dart | 42 +++++++++++++ .../bloc_feature_structure/pubspec.yaml | 4 -- .../src/components/CodeSnippet/index.tsx | 23 +++++++ 13 files changed, 229 insertions(+), 40 deletions(-) create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1.dart create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1a.yaml create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step3.dart diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index 766d606e..b3c582e3 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -476,7 +476,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-16T22:57:40.785908Z", + "generated": "2023-01-17T17:39:47.968110Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index 4182252d..3688e4fe 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-16 17:57:40.777691. +# Generated by pub on 2023-01-17 12:39:47.951940. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index 7902889e..e31cf0a3 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -5,11 +5,16 @@ sidebar_position: 3 import CodeBlock from '@theme/CodeBlock'; import ruleDefintion from "!!raw-loader!../../../../examples/hello_world_rules/lib/hello_world_rules.dart"; -import example from "!!raw-loader!../../../../examples/hello_world_rules/example/lib/example.dart"; +import step0 from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step0.dart"; +import step1 from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step1.dart"; +import step1a from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step1a.yaml"; +import step2 from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step2.dart"; +import step3 from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step3.dart"; import pubspec from "!!raw-loader!../../../../examples/hello_world_rules/pubspec.yaml"; import { trimSnippet, CodeSnippet, + generateSnippet, } from "../../src/components/CodeSnippet"; ## Overview @@ -30,9 +35,18 @@ A typical feature-first folder structure for a Flutter app may look something li │ │ │ ├── entities │ │ │ ├── repositories │ │ ├── presentation -│ │ │ ├── controller -│ │ │ ├── view +│ │ │ ├── controllers +│ │ │ ├── states +│ │ │ ├── widgets ``` +> *The above structure is roughly based on [this great article series](https://codewithandrea.com/articles/flutter-app-architecture-riverpod-introduction/) +> on Riverpod architecture by Andrea Bizzotto.* + +In order to enforce the use of such a structure programmatically, we could implement any of the following cases: + +- only permit the declaration of widgets in the appropriate `widgets` folders +- only permit the declaration of business logic in `controllers` folder (such as `BlocBase` or `Notifier` classes) +- prevent json serialization/deserialization from anywhere besides `data` layer Since each layer category will have its own definition of what code should be allowed in it, this tutorial will focus on disallowing the creation of BLoC classes in any folder besides @@ -41,8 +55,7 @@ the presentation > controller layer. ### Learning Objectives - Why would we want to create a Lint Rule ? Ans: to enforce some rules on our codebase -- Conditional lint rule -- Inspects path of ResolvedUnitResult +- Two-part LintRule that checks unit file path before proceeding - Using context variables (like ```unit```) @@ -51,18 +64,46 @@ the presentation > controller layer. Determining the logic of a Lint rule can be tricky. For this feature-first BLoC rule, we want to prevent a developer from creating a bloc class outside of presentation > controller, but this can possibly be done in different ways. Additionally, we want to be mindful that the performance of all of our lints could be negatively affected if -one lint rule is written in an inefficient way, so we need to write our lint in an efficient way. +just one lint rule is written in an inefficient way, so we need to write our lint in an efficient way. Therefore, the logic of our rule will be: -1. Use the `includes` getter of LintRule to restrict our rule from executing on anything besides `/presentation/controller/` folders. -2. Check if a given unit imports package:bloc; if not, we exit. -3. Check if any particular class declaration extends `BlocBase`. +1. Restrict our rule from executing on anything besides files contained in `**/presentation/controller/**` folders +2. Check if any particular class declaration extends `BlocBase` +3. OPTIONAL: Check if the particular file imports package:bloc before checking all class declarations for a BlocBase extension With requirements defined, we can move onto the build phase. +## Creating our Rule + +Lets start by creating a rule package `bloc_feature_structure` and adding `sidecar` +and `analyzer` to `pubspec.yaml`. + + +```bash +dart create bloc_feature_structure +``` + +{generateSnippet(step1a, [''])} + +Our first course of action is to create our LintRule class and its respective LintCode. + + +{generateSnippet(step1, [''])} + +Just as we did in the previous tutorial, we ensure that the class name is the PascalCase representation of the LintCode.id +that we assign. + +From here we can build out the first of our requirements: to only analyze files outside of the application folder. +If you remember back to our feature-first project structure, + +{trimSnippet(step2, [''])} + +Finally, if +{trimSnippet(step3, [''])} ## Notes - Mention packages that try to solve folder structure (but dont do so) -- Include steps to set up `sidecar_lints` to assist with rule creation \ No newline at end of file +- Include steps to set up `sidecar_lints` to assist with rule creation +- Mention future benchmarking objective to help optimize rules \ No newline at end of file diff --git a/website/sidecar/docs/tutorials/design_system_insets.mdx b/website/sidecar/docs/tutorials/design_system_insets.mdx index 8b59f462..d784e13e 100644 --- a/website/sidecar/docs/tutorials/design_system_insets.mdx +++ b/website/sidecar/docs/tutorials/design_system_insets.mdx @@ -12,6 +12,14 @@ import { CodeSnippet, } from "../../src/components/CodeSnippet"; +## Objective + +A design system is a standardization concept that abstracts the design specifics of an application into reusable components. +In a Flutter application, we could isolate any design specifics to a `theme.dart` file, and reference our theme anywhere +in our application. + + + ### Learning Objectives - Multiple similar use cases (EdgeInsets.all, .only, .symmetric) diff --git a/website/sidecar/docs/tutorials/string_locator.mdx b/website/sidecar/docs/tutorials/string_locator.mdx index 61d77450..c98c3720 100644 --- a/website/sidecar/docs/tutorials/string_locator.mdx +++ b/website/sidecar/docs/tutorials/string_locator.mdx @@ -9,13 +9,19 @@ import example from "!!raw-loader!../../../../examples/hello_world_rules/example import pubspec from "!!raw-loader!../../../../examples/hello_world_rules/pubspec.yaml"; import { trimSnippet, + generateSnippet, CodeSnippet, } from "../../src/components/CodeSnippet"; +## Introduction + +In the previous tutorial, we learned the basics of creating a LintRule and how to +enable rules in an example app. Now we'll take what we learned to come up with a +more real use case: finding any string that doesn't come from a translation library. ## Objective -Find all string literals used in 'Text' widgets +Find all string literals used in 'Text' widgets. ### Learning Objectives diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml index 341d5688..02fa8fa2 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml @@ -1,5 +1,3 @@ -include: package:lints/recommended.yaml - analyzer: plugins: - sidecar diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart index 49cd00dc..32635288 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart @@ -1,47 +1,53 @@ /* SNIPPET START */ +import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:glob/glob.dart'; import 'package:sidecar/sidecar.dart'; -import 'package:analyzer/dart/ast/ast.dart'; class BlocOutsideControllerLayer extends LintRule { + // we can use variables for better code legibility static const _id = 'bloc_outside_controller_layer'; static const _package = 'bloc_feature_structure'; - static const _message = 'Logic should only be created in application folders'; + static const _message = 'Logic should be created in application folders.'; @override LintCode get code => const LintCode(_id, package: _package); - /* SKIP */ - - @override - void initializeVisitor(NodeRegistry registry) => registry - ..addCompilationUnit(this) - ..addClassDeclaration(this); - /* SKIP END */ @override void visitCompilationUnit(CompilationUnit node) { if (applicationFolderGlob.matches(unit.path)) return; - final imports = node.directives.whereType(); - final uris = - imports.map((i) => i.element2?.uri).whereType(); - final blocUris = uris - .where((element) => element.relativeUri.pathSegments.first == 'bloc'); - if (blocUris.isNotEmpty) hasBlocImport = true; + + unitHasBlocImport = doesHaveBlocImport(node); } - bool hasBlocImport = false; + bool doesHaveBlocImport(CompilationUnit node) { + final blocImports = node.directives + .whereType() + .map((i) => i.element2?.uri) + .whereType() + .where((e) => e.relativeUri.pathSegments.first == 'bloc'); + if (blocImports.isNotEmpty) unitHasBlocImport = true; + return false; + } + + late bool unitHasBlocImport; + + @override + void initializeVisitor(NodeRegistry registry) => + registry.addCompilationUnit(this); @override void visitClassDeclaration(ClassDeclaration node) { - if (!hasBlocImport) return; - if (!blocBase.isAssignableFromType(node.declaredElement2?.thisType)) return; + if (!unitHasBlocImport) return; + + final classType = node.declaredElement2?.thisType; + if (!blocBase.isAssignableFromType(classType)) return; reportAstNode(node.name, message: _message); } } -/* SNIPPET END */ - -final blocBase = TypeChecker.fromName('BlocBase', packageName: 'bloc'); final applicationFolderGlob = Glob('**/features/**/application/**'); +final blocBase = + TypeChecker.fromName('BlocBase', packageName: 'bloc'); +/* SNIPPET END */ \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1.dart new file mode 100644 index 00000000..3b62d356 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1.dart @@ -0,0 +1,19 @@ +/* SNIPPET START */ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:sidecar/sidecar.dart'; + +class BlocOutsideControllerLayer extends LintRule { + // we can use variables for better code legibility + static const id = 'bloc_outside_controller_layer'; + static const package = 'bloc_feature_structure'; + static const message = 'Logic should be created in application folders.'; + + @override + LintCode get code => const LintCode(id, package: package); + + @override + void initializeVisitor(NodeRegistry registry) { + // TODO: implement initializeVisitor + } +} +/* SNIPPET END */ \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1a.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1a.yaml new file mode 100644 index 00000000..82adbc03 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1a.yaml @@ -0,0 +1,12 @@ +name: bloc_feature_structure +version: 1.0.0 + +environment: + sdk: ">=2.17.0 <3.0.0" + +dependencies: + analyzer: ^4.7.0 + sidecar: ^0.1.0-dev.18 + +dev_dependencies: + sidecar_lints: ^0.1.0-dev.1 diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart new file mode 100644 index 00000000..00a4ecf7 --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart @@ -0,0 +1,38 @@ +/* SNIPPET START */ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:glob/glob.dart'; +import 'package:sidecar/sidecar.dart'; + +class BlocOutsideControllerLayer extends LintRule { + /* SKIP */ + // we can use variables for better code legibility + static const _id = 'bloc_outside_controller_layer'; + static const _package = 'bloc_feature_structure'; + static const _message = 'Logic should be created in application folders.'; + + @override + LintCode get code => const LintCode(_id, package: _package); + + /* SKIP END */ + @override + void visitCompilationUnit(CompilationUnit node) { + final applicationFolderGlob = Glob('**/features/**/application/**'); + isApplicationFile = applicationFolderGlob.matches(unit.path); + } + + late final bool isApplicationFile; + + @override + void initializeVisitor(NodeRegistry registry) => + registry.addCompilationUnit(this); + + @override + void visitClassDeclaration(ClassDeclaration node) { + // skip any files within an `application` folder + if (isApplicationFile) return; + + // TODO: check if declaration is a bloc class + } +} + +/* SNIPPET END */ \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step3.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step3.dart new file mode 100644 index 00000000..8cdf27eb --- /dev/null +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step3.dart @@ -0,0 +1,42 @@ +/* SNIPPET START */ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:glob/glob.dart'; +import 'package:sidecar/sidecar.dart'; + +class BlocOutsideControllerLayer extends LintRule { + /* SKIP */ + // we can use variables for better code legibility + static const _id = 'bloc_outside_controller_layer'; + static const _package = 'bloc_feature_structure'; + static const _message = 'Logic should be created in application folders.'; + + @override + LintCode get code => const LintCode(_id, package: _package); + + @override + void visitCompilationUnit(CompilationUnit node) { + final applicationFolderGlob = Glob('**/features/**/application/**'); + isApplicationFile = applicationFolderGlob.matches(unit.path); + } + + late final bool isApplicationFile; + + @override + void initializeVisitor(NodeRegistry registry) => + registry.addCompilationUnit(this); + + /* SKIP END */ + @override + void visitClassDeclaration(ClassDeclaration node) { + // skip any files within an `application` folder + if (isApplicationFile) return; + + final blocBase = TypeChecker.fromName('BlocBase', packageName: 'bloc'); + final classType = node.declaredElement2?.thisType; + if (!blocBase.isAssignableFromType(classType)) return; + + reportAstNode(node.name, message: _message); + } +} + +/* SNIPPET END */ \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml index c081fd65..8f0e6524 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml @@ -1,8 +1,6 @@ name: bloc_feature_structure -description: A sample command-line application. version: 1.0.0 publish_to: none -# homepage: https://www.example.com environment: sdk: ">=2.17.6 <3.0.0" @@ -13,9 +11,7 @@ dependencies: sidecar: ^0.1.0-dev.18 dev_dependencies: - lints: ^2.0.0 sidecar_lints: ^0.1.0-dev.1 - test: ^1.16.0 dependency_overrides: sidecar: diff --git a/website/sidecar/src/components/CodeSnippet/index.tsx b/website/sidecar/src/components/CodeSnippet/index.tsx index 6dc20239..1ae2988a 100644 --- a/website/sidecar/src/components/CodeSnippet/index.tsx +++ b/website/sidecar/src/components/CodeSnippet/index.tsx @@ -6,6 +6,29 @@ const SKIP_END = "/* SKIP END */"; const START_AT = "/* SNIPPET START */"; const END_AT = "/* SNIPPET END */"; +const SNIPPET_START = "/* SNIPPET START */"; +const SNIPPET_END = "/* SNIPPET END */"; + +export function generateSnippet(contents: string, snippets: Array): string { + // find all snippet comments in code + // extract the snippet name + // if snippet name doesnt match any value from snippets array => remove that code + const startAtIndex = contents.indexOf(START_AT); + if (startAtIndex < 0) return contents; + + let endAtIndex = contents.indexOf(END_AT); + if (endAtIndex < 0) endAtIndex = undefined; + + contents = contents + .substring(startAtIndex + START_AT.length, endAtIndex) + .trim(); + + return contents.replace( + /\n?(?:\/\* SNIP \*\/)(?:\n|.)+(?:\/\* SKIP END \*\/)/, + "" + ); +} + export function trimSnippet(snippet: string): string { const startAtIndex = snippet.indexOf(START_AT); if (startAtIndex < 0) return snippet; From b45ce017ea517b4461a8ff27deabe100acbadd23 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Tue, 17 Jan 2023 15:46:40 -0500 Subject: [PATCH 05/29] docs: Delete placeholder tutorial pages. --- .../docs/tutorials/design_system_insets.mdx | 1 - .../docs/tutorials/design_system_methods.mdx | 18 ------------------ website/sidecar/docs/tutorials/quick_fix.mdx | 18 ------------------ .../tutorials/riverpod_final_providers.mdx | 18 ------------------ 4 files changed, 55 deletions(-) delete mode 100644 website/sidecar/docs/tutorials/design_system_methods.mdx delete mode 100644 website/sidecar/docs/tutorials/quick_fix.mdx delete mode 100644 website/sidecar/docs/tutorials/riverpod_final_providers.mdx diff --git a/website/sidecar/docs/tutorials/design_system_insets.mdx b/website/sidecar/docs/tutorials/design_system_insets.mdx index d784e13e..da8f63c7 100644 --- a/website/sidecar/docs/tutorials/design_system_insets.mdx +++ b/website/sidecar/docs/tutorials/design_system_insets.mdx @@ -19,7 +19,6 @@ In a Flutter application, we could isolate any design specifics to a `theme.dart in our application. - ### Learning Objectives - Multiple similar use cases (EdgeInsets.all, .only, .symmetric) diff --git a/website/sidecar/docs/tutorials/design_system_methods.mdx b/website/sidecar/docs/tutorials/design_system_methods.mdx deleted file mode 100644 index e9750966..00000000 --- a/website/sidecar/docs/tutorials/design_system_methods.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Design System Methods -sidebar_position: 7 ---- - -import CodeBlock from '@theme/CodeBlock'; -import ruleDefintion from "!!raw-loader!../../../../examples/hello_world_rules/lib/hello_world_rules.dart"; -import example from "!!raw-loader!../../../../examples/hello_world_rules/example/lib/example.dart"; -import pubspec from "!!raw-loader!../../../../examples/hello_world_rules/pubspec.yaml"; -import { - trimSnippet, - CodeSnippet, -} from "../../src/components/CodeSnippet"; - -### Learning Objectives - -- - diff --git a/website/sidecar/docs/tutorials/quick_fix.mdx b/website/sidecar/docs/tutorials/quick_fix.mdx deleted file mode 100644 index 00fd152f..00000000 --- a/website/sidecar/docs/tutorials/quick_fix.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: ??? -sidebar_position: 6 ---- - -import CodeBlock from '@theme/CodeBlock'; -import ruleDefintion from "!!raw-loader!../../../../examples/hello_world_rules/lib/hello_world_rules.dart"; -import example from "!!raw-loader!../../../../examples/hello_world_rules/example/lib/example.dart"; -import pubspec from "!!raw-loader!../../../../examples/hello_world_rules/pubspec.yaml"; -import { - trimSnippet, - CodeSnippet, -} from "../../src/components/CodeSnippet"; - -### Learning Objectives - -- Lints with QuickFixes - diff --git a/website/sidecar/docs/tutorials/riverpod_final_providers.mdx b/website/sidecar/docs/tutorials/riverpod_final_providers.mdx deleted file mode 100644 index dbb3a342..00000000 --- a/website/sidecar/docs/tutorials/riverpod_final_providers.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Riverpod Final Providers -sidebar_position: 5 ---- - -import CodeBlock from '@theme/CodeBlock'; -import ruleDefintion from "!!raw-loader!../../../../examples/hello_world_rules/lib/hello_world_rules.dart"; -import example from "!!raw-loader!../../../../examples/hello_world_rules/example/lib/example.dart"; -import pubspec from "!!raw-loader!../../../../examples/hello_world_rules/pubspec.yaml"; -import { - trimSnippet, - CodeSnippet, -} from "../../src/components/CodeSnippet"; - -### Learning Objectives - -- Audience: Package Author - From a7808406d89dc90a8d66ed5feeebb83d0a62da66 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Tue, 17 Jan 2023 16:00:36 -0500 Subject: [PATCH 06/29] test: Fixed sourceLocationFromJson --- .../src/utils/json_utils/source_location_utils_test.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/sidecar/test/src/utils/json_utils/source_location_utils_test.dart b/packages/sidecar/test/src/utils/json_utils/source_location_utils_test.dart index 54c01903..30d829e2 100644 --- a/packages/sidecar/test/src/utils/json_utils/source_location_utils_test.dart +++ b/packages/sidecar/test/src/utils/json_utils/source_location_utils_test.dart @@ -30,8 +30,12 @@ void main() { final location = sourceLocationFromJson(json); expect( location, - SourceLocation(10, - sourceUrl: Directory.current.path, line: 1, column: 10), + SourceLocation( + 10, + sourceUrl: Uri.file(Directory.current.path), + line: 1, + column: 10, + ), ); }); }); From 783e56fdab2d149db1a2c48ab7cd7542ecd65784 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:17:15 -0500 Subject: [PATCH 07/29] docs: Index page text changes. --- .../usage/snippets/.dart_tool/package_config.json | 2 +- .../snippets/.dart_tool/sidecar_logs/latest.log | 2 +- .../.dart_tool/sidecar_logs/log-1673731612777.log | 1 + .../.dart_tool/sidecar_logs/log-1674142970687.log | 1 + website/sidecar/docs/usage/snippets/.packages | 2 +- website/sidecar/docusaurus.config.js | 8 ++++---- .../src/components/HomepageFeatures/index.tsx | 14 ++++++-------- website/sidecar/src/pages/index.tsx | 6 +++--- 8 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1673731612777.log create mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1674142970687.log diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json b/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json index 12493fbf..a8be2c75 100644 --- a/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json +++ b/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json @@ -278,7 +278,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-16T17:46:57.926930Z", + "generated": "2023-01-19T15:42:23.036350Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log index e0f4f331..5a72216b 100644 --- a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log +++ b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log @@ -1 +1 @@ -2023-01-14T16:26:52.777265 +2023-01-19T10:44:28.801379 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1673731612777.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1673731612777.log new file mode 100644 index 00000000..e0f4f331 --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1673731612777.log @@ -0,0 +1 @@ +2023-01-14T16:26:52.777265 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1674142970687.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1674142970687.log new file mode 100644 index 00000000..81f120ad --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1674142970687.log @@ -0,0 +1 @@ +2023-01-19T10:42:50.687752 diff --git a/website/sidecar/docs/usage/snippets/.packages b/website/sidecar/docs/usage/snippets/.packages index 90d29cad..712026b5 100644 --- a/website/sidecar/docs/usage/snippets/.packages +++ b/website/sidecar/docs/usage/snippets/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-16 12:46:57.923027. +# Generated by pub on 2023-01-19 10:42:23.030255. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ diff --git a/website/sidecar/docusaurus.config.js b/website/sidecar/docusaurus.config.js index cd1bcf1e..fda18ff9 100644 --- a/website/sidecar/docusaurus.config.js +++ b/website/sidecar/docusaurus.config.js @@ -6,9 +6,9 @@ const darkCodeTheme = require('prism-react-renderer/themes/dracula'); /** @type {import('@docusaurus/types').Config} */ const config = { - title: 'Sidecar', - tagline: 'Dinosaurs are cool', - url: 'https://your-docusaurus-test-site.com', + title: 'Sidecar Analyzer', + tagline: 'Enable a more personalized developer experience within your IDE.', + url: 'https://sidecaranalyzer.dev', baseUrl: '/', onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', @@ -16,7 +16,7 @@ const config = { // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: 'facebook', // Usually your GitHub org/user name. + organizationName: 'pattobrien', // Usually your GitHub org/user name. projectName: 'sidecar', // Usually your repo name. // Even if you don't use internalization, you can use this field to set useful diff --git a/website/sidecar/src/components/HomepageFeatures/index.tsx b/website/sidecar/src/components/HomepageFeatures/index.tsx index 07a73bb8..43b8db47 100644 --- a/website/sidecar/src/components/HomepageFeatures/index.tsx +++ b/website/sidecar/src/components/HomepageFeatures/index.tsx @@ -14,28 +14,26 @@ const FeatureList: FeatureItem[] = [ Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <> - Docusaurus was designed from the ground up to be easily installed and - used to get your website up and running quickly. + Use custom lints and quick fixes just as easily as those included in the official Dart linter package. ), }, { - title: 'Focus on What Matters', + title: 'Customize Your DevX', Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, description: ( <> - Docusaurus lets you focus on your docs, and we'll do the chores. Go - ahead and move your docs into the docs directory. + Enforce rules that are perfectly tailored to your package or application. ), }, { - title: 'Powered by React', + title: 'Powered by Dart', Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, description: ( <> - Extend or customize your website layout by reusing React. Docusaurus can - be extended while reusing the same header and footer. + Sidecar was built around Dart and Flutter, so you can expect the same level of performance + as the native Dart SDK toolchain. ), }, diff --git a/website/sidecar/src/pages/index.tsx b/website/sidecar/src/pages/index.tsx index 305139fb..6854617d 100644 --- a/website/sidecar/src/pages/index.tsx +++ b/website/sidecar/src/pages/index.tsx @@ -8,7 +8,7 @@ import HomepageFeatures from '@site/src/components/HomepageFeatures'; import styles from './index.module.css'; function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext(); return (
@@ -18,7 +18,7 @@ function HomepageHeader() { - Docusaurus Tutorial - 5min ⏱️ + Get Started
@@ -27,7 +27,7 @@ function HomepageHeader() { } export default function Home(): JSX.Element { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext(); return ( Date: Thu, 19 Jan 2023 11:38:43 -0500 Subject: [PATCH 08/29] docs: Undraw images, blue style for entire site. --- .../sidecar/.dart_tool/package_config.json | 2 +- website/sidecar/.packages | 2 +- .../snippets/.dart_tool/package_config.json | 136 ++++++++++- .../snippets/.dart_tool/package_config_subset | 92 ++++++- .../.dart_tool/sidecar_logs/latest.log | 2 +- .../sidecar_logs/log-1673731612777.log | 1 - .../sidecar_logs/log-1674142970687.log | 1 - .../log-2023-01-19T11:37:33.118729.log | 1 + website/sidecar/docs/usage/snippets/.packages | 26 +- .../src/components/HomepageFeatures/index.tsx | 6 +- website/sidecar/src/css/custom.scss | 6 +- .../img/undraw_computer_dart_flutter.svg | 228 ++++++++++++++++++ .../sidecar/static/img/undraw_development.svg | 1 + .../static/img/undraw_mobile_development.svg | 1 + 14 files changed, 488 insertions(+), 17 deletions(-) delete mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1673731612777.log delete mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1674142970687.log create mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-2023-01-19T11:37:33.118729.log create mode 100644 website/sidecar/static/img/undraw_computer_dart_flutter.svg create mode 100644 website/sidecar/static/img/undraw_development.svg create mode 100644 website/sidecar/static/img/undraw_mobile_development.svg diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index b3c582e3..102a0117 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -476,7 +476,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-17T17:39:47.968110Z", + "generated": "2023-01-19T16:37:36.053638Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index 3688e4fe..cf3587d9 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-17 12:39:47.951940. +# Generated by pub on 2023-01-19 11:37:36.045196. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json b/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json index a8be2c75..69839050 100644 --- a/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json +++ b/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json @@ -31,6 +31,12 @@ "packageUri": "lib/", "languageVersion": "2.14" }, + { + "name": "boolean_selector", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.1", + "packageUri": "lib/", + "languageVersion": "2.17" + }, { "name": "characters", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0", @@ -61,6 +67,12 @@ "packageUri": "lib/", "languageVersion": "2.12" }, + { + "name": "coverage", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.2", + "packageUri": "lib/", + "languageVersion": "2.15" + }, { "name": "crypto", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2", @@ -115,6 +127,30 @@ "packageUri": "lib/", "languageVersion": "2.12" }, + { + "name": "http_multi_server", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_multi_server-3.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "http_parser", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "io", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/io-1.0.3", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "js", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/js-0.6.5", + "packageUri": "lib/", + "languageVersion": "2.16" + }, { "name": "json_annotation", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0", @@ -127,6 +163,12 @@ "packageUri": "lib/", "languageVersion": "2.12" }, + { + "name": "matcher", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12", + "packageUri": "lib/", + "languageVersion": "2.12" + }, { "name": "material_color_utilities", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4", @@ -139,6 +181,18 @@ "packageUri": "lib/", "languageVersion": "2.12" }, + { + "name": "mime", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/mime-1.0.3", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "node_preamble", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/node_preamble-2.0.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, { "name": "package_config", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0", @@ -151,6 +205,12 @@ "packageUri": "lib/", "languageVersion": "2.12" }, + { + "name": "pool", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pool-1.5.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, { "name": "pub_semver", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3", @@ -175,9 +235,33 @@ "packageUri": "lib/", "languageVersion": "2.17" }, + { + "name": "shelf", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "shelf_packages_handler", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "shelf_static", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "shelf_web_socket", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3", + "packageUri": "lib/", + "languageVersion": "2.17" + }, { "name": "sidecar", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.18", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.19", "packageUri": "lib/", "languageVersion": "2.17" }, @@ -199,6 +283,18 @@ "packageUri": "lib/", "languageVersion": "2.12" }, + { + "name": "source_map_stack_trace", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "source_maps", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.10", + "packageUri": "lib/", + "languageVersion": "2.12" + }, { "name": "source_span", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1", @@ -217,6 +313,12 @@ "packageUri": "lib/", "languageVersion": "2.12" }, + { + "name": "stream_channel", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.1", + "packageUri": "lib/", + "languageVersion": "2.14" + }, { "name": "stream_transform", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0", @@ -235,6 +337,24 @@ "packageUri": "lib/", "languageVersion": "2.12" }, + { + "name": "test", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test-1.21.4", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "test_api", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "test_core", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_core-0.4.16", + "packageUri": "lib/", + "languageVersion": "2.14" + }, { "name": "typed_data", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1", @@ -265,6 +385,18 @@ "packageUri": "lib/", "languageVersion": "2.14" }, + { + "name": "web_socket_channel", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-2.3.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "webkit_inspection_protocol", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, { "name": "yaml", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1", @@ -278,7 +410,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-19T15:42:23.036350Z", + "generated": "2023-01-19T16:37:35.255557Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset b/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset index bc0cc2da..4b299c40 100644 --- a/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset +++ b/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset @@ -18,6 +18,10 @@ async 2.14 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib/ +boolean_selector +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.1/lib/ characters 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/ @@ -38,6 +42,10 @@ convert 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0/lib/ +coverage +2.15 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.2/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.2/lib/ crypto 2.14 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/ @@ -70,6 +78,22 @@ hotreloader 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5/lib/ +http_multi_server +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_multi_server-3.2.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_multi_server-3.2.1/lib/ +http_parser +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/lib/ +io +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/io-1.0.3/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/io-1.0.3/lib/ +js +2.16 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/js-0.6.5/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/js-0.6.5/lib/ json_annotation 2.17 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/ @@ -78,6 +102,10 @@ logging 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib/ +matcher +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib/ material_color_utilities 2.13 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/ @@ -86,6 +114,14 @@ meta 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/ +mime +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/mime-1.0.3/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/mime-1.0.3/lib/ +node_preamble +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/node_preamble-2.0.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/node_preamble-2.0.1/lib/ package_config 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0/ @@ -94,6 +130,10 @@ path 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3/lib/ +pool +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pool-1.5.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pool-1.5.1/lib/ pub_semver 2.17 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3/ @@ -110,10 +150,26 @@ riverpod 2.17 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3/lib/ +shelf +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0/lib/ +shelf_packages_handler +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1/lib/ +shelf_static +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1/lib/ +shelf_web_socket +2.17 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3/lib/ sidecar 2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.18/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.18/lib/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.19/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.19/lib/ sidecar_annotations 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/ @@ -122,6 +178,14 @@ sidecar_package_utilities 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/lib/ +source_map_stack_trace +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1/lib/ +source_maps +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.10/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.10/lib/ source_span 2.14 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1/ @@ -134,6 +198,10 @@ state_notifier 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1/lib/ +stream_channel +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.1/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.1/lib/ stream_transform 2.14 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0/ @@ -146,6 +214,18 @@ term_glyph 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib/ +test +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test-1.21.4/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test-1.21.4/lib/ +test_api +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib/ +test_core +2.14 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_core-0.4.16/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_core-0.4.16/lib/ typed_data 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/ @@ -166,6 +246,14 @@ watcher 2.14 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2/ file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2/lib/ +web_socket_channel +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-2.3.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-2.3.0/lib/ +webkit_inspection_protocol +2.12 +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0/ +file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0/lib/ yaml 2.12 file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/ diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log index 5a72216b..54aeb04d 100644 --- a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log +++ b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log @@ -1 +1 @@ -2023-01-19T10:44:28.801379 +2023-01-19T11:37:42.697621 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1673731612777.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1673731612777.log deleted file mode 100644 index e0f4f331..00000000 --- a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1673731612777.log +++ /dev/null @@ -1 +0,0 @@ -2023-01-14T16:26:52.777265 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1674142970687.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1674142970687.log deleted file mode 100644 index 81f120ad..00000000 --- a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-1674142970687.log +++ /dev/null @@ -1 +0,0 @@ -2023-01-19T10:42:50.687752 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-2023-01-19T11:37:33.118729.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-2023-01-19T11:37:33.118729.log new file mode 100644 index 00000000..a4325137 --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-2023-01-19T11:37:33.118729.log @@ -0,0 +1 @@ +2023-01-19T11:37:33.118729 diff --git a/website/sidecar/docs/usage/snippets/.packages b/website/sidecar/docs/usage/snippets/.packages index 712026b5..3eb886d7 100644 --- a/website/sidecar/docs/usage/snippets/.packages +++ b/website/sidecar/docs/usage/snippets/.packages @@ -3,17 +3,19 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-19 10:42:23.030255. +# Generated by pub on 2023-01-19 11:37:35.249960. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ args:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib/ async:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib/ +boolean_selector:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.1/lib/ characters:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/lib/ checked_yaml:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib/ cli_util:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib/ collection:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib/ convert:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0/lib/ +coverage:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.2/lib/ crypto:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib/ dart_style:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4/lib/ design_system_lints:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.9/lib/ @@ -23,30 +25,50 @@ freezed_annotation:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/f frontend_server_client:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3/lib/ glob:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1/lib/ hotreloader:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5/lib/ +http_multi_server:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_multi_server-3.2.1/lib/ +http_parser:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/lib/ +io:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/io-1.0.3/lib/ +js:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/js-0.6.5/lib/ json_annotation:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib/ logging:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib/ +matcher:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib/ material_color_utilities:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/lib/ meta:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/ +mime:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/mime-1.0.3/lib/ +node_preamble:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/node_preamble-2.0.1/lib/ package_config:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0/lib/ path:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3/lib/ +pool:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pool-1.5.1/lib/ pub_semver:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3/lib/ pubspec_parse:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1/lib/ recase:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0/lib/ riverpod:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3/lib/ -sidecar:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.18/lib/ +shelf:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0/lib/ +shelf_packages_handler:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1/lib/ +shelf_static:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1/lib/ +shelf_web_socket:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3/lib/ +sidecar:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.19/lib/ sidecar_annotations:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/lib/ sidecar_package_utilities:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/lib/ sky_engine:file:///Users/pattobrien/fvm/versions/3.0.5/bin/cache/pkg/sky_engine/lib/ +source_map_stack_trace:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1/lib/ +source_maps:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.10/lib/ source_span:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1/lib/ stack_trace:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/ state_notifier:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1/lib/ +stream_channel:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.1/lib/ stream_transform:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0/lib/ string_scanner:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib/ term_glyph:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib/ +test:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test-1.21.4/lib/ +test_api:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib/ +test_core:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_core-0.4.16/lib/ typed_data:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib/ uuid:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7/lib/ vector_math:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib/ vm_service:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0/lib/ watcher:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2/lib/ +web_socket_channel:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-2.3.0/lib/ +webkit_inspection_protocol:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0/lib/ yaml:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib/ counter_app:lib/ diff --git a/website/sidecar/src/components/HomepageFeatures/index.tsx b/website/sidecar/src/components/HomepageFeatures/index.tsx index 43b8db47..015113e9 100644 --- a/website/sidecar/src/components/HomepageFeatures/index.tsx +++ b/website/sidecar/src/components/HomepageFeatures/index.tsx @@ -11,7 +11,7 @@ type FeatureItem = { const FeatureList: FeatureItem[] = [ { title: 'Easy to Use', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, + Svg: require('@site/static/img/undraw_mobile_development.svg').default, description: ( <> Use custom lints and quick fixes just as easily as those included in the official Dart linter package. @@ -20,7 +20,7 @@ const FeatureList: FeatureItem[] = [ }, { title: 'Customize Your DevX', - Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, + Svg: require('@site/static/img/undraw_development.svg').default, description: ( <> Enforce rules that are perfectly tailored to your package or application. @@ -29,7 +29,7 @@ const FeatureList: FeatureItem[] = [ }, { title: 'Powered by Dart', - Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, + Svg: require('@site/static/img/undraw_computer_dart_flutter.svg').default, description: ( <> Sidecar was built around Dart and Flutter, so you can expect the same level of performance diff --git a/website/sidecar/src/css/custom.scss b/website/sidecar/src/css/custom.scss index 2bc6a4cf..22dd425b 100644 --- a/website/sidecar/src/css/custom.scss +++ b/website/sidecar/src/css/custom.scss @@ -6,7 +6,7 @@ /* You can override the default Infima variables here. */ :root { - --ifm-color-primary: #2e8555; + --ifm-color-primary: #0175C2; --ifm-color-primary-dark: #29784c; --ifm-color-primary-darker: #277148; --ifm-color-primary-darkest: #205d3b; @@ -19,7 +19,7 @@ /* For readability concerns, you should choose a lighter palette in dark mode. */ [data-theme='dark'] { - --ifm-color-primary: #25c2a0; + --ifm-color-primary: #13B9FD; --ifm-color-primary-dark: #21af90; --ifm-color-primary-darker: #1fa588; --ifm-color-primary-darkest: #1a8870; @@ -27,4 +27,4 @@ --ifm-color-primary-lighter: #32d8b4; --ifm-color-primary-lightest: #4fddbf; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); -} +} \ No newline at end of file diff --git a/website/sidecar/static/img/undraw_computer_dart_flutter.svg b/website/sidecar/static/img/undraw_computer_dart_flutter.svg new file mode 100644 index 00000000..10cc8d95 --- /dev/null +++ b/website/sidecar/static/img/undraw_computer_dart_flutter.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/sidecar/static/img/undraw_development.svg b/website/sidecar/static/img/undraw_development.svg new file mode 100644 index 00000000..82e168c8 --- /dev/null +++ b/website/sidecar/static/img/undraw_development.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/sidecar/static/img/undraw_mobile_development.svg b/website/sidecar/static/img/undraw_mobile_development.svg new file mode 100644 index 00000000..5a823c11 --- /dev/null +++ b/website/sidecar/static/img/undraw_mobile_development.svg @@ -0,0 +1 @@ + \ No newline at end of file From 6ac6bcb2e8ff95d12bdd4b034a0dd2d1efcf7bba Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:45:11 -0500 Subject: [PATCH 09/29] docs: Discord invite link. --- website/sidecar/docusaurus.config.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/sidecar/docusaurus.config.js b/website/sidecar/docusaurus.config.js index fda18ff9..bb0607bf 100644 --- a/website/sidecar/docusaurus.config.js +++ b/website/sidecar/docusaurus.config.js @@ -109,12 +109,12 @@ const config = { // }, { label: 'Discord', - href: 'https://discordapp.com/invite/sidecar', - }, - { - label: 'Twitter', - href: 'https://twitter.com/docusaurus', + href: 'https://discord.gg/YhFS6V26Vg', }, + // { + // label: 'Twitter', + // href: 'https://twitter.com/pattobrien', + // }, ], }, { From 5e93820d0af70562ce3f30f75816aa5406a93ac3 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:11:24 -0500 Subject: [PATCH 10/29] docs: Introduction page and tutorial page. --- website/sidecar/docs/intro.md | 17 ++++++++--------- website/sidecar/docs/tutorials/_category_.json | 6 +++++- .../docs/tutorials/bloc_file_structure.mdx | 1 + .../docs/tutorials/design_system_insets.mdx | 1 + website/sidecar/docs/tutorials/hello_world.mdx | 1 + .../sidecar/docs/tutorials/string_locator.mdx | 1 + 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/website/sidecar/docs/intro.md b/website/sidecar/docs/intro.md index 30258843..9992288e 100644 --- a/website/sidecar/docs/intro.md +++ b/website/sidecar/docs/intro.md @@ -1,20 +1,19 @@ --- sidebar_position: 1 +title: Introduction --- -# Introduction -Sidecar is a framework for creating static analysis tools for Dart. - -It allows developers to create lint or quick assists that represent their app. +> NOTE: This site is an active, high-priority project to help get you and others started with creating your own lint rules. +If there's any trouble you have with using Sidecar or a Sidecar-based rule package (like design_system_lints), your +feedback would be greatly appreciated in the [Discord channel](https://discord.gg/YhFS6V26Vg). ## Getting Started -### Usage Guides - -Intended for end users of Sidecar-based rule packages. Contains information about... +Sidecar is a framework for creating custom lint and quick fix rules for Dart and Flutter projects. -### Developer Guide -Intended for individuals who wish to extend Sidecar and create their own rules. +If you want to create your own lint rules, we've created several [tutorials](category/tutorials) that break down the process of doing so. +But before diving in to the tutorials, its highly recommended that you understand the core concepts and usage guidelines of both +sidecar and package:analyzer. diff --git a/website/sidecar/docs/tutorials/_category_.json b/website/sidecar/docs/tutorials/_category_.json index b84fc017..7a0df814 100644 --- a/website/sidecar/docs/tutorials/_category_.json +++ b/website/sidecar/docs/tutorials/_category_.json @@ -1,4 +1,8 @@ { "label": "Tutorials", - "position": 4 + "position": 4, + "link": { + "type": "generated-index", + "description": "Learn the process of creating your own lint rules. It's highly recommended that you start from Hello World and follow the rest in order, as each lesson builds upon concepts introduced in previous tutorials." + } } \ No newline at end of file diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index e31cf0a3..fdd1af52 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -1,6 +1,7 @@ --- title: Bloc File Structure sidebar_position: 3 +description: "" --- import CodeBlock from '@theme/CodeBlock'; diff --git a/website/sidecar/docs/tutorials/design_system_insets.mdx b/website/sidecar/docs/tutorials/design_system_insets.mdx index da8f63c7..56198bd6 100644 --- a/website/sidecar/docs/tutorials/design_system_insets.mdx +++ b/website/sidecar/docs/tutorials/design_system_insets.mdx @@ -1,6 +1,7 @@ --- title: Design System Insets sidebar_position: 5 +description: "" --- import CodeBlock from '@theme/CodeBlock'; diff --git a/website/sidecar/docs/tutorials/hello_world.mdx b/website/sidecar/docs/tutorials/hello_world.mdx index d6db54cb..c02a9c66 100644 --- a/website/sidecar/docs/tutorials/hello_world.mdx +++ b/website/sidecar/docs/tutorials/hello_world.mdx @@ -1,6 +1,7 @@ --- title: Hello World sidebar_position: 1 +description: "" --- import CodeBlock from '@theme/CodeBlock'; diff --git a/website/sidecar/docs/tutorials/string_locator.mdx b/website/sidecar/docs/tutorials/string_locator.mdx index c98c3720..a03e371a 100644 --- a/website/sidecar/docs/tutorials/string_locator.mdx +++ b/website/sidecar/docs/tutorials/string_locator.mdx @@ -1,6 +1,7 @@ --- title: String Locator sidebar_position: 2 +description: "" --- import CodeBlock from '@theme/CodeBlock'; From 8ef16f28f7e8503f59b746ec99468c23f3893235 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:23:08 -0500 Subject: [PATCH 11/29] docs: Initial setup CLI image, removed old usage guide placeholders. --- .../sidecar/docs/core-concepts/_category_.json | 8 -------- .../docs/core-concepts/how_it_works.mdx | 4 ---- website/sidecar/docs/core-concepts/main.dart | 3 --- .../docs/core-concepts/publishing_rules.mdx | 4 ---- website/sidecar/docs/core-concepts/rules.mdx | 15 --------------- website/sidecar/docs/core-concepts/testing.mdx | 10 ---------- website/sidecar/docs/usage/_category_.json | 2 +- website/sidecar/docs/usage/configuration.md | 9 --------- website/sidecar/docs/usage/intial_setup.mdx | 12 +++++++++++- website/sidecar/docs/usage/playground.md | 6 ------ website/sidecar/static/img/cli_output.png | Bin 0 -> 161706 bytes 11 files changed, 12 insertions(+), 61 deletions(-) delete mode 100644 website/sidecar/docs/core-concepts/_category_.json delete mode 100644 website/sidecar/docs/core-concepts/how_it_works.mdx delete mode 100644 website/sidecar/docs/core-concepts/main.dart delete mode 100644 website/sidecar/docs/core-concepts/publishing_rules.mdx delete mode 100644 website/sidecar/docs/core-concepts/rules.mdx delete mode 100644 website/sidecar/docs/core-concepts/testing.mdx delete mode 100644 website/sidecar/docs/usage/configuration.md delete mode 100644 website/sidecar/docs/usage/playground.md create mode 100644 website/sidecar/static/img/cli_output.png diff --git a/website/sidecar/docs/core-concepts/_category_.json b/website/sidecar/docs/core-concepts/_category_.json deleted file mode 100644 index c9bd6311..00000000 --- a/website/sidecar/docs/core-concepts/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Core Concepts", - "position": 3, - "link": { - "type": "generated-index", - "description": "Learn how to use lint rules and other tools in your IDE and command line. For how-to guides on creating rules, see TODO." - } -} \ No newline at end of file diff --git a/website/sidecar/docs/core-concepts/how_it_works.mdx b/website/sidecar/docs/core-concepts/how_it_works.mdx deleted file mode 100644 index fbabeaea..00000000 --- a/website/sidecar/docs/core-concepts/how_it_works.mdx +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: How Sidecar Works -sidebar_position: 3 ---- diff --git a/website/sidecar/docs/core-concepts/main.dart b/website/sidecar/docs/core-concepts/main.dart deleted file mode 100644 index 17c84f4e..00000000 --- a/website/sidecar/docs/core-concepts/main.dart +++ /dev/null @@ -1,3 +0,0 @@ -/* SNIPPET START */ - -final x = Set(); diff --git a/website/sidecar/docs/core-concepts/publishing_rules.mdx b/website/sidecar/docs/core-concepts/publishing_rules.mdx deleted file mode 100644 index 8b82ac2c..00000000 --- a/website/sidecar/docs/core-concepts/publishing_rules.mdx +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Publishing a Rule Package -sidebar_position: 2 ---- \ No newline at end of file diff --git a/website/sidecar/docs/core-concepts/rules.mdx b/website/sidecar/docs/core-concepts/rules.mdx deleted file mode 100644 index 8f97bd4d..00000000 --- a/website/sidecar/docs/core-concepts/rules.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Creating a Rule -sidebar_position: 1 ---- - -import CodeBlock from '@theme/CodeBlock'; -import main from "!!raw-loader!./main.dart"; -import { - trimSnippet, - CodeSnippet, -} from "../../src/components/CodeSnippet"; - -Some imported code: - -{trimSnippet(main)} diff --git a/website/sidecar/docs/core-concepts/testing.mdx b/website/sidecar/docs/core-concepts/testing.mdx deleted file mode 100644 index 91511d9b..00000000 --- a/website/sidecar/docs/core-concepts/testing.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Testing -sidebar_position: 4 ---- - - -## Overview - -It's recommended for rule developers to take a TDD approach to writing rules, as it may help understand the boundaries of a particular use case. - diff --git a/website/sidecar/docs/usage/_category_.json b/website/sidecar/docs/usage/_category_.json index 1e103372..97650cd9 100644 --- a/website/sidecar/docs/usage/_category_.json +++ b/website/sidecar/docs/usage/_category_.json @@ -3,6 +3,6 @@ "position": 1, "link": { "type": "generated-index", - "description": "Learn how to use lint rules and other tools in your IDE and command line. For how-to guides on creating rules, see TODO." + "description": "Learn the basics of enabling and customizing sidecar rules in your IDE or CLI." } } \ No newline at end of file diff --git a/website/sidecar/docs/usage/configuration.md b/website/sidecar/docs/usage/configuration.md deleted file mode 100644 index afba2813..00000000 --- a/website/sidecar/docs/usage/configuration.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 3 -sidebar_label: 'Configuration' -description: Walkthrough of the sidecar.yaml file. ---- - -# Configuration (sidecar.yaml) - -TODO \ No newline at end of file diff --git a/website/sidecar/docs/usage/intial_setup.mdx b/website/sidecar/docs/usage/intial_setup.mdx index adc46662..a63c02f0 100644 --- a/website/sidecar/docs/usage/intial_setup.mdx +++ b/website/sidecar/docs/usage/intial_setup.mdx @@ -1,5 +1,6 @@ --- sidebar_position: 2 +title: IDE and CLI Setup description: Setup rules for use within an IDE or CLI. --- @@ -7,6 +8,8 @@ import CodeBlock from '@theme/CodeBlock'; import main from "!!raw-loader!./snippets/configuration-simple.yaml"; import analysisOptions from "!!raw-loader!./snippets/analysis_options.yaml"; import pubspec from "!!raw-loader!./snippets/pubspec.yaml"; +import cliOutputImage from '../../static/img/cli_output.png'; + import { trimSnippet, CodeSnippet, @@ -58,4 +61,11 @@ dart pub global activate sidecar sidecar analyze ``` -> NOTE: If you have a particular CLI use case in mind and would like to give feedback, feel free to reach out on Github. +After several seconds of analysis, you should see results appear for each rule that is enabled in your project. + +CLI Output example + + +### Contributing CLI Use Cases + +If you have a particular CLI use case in mind, your feedback would be greatly appreciated in the [Discord channel](https://discord.gg/YhFS6V26Vg) diff --git a/website/sidecar/docs/usage/playground.md b/website/sidecar/docs/usage/playground.md deleted file mode 100644 index 3dab7a2e..00000000 --- a/website/sidecar/docs/usage/playground.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 4 -description: Try out Sidecar. ---- - -# Playground \ No newline at end of file diff --git a/website/sidecar/static/img/cli_output.png b/website/sidecar/static/img/cli_output.png new file mode 100644 index 0000000000000000000000000000000000000000..077e795c04feb96d5539bafd9b51af7d18484009 GIT binary patch literal 161706 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 u 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 z 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 G^4|c%W)X@2 literal 0 HcmV?d00001 From ac7307b3c0c57df2e131fe28d785988061d200ab Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:28:08 -0500 Subject: [PATCH 12/29] docs: Removed docusaurus nav bar icon. --- website/sidecar/docusaurus.config.js | 12 ++++++------ website/sidecar/src/pages/index.tsx | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/website/sidecar/docusaurus.config.js b/website/sidecar/docusaurus.config.js index bb0607bf..9def1a27 100644 --- a/website/sidecar/docusaurus.config.js +++ b/website/sidecar/docusaurus.config.js @@ -12,7 +12,7 @@ const config = { baseUrl: '/', onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', - favicon: 'img/favicon.ico', + // favicon: 'img/favicon.ico', // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. @@ -60,11 +60,11 @@ const config = { defaultMode: "dark", }, navbar: { - title: 'Sidecar', - logo: { - alt: 'My Site Logo', - src: 'img/logo.svg', - }, + title: 'Sidecar Analyzer', + // logo: { + // alt: 'My Site Logo', + // src: 'img/logo.svg', + // }, items: [ // { // type: 'doc', diff --git a/website/sidecar/src/pages/index.tsx b/website/sidecar/src/pages/index.tsx index 6854617d..4195ff6a 100644 --- a/website/sidecar/src/pages/index.tsx +++ b/website/sidecar/src/pages/index.tsx @@ -30,7 +30,7 @@ export default function Home(): JSX.Element { const { siteConfig } = useDocusaurusContext(); return (
From 418ff7c8f135135856b6978416e442ad9c810b29 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:58:58 -0500 Subject: [PATCH 13/29] docs: Usage rewording. --- website/sidecar/docs/usage/intial_setup.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/sidecar/docs/usage/intial_setup.mdx b/website/sidecar/docs/usage/intial_setup.mdx index a63c02f0..00981546 100644 --- a/website/sidecar/docs/usage/intial_setup.mdx +++ b/website/sidecar/docs/usage/intial_setup.mdx @@ -46,7 +46,7 @@ to display lints and assist recommendations within your IDE, perform the followi {trimSnippet(analysisOptions)} -After several seconds of start-up (and potentially a restart of your IDE), the lints should begin appearing in your editor. +That's all it takes! Your lints should begin appearing in your editor. ## CLI Mode @@ -61,7 +61,7 @@ dart pub global activate sidecar sidecar analyze ``` -After several seconds of analysis, you should see results appear for each rule that is enabled in your project. +You should see analysis results appear for each file in your project: CLI Output example From b3356f580bada1bebe938f7ec17270ae32cf7c4f Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 13:30:40 -0500 Subject: [PATCH 14/29] docs: Add gitignore for snippets. --- website/sidecar/.dart_tool/package_config.json | 2 +- website/sidecar/.packages | 2 +- website/sidecar/docs/usage/snippets/.gitignore | 1 + .../tutorials/bloc_feature_structure/lib/step2.dart | 12 +++++------- .../tutorials/bloc_feature_structure/pubspec.yaml | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) create mode 100644 website/sidecar/docs/usage/snippets/.gitignore diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index 102a0117..eabe333a 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -476,7 +476,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-19T16:37:36.053638Z", + "generated": "2023-01-19T17:32:17.081265Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index cf3587d9..183466b1 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-19 11:37:36.045196. +# Generated by pub on 2023-01-19 12:32:17.072533. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ diff --git a/website/sidecar/docs/usage/snippets/.gitignore b/website/sidecar/docs/usage/snippets/.gitignore new file mode 100644 index 00000000..8d15be0b --- /dev/null +++ b/website/sidecar/docs/usage/snippets/.gitignore @@ -0,0 +1 @@ +.dart_tool/ \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart index 00a4ecf7..30e63206 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart @@ -4,14 +4,14 @@ import 'package:glob/glob.dart'; import 'package:sidecar/sidecar.dart'; class BlocOutsideControllerLayer extends LintRule { - /* SKIP */ - // we can use variables for better code legibility - static const _id = 'bloc_outside_controller_layer'; + // {@snippet: lint_code} + static const id = 'bloc_outside_controller_layer'; static const _package = 'bloc_feature_structure'; static const _message = 'Logic should be created in application folders.'; @override - LintCode get code => const LintCode(_id, package: _package); + LintCode get code => const LintCode(id, package: _package); + // {@snippet_end: lint_code} /* SKIP END */ @override @@ -33,6 +33,4 @@ class BlocOutsideControllerLayer extends LintRule { // TODO: check if declaration is a bloc class } -} - -/* SNIPPET END */ \ No newline at end of file +} /* SNIPPET END */ diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml index 8f0e6524..dadf9dbc 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/pubspec.yaml @@ -8,7 +8,7 @@ environment: dependencies: analyzer: ^4.7.0 glob: ^2.1.1 - sidecar: ^0.1.0-dev.18 + sidecar: ^0.1.0-dev.19 dev_dependencies: sidecar_lints: ^0.1.0-dev.1 From 35fb54c604a220a245b7e543f9850d71ee6943e2 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 13:31:08 -0500 Subject: [PATCH 15/29] docs: Delete log files. --- .../snippets/.dart_tool/package_config.json | 416 ------------------ .../snippets/.dart_tool/package_config_subset | 273 ------------ .../.dart_tool/sidecar_logs/latest.log | 1 - .../log-2023-01-19T11:37:33.118729.log | 1 - .../docs/usage/snippets/.dart_tool/version | 1 - 5 files changed, 692 deletions(-) delete mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/package_config.json delete mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset delete mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log delete mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-2023-01-19T11:37:33.118729.log delete mode 100644 website/sidecar/docs/usage/snippets/.dart_tool/version diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json b/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json deleted file mode 100644 index 69839050..00000000 --- a/website/sidecar/docs/usage/snippets/.dart_tool/package_config.json +++ /dev/null @@ -1,416 +0,0 @@ -{ - "configVersion": 2, - "packages": [ - { - "name": "_fe_analyzer_shared", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "analyzer", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "analyzer_plugin", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "args", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "async", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "boolean_selector", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.1", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "characters", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "checked_yaml", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "cli_util", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "collection", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "convert", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "coverage", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.2", - "packageUri": "lib/", - "languageVersion": "2.15" - }, - { - "name": "crypto", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "dart_style", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "design_system_lints", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.9", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "file", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "flutter", - "rootUri": "file:///Users/pattobrien/fvm/versions/3.0.5/packages/flutter", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "freezed_annotation", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "frontend_server_client", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "glob", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1", - "packageUri": "lib/", - "languageVersion": "2.15" - }, - { - "name": "hotreloader", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "http_multi_server", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_multi_server-3.2.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "http_parser", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "io", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/io-1.0.3", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "js", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/js-0.6.5", - "packageUri": "lib/", - "languageVersion": "2.16" - }, - { - "name": "json_annotation", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "logging", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "matcher", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "material_color_utilities", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4", - "packageUri": "lib/", - "languageVersion": "2.13" - }, - { - "name": "meta", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "mime", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/mime-1.0.3", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "node_preamble", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/node_preamble-2.0.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "package_config", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "path", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "pool", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pool-1.5.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "pub_semver", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "pubspec_parse", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "recase", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "riverpod", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "shelf", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "shelf_packages_handler", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "shelf_static", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "shelf_web_socket", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "sidecar", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.19", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "sidecar_annotations", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "sidecar_package_utilities", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "sky_engine", - "rootUri": "file:///Users/pattobrien/fvm/versions/3.0.5/bin/cache/pkg/sky_engine", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "source_map_stack_trace", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "source_maps", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.10", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "source_span", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "stack_trace", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "state_notifier", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "stream_channel", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.1", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "stream_transform", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "string_scanner", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "term_glyph", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "test", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test-1.21.4", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "test_api", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "test_core", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_core-0.4.16", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "typed_data", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "uuid", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "vector_math", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "vm_service", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0", - "packageUri": "lib/", - "languageVersion": "2.15" - }, - { - "name": "watcher", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2", - "packageUri": "lib/", - "languageVersion": "2.14" - }, - { - "name": "web_socket_channel", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-2.3.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "webkit_inspection_protocol", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "yaml", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "counter_app", - "rootUri": "../", - "packageUri": "lib/", - "languageVersion": "2.17" - } - ], - "generated": "2023-01-19T16:37:35.255557Z", - "generator": "pub", - "generatorVersion": "2.17.6" -} diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset b/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset deleted file mode 100644 index 4b299c40..00000000 --- a/website/sidecar/docs/usage/snippets/.dart_tool/package_config_subset +++ /dev/null @@ -1,273 +0,0 @@ -_fe_analyzer_shared -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ -analyzer -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ -analyzer_plugin -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ -args -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib/ -async -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib/ -boolean_selector -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.1/lib/ -characters -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/characters-1.2.0/lib/ -checked_yaml -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib/ -cli_util -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib/ -collection -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib/ -convert -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1.0/lib/ -coverage -2.15 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.2/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.2/lib/ -crypto -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib/ -dart_style -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4/lib/ -design_system_lints -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.9/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.9/lib/ -file -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib/ -freezed_annotation -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed_annotation-2.2.0/lib/ -frontend_server_client -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/frontend_server_client-2.1.3/lib/ -glob -2.15 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/glob-2.1.1/lib/ -hotreloader -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/hotreloader-3.0.5/lib/ -http_multi_server -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_multi_server-3.2.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_multi_server-3.2.1/lib/ -http_parser -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/lib/ -io -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/io-1.0.3/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/io-1.0.3/lib/ -js -2.16 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/js-0.6.5/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/js-0.6.5/lib/ -json_annotation -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib/ -logging -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib/ -matcher -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib/ -material_color_utilities -2.13 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.4/lib/ -meta -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/ -mime -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/mime-1.0.3/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/mime-1.0.3/lib/ -node_preamble -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/node_preamble-2.0.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/node_preamble-2.0.1/lib/ -package_config -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/package_config-2.1.0/lib/ -path -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/path-1.8.3/lib/ -pool -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pool-1.5.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pool-1.5.1/lib/ -pub_semver -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.1.3/lib/ -pubspec_parse -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.2.1/lib/ -recase -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/recase-4.1.0/lib/ -riverpod -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/riverpod-2.1.3/lib/ -shelf -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0/lib/ -shelf_packages_handler -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1/lib/ -shelf_static -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1/lib/ -shelf_web_socket -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3/lib/ -sidecar -2.17 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.19/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.19/lib/ -sidecar_annotations -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/lib/ -sidecar_package_utilities -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/lib/ -source_map_stack_trace -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1/lib/ -source_maps -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.10/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.10/lib/ -source_span -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.1/lib/ -stack_trace -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/ -state_notifier -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/state_notifier-0.7.2+1/lib/ -stream_channel -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.1/lib/ -stream_transform -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/stream_transform-2.1.0/lib/ -string_scanner -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib/ -term_glyph -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib/ -test -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test-1.21.4/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test-1.21.4/lib/ -test_api -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib/ -test_core -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_core-0.4.16/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/test_core-0.4.16/lib/ -typed_data -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib/ -uuid -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/uuid-3.0.7/lib/ -vector_math -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib/ -vm_service -2.15 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/vm_service-9.4.0/lib/ -watcher -2.14 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/watcher-1.0.2/lib/ -web_socket_channel -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-2.3.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-2.3.0/lib/ -webkit_inspection_protocol -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/webkit_inspection_protocol-1.2.0/lib/ -yaml -2.12 -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/ -file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib/ -counter_app -2.17 -file:///Users/pattobrien/Development/sidecar/website/sidecar/docs/usage/snippets/ -file:///Users/pattobrien/Development/sidecar/website/sidecar/docs/usage/snippets/lib/ -sky_engine -2.12 -file:///Users/pattobrien/fvm/versions/3.0.5/bin/cache/pkg/sky_engine/ -file:///Users/pattobrien/fvm/versions/3.0.5/bin/cache/pkg/sky_engine/lib/ -flutter -2.12 -file:///Users/pattobrien/fvm/versions/3.0.5/packages/flutter/ -file:///Users/pattobrien/fvm/versions/3.0.5/packages/flutter/lib/ -2 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log deleted file mode 100644 index 54aeb04d..00000000 --- a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/latest.log +++ /dev/null @@ -1 +0,0 @@ -2023-01-19T11:37:42.697621 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-2023-01-19T11:37:33.118729.log b/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-2023-01-19T11:37:33.118729.log deleted file mode 100644 index a4325137..00000000 --- a/website/sidecar/docs/usage/snippets/.dart_tool/sidecar_logs/log-2023-01-19T11:37:33.118729.log +++ /dev/null @@ -1 +0,0 @@ -2023-01-19T11:37:33.118729 diff --git a/website/sidecar/docs/usage/snippets/.dart_tool/version b/website/sidecar/docs/usage/snippets/.dart_tool/version deleted file mode 100644 index 7da3c168..00000000 --- a/website/sidecar/docs/usage/snippets/.dart_tool/version +++ /dev/null @@ -1 +0,0 @@ -3.0.5 \ No newline at end of file From 1902d69a845ae20391e10bb2f522ec35a94877dd Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 15:23:57 -0500 Subject: [PATCH 16/29] docs: Make unfinished tutorials private. --- .../{design_system_insets.mdx => _design_system_insets.mdx} | 0 .../docs/tutorials/{string_locator.mdx => _string_locator.mdx} | 0 website/sidecar/docs/tutorials/bloc_file_structure.mdx | 2 ++ 3 files changed, 2 insertions(+) rename website/sidecar/docs/tutorials/{design_system_insets.mdx => _design_system_insets.mdx} (100%) rename website/sidecar/docs/tutorials/{string_locator.mdx => _string_locator.mdx} (100%) diff --git a/website/sidecar/docs/tutorials/design_system_insets.mdx b/website/sidecar/docs/tutorials/_design_system_insets.mdx similarity index 100% rename from website/sidecar/docs/tutorials/design_system_insets.mdx rename to website/sidecar/docs/tutorials/_design_system_insets.mdx diff --git a/website/sidecar/docs/tutorials/string_locator.mdx b/website/sidecar/docs/tutorials/_string_locator.mdx similarity index 100% rename from website/sidecar/docs/tutorials/string_locator.mdx rename to website/sidecar/docs/tutorials/_string_locator.mdx diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index fdd1af52..1873ba16 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -18,6 +18,8 @@ import { generateSnippet, } from "../../src/components/CodeSnippet"; +> NOTE: This guide is a work in progress. + ## Overview Let's say we want to enforce all developers on our Flutter app to use a feature-first project structure. From 694b1516e916a86f6eba8c81c60994cdb2000a41 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 15:50:58 -0500 Subject: [PATCH 17/29] docs: Hello world completed tutorial. --- website/sidecar/docs/concepts/_category_.json | 4 ++++ .../docs/concepts/rule_creation_checklist.mdx | 21 +++++++++++++++++++ .../docs/tutorials/bloc_file_structure.mdx | 4 ++-- .../sidecar/docs/tutorials/hello_world.mdx | 14 ++++++++----- website/sidecar/docs/usage/troubleshooting.md | 5 ++--- website/sidecar/docusaurus.config.js | 8 +++---- 6 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 website/sidecar/docs/concepts/_category_.json create mode 100644 website/sidecar/docs/concepts/rule_creation_checklist.mdx diff --git a/website/sidecar/docs/concepts/_category_.json b/website/sidecar/docs/concepts/_category_.json new file mode 100644 index 00000000..78ee8651 --- /dev/null +++ b/website/sidecar/docs/concepts/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Core Concepts", + "position": 3 +} \ No newline at end of file diff --git a/website/sidecar/docs/concepts/rule_creation_checklist.mdx b/website/sidecar/docs/concepts/rule_creation_checklist.mdx new file mode 100644 index 00000000..34c2a04c --- /dev/null +++ b/website/sidecar/docs/concepts/rule_creation_checklist.mdx @@ -0,0 +1,21 @@ +--- +title: Rule Creation Checklist +sidebar_position: 1 +description: "" +--- + +import CodeBlock from '@theme/CodeBlock'; +import { + trimSnippet, + CodeSnippet, +} from "../../src/components/CodeSnippet"; + +If you're creating a new lint rule and lints are not appearing in the IDE of an example project, + you can follow this checklist for requirements: + +- [ ] Rule has a unique RuleCode ID (in snake_case) +- [ ] The Rule's ClassName is the PascalCase equivalent of the RuleCode ID +- [ ] The `code.package` value matches the name given to the rule package +- [ ] Lint Rule is exported from `lib/.dart` +- [ ] + diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index 1873ba16..3025a799 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -42,8 +42,8 @@ A typical feature-first folder structure for a Flutter app may look something li │ │ │ ├── states │ │ │ ├── widgets ``` -> *The above structure is roughly based on [this great article series](https://codewithandrea.com/articles/flutter-app-architecture-riverpod-introduction/) -> on Riverpod architecture by Andrea Bizzotto.* +> *The above structure is roughly based on [this great architecture series](https://codewithandrea.com/articles/flutter-app-architecture-riverpod-introduction/) +> by Andrea Bizzotto.* In order to enforce the use of such a structure programmatically, we could implement any of the following cases: diff --git a/website/sidecar/docs/tutorials/hello_world.mdx b/website/sidecar/docs/tutorials/hello_world.mdx index c02a9c66..faac1863 100644 --- a/website/sidecar/docs/tutorials/hello_world.mdx +++ b/website/sidecar/docs/tutorials/hello_world.mdx @@ -98,9 +98,10 @@ We've now fully defined our `HelloWorld` rule class! ### Making our Rule Visible to Sidecar +There are two other requirements that make our newly created rule visible to sidecar: -- adding lint code to package's pubspec.yaml file -- ensuring the rule is available from lib/hello_world_rules.dart +- adding lint code to package's pubspec.yaml file (see: [sidecar_lints pubspec](https://github.com/pattobrien/sidecar/blob/master/packages/sidecar_lints/pubspec.yaml#L28)) +- ensuring the rule is available from lib/hello_world_rules.dart (see: [lib/sidecar_lints.dart](https://github.com/pattobrien/sidecar/blob/master/packages/sidecar_lints/lib/sidecar_lints.dart)) ## Validating our LintRule in an IDE @@ -142,11 +143,13 @@ only taking a few lines of code to write: ``` On the otherhand, there are many individual requirements to abide by, and forgetting any of them results in no lint appearing at all. - + In the next tutorials, we will cover ways to help remember all of the rule requirements by using the package `sidecar_lints`. + diff --git a/website/sidecar/docs/usage/troubleshooting.md b/website/sidecar/docs/usage/troubleshooting.md index cb569312..9ff48a71 100644 --- a/website/sidecar/docs/usage/troubleshooting.md +++ b/website/sidecar/docs/usage/troubleshooting.md @@ -8,12 +8,12 @@ description: What to do when lints no longer update, RAM usage, etc. In IDE-Server mode, Sidecar boots up using the ```analyzer_plugin``` APIs created by the Dart team. Due to the experimental nature of both Sidecar and analyzer_plugin, there are some limitations that users should be aware of. -## Lints stop updating +## Lints no longer updating When using a lint package, its possible that you experience unexpected problems, such as: - A particular file does not show lints -- Lints stop updating or are seen appearing over the wrong code +- Lints dont update when editing a file and/or lints are seen appearing over the wrong code While the remaining bugs are being ironed out, the recommended fix is to restart the analyzer server and/or restart your IDE (can be done via Dart official extensions). @@ -23,4 +23,3 @@ Since the official Dart lints do not themselves use the analyzer_plugin architec they are run on a separate isolate than Sidecar rules. Because both Dart programs must analyze the entire Dart package and dependencies, enabling Sidecar is expected to have some increase in RAM resources (expect around 25% increase, but no more than a 50% increase). - diff --git a/website/sidecar/docusaurus.config.js b/website/sidecar/docusaurus.config.js index 9def1a27..5400e8ef 100644 --- a/website/sidecar/docusaurus.config.js +++ b/website/sidecar/docusaurus.config.js @@ -36,15 +36,15 @@ const config = { sidebarPath: require.resolve('./sidebars.js'), // Please change this to your repo. // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', + // editUrl: + // 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', }, blog: { showReadingTime: true, // Please change this to your repo. // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', + // editUrl: + // 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', }, theme: { customCss: require.resolve('./src/css/custom.scss'), From 929be3748096d6793a00f3b8815af4d5a4747868 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Thu, 19 Jan 2023 15:53:52 -0500 Subject: [PATCH 18/29] docs: Bloc file structure guide cleanup. --- .../docs/tutorials/bloc_file_structure.mdx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index 3025a799..7f3f1f5c 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -96,17 +96,25 @@ Our first course of action is to create our LintRule class and its respective Li Just as we did in the previous tutorial, we ensure that the class name is the PascalCase representation of the LintCode.id that we assign. - + {trimSnippet(step2, [''])} -Finally, if + {trimSnippet(step3, [''])} +Completed code: + +{trimSnippet(step0, [''])} + + \ No newline at end of file From 5e2266fa40d0bcebc86b25a18a0e0bd529f8c56c Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Sat, 21 Jan 2023 15:36:09 -0500 Subject: [PATCH 19/29] feat: generateSnippet shows particular snippets. --- .../sidecar/.dart_tool/package_config.json | 2 +- website/sidecar/.packages | 2 +- .../docs/tutorials/bloc_file_structure.mdx | 18 +- website/sidecar/docs/usage/snippets/.packages | 2 +- .../lib/bloc_feature_structure.dart | 1 - .../lib/bloc_outside_controller_layer.dart | 53 ++++ .../bloc_feature_structure/lib/step0.dart | 53 ---- .../bloc_feature_structure/lib/step1.dart | 19 -- .../bloc_feature_structure/lib/step2.dart | 36 --- .../.dart_tool/package_config.json | 290 ++++++++++++++++++ .../tutorials/design_system_insets/.packages | 53 ++++ .../src/components/CodeSnippet/index.tsx | 53 +++- 12 files changed, 442 insertions(+), 140 deletions(-) delete mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_feature_structure.dart create mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart delete mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step0.dart delete mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step1.dart delete mode 100644 website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step2.dart create mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/.dart_tool/package_config.json create mode 100644 website/sidecar/lib/src/tutorials/design_system_insets/.packages diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index eabe333a..c464c9fc 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -476,7 +476,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-19T17:32:17.081265Z", + "generated": "2023-01-21T18:56:51.182720Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index 183466b1..0e40dd8f 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-19 12:32:17.072533. +# Generated by pub on 2023-01-21 13:56:51.175238. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ diff --git a/website/sidecar/docs/tutorials/bloc_file_structure.mdx b/website/sidecar/docs/tutorials/bloc_file_structure.mdx index 7f3f1f5c..4f16bb87 100644 --- a/website/sidecar/docs/tutorials/bloc_file_structure.mdx +++ b/website/sidecar/docs/tutorials/bloc_file_structure.mdx @@ -6,12 +6,9 @@ description: "" import CodeBlock from '@theme/CodeBlock'; import ruleDefintion from "!!raw-loader!../../../../examples/hello_world_rules/lib/hello_world_rules.dart"; -import step0 from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step0.dart"; -import step1 from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step1.dart"; -import step1a from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step1a.yaml"; -import step2 from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step2.dart"; -import step3 from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step3.dart"; -import pubspec from "!!raw-loader!../../../../examples/hello_world_rules/pubspec.yaml"; +import rule from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart"; +import pubspec from "!!raw-loader!../../lib/src/tutorials/bloc_feature_structure/lib/step1a.yaml"; + import { trimSnippet, CodeSnippet, @@ -87,12 +84,12 @@ and `analyzer` to `pubspec.yaml`. dart create bloc_feature_structure ``` -{generateSnippet(step1a, [''])} +{trimSnippet(pubspec, [''])} Our first course of action is to create our LintRule class and its respective LintCode. -{generateSnippet(step1, [''])} +{generateSnippet(rule, ['LINTCODE', 'ClassStart', 'CLASSEND', 'RuleImports'])} Just as we did in the previous tutorial, we ensure that the class name is the PascalCase representation of the LintCode.id that we assign. @@ -100,14 +97,13 @@ that we assign. From here we can build out the first of our requirements: to only analyze files outside of the application folder. If you remember back to our feature-first project structure, --> -{trimSnippet(step2, [''])} -{trimSnippet(step3, [''])} +{generateSnippet(rule, ['ClassStart', 'CLASSEND', 'VisitCompilationUnit', 'isApplicationFile'])} Completed code: -{trimSnippet(step0, [''])} +{generateSnippet(rule, [''])} -In the next tutorials, we will cover ways to help remember all of the rule requirements by using the package `sidecar_lints`. + +The [rule creation checklist](../concepts/rule_creation_checklist.mdx) makes it easy to ensure you've covered all the bases. +Additionally, it's highly recommended to use package:sidecar_lints to help ensure all of your rules are properly defined for Sidecar. + +If you remember back to our feature-first project structure, we only want our rule to analyze files that are outside of the `presentation/controllers` +folder, since we should not be creating BLoC classes in any other folder. + +In Sidecar, rule execution is scoped to a single file, and we can use the `unit` context variable to see exactly what file +is being analyzed. We can use the package `glob` to check if the file path matches the particular `presentation/controllers` +folder we're filtering for. {generateSnippet(rule, ['ClassStart', 'CLASSEND', 'VisitCompilationUnit', 'isApplicationFile'])} +In this example, we create a `isControllerFile` variable that will store the result of our glob check. We can then use this variable +in our `visitClassDeclaration` method before proceeding with the rest of our logic. + +### Type-checking a class declaration + Finally, we create our logic that checks if the class declaration extends `BlocBase` and if so, we report the lint. +Unfortunately, we cannot simply import `BlocBase` from `package:bloc` and use it to type check our class declaration, +as the analyzer does not provide us with a `Type` object to compare against. + +Instead, we must use the `TypeChecker` utility shipped in Sidecar, which gives us a simple way to check if an analyzed type +matches a particular type that we're looking for. + +> NOTE: If you're interested in learning more about the `TypeChecker` utility, you can read more about it [here](/docs/concepts/type_checking) {generateSnippet(rule, ['ClassStart', 'CLASSEND', 'isApplicationFile', 'visitClassDeclaration'])} +### Performance Considerations + +The reason we don't handle the file-check logic directly in `visitClassDeclaration` is because we always want to avoid unnecessary computation +in the case that a particular file has multiple class declarations. If we were to instead check the file path in `visitClassDeclaration`, +we would be redundantly checking the file path every time, and this could be a performance bottleneck. + +When writing a lint rule, we want to make sure that we are only performing the necessary computation to ensure that our lint is as performant as possible. +This is necessary when developers expect lints to appear after every file change within fractions of a second in the code editor. + + +## Conclusion + +TODO + \ No newline at end of file diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart index 59de75d5..5cbf8245 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart @@ -21,13 +21,13 @@ class BlocOutsideControllerLayer extends LintRule { /* SNIP VisitCompilationUnit */ @override void visitCompilationUnit(CompilationUnit node) { - final applicationFolderGlob = Glob('**/features/**/application/**'); - isApplicationFile = applicationFolderGlob.matches(unit.path); + final controllersFolderGlob = Glob('**/features/**/controllers/**'); + isControllerFile = controllersFolderGlob.matches(unit.path); } /* SNIP VisitCompilationUnit END */ /* SNIP isApplicationFile */ - late final bool isApplicationFile; + late final bool isControllerFile; /* SNIP isApplicationFile END */ /* SNIP initializeVisitor */ @@ -39,6 +39,10 @@ class BlocOutsideControllerLayer extends LintRule { /* SNIP visitClassDeclaration */ @override void visitClassDeclaration(ClassDeclaration node) { + // dont perform type analysis on files inside of controller folders + if (isControllerFile) return; + + // type check against the type of the declared class final classType = node.declaredElement2?.thisType; final blocBase = TypeChecker.fromName('BlocBase', packageName: 'bloc'); if (!blocBase.isAssignableFromType(classType)) return; From 5781be548690008c9ca118e05c159789bed1b512 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Sun, 22 Jan 2023 16:51:30 -0500 Subject: [PATCH 25/29] chore: Upgrade to Sidecar v0.1.0-dev.21. --- .../example/analysis_options.yaml | 2 +- .../sidecar/.dart_tool/package_config.json | 8 +---- website/sidecar/.packages | 3 +- .../docs/concepts/snippets/type_checking.dart | 4 +-- .../analysis_options.yaml | 2 +- .../example/analysis_options.yaml | 2 -- .../lib/bloc_outside_controller_layer.dart | 2 +- .../bloc_feature_structure/lib/step3.dart | 2 +- .../hello_world/analysis_options.yaml | 30 ------------------- 9 files changed, 8 insertions(+), 47 deletions(-) diff --git a/packages/sidecar_lints/example/analysis_options.yaml b/packages/sidecar_lints/example/analysis_options.yaml index 341d5688..bfc5d79a 100644 --- a/packages/sidecar_lints/example/analysis_options.yaml +++ b/packages/sidecar_lints/example/analysis_options.yaml @@ -2,4 +2,4 @@ include: package:lints/recommended.yaml analyzer: plugins: - - sidecar + # - sidecar diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index c464c9fc..21293a2b 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -331,12 +331,6 @@ "packageUri": "lib/", "languageVersion": "2.12" }, - { - "name": "sidecar_package_utilities", - "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7", - "packageUri": "lib/", - "languageVersion": "2.12" - }, { "name": "source_gen", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_gen-1.2.6", @@ -476,7 +470,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-21T18:56:51.182720Z", + "generated": "2023-01-22T21:44:56.466912Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index 0e40dd8f..7f053910 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-21 13:56:51.175238. +# Generated by pub on 2023-01-22 16:44:56.457341. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ @@ -59,7 +59,6 @@ shelf_static:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_s shelf_web_socket:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3/lib/ sidecar:../../packages/sidecar/lib/ sidecar_annotations:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/lib/ -sidecar_package_utilities:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_package_utilities-0.1.0-dev.7/lib/ source_gen:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_gen-1.2.6/lib/ source_helper:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_helper-1.3.3/lib/ source_map_stack_trace:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-2.1.1/lib/ diff --git a/website/sidecar/docs/concepts/snippets/type_checking.dart b/website/sidecar/docs/concepts/snippets/type_checking.dart index 057cd9a0..43defce8 100644 --- a/website/sidecar/docs/concepts/snippets/type_checking.dart +++ b/website/sidecar/docs/concepts/snippets/type_checking.dart @@ -4,7 +4,7 @@ import 'package:sidecar/sidecar.dart'; /* SNIP TypeChecker */ // 1. Create the TypeChecker const statelessWidget = - TypeChecker.fromName('StatelessWidget', packageName: 'flutter'); + TypeChecker.fromPackage('StatelessWidget', package: 'flutter'); /* SNIP TypeChecker END */ /* SNIP ClassStart */ @@ -35,7 +35,7 @@ class MyLint extends LintRule { @override void visitInstanceCreationExpression(InstanceCreationExpression node) { // 2. Use the TypeChecker to check the type of a particular AstNode - const colorTypeChecker = TypeChecker.fromDartType('Color', package: 'ui'); + const colorTypeChecker = TypeChecker.fromDart('Color', package: 'ui'); final returnType = node.constructorName.staticElement?.returnType; if (colorTypeChecker.isAssignableFromType(returnType)) { // do something diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml index 02fa8fa2..cfe4967b 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/analysis_options.yaml @@ -1,3 +1,3 @@ analyzer: plugins: - - sidecar + # - sidecar diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/analysis_options.yaml b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/analysis_options.yaml index 341d5688..02fa8fa2 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/analysis_options.yaml +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/example/analysis_options.yaml @@ -1,5 +1,3 @@ -include: package:lints/recommended.yaml - analyzer: plugins: - sidecar diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart index 5cbf8245..decd8f45 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/bloc_outside_controller_layer.dart @@ -44,7 +44,7 @@ class BlocOutsideControllerLayer extends LintRule { // type check against the type of the declared class final classType = node.declaredElement2?.thisType; - final blocBase = TypeChecker.fromName('BlocBase', packageName: 'bloc'); + final blocBase = TypeChecker.fromPackage('BlocBase', package: 'bloc'); if (!blocBase.isAssignableFromType(classType)) return; reportAstNode(node.name, message: message); diff --git a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step3.dart b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step3.dart index 8cdf27eb..8f7c5b2e 100644 --- a/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step3.dart +++ b/website/sidecar/lib/src/tutorials/bloc_feature_structure/lib/step3.dart @@ -31,7 +31,7 @@ class BlocOutsideControllerLayer extends LintRule { // skip any files within an `application` folder if (isApplicationFile) return; - final blocBase = TypeChecker.fromName('BlocBase', packageName: 'bloc'); + final blocBase = TypeChecker.fromPackage('BlocBase', package: 'bloc'); final classType = node.declaredElement2?.thisType; if (!blocBase.isAssignableFromType(classType)) return; diff --git a/website/sidecar/lib/src/tutorials/hello_world/analysis_options.yaml b/website/sidecar/lib/src/tutorials/hello_world/analysis_options.yaml index dee8927a..e69de29b 100644 --- a/website/sidecar/lib/src/tutorials/hello_world/analysis_options.yaml +++ b/website/sidecar/lib/src/tutorials/hello_world/analysis_options.yaml @@ -1,30 +0,0 @@ -# This file configures the static analysis results for your project (errors, -# warnings, and lints). -# -# This enables the 'recommended' set of lints from `package:lints`. -# This set helps identify many issues that may lead to problems when running -# or consuming Dart code, and enforces writing Dart using a single, idiomatic -# style and format. -# -# If you want a smaller set of lints you can change this to specify -# 'package:lints/core.yaml'. These are just the most critical lints -# (the recommended set includes the core lints). -# The core lints are also what is used by pub.dev for scoring packages. - -include: package:lints/recommended.yaml - -# Uncomment the following section to specify additional rules. - -# linter: -# rules: -# - camel_case_types - -# analyzer: -# exclude: -# - path/to/excluded/files/** - -# For more information about the core and recommended set of lints, see -# https://dart.dev/go/core-lints - -# For additional information about configuring this file, see -# https://dart.dev/guides/language/analysis-options From fccac3391dbf387db35ede820262e510189d2a6f Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Mon, 23 Jan 2023 12:04:50 -0500 Subject: [PATCH 26/29] docs: Testing documentation. --- .../docs/concepts/snippets/testing.dart | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 website/sidecar/docs/concepts/snippets/testing.dart diff --git a/website/sidecar/docs/concepts/snippets/testing.dart b/website/sidecar/docs/concepts/snippets/testing.dart new file mode 100644 index 00000000..57303732 --- /dev/null +++ b/website/sidecar/docs/concepts/snippets/testing.dart @@ -0,0 +1,66 @@ +/* SNIP Imports */ +import 'package:design_system_lints/design_system_lints.dart'; +import 'package:sidecar/test.dart'; +import 'package:test/test.dart'; + +/* SNIP Imports END */ +/* SNIP Content1 */ +const contentDesignSystem = ''' +import 'package:design_system_annotations/design_system_annotations.dart'; +import 'package:flutter/material.dart'; +@designSystem +class DesignSystemX { + static const value = 3.1; +} +final edgeInsets = EdgeInsets.all(DesignSystemX.value); +'''; +/* SNIP Content1 END */ +/* SNIP Content2 */ +const contentEdgeInsetsAll = ''' +import 'package:flutter/material.dart'; +class MyWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(2.0), + ); + } +} +'''; +/* SNIP Content2 END */ +/* SNIP Content3 */ +const contentEdgeInsetsOnly = ''' +import 'package:flutter/material.dart'; +class MyWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.only(left: 1.1, right: 1.2, top: 1.3, bottom: 1.4), + ); + } +} +'''; +/* SNIP Content3 END */ +/* SNIP StartTest */ +void main() { + group('avoid_edge_insets_literal:', () { + setUpRules([AvoidEdgeInsetsLiteral()]); +/* SNIP StartTest END */ +/* SNIP RuleTest1 */ + ruleTest('EdgeInsets using Design System', contentDesignSystem, []); +/* SNIP RuleTest1 END */ +/* SNIP RuleTest2 */ + ruleTest('EdgeInsets.all', contentEdgeInsetsAll, [ExpectedText('2.0')]); +/* SNIP RuleTest2 END */ +/* SNIP RuleTest3 */ + ruleTest('EdgeInsets.only', contentEdgeInsetsOnly, [ + ExpectedText('1.1'), + ExpectedText('1.2'), + ExpectedText('1.3'), + ExpectedText('1.4'), + ]); +/* SNIP RuleTest3 END */ + /* SNIP TestEnd */ + }); +} +/* SNIP TestEnd END */ From 43681742e32a1ed8249388549fa410beb9266951 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Mon, 23 Jan 2023 12:06:36 -0500 Subject: [PATCH 27/29] docs: Integration Testing documentation. --- .../sidecar/.dart_tool/package_config.json | 10 ++++- website/sidecar/.packages | 5 ++- .../docs/concepts/integration_testing.mdx | 45 +++++++++++++++++++ .../sidecar/docs/concepts/type_checking.mdx | 1 - website/sidecar/pubspec.yaml | 6 ++- 5 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 website/sidecar/docs/concepts/integration_testing.mdx diff --git a/website/sidecar/.dart_tool/package_config.json b/website/sidecar/.dart_tool/package_config.json index 21293a2b..41be4a68 100644 --- a/website/sidecar/.dart_tool/package_config.json +++ b/website/sidecar/.dart_tool/package_config.json @@ -139,6 +139,12 @@ "packageUri": "lib/", "languageVersion": "2.17" }, + { + "name": "design_system_lints", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.11", + "packageUri": "lib/", + "languageVersion": "2.17" + }, { "name": "file", "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4", @@ -321,7 +327,7 @@ }, { "name": "sidecar", - "rootUri": "../../../packages/sidecar", + "rootUri": "file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.21", "packageUri": "lib/", "languageVersion": "2.17" }, @@ -470,7 +476,7 @@ "languageVersion": "2.17" } ], - "generated": "2023-01-22T21:44:56.466912Z", + "generated": "2023-01-23T16:33:20.511367Z", "generator": "pub", "generatorVersion": "2.17.6" } diff --git a/website/sidecar/.packages b/website/sidecar/.packages index 7f053910..9c1791f9 100644 --- a/website/sidecar/.packages +++ b/website/sidecar/.packages @@ -3,7 +3,7 @@ # # For more info see: https://dart.dev/go/dot-packages-deprecation # -# Generated by pub on 2023-01-22 16:44:56.457341. +# Generated by pub on 2023-01-23 11:33:20.502685. _fe_analyzer_shared:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-47.0.0/lib/ analyzer:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer-4.7.0/lib/ analyzer_plugin:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.11.1/lib/ @@ -27,6 +27,7 @@ convert:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/convert-3.1. coverage:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/coverage-1.6.1/lib/ crypto:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib/ dart_style:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/dart_style-2.2.4/lib/ +design_system_lints:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/design_system_lints-0.1.0-dev.11/lib/ file:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib/ fixnum:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/fixnum-1.0.1/lib/ freezed:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/freezed-2.2.0/lib/ @@ -57,7 +58,7 @@ shelf:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf-1.4.0/li shelf_packages_handler:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-3.0.1/lib/ shelf_static:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_static-1.1.1/lib/ shelf_web_socket:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-1.0.3/lib/ -sidecar:../../packages/sidecar/lib/ +sidecar:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar-0.1.0-dev.21/lib/ sidecar_annotations:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/sidecar_annotations-0.1.0-dev.1/lib/ source_gen:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_gen-1.2.6/lib/ source_helper:file:///Users/pattobrien/.pub-cache/hosted/pub.dartlang.org/source_helper-1.3.3/lib/ diff --git a/website/sidecar/docs/concepts/integration_testing.mdx b/website/sidecar/docs/concepts/integration_testing.mdx new file mode 100644 index 00000000..cd60300e --- /dev/null +++ b/website/sidecar/docs/concepts/integration_testing.mdx @@ -0,0 +1,45 @@ +--- +title: Integration Testing +sidebar_position: 3 +description: "" +--- + +import CodeBlock from '@theme/CodeBlock'; +import testing from "!!raw-loader!./snippets/testing.dart"; +import { + trimSnippet, + generateSnippet, + CodeSnippet, +} from "../../src/components/CodeSnippet"; + +Sidecar ships with a series of test utilities that make it easy to write integration tests for Sidecar rules. + +When writing rule tests, we must create a string containing example code that we expect to trigger or not trigger a lint. + +The below snippet shows code that we would expect to show a lint for the `avoid_edge_insets_literal` rule from design_system_lints. The rule +is expected to find values used in an `EdgeInsets` constructor, and show a lint if that value is not annotated +with `@designSystem` (see [design_system_lints](https://pub.dev/packages/design_system_lints) for +a full explanation of these rules). + +{generateSnippet(testing, ['Content2'])} + +In this example, we would expect a lint to be reported underneath the `2.0` value. We can easily test for this, +by writing the following rule in the `test` directory of our rule package: + +{generateSnippet(testing, ['StartTest', 'TestEnd', 'RuleTest2' ])} + +Before we can run any rule test, we must first use the `setUpRules` function with the particular rule we're looking to test (here, `AvoidEdgeInsetsLiteral`). +We can then use the `ExpectedText` test utility to check if a lint is found over the particular code `2.0`. We also make +the test description `EdgeInsets.all`, as that's exactly the use case we're testing for. + +If we want to test that a lint is found when using a different instantiation of `EdgeInsets` (e.g. `EdgeInsets.only`), +we can create another test that checks each of the parameters given to `EdgeInsets.only` (i.e. `left`, `right`, `top`, `bottom`) +by writing 4 different `ExpectedText` values and providing them to our `ruleTest`: + +{generateSnippet(testing, ['Imports', 'StartTest', 'TestEnd', 'RuleTest3', 'Content3'])} + +Finally, if we write a test where we expect no lints (such as when our `EdgeInset` values are annotated with `@designSystem`), +we simply simply leave the `ExpectedText` array empty for our `ruleTest`: + +{generateSnippet(testing, ['Imports', 'StartTest', 'TestEnd', 'RuleTest1', 'Content1'])} + diff --git a/website/sidecar/docs/concepts/type_checking.mdx b/website/sidecar/docs/concepts/type_checking.mdx index f58af655..756870f9 100644 --- a/website/sidecar/docs/concepts/type_checking.mdx +++ b/website/sidecar/docs/concepts/type_checking.mdx @@ -5,7 +5,6 @@ description: "" --- import CodeBlock from '@theme/CodeBlock'; - import dartTypeChecker from "!!raw-loader!./snippets/type_checking.dart"; import { generateSnippet, diff --git a/website/sidecar/pubspec.yaml b/website/sidecar/pubspec.yaml index d64c97ae..d4f2e1a4 100644 --- a/website/sidecar/pubspec.yaml +++ b/website/sidecar/pubspec.yaml @@ -11,18 +11,20 @@ environment: dependencies: analyzer: ^4.2.0 + design_system_lints: ^0.1.0-dev.11 freezed_annotation: ^2.1.0 # non-dart official package glob: ^2.1.0 json_annotation: ^4.6.0 meta: ^1.7.0 path: ^1.8.1 pub_semver: ^2.1.1 - sidecar: - path: ../../packages/sidecar/ + # sidecar: + # path: ../../packages/sidecar/ # sidecar_annotations: # path: ../../packages/sidecar_annotations/ # sidecar_package_utilities: # path: ../../packages/sidecar_package_utilities/ + sidecar: ^0.1.0-dev.21 source_span: ^1.8.0 test: ^1.16.0 From b928da79210e52a1b0e3eb2a587b097e04aeaf30 Mon Sep 17 00:00:00 2001 From: pattobrien <12474318+pattobrien@users.noreply.github.com> Date: Mon, 23 Jan 2023 16:08:38 -0500 Subject: [PATCH 28/29] docs: Warning message on intro page. --- website/sidecar/docs/concepts/_category_.json | 5 ++++- website/sidecar/docs/intro.md | 14 +++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/website/sidecar/docs/concepts/_category_.json b/website/sidecar/docs/concepts/_category_.json index 78ee8651..135ca4e5 100644 --- a/website/sidecar/docs/concepts/_category_.json +++ b/website/sidecar/docs/concepts/_category_.json @@ -1,4 +1,7 @@ { "label": "Core Concepts", - "position": 3 + "position": 3, + "link": { + "type": "generated-index" + } } \ No newline at end of file diff --git a/website/sidecar/docs/intro.md b/website/sidecar/docs/intro.md index 9992288e..542d7b66 100644 --- a/website/sidecar/docs/intro.md +++ b/website/sidecar/docs/intro.md @@ -2,18 +2,22 @@ sidebar_position: 1 title: Introduction --- +:::caution +Sidecar is currently an experimental package and is not recommended to be used to create lints for production projects. -> NOTE: This site is an active, high-priority project to help get you and others started with creating your own lint rules. -If there's any trouble you have with using Sidecar or a Sidecar-based rule package (like design_system_lints), your -feedback would be greatly appreciated in the [Discord channel](https://discord.gg/YhFS6V26Vg). +However, if you'd still like to proceed and create your own lints, these docs can certainly help get you started. +For any additional questions that you have, dont hesitate to reach out on [Discord](https://discord.gg/YhFS6V26Vg). +::: ## Getting Started Sidecar is a framework for creating custom lint and quick fix rules for Dart and Flutter projects. +For information on how to set up a rule package in order to display lints throughout your codebase or CLI, check out the [usage guides](category/usage-guides) +for setup steps and troublshooting tips. If you want to create your own lint rules, we've created several [tutorials](category/tutorials) that break down the process of doing so. -But before diving in to the tutorials, its highly recommended that you understand the core concepts and usage guidelines of both -sidecar and package:analyzer. +But before diving in, its highly recommended that you fully understand the [core concepts](category/core-concepts) and usage guides of both +sidecar and [package:analyzer](https://pub.dev/packages/analyzer). From 45f6970bf69451c7791d91364ec708ede089726f Mon Sep 17 00:00:00 2001 From: Patt O'Brien <12474318+pattobrien@users.noreply.github.com> Date: Sat, 7 Oct 2023 13:52:40 -0400 Subject: [PATCH 29/29] test: Test change to see if codecov is triggered. --- packages/sidecar/lib/sidecar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sidecar/lib/sidecar.dart b/packages/sidecar/lib/sidecar.dart index f8a03686..fd2d5996 100644 --- a/packages/sidecar/lib/sidecar.dart +++ b/packages/sidecar/lib/sidecar.dart @@ -1,6 +1,6 @@ // Temporarily ignore ordering // ignore_for_file: directives_ordering - +// library sidecar; // is this needed any more?