Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: pkg/compiler/lib/src/js_backend/js_interop_analysis.dart

Issue 1409033005: Add @anonymous annotation and restrict object literal constructors to only anonymous classes. This … (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: ptal Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// Analysis to determine how to generate code for typed JavaScript interop. 5 /// Analysis to determine how to generate code for typed JavaScript interop.
6 library compiler.src.js_backend.js_interop_analysis; 6 library compiler.src.js_backend.js_interop_analysis;
7 7
8 import '../common/names.dart' show Identifiers; 8 import '../common/names.dart' show Identifiers;
9 import '../compiler.dart' show Compiler; 9 import '../compiler.dart' show Compiler;
10 import '../diagnostics/messages.dart' show MessageKind; 10 import '../diagnostics/messages.dart' show MessageKind;
11 import '../constants/values.dart' 11 import '../constants/values.dart'
12 show 12 show
13 ConstantValue, 13 ConstantValue,
14 ConstructedConstantValue, 14 ConstructedConstantValue,
15 ListConstantValue, 15 ListConstantValue,
16 NullConstantValue, 16 NullConstantValue,
17 StringConstantValue, 17 StringConstantValue,
18 TypeConstantValue; 18 TypeConstantValue;
19 import '../elements/elements.dart' 19 import '../elements/elements.dart'
20 show 20 show
21 ClassElement, 21 ClassElement,
22 Element, 22 Element,
23 FieldElement, 23 FieldElement,
24 FunctionElement, 24 FunctionElement,
25 LibraryElement, 25 LibraryElement,
26 ParameterElement,
26 MetadataAnnotation; 27 MetadataAnnotation;
27 28
28 import '../js/js.dart' as jsAst; 29 import '../js/js.dart' as jsAst;
29 import '../js/js.dart' show js; 30 import '../js/js.dart' show js;
30 import '../universe/selector.dart' show Selector; 31 import '../universe/selector.dart' show Selector;
31 import '../universe/universe.dart' show SelectorConstraints; 32 import '../universe/universe.dart' show SelectorConstraints;
32 33
33 import 'backend_helpers.dart' show BackendHelpers; 34 import 'backend_helpers.dart' show BackendHelpers;
34 import 'js_backend.dart' show JavaScriptBackend; 35 import 'js_backend.dart' show JavaScriptBackend;
35 36
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 } else { 77 } else {
77 // TODO(jacobr): report a warning if the value is not a String. 78 // TODO(jacobr): report a warning if the value is not a String.
78 backend.setJsInteropName(e, ''); 79 backend.setJsInteropName(e, '');
79 } 80 }
80 enabledJsInterop = true; 81 enabledJsInterop = true;
81 return; 82 return;
82 } 83 }
83 } 84 }
84 } 85 }
85 86
87 bool hasAnonymousAnnotation(Element element) {
88 if (backend.helpers.jsAnonymousClass == null) return false;
89 return element.metadata.any((MetadataAnnotation annotation) {
90 ConstantValue constant = backend.compiler.constants.getConstantValue(
91 annotation.constant);
92 if (constant == null ||
93 constant is! ConstructedConstantValue) return false;
94 ConstructedConstantValue constructedConstant = constant;
95 return constructedConstant.type.element ==
96 backend.helpers.jsAnonymousClass;
97 });
98 }
99
100 void _checkFunctionParameters(FunctionElement fn) {
101 if (fn.hasFunctionSignature &&
102 fn.functionSignature.optionalParametersAreNamed) {
103 backend.reporter.reportErrorMessage(fn,
104 MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS, {
105 'method': fn.name
106 });
107 }
108 }
109
86 void processJsInteropAnnotationsInLibrary(LibraryElement library) { 110 void processJsInteropAnnotationsInLibrary(LibraryElement library) {
87 processJsInteropAnnotation(library); 111 processJsInteropAnnotation(library);
88 library.implementation.forEachLocalMember((Element element) { 112 library.implementation.forEachLocalMember((Element element) {
89 processJsInteropAnnotation(element); 113 processJsInteropAnnotation(element);
90 if (!element.isClass || !backend.isJsInterop(element)) return; 114 if (!backend.isJsInterop(element)) return;
115 if (element is FunctionElement) {
116 _checkFunctionParameters(element);
117 }
118
119 if (!element.isClass) return;
91 120
92 ClassElement classElement = element; 121 ClassElement classElement = element;
93 122
94 if (!classElement 123 if (!classElement
95 .implementsInterface(helpers.jsJavaScriptObjectClass)) { 124 .implementsInterface(helpers.jsJavaScriptObjectClass)) {
96 backend.reporter.reportErrorMessage(classElement, 125 backend.reporter.reportErrorMessage(classElement,
97 MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS, { 126 MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS, {
98 'cls': classElement.name, 127 'cls': classElement.name,
99 'superclass': classElement.superclass.name 128 'superclass': classElement.superclass.name
100 }); 129 });
101 } 130 }
102 131
103 classElement.forEachMember( 132 classElement.forEachMember(
104 (ClassElement classElement, Element member) { 133 (ClassElement classElement, Element member) {
105 processJsInteropAnnotation(member); 134 processJsInteropAnnotation(member);
106 135
107 if (!member.isSynthesized && 136 if (!member.isSynthesized &&
108 backend.isJsInterop(classElement) && 137 backend.isJsInterop(classElement) &&
109 member is FunctionElement) { 138 member is FunctionElement) {
110 FunctionElement fn = member; 139 FunctionElement fn = member;
111 if (!fn.isExternal && !fn.isAbstract) { 140 if (!fn.isExternal && !fn.isAbstract && !fn.isConstructor &&
141 !fn.isStatic) {
112 backend.reporter.reportErrorMessage( 142 backend.reporter.reportErrorMessage(
113 fn, 143 fn,
114 MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER, 144 MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
115 {'cls': classElement.name, 'member': member.name}); 145 {'cls': classElement.name, 'member': member.name});
116 } 146 }
147
148 if (fn.isFactoryConstructor && hasAnonymousAnnotation(classElement)) {
149 fn.functionSignature.orderedForEachParameter(
150 (ParameterElement parameter) {
151 if (!parameter.isNamed) {
152 backend.reporter.reportErrorMessage(parameter,
153 MessageKind
154 .JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS ,
155 {
156 'parameter': parameter.name,
157 'cls': classElement.name
158 });
159 }
160 });
161 } else {
162 _checkFunctionParameters(fn);
163 }
117 } 164 }
118 }); 165 });
119 }); 166 });
120 } 167 }
121 168
122 jsAst.Statement buildJsInteropBootstrap() { 169 jsAst.Statement buildJsInteropBootstrap() {
123 if (!enabledJsInterop) return null; 170 if (!enabledJsInterop) return null;
124 List<jsAst.Statement> statements = <jsAst.Statement>[]; 171 List<jsAst.Statement> statements = <jsAst.Statement>[];
125 backend.compiler.codegenWorld.forEachInvokedName( 172 backend.compiler.codegenWorld.forEachInvokedName(
126 (String name, Map<Selector, SelectorConstraints> selectors) { 173 (String name, Map<Selector, SelectorConstraints> selectors) {
(...skipping 10 matching lines...) Expand all
137 var name = backend.namer.invocationName(selector); 184 var name = backend.namer.invocationName(selector);
138 statements.add(js.statement( 185 statements.add(js.statement(
139 'Function.prototype.# = function(#) { return this(#) }', 186 'Function.prototype.# = function(#) { return this(#) }',
140 [name, parameters, parameters])); 187 [name, parameters, parameters]));
141 } 188 }
142 }); 189 });
143 }); 190 });
144 return new jsAst.Block(statements); 191 return new jsAst.Block(statements);
145 } 192 }
146 } 193 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/backend_helpers.dart ('k') | pkg/compiler/lib/src/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698