source_gen icon indicating copy to clipboard operation
source_gen copied to clipboard

typeChecker.isAssignableFromType(dartType) and constantReader.instanceOf(typeChecker) always return false if the import directive of the 'typechecked' class includes a relative path.

Open simphotonics opened this issue 5 years ago • 0 comments

The methods for checking if an instance of DartType refers to a specific type or class literal:

  • typeChecker.isAssignableFromType(dartType) and
  • constantReader.instanceOf(typeChecker)

always return false if the import directive of the class that was used to create the TypeChecker includes a relative path.

The methods above return false even if the TypeChecker is instantiated with the correct class literal. See main() below.

Suppose we have the following files that are located in the test directory of a Dart project with normal folder structure.

File: test/src/player.dart containing the class Player.

class Player {
  const Player({this.firstName});
  /// First name of player.
  final String firstName;
}

File: test/src/team.dart containing the class Team.

import 'player.dart'

class Team {
  const Team();
  final player1 = const Player(firstName: 'Thomas'); 
  final player2 = const Player(firstName: 'Alex');
}

File: test/team_test.dart containing main().

import 'package:source_gen/source_gen.dart';
import 'package:source_gen_test/src/init_library_reader.dart';
import 'src/player.dart';  // Import directive with relative uri. 
import 'src/team.dart';    // <------- relative uri.

Future<void> main() async {
  /// Get library reader.
  final libraryReader =
      await initializeLibraryReaderForDirectory('test/src', 'player.dart');

  // Get ConstantReader of field 'player1'. 
  final constantReader = 
      ConstantReader(libraryReader.classes.first.fields[0].computeConstantValue());
  final typeChecker = TypeChecker.fromRuntime(Player);

  // Static type of field 'player1'.
  final dartType = constantReader.objectValue.type;
  print(dartType); // Prints: Player.

  print(constantReader.instanceOf(typeChecker)); // Prints: false. 
  print(typeChecker.isAssignableFromType(dartType)); // Prints: false.
}

Running main() one can notice that the methods constantReader.instanceOf(typeChecker) and typeChecker.isAssignableFromType(dartType) both return false if the import directive of the class Player contains a relative path.

print(typeChecker) outputs: file:///home/dan/WORK/generic_reader/test/src/player.dart#Player

Type-checking works as expected if the import directive includes a fully qualified package uri. In that case, print(typeChecker) prints: asset:team_project/lib/src/entities/player.dart#Player

This might be by design, but maybe it would be worthwhile to mention it in the method docs.

simphotonics avatar May 14 '20 21:05 simphotonics