| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library elements.modelx; | 5 library elements.modelx; |
| 6 | 6 |
| 7 import 'dart:uri'; | 7 import 'dart:uri'; |
| 8 import 'dart:collection' show LinkedHashMap; | 8 import 'dart:collection' show LinkedHashMap; |
| 9 | 9 |
| 10 import 'elements.dart'; | 10 import 'elements.dart'; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 | 125 |
| 126 /** | 126 /** |
| 127 * Is [:true:] if this element introduces the entity of this element. | 127 * Is [:true:] if this element introduces the entity of this element. |
| 128 * | 128 * |
| 129 * See [:patch_parser.dart:] for a description of the terminology. | 129 * See [:patch_parser.dart:] for a description of the terminology. |
| 130 */ | 130 */ |
| 131 bool get isDeclaration => !isPatch; | 131 bool get isDeclaration => !isPatch; |
| 132 | 132 |
| 133 bool get isSynthesized => false; | 133 bool get isSynthesized => false; |
| 134 | 134 |
| 135 bool get isForwardingConstructor => false; |
| 136 |
| 135 /** | 137 /** |
| 136 * Returns the element which defines the implementation for the entity of this | 138 * Returns the element which defines the implementation for the entity of this |
| 137 * element. | 139 * element. |
| 138 * | 140 * |
| 139 * See [:patch_parser.dart:] for a description of the terminology. | 141 * See [:patch_parser.dart:] for a description of the terminology. |
| 140 */ | 142 */ |
| 141 Element get implementation => isPatched ? patch : this; | 143 Element get implementation => isPatched ? patch : this; |
| 142 | 144 |
| 143 /** | 145 /** |
| 144 * Returns the element which introduces the entity of this element. | 146 * Returns the element which introduces the entity of this element. |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 void setFixedBackendName(String name) { | 265 void setFixedBackendName(String name) { |
| 264 _fixedBackendName = name; | 266 _fixedBackendName = name; |
| 265 } | 267 } |
| 266 | 268 |
| 267 FunctionElement asFunctionElement() => null; | 269 FunctionElement asFunctionElement() => null; |
| 268 | 270 |
| 269 static bool isInvalid(Element e) => e == null || e.isErroneous(); | 271 static bool isInvalid(Element e) => e == null || e.isErroneous(); |
| 270 | 272 |
| 271 bool isAbstract(Compiler compiler) => modifiers.isAbstract(); | 273 bool isAbstract(Compiler compiler) => modifiers.isAbstract(); |
| 272 bool isForeign(Compiler compiler) => getLibrary() == compiler.foreignLibrary; | 274 bool isForeign(Compiler compiler) => getLibrary() == compiler.foreignLibrary; |
| 275 |
| 276 FunctionElement get targetConstructor => null; |
| 273 } | 277 } |
| 274 | 278 |
| 275 /** | 279 /** |
| 276 * Represents an unresolvable or duplicated element. | 280 * Represents an unresolvable or duplicated element. |
| 277 * | 281 * |
| 278 * An [ErroneousElement] is used instead of [null] to provide additional | 282 * An [ErroneousElement] is used instead of [null] to provide additional |
| 279 * information about the error that caused the element to be unresolvable | 283 * information about the error that caused the element to be unresolvable |
| 280 * or otherwise invalid. | 284 * or otherwise invalid. |
| 281 * | 285 * |
| 282 * Accessing any field or calling any method defined on [ErroneousElement] | 286 * Accessing any field or calling any method defined on [ErroneousElement] |
| (...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 Node parseNode(DiagnosticListener listener) { | 1261 Node parseNode(DiagnosticListener listener) { |
| 1258 if (cachedNode != null) return cachedNode; | 1262 if (cachedNode != null) return cachedNode; |
| 1259 cachedNode = constructor.parseNode(listener); | 1263 cachedNode = constructor.parseNode(listener); |
| 1260 assert(cachedNode != null); | 1264 assert(cachedNode != null); |
| 1261 return cachedNode; | 1265 return cachedNode; |
| 1262 } | 1266 } |
| 1263 | 1267 |
| 1264 Token position() => constructor.position(); | 1268 Token position() => constructor.position(); |
| 1265 } | 1269 } |
| 1266 | 1270 |
| 1271 /** |
| 1272 * A constructor that is not defined in the source code but rather implied by |
| 1273 * the language semantics. |
| 1274 * |
| 1275 * This class is used to represent default constructors and forwarding |
| 1276 * constructors for mixin applications. |
| 1277 */ |
| 1267 class SynthesizedConstructorElementX extends FunctionElementX { | 1278 class SynthesizedConstructorElementX extends FunctionElementX { |
| 1279 /// The target constructor if this synthetic constructor is a forwarding |
| 1280 /// constructor in a mixin application. |
| 1281 final FunctionElement target; |
| 1282 |
| 1268 SynthesizedConstructorElementX(Element enclosing) | 1283 SynthesizedConstructorElementX(Element enclosing) |
| 1269 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, | 1284 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, |
| 1270 Modifiers.EMPTY, enclosing); | 1285 Modifiers.EMPTY, enclosing), |
| 1286 target = null; |
| 1271 | 1287 |
| 1272 SynthesizedConstructorElementX.forDefault(Element enclosing, | 1288 SynthesizedConstructorElementX.forDefault(Element enclosing, |
| 1273 Compiler compiler) | 1289 Compiler compiler) |
| 1274 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, | 1290 : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR, |
| 1275 Modifiers.EMPTY, enclosing) { | 1291 Modifiers.EMPTY, enclosing), |
| 1292 target = null { |
| 1293 // TODO(karlklose): get rid of the fake AST. |
| 1276 type = new FunctionType(this, | 1294 type = new FunctionType(this, |
| 1277 compiler.types.voidType, | 1295 compiler.types.voidType, |
| 1278 const Link<DartType>(), | 1296 const Link<DartType>(), |
| 1279 const Link<DartType>(), | 1297 const Link<DartType>(), |
| 1280 const Link<SourceString>(), | 1298 const Link<SourceString>(), |
| 1281 const Link<DartType>()); | 1299 const Link<DartType>()); |
| 1282 cachedNode = new FunctionExpression( | 1300 cachedNode = new FunctionExpression( |
| 1283 new Identifier(enclosing.position()), | 1301 new Identifier(enclosing.position()), |
| 1284 new NodeList.empty(), | 1302 new NodeList.empty(), |
| 1285 new Block(new NodeList.empty()), | 1303 new Block(new NodeList.empty()), |
| 1286 null, Modifiers.EMPTY, null, null); | 1304 null, Modifiers.EMPTY, null, null); |
| 1287 } | 1305 } |
| 1288 | 1306 |
| 1307 /** |
| 1308 * Create synthetic constructor that directly forwards to a constructor in the |
| 1309 * super class of a mixin application. |
| 1310 * |
| 1311 * In a mixin application `Base with M`, any constructor defined in `Base` is |
| 1312 * available as if they were a constructor defined in the mixin application |
| 1313 * with the same formal parameters that calls the constructor in the super |
| 1314 * class via a `super` initializer (see Ch. 9.1 in the specification). |
| 1315 */ |
| 1316 SynthesizedConstructorElementX.forwarding(SourceString name, this.target, |
| 1317 Element enclosing) |
| 1318 : super(name, ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY, |
| 1319 enclosing); |
| 1320 |
| 1321 Token position() => enclosingElement.position(); |
| 1322 |
| 1289 bool get isSynthesized => true; | 1323 bool get isSynthesized => true; |
| 1290 | 1324 |
| 1291 Token position() => enclosingElement.position(); | 1325 bool get isForwardingConstructor => target != null; |
| 1326 |
| 1327 FunctionElement get targetConstructor => target; |
| 1328 |
| 1329 FunctionSignature computeSignature(compiler) { |
| 1330 if (target != null) { |
| 1331 return target.computeSignature(compiler); |
| 1332 } else { |
| 1333 assert(cachedNode != null); |
| 1334 return super.computeSignature(compiler); |
| 1335 } |
| 1336 } |
| 1337 |
| 1338 get declaration => this; |
| 1339 get implementation => this; |
| 1340 get defaultImplementation => this; |
| 1292 } | 1341 } |
| 1293 | 1342 |
| 1294 class VoidElementX extends ElementX { | 1343 class VoidElementX extends ElementX { |
| 1295 VoidElementX(Element enclosing) | 1344 VoidElementX(Element enclosing) |
| 1296 : super(const SourceString('void'), ElementKind.VOID, enclosing); | 1345 : super(const SourceString('void'), ElementKind.VOID, enclosing); |
| 1297 DartType computeType(compiler) => compiler.types.voidType; | 1346 DartType computeType(compiler) => compiler.types.voidType; |
| 1298 Node parseNode(_) { | 1347 Node parseNode(_) { |
| 1299 throw 'internal error: parseNode on void'; | 1348 throw 'internal error: parseNode on void'; |
| 1300 } | 1349 } |
| 1301 bool impliesType() => true; | 1350 bool impliesType() => true; |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 return super.toString(); | 1882 return super.toString(); |
| 1834 } | 1883 } |
| 1835 } | 1884 } |
| 1836 } | 1885 } |
| 1837 | 1886 |
| 1838 class MixinApplicationElementX extends BaseClassElementX | 1887 class MixinApplicationElementX extends BaseClassElementX |
| 1839 implements MixinApplicationElement { | 1888 implements MixinApplicationElement { |
| 1840 final Node node; | 1889 final Node node; |
| 1841 final Modifiers modifiers; | 1890 final Modifiers modifiers; |
| 1842 | 1891 |
| 1843 FunctionElement constructor; | 1892 Link<FunctionElement> constructors = new Link<FunctionElement>(); |
| 1893 |
| 1844 ClassElement mixin; | 1894 ClassElement mixin; |
| 1845 | 1895 |
| 1846 // TODO(kasperl): The analyzer complains when I don't have these two | 1896 // TODO(kasperl): The analyzer complains when I don't have these two |
| 1847 // fields. This is pretty weird. I cannot replace them with getters. | 1897 // fields. This is pretty weird. I cannot replace them with getters. |
| 1848 final ClassElement patch = null; | 1898 final ClassElement patch = null; |
| 1849 final ClassElement origin = null; | 1899 final ClassElement origin = null; |
| 1850 | 1900 |
| 1851 MixinApplicationElementX(SourceString name, Element enclosing, int id, | 1901 MixinApplicationElementX(SourceString name, Element enclosing, int id, |
| 1852 this.node, this.modifiers) | 1902 this.node, this.modifiers) |
| 1853 : super(name, enclosing, id, STATE_NOT_STARTED); | 1903 : super(name, enclosing, id, STATE_NOT_STARTED); |
| 1854 | 1904 |
| 1855 bool get isMixinApplication => true; | 1905 bool get isMixinApplication => true; |
| 1856 bool get hasConstructor => constructor != null; | 1906 bool get hasConstructor => !constructors.isEmpty; |
| 1857 bool get hasLocalScopeMembers => false; | 1907 bool get hasLocalScopeMembers => !constructors.isEmpty; |
| 1858 | 1908 |
| 1859 Token position() => node.getBeginToken(); | 1909 Token position() => node.getBeginToken(); |
| 1860 | 1910 |
| 1861 Node parseNode(DiagnosticListener listener) => node; | 1911 Node parseNode(DiagnosticListener listener) => node; |
| 1862 | 1912 |
| 1913 FunctionElement lookupLocalConstructor(SourceString name) { |
| 1914 for (Link<Element> link = constructors; |
| 1915 !link.isEmpty; |
| 1916 link = link.tail) { |
| 1917 if (link.head.name == name) return link.head; |
| 1918 } |
| 1919 return null; |
| 1920 } |
| 1921 |
| 1863 Element localLookup(SourceString name) { | 1922 Element localLookup(SourceString name) { |
| 1864 if (this.name == name) return constructor; | 1923 Element constructor = lookupLocalConstructor(name); |
| 1924 if (constructor != null) return constructor; |
| 1865 if (mixin == null) return null; | 1925 if (mixin == null) return null; |
| 1866 Element mixedInElement = mixin.localLookup(name); | 1926 Element mixedInElement = mixin.localLookup(name); |
| 1867 if (mixedInElement == null) return null; | 1927 if (mixedInElement == null) return null; |
| 1868 return mixedInElement.isInstanceMember() ? mixedInElement : null; | 1928 return mixedInElement.isInstanceMember() ? mixedInElement : null; |
| 1869 } | 1929 } |
| 1870 | 1930 |
| 1871 void forEachLocalMember(void f(Element member)) { | 1931 void forEachLocalMember(void f(Element member)) { |
| 1932 constructors.forEach(f); |
| 1872 if (mixin != null) mixin.forEachLocalMember((Element mixedInElement) { | 1933 if (mixin != null) mixin.forEachLocalMember((Element mixedInElement) { |
| 1873 if (mixedInElement.isInstanceMember()) f(mixedInElement); | 1934 if (mixedInElement.isInstanceMember()) f(mixedInElement); |
| 1874 }); | 1935 }); |
| 1875 } | 1936 } |
| 1876 | 1937 |
| 1877 void addMember(Element element, DiagnosticListener listener) { | 1938 void addMember(Element element, DiagnosticListener listener) { |
| 1878 throw new UnsupportedError("cannot add member to $this"); | 1939 throw new UnsupportedError("cannot add member to $this"); |
| 1879 } | 1940 } |
| 1880 | 1941 |
| 1881 void addToScope(Element element, DiagnosticListener listener) { | 1942 void addToScope(Element element, DiagnosticListener listener) { |
| 1882 throw new UnsupportedError("cannot add to scope of $this"); | 1943 listener.internalError('cannot add to scope of $this', element: this); |
| 1944 } |
| 1945 |
| 1946 void addConstructor(FunctionElement constructor) { |
| 1947 constructors = constructors.prepend(constructor); |
| 1883 } | 1948 } |
| 1884 | 1949 |
| 1885 void setDefaultConstructor(FunctionElement constructor, Compiler compiler) { | 1950 void setDefaultConstructor(FunctionElement constructor, Compiler compiler) { |
| 1886 assert(!hasConstructor); | 1951 assert(!hasConstructor); |
| 1887 this.constructor = constructor; | 1952 addConstructor(constructor); |
| 1888 } | 1953 } |
| 1889 | 1954 |
| 1890 Link<DartType> computeTypeParameters(Compiler compiler) { | 1955 Link<DartType> computeTypeParameters(Compiler compiler) { |
| 1891 NamedMixinApplication named = node.asNamedMixinApplication(); | 1956 NamedMixinApplication named = node.asNamedMixinApplication(); |
| 1892 if (named == null) return const Link<DartType>(); | 1957 if (named == null) return const Link<DartType>(); |
| 1893 return TypeDeclarationElementX.createTypeVariables( | 1958 return TypeDeclarationElementX.createTypeVariables( |
| 1894 this, named.typeParameters); | 1959 this, named.typeParameters); |
| 1895 } | 1960 } |
| 1896 } | 1961 } |
| 1897 | 1962 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2019 | 2084 |
| 2020 MetadataAnnotation ensureResolved(Compiler compiler) { | 2085 MetadataAnnotation ensureResolved(Compiler compiler) { |
| 2021 if (resolutionState == STATE_NOT_STARTED) { | 2086 if (resolutionState == STATE_NOT_STARTED) { |
| 2022 compiler.resolver.resolveMetadataAnnotation(this); | 2087 compiler.resolver.resolveMetadataAnnotation(this); |
| 2023 } | 2088 } |
| 2024 return this; | 2089 return this; |
| 2025 } | 2090 } |
| 2026 | 2091 |
| 2027 String toString() => 'MetadataAnnotation($value, $resolutionState)'; | 2092 String toString() => 'MetadataAnnotation($value, $resolutionState)'; |
| 2028 } | 2093 } |
| OLD | NEW |