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

Side by Side Diff: compiler/java/com/google/dart/compiler/parser/DartParserCommentsHelper.java

Issue 10661022: Issue 3752. Support for @override annotations (as structured doc comments) (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 package com.google.dart.compiler.parser;
6
7 import com.google.common.collect.Lists;
8 import com.google.dart.compiler.DartCompilerListener;
9 import com.google.dart.compiler.Source;
10 import com.google.dart.compiler.ast.ASTVisitor;
11 import com.google.dart.compiler.ast.DartComment;
12 import com.google.dart.compiler.ast.DartDeclaration;
13 import com.google.dart.compiler.ast.DartField;
14 import com.google.dart.compiler.ast.DartMethodDefinition;
15 import com.google.dart.compiler.ast.DartNode;
16 import com.google.dart.compiler.ast.DartUnit;
17 import com.google.dart.compiler.common.SourceInfo;
18 import com.google.dart.compiler.metrics.CompilerMetrics;
19
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.Comparator;
23 import java.util.List;
24
25 /**
26 * A parser for Dart that records comment positions.
27 */
28 public class DartParserCommentsHelper {
29
30 static class CommentParserContext extends DartScannerParserContext {
31
32 private List<int[]> commentLocs;
33
34 CommentParserContext(Source source, String code, DartCompilerListener listen er,
35 CompilerMetrics metrics) {
36 super(source, code, listener, metrics);
37 }
38
39 List<int[]> getCommentLocs() {
40 return commentLocs;
41 }
42
43 @Override
44 protected DartScanner createScanner(String sourceCode) {
45 commentLocs = Lists.newArrayList();
46 return new CommentScanner(sourceCode);
47 }
48
49 private class CommentScanner extends DartScanner {
50
51 CommentScanner(String sourceCode) {
52 super(sourceCode);
53 }
54
55 @Override
56 protected void recordCommentLocation(int start, int stop, int line, int co l) {
57 int size = commentLocs.size();
58 if (size > 0) {
59 // the parser may re-scan lookahead tokens
60 // fortunately, comments are always scanned as comments
61 int[] loc = commentLocs.get(size - 1);
62 if (start <= loc[0] && stop <= loc[1]) {
63 return;
64 }
65 }
66 commentLocs.add(new int[] {start, stop});
67 }
68 }
69 }
70
71 static void addComments(DartUnit unit, Source source, String sourceCode, List< int[]> commentLocs) {
72 for (int[] loc : commentLocs) {
73 int start = loc[0];
74 int length = loc[1] - start;
75 DartComment.Style style = getCommentStyle(sourceCode, start);
76 unit.getComments().add(new DartComment(source, start, length, style));
77 }
78 List<DartComment> comments = unit.getComments();
79 if (comments != null) {
80 assignDartComments(unit, sourceCode, comments);
81 }
82 }
83
84 private static void assignDartComments(DartUnit unit, String sourceCode,
85 List<DartComment> comments) {
86 // Collect the AST nodes in a list.
87 final List<DartNode> astNodes = new ArrayList<DartNode>();
88 unit.accept(new ASTVisitor<DartNode>() {
89 @Override
90 public DartNode visitDeclaration(DartDeclaration<?> node) {
91 astNodes.add(node);
92 // Avoid NPE in visitors because of missing part.
93 try {
94 super.visitDeclaration(node);
95 } catch (NullPointerException e) {
96 }
97 // No result.
98 return null;
99 }
100 });
101
102 // Collect all the nodes in one list.
103 List<DartNode> nodes = new ArrayList<DartNode>();
104
105 nodes.addAll(comments);
106 nodes.addAll(astNodes);
107
108 // Sort the nodes by their position in the source file.
109 Collections.sort(nodes, new Comparator<DartNode>() {
110 @Override
111 public int compare(DartNode node1, DartNode node2) {
112 return node1.getSourceInfo().getOffset() - node2.getSourceInfo().getOffs et();
113 }
114 });
115
116 // Assign dart docs to their associated DartDeclarations.
117 for (int i = 0; i < nodes.size(); i++) {
118 DartNode node = nodes.get(i);
119 if (node instanceof DartComment) {
120 DartComment comment = (DartComment) node;
121 // prepare next declaration
122 DartDeclaration<?> decl = null;
123 {
124 int delta = 1;
125 while (i + delta < nodes.size()) {
126 DartNode next = nodes.get(i + delta);
127 // skip all comments
128 if (next instanceof DartComment) {
129 delta++;
130 continue;
131 }
132 // declaration found
133 if (next instanceof DartDeclaration) {
134 decl = (DartDeclaration<?>) next;
135 if (!commentContainedBySibling(comment, decl)) {
136 if (i + 2 < nodes.size()) {
137 decl = adjustDartdocTarget(next, nodes.get(i + 2));
138 }
139 }
140 break;
141 }
142 // something other than declaration
143 break;
144 }
145 }
146 // apply comment to declaration
147 if (decl != null) {
148 String commentStr = sourceCode.substring(comment.getSourceInfo().getOf fset(),
149 comment.getSourceInfo().getEnd());
150 // may be @Metadata
151 if (commentStr.contains("@deprecated")) {
152 decl.setMetadata(decl.getMetadata().makeDeprecated());
153 }
154 if (commentStr.contains("@override")) {
155 decl.setMetadata(decl.getMetadata().makeOverride());
156 }
157 // DartDoc
158 if (comment.isDartDoc()) {
159 decl.setDartDoc(comment);
160 }
161 }
162 }
163 }
164 }
165
166 private static DartDeclaration<?> adjustDartdocTarget(DartNode currentNode, Da rtNode nextNode) {
167 if (currentNode instanceof DartField && nextNode instanceof DartMethodDefini tion) {
168 if (currentNode.getSourceInfo().equals(nextNode.getSourceInfo())) {
169 return (DartDeclaration<?>) nextNode;
170 }
171 }
172
173 return (DartDeclaration<?>) currentNode;
174 }
175
176 /**
177 * DartC creates both a DartField and a DartMethodDefinition for getters and s etters. They have
178 * the same source location; we want to assign the DartDoc to the method defin ition and not the
179 * field.
180 */
181 private static boolean commentContainedBySibling(DartComment comment, DartDecl aration<?> node) {
182 for (DartNode child : getChildren(node.getParent())) {
183 if (child != node && !(child instanceof DartComment)) {
184 if (isContainedBy(comment, child)) {
185 return true;
186 }
187 }
188 }
189
190 return false;
191 }
192
193 private static List<DartNode> getChildren(DartNode parent) {
194 final List<DartNode> children = new ArrayList<DartNode>();
195
196 parent.visitChildren(new ASTVisitor<DartNode>() {
197 @Override
198 public DartNode visitNode(DartNode node) {
199 children.add(node);
200 return null;
201 }
202 });
203
204 return children;
205 }
206
207 private static boolean isContainedBy(DartNode node, DartNode containedByNode) {
208 SourceInfo nodeSource = node.getSourceInfo();
209 SourceInfo containedBySource = containedByNode.getSourceInfo();
210 int nodeEnd = nodeSource.getOffset() + nodeSource.getLength();
211 int containedByEnd = containedBySource.getOffset() + containedBySource.getLe ngth();
212 return nodeSource.getOffset() >= containedBySource.getOffset() && nodeEnd <= containedByEnd;
213 }
214
215 /**
216 * Return the style of the comment in the given string.
217 *
218 * @param sourceString the source containing the comment
219 * @param commentStart the location of the comment in the source
220 * @return the style of the comment in the given string
221 */
222 private static DartComment.Style getCommentStyle(String sourceString, int comm entStart) {
223 boolean hasMore1 = commentStart + 1 < sourceString.length();
224 boolean hasMore2 = commentStart + 2 < sourceString.length();
225 if (hasMore1 && sourceString.charAt(commentStart + 1) == '/') {
226 return DartComment.Style.END_OF_LINE;
227 } else if (hasMore2 && sourceString.charAt(commentStart + 2) == '*') {
228 return DartComment.Style.DART_DOC;
229 }
230 return DartComment.Style.BLOCK;
231 }
232 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698