Store Typedef(s) in kernel when parsing with Fasta, deserilize in DillLibraryBuilder.

R=ahe@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2882893002 .
This commit is contained in:
Konstantin Shcheglov 2017-05-14 17:51:52 -07:00
parent 66a8d2ec9c
commit dd62ad5d77
26 changed files with 170 additions and 23 deletions

View file

@ -79,6 +79,8 @@ class ElementStoreImplementation implements ElementStore {
do {
if (builder is ClassBuilder) {
elements[builder] = new KernelClassElement(builder);
} else if (builder is KernelFunctionTypeAliasBuilder) {
elements[builder] = new KernelFunctionTypeAliasElement(builder);
} else if (builder is DillMemberBuilder) {
Member member = builder.member;
if (member is Field) {} else if (member is Procedure) {
@ -289,6 +291,27 @@ class KernelClassElement extends MockClassElement {
}
}
class KernelFunctionTypeAliasElement extends MockFunctionTypeAliasElement {
final KernelFunctionTypeAliasBuilder builder;
KernelFunctionTypeAliasElement(this.builder);
@override
analyzer.DartType get returnType {
return internalError("not supported.");
}
@override
analyzer.FunctionType get type {
return internalError("not supported.");
}
@override
List<TypeParameterElement> get typeParameters {
return internalError("not supported.");
}
}
class KernelInterfaceType extends MockInterfaceType {
final KernelClassElement element;

View file

@ -347,6 +347,17 @@ abstract class MockFunctionElement extends MockElement
FunctionDeclaration computeNode() => internalError("not supported.");
}
abstract class MockFunctionTypeAliasElement extends MockElement
implements FunctionTypeAliasElement {
MockFunctionTypeAliasElement() : super(ElementKind.FUNCTION_TYPE_ALIAS);
CompilationUnitElement get enclosingElement {
return internalError("not supported.");
}
TypeAlias computeNode() => internalError("not supported.");
}
abstract class MockParameterElement extends MockElement
implements ParameterElement {
MockParameterElement() : super(ElementKind.PARAMETER);

View file

@ -4,6 +4,7 @@
library fasta.dill_library_builder;
import 'package:front_end/src/fasta/dill/dill_typedef_builder.dart';
import 'package:kernel/ast.dart'
show
Class,
@ -15,7 +16,8 @@ import 'package:kernel/ast.dart'
ListLiteral,
Member,
Procedure,
StaticGet;
StaticGet,
Typedef;
import '../errors.dart' show internalError;
@ -104,6 +106,11 @@ class DillLibraryBuilder extends LibraryBuilder<KernelTypeBuilder, Library> {
return builder;
}
void addTypedef(Typedef typedef) {
var typedefBuilder = new DillFunctionTypeAliasBuilder(typedef, this);
addBuilder(typedef.name, typedefBuilder, typedef.fileOffset);
}
bool addToExportScope(String name, Builder member) {
return internalError("Not implemented yet.");
}

View file

@ -36,6 +36,7 @@ class DillLoader extends Loader<Library> {
Future<Null> buildOutline(DillLibraryBuilder builder) async {
builder.library.classes.forEach(builder.addClass);
builder.library.procedures.forEach(builder.addMember);
builder.library.typedefs.forEach(builder.addTypedef);
builder.library.fields.forEach(builder.addMember);
}

View file

@ -0,0 +1,47 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library fasta.dill_typedef_builder;
import 'package:front_end/src/fasta/builder/library_builder.dart';
import 'package:front_end/src/fasta/errors.dart';
import 'package:kernel/ast.dart' show DartType, Typedef;
import '../kernel/kernel_builder.dart'
show
FormalParameterBuilder,
KernelFunctionTypeAliasBuilder,
KernelTypeBuilder,
MetadataBuilder,
TypeVariableBuilder;
import 'dill_library_builder.dart' show DillLibraryBuilder;
class DillFunctionTypeAliasBuilder extends KernelFunctionTypeAliasBuilder {
final Typedef typedef;
DillFunctionTypeAliasBuilder(this.typedef, DillLibraryBuilder parent)
: super(null, null, typedef.name, null, null, parent, typedef.fileOffset);
@override
List<FormalParameterBuilder> get formals {
return internalError('Not implemented.');
}
List<MetadataBuilder> get metadata {
return internalError('Not implemented.');
}
@override
KernelTypeBuilder get returnType {
return internalError('Not implemented.');
}
@override
List<TypeVariableBuilder> get typeVariables {
return internalError('Not implemented.');
}
@override
DartType buildThisType(LibraryBuilder library) => typedef.type;
}

View file

@ -4,6 +4,7 @@
library fasta.kernel_function_type_alias_builder;
import 'package:front_end/src/fasta/util/relativize.dart';
import 'package:kernel/ast.dart'
show
DartType,
@ -11,17 +12,17 @@ import 'package:kernel/ast.dart'
FunctionType,
InvalidType,
NamedType,
TypeParameter;
TypeParameter,
Typedef;
import 'package:kernel/type_algebra.dart' show substitute;
import '../messages.dart' show warning;
import 'kernel_builder.dart'
show
FormalParameterBuilder,
FunctionTypeAliasBuilder,
KernelFormalParameterBuilder,
KernelLibraryBuilder,
KernelTypeBuilder,
KernelTypeVariableBuilder,
LibraryBuilder,
@ -46,6 +47,14 @@ class KernelFunctionTypeAliasBuilder
: super(metadata, returnType, name, typeVariables, formals, parent,
charOffset);
Typedef build(KernelLibraryBuilder libraryBuilder) {
DartType type = buildThisType(libraryBuilder);
var typedef_ = new Typedef(name, type);
typedef_.fileUri = relativizeUri(parent.fileUri);
typedef_.fileOffset = charOffset;
return typedef_;
}
DartType buildThisType(LibraryBuilder library) {
if (thisType != null) {
if (thisType == const InvalidType()) {
@ -90,22 +99,6 @@ class KernelFunctionTypeAliasBuilder
requiredParameterCount: requiredParameterCount);
}
/// [arguments] have already been built.
DartType buildTypesWithBuiltArguments(
LibraryBuilder library, List<DartType> arguments) {
var thisType = buildThisType(library);
if (thisType is DynamicType) return thisType;
FunctionType result = thisType;
if (result.typeParameters.isEmpty && arguments == null) return result;
arguments =
computeDefaultTypeArguments(library, result.typeParameters, arguments);
Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
for (int i = 0; i < result.typeParameters.length; i++) {
substitution[result.typeParameters[i]] = arguments[i];
}
return substitute(result.withoutTypeParameters, substitution);
}
DartType buildType(
LibraryBuilder library, List<KernelTypeBuilder> arguments) {
var thisType = buildThisType(library);
@ -121,4 +114,20 @@ class KernelFunctionTypeAliasBuilder
}
return buildTypesWithBuiltArguments(library, builtArguments);
}
/// [arguments] have already been built.
DartType buildTypesWithBuiltArguments(
LibraryBuilder library, List<DartType> arguments) {
var thisType = buildThisType(library);
if (thisType is DynamicType) return thisType;
FunctionType result = thisType;
if (result.typeParameters.isEmpty && arguments == null) return result;
arguments =
computeDefaultTypeArguments(library, result.typeParameters, arguments);
Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
for (int i = 0; i < result.typeParameters.length; i++) {
substitution[result.typeParameters[i]] = arguments[i];
}
return substitute(result.withoutTypeParameters, substitution);
}
}

View file

@ -652,9 +652,8 @@ class KernelLibraryBuilder
library.addMember(builder.build(this)..isStatic = true);
} else if (builder is KernelProcedureBuilder) {
library.addMember(builder.build(this)..isStatic = true);
} else if (builder is FunctionTypeAliasBuilder) {
// Kernel discard typedefs and use their corresponding function types
// directly.
} else if (builder is KernelFunctionTypeAliasBuilder) {
library.addTypedef(builder.build(this));
} else if (builder is KernelEnumBuilder) {
library.addClass(builder.build(this, coreLibrary));
} else if (builder is PrefixBuilder) {

View file

@ -184,6 +184,31 @@ static method main() → dynamic {
}
}
test_compile_typedef() async {
writeFile('/test/.packages', 'test:lib/');
String aPath = '/test/lib/a.dart';
String bPath = '/test/lib/b.dart';
writeFile(aPath, 'typedef int F<T>(T x);');
Uri bUri = writeFile(
bPath,
r'''
import 'a.dart';
F<String> f;
''');
Program program = await getInitialState(bUri);
Library library = _getLibrary(program, bUri);
expect(
_getLibraryText(library),
r'''
library;
import self as self;
import "dart:core" as core;
static field (core::String) core::int f;
''');
}
test_updatePart() async {
writeFile('/test/.packages', 'test:lib/');
String libPath = '/test/lib/test.dart';

View file

@ -64,6 +64,7 @@ final subpackageRules = {
]),
'lib/src/fasta/dill': new SubpackageRules(allowedDependencies: [
'lib/src/fasta',
'lib/src/fasta/builder',
'lib/src/fasta/kernel',
]),
'lib/src/fasta/kernel': new SubpackageRules(allowedDependencies: [

View file

@ -2,6 +2,7 @@ library;
import self as self;
import "dart:core" as core;
typedef Callback = <T extends core::Object>(T) → void;
class Foo<T extends core::Object> extends core::Object {
final field self::Foo::T finalField;
final field (self::Foo::T) → void callbackField;

View file

@ -2,6 +2,7 @@ library test;
import self as self;
import "dart:core" as core;
typedef F = <V extends core::Object>(V) → void;
class C<T extends core::Object> extends self::D<self::C::T> {
constructor •() → void
: super self::D::•()

View file

@ -2,6 +2,7 @@ library test;
import self as self;
import "dart:core" as core;
typedef G = <V extends core::Object>() → core::List<V>;
class C<T extends core::Object> extends self::D<self::C::T> {
constructor •() → void
: super self::D::•()

View file

@ -2,6 +2,7 @@ library test;
import self as self;
import "dart:core" as core;
typedef F = <V extends core::Object>() → V;
class C<T extends core::Object> extends self::D<self::C::T> {
constructor •() → void
: super self::D::•()

View file

@ -2,6 +2,7 @@ library test;
import self as self;
import "dart:core" as core;
typedef FunctionReturningNum = () → core::num;
static method main() → dynamic {
core::int i = 1;
core::Object o = 1;

View file

@ -1,5 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
typedef FunctionReturningNum = () → core::num;
static method main() → dynamic
;

View file

@ -2,6 +2,7 @@ library test;
import self as self;
import "dart:core" as core;
typedef FunctionReturningNum = () → core::num;
static method main() → dynamic {
core::int i = 1;
core::Object o = 1;

View file

@ -2,6 +2,7 @@ library test;
import self as self;
import "dart:core" as core;
typedef FunctionReturningInt = () → core::int;
static method main() → dynamic {
function f() → core::num
return 0;

View file

@ -1,5 +1,7 @@
library test;
import self as self;
import "dart:core" as core;
typedef FunctionReturningInt = () → core::int;
static method main() → dynamic
;

View file

@ -2,6 +2,7 @@ library test;
import self as self;
import "dart:core" as core;
typedef FunctionReturningInt = () → core::int;
static method main() → dynamic {
function f() → core::num
return 0;

View file

@ -2,6 +2,7 @@ library test;
import self as self;
import "dart:core" as core;
typedef F = () → core::int;
static method main() → dynamic {
core::List<() → core::int> v = <() → core::int>[() → core::int {
return 1;

View file

@ -1,5 +1,7 @@
library;
import self as self;
import "dart:core" as core;
typedef Handle = (core::String) → dynamic;
static method main() → dynamic
;

View file

@ -2,6 +2,7 @@ library;
import self as self;
import "dart:core" as core;
typedef Func = () → void;
class C<T extends core::Object> extends core::Object {
constructor •() → void
;

View file

@ -1,5 +1,6 @@
library;
import self as self;
typedef Foo = () → void;
static method main() → dynamic
;

View file

@ -2,6 +2,7 @@ library;
import self as self;
import "dart:core" as core;
typedef VoidFunction = () → void;
class Fisk extends core::Object {
constructor •() → void
;

View file

@ -2,6 +2,9 @@ library;
import self as self;
import "dart:core" as core;
typedef _NullaryFunction = () → dynamic;
typedef _UnaryFunction = (dynamic) → dynamic;
typedef _BinaryFunction = (dynamic, dynamic) → dynamic;
static method main() → dynamic {
core::print(self::main is () → dynamic);
core::print(self::main is (dynamic) → dynamic);

View file

@ -1,5 +1,8 @@
library;
import self as self;
typedef _NullaryFunction = () → dynamic;
typedef _UnaryFunction = (dynamic) → dynamic;
typedef _BinaryFunction = (dynamic, dynamic) → dynamic;
static method main() → dynamic
;