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

Side by Side Diff: compiler/java/com/google/dart/compiler/resolver/Resolver.java

Issue 8231031: Check for compile-time constants in DartCompiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Renamed CompileTimeConstTest to CTConst2Test Created 9 years, 2 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) 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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698