OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 package com.google.dart.compiler.type; | 5 package com.google.dart.compiler.type; |
6 | 6 |
7 import com.google.common.annotations.VisibleForTesting; | 7 import com.google.common.annotations.VisibleForTesting; |
8 import com.google.common.base.Joiner; | 8 import com.google.common.base.Joiner; |
9 import com.google.common.base.Objects; | 9 import com.google.common.base.Objects; |
10 import com.google.common.collect.ArrayListMultimap; | 10 import com.google.common.collect.ArrayListMultimap; |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 return "operator " + operator.getSyntax(); | 305 return "operator " + operator.getSyntax(); |
306 } | 306 } |
307 | 307 |
308 private Type analyzeBinaryOperator(DartNode node, Type lhsType, Token operat
or, | 308 private Type analyzeBinaryOperator(DartNode node, Type lhsType, Token operat
or, |
309 DartNode diagnosticNode, DartExpression rhs) { | 309 DartNode diagnosticNode, DartExpression rhs) { |
310 Type rhsType = nonVoidTypeOf(rhs); | 310 Type rhsType = nonVoidTypeOf(rhs); |
311 String methodName = methodNameForBinaryOperator(operator); | 311 String methodName = methodNameForBinaryOperator(operator); |
312 HasSourceInfo problemTarget = getOperatorHasSourceInfo(node); | 312 HasSourceInfo problemTarget = getOperatorHasSourceInfo(node); |
313 Member member = lookupMember(lhsType, methodName, problemTarget); | 313 Member member = lookupMember(lhsType, methodName, problemTarget); |
314 if (member != null) { | 314 if (member != null) { |
315 node.setElement(member.getElement()); | 315 Element element = member.getElement(); |
| 316 node.setElement(element); |
316 FunctionType methodType = getMethodType(lhsType, member, methodName, dia
gnosticNode); | 317 FunctionType methodType = getMethodType(lhsType, member, methodName, dia
gnosticNode); |
| 318 checkDeprecated(problemTarget, element); |
317 Type returnType = checkInvocation(Collections.<DartExpression> singleton
List(rhs), | 319 Type returnType = checkInvocation(Collections.<DartExpression> singleton
List(rhs), |
318 diagnosticNode, methodName, methodType); | 320 diagnosticNode, methodName, methodType); |
319 // tweak return type for int/int and int/double operators | 321 // tweak return type for int/int and int/double operators |
320 { | 322 { |
321 boolean lhsInt = intType.equals(lhsType); | 323 boolean lhsInt = intType.equals(lhsType); |
322 boolean rhsInt = intType.equals(rhsType); | 324 boolean rhsInt = intType.equals(rhsType); |
323 boolean lhsDouble = doubleType.equals(lhsType); | 325 boolean lhsDouble = doubleType.equals(lhsType); |
324 boolean rhsDouble = doubleType.equals(rhsType); | 326 boolean rhsDouble = doubleType.equals(rhsType); |
325 switch (operator) { | 327 switch (operator) { |
326 case ADD: | 328 case ADD: |
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 return voidType; | 1223 return voidType; |
1222 } | 1224 } |
1223 | 1225 |
1224 @Override | 1226 @Override |
1225 public Type visitBreakStatement(DartBreakStatement node) { | 1227 public Type visitBreakStatement(DartBreakStatement node) { |
1226 return voidType; | 1228 return voidType; |
1227 } | 1229 } |
1228 | 1230 |
1229 @Override | 1231 @Override |
1230 public Type visitFunctionObjectInvocation(DartFunctionObjectInvocation node)
{ | 1232 public Type visitFunctionObjectInvocation(DartFunctionObjectInvocation node)
{ |
1231 node.setElement(functionType.getElement()); | 1233 ClassElement element = functionType.getElement(); |
| 1234 node.setElement(element); |
| 1235 checkDeprecated(node, element); |
1232 return checkInvocation(node, node, null, typeOf(node.getTarget())); | 1236 return checkInvocation(node, node, null, typeOf(node.getTarget())); |
1233 } | 1237 } |
1234 | 1238 |
1235 @Override | 1239 @Override |
1236 public Type visitMethodInvocation(DartMethodInvocation node) { | 1240 public Type visitMethodInvocation(DartMethodInvocation node) { |
1237 DartIdentifier nameNode = node.getFunctionName(); | 1241 DartIdentifier nameNode = node.getFunctionName(); |
1238 String name = node.getFunctionNameString(); | 1242 String name = node.getFunctionNameString(); |
1239 Element element = node.getElement(); | 1243 Element element = node.getElement(); |
1240 if (element != null && (element.getModifiers().isStatic() | 1244 if (element != null && (element.getModifiers().isStatic() |
1241 || Elements.isTopLevel(element))) { | 1245 || Elements.isTopLevel(element))) { |
1242 node.setElement(element); | 1246 node.setElement(element); |
| 1247 checkDeprecated(nameNode, element); |
1243 return checkInvocation(node, nameNode, name, element.getType()); | 1248 return checkInvocation(node, nameNode, name, element.getType()); |
1244 } | 1249 } |
1245 DartNode target = node.getTarget(); | 1250 DartNode target = node.getTarget(); |
1246 Type receiver = nonVoidTypeOf(target); | 1251 Type receiver = nonVoidTypeOf(target); |
1247 Member member = lookupMember(receiver, name, nameNode); | 1252 Member member = lookupMember(receiver, name, nameNode); |
1248 if (member != null) { | 1253 if (member != null) { |
1249 Element methodElement = member.getElement(); | 1254 Element methodElement = member.getElement(); |
1250 node.setElement(methodElement); | 1255 node.setElement(methodElement); |
1251 if (nameNode != null) { | 1256 if (nameNode != null) { |
1252 nameNode.setElement(methodElement); | 1257 nameNode.setElement(methodElement); |
1253 } | 1258 } |
1254 } | 1259 } |
| 1260 checkDeprecated(nameNode, nameNode.getElement()); |
1255 FunctionType methodType = getMethodType(receiver, member, name, nameNode); | 1261 FunctionType methodType = getMethodType(receiver, member, name, nameNode); |
1256 return checkInvocation(node, nameNode, name, methodType); | 1262 return checkInvocation(node, nameNode, name, methodType); |
1257 } | 1263 } |
1258 | 1264 |
1259 @Override | 1265 @Override |
1260 public Type visitSuperConstructorInvocation(DartSuperConstructorInvocation n
ode) { | 1266 public Type visitSuperConstructorInvocation(DartSuperConstructorInvocation n
ode) { |
1261 return checkConstructorForwarding(node, node.getElement()); | 1267 return checkConstructorForwarding(node, node.getElement()); |
1262 } | 1268 } |
1263 | 1269 |
1264 private Type checkConstructorForwarding(DartInvocation node, ConstructorElem
ent element) { | 1270 private Type checkConstructorForwarding(DartInvocation node, ConstructorElem
ent element) { |
1265 if (element == null) { | 1271 if (element == null) { |
1266 visit(node.getArguments()); | 1272 visit(node.getArguments()); |
1267 return voidType; | 1273 return voidType; |
1268 } else { | 1274 } else { |
1269 node.setElement(element); | 1275 node.setElement(element); |
| 1276 checkDeprecated(node, element); |
1270 checkInvocation(node, node, null, typeAsMemberOf(element, currentClass))
; | 1277 checkInvocation(node, node, null, typeAsMemberOf(element, currentClass))
; |
1271 return voidType; | 1278 return voidType; |
1272 } | 1279 } |
1273 } | 1280 } |
1274 | 1281 |
1275 @Override | 1282 @Override |
1276 public Type visitCase(DartCase node) { | 1283 public Type visitCase(DartCase node) { |
1277 node.visitChildren(this); | 1284 node.visitChildren(this); |
1278 return voidType; | 1285 return voidType; |
1279 } | 1286 } |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1867 // The constructor in the interface is resolved to the type paramete
rs declared in | 1874 // The constructor in the interface is resolved to the type paramete
rs declared in |
1868 // the interface, but the constructor body has type parameters resol
ved to the type | 1875 // the interface, but the constructor body has type parameters resol
ved to the type |
1869 // parameters in the default class. This substitution patches up th
e type variable | 1876 // parameters in the default class. This substitution patches up th
e type variable |
1870 // references used in parameters so they match the concrete class. | 1877 // references used in parameters so they match the concrete class. |
1871 substParams = ((ClassElement)constructorElement.getEnclosingElement(
)).getType().getArguments(); | 1878 substParams = ((ClassElement)constructorElement.getEnclosingElement(
)).getType().getArguments(); |
1872 } else { | 1879 } else { |
1873 substParams = ifaceType.getElement().getTypeParameters(); | 1880 substParams = ifaceType.getElement().getTypeParameters(); |
1874 } | 1881 } |
1875 List<Type> arguments = ifaceType.getArguments(); | 1882 List<Type> arguments = ifaceType.getArguments(); |
1876 ftype = (FunctionType) ftype.subst(arguments, substParams); | 1883 ftype = (FunctionType) ftype.subst(arguments, substParams); |
1877 checkInvocation(node, node, null, ftype); | 1884 checkDeprecated(getConstructorNameNode(node), constructorElement); |
| 1885 checkInvocation(node, node, constructorElement.getName(), ftype); |
1878 } | 1886 } |
1879 } | 1887 } |
1880 type.getClass(); // quick null check | 1888 type.getClass(); // quick null check |
1881 return type; | 1889 return type; |
1882 } | 1890 } |
1883 | 1891 |
1884 /** | 1892 /** |
1885 * @param cls the {@link ClassElement} which has unimplemented members. | 1893 * @param cls the {@link ClassElement} which has unimplemented members. |
1886 * @param unimplementedMembers the unimplemented members {@link Element}s. | 1894 * @param unimplementedMembers the unimplemented members {@link Element}s. |
1887 * @return the {@link StringBuilder} with message about unimplemented member
s. | 1895 * @return the {@link StringBuilder} with message about unimplemented member
s. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1974 return dynamicType; | 1982 return dynamicType; |
1975 } | 1983 } |
1976 element = member.getElement(); | 1984 element = member.getElement(); |
1977 node.setElement(element); | 1985 node.setElement(element); |
1978 Modifiers modifiers = element.getModifiers(); | 1986 Modifiers modifiers = element.getModifiers(); |
1979 if (modifiers.isStatic()) { | 1987 if (modifiers.isStatic()) { |
1980 return typeError(node.getName(), | 1988 return typeError(node.getName(), |
1981 TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE, | 1989 TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE, |
1982 name, element.getName()); | 1990 name, element.getName()); |
1983 } | 1991 } |
| 1992 // @deprecated |
| 1993 if (element != null && element.getMetadata().isDeprecated()) { |
| 1994 onError(node.getName(), TypeErrorCode.DEPRECATED_ELEMENT, name); |
| 1995 } |
| 1996 // analyze Element |
1984 switch (element.getKind()) { | 1997 switch (element.getKind()) { |
1985 case DYNAMIC: | 1998 case DYNAMIC: |
1986 return dynamicType; | 1999 return dynamicType; |
1987 case CONSTRUCTOR: | 2000 case CONSTRUCTOR: |
1988 return typeError(node.getName(), TypeErrorCode.MEMBER_IS_A_CONSTRUCTOR
, | 2001 return typeError(node.getName(), TypeErrorCode.MEMBER_IS_A_CONSTRUCTOR
, |
1989 name, element.getName()); | 2002 name, element.getName()); |
1990 | 2003 |
1991 case METHOD: | 2004 case METHOD: |
1992 return member.getType(); | 2005 return member.getType(); |
1993 | 2006 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 // bit operations, we currently allow them to be used | 2181 // bit operations, we currently allow them to be used |
2169 // if the left-hand-side is of type num. | 2182 // if the left-hand-side is of type num. |
2170 // TODO(karlklose) find a clean solution, i.e., without a special case
for num. | 2183 // TODO(karlklose) find a clean solution, i.e., without a special case
for num. |
2171 if (type.equals(numType)) { | 2184 if (type.equals(numType)) { |
2172 return intType; | 2185 return intType; |
2173 } else { | 2186 } else { |
2174 String name = methodNameForUnaryOperator(node, operator); | 2187 String name = methodNameForUnaryOperator(node, operator); |
2175 HasSourceInfo problemTarget = getOperatorHasSourceInfo(node); | 2188 HasSourceInfo problemTarget = getOperatorHasSourceInfo(node); |
2176 Member member = lookupMember(type, name, problemTarget); | 2189 Member member = lookupMember(type, name, problemTarget); |
2177 if (member != null) { | 2190 if (member != null) { |
2178 node.setElement(member.getElement()); | 2191 Element element = member.getElement(); |
| 2192 node.setElement(element); |
2179 FunctionType methodType = getMethodType(type, member, name, node); | 2193 FunctionType methodType = getMethodType(type, member, name, node); |
| 2194 checkDeprecated(problemTarget, element); |
2180 return checkInvocation(Collections.<DartExpression>emptyList(), no
de, name, methodType); | 2195 return checkInvocation(Collections.<DartExpression>emptyList(), no
de, name, methodType); |
2181 } else { | 2196 } else { |
2182 return dynamicType; | 2197 return dynamicType; |
2183 } | 2198 } |
2184 } | 2199 } |
2185 case NOT: | 2200 case NOT: |
2186 checkAssignable(boolType, expression); | 2201 checkAssignable(boolType, expression); |
2187 return boolType; | 2202 return boolType; |
2188 case SUB: | 2203 case SUB: |
2189 case INC: | 2204 case INC: |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2259 if (type instanceof InterfaceType) { | 2274 if (type instanceof InterfaceType) { |
2260 InterfaceType interfaceType = (InterfaceType) type; | 2275 InterfaceType interfaceType = (InterfaceType) type; |
2261 Element callElement = interfaceType.getElement().lookupLocalElement(
"call"); | 2276 Element callElement = interfaceType.getElement().lookupLocalElement(
"call"); |
2262 if (ElementKind.of(callElement) == ElementKind.METHOD) { | 2277 if (ElementKind.of(callElement) == ElementKind.METHOD) { |
2263 node.setElement(callElement); | 2278 node.setElement(callElement); |
2264 type = typeAsMemberOf(callElement, interfaceType); | 2279 type = typeAsMemberOf(callElement, interfaceType); |
2265 } | 2280 } |
2266 } | 2281 } |
2267 break; | 2282 break; |
2268 } | 2283 } |
| 2284 checkDeprecated(target, element); |
2269 return checkInvocation(node, target, name, type); | 2285 return checkInvocation(node, target, name, type); |
2270 } | 2286 } |
2271 | 2287 |
| 2288 /** |
| 2289 * Report warning if given {@link Element} is deprecated. |
| 2290 */ |
| 2291 private void checkDeprecated(HasSourceInfo nameNode, Element element) { |
| 2292 if (element != null && element.getMetadata().isDeprecated()) { |
| 2293 onError(nameNode, TypeErrorCode.DEPRECATED_ELEMENT, element); |
| 2294 } |
| 2295 } |
| 2296 |
2272 private Type checkInvocation(DartInvocation node, DartNode diagnosticNode, S
tring name, | 2297 private Type checkInvocation(DartInvocation node, DartNode diagnosticNode, S
tring name, |
2273 Type type) { | 2298 Type type) { |
2274 List<DartExpression> argumentNodes = node.getArguments(); | 2299 List<DartExpression> argumentNodes = node.getArguments(); |
2275 return checkInvocation(argumentNodes, diagnosticNode, name, type); | 2300 return checkInvocation(argumentNodes, diagnosticNode, name, type); |
2276 } | 2301 } |
2277 | 2302 |
2278 private Type checkInvocation(List<DartExpression> argumentNodes, | 2303 private Type checkInvocation(List<DartExpression> argumentNodes, DartNode di
agnosticNode, |
2279 DartNode diagnosticNode, String name, Type type) { | 2304 String name, Type type) { |
2280 // Prepare argument types. | 2305 // Prepare argument types. |
2281 List<Type> argumentTypes = Lists.newArrayListWithCapacity(argumentNodes.si
ze()); | 2306 List<Type> argumentTypes = Lists.newArrayListWithCapacity(argumentNodes.si
ze()); |
2282 for (DartExpression argumentNode : argumentNodes) { | 2307 for (DartExpression argumentNode : argumentNodes) { |
2283 Type argumentType = getInvocationArgumentType(argumentNode); | 2308 Type argumentType = getInvocationArgumentType(argumentNode); |
2284 argumentTypes.add(argumentType); | 2309 argumentTypes.add(argumentType); |
2285 } | 2310 } |
2286 // Check that argument types are compatible with type of invoked object. | 2311 // Check that argument types are compatible with type of invoked object. |
2287 try { | 2312 try { |
2288 switch (TypeKind.of(type)) { | 2313 switch (TypeKind.of(type)) { |
2289 case FUNCTION_ALIAS: | 2314 case FUNCTION_ALIAS: |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2531 } | 2556 } |
2532 // prevent recursion | 2557 // prevent recursion |
2533 if (visited.contains(current)) { | 2558 if (visited.contains(current)) { |
2534 return false; | 2559 return false; |
2535 } | 2560 } |
2536 visited.add(current); | 2561 visited.add(current); |
2537 // check type of "current" function type alias | 2562 // check type of "current" function type alias |
2538 return hasFunctionTypeAliasReference(visited, target, current); | 2563 return hasFunctionTypeAliasReference(visited, target, current); |
2539 } | 2564 } |
2540 | 2565 |
| 2566 /** |
| 2567 * @return the {@link DartIdentifier} corresponding to the name of construct
or. |
| 2568 */ |
| 2569 public static DartIdentifier getConstructorNameNode(DartNewExpression node)
{ |
| 2570 DartNode constructor = node.getConstructor(); |
| 2571 return getConstructorNameNode(constructor); |
| 2572 } |
| 2573 |
| 2574 /** |
| 2575 * @return the {@link DartIdentifier} corresponding to the name of construct
or. |
| 2576 */ |
| 2577 public static DartIdentifier getConstructorNameNode(DartNode constructor) { |
| 2578 if (constructor instanceof DartPropertyAccess) { |
| 2579 return ((DartPropertyAccess) constructor).getName(); |
| 2580 } else if (constructor instanceof DartTypeNode) { |
| 2581 return getConstructorNameNode(((DartTypeNode) constructor).getIdentifier
()); |
| 2582 } else { |
| 2583 return (DartIdentifier) constructor; |
| 2584 } |
| 2585 } |
| 2586 |
2541 @Override | 2587 @Override |
2542 public Type visitIntegerLiteral(DartIntegerLiteral node) { | 2588 public Type visitIntegerLiteral(DartIntegerLiteral node) { |
2543 return typeOfLiteral(node); | 2589 return typeOfLiteral(node); |
2544 } | 2590 } |
2545 | 2591 |
2546 @Override | 2592 @Override |
2547 public Type visitStringLiteral(DartStringLiteral node) { | 2593 public Type visitStringLiteral(DartStringLiteral node) { |
2548 return typeOfLiteral(node); | 2594 return typeOfLiteral(node); |
2549 } | 2595 } |
2550 | 2596 |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2860 for (VariableElement v : parameters) { | 2906 for (VariableElement v : parameters) { |
2861 if (v.isNamed()) { | 2907 if (v.isNamed()) { |
2862 named.add(v); | 2908 named.add(v); |
2863 } | 2909 } |
2864 } | 2910 } |
2865 return named; | 2911 return named; |
2866 } | 2912 } |
2867 } | 2913 } |
2868 } | 2914 } |
2869 } | 2915 } |
OLD | NEW |