From 875abcea3924e94b60bfbb003467542af9d983d8 Mon Sep 17 00:00:00 2001 From: Jenny Messerly Date: Mon, 16 Jul 2018 19:32:44 +0000 Subject: [PATCH] Remove experimental closure support from dartdevc Change-Id: Id171cbfd220c4b504f13183ffdcad581c44fb41a Reviewed-on: https://dart-review.googlesource.com/64826 Commit-Queue: Jenny Messerly Reviewed-by: Bob Nystrom --- .../lib/src/analyzer/code_generator.dart | 165 ++++--------- .../lib/src/analyzer/js_typeref_codegen.dart | 127 ---------- .../lib/src/analyzer/module_compiler.dart | 28 +-- .../lib/src/closure/closure_annotation.dart | 133 ---------- .../lib/src/closure/closure_annotator.dart | 38 --- .../lib/src/closure/closure_type.dart | 85 ------- .../lib/src/compiler/js_utils.dart | 3 +- pkg/dev_compiler/lib/src/js_ast/js_ast.dart | 3 - pkg/dev_compiler/lib/src/js_ast/js_types.dart | 202 ---------------- pkg/dev_compiler/lib/src/js_ast/nodes.dart | 92 +------ pkg/dev_compiler/lib/src/js_ast/printer.dart | 63 +---- pkg/dev_compiler/lib/src/js_ast/template.dart | 28 +-- .../lib/src/js_ast/type_printer.dart | 227 ------------------ pkg/dev_compiler/lib/src/kernel/compiler.dart | 3 +- .../test/closure/closure_annotation_test.dart | 125 ---------- .../test/closure/closure_type_test.dart | 82 ------- 16 files changed, 61 insertions(+), 1343 deletions(-) delete mode 100644 pkg/dev_compiler/lib/src/analyzer/js_typeref_codegen.dart delete mode 100644 pkg/dev_compiler/lib/src/closure/closure_annotation.dart delete mode 100644 pkg/dev_compiler/lib/src/closure/closure_annotator.dart delete mode 100644 pkg/dev_compiler/lib/src/closure/closure_type.dart delete mode 100644 pkg/dev_compiler/lib/src/js_ast/js_types.dart delete mode 100644 pkg/dev_compiler/lib/src/js_ast/type_printer.dart delete mode 100644 pkg/dev_compiler/test/closure/closure_annotation_test.dart delete mode 100644 pkg/dev_compiler/test/closure/closure_type_test.dart diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart index a0d0b67ef6c..c39397d36eb 100644 --- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart +++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart @@ -35,7 +35,6 @@ import 'package:analyzer/src/task/strong/ast_properties.dart'; import 'package:path/path.dart' as path; import 'package:source_span/source_span.dart' show SourceLocation; -import '../closure/closure_annotator.dart' show ClosureAnnotator; import '../compiler/js_metalet.dart' as JS; import '../compiler/js_names.dart' as JS; import '../compiler/js_utils.dart' as JS; @@ -49,7 +48,6 @@ import 'element_helpers.dart'; import 'error_helpers.dart'; import 'extension_types.dart' show ExtensionTypeSet; import 'js_interop.dart'; -import 'js_typeref_codegen.dart' show JSTypeRefCodegen; import 'js_typerep.dart'; import 'module_compiler.dart' show BuildUnit, CompilerOptions, JSModuleFile; import 'nullable_type_inference.dart' show NullableTypeInference; @@ -74,11 +72,7 @@ import 'type_utilities.dart'; // expressions (which result in JS.Expression) and statements // (which result in (JS.Statement). class CodeGenerator extends Object - with - ClosureAnnotator, - JSTypeRefCodegen, - NullableTypeInference, - SharedCompiler + with NullableTypeInference, SharedCompiler implements AstVisitor { final AnalysisContext context; final SummaryDataStore summaryData; @@ -871,13 +865,10 @@ class CodeGenerator extends Object } } - JS.Expression body = closureAnnotate( - runtimeCall('typedef(#, () => #)', [ - js.string(element.name, "'"), - _emitFunctionType(type, nameType: false) - ]), - element, - node); + JS.Expression body = runtimeCall('typedef(#, () => #)', [ + js.string(element.name, "'"), + _emitFunctionType(type, nameType: false) + ]); if (typeFormals.isNotEmpty) { return _defineClassTypeArguments(element, typeFormals, @@ -1231,19 +1222,6 @@ class CodeGenerator extends Object .toList(growable: false); } - /// Emits a field declaration for TypeScript & Closure's ES6_TYPED - /// (e.g. `class Foo { i: string; }`) - JS.VariableDeclarationList _emitTypeScriptField(FieldElement field) { - return JS.VariableDeclarationList(field.isStatic ? 'static' : null, [ - JS.VariableInitialization( - JS.Identifier( - // TODO(ochafik): use a refactored _emitMemberName instead. - field.name, - type: emitTypeRef(field.type)), - null) - ]); - } - @override JS.Statement visitEnumDeclaration(EnumDeclaration node) { return _emitClassDeclaration(node, node.element, []); @@ -1279,19 +1257,12 @@ class CodeGenerator extends Object JS.Expression className, JS.Expression heritage, List methods) { - var typeParams = _emitTypeFormals(classElem.typeParameters); - - var jsFields = options.closure - ? classElem.fields.map(_emitTypeScriptField).toList() - : null; if (classElem.typeParameters.isNotEmpty) { - return JS.ClassExpression(className as JS.Identifier, heritage, methods, - typeParams: typeParams, fields: jsFields) + return JS.ClassExpression(className as JS.Identifier, heritage, methods) .toStatement(); } - var classExpr = JS.ClassExpression( - JS.TemporaryId(classElem.name), heritage, methods, - typeParams: typeParams, fields: jsFields); + var classExpr = + JS.ClassExpression(JS.TemporaryId(classElem.name), heritage, methods); return js.statement('# = #;', [className, classExpr]); } @@ -1648,8 +1619,7 @@ class CodeGenerator extends Object body.add(js.statement( 'return super.#(#)(#);', [name, typeFormals, jsParams])); } - var fn = JS.Fun(jsParams, JS.Block(body), - typeParams: typeFormals, returnType: emitTypeRef(type.returnType)); + var fn = JS.Fun(jsParams, JS.Block(body)); methods.add(JS.Method(name, fn)); } else { throw StateError( @@ -1664,7 +1634,6 @@ class CodeGenerator extends Object if (isUnsupportedFactoryConstructor(node)) return null; var element = node.element; - var returnType = emitTypeRef(element.returnType); var name = _constructorName(element.name); JS.Fun fun; @@ -1687,8 +1656,7 @@ class CodeGenerator extends Object js.statement('return $newKeyword #(#)', [visitConstructorName(redirect), params]) ..sourceInformation = _nodeStart(redirect) - ]), - returnType: returnType); + ])); } else { // Normal factory constructor var body = []; @@ -1697,16 +1665,13 @@ class CodeGenerator extends Object body.add(_visitStatement(node.body)); var params = _emitParameters(node.parameters?.parameters); - fun = JS.Fun(params, JS.Block(body), returnType: returnType); + fun = JS.Fun(params, JS.Block(body)); } _currentFunction = savedFunction; - return closureAnnotate( - JS.Method(name, fun, isStatic: true) - ..sourceInformation = _functionEnd(node), - element, - node); + return JS.Method(name, fun, isStatic: true) + ..sourceInformation = _functionEnd(node); } /// Given a class C that implements method M from interface I, but does not @@ -1784,7 +1749,7 @@ class CodeGenerator extends Object return JS.Method( _declareMemberName(method, useExtension: _extensionTypes.isNativeClass(type.element)), - JS.Fun(fnArgs, fnBlock, typeParams: typeParams), + JS.Fun(fnArgs, fnBlock), isGetter: method is PropertyAccessorElement && method.isGetter, isSetter: method is PropertyAccessorElement && method.isSetter, isStatic: false); @@ -2630,14 +2595,11 @@ class CodeGenerator extends Object fn = _emitFunction(node.element, node.parameters, node.body); } - return closureAnnotate( - JS.Method(_declareMemberName(node.element), fn, - isGetter: node.isGetter, - isSetter: node.isSetter, - isStatic: node.isStatic) - ..sourceInformation = _functionEnd(node), - node.element, - node); + return JS.Method(_declareMemberName(node.element), fn, + isGetter: node.isGetter, + isSetter: node.isSetter, + isStatic: node.isStatic) + ..sourceInformation = _functionEnd(node); } @override @@ -2683,8 +2645,7 @@ class CodeGenerator extends Object var element = resolutionMap.elementDeclaredByFunctionDeclaration(node); var nameExpr = _emitTopLevelName(element); - body.add( - closureAnnotate(js.statement('# = #', [nameExpr, fn]), element, node)); + body.add(js.statement('# = #', [nameExpr, fn])); // Function types of top-level/static functions are only needed when // dart:mirrors is enabled. // TODO(jmesserly): do we even need this for mirrors, since statics are not @@ -2718,13 +2679,10 @@ class CodeGenerator extends Object JS.Method _emitTopLevelProperty(FunctionDeclaration node) { var name = node.name.name; - return closureAnnotate( - JS.Method(_propertyName(name), - _emitFunctionExpression(node.functionExpression), - isGetter: node.isGetter, isSetter: node.isSetter) - ..sourceInformation = _functionEnd(node), - node.element, - node); + return JS.Method( + _propertyName(name), _emitFunctionExpression(node.functionExpression), + isGetter: node.isGetter, isSetter: node.isSetter) + ..sourceInformation = _functionEnd(node); } bool _executesAtTopLevel(AstNode node) { @@ -2788,8 +2746,7 @@ class CodeGenerator extends Object // Convert `function(...) { ... }` to `(...) => ...` // This is for readability, but it also ensures correct `this` binding. - return JS.ArrowFun(f.params, body, - typeParams: f.typeParams, returnType: f.returnType); + return JS.ArrowFun(f.params, body); } /// Emits a non-arrow FunctionExpression node. @@ -2824,8 +2781,7 @@ class CodeGenerator extends Object ]); code = super.exitFunction(element.name, formals, code); - return JS.Fun(formals, code, - typeParams: typeFormals, returnType: emitTypeRef(type.returnType)); + return JS.Fun(formals, code); } JS.Block _emitFunctionBody(ExecutableElement element, @@ -2897,8 +2853,7 @@ class CodeGenerator extends Object // TODO(jmesserly): this will emit argument initializers (for default // values) inside the generator function body. Is that the best place? var jsBody = _emitFunctionBody(element, parameters, body); - var genFn = JS.Fun(jsParams, jsBody, - isGenerator: true, returnType: emitTypeRef(returnType)); + var genFn = JS.Fun(jsParams, jsBody, isGenerator: true); // Name the function if possible, to get better stack traces. var name = element.name; @@ -3132,9 +3087,8 @@ class CodeGenerator extends Object return JS.PropertyAccess(target, member); } - JS.Identifier _emitVariableDef(SimpleIdentifier id, {JS.TypeRef type}) { - return JS.Identifier(id.name, type: type) - ..sourceInformation = _nodeStart(id); + JS.Identifier _emitVariableDef(SimpleIdentifier id) { + return JS.Identifier(id.name)..sourceInformation = _nodeStart(id); } /// Returns `true` if the type name referred to by [node] is used in a @@ -3175,8 +3129,7 @@ class CodeGenerator extends Object element, () => JS.TemporaryId(element.name.substring(1))); } - var type = declaration ? emitTypeRef(element.type) : null; - return JS.Identifier(element.name, type: type); + return JS.Identifier(element.name); } List _parameterMetadata(FormalParameter p) => @@ -4272,8 +4225,7 @@ class CodeGenerator extends Object return null; } - var name = - _emitVariableDef(node.name, type: emitTypeRef(node.element.type)); + var name = _emitVariableDef(node.name); return JS.VariableInitialization( name, _visitInitializer(node.initializer, node.element)); } @@ -4300,13 +4252,10 @@ class CodeGenerator extends Object _isJSInvocation(init) || init is InstanceCreationExpression && isSdkInternalRuntime(init.staticElement.library)) { - moduleItems.add(closureAnnotate( - js.statement('# = #;', [ - _emitTopLevelName(field.element), - _visitInitializer(field.initializer, field.element) - ]), - field.element, - field)); + moduleItems.add(js.statement('# = #;', [ + _emitTopLevelName(field.element), + _visitInitializer(field.initializer, field.element) + ])); } else { lazyFields.add(field); } @@ -4332,41 +4281,24 @@ class CodeGenerator extends Object for (var node in fields) { var element = node.element; var access = emitFieldName(element); - accessors.add(closureAnnotate( - JS.Method( - access, - js.call('function() { return #; }', - _visitInitializer(node.initializer, element)) as JS.Fun, - isGetter: true) - ..sourceInformation = - _hoverComment(JS.PropertyAccess(objExpr, access), node.name), - _findAccessor(element, getter: true), - node)); + accessors.add(JS.Method( + access, + js.call('function() { return #; }', + _visitInitializer(node.initializer, element)) as JS.Fun, + isGetter: true) + ..sourceInformation = + _hoverComment(JS.PropertyAccess(objExpr, access), node.name)); // TODO(jmesserly): currently uses a dummy setter to indicate writable. if (!node.isFinal && !node.isConst) { - accessors.add(closureAnnotate( - JS.Method(access, js.call('function(_) {}') as JS.Fun, - isSetter: true), - _findAccessor(element, getter: false), - node)); + accessors.add(JS.Method(access, js.call('function(_) {}') as JS.Fun, + isSetter: true)); } } return runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]); } - PropertyAccessorElement _findAccessor(VariableElement element, - {bool getter}) { - var parent = element.enclosingElement; - if (parent is ClassElement) { - return getter - ? parent.getGetter(element.name) - : parent.getSetter(element.name); - } - return null; - } - JS.Expression _emitConstructorName(DartType type, String name) { return _emitJSInterop(type.element) ?? JS.PropertyAccess(_emitConstructorAccess(type), _constructorName(name)); @@ -6219,15 +6151,6 @@ class CodeGenerator extends Object () => JS.TemporaryId(jsLibraryName(_libraryRoot, library))); } - T closureAnnotate( - T node, Element element, AnnotatedNode original) { - if (options.closure) { - node.closureAnnotation = - closureAnnotationFor(node, original, element, namedArgumentTemp.name); - } - return node; - } - /// Return true if this is one of the methods/properties on all Dart Objects /// (toString, hashCode, noSuchMethod, runtimeType). /// diff --git a/pkg/dev_compiler/lib/src/analyzer/js_typeref_codegen.dart b/pkg/dev_compiler/lib/src/analyzer/js_typeref_codegen.dart deleted file mode 100644 index fd61c5ad4e3..00000000000 --- a/pkg/dev_compiler/lib/src/analyzer/js_typeref_codegen.dart +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer/dart/element/type.dart'; -import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; - -import '../js_ast/js_ast.dart' as JS; -import 'module_compiler.dart' show CompilerOptions; -import 'js_interop.dart'; - -/// Mixin with logic to generate [TypeRef]s out of [DartType]s. -abstract class JSTypeRefCodegen { - final _resolved = {}; - - // Mixin dependencies: - CompilerOptions get options; - TypeProvider get types; - LibraryElement get dartJSLibrary; - JS.Identifier get namedArgumentTemp; - JS.Identifier emitLibraryName(LibraryElement e); - - /// Finds the qualified path to the type. - JS.TypeRef _emitTopLevelTypeRef(DartType type) { - var e = type.element; - return JS.TypeRef.qualified([ - emitLibraryName(e.library), - JS.Identifier(getJSExportName(e) ?? e.name) - ]); - } - - JS.TypeRef emitTypeRef(DartType type) { - if (!options.closure) return null; - - return _resolved.putIfAbsent(type, () { - if (type == null) JS.TypeRef.unknown(); - // TODO(ochafik): Consider calling _loader.declareBeforeUse(type.element). - if (type.isBottom || type.isDynamic) JS.TypeRef.any(); - if (type.isVoid) return JS.TypeRef.void_(); - - if (type == types.intType) return JS.TypeRef.number().orNull(); - if (type == types.numType) return JS.TypeRef.number().orNull(); - if (type == types.doubleType) return JS.TypeRef.number().orNull(); - if (type == types.boolType) return JS.TypeRef.boolean().orNull(); - if (type == types.stringType) return JS.TypeRef.string(); - - if (type is TypeParameterType) return JS.TypeRef.named(type.name); - if (type is ParameterizedType) { - JS.TypeRef rawType; - if (type is FunctionType && type.name == null) { - var args = {}; - for (var param in type.parameters) { - if (param.isNamed) break; - var type = emitTypeRef(param.type); - args[JS.Identifier(param.name)] = - param.isPositional ? type.toOptional() : type; - } - var namedParamType = emitNamedParamsArgType(type.parameters); - if (namedParamType != null) { - args[namedArgumentTemp] = namedParamType.toOptional(); - } - - rawType = JS.TypeRef.function(emitTypeRef(type.returnType), args); - } else { - var jsTypeRef = _getDartJsTypeRef(type); - if (jsTypeRef != null) return jsTypeRef; - - rawType = _emitTopLevelTypeRef(type); - } - var typeArgs = _getOwnTypeArguments(type).map(emitTypeRef); - return typeArgs.isEmpty - ? rawType - : JS.TypeRef.generic(rawType, typeArgs); - } - return JS.TypeRef.unknown(); - }); - } - - JS.TypeRef emitNamedParamsArgType(Iterable params) { - if (!options.closure) return null; - - var namedArgs = {}; - for (ParameterElement param in params) { - if (param.isPositional) continue; - namedArgs[JS.Identifier(param.name)] = - emitTypeRef(param.type).toOptional(); - } - if (namedArgs.isEmpty) return null; - return JS.TypeRef.record(namedArgs); - } - - /// Gets the "own" type arguments of [type]. - /// - /// Method argument with adhoc unnamed [FunctionType] inherit any type params - /// from their enclosing class: - /// - /// class Foo { - /// void method(f()); // f has [T] as type arguments, - /// } // but [] as its "own" type arguments. - Iterable _getOwnTypeArguments(ParameterizedType type) sync* { - for (int i = 0, n = type.typeParameters.length; i < n; i++) { - if (type.typeParameters[i].enclosingElement == type.element) { - yield type.typeArguments[i]; - } - } - } - - /// Special treatment of types from dart:js - /// TODO(ochafik): Is this the right thing to do? And what about package:js? - JS.TypeRef _getDartJsTypeRef(DartType type) { - if (type.element.library == dartJSLibrary) { - switch (type.name) { - case 'JsArray': - return JS.TypeRef.array( - type is InterfaceType && type.typeArguments.length == 1 - ? emitTypeRef(type.typeArguments.single) - : null); - case 'JsObject': - return JS.TypeRef.object(); - case 'JsFunction': - return JS.TypeRef.function(); - } - } - return null; - } -} diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart index 676b7210ee1..74fea7986ac 100644 --- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart +++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart @@ -6,8 +6,7 @@ import 'dart:collection' show HashSet, Queue; import 'dart:convert' show json; import 'dart:io' show File; -import 'package:analyzer/analyzer.dart' - show AnalysisError, CompilationUnit, ErrorSeverity; +import 'package:analyzer/analyzer.dart' show AnalysisError, CompilationUnit; import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/dart/element/element.dart' show LibraryElement, UriReferencedElement; @@ -16,7 +15,6 @@ import 'package:analyzer/file_system/physical_file_system.dart' show PhysicalResourceProvider; import 'package:analyzer/src/context/builder.dart' show ContextBuilder; import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl; -import 'package:analyzer/src/error/codes.dart' show StaticTypeWarningCode; import 'package:analyzer/src/generated/engine.dart' show AnalysisContext, AnalysisEngine; import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager; @@ -129,21 +127,6 @@ class ModuleCompiler { return ModuleCompiler._(context, summaryData); } - bool _isFatalError(AnalysisError e, CompilerOptions options) { - if (errorSeverity(context, e) != ErrorSeverity.ERROR) return false; - - // These errors are not fatal in the REPL compile mode as we - // allow access to private members across library boundaries - // and those accesses will show up as undefined members unless - // additional analyzer changes are made to support them. - // TODO(jacobr): consider checking that the identifier name - // referenced by the error is private. - return !options.replCompile || - (e.errorCode != StaticTypeWarningCode.UNDEFINED_GETTER && - e.errorCode != StaticTypeWarningCode.UNDEFINED_SETTER && - e.errorCode != StaticTypeWarningCode.UNDEFINED_METHOD); - } - /// Compiles a single Dart build unit into a JavaScript module. /// /// *Warning* - this may require resolving the entire world. @@ -263,9 +246,6 @@ class CompilerOptions { /// to private members across library boundaries. final bool replCompile; - /// Whether to emit Closure Compiler-friendly code. - final bool closure; - /// Mapping from absolute file paths to bazel short path to substitute in /// source maps. final Map bazelMapping; @@ -284,7 +264,6 @@ class CompilerOptions { this.replCompile = false, this.emitMetadata = false, this.enableAsserts = true, - this.closure = false, this.bazelMapping = const {}, this.summaryOutPath}); @@ -298,7 +277,6 @@ class CompilerOptions { replCompile = args['repl-compile'] as bool, emitMetadata = args['emit-metadata'] as bool, enableAsserts = args['enable-asserts'] as bool, - closure = args['closure-experimental'] as bool, bazelMapping = _parseBazelMappings(args['bazel-mapping'] as List), summaryOutPath = args['summary-out'] as String; @@ -432,9 +410,7 @@ class JSModuleFile { JSModuleCode getCode(ModuleFormat format, String jsUrl, String mapUrl, {bool singleOutFile = false}) { var opts = JS.JavaScriptPrintingOptions( - emitTypes: options.closure, - allowKeywordsInProperties: true, - allowSingleLineIfStatements: true); + allowKeywordsInProperties: true, allowSingleLineIfStatements: true); JS.SimpleJavaScriptPrintingContext printer; SourceMapBuilder sourceMap; if (options.sourceMap) { diff --git a/pkg/dev_compiler/lib/src/closure/closure_annotation.dart b/pkg/dev_compiler/lib/src/closure/closure_annotation.dart deleted file mode 100644 index 7274d6545dd..00000000000 --- a/pkg/dev_compiler/lib/src/closure/closure_annotation.dart +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import '../js_ast/js_ast.dart' as JS show TypeRef, ClosureTypePrinter; - -/// Set of closure annotations that can be [toString]ed to a single JsDoc comment. -/// See https://developers.google.com/closure/compiler/docs/js-for-compiler -/// -/// TODO(ochafik): Support inclusion of 'normal' comments (including @param comments). -class ClosureAnnotation { - final String comment; - final bool isConst; - final bool isConstructor; - final bool isFinal; - final bool isNoCollapse; - final bool isNoSideEffects; - final bool isOverride; - final bool isPrivate; - final bool isProtected; - final bool isStruct; - final bool isTypedef; - final JS.TypeRef lendsToType; - final JS.TypeRef returnType; - final JS.TypeRef superType; - final JS.TypeRef thisType; - final JS.TypeRef throwsType; - final JS.TypeRef type; - final List interfaces; - final List templates; - final Map paramTypes; - - ClosureAnnotation( - {this.comment, - this.interfaces = const [], - this.isConst = false, - this.isConstructor = false, - this.isFinal = false, - this.isNoCollapse = false, - this.isNoSideEffects = false, - this.isOverride = false, - this.isPrivate = false, - this.isProtected = false, - this.isStruct = false, - this.isTypedef = false, - this.lendsToType, - this.paramTypes = const {}, - this.returnType, - this.superType, - this.templates = const [], - this.thisType, - this.throwsType, - this.type}); - - @override - int get hashCode => _cachedString.hashCode; - - @override - bool operator ==(other) => - other is ClosureAnnotation && _cachedString == other._cachedString; - - @override - String toString([String indent = '']) => - _cachedString.replaceAll('\n', '\n$indent'); - - String _print(JS.TypeRef t) => (JS.ClosureTypePrinter()..visit(t)).toString(); - - String __cachedString; - String get _cachedString { - if (__cachedString == null) { - bool isNonWildcard(JS.TypeRef t) => t != null && !t.isAny && !t.isUnknown; - - var lines = []; - if (comment != null) lines.addAll(comment.split('\n')); - if (templates != null && templates.isNotEmpty) { - lines.add('@template ${templates.join(', ')}'); - } - if (thisType != null) lines.add('@this {${_print(thisType)}}'); - if (isOverride) lines.add('@override'); - if (isNoSideEffects) lines.add('@nosideeffects'); - if (isNoCollapse) lines.add('@nocollapse'); - if (lendsToType != null) lines.add('@lends {${_print(lendsToType)}}'); - - { - var typeHolders = []; - if (isPrivate) typeHolders.add('@private'); - if (isProtected) typeHolders.add('@protected'); - if (isFinal) typeHolders.add('@final'); - if (isConst) typeHolders.add('@const'); - if (isTypedef) typeHolders.add('@typedef'); - if (isNonWildcard(type)) { - if (typeHolders.isEmpty) typeHolders.add('@type'); - typeHolders.add('{${_print(type)}}'); - } - if (!typeHolders.isEmpty) lines.add(typeHolders.join(' ')); - } - - { - List constructorLine = []; - if (isConstructor) constructorLine.add('@constructor'); - if (isStruct) constructorLine.add('@struct'); - if (isNonWildcard(superType)) { - constructorLine.add('@extends {${_print(superType)}}'); - } - - if (constructorLine.isNotEmpty) lines.add(constructorLine.join(' ')); - } - - if (interfaces != null) { - for (var interface in interfaces) { - if (isNonWildcard(interface)) - lines.add('@implements {${_print(interface)}}'); - } - } - - if (paramTypes != null) { - paramTypes.forEach((String paramName, JS.TypeRef paramType) { - // Must output params even with wildcard type. - lines.add('@param {${_print(paramType)}} $paramName'); - }); - } - if (isNonWildcard(returnType)) - lines.add('@return {${_print(returnType)}}'); - if (isNonWildcard(throwsType)) - lines.add('@throws {${_print(throwsType)}}'); - - if (lines.length == 0) return ''; - if (lines.length == 1) return '/** ${lines.single} */'; - __cachedString = '/**\n' + lines.map((l) => ' * $l').join('\n') + '\n */'; - } - return __cachedString; - } -} diff --git a/pkg/dev_compiler/lib/src/closure/closure_annotator.dart b/pkg/dev_compiler/lib/src/closure/closure_annotator.dart deleted file mode 100644 index 133aae2263b..00000000000 --- a/pkg/dev_compiler/lib/src/closure/closure_annotator.dart +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer/dart/element/type.dart'; -import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; - -import '../js_ast/js_ast.dart' as JS show Node, TypeRef; - -import 'closure_annotation.dart'; - -/// Mixin that can generate [ClosureAnnotation]s for Dart elements and types. -abstract class ClosureAnnotator { - TypeProvider get types; - - JS.TypeRef emitTypeRef(DartType type); - - // TODO(ochafik): Handle destructured params when Closure supports it. - ClosureAnnotation closureAnnotationFor(JS.Node node, AnnotatedNode original, - Element e, String namedArgsMapName) { - // Note: Dart and Closure privacy are not compatible: don't set `isPrivate: e.isPrivate`. - return ClosureAnnotation( - comment: original?.documentationComment?.toSource(), - // Note: we don't set isConst here because Closure's constness and - // Dart's are not really compatible. - isFinal: e is VariableElement && (e.isFinal || e.isConst), - type: e is VariableElement - ? emitTypeRef(e.type /*, forceTypeDefExpansion: true*/) - : null, - superType: e is ClassElement ? emitTypeRef(e.supertype) : null, - interfaces: - e is ClassElement ? e.interfaces.map(emitTypeRef).toList() : null, - isOverride: e.isOverride, - isTypedef: e is FunctionTypeAliasElement); - } -} diff --git a/pkg/dev_compiler/lib/src/closure/closure_type.dart b/pkg/dev_compiler/lib/src/closure/closure_type.dart deleted file mode 100644 index bc29be0d913..00000000000 --- a/pkg/dev_compiler/lib/src/closure/closure_type.dart +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -/// Poor-man's representation of a Closure type. -/// See https://developers.google.com/closure/compiler/docs/js-for-compiler -/// -/// The goal here is not to completely support Closure's type system, but to -/// be able to generate just the types needed for DDC's JS output. -/// -/// TODO(ochafik): Consider convergence with TypeScript, which has no nullability-awareness -/// (see http://www.typescriptlang.org/Handbook). -class ClosureType { - static const ClosureType _ALL = ClosureType._("*"); - static const ClosureType _UNKNOWN = ClosureType._("?"); - - final String _representation; - final bool isNullable; - - const ClosureType._(this._representation, {this.isNullable = true}); - - bool get isAll => _representation == "*"; - bool get isUnknown => _representation == "?"; - - @override - toString() => _representation; - - factory ClosureType.all() => _ALL; - factory ClosureType.unknown() => _UNKNOWN; - - factory ClosureType.record(Map fieldTypes) { - var entries = []; - fieldTypes.forEach((n, t) => entries.add('$n: $t')); - return ClosureType._('{${entries.join(', ')}}'); - } - factory ClosureType.function( - [List paramTypes, ClosureType returnType]) { - if (paramTypes == null && returnType == null) { - return ClosureType.type("Function"); - } - var suffix = returnType == null ? '' : ':$returnType'; - return ClosureType._( - 'function(${paramTypes == null ? '...*' : paramTypes.join(', ')})$suffix'); - } - - factory ClosureType.map([ClosureType keyType, ClosureType valueType]) => - ClosureType._("Object<${keyType ?? _ALL}, ${valueType ?? _ALL}>"); - - factory ClosureType.type([String className = "Object"]) => - ClosureType._(className); - - factory ClosureType.array([ClosureType componentType]) => - ClosureType._("Array<${componentType ?? _ALL}>"); - - factory ClosureType.undefined() => - ClosureType._("undefined", isNullable: false); - factory ClosureType.number() => ClosureType._("number", isNullable: false); - factory ClosureType.boolean() => ClosureType._("boolean", isNullable: false); - factory ClosureType.string() => ClosureType._("string"); - - ClosureType toOptional() => ClosureType._("$this="); - - ClosureType toNullable() => isNullable - ? this - : ClosureType._( - _representation.startsWith('!') - ? _representation.substring(1) - : "?$this", - isNullable: true); - - ClosureType toNonNullable() => !isNullable - ? this - : ClosureType._( - _representation.startsWith('?') - ? _representation.substring(1) - : "!$this", - isNullable: false); - - /// TODO(ochafik): See which optimizations make sense here (it could be that `(*|undefined)` - /// cannot be optimized to `*` when used to model optional record fields). - ClosureType or(ClosureType other) => ClosureType._("($this|$other)", - isNullable: isNullable || other.isNullable); - - ClosureType orUndefined() => or(ClosureType.undefined()); -} diff --git a/pkg/dev_compiler/lib/src/compiler/js_utils.dart b/pkg/dev_compiler/lib/src/compiler/js_utils.dart index 76686c01be4..a0275c6a573 100644 --- a/pkg/dev_compiler/lib/src/compiler/js_utils.dart +++ b/pkg/dev_compiler/lib/src/compiler/js_utils.dart @@ -17,8 +17,7 @@ Fun simplifyPassThroughArrowFunCallBody(Fun fn) { innerFun.params.isEmpty) { var body = innerFun.body; if (body is Block) { - return Fun(fn.params, body, - typeParams: fn.typeParams, returnType: fn.returnType); + return Fun(fn.params, body); } } } diff --git a/pkg/dev_compiler/lib/src/js_ast/js_ast.dart b/pkg/dev_compiler/lib/src/js_ast/js_ast.dart index 21eadd34b8e..ee8289ecf2d 100644 --- a/pkg/dev_compiler/lib/src/js_ast/js_ast.dart +++ b/pkg/dev_compiler/lib/src/js_ast/js_ast.dart @@ -6,11 +6,8 @@ library js_ast; import 'precedence.dart'; import 'characters.dart' as charCodes; -import '../closure/closure_annotation.dart'; part 'nodes.dart'; part 'builder.dart'; -part 'js_types.dart'; part 'printer.dart'; part 'template.dart'; -part 'type_printer.dart'; diff --git a/pkg/dev_compiler/lib/src/js_ast/js_types.dart b/pkg/dev_compiler/lib/src/js_ast/js_types.dart deleted file mode 100644 index e45c96c2ad7..00000000000 --- a/pkg/dev_compiler/lib/src/js_ast/js_types.dart +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2016, 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. - -part of js_ast; - -final _any = AnyTypeRef._(); -final _unknown = UnknownTypeRef._(); -final _null = NullTypeRef(); - -/// JavaScript type reference, designed to support a subset of the type systems -/// of the Closure Compiler and TypeScript: -/// - https://developers.google.com/closure/compiler/docs/js-for-compiler#types -/// - https://github.com/Microsoft/TypeScript/blob/v1.8.0-beta/doc/spec.md#3 -/// -/// Note that some subtleties like "nullability" or "optionality" are handled -/// using unions (with a [NullTypeRef] or with an "undefined" named typeref). -/// Also, primitives aren't modeled differently than named / qualified types, -/// as it brings little value for now. Primitive-specific type formatting is -/// handled by the type printers (for instance, the knowledge that -/// `number|null` is just `number` in TypeScript, and is `number?` in Closure). -abstract class TypeRef extends Expression { - int get precedenceLevel => PRIMARY; - - TypeRef(); - - factory TypeRef.any() => _any; - - factory TypeRef.void_() => TypeRef.named('void'); - - factory TypeRef.unknown() => _unknown; - - factory TypeRef.generic(TypeRef rawType, Iterable typeArgs) { - if (typeArgs.isEmpty) { - throw ArgumentError.value(typeArgs, "typeArgs", "is empty"); - } - return GenericTypeRef(rawType, typeArgs.toList()); - } - - factory TypeRef.array([TypeRef elementType]) => ArrayTypeRef(elementType); - - factory TypeRef.object([TypeRef keyType, TypeRef valueType]) { - // TODO(ochafik): Roll out a dedicated ObjectTypeRef? - var rawType = TypeRef.named('Object'); - return keyType == null && valueType == null - ? rawType - : GenericTypeRef(rawType, [keyType ?? _any, valueType ?? _any]); - } - - factory TypeRef.function( - [TypeRef returnType, Map paramTypes]) => - FunctionTypeRef(returnType, paramTypes); - - factory TypeRef.record(Map types) => - RecordTypeRef(types); - - factory TypeRef.string() => TypeRef.named('string'); - - factory TypeRef.number() => TypeRef.named('number'); - - factory TypeRef.undefined() => TypeRef.named('undefined'); - - factory TypeRef.boolean() => TypeRef.named('boolean'); - - factory TypeRef.qualified(List path) => QualifiedTypeRef(path); - - factory TypeRef.named(String name) => - TypeRef.qualified([Identifier(name)]); - - bool get isAny => this is AnyTypeRef; - bool get isUnknown => this is UnknownTypeRef; - bool get isNull => this is NullTypeRef; - - TypeRef or(TypeRef other) => UnionTypeRef([this, other]); - - TypeRef orUndefined() => or(TypeRef.undefined()); - TypeRef orNull() => or(_null); - - TypeRef toOptional() => OptionalTypeRef(this); -} - -class AnyTypeRef extends TypeRef { - AnyTypeRef._() : super(); - - factory AnyTypeRef() => _any; - T accept(NodeVisitor visitor) => visitor.visitAnyTypeRef(this); - void visitChildren(NodeVisitor visitor) {} - _clone() => AnyTypeRef(); -} - -class NullTypeRef extends QualifiedTypeRef { - NullTypeRef() : super([Identifier("null")]); - _clone() => NullTypeRef(); -} - -class UnknownTypeRef extends TypeRef { - UnknownTypeRef._() : super(); - - factory UnknownTypeRef() => _unknown; - T accept(NodeVisitor visitor) => visitor.visitUnknownTypeRef(this); - void visitChildren(NodeVisitor visitor) {} - _clone() => UnknownTypeRef(); -} - -class QualifiedTypeRef extends TypeRef { - final List path; - QualifiedTypeRef(this.path); - - T accept(NodeVisitor visitor) => visitor.visitQualifiedTypeRef(this); - void visitChildren(NodeVisitor visitor) => - path.forEach((p) => p.accept(visitor)); - _clone() => QualifiedTypeRef(path); -} - -class ArrayTypeRef extends TypeRef { - final TypeRef elementType; - ArrayTypeRef(this.elementType); - T accept(NodeVisitor visitor) => visitor.visitArrayTypeRef(this); - void visitChildren(NodeVisitor visitor) { - elementType.accept(visitor); - } - - _clone() => ArrayTypeRef(elementType); -} - -class GenericTypeRef extends TypeRef { - final TypeRef rawType; - final List typeArgs; - GenericTypeRef(this.rawType, this.typeArgs); - - T accept(NodeVisitor visitor) => visitor.visitGenericTypeRef(this); - void visitChildren(NodeVisitor visitor) { - rawType.accept(visitor); - typeArgs.forEach((p) => p.accept(visitor)); - } - - _clone() => GenericTypeRef(rawType, typeArgs); -} - -class UnionTypeRef extends TypeRef { - final List types; - UnionTypeRef(this.types); - - T accept(NodeVisitor visitor) => visitor.visitUnionTypeRef(this); - void visitChildren(NodeVisitor visitor) { - types.forEach((p) => p.accept(visitor)); - } - - _clone() => UnionTypeRef(types); - - @override - TypeRef or(TypeRef other) { - if (types.contains(other)) return this; - return UnionTypeRef([] - ..addAll(types) - ..add(other)); - } -} - -class OptionalTypeRef extends TypeRef { - final TypeRef type; - OptionalTypeRef(this.type); - - T accept(NodeVisitor visitor) => visitor.visitOptionalTypeRef(this); - void visitChildren(NodeVisitor visitor) { - type.accept(visitor); - } - - _clone() => OptionalTypeRef(type); - - @override - TypeRef orUndefined() => this; -} - -class RecordTypeRef extends TypeRef { - final Map types; - RecordTypeRef(this.types); - - T accept(NodeVisitor visitor) => visitor.visitRecordTypeRef(this); - void visitChildren(NodeVisitor visitor) { - types.values.forEach((p) => p.accept(visitor)); - } - - _clone() => RecordTypeRef(types); -} - -class FunctionTypeRef extends TypeRef { - final TypeRef returnType; - final Map paramTypes; - FunctionTypeRef(this.returnType, this.paramTypes); - - T accept(NodeVisitor visitor) => visitor.visitFunctionTypeRef(this); - void visitChildren(NodeVisitor visitor) { - returnType.accept(visitor); - paramTypes.forEach((n, t) { - n.accept(visitor); - t.accept(visitor); - }); - } - - _clone() => FunctionTypeRef(returnType, paramTypes); -} diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart index 2af42b14acf..810bedf8ee0 100644 --- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart +++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart @@ -4,7 +4,7 @@ part of js_ast; -abstract class NodeVisitor implements TypeRefVisitor { +abstract class NodeVisitor { T visitProgram(Program node); T visitBlock(Block node); @@ -95,18 +95,6 @@ abstract class NodeVisitor implements TypeRefVisitor { T visitSimpleBindingPattern(SimpleBindingPattern node); } -abstract class TypeRefVisitor { - T visitQualifiedTypeRef(QualifiedTypeRef node); - T visitGenericTypeRef(GenericTypeRef node); - T visitUnionTypeRef(UnionTypeRef node); - T visitRecordTypeRef(RecordTypeRef node); - T visitOptionalTypeRef(OptionalTypeRef node); - T visitFunctionTypeRef(FunctionTypeRef node); - T visitAnyTypeRef(AnyTypeRef node); - T visitUnknownTypeRef(UnknownTypeRef node); - T visitArrayTypeRef(ArrayTypeRef node); -} - class BaseVisitor implements NodeVisitor { T visitNode(Node node) { node.visitChildren(this); @@ -229,17 +217,6 @@ class BaseVisitor implements NodeVisitor { visitBindingPattern(node); T visitDestructuredVariable(DestructuredVariable node) => visitNode(node); T visitSimpleBindingPattern(SimpleBindingPattern node) => visitNode(node); - - T visitTypeRef(TypeRef node) => visitNode(node); - T visitQualifiedTypeRef(QualifiedTypeRef node) => visitTypeRef(node); - T visitGenericTypeRef(GenericTypeRef node) => visitTypeRef(node); - T visitOptionalTypeRef(OptionalTypeRef node) => visitTypeRef(node); - T visitRecordTypeRef(RecordTypeRef node) => visitTypeRef(node); - T visitUnionTypeRef(UnionTypeRef node) => visitTypeRef(node); - T visitFunctionTypeRef(FunctionTypeRef node) => visitTypeRef(node); - T visitAnyTypeRef(AnyTypeRef node) => visitTypeRef(node); - T visitUnknownTypeRef(UnknownTypeRef node) => visitTypeRef(node); - T visitArrayTypeRef(ArrayTypeRef node) => visitTypeRef(node); } abstract class Node { @@ -247,9 +224,6 @@ abstract class Node { /// setting this after construction. Object sourceInformation; - /// Closure annotation of this node. - ClosureAnnotation closureAnnotation; - T accept(NodeVisitor visitor); void visitChildren(NodeVisitor visitor); @@ -892,13 +866,9 @@ class DestructuredVariable extends Expression implements Parameter { final BindingPattern structure; final Expression defaultValue; - final TypeRef type; + DestructuredVariable( - {this.name, - this.property, - this.structure, - this.defaultValue, - this.type}) { + {this.name, this.property, this.structure, this.defaultValue}) { assert(name != null || structure != null); } @@ -1177,16 +1147,13 @@ class Postfix extends Expression { int get precedenceLevel => UNARY; } -abstract class Parameter implements Expression, VariableBinding { - TypeRef get type; -} +abstract class Parameter implements Expression, VariableBinding {} class Identifier extends Expression implements Parameter { final String name; final bool allowRename; - final TypeRef type; - Identifier(this.name, {this.allowRename = true, this.type}) { + Identifier(this.name, {this.allowRename = true}) { if (!_identifierRE.hasMatch(name)) { throw ArgumentError.value(name, "name", "not a valid identifier"); } @@ -1204,7 +1171,6 @@ class Identifier extends Expression implements Parameter { // This is an expression for convenience in the AST. class RestParameter extends Expression implements Parameter { final Identifier parameter; - TypeRef get type => null; RestParameter(this.parameter); @@ -1278,24 +1244,13 @@ class NamedFunction extends Expression { } abstract class FunctionExpression extends Expression { + Node get body; // Expression or block List get params; - - get body; // Expression or block - /// Type parameters passed to this generic function, if any. `null` otherwise. - // TODO(ochafik): Support type bounds. - List get typeParams; - - /// Return type of this function, if any. `null` otherwise. - TypeRef get returnType; } class Fun extends FunctionExpression { final List params; final Block body; - @override - final List typeParams; - @override - final TypeRef returnType; /** Whether this is a JS generator (`function*`) that may contain `yield`. */ final bool isGenerator; @@ -1304,9 +1259,7 @@ class Fun extends FunctionExpression { Fun(this.params, this.body, {this.isGenerator = false, - this.asyncModifier = const AsyncModifier.sync(), - this.typeParams, - this.returnType}); + this.asyncModifier = const AsyncModifier.sync()}); T accept(NodeVisitor visitor) => visitor.visitFun(this); @@ -1324,12 +1277,8 @@ class Fun extends FunctionExpression { class ArrowFun extends FunctionExpression { final List params; final body; // Expression or Block - @override - final List typeParams; - @override - final TypeRef returnType; - ArrowFun(this.params, this.body, {this.typeParams, this.returnType}); + ArrowFun(this.params, this.body); T accept(NodeVisitor visitor) => visitor.visitArrowFun(this); @@ -1627,15 +1576,7 @@ class ClassExpression extends Expression { final Expression heritage; // Can be null. final List methods; - /// Type parameters of this class, if any. `null` otherwise. - // TODO(ochafik): Support type bounds. - final List typeParams; - - /// Field declarations of this class (TypeScript / ES6_TYPED). - final List fields; - - ClassExpression(this.name, this.heritage, this.methods, - {this.typeParams, this.fields}); + ClassExpression(this.name, this.heritage, this.methods); T accept(NodeVisitor visitor) => visitor.visitClassExpression(this); @@ -1643,23 +1584,12 @@ class ClassExpression extends Expression { name.accept(visitor); if (heritage != null) heritage.accept(visitor); for (Method element in methods) element.accept(visitor); - if (fields != null) { - for (var field in fields) { - field.accept(visitor); - } - } - if (typeParams != null) { - for (var typeParam in typeParams) { - typeParam.accept(visitor); - } - } } @override ClassDeclaration toStatement() => ClassDeclaration(this); - ClassExpression _clone() => ClassExpression(name, heritage, methods, - typeParams: typeParams, fields: fields); + ClassExpression _clone() => ClassExpression(name, heritage, methods); int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; } @@ -1726,7 +1656,6 @@ class InterpolatedParameter extends Expression with InterpolatedNode implements Identifier { final nameOrPosition; - TypeRef get type => null; String get name { throw "InterpolatedParameter.name must not be invoked"; @@ -1797,7 +1726,6 @@ class InterpolatedIdentifier extends Expression with InterpolatedNode implements Identifier { final nameOrPosition; - TypeRef get type => null; InterpolatedIdentifier(this.nameOrPosition); diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart index da7274518a1..a85c3867e52 100644 --- a/pkg/dev_compiler/lib/src/js_ast/printer.dart +++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart @@ -8,7 +8,6 @@ class JavaScriptPrintingOptions { final bool shouldCompressOutput; final bool minifyLocalVariables; final bool preferSemicolonToNewlineInMinifiedOutput; - final bool emitTypes; final bool allowSingleLineIfStatements; /// True to allow keywords in properties, such as `obj.var` or `obj.function` @@ -19,7 +18,6 @@ class JavaScriptPrintingOptions { {this.shouldCompressOutput = false, this.minifyLocalVariables = false, this.preferSemicolonToNewlineInMinifiedOutput = false, - this.emitTypes = false, this.allowKeywordsInProperties = false, this.allowSingleLineIfStatements = false}); } @@ -58,7 +56,7 @@ class SimpleJavaScriptPrintingContext extends JavaScriptPrintingContext { // TODO(ochafik): Inline the body of [TypeScriptTypePrinter] here if/when it no // longer needs to share utils with [ClosureTypePrinter]. -class Printer extends TypeScriptTypePrinter implements NodeVisitor { +class Printer implements NodeVisitor { final JavaScriptPrintingOptions options; final JavaScriptPrintingContext context; final bool shouldCompressOutput; @@ -296,7 +294,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { visitExpressionStatement(ExpressionStatement expressionStatement) { indent(); - outClosureAnnotation(expressionStatement); visitNestedExpression(expressionStatement.expression, EXPRESSION, newInForInit: false, newAtStatementBegin: true); outSemicolonLn(); @@ -558,14 +555,12 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { newInForInit: false, newAtStatementBegin: false); } localNamer.enterScope(fun); - outTypeParams(fun.typeParams); out("("); if (fun.params != null) { visitCommaSeparated(fun.params, PRIMARY, newInForInit: false, newAtStatementBegin: false); } out(")"); - outTypeAnnotation(fun.returnType); switch (fun.asyncModifier) { case const AsyncModifier.sync(): break; @@ -585,7 +580,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { visitFunctionDeclaration(FunctionDeclaration declaration) { indent(); - outClosureAnnotation(declaration); var f = declaration.function; context.enterNode(f); functionOut(f, declaration.name); @@ -623,7 +617,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { } visitVariableDeclarationList(VariableDeclarationList list) { - outClosureAnnotation(list); // Note: keyword can be null for non-static field declarations. if (list.keyword != null) { out(list.keyword); @@ -665,7 +658,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { } visit(structure); } - outTypeAnnotation(node.type); var defaultValue = node.defaultValue; if (defaultValue != null) { spaceOut(); @@ -695,7 +687,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { } visitVariableInitialization(VariableInitialization init) { - outClosureAnnotation(init); visitNestedExpression(init.declaration, LEFT_HAND_SIDE, newInForInit: inForInit, newAtStatementBegin: atStatementBegin); if (init.value != null) { @@ -898,7 +889,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { visitIdentifier(Identifier node) { out(localNamer.getName(node)); - outTypeAnnotation(node.type); } visitRestParameter(RestParameter node) { @@ -966,9 +956,7 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { visitArrowFun(ArrowFun fun) { localNamer.enterScope(fun); - if (fun.params.length == 1 && - fun.params[0] is Identifier && - (!options.emitTypes || fun.params[0].type == null)) { + if (fun.params.length == 1 && fun.params[0] is Identifier) { visitNestedExpression(fun.params.single, SPREAD, newInForInit: false, newAtStatementBegin: false); } else { @@ -977,7 +965,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { newInForInit: false, newAtStatementBegin: false); out(")"); } - outTypeAnnotation(fun.returnType); spaceOut(); out("=>"); var body = fun.body; @@ -1116,24 +1103,10 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { lineOut(); } - void outTypeParams(Iterable typeParams) { - if (typeParams != null && options.emitTypes && typeParams.isNotEmpty) { - out("<"); - var first = true; - for (var typeParam in typeParams) { - if (!first) out(", "); - first = false; - visit(typeParam); - } - out(">"); - } - } - visitClassExpression(ClassExpression node) { localNamer.enterScope(node); out('class '); visit(node.name); - outTypeParams(node.typeParams); if (node.heritage != null) { out(' extends '); visit(node.heritage); @@ -1143,14 +1116,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { out('{'); lineOut(); indentMore(); - if (options.emitTypes && node.fields != null) { - for (var field in node.fields) { - indent(); - visit(field); - out(";"); - lineOut(); - } - } for (var method in node.methods) { indent(); visit(method); @@ -1166,7 +1131,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { } visitMethod(Method node) { - outClosureAnnotation(node); if (node.isStatic) { out('static '); } @@ -1198,17 +1162,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { localNamer.leaveScope(); } - void outClosureAnnotation(Node node) { - if (node != null && node.closureAnnotation != null) { - String comment = node.closureAnnotation.toString(indentation); - if (comment.isNotEmpty) { - out(comment); - lineOut(); - indent(); - } - } - } - void propertyNameOut(Expression node, {bool inMethod = false, bool inAccess = false}) { if (node is LiteralNumber) { @@ -1404,18 +1357,6 @@ class Printer extends TypeScriptTypePrinter implements NodeVisitor { out("await "); visit(node.expression); } - - void outTypeAnnotation(TypeRef node) { - if (node == null || !options.emitTypes || node.isUnknown) return; - - if (node is OptionalTypeRef) { - out("?: "); - visit(node.type); - } else { - out(": "); - visit(node); - } - } } // Collects all the var declarations in the function. We need to do this in a diff --git a/pkg/dev_compiler/lib/src/js_ast/template.dart b/pkg/dev_compiler/lib/src/js_ast/template.dart index 6475446fbf1..178b15c661b 100644 --- a/pkg/dev_compiler/lib/src/js_ast/template.dart +++ b/pkg/dev_compiler/lib/src/js_ast/template.dart @@ -598,7 +598,7 @@ class InstantiatorGeneratorVisitor implements NodeVisitor { Instantiator visitArrowFun(ArrowFun node) { var paramMakers = node.params.map(visitSplayable).toList(); - Instantiator makeBody = visit(node.body as Node); + Instantiator makeBody = visit(node.body); return (a) => ArrowFun(splayNodes(paramMakers, a), makeBody(a)); } @@ -700,32 +700,6 @@ class InstantiatorGeneratorVisitor implements NodeVisitor { Instantiator visitExportClause(ExportClause node) => throw UnimplementedError(); - Instantiator visitAnyTypeRef(AnyTypeRef node) => throw UnimplementedError(); - - Instantiator visitUnknownTypeRef(UnknownTypeRef node) => - throw UnimplementedError(); - - Instantiator visitArrayTypeRef(ArrayTypeRef node) => - throw UnimplementedError(); - - Instantiator visitFunctionTypeRef(FunctionTypeRef node) => - throw UnimplementedError(); - - Instantiator visitGenericTypeRef(GenericTypeRef node) => - throw UnimplementedError(); - - Instantiator visitQualifiedTypeRef(QualifiedTypeRef node) => - throw UnimplementedError(); - - Instantiator visitOptionalTypeRef(OptionalTypeRef node) => - throw UnimplementedError(); - - Instantiator visitRecordTypeRef(RecordTypeRef node) => - throw UnimplementedError(); - - Instantiator visitUnionTypeRef(UnionTypeRef node) => - throw UnimplementedError(); - @override Instantiator visitDestructuredVariable( DestructuredVariable node) { diff --git a/pkg/dev_compiler/lib/src/js_ast/type_printer.dart b/pkg/dev_compiler/lib/src/js_ast/type_printer.dart deleted file mode 100644 index 512348257fa..00000000000 --- a/pkg/dev_compiler/lib/src/js_ast/type_printer.dart +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) 2016, 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. - -part of js_ast; - -abstract class _TypePrinterBase implements TypeRefVisitor { - void out(String s); - void visit(Node node); - - void outSeparated(String separator, Iterable items, - [action(T item)]) { - action ??= visit; - var first = true; - for (var item in items) { - if (first) { - first = false; - } else { - out(separator); - } - action(item); - } - } - - void outTypeArg(Iterable typeArgs) { - if (typeArgs.isNotEmpty) { - // TODO(ochafik): Double-check precedence issues when we start emitting - // type arguments outside type literals (generic method call, etc). - out('<'); - outSeparated(", ", typeArgs); - out('>'); - } - } - - @override - visitQualifiedTypeRef(QualifiedTypeRef node) { - outSeparated(".", node.path); - } -} - -abstract class TypeScriptTypePrinter extends _TypePrinterBase { - void _outTypeAnnotation(TypeRef type) { - if (type is OptionalTypeRef) { - out("?: "); - visit(type.type); - } else { - out(": "); - visit(type); - } - } - - @override - visitGenericTypeRef(GenericTypeRef node) { - if (node.rawType is FunctionTypeRef) { - outTypeArg(node.typeArgs); - visit(node.rawType); - } else { - visit(node.rawType); - outTypeArg(node.typeArgs); - } - } - - @override - visitArrayTypeRef(ArrayTypeRef node) { - if (node.elementType == null) { - out("Array"); - } else { - visit(node.elementType); - out("[]"); - } - } - - @override - visitOptionalTypeRef(OptionalTypeRef node) { - visit(node.type); - } - - @override - visitRecordTypeRef(RecordTypeRef node) { - out('{'); - outSeparated(", ", node.types.keys, (Identifier name) { - var type = node.types[name]; - visit(name); - _outTypeAnnotation(type); - }); - out('}'); - } - - @override - visitUnionTypeRef(UnionTypeRef node) { - outSeparated("|", node.types.where((t) => !t.isNull)); - } - - @override - visitFunctionTypeRef(FunctionTypeRef node) { - if (node.returnType == null) { - out('Function'); - } else { - out('('); - if (node.paramTypes == null) { - out('...any'); - } else { - outSeparated(", ", node.paramTypes.keys, (Identifier name) { - var paramType = node.paramTypes[name]; - visit(name); - _outTypeAnnotation(paramType); - }); - } - out(') => '); - visit(node.returnType); - } - } - - @override - visitAnyTypeRef(AnyTypeRef node) { - out("any"); - } - - @override - visitUnknownTypeRef(UnknownTypeRef node) { - out("any"); - } -} - -class ClosureTypePrinter extends _TypePrinterBase implements NodeVisitor { - final _buffer = StringBuffer(); - - @override - void out(String s) => _buffer.write(s); - - @override - void visit(Node node) => node.accept(this); - - noSuchMethod(Invocation i) => super.noSuchMethod(i); - - @override - visitGenericTypeRef(GenericTypeRef node) { - visit(node.rawType); - outTypeArg(node.typeArgs); - } - - @override - visitIdentifier(Identifier node) { - //out(localNamer.getName(node)); - out(node.name); - } - - @override - visitAccess(PropertyAccess node) { - var selector = node.selector; - if (selector is LiteralString) { - visit(node.receiver); - out("."); - out(selector.valueWithoutQuotes); - } else { - assert(false); - out("?"); - } - } - - @override - toString() => _buffer.toString(); - - @override - visitArrayTypeRef(ArrayTypeRef node) { - out("Array"); - if (node.elementType != null) { - out("<"); - visit(node.elementType); - out(">"); - } - } - - @override - visitOptionalTypeRef(OptionalTypeRef node) { - visit(node.type); - out("="); - } - - @override - visitRecordTypeRef(RecordTypeRef node) { - out('{'); - outSeparated(", ", node.types.keys, (Identifier name) { - var type = node.types[name]; - visit(name); - out(": "); - visit(type is OptionalTypeRef ? type.orUndefined() : type); - }); - out('}'); - } - - @override - visitAnyTypeRef(AnyTypeRef node) { - out("*"); - } - - @override - visitUnknownTypeRef(UnknownTypeRef node) { - out("?"); - } - - @override - visitUnionTypeRef(UnionTypeRef node) { - out("("); - outSeparated("|", node.types); - out(")"); - } - - @override - visitFunctionTypeRef(FunctionTypeRef node) { - if (node.returnType == null) { - out('Function'); - } else { - out('function('); - if (node.paramTypes == null) { - out("...*"); - } else { - outSeparated(", ", node.paramTypes.values); - } - out(')'); - if (node.returnType != null) { - out(":"); - visit(node.returnType); - } - } - } -} diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index 3d6f202cd73..d7d658e3ab5 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -4839,8 +4839,7 @@ class ProgramCompiler extends Object // Convert `function(...) { ... }` to `(...) => ...` // This is for readability, but it also ensures correct `this` binding. - return JS.ArrowFun(f.params, body, - typeParams: f.typeParams, returnType: f.returnType); + return JS.ArrowFun(f.params, body); } @override diff --git a/pkg/dev_compiler/test/closure/closure_annotation_test.dart b/pkg/dev_compiler/test/closure/closure_annotation_test.dart deleted file mode 100644 index e3347c68a3c..00000000000 --- a/pkg/dev_compiler/test/closure/closure_annotation_test.dart +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -library dev_compiler.test.closure_annotation_test; - -import 'package:test/test.dart'; - -import 'package:dev_compiler/src/closure/closure_annotation.dart'; -import 'package:dev_compiler/src/js_ast/js_ast.dart' show TypeRef, Identifier; - -void main() { - group('ClosureAnnotation', () { - var anyType = TypeRef.any(); - var unknownType = TypeRef.unknown(); - var numberType = TypeRef.number(); - var stringType = TypeRef.string(); - var booleanType = TypeRef.boolean(); - var fooType = TypeRef.qualified([Identifier("foo"), Identifier("Foo")]); - var barType = TypeRef.named("Bar"); - var bazType = TypeRef.named("Baz"); - var bamType = TypeRef.named("Bam"); - var batType = TypeRef.named("Bat"); - - test('gives empty comment when no has no meaningful info', () { - expect(ClosureAnnotation().toString(), ""); - expect(ClosureAnnotation(type: anyType).toString(), ""); - expect(ClosureAnnotation(type: unknownType).toString(), ""); - }); - - test('gives single line comment when it fits', () { - expect(ClosureAnnotation(type: numberType).toString(), - "/** @type {number} */"); - expect(ClosureAnnotation(paramTypes: {'foo': anyType}).toString(), - "/** @param {*} foo */"); - expect(ClosureAnnotation(paramTypes: {'foo': unknownType}).toString(), - "/** @param {?} foo */"); - }); - - test('gives multiple line comment when it it does not fit on one line', () { - expect( - ClosureAnnotation( - returnType: stringType, - paramTypes: {'foo': numberType}).toString(), - "/**\n" - " * @param {number} foo\n" - " * @return {string}\n" - " */"); - }); - - test('inserts indentation', () { - expect( - ClosureAnnotation( - returnType: stringType, - paramTypes: {'foo': numberType}).toString(" "), - "/**\n" // No indent on first line. - " * @param {number} foo\n" - " * @return {string}\n" - " */"); - }); - - test('compresses @type, @final, @const, @private, @protected, @typedef', - () { - expect(ClosureAnnotation(type: stringType).toString(), - "/** @type {string} */"); - expect(ClosureAnnotation(type: stringType, isConst: true).toString(), - "/** @const {string} */"); - expect(ClosureAnnotation(type: stringType, isFinal: true).toString(), - "/** @final {string} */"); - expect(ClosureAnnotation(type: stringType, isPrivate: true).toString(), - "/** @private {string} */"); - expect(ClosureAnnotation(type: stringType, isTypedef: true).toString(), - "/** @typedef {string} */"); - expect(ClosureAnnotation(type: stringType, isProtected: true).toString(), - "/** @protected {string} */"); - expect( - ClosureAnnotation( - type: stringType, - isPrivate: true, - isConst: true, - isFinal: true, - isProtected: true, - isTypedef: true) - .toString(), - "/** @private @protected @final @const @typedef {string} */"); - }); - - test('supports a full constructor annotation', () { - expect( - ClosureAnnotation( - returnType: booleanType, - throwsType: bamType, - thisType: fooType, - superType: barType, - lendsToType: batType, - interfaces: [bazType], - isStruct: true, - isPrivate: true, - isProtected: true, - isOverride: true, - isFinal: true, - isConst: true, - isConstructor: true, - isNoSideEffects: true, - isNoCollapse: true, - paramTypes: {'x': stringType, 'y': numberType}, - templates: ['A', 'B']).toString(), - '/**\n' - ' * @template A, B\n' - ' * @this {foo.Foo}\n' - ' * @override\n' - ' * @nosideeffects\n' - ' * @nocollapse\n' - ' * @lends {Bat}\n' - ' * @private @protected @final @const\n' - ' * @constructor @struct @extends {Bar}\n' - ' * @implements {Baz}\n' - ' * @param {string} x\n' - ' * @param {number} y\n' - ' * @return {boolean}\n' - ' * @throws {Bam}\n' - ' */'); - }); - }); -} diff --git a/pkg/dev_compiler/test/closure/closure_type_test.dart b/pkg/dev_compiler/test/closure/closure_type_test.dart deleted file mode 100644 index c8b7c6244cf..00000000000 --- a/pkg/dev_compiler/test/closure/closure_type_test.dart +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -library dev_compiler.test.closure_type_test; - -import 'package:test/test.dart'; - -import 'package:dev_compiler/src/closure/closure_type.dart'; - -void main() { - expectToString(ClosureType t, String s, - {String nullable, String nonNullable}) { - expect(t.toString(), s); - if (nullable != null) { - expect(t.toNullable().toString(), nullable); - } - if (nonNullable != null) { - expect(t.toNonNullable().toString(), nonNullable); - } - } - - group('ClosureType', () { - test('supports simple types', () { - expectToString(ClosureType.number(), "number", - nullable: "?number", nonNullable: "number"); - expectToString(ClosureType.boolean(), "boolean", - nullable: "?boolean", nonNullable: "boolean"); - expectToString(ClosureType.string(), "string", - nullable: "string", nonNullable: "!string"); - expectToString(ClosureType.type("foo.Bar"), "foo.Bar", - nullable: "foo.Bar", nonNullable: "!foo.Bar"); - }); - - test('supports array types', () { - expectToString(ClosureType.array(), "Array<*>", - nullable: "Array<*>", nonNullable: "!Array<*>"); - expectToString(ClosureType.array(ClosureType.type("Foo")), "Array", - nullable: "Array", nonNullable: "!Array"); - }); - - test('supports map types', () { - expectToString( - ClosureType.map(ClosureType.type("Foo"), ClosureType.type("Bar")), - "Object", - nullable: "Object", - nonNullable: "!Object"); - expectToString(ClosureType.map(), "Object<*, *>", - nullable: "Object<*, *>", nonNullable: "!Object<*, *>"); - }); - - test('supports function types', () { - expectToString(ClosureType.function(), "Function", - nullable: "Function", nonNullable: "!Function"); - expectToString( - ClosureType.function([ClosureType.number()]), "function(number)"); - expectToString(ClosureType.function(null, ClosureType.number()), - "function(...*):number"); - expectToString( - ClosureType.function([ClosureType.number(), ClosureType.string()], - ClosureType.boolean()), - "function(number, string):boolean"); - }); - - test('supports union types', () { - expectToString( - ClosureType.number().or(ClosureType.boolean()), "(number|boolean)"); - expectToString(ClosureType.number().orUndefined(), "(number|undefined)"); - }); - - test('supports record types', () { - expectToString( - ClosureType.record( - {'x': ClosureType.number(), 'y': ClosureType.boolean()}), - "{x: number, y: boolean}"); - }); - - test('supports optional pseudo-types', () { - expectToString(ClosureType.number().toOptional(), "number="); - }); - }); -}