Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 library dart2js.resolution_strategy; | |
|
Siggi Cherem (dart-lang)
2017/04/24 19:36:48
let's move this file under "resolution/"
Johnni Winther
2017/04/25 07:52:51
Done.
| |
| 6 | |
| 7 import 'common.dart'; | |
| 8 import 'common_elements.dart'; | |
| 9 import 'common/resolution.dart'; | |
| 10 import 'common/tasks.dart'; | |
| 11 import 'compiler.dart'; | |
| 12 import 'elements/elements.dart'; | |
| 13 import 'elements/entities.dart'; | |
| 14 import 'elements/resolution_types.dart'; | |
| 15 import 'environment.dart'; | |
| 16 import 'frontend_strategy.dart'; | |
| 17 import 'library_loader.dart'; | |
| 18 import 'native/resolver.dart'; | |
| 19 import 'js_backend/native_data.dart'; | |
| 20 import 'serialization/task.dart'; | |
| 21 import 'patch_parser.dart'; | |
| 22 import 'resolved_uri_translator.dart'; | |
| 23 import 'universe/call_structure.dart'; | |
| 24 | |
| 25 /// [FrontendStrategy] that loads '.dart' files and creates a resolved element | |
| 26 /// model using the resolver. | |
| 27 class ResolutionFrontEndStrategy implements FrontEndStrategy { | |
| 28 final Compiler _compiler; | |
| 29 final ElementEnvironment elementEnvironment; | |
| 30 AnnotationProcessor _annotationProcessor; | |
| 31 | |
| 32 ResolutionFrontEndStrategy(this._compiler) | |
| 33 : elementEnvironment = new _CompilerElementEnvironment(_compiler); | |
| 34 | |
| 35 LibraryLoaderTask createLibraryLoader( | |
| 36 ResolvedUriTranslator uriTranslator, | |
| 37 ScriptLoader scriptLoader, | |
| 38 ElementScanner scriptScanner, | |
| 39 LibraryDeserializer deserializer, | |
| 40 PatchResolverFunction patchResolverFunc, | |
| 41 PatchParserTask patchParser, | |
| 42 Environment environment, | |
| 43 DiagnosticReporter reporter, | |
| 44 Measurer measurer) { | |
| 45 return new ResolutionLibraryLoaderTask( | |
| 46 uriTranslator, | |
| 47 scriptLoader, | |
| 48 scriptScanner, | |
| 49 deserializer, | |
| 50 patchResolverFunc, | |
| 51 patchParser, | |
| 52 environment, | |
| 53 reporter, | |
| 54 measurer); | |
| 55 } | |
| 56 | |
| 57 AnnotationProcessor get annotationProcesser => | |
| 58 _annotationProcessor ??= new _ElementAnnotationProcessor(_compiler); | |
| 59 } | |
| 60 | |
| 61 /// An element environment base on a [Compiler]. | |
| 62 class _CompilerElementEnvironment implements ElementEnvironment { | |
| 63 final Compiler _compiler; | |
| 64 | |
| 65 _CompilerElementEnvironment(this._compiler); | |
| 66 | |
| 67 LibraryProvider get _libraryProvider => _compiler.libraryLoader; | |
| 68 Resolution get _resolution => _compiler.resolution; | |
| 69 | |
| 70 ResolutionDynamicType get dynamicType => const ResolutionDynamicType(); | |
| 71 | |
| 72 @override | |
| 73 LibraryEntity get mainLibrary => _compiler.mainApp; | |
| 74 | |
| 75 @override | |
| 76 FunctionEntity get mainFunction => _compiler.mainFunction; | |
| 77 | |
| 78 @override | |
| 79 Iterable<LibraryEntity> get libraries => _compiler.libraryLoader.libraries; | |
| 80 | |
| 81 @override | |
| 82 ResolutionInterfaceType getThisType(ClassElement cls) { | |
| 83 cls.ensureResolved(_resolution); | |
| 84 return cls.thisType; | |
| 85 } | |
| 86 | |
| 87 @override | |
| 88 ResolutionInterfaceType getRawType(ClassElement cls) { | |
| 89 cls.ensureResolved(_resolution); | |
| 90 return cls.rawType; | |
| 91 } | |
| 92 | |
| 93 @override | |
| 94 ResolutionDartType getTypeVariableBound(TypeVariableElement typeVariable) { | |
| 95 return typeVariable.bound; | |
| 96 } | |
| 97 | |
| 98 @override | |
| 99 ResolutionInterfaceType createInterfaceType( | |
| 100 ClassElement cls, List<ResolutionDartType> typeArguments) { | |
| 101 cls.ensureResolved(_resolution); | |
| 102 return cls.thisType.createInstantiation(typeArguments); | |
| 103 } | |
| 104 | |
| 105 @override | |
| 106 bool isSubtype(ResolutionDartType a, ResolutionDartType b) { | |
| 107 return _compiler.types.isSubtype(a, b); | |
| 108 } | |
| 109 | |
| 110 @override | |
| 111 MemberElement lookupClassMember(ClassElement cls, String name, | |
| 112 {bool setter: false, bool required: false}) { | |
| 113 cls.ensureResolved(_resolution); | |
| 114 Element member = cls.implementation.lookupLocalMember(name); | |
| 115 if (member != null && member.isAbstractField) { | |
| 116 AbstractFieldElement abstractField = member; | |
| 117 if (setter) { | |
| 118 member = abstractField.setter; | |
| 119 } else { | |
| 120 member = abstractField.getter; | |
| 121 } | |
| 122 if (member == null && required) { | |
| 123 throw new SpannableAssertionFailure( | |
| 124 cls, | |
| 125 "The class '${cls.name}' does not contain required " | |
| 126 "${setter ? 'setter' : 'getter'}: '$name'."); | |
| 127 } | |
| 128 } | |
| 129 if (member == null && required) { | |
| 130 throw new SpannableAssertionFailure( | |
| 131 cls, | |
| 132 "The class '${cls.name}' does not " | |
| 133 "contain required member: '$name'."); | |
| 134 } | |
| 135 return member?.declaration; | |
| 136 } | |
| 137 | |
| 138 @override | |
| 139 ConstructorElement lookupConstructor(ClassElement cls, String name, | |
| 140 {bool required: false}) { | |
| 141 cls.ensureResolved(_resolution); | |
| 142 ConstructorElement constructor = cls.implementation.lookupConstructor(name); | |
| 143 if (constructor == null && required) { | |
| 144 throw new SpannableAssertionFailure( | |
| 145 cls, | |
| 146 "The class '${cls.name}' does not contain " | |
| 147 "required constructor: '$name'."); | |
| 148 } | |
| 149 return constructor?.declaration; | |
| 150 } | |
| 151 | |
| 152 @override | |
| 153 void forEachClassMember( | |
| 154 ClassElement cls, void f(ClassElement declarer, MemberElement member)) { | |
| 155 cls.ensureResolved(_resolution); | |
| 156 cls.forEachMember((ClassElement declarer, MemberElement member) { | |
| 157 if (member.isSynthesized) return; | |
| 158 if (member.isMalformed) return; | |
| 159 f(declarer, member); | |
| 160 }, includeSuperAndInjectedMembers: true); | |
| 161 } | |
| 162 | |
| 163 @override | |
| 164 ClassEntity getSuperClass(ClassElement cls) => cls.superclass; | |
| 165 | |
| 166 @override | |
| 167 void forEachSupertype( | |
| 168 ClassElement cls, void f(ResolutionInterfaceType supertype)) { | |
| 169 cls.allSupertypes | |
| 170 .forEach((ResolutionInterfaceType supertype) => f(supertype)); | |
| 171 } | |
| 172 | |
| 173 @override | |
| 174 void forEachMixin(ClassElement cls, void f(ClassElement mixin)) { | |
| 175 for (; cls != null; cls = cls.superclass) { | |
| 176 if (cls.isMixinApplication) { | |
| 177 MixinApplicationElement mixinApplication = cls; | |
| 178 f(mixinApplication.mixin); | |
| 179 } | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 @override | |
| 184 MemberElement lookupLibraryMember(LibraryElement library, String name, | |
| 185 {bool setter: false, bool required: false}) { | |
| 186 Element member = library.implementation.findLocal(name); | |
| 187 if (member != null && member.isAbstractField) { | |
| 188 AbstractFieldElement abstractField = member; | |
| 189 if (setter) { | |
| 190 member = abstractField.setter; | |
| 191 } else { | |
| 192 member = abstractField.getter; | |
| 193 } | |
| 194 if (member == null && required) { | |
| 195 throw new SpannableAssertionFailure( | |
| 196 library, | |
| 197 "The library '${library.canonicalUri}' does not contain required " | |
| 198 "${setter ? 'setter' : 'getter'}: '$name'."); | |
| 199 } | |
| 200 } | |
| 201 if (member == null && required) { | |
| 202 throw new SpannableAssertionFailure( | |
| 203 member, | |
| 204 "The library '${library.libraryName}' does not " | |
| 205 "contain required member: '$name'."); | |
| 206 } | |
| 207 return member?.declaration; | |
| 208 } | |
| 209 | |
| 210 @override | |
| 211 ClassElement lookupClass(LibraryElement library, String name, | |
| 212 {bool required: false}) { | |
| 213 ClassElement cls = library.implementation.findLocal(name); | |
| 214 if (cls == null && required) { | |
| 215 throw new SpannableAssertionFailure( | |
| 216 cls, | |
| 217 "The library '${library.libraryName}' does not " | |
| 218 "contain required class: '$name'."); | |
| 219 } | |
| 220 return cls?.declaration; | |
| 221 } | |
| 222 | |
| 223 @override | |
| 224 void forEachClass(LibraryElement library, void f(ClassElement cls)) { | |
| 225 library.implementation.forEachLocalMember((member) { | |
| 226 if (member.isClass) { | |
| 227 f(member); | |
| 228 } | |
| 229 }); | |
| 230 } | |
| 231 | |
| 232 @override | |
| 233 LibraryElement lookupLibrary(Uri uri, {bool required: false}) { | |
| 234 LibraryElement library = _libraryProvider.lookupLibrary(uri); | |
| 235 // If the script of the library is synthesized, the library does not exist | |
| 236 // and we do not try to load the helpers. | |
| 237 // | |
| 238 // This could for example happen if dart:async is disabled, then loading it | |
| 239 // should not try to find the given element. | |
| 240 if (library != null && library.isSynthesized) { | |
| 241 return null; | |
| 242 } | |
| 243 if (library == null && required) { | |
| 244 throw new SpannableAssertionFailure( | |
| 245 library, "The library '${uri}' was not found."); | |
| 246 } | |
| 247 return library; | |
| 248 } | |
| 249 | |
| 250 @override | |
| 251 CallStructure getCallStructure(MethodElement method) { | |
| 252 ResolutionFunctionType type = method.computeType(_resolution); | |
| 253 return new CallStructure( | |
| 254 type.parameterTypes.length + | |
| 255 type.optionalParameterTypes.length + | |
| 256 type.namedParameterTypes.length, | |
| 257 type.namedParameters); | |
| 258 } | |
| 259 | |
| 260 @override | |
| 261 bool isDeferredLoadLibraryGetter(MemberElement member) { | |
| 262 return member.isDeferredLoaderGetter; | |
| 263 } | |
| 264 | |
| 265 @override | |
| 266 ResolutionFunctionType getFunctionType(MethodElement method) { | |
| 267 method.computeType(_resolution); | |
| 268 return method.type; | |
| 269 } | |
| 270 | |
| 271 @override | |
| 272 ResolutionFunctionType getLocalFunctionType(LocalFunctionElement function) { | |
| 273 return function.type; | |
| 274 } | |
| 275 | |
| 276 @override | |
| 277 ResolutionDartType getUnaliasedType(ResolutionDartType type) { | |
| 278 type.computeUnaliased(_resolution); | |
| 279 return type.unaliased; | |
| 280 } | |
| 281 } | |
| 282 | |
| 283 /// Original logic for annotation processing, which involves in some cases | |
| 284 /// triggering pre-parsing and validation of the annotations. | |
|
Siggi Cherem (dart-lang)
2017/04/24 19:36:48
Thanks for adding a comment to this :) - A couple
Johnni Winther
2017/04/25 07:52:51
Used your suggestion (and Emily is to thank for th
| |
| 285 class _ElementAnnotationProcessor implements AnnotationProcessor { | |
| 286 Compiler _compiler; | |
| 287 | |
| 288 _ElementAnnotationProcessor(this._compiler); | |
| 289 | |
| 290 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its | |
| 291 /// native name from the annotation. | |
| 292 void extractNativeAnnotations( | |
| 293 LibraryElement library, NativeBasicDataBuilder nativeBasicDataBuilder) { | |
| 294 library.forEachLocalMember((Element element) { | |
| 295 if (element.isClass) { | |
| 296 EagerAnnotationHandler.checkAnnotation(_compiler, element, | |
| 297 new NativeAnnotationHandler(nativeBasicDataBuilder)); | |
| 298 } | |
| 299 }); | |
| 300 } | |
| 301 | |
| 302 void extractJsInteropAnnotations( | |
| 303 LibraryElement library, NativeBasicDataBuilder nativeBasicDataBuilder) { | |
| 304 bool checkJsInteropAnnotation(Element element) { | |
| 305 return EagerAnnotationHandler.checkAnnotation( | |
| 306 _compiler, element, const JsInteropAnnotationHandler()); | |
| 307 } | |
| 308 | |
| 309 if (checkJsInteropAnnotation(library)) { | |
| 310 nativeBasicDataBuilder.markAsJsInteropLibrary(library); | |
| 311 } | |
| 312 library.forEachLocalMember((Element element) { | |
| 313 if (element.isClass) { | |
| 314 ClassElement cls = element; | |
| 315 if (checkJsInteropAnnotation(element)) { | |
| 316 nativeBasicDataBuilder.markAsJsInteropClass(cls); | |
| 317 } | |
| 318 } | |
| 319 }); | |
| 320 } | |
| 321 } | |
| OLD | NEW |