Chromium Code Reviews| Index: compiler/java/com/google/dart/compiler/parser/DartParser.java |
| diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java |
| index aab12a532fb9fcdbdcfb9c4cafff33b883b7efb3..964f3f52ea41fa9f93a03968fe93264f57e0df41 100644 |
| --- a/compiler/java/com/google/dart/compiler/parser/DartParser.java |
| +++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java |
| @@ -90,6 +90,7 @@ import com.google.dart.compiler.ast.LibraryNode; |
| import com.google.dart.compiler.ast.LibraryUnit; |
| import com.google.dart.compiler.ast.Modifiers; |
| import com.google.dart.compiler.parser.DartScanner.Location; |
| +import com.google.dart.compiler.parser.DartScanner.Position; |
| import com.google.dart.compiler.util.Lists; |
| import java.io.IOException; |
| @@ -111,7 +112,9 @@ public class DartParser extends CompletionHooksParserBase { |
| private Set<String> prefixes; |
| private boolean isDietParse; |
| private boolean isParsingInterface; |
| - private boolean isParsingAbstract; |
| + private boolean isTopLevelAbstract; |
| + private DartScanner.Position topLevelAbstractModifierPosition; |
| + private DartScanner.Position classLevelAbstractModifierPosition; |
| private boolean isParsingClass; |
| /** |
| @@ -254,9 +257,11 @@ public class DartParser extends CompletionHooksParserBase { |
| beginTopLevelElement(); |
| isParsingClass = isParsingInterface = false; |
| // Check for ABSTRACT_KEYWORD. |
| - isParsingAbstract = false; |
| + isTopLevelAbstract = false; |
| + topLevelAbstractModifierPosition = null; |
| if (optionalPseudoKeyword(ABSTRACT_KEYWORD)) { |
| - isParsingAbstract = true; |
| + isTopLevelAbstract = true; |
| + topLevelAbstractModifierPosition = position(); |
| } |
| // Parse top level element. |
| if (optional(Token.CLASS)) { |
| @@ -270,8 +275,21 @@ public class DartParser extends CompletionHooksParserBase { |
| } else { |
| node = done(parseFieldOrMethod(false)); |
| } |
| + // Parsing was successful, add node. |
| if (node != null) { |
| unit.addTopLevelNode(node); |
| + // Only "class" can be top-level abstract element. |
| + if (isTopLevelAbstract) { |
|
codefu
2011/12/29 16:03:05
Couldn't this just be:
if(isTopLevelAbstract && !i
|
| + if (!(node instanceof DartClass) || ((DartClass) node).isInterface()) { |
| + Position abstractPositionEnd = |
| + topLevelAbstractModifierPosition.getAdvancedColumns(ABSTRACT_KEYWORD.length()); |
| + Location location = |
| + new Location(topLevelAbstractModifierPosition, abstractPositionEnd); |
| + reportError(new DartCompilationError(source, |
| + location, |
| + ParserErrorCode.ABSTRACT_TOP_LEVEL_ELEMENT)); |
| + } |
| + } |
| } |
| } catch (ParserException e) { |
| Location beginLocation = ctx.getTokenLocation(); |
| @@ -555,7 +573,7 @@ public class DartParser extends CompletionHooksParserBase { |
| // Parse modifiers. |
| Modifiers modifiers = Modifiers.NONE; |
| - if (isParsingAbstract) { |
| + if (isTopLevelAbstract) { |
| modifiers = modifiers.makeAbstract(); |
| } |
| @@ -853,6 +871,7 @@ public class DartParser extends CompletionHooksParserBase { |
| reportError(position(), ParserErrorCode.ABSTRACT_MEMBER_IN_INTERFACE); |
| } |
| modifiers = modifiers.makeAbstract(); |
| + classLevelAbstractModifierPosition = position(); |
| } else if (optionalPseudoKeyword(FACTORY_KEYWORD)) { |
| if (isParsingInterface) { |
| reportError(position(), ParserErrorCode.FACTORY_MEMBER_IN_INTERFACE); |
| @@ -1192,6 +1211,16 @@ public class DartParser extends CompletionHooksParserBase { |
| private DartNode parseMethodOrAccessor(Modifiers modifiers, DartTypeNode returnType) { |
| DartMethodDefinition method = done(parseMethod(modifiers, returnType)); |
| + // Abstract method can not have a body. |
| + if (method.getModifiers().isAbstract() && method.getFunction().getBody() != null) { |
| + Location location = |
| + new Location(classLevelAbstractModifierPosition, |
| + classLevelAbstractModifierPosition.getAdvancedColumns(ABSTRACT_KEYWORD.length())); |
| + reportError(new DartCompilationError(ctx.getSource(), |
| + location, |
| + ParserErrorCode.ABSTRACT_METHOD_WITH_BODY)); |
| + } |
| + // If getter or setter, generate DartFieldDefinition instead. |
| if (method.getModifiers().isGetter() || method.getModifiers().isSetter()) { |
| DartField field = new DartField((DartIdentifier) method.getName(), |
| method.getModifiers().makeAbstractField(), method, null); |
| @@ -1201,6 +1230,7 @@ public class DartParser extends CompletionHooksParserBase { |
| fieldDefinition.setSourceInfo(field); |
| return fieldDefinition; |
| } |
| + // OK, use method as method. |
| return method; |
| } |
| @@ -3792,6 +3822,6 @@ public class DartParser extends CompletionHooksParserBase { |
| } |
| private boolean currentlyParsingToplevel() { |
| - return !(isParsingInterface || isParsingAbstract || isParsingClass); |
| + return !(isParsingInterface || isTopLevelAbstract || isParsingClass); |
| } |
| } |