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

Side by Side Diff: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java

Issue 10703046: Issue 3753. Support for @deprecated annotation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Analyze for @deprecated all invocable elements Created 8 years, 5 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) 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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698