| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 fasta.class_builder; | 5 library fasta.class_builder; |
| 6 | 6 |
| 7 import '../errors.dart' show internalError; | 7 import '../errors.dart' show internalError; |
| 8 | 8 |
| 9 import 'builder.dart' | 9 import 'builder.dart' |
| 10 show | 10 show |
| 11 Builder, | 11 Builder, |
| 12 ConstructorReferenceBuilder, | 12 ConstructorReferenceBuilder, |
| 13 LibraryBuilder, | 13 LibraryBuilder, |
| 14 MemberBuilder, | 14 MemberBuilder, |
| 15 MetadataBuilder, | 15 MetadataBuilder, |
| 16 MixinApplicationBuilder, | 16 MixinApplicationBuilder, |
| 17 NamedTypeBuilder, | 17 NamedTypeBuilder, |
| 18 Scope, |
| 19 ScopeBuilder, |
| 18 TypeBuilder, | 20 TypeBuilder, |
| 19 TypeDeclarationBuilder, | 21 TypeDeclarationBuilder, |
| 20 TypeVariableBuilder; | 22 TypeVariableBuilder; |
| 21 | 23 |
| 22 import '../scope.dart' show AccessErrorBuilder, AmbiguousBuilder, Scope; | |
| 23 | |
| 24 abstract class ClassBuilder<T extends TypeBuilder, R> | 24 abstract class ClassBuilder<T extends TypeBuilder, R> |
| 25 extends TypeDeclarationBuilder<T, R> { | 25 extends TypeDeclarationBuilder<T, R> { |
| 26 final List<TypeVariableBuilder> typeVariables; | 26 final List<TypeVariableBuilder> typeVariables; |
| 27 | 27 |
| 28 T supertype; | 28 T supertype; |
| 29 | 29 |
| 30 List<T> interfaces; | 30 List<T> interfaces; |
| 31 | 31 |
| 32 final Map<String, Builder> members; | 32 final Scope scope; |
| 33 |
| 34 final Scope constructors; |
| 35 |
| 36 final ScopeBuilder scopeBuilder; |
| 37 |
| 38 final ScopeBuilder constructorScopeBuilder; |
| 33 | 39 |
| 34 ClassBuilder( | 40 ClassBuilder( |
| 35 List<MetadataBuilder> metadata, | 41 List<MetadataBuilder> metadata, |
| 36 int modifiers, | 42 int modifiers, |
| 37 String name, | 43 String name, |
| 38 this.typeVariables, | 44 this.typeVariables, |
| 39 this.supertype, | 45 this.supertype, |
| 40 this.interfaces, | 46 this.interfaces, |
| 41 this.members, | 47 this.scope, |
| 48 this.constructors, |
| 42 LibraryBuilder parent, | 49 LibraryBuilder parent, |
| 43 int charOffset) | 50 int charOffset) |
| 44 : super(metadata, modifiers, name, parent, charOffset); | 51 : scopeBuilder = new ScopeBuilder(scope), |
| 52 constructorScopeBuilder = new ScopeBuilder(constructors), |
| 53 super(metadata, modifiers, name, parent, charOffset); |
| 45 | 54 |
| 46 /// Returns true if this class is the result of applying a mixin to its | 55 /// Returns true if this class is the result of applying a mixin to its |
| 47 /// superclass. | 56 /// superclass. |
| 48 bool get isMixinApplication => mixedInType != null; | 57 bool get isMixinApplication => mixedInType != null; |
| 49 | 58 |
| 50 T get mixedInType; | 59 T get mixedInType; |
| 51 | 60 |
| 52 List<ConstructorReferenceBuilder> get constructorReferences => null; | 61 List<ConstructorReferenceBuilder> get constructorReferences => null; |
| 53 | 62 |
| 54 Map<String, Builder> get constructors; | |
| 55 | |
| 56 Map<String, Builder> get membersInScope => members; | |
| 57 | |
| 58 LibraryBuilder get library { | 63 LibraryBuilder get library { |
| 59 LibraryBuilder library = parent; | 64 LibraryBuilder library = parent; |
| 60 return library.partOfLibrary ?? library; | 65 return library.partOfLibrary ?? library; |
| 61 } | 66 } |
| 62 | 67 |
| 63 int resolveConstructors(LibraryBuilder library) { | 68 int resolveConstructors(LibraryBuilder library) { |
| 64 if (constructorReferences == null) return 0; | 69 if (constructorReferences == null) return 0; |
| 65 Scope scope = computeInstanceScope(library.scope); | |
| 66 for (ConstructorReferenceBuilder ref in constructorReferences) { | 70 for (ConstructorReferenceBuilder ref in constructorReferences) { |
| 67 ref.resolveIn(scope); | 71 ref.resolveIn(scope); |
| 68 } | 72 } |
| 69 return constructorReferences.length; | 73 return constructorReferences.length; |
| 70 } | 74 } |
| 71 | 75 |
| 72 Scope computeInstanceScope(Scope parent) { | |
| 73 if (typeVariables != null) { | |
| 74 Map<String, Builder> local = <String, Builder>{}; | |
| 75 for (TypeVariableBuilder t in typeVariables) { | |
| 76 local[t.name] = t; | |
| 77 } | |
| 78 parent = new Scope(local, null, parent, isModifiable: false); | |
| 79 } | |
| 80 return new Scope(membersInScope, null, parent, isModifiable: false); | |
| 81 } | |
| 82 | |
| 83 /// Used to lookup a static member of this class. | 76 /// Used to lookup a static member of this class. |
| 84 Builder findStaticBuilder(String name, int charOffset, Uri fileUri, | 77 Builder findStaticBuilder(String name, int charOffset, Uri fileUri, |
| 85 {bool isSetter: false}) { | 78 {bool isSetter: false}) { |
| 86 Builder builder = members[name]; | 79 Builder builder = isSetter |
| 87 if (builder?.next != null) { | 80 ? scope.lookupSetter(name, charOffset, fileUri, isInstanceScope: false) |
| 88 Builder getterBuilder; | 81 : scope.lookup(name, charOffset, fileUri, isInstanceScope: false); |
| 89 Builder setterBuilder; | 82 return builder; |
| 90 Builder current = builder; | |
| 91 while (current != null) { | |
| 92 if (current.isGetter && getterBuilder == null) { | |
| 93 getterBuilder = current; | |
| 94 } else if (current.isSetter && setterBuilder == null) { | |
| 95 setterBuilder = current; | |
| 96 } else { | |
| 97 return new AmbiguousBuilder(name, builder, charOffset, fileUri); | |
| 98 } | |
| 99 current = current.next; | |
| 100 } | |
| 101 if (getterBuilder?.isInstanceMember ?? false) { | |
| 102 getterBuilder = null; | |
| 103 } | |
| 104 if (setterBuilder?.isInstanceMember ?? false) { | |
| 105 setterBuilder = null; | |
| 106 } | |
| 107 builder = isSetter ? setterBuilder : getterBuilder; | |
| 108 if (builder == null) { | |
| 109 if (isSetter && getterBuilder != null) { | |
| 110 return new AccessErrorBuilder( | |
| 111 name, getterBuilder, charOffset, fileUri); | |
| 112 } else if (!isSetter && setterBuilder != null) { | |
| 113 return new AccessErrorBuilder( | |
| 114 name, setterBuilder, charOffset, fileUri); | |
| 115 } | |
| 116 } | |
| 117 } | |
| 118 if (builder == null) { | |
| 119 return null; | |
| 120 } else if (isSetter && builder.isGetter) { | |
| 121 return null; | |
| 122 } else { | |
| 123 return builder.isInstanceMember ? null : builder; | |
| 124 } | |
| 125 } | 83 } |
| 126 | 84 |
| 127 Builder findConstructorOrFactory(String name, int charOffset, Uri uri) { | 85 Builder findConstructorOrFactory(String name, int charOffset, Uri uri) { |
| 128 return constructors[name]; | 86 return constructors.lookup(name, charOffset, uri); |
| 129 } | 87 } |
| 130 | 88 |
| 131 /// Returns a map which maps the type variables of [superclass] to their | 89 /// Returns a map which maps the type variables of [superclass] to their |
| 132 /// respective values as defined by the superclass clause of this class (and | 90 /// respective values as defined by the superclass clause of this class (and |
| 133 /// its superclasses). | 91 /// its superclasses). |
| 134 /// | 92 /// |
| 135 /// It's assumed that [superclass] is a superclass of this class. | 93 /// It's assumed that [superclass] is a superclass of this class. |
| 136 /// | 94 /// |
| 137 /// For example, given: | 95 /// For example, given: |
| 138 /// | 96 /// |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 } | 143 } |
| 186 directSubstitutionMap[variables[i]] = argument; | 144 directSubstitutionMap[variables[i]] = argument; |
| 187 } | 145 } |
| 188 substitutionMap = directSubstitutionMap; | 146 substitutionMap = directSubstitutionMap; |
| 189 } | 147 } |
| 190 } | 148 } |
| 191 return substitutionMap; | 149 return substitutionMap; |
| 192 } | 150 } |
| 193 | 151 |
| 194 void forEach(void f(String name, MemberBuilder builder)) { | 152 void forEach(void f(String name, MemberBuilder builder)) { |
| 195 members.forEach(f); | 153 scope.forEach(f); |
| 196 } | 154 } |
| 197 | 155 |
| 198 /// Don't use for scope lookup. Only use when an element is known to exist | 156 /// Don't use for scope lookup. Only use when an element is known to exist |
| 199 /// (and not a setter). | 157 /// (and not a setter). |
| 200 MemberBuilder operator [](String name) { | 158 MemberBuilder operator [](String name) { |
| 201 return members[name] ?? internalError("Not found: '$name'."); | 159 return scope.local[name] ?? internalError("Not found: '$name'."); |
| 202 } | 160 } |
| 203 | 161 |
| 204 void addCompileTimeError(int charOffset, String message) { | 162 void addCompileTimeError(int charOffset, String message) { |
| 205 library.addCompileTimeError(charOffset, message, fileUri: fileUri); | 163 library.addCompileTimeError(charOffset, message, fileUri: fileUri); |
| 206 } | 164 } |
| 207 | 165 |
| 208 void addWarning(int charOffset, String message) { | 166 void addWarning(int charOffset, String message) { |
| 209 library.addWarning(charOffset, message, fileUri: fileUri); | 167 library.addWarning(charOffset, message, fileUri: fileUri); |
| 210 } | 168 } |
| 211 | 169 |
| 212 void addNit(int charOffset, String message) { | 170 void addNit(int charOffset, String message) { |
| 213 library.addNit(charOffset, message, fileUri: fileUri); | 171 library.addNit(charOffset, message, fileUri: fileUri); |
| 214 } | 172 } |
| 215 } | 173 } |
| OLD | NEW |