| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** | 5 /** |
| 6 * Any abstract representation of a dart element. This includes | 6 * Any abstract representation of a dart element. This includes |
| 7 * [Library], [Type] and [Member]. | 7 * [Library], [Type] and [Member]. |
| 8 */ | 8 */ |
| 9 class Element implements Hashable { | 9 class Element implements Hashable { |
| 10 // TODO(jimhug): Make name final when we can do it for Library. | 10 // TODO(jimhug): Make name final when we can do it for Library. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 | 49 |
| 50 /** Resolve types and other references in the [Element]. */ | 50 /** Resolve types and other references in the [Element]. */ |
| 51 void resolve() {} | 51 void resolve() {} |
| 52 | 52 |
| 53 /** | 53 /** |
| 54 * Any type parameters that this element defines to setup a generic | 54 * Any type parameters that this element defines to setup a generic |
| 55 * type resolution context. This is currently used for both generic | 55 * type resolution context. This is currently used for both generic |
| 56 * types and the semi-magical generic factory methods - but it will | 56 * types and the semi-magical generic factory methods - but it will |
| 57 * not be used for any other members in the current dart language. | 57 * not be used for any other members in the current dart language. |
| 58 */ | 58 */ |
| 59 // TODO(jimhug): Confirm whether or not these are still on factories. |
| 59 List<ParameterType> get typeParameters() => null; | 60 List<ParameterType> get typeParameters() => null; |
| 60 | 61 |
| 62 List<Type> get typeArgsInOrder() => const []; |
| 63 |
| 61 // TODO(jimhug): Probably kill this. | 64 // TODO(jimhug): Probably kill this. |
| 62 Element get enclosingElement() => | 65 Element get enclosingElement() => |
| 63 _enclosingElement == null ? library : _enclosingElement; | 66 _enclosingElement == null ? library : _enclosingElement; |
| 64 | 67 |
| 65 // TODO(jimhug): Absolutely kill this one. | 68 // TODO(jimhug): Absolutely kill this one. |
| 66 set enclosingElement(Element e) => _enclosingElement = e; | 69 set enclosingElement(Element e) => _enclosingElement = e; |
| 67 | 70 |
| 71 Type lookupTypeParam(String name) { |
| 72 if (typeParameters == null) return null; |
| 73 |
| 74 for (int i=0; i < typeParameters.length; i++) { |
| 75 if (typeParameters[i].name == name) { |
| 76 return typeArgsInOrder[i]; |
| 77 } |
| 78 } |
| 79 return null; |
| 80 } |
| 81 |
| 68 | 82 |
| 69 /** | 83 /** |
| 70 * Resolves [node] in the context of this element. Will | 84 * Resolves [node] in the context of this element. Will |
| 71 * search up the tree of [enclosingElement] to look for matches. | 85 * search up the tree of [enclosingElement] to look for matches. |
| 72 * If [typeErrors] then types that are not found will create errors, | 86 * If [typeErrors] then types that are not found will create errors, |
| 73 * otherwise they will only signal warnings. | 87 * otherwise they will only signal warnings. |
| 74 */ | 88 */ |
| 75 Type resolveType(TypeReference node, bool typeErrors) { | 89 Type resolveType(TypeReference node, bool typeErrors, bool allowTypeParams) { |
| 76 if (node == null) return world.varType; | 90 if (node == null) return world.varType; |
| 77 | 91 |
| 78 if (node.type != null) return node.type; | |
| 79 | |
| 80 // TODO(jmesserly): if we failed to resolve a type, we need a way to save | 92 // TODO(jmesserly): if we failed to resolve a type, we need a way to save |
| 81 // that it was an error, so we don't try to resolve it again and show the | 93 // that it was an error, so we don't try to resolve it again and show the |
| 82 // same message twice. | 94 // same message twice. |
| 83 | 95 |
| 84 if (node is NameTypeReference) { | 96 if (node is SimpleTypeReference) { |
| 97 var ret = node.dynamic.type; |
| 98 if (ret == world.voidType) { |
| 99 world.error('"void" only allowed as return type', node.span); |
| 100 return world.varType; |
| 101 } |
| 102 return ret; |
| 103 } else if (node is NameTypeReference) { |
| 85 NameTypeReference typeRef = node; | 104 NameTypeReference typeRef = node; |
| 86 String name; | 105 String name; |
| 87 if (typeRef.names != null) { | 106 if (typeRef.names != null) { |
| 88 name = typeRef.names.last().name; | 107 name = typeRef.names.last().name; |
| 89 } else { | 108 } else { |
| 90 name = typeRef.name.name; | 109 name = typeRef.name.name; |
| 91 } | 110 } |
| 92 if (typeParameters != null) { | 111 var typeParamType = lookupTypeParam(name); |
| 93 for (var tp in typeParameters) { | 112 if (typeParamType != null) { |
| 94 if (tp.name == name) { | 113 if (!allowTypeParams) { |
| 95 typeRef.type = tp; | 114 world.error('using type parameter in illegal context.', node.span); |
| 96 } | |
| 97 } | 115 } |
| 98 } | 116 return typeParamType; |
| 99 if (typeRef.type != null) { | |
| 100 return typeRef.type; | |
| 101 } | 117 } |
| 102 | 118 |
| 103 return enclosingElement.resolveType(node, typeErrors); | 119 return enclosingElement.resolveType(node, typeErrors, allowTypeParams); |
| 104 } else if (node is GenericTypeReference) { | 120 } else if (node is GenericTypeReference) { |
| 105 GenericTypeReference typeRef = node; | 121 GenericTypeReference typeRef = node; |
| 106 // TODO(jimhug): Expand the handling of typeErrors to generics and funcs | 122 // TODO(jimhug): Expand the handling of typeErrors to generics and funcs |
| 107 var baseType = resolveType(typeRef.baseType, typeErrors); | 123 var baseType = resolveType(typeRef.baseType, typeErrors, |
| 124 allowTypeParams); |
| 125 //!!!print('resolving generic: ${baseType.name}'); |
| 108 if (!baseType.isGeneric) { | 126 if (!baseType.isGeneric) { |
| 109 world.error('${baseType.name} is not generic', typeRef.span); | 127 world.error('${baseType.name} is not generic', typeRef.span); |
| 110 return null; | 128 return world.varType; |
| 111 } | 129 } |
| 112 if (typeRef.typeArguments.length != baseType.typeParameters.length) { | 130 if (typeRef.typeArguments.length != baseType.typeParameters.length) { |
| 113 world.error('wrong number of type arguments', typeRef.span); | 131 world.error('wrong number of type arguments', typeRef.span); |
| 114 return null; | 132 return world.varType; |
| 115 } | 133 } |
| 116 var typeArgs = []; | 134 var typeArgs = []; |
| 117 for (int i=0; i < typeRef.typeArguments.length; i++) { | 135 for (int i=0; i < typeRef.typeArguments.length; i++) { |
| 118 typeArgs.add(resolveType(typeRef.typeArguments[i], typeErrors)); | 136 typeArgs.add(resolveType(typeRef.typeArguments[i], typeErrors, |
| 137 allowTypeParams)); |
| 119 } | 138 } |
| 120 typeRef.type = baseType.getOrMakeConcreteType(typeArgs); | 139 return baseType.getOrMakeConcreteType(typeArgs); |
| 121 } else if (node is FunctionTypeReference) { | 140 } else if (node is FunctionTypeReference) { |
| 122 FunctionTypeReference typeRef = node; | 141 FunctionTypeReference typeRef = node; |
| 123 var name = ''; | 142 var name = ''; |
| 124 if (typeRef.func.name != null) { | 143 if (typeRef.func.name != null) { |
| 125 name = typeRef.func.name.name; | 144 name = typeRef.func.name.name; |
| 126 } | 145 } |
| 127 // Totally bogus! | 146 return library.getOrAddFunctionType(this, name, typeRef.func, null); |
| 128 typeRef.type = library.getOrAddFunctionType(this, name, typeRef.func); | |
| 129 } else { | |
| 130 world.internalError('unknown type reference', node.span); | |
| 131 } | 147 } |
| 132 return node.type; | 148 world.internalError('unexpected TypeReference', node.span); |
| 133 } | 149 } |
| 134 } | 150 } |
| 135 | 151 |
| 136 /** | 152 /** |
| 137 * An [Element] representing something in the top level JavaScript environment. | 153 * An [Element] representing something in the top level JavaScript environment. |
| 138 */ | 154 */ |
| 139 class ExistingJsGlobal extends Element { | 155 class ExistingJsGlobal extends Element { |
| 140 /** The element causing this alias. */ | 156 /** The element causing this alias. */ |
| 141 final Element declaringElement; | 157 final Element declaringElement; |
| 142 | 158 |
| 143 ExistingJsGlobal(name, this.declaringElement) : super(name, null); | 159 ExistingJsGlobal(name, this.declaringElement) : super(name, null); |
| 144 | 160 |
| 145 /** Should this element be treated as native JS? */ | 161 /** Should this element be treated as native JS? */ |
| 146 bool get isNative() => true; | 162 bool get isNative() => true; |
| 147 | 163 |
| 148 /** This must be the highest possible priority. */ | 164 /** This must be the highest possible priority. */ |
| 149 int get jsnamePriority() => 10; | 165 int get jsnamePriority() => 10; |
| 150 | 166 |
| 151 /** A source location for messages to the user about this [Element]. */ | 167 /** A source location for messages to the user about this [Element]. */ |
| 152 SourceSpan get span() => declaringElement.span; | 168 SourceSpan get span() => declaringElement.span; |
| 153 | 169 |
| 154 /** A library for messages. */ | 170 /** A library for messages. */ |
| 155 Library get library() => declaringElement.library; | 171 Library get library() => declaringElement.library; |
| 156 | 172 |
| 157 } | 173 } |
| OLD | NEW |