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 |