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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/elements/modelx.dart

Issue 14168003: Implement implicit constructors in mixin applications. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix an assert. Created 7 years, 7 months 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698