Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error during migration: Bad state: Unrelated types #45970

Closed
insinfo opened this issue May 10, 2021 · 6 comments
Closed

Error during migration: Bad state: Unrelated types #45970

insinfo opened this issue May 10, 2021 · 6 comments
Labels
area-migration (deprecated) Deprecated: this label is no longer actively used (was: issues with the `dart migrate` tool).

Comments

@insinfo
Copy link

insinfo commented May 10, 2021

Bad state: Unrelated types: class Object and abstract class FutureOr in (readData ?? (req, res) {if (req.bodyAsObject is! Data) {throw GalileoHttpException.badRequest(message: 'Invalid request body. Expected $Data; found ${req.bodyAsObject} instead.');} else {return req.bodyAsObject as Data;}})

dart migrate
Migrating D:\MyDartProjects\galileo\packages\framework

See https://dart.dev/go/null-safety-migration for a migration guide.

Analyzing project...
[-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\]No analysis issues found.

Generating migration suggestions...
[---------------------------------------/                                                                                                                                                              ]Aborting migration due to an exception.  This most likely is due to a
bug in the migration tool.  Please consider filing a bug report at:

https://github.com/dart-lang/sdk/issues/new
Please include the SDK version (2.12.4) in your bug report.

To attempt to perform migration anyway, you may re-run with
--ignore-exceptions.

Exception details:

Bad state: Unrelated types: class Object and abstract class FutureOr<T> at offset 2391 in D:\MyDartProjects\galileo\packages\framework\lib\src\core\service.dart (readData ?? (req, res) {if (req.bodyAsObject is! Data) {throw GalileoHttpException.badRequest(message: 'Invalid request body. Expected $Data; found ${req.bodyAsObject} instead.');} else {return req.bodyAsObject as Data;}})

#0      DecoratedClassHierarchy.getDecoratedSupertype (package:nnbd_migration/src/decorated_class_hierarchy.dart:67:10)
#1      DecoratedClassHierarchy.asInstanceOf (package:nnbd_migration/src/decorated_class_hierarchy.dart:38:18)
#2      EdgeBuilder._decorateUpperOrLowerBound (package:nnbd_migration/src/edge_builder.dart:2108:18)
#3      EdgeBuilder._decorateUpperOrLowerBound (package:nnbd_migration/src/edge_builder.dart:2070:14)
#4      EdgeBuilder._decorateUpperOrLowerBound (package:nnbd_migration/src/edge_builder.dart:2154:26)
#5      EdgeBuilder.visitBinaryExpression (package:nnbd_migration/src/edge_builder.dart:495:26)
#6      BinaryExpressionImpl.accept (package:analyzer/src/dart/ast/ast.dart:967:49)
#7      EdgeBuilder._dispatch (package:nnbd_migration/src/edge_builder.dart:2207:24)
#8      EdgeBuilder._handleAssignment (package:nnbd_migration/src/edge_builder.dart:2329:20)
#9      EdgeBuilder.visitAssignmentExpression (package:nnbd_migration/src/edge_builder.dart:409:26)
#10     AssignmentExpressionImpl.accept (package:analyzer/src/dart/ast/ast.dart:715:49)
#11     EdgeBuilder._dispatch (package:nnbd_migration/src/edge_builder.dart:2207:24)
#12     EdgeBuilder.visitExpressionStatement (package:nnbd_migration/src/edge_builder.dart:801:25)
#13     ExpressionStatementImpl.accept (package:analyzer/src/dart/ast/ast.dart:3676:49)
#14     EdgeBuilder._dispatch (package:nnbd_migration/src/edge_builder.dart:2207:24)
#15     EdgeBuilder.visitNode (package:nnbd_migration/src/edge_builder.dart:1340:9)
#16     GeneralizingAstVisitor.visitStatement (package:analyzer/dart/ast/visitor.dart:517:39)
#17     GeneralizingAstVisitor.visitBlock (package:analyzer/dart/ast/visitor.dart:165:31)
#18     BlockImpl.accept (package:analyzer/src/dart/ast/ast.dart:1083:49)
#19     EdgeBuilder._dispatch (package:nnbd_migration/src/edge_builder.dart:2207:24)
#20     EdgeBuilder.visitNode (package:nnbd_migration/src/edge_builder.dart:1340:9)
#21     GeneralizingAstVisitor.visitFunctionBody (package:analyzer/dart/ast/visitor.dart:324:45)
#22     GeneralizingAstVisitor.visitBlockFunctionBody (package:analyzer/dart/ast/visitor.dart:168:55)
#23     BlockFunctionBodyImpl.accept (package:analyzer/src/dart/ast/ast.dart:1038:49)
#24     EdgeBuilder._dispatch (package:nnbd_migration/src/edge_builder.dart:2207:24)
#25     EdgeBuilder._handleExecutableDeclaration (package:nnbd_migration/src/edge_builder.dart:2488:7)
#26     EdgeBuilder.visitConstructorDeclaration (package:nnbd_migration/src/edge_builder.dart:712:5)
#27     ConstructorDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:2566:15)
#28     EdgeBuilder._dispatch (package:nnbd_migration/src/edge_builder.dart:2207:24)
#29     EdgeBuilder._dispatchList (package:nnbd_migration/src/edge_builder.dart:2229:7)
#30     EdgeBuilder.visitClassOrMixinOrExtensionDeclaration (package:nnbd_migration/src/edge_builder.dart:607:7)
#31     EdgeBuilder.visitClassDeclaration (package:nnbd_migration/src/edge_builder.dart:574:5)
#32     ClassDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:1536:49)
#33     EdgeBuilder._dispatch (package:nnbd_migration/src/edge_builder.dart:2207:24)
#34     EdgeBuilder.visitNode (package:nnbd_migration/src/edge_builder.dart:1340:9)
#35     GeneralizingAstVisitor.visitCompilationUnit (package:analyzer/dart/ast/visitor.dart:202:51)
#36     CompletenessTracker.visitCompilationUnit.<anonymous closure> (package:nnbd_migration/src/utilities/completeness_tracker.dart:52:24)
#37     PermissiveModeVisitor.reportExceptionsIfPermissive (package:nnbd_migration/src/utilities/permissive_mode.dart:26:24)
#38     CompletenessTracker.visitCompilationUnit (package:nnbd_migration/src/utilities/completeness_tracker.dart:43:5)
#39     CompilationUnitImpl.accept (package:analyzer/src/dart/ast/ast.dart:2134:49)
#40     NullabilityMigrationImpl.processInput (package:nnbd_migration/src/nullability_migration_impl.dart:244:12)
#41     NonNullableFix.processUnit (package:nnbd_migration/src/front_end/non_nullable_fix.dart:164:15)
#42     _FixCodeProcessor.runLaterPhases.<anonymous closure> (package:nnbd_migration/migration_cli.dart:1154:19)
#43     _FixCodeProcessor.runLaterPhases.<anonymous closure> (package:nnbd_migration/migration_cli.dart:1152:28)
#44     _FixCodeProcessor.processResources (package:nnbd_migration/migration_cli.dart:1081:30)
<asynchronous suspension>
#45     _FixCodeProcessor.runLaterPhases (package:nnbd_migration/migration_cli.dart:1152:5)
<asynchronous suspension>
#46     MigrationCliRunner.run (package:nnbd_migration/migration_cli.dart:749:24)
<asynchronous suspension>
#47     MigrateCommand.run (package:nnbd_migration/migration_cli.dart:185:7)
<asynchronous suspension>
#48     CommandRunner.runCommand (package:args/command_runner.dart:196:13)
<asynchronous suspension>
#49     DartdevRunner.runCommand (package:dartdev/dartdev.dart:199:18)
<asynchronous suspension>
#50     runDartdev (package:dartdev/dartdev.dart:53:16)
<asynchronous suspension>
#51     main (file:///C:/b/s/w/ir/cache/builder/sdk/pkg/dartdev/bin/dartdev.dart:11:3)
<asynchronous suspension>

PS D:\MyDartProjects\galileo\packages\framework>

* Dart SDK version: 2.12.4 (stable) (Thu Apr 15 12:26:53 2021 +0200) on "windows_x64"
* Windows
@insinfo
Copy link
Author

insinfo commented May 10, 2021

server.dart

library galileo_framework.http.server;

import 'dart:async';
import 'dart:collection' show HashMap;
import 'dart:convert';
import 'package:galileo_container/galileo_container.dart';
import 'package:galileo_http_exception/galileo_http_exception.dart';
import 'package:galileo_route/galileo_route.dart';
import 'package:galileo_combinator/galileo_combinator.dart';
import 'package:http_parser/http_parser.dart';
import 'package:logging/logging.dart';
import 'package:mime/mime.dart';
import 'package:tuple/tuple.dart';
import 'controller.dart';
import 'env.dart';
import 'hooked_service.dart';
import 'request_context.dart';
import 'response_context.dart';
import 'routable.dart';
import 'service.dart';

//final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)');

/// A function that configures an [Galileo] server in some way.
typedef FutureOr<void> GalileoConfigurer(Galileo app);

/// A function that asynchronously generates a view from the given path and data.
typedef FutureOr<String> ViewGenerator(String path, [Map<String, dynamic> data]);

/// A powerful real-time/REST/MVC server class.
class Galileo extends Routable {
  static ViewGenerator noViewEngineConfigured = (String view, [Map data]) => 'No view engine has been configured yet.';

  final List<Galileo> _children = [];
  final Map<String, Tuple4<List, Map<String, dynamic>, ParseResult<RouteResult>, MiddlewarePipeline>> handlerCache =
      HashMap();

  Router<RequestHandler> _flattened;
  Galileo _parent;

  /// A global Map of converters that can transform responses bodies.
  final Map<String, Converter<List<int>, List<int>>> encoders = {};

  final Map<dynamic, InjectionRequest> _preContained = {};

  /// A [MimeTypeResolver] that can be used to specify the MIME types of files not known by `package:mime`.
  final MimeTypeResolver mimeTypeResolver = MimeTypeResolver();

  /// A middleware to inject a serialize on every request.
  FutureOr<String> Function(dynamic) serializer;

  /// A [Map] of dependency data obtained via reflection.
  ///
  /// You may modify this [Map] yourself if you intend to avoid reflection entirely.
  Map<dynamic, InjectionRequest> get preContained => _preContained;

  /// Returns the [flatten]ed version of this router in production.
  Router<RequestHandler> get optimizedRouter => _flattened ?? this;

  /// Determines whether to allow HTTP request method overrides.
  bool allowMethodOverrides = true;

  /// All child application mounted on this instance.
  List<Galileo> get children => List<Galileo>.unmodifiable(_children);

  final Map<Pattern, Controller> _controllers = {};

  /// A set of [Controller] objects that have been loaded into the application.
  Map<Pattern, Controller> get controllers => _controllers;

  /// Now *deprecated*, in favor of [GalileoEnv] and [galileoEnv]. Use `app.environment.isProduction`
  /// instead.
  ///
  /// Indicates whether the application is running in a production environment.
  ///
  /// The criteria for this is the `GALILEO_ENV` environment variable being set to
  /// `'production'`.
  ///
  /// This value is memoized the first time you call it, so do not change environment
  /// configuration at runtime!
  @deprecated
  bool get isProduction => environment.isProduction;

  /// The [GalileoEnvironment] in which the application is running.
  ///
  /// By default, it is automatically inferred.
  final GalileoEnvironment environment;

  /// Returns the parent instance of this application, if any.
  Galileo get parent => _parent;

  /// Outputs diagnostics and debug messages.
  Logger logger;

  /// Plug-ins to be called right before server startup.
  ///
  /// If the server is never started, they will never be called.
  final List<GalileoConfigurer> startupHooks = [];

  /// Plug-ins to be called right before server shutdown.
  ///
  /// If the server is never [close]d, they will never be called.
  final List<GalileoConfigurer> shutdownHooks = [];

  /// Always run before responses are sent.
  ///
  /// These will only not run if a response's `willCloseItself` is set to `true`.
  final List<RequestHandler> responseFinalizers = [];

  /// A [Map] of application-specific data that can be accessed by any
  /// piece of code that can see this [Galileo] instance.
  ///
  /// Packages like `package:galileo_configuration` populate this map
  /// for you.
  final Map configuration = {};

  /// A function that renders views.
  ///
  /// Called by [ResponseContext]@`render`.
  ViewGenerator viewGenerator = noViewEngineConfigured;

  /// The handler currently configured to run on [GalileoHttpException]s.
  Function(GalileoHttpException e, RequestContext req, ResponseContext res) errorHandler =
      (GalileoHttpException e, RequestContext req, ResponseContext res) {
    if (!req.accepts('text/html', strict: true) &&
        (req.accepts('application/json') || req.accepts('application/javascript'))) {
      res.json(e.toJson());
      return;
    }

    res.contentType = MediaType('text', 'html', {'charset': 'utf8'});
    res.statusCode = e.statusCode;
    res.write("<!DOCTYPE html><html><head><title>${e.message}</title>");
    res.write("</head><body><h1>${e.message}</h1><ul>");

    for (String error in e.errors) {
      res.write("<li>$error</li>");
    }

    res.write("</ul></body></html>");
    res.close();
  };

  @override
  Route<RequestHandler> addRoute(String method, String path, RequestHandler handler,
      {Iterable<RequestHandler> middleware}) {
    middleware ??= [];
    if (_flattened != null) {
      logger?.warning('WARNING: You added a route ($method $path) to the router, after it had been optimized.');
      logger?.warning('This route will be ignored, and no requests will ever reach it.');
    }

    return super.addRoute(method, path, handler, middleware: middleware ?? []);
  }

  @override
  mount(String path, Router<RequestHandler> router) {
    if (_flattened != null) {
      logger?.warning('WARNING: You added mounted a child router ($path) on the router, after it had been optimized.');
      logger?.warning('This route will be ignored, and no requests will ever reach it.');
    }

    if (router is Galileo) {
      router._parent = this;
      _children.add(router);
    }

    return super.mount(path.toString(), router);
  }

  /// Loads some base dependencies into the service container.
  void bootstrapContainer() {
    if (runtimeType != Galileo) {
      container.registerSingleton(this);
    }

    container.registerSingleton<Galileo>(this);
    container.registerSingleton<Routable>(this);
    container.registerSingleton<Router>(this);
  }

  /// Shuts down the server, and closes any open [StreamController]s.
  ///
  /// The server will be **COMPLETELY DEFUNCT** after this operation!
  Future close() {
    Future.forEach(services.values, (Service service) {
      service.close();
    });

    super.close();
    viewGenerator = noViewEngineConfigured;
    _preContained.clear();
    handlerCache.clear();
    encoders.clear();
    //_serializer = json.encode;
    _children.clear();
    _parent = null;
    logger = null;
    startupHooks.clear();
    shutdownHooks.clear();
    responseFinalizers.clear();
    _flattened = null;
    return Future.value();
  }

  @override
  void dumpTree(
      {callback(String tree), String header = 'Dumping route tree:', String tab = '  ', bool showMatchers = false}) {
    if (environment.isProduction) {
      _flattened ??= flatten(this);

      _flattened.dumpTree(
          callback: callback,
          header: header?.isNotEmpty == true
              ? header
              : (environment.isProduction ? 'Dumping flattened route tree:' : 'Dumping route tree:'),
          tab: tab ?? '  ');
    } else {
      super.dumpTree(
          callback: callback,
          header: header?.isNotEmpty == true
              ? header
              : (environment.isProduction ? 'Dumping flattened route tree:' : 'Dumping route tree:'),
          tab: tab ?? '  ');
    }
  }

  Future getHandlerResult(handler, RequestContext req, ResponseContext res) {
    if (handler is RequestHandler) {
      var result = handler(req, res);
      return getHandlerResult(result, req, res);
    }

    if (handler is Future) {
      return handler.then((result) => getHandlerResult(result, req, res));
    }

    if (handler is Function) {
      var result = runContained(handler, req, res);
      return getHandlerResult(result, req, res);
    }

    if (handler is Stream) {
      return getHandlerResult(handler.toList(), req, res);
    }

    return Future.value(handler);
  }

  /// Runs some [handler]. Returns `true` if request execution should continue.
  Future<bool> executeHandler(handler, RequestContext req, ResponseContext res) {
    return getHandlerResult(handler, req, res).then((result) {
      if (result == null) {
        return false;
      } else if (result is bool) {
        return result;
      } else if (result != null) {
        return res.serialize(result);
      } else {
        return res.isOpen;
      }
    });
  }

  /// Attempts to find a property by the given name within this application.
  findProperty(key) {
    if (configuration.containsKey(key)) return configuration[key];
    return parent != null ? parent.findProperty(key) : null;
  }

  /// Runs several optimizations, *if* [galileoEnv.isProduction] is `true`.
  ///
  /// * Preprocesses all dependency injection, and eliminates the burden of reflecting handlers
  /// at run-time.
  /// * [flatten]s the route tree into a linear one.
  ///
  /// You may [force] the optimization to run, if you are not running in production.
  void optimizeForProduction({bool force = false}) {
    if (environment.isProduction || force == true) {
      _flattened ??= flatten(this);
      logger?.info('Galileo is running in production mode.');
    }
  }

  /// Run a function after injecting from service container.
  /// If this function has been reflected before, then
  /// the execution will be faster, as the injection requirements were stored beforehand.
  Future runContained(Function handler, RequestContext req, ResponseContext res, [Container container]) {
    return Future.sync(() {
      if (_preContained.containsKey(handler)) {
        return handleContained(handler, _preContained[handler], container)(req, res);
      }

      return runReflected(handler, req, res, container);
    });
  }

  /// Runs with DI, and *always* reflects. Prefer [runContained].
  Future runReflected(Function handler, RequestContext req, ResponseContext res, [Container container]) {
    container ??= req?.container ?? res?.app?.container;
    var h = handleContained(handler, _preContained[handler] = preInject(handler, container.reflector), container);
    return Future.sync(() => h(req, res));
    // return   closureMirror.apply(args).reflectee;
  }

  /// Applies an [GalileoConfigurer] to this instance.
  Future configure(GalileoConfigurer configurer) {
    return Future.sync(() => configurer(this));
  }

  /// Shorthand for using the [container] to instantiate, and then mount a [Controller].
  /// Returns the created controller.
  ///
  /// Just like [Container].make, in contexts without properly-reified generics (dev releases of Dart 2),
  /// provide a [type] argument as well.
  ///
  /// If you are on `Dart >=2.0.0`, simply call `mountController<T>()`.
  Future<T> mountController<T extends Controller>([Type type]) {
    var controller = container.make<T>(type);
    return configure(controller.configureServer).then((_) => controller);
  }

  /// Shorthand for calling `all('*', handler)`.
  Route<RequestHandler> fallback(RequestHandler handler) {
    return all('*', handler);
  }

  @override
  HookedService<Id, Data, T> use<Id, Data, T extends Service<Id, Data>>(String path, T service) {
    service.app = this;
    return super.use(path, service)..app = this;
  }

  static const String _reflectionErrorMessage = ThrowingReflector.defaultErrorMessage + ' ' + _reflectionInfo;

  static const String _reflectionInfo =
      'Features like controllers, constructor dependency injection, and `ioc` require reflection, '
      'and will not work without it.\n\n'
      'For more, see the documentation:\n'
      'https://docs.galileo-dart.dev/guides/dependency-injection#enabling-dart-mirrors-or-other-reflection';

  Galileo(
      {Reflector reflector = const ThrowingReflector(errorMessage: _reflectionErrorMessage),
      this.environment = galileoEnv,
      this.logger,
      this.allowMethodOverrides = true,
      this.serializer,
      this.viewGenerator})
      : super(reflector) {
    if (reflector is EmptyReflector || reflector is ThrowingReflector) {
      var msg = 'No `reflector` was passed to the Galileo constructor, so reflection will not be available.\n' +
          _reflectionInfo;
      logger?.warning(msg);
    }

    bootstrapContainer();
    viewGenerator ??= noViewEngineConfigured;
    serializer ??= json.encode;
  }
}

@mit-mit mit-mit changed the title Bad state: Unrelated types: class Object and abstract class FutureOr<T> in (readData ?? (req, res) {if (req.bodyAsObject is! Data) {throw GalileoHttpException.badRequest(message: 'Invalid request body. Expected $Data; found ${req.bodyAsObject} instead.');} else {return req.bodyAsObject as Data;}}) Error during migration: Bad state: Unrelated types May 11, 2021
@mit-mit mit-mit added the area-migration (deprecated) Deprecated: this label is no longer actively used (was: issues with the `dart migrate` tool). label May 11, 2021
@stereotype441
Copy link
Member

Note: #45663 has a similar stack trace and might be the same issue.

@stereotype441
Copy link
Member

@insinfo were you able to make progress on the migration by supplying the --ignore-exceptions flag when running the migration tool?

@insinfo
Copy link
Author

insinfo commented May 25, 2021

@stereotype441
I didn't make any progress in the migration of this package (https://pub.dev/packages/galileo_framework), because after using the tool I have many errors and problems, and it doesn't run the tests

@srawlins
Copy link
Member

srawlins commented Aug 4, 2022

I think a duplicate of #45663

@stereotype441
Copy link
Member

As of 1c7fe71, the null safety migration tool has been removed from active development and retired. No further work on the tool is planned.

If you still need help, or you believe this issue has been closed in error, please feel free to reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-migration (deprecated) Deprecated: this label is no longer actively used (was: issues with the `dart migrate` tool).
Projects
None yet
Development

No branches or pull requests

4 participants