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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 } catch (CyclicDeclarationException e) { | 220 } catch (CyclicDeclarationException e) { |
221 DartNode node = e.getElement().getNode(); | 221 DartNode node = e.getElement().getNode(); |
222 if (node == null) { | 222 if (node == null) { |
223 node = cls; | 223 node = cls; |
224 } | 224 } |
225 onError(node, ResolverErrorCode.CYCLIC_CLASS, e.getElement().getName()); | 225 onError(node, ResolverErrorCode.CYCLIC_CLASS, e.getElement().getName()); |
226 } catch (DuplicatedInterfaceException e) { | 226 } catch (DuplicatedInterfaceException e) { |
227 onError(cls, ResolverErrorCode.DUPLICATED_INTERFACE, | 227 onError(cls, ResolverErrorCode.DUPLICATED_INTERFACE, |
228 e.getFirst(), e.getSecond()); | 228 e.getFirst(), e.getSecond()); |
229 } | 229 } |
| 230 |
| 231 checkClassTypeVariables(classElement); |
| 232 |
| 233 // Push new resolution context. |
230 ResolutionContext previousContext = context; | 234 ResolutionContext previousContext = context; |
231 EnclosingElement previousHolder = currentHolder; | 235 EnclosingElement previousHolder = currentHolder; |
232 currentHolder = classElement; | 236 currentHolder = classElement; |
233 context = topLevelContext.extend(classElement); | 237 context = topLevelContext.extend(classElement); |
234 | 238 |
235 for (Element element : classElement.getMembers()) { | 239 for (Element element : classElement.getMembers()) { |
236 element.getNode().accept(this); | 240 element.getNode().accept(this); |
237 } | 241 } |
238 | 242 |
239 for (Element element : classElement.getConstructors()) { | 243 for (Element element : classElement.getConstructors()) { |
240 element.getNode().accept(this); | 244 element.getNode().accept(this); |
241 } | 245 } |
242 | 246 |
243 checkRedirectConstructorCycle(classElement.getConstructors(), context); | 247 checkRedirectConstructorCycle(classElement.getConstructors(), context); |
244 if (Elements.needsImplicitDefaultConstructor(classElement)) { | 248 if (Elements.needsImplicitDefaultConstructor(classElement)) { |
245 checkImplicitDefaultDefaultSuperInvocation(cls, classElement); | 249 checkImplicitDefaultDefaultSuperInvocation(cls, classElement); |
246 } | 250 } |
247 | 251 |
248 // Check that interface constructors have corresponding methods in default
class. | 252 // Check that interface constructors have corresponding methods in default
class. |
249 if (cls.getDefaultClass() != null) { | 253 if (cls.getDefaultClass() != null) { |
250 checkInteraceConstructors(classElement); | 254 checkInteraceConstructors(classElement); |
251 } | 255 } |
252 | 256 |
253 context = previousContext; | 257 context = previousContext; |
254 currentHolder = previousHolder; | 258 currentHolder = previousHolder; |
255 return classElement; | 259 return classElement; |
256 } | 260 } |
257 | 261 |
258 /** | 262 /** |
| 263 * Check that used type variables are unique and don't shadow and existing e
lements. |
| 264 */ |
| 265 private void checkClassTypeVariables(ClassElement classElement) { |
| 266 Scope scope = context.getScope(); |
| 267 Set<String> declaredVariableNames = Sets.newHashSet(); |
| 268 for (Type type : classElement.getTypeParameters()) { |
| 269 if (type instanceof TypeVariable) { |
| 270 Element typeVariableElement = type.getElement(); |
| 271 String name = typeVariableElement.getName(); |
| 272 // Check that type variables are unique in this Class declaration. |
| 273 if (declaredVariableNames.contains(name)) { |
| 274 onError(typeVariableElement.getNode(), ResolverErrorCode.DUPLICATE_T
YPE_VARIABLE, name); |
| 275 } else { |
| 276 declaredVariableNames.add(name); |
| 277 } |
| 278 // Check that type variable is not shadowing any element in enclosing
context. |
| 279 Element existingElement = scope.findElement(scope.getLibrary(), name); |
| 280 if (existingElement != null) { |
| 281 onError( |
| 282 typeVariableElement.getNode(), |
| 283 ResolverErrorCode.DUPLICATE_TYPE_VARIABLE_WARNING, |
| 284 name, |
| 285 existingElement, |
| 286 Elements.getRelativeElementLocation(typeVariableElement, existin
gElement)); |
| 287 } |
| 288 } |
| 289 } |
| 290 } |
| 291 |
| 292 /** |
259 * Checks that interface constructors have corresponding methods in default
class. | 293 * Checks that interface constructors have corresponding methods in default
class. |
260 */ | 294 */ |
261 private void checkInteraceConstructors(ClassElement interfaceElement) { | 295 private void checkInteraceConstructors(ClassElement interfaceElement) { |
262 String interfaceClassName = interfaceElement.getName(); | 296 String interfaceClassName = interfaceElement.getName(); |
263 String defaultClassName = interfaceElement.getDefaultClass().getElement().
getName(); | 297 String defaultClassName = interfaceElement.getDefaultClass().getElement().
getName(); |
264 for (ConstructorElement interfaceConstructor : interfaceElement.getConstru
ctors()) { | 298 for (ConstructorElement interfaceConstructor : interfaceElement.getConstru
ctors()) { |
265 ConstructorElement defaultConstructor = | 299 ConstructorElement defaultConstructor = |
266 resolveInterfaceConstructorInDefaultClass( | 300 resolveInterfaceConstructorInDefaultClass( |
267 interfaceConstructor.getNode(), | 301 interfaceConstructor.getNode(), |
268 interfaceConstructor); | 302 interfaceConstructor); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 ResolutionContext previousContext = context; | 388 ResolutionContext previousContext = context; |
355 context = context.extend(member.getName()); | 389 context = context.extend(member.getName()); |
356 assert currentMethod == null : "Nested methods?"; | 390 assert currentMethod == null : "Nested methods?"; |
357 innermostFunction = currentMethod = member; | 391 innermostFunction = currentMethod = member; |
358 | 392 |
359 DartFunction functionNode = node.getFunction(); | 393 DartFunction functionNode = node.getFunction(); |
360 List<DartParameter> parameters = functionNode.getParams(); | 394 List<DartParameter> parameters = functionNode.getParams(); |
361 | 395 |
362 FunctionType type = (FunctionType) member.getType(); | 396 FunctionType type = (FunctionType) member.getType(); |
363 for (TypeVariable typeVariable : type.getTypeVariables()) { | 397 for (TypeVariable typeVariable : type.getTypeVariables()) { |
364 context.declare(typeVariable.getElement()); | 398 context.declare( |
| 399 typeVariable.getElement(), |
| 400 ResolverErrorCode.DUPLICATE_TYPE_VARIABLE, |
| 401 ResolverErrorCode.DUPLICATE_TYPE_VARIABLE_WARNING); |
365 } | 402 } |
366 | 403 |
367 // First declare all normal parameters in the scope, putting them in the | 404 // First declare all normal parameters in the scope, putting them in the |
368 // scope of the default expressions so we can report better errors. | 405 // scope of the default expressions so we can report better errors. |
369 for (DartParameter parameter : parameters) { | 406 for (DartParameter parameter : parameters) { |
370 assert parameter.getSymbol() != null; | 407 assert parameter.getSymbol() != null; |
371 if (parameter.getQualifier() instanceof DartThisExpression) { | 408 if (parameter.getQualifier() instanceof DartThisExpression) { |
372 checkParameterInitializer(node, parameter); | 409 checkParameterInitializer(node, parameter); |
373 } else { | 410 } else { |
374 getContext().declare(parameter.getSymbol()); | 411 getContext().declare( |
| 412 parameter.getSymbol(), |
| 413 ResolverErrorCode.DUPLICATE_PARAMETER, |
| 414 ResolverErrorCode.DUPLICATE_PARAMETER_WARNING); |
375 } | 415 } |
376 } | 416 } |
377 for (DartParameter parameter : parameters) { | 417 for (DartParameter parameter : parameters) { |
378 // Then resolve the default values. | 418 // Then resolve the default values. |
379 resolve(parameter.getDefaultExpr()); | 419 resolve(parameter.getDefaultExpr()); |
380 } | 420 } |
381 | 421 |
382 if ((functionNode.getBody() == null) | 422 if ((functionNode.getBody() == null) |
383 && !Elements.isNonFactoryConstructor(member) | 423 && !Elements.isNonFactoryConstructor(member) |
384 && !member.getModifiers().isAbstract() | 424 && !member.getModifiers().isAbstract() |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 | 542 |
503 @Override | 543 @Override |
504 public Element visitFunction(DartFunction node) { | 544 public Element visitFunction(DartFunction node) { |
505 throw context.internalError(node, "should not be called."); | 545 throw context.internalError(node, "should not be called."); |
506 } | 546 } |
507 | 547 |
508 @Override | 548 @Override |
509 public Element visitParameter(DartParameter x) { | 549 public Element visitParameter(DartParameter x) { |
510 Element element = super.visitParameter(x); | 550 Element element = super.visitParameter(x); |
511 resolve(x.getDefaultExpr()); | 551 resolve(x.getDefaultExpr()); |
512 getContext().declare(element); | 552 getContext().declare( |
| 553 element, |
| 554 ResolverErrorCode.DUPLICATE_PARAMETER, |
| 555 ResolverErrorCode.DUPLICATE_PARAMETER_WARNING); |
513 return element; | 556 return element; |
514 } | 557 } |
515 | 558 |
516 public Element resolveVariable(DartVariable x, Modifiers modifiers) { | 559 public Element resolveVariable(DartVariable x, Modifiers modifiers) { |
517 // Visit the initializer first. | 560 // Visit the initializer first. |
518 resolve(x.getValue()); | 561 resolve(x.getValue()); |
519 VariableElement element = Elements.variableElement(x, x.getVariableName(),
modifiers); | 562 VariableElement element = Elements.variableElement(x, x.getVariableName(),
modifiers); |
520 getContext().declare(recordElement(x, element)); | 563 getContext().declare( |
| 564 recordElement(x, element), |
| 565 ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_ERROR, |
| 566 ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_WARNING); |
521 return element; | 567 return element; |
522 } | 568 } |
523 | 569 |
524 @Override | 570 @Override |
525 public Element visitVariableStatement(DartVariableStatement node) { | 571 public Element visitVariableStatement(DartVariableStatement node) { |
526 resolveVariableStatement(node, false); | 572 resolveVariableStatement(node, false); |
527 return null; | 573 return null; |
528 } | 574 } |
529 | 575 |
530 private void resolveVariableStatement(DartVariableStatement node, | 576 private void resolveVariableStatement(DartVariableStatement node, |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1582 ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclos
ingElement(); | 1628 ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclos
ingElement(); |
1583 ClassElement currentClass = (ClassElement) constructor.getEnclosingEleme
nt(); | 1629 ClassElement currentClass = (ClassElement) constructor.getEnclosingEleme
nt(); |
1584 if (nextClass.getName().equals(currentClass.getName())) { | 1630 if (nextClass.getName().equals(currentClass.getName())) { |
1585 return nextConstructorElement; | 1631 return nextConstructorElement; |
1586 } | 1632 } |
1587 } | 1633 } |
1588 } | 1634 } |
1589 return null; | 1635 return null; |
1590 } | 1636 } |
1591 } | 1637 } |
OLD | NEW |