Chromium Code Reviews| 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 package com.google.dart.compiler.resolver; | 5 package com.google.dart.compiler.resolver; |
| 6 | 6 |
| 7 import com.google.common.annotations.VisibleForTesting; | 7 import com.google.common.annotations.VisibleForTesting; |
| 8 import com.google.common.collect.Sets; | 8 import com.google.common.collect.Sets; |
| 9 import com.google.dart.compiler.DartCompilationPhase; | 9 import com.google.dart.compiler.DartCompilationPhase; |
| 10 import com.google.dart.compiler.DartCompilerContext; | 10 import com.google.dart.compiler.DartCompilerContext; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 import com.google.dart.compiler.ast.DartSwitchMember; | 52 import com.google.dart.compiler.ast.DartSwitchMember; |
| 53 import com.google.dart.compiler.ast.DartSwitchStatement; | 53 import com.google.dart.compiler.ast.DartSwitchStatement; |
| 54 import com.google.dart.compiler.ast.DartThisExpression; | 54 import com.google.dart.compiler.ast.DartThisExpression; |
| 55 import com.google.dart.compiler.ast.DartTryStatement; | 55 import com.google.dart.compiler.ast.DartTryStatement; |
| 56 import com.google.dart.compiler.ast.DartTypeNode; | 56 import com.google.dart.compiler.ast.DartTypeNode; |
| 57 import com.google.dart.compiler.ast.DartTypedLiteral; | 57 import com.google.dart.compiler.ast.DartTypedLiteral; |
| 58 import com.google.dart.compiler.ast.DartUnit; | 58 import com.google.dart.compiler.ast.DartUnit; |
| 59 import com.google.dart.compiler.ast.DartUnqualifiedInvocation; | 59 import com.google.dart.compiler.ast.DartUnqualifiedInvocation; |
| 60 import com.google.dart.compiler.ast.DartVariable; | 60 import com.google.dart.compiler.ast.DartVariable; |
| 61 import com.google.dart.compiler.ast.DartVariableStatement; | 61 import com.google.dart.compiler.ast.DartVariableStatement; |
| 62 import com.google.dart.compiler.ast.DartVisitor; | |
| 62 import com.google.dart.compiler.ast.DartWhileStatement; | 63 import com.google.dart.compiler.ast.DartWhileStatement; |
| 63 import com.google.dart.compiler.ast.Modifiers; | 64 import com.google.dart.compiler.ast.Modifiers; |
| 64 import com.google.dart.compiler.type.FunctionType; | 65 import com.google.dart.compiler.type.FunctionType; |
| 65 import com.google.dart.compiler.type.InterfaceType; | 66 import com.google.dart.compiler.type.InterfaceType; |
| 66 import com.google.dart.compiler.type.InterfaceType.Member; | 67 import com.google.dart.compiler.type.InterfaceType.Member; |
| 67 import com.google.dart.compiler.type.Type; | 68 import com.google.dart.compiler.type.Type; |
| 68 import com.google.dart.compiler.type.TypeVariable; | 69 import com.google.dart.compiler.type.TypeVariable; |
| 69 | 70 |
| 70 import java.util.EnumSet; | 71 import java.util.EnumSet; |
| 71 import java.util.Iterator; | 72 import java.util.Iterator; |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 | 332 |
| 332 if (Elements.isNonFactoryConstructor(member)) { | 333 if (Elements.isNonFactoryConstructor(member)) { |
| 333 resolveInitializers(node); | 334 resolveInitializers(node); |
| 334 } | 335 } |
| 335 | 336 |
| 336 context = previousContext; | 337 context = previousContext; |
| 337 innermostFunction = currentMethod = null; | 338 innermostFunction = currentMethod = null; |
| 338 return member; | 339 return member; |
| 339 } | 340 } |
| 340 | 341 |
| 341 private void resolveConstantExpression(DartExpression defaultExpr) { | 342 private void resolveConstantExpression(DartExpression expr) { |
| 342 resolve(defaultExpr); | 343 resolve(expr); |
| 343 checkConstantExpression(defaultExpr); | 344 checkConstantExpression(expr); |
| 344 } | 345 } |
| 345 | 346 |
| 346 private void checkConstantExpression(DartExpression defaultExpr) { | 347 private void checkConstantExpression(DartExpression expr) { |
| 347 // See bug 4568007. | 348 if (expr != null) { |
| 348 } | 349 DartVisitor v = CompileTimeConstVisitor.create(typeProvider, context); |
| 349 | 350 v.accept(expr); |
| 350 private void checkConstantLiteral(DartExpression defaultExpr) { | |
| 351 if ((!(defaultExpr instanceof DartLiteral)) | |
| 352 || ((defaultExpr instanceof DartTypedLiteral) | |
| 353 && (!((DartTypedLiteral) defaultExpr).isConst()))) { | |
| 354 resolutionError(defaultExpr, DartCompilerErrorCode.EXPECTED_CONSTANT_LIT ERAL); | |
| 355 } | 351 } |
| 356 } | 352 } |
| 357 | 353 |
| 354 private void checkConstantLiteral(DartExpression expr) { | |
| 355 boolean isConstant = true; | |
| 356 if (expr instanceof DartStringInterpolation) { | |
| 357 isConstant = false; | |
| 358 } else if (expr instanceof DartLiteral) { | |
| 359 if (expr instanceof DartTypedLiteral && !((DartTypedLiteral) expr).isCon st()){ | |
| 360 isConstant = false; | |
| 361 } | |
| 362 } else { | |
| 363 isConstant = false; | |
| 364 } | |
| 365 | |
| 366 if (!isConstant) { | |
| 367 resolutionError(expr, DartCompilerErrorCode.EXPECTED_CONSTANT_LITERAL); | |
| 368 } | |
| 369 } | |
| 370 | |
| 358 @Override | 371 @Override |
| 359 public Element visitField(DartField node) { | 372 public Element visitField(DartField node) { |
| 360 DartExpression expression = node.getValue(); | 373 DartExpression expression = node.getValue(); |
| 361 Modifiers modifiers = node.getModifiers(); | 374 Modifiers modifiers = node.getModifiers(); |
| 362 boolean isStatic = modifiers.isStatic(); | 375 boolean isStatic = modifiers.isStatic(); |
| 363 boolean isFinal = modifiers.isFinal(); | 376 boolean isFinal = modifiers.isFinal(); |
| 364 boolean isTopLevel = ElementKind.of(currentHolder).equals(ElementKind.LIBR ARY); | 377 boolean isTopLevel = ElementKind.of(currentHolder).equals(ElementKind.LIBR ARY); |
| 365 | 378 |
| 366 if (expression != null) { | 379 if (expression != null) { |
| 380 resolve(expression); | |
| 367 if (isStatic || isTopLevel) { | 381 if (isStatic || isTopLevel) { |
| 368 checkConstantExpression(expression); | 382 checkConstantExpression(expression); |
| 383 // Now, this constant has a type. Save it for future reference | |
| 384 Element element = node.getSymbol(); | |
| 385 if (expression.getType() != null) { | |
| 386 Elements.setType(element, expression.getType()); | |
| 387 } | |
| 369 } else { | 388 } else { |
| 370 // TODO(5200401): Only allow constant literals for inline field initia lizers for now. | 389 // TODO(5200401): Only allow constant literals for inline field initia lizers for now. |
| 371 checkConstantLiteral(expression); | 390 checkConstantLiteral(expression); |
|
ngeoffray
2011/10/14 09:26:56
Could you remove that TODO now? We should be able
zundel
2011/10/14 10:04:21
I wasn't sure that non static variables needed to
ngeoffray
2011/10/14 10:33:42
Right now, non-static variables can only have comp
floitsch
2011/10/14 14:36:58
I agree. This should be a checkConstantExpression.
| |
| 372 } | 391 } |
| 373 resolve(expression); | |
| 374 } else if (isStatic && isFinal) { | 392 } else if (isStatic && isFinal) { |
| 375 resolutionError(node, DartCompilerErrorCode.STATIC_FINAL_REQUIRES_VALUE) ; | 393 resolutionError(node, DartCompilerErrorCode.STATIC_FINAL_REQUIRES_VALUE) ; |
| 376 } | 394 } |
| 377 | 395 |
| 378 // If field is an acessor, both getter and setter need to be visited (if p resent). | 396 // If field is an accessor, both getter and setter need to be visited (if present). |
| 379 FieldElement field = node.getSymbol(); | 397 FieldElement field = node.getSymbol(); |
| 380 if (field.getGetter() != null) { | 398 if (field.getGetter() != null) { |
| 381 resolve(field.getGetter().getNode()); | 399 resolve(field.getGetter().getNode()); |
| 382 } | 400 } |
| 383 if (field.getSetter() != null) { | 401 if (field.getSetter() != null) { |
| 384 resolve(field.getSetter().getNode()); | 402 resolve(field.getSetter().getNode()); |
| 385 } | 403 } |
| 386 return null; | 404 return null; |
| 387 } | 405 } |
| 388 | 406 |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 847 | 865 |
| 848 @Override | 866 @Override |
| 849 public Element visitFunctionObjectInvocation(DartFunctionObjectInvocation x) { | 867 public Element visitFunctionObjectInvocation(DartFunctionObjectInvocation x) { |
| 850 x.getTarget().accept(this); | 868 x.getTarget().accept(this); |
| 851 visit(x.getArgs()); | 869 visit(x.getArgs()); |
| 852 return null; | 870 return null; |
| 853 } | 871 } |
| 854 | 872 |
| 855 @Override | 873 @Override |
| 856 public Element visitNewExpression(DartNewExpression x) { | 874 public Element visitNewExpression(DartNewExpression x) { |
| 875 | |
| 857 this.visit(x.getArgs()); | 876 this.visit(x.getArgs()); |
| 858 | 877 |
| 878 if (x.isConst()) { | |
| 879 for (DartExpression arg : x.getArgs()) { | |
| 880 checkConstantExpression(arg); | |
| 881 } | |
| 882 } | |
| 883 | |
| 859 Element element = x.getConstructor().accept(getContext().new Selector() { | 884 Element element = x.getConstructor().accept(getContext().new Selector() { |
| 860 // Only 'new' expressions can have a type in a property access. | 885 // Only 'new' expressions can have a type in a property access. |
| 861 @Override public Element visitTypeNode(DartTypeNode type) { | 886 @Override public Element visitTypeNode(DartTypeNode type) { |
| 862 return recordType(type, resolveType(type, inStaticContext(currentMetho d))); | 887 return recordType(type, resolveType(type, inStaticContext(currentMetho d))); |
| 863 } | 888 } |
| 864 | 889 |
| 865 @Override public Element visitPropertyAccess(DartPropertyAccess node) { | 890 @Override public Element visitPropertyAccess(DartPropertyAccess node) { |
| 866 Element element = node.getQualifier().accept(this); | 891 Element element = node.getQualifier().accept(this); |
| 867 if (ElementKind.of(element).equals(ElementKind.CLASS)) { | 892 if (ElementKind.of(element).equals(ElementKind.CLASS)) { |
| 868 return Elements.lookupConstructor(((ClassElement) element), node.get PropertyName()); | 893 return Elements.lookupConstructor(((ClassElement) element), node.get PropertyName()); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1217 && ElementKind.of(target).equals(ElementKind.METHOD)) { | 1242 && ElementKind.of(target).equals(ElementKind.METHOD)) { |
| 1218 if (!target.getModifiers().isStatic() && !Elements.isTopLevel(target)) { | 1243 if (!target.getModifiers().isStatic() && !Elements.isTopLevel(target)) { |
| 1219 resolutionError(node, DartCompilerErrorCode.INSTANCE_METHOD_FROM_STATI C); | 1244 resolutionError(node, DartCompilerErrorCode.INSTANCE_METHOD_FROM_STATI C); |
| 1220 } | 1245 } |
| 1221 } | 1246 } |
| 1222 } | 1247 } |
| 1223 | 1248 |
| 1224 private void checkVariableStatement(DartVariableStatement node, | 1249 private void checkVariableStatement(DartVariableStatement node, |
| 1225 DartVariable variable, | 1250 DartVariable variable, |
| 1226 boolean isImplicitlyInitialized) { | 1251 boolean isImplicitlyInitialized) { |
| 1227 if (node.getModifiers().isFinal()) { | 1252 Modifiers modifiers = node.getModifiers(); |
| 1253 if (modifiers.isFinal()) { | |
| 1228 if (!isImplicitlyInitialized && (variable.getValue() == null)) { | 1254 if (!isImplicitlyInitialized && (variable.getValue() == null)) { |
| 1229 resolutionError(variable.getName(), DartCompilerErrorCode.CONSTANTS_MU ST_BE_INITIALIZED); | 1255 resolutionError(variable.getName(), DartCompilerErrorCode.CONSTANTS_MU ST_BE_INITIALIZED); |
| 1230 } else if (isImplicitlyInitialized && (variable.getValue() != null)) { | 1256 } else if (isImplicitlyInitialized && (variable.getValue() != null)) { |
| 1231 resolutionError(variable.getName(), DartCompilerErrorCode.CANNOT_BE_IN ITIALIZED); | 1257 resolutionError(variable.getName(), DartCompilerErrorCode.CANNOT_BE_IN ITIALIZED); |
| 1232 } else { | 1258 } else if (modifiers.isConstant() && variable.getValue() != null) { |
| 1233 checkConstantExpression(variable.getValue()); | 1259 resolveConstantExpression(variable.getValue()); |
| 1260 node.setType(variable.getValue().getType()); | |
| 1234 } | 1261 } |
| 1235 } | 1262 } |
| 1236 } | 1263 } |
| 1237 | 1264 |
| 1238 private void checkParameterInitializer(DartMethodDefinition method, DartPara meter parameter) { | 1265 private void checkParameterInitializer(DartMethodDefinition method, DartPara meter parameter) { |
| 1239 if (Elements.isNonFactoryConstructor(method.getSymbol())) { | 1266 if (Elements.isNonFactoryConstructor(method.getSymbol())) { |
| 1240 if (method.getModifiers().isRedirectedConstructor()) { | 1267 if (method.getModifiers().isRedirectedConstructor()) { |
| 1241 resolutionError(parameter.getName(), | 1268 resolutionError(parameter.getName(), |
| 1242 DartCompilerErrorCode.PARAMETER_INIT_WITH_REDIR_CONSTRUCTOR); | 1269 DartCompilerErrorCode.PARAMETER_INIT_WITH_REDIR_CONSTRUCTOR); |
| 1243 } | 1270 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1344 ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclos ingElement(); | 1371 ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclos ingElement(); |
| 1345 ClassElement currentClass = (ClassElement) constructor.getEnclosingEleme nt(); | 1372 ClassElement currentClass = (ClassElement) constructor.getEnclosingEleme nt(); |
| 1346 if (nextClass.getName().equals(currentClass.getName())) { | 1373 if (nextClass.getName().equals(currentClass.getName())) { |
| 1347 return nextConstructorElement; | 1374 return nextConstructorElement; |
| 1348 } | 1375 } |
| 1349 } | 1376 } |
| 1350 } | 1377 } |
| 1351 return null; | 1378 return null; |
| 1352 } | 1379 } |
| 1353 } | 1380 } |
| OLD | NEW |