OLD | NEW |
---|---|
(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.type; | |
6 | |
7 import com.google.common.collect.Maps; | |
8 import com.google.dart.compiler.ast.DartExpression; | |
9 import com.google.dart.compiler.ast.DartMethodInvocation; | |
10 import com.google.dart.compiler.ast.DartStringLiteral; | |
11 import com.google.dart.compiler.ast.DartUnqualifiedInvocation; | |
12 import com.google.dart.compiler.resolver.Element; | |
13 import com.google.dart.compiler.resolver.ElementKind; | |
14 import com.google.dart.compiler.resolver.Elements; | |
15 import com.google.dart.compiler.resolver.EnclosingElement; | |
16 import com.google.dart.compiler.resolver.LibraryElement; | |
17 import com.google.dart.compiler.util.apache.StringUtils; | |
18 | |
19 import java.util.List; | |
20 import java.util.Map; | |
21 | |
22 /** | |
23 * Provides type information which can not be inferred from source itself. | |
Brian Wilkerson
2012/08/01 17:45:46
nit: "can not" --> "cannot", here and below
| |
24 */ | |
25 public class ExternalTypeAnalyzers { | |
26 private static final Map<String, String> tagToElementType = Maps.newHashMap(); | |
27 static { | |
28 tagToElementType.put("A", "AnchorElement"); | |
29 tagToElementType.put("AREA", "AreaElement"); | |
30 tagToElementType.put("BR", "BRElement"); | |
31 tagToElementType.put("BASE", "BaseElement"); | |
32 tagToElementType.put("BODY", "BodyElement"); | |
33 tagToElementType.put("BUTTON", "ButtonElement"); | |
34 tagToElementType.put("CANVAS", "CanvasElement"); | |
35 tagToElementType.put("DL", "DListElement"); | |
36 tagToElementType.put("DETAILS", "DetailsElement"); | |
37 tagToElementType.put("DIV", "DivElement"); | |
38 tagToElementType.put("EMBED", "EmbedElement"); | |
39 tagToElementType.put("FIELDSET", "FieldSetElement"); | |
40 tagToElementType.put("FORM", "FormElement"); | |
41 tagToElementType.put("HR", "HRElement"); | |
42 tagToElementType.put("HEAD", "HeadElement"); | |
43 tagToElementType.put("H1", "HeadingElement"); | |
44 tagToElementType.put("H2", "HeadingElement"); | |
45 tagToElementType.put("H3", "HeadingElement"); | |
46 tagToElementType.put("H4", "HeadingElement"); | |
47 tagToElementType.put("H5", "HeadingElement"); | |
48 tagToElementType.put("H6", "HeadingElement"); | |
49 tagToElementType.put("HTML", "HtmlElement"); | |
50 tagToElementType.put("IFRAME", "IFrameElement"); | |
51 tagToElementType.put("IMG", "ImageElement"); | |
52 tagToElementType.put("INPUT", "InputElement"); | |
53 tagToElementType.put("KEYGEN", "KeygenElement"); | |
54 tagToElementType.put("LI", "LIElement"); | |
55 tagToElementType.put("LABEL", "LabelElement"); | |
56 tagToElementType.put("LEGEND", "LegendElement"); | |
57 tagToElementType.put("LINK", "LinkElement"); | |
58 tagToElementType.put("MAP", "MapElement"); | |
59 tagToElementType.put("MENU", "MenuElement"); | |
60 tagToElementType.put("METER", "MeterElement"); | |
61 tagToElementType.put("OL", "OListElement"); | |
62 tagToElementType.put("OBJECT", "ObjectElement"); | |
63 tagToElementType.put("OPTGROUP", "OptGroupElement"); | |
64 tagToElementType.put("OUTPUT", "OutputElement"); | |
65 tagToElementType.put("P", "ParagraphElement"); | |
66 tagToElementType.put("PARAM", "ParamElement"); | |
67 tagToElementType.put("PRE", "PreElement"); | |
68 tagToElementType.put("PROGRESS", "ProgressElement"); | |
69 tagToElementType.put("SCRIPT", "ScriptElement"); | |
70 tagToElementType.put("SOURCE", "SourceElement"); | |
71 tagToElementType.put("SPAN", "SpanElement"); | |
72 tagToElementType.put("STYLE", "StyleElement"); | |
73 tagToElementType.put("CAPTION", "TableCaptionElement"); | |
74 tagToElementType.put("TD", "TableCellElement"); | |
75 tagToElementType.put("COL", "TableColElement"); | |
76 tagToElementType.put("TABLE", "TableElement"); | |
77 tagToElementType.put("TR", "TableRowElement"); | |
78 tagToElementType.put("TEXTAREA", "TextAreaElement"); | |
79 tagToElementType.put("TITLE", "TitleElement"); | |
80 tagToElementType.put("TRACK", "TrackElement"); | |
81 tagToElementType.put("UL", "UListElement"); | |
82 tagToElementType.put("VIDEO", "VideoElement"); | |
83 tagToElementType.put("DART_EDITOR_NO_SUCH_TYPE", "DartEditorNoSuchElement"); | |
84 } | |
85 | |
86 /** | |
87 * Attempts to make better guess about return type of invocation. | |
88 * | |
89 * @return the better {@link Type} guess, may be "defaultType" if can not make better guess. | |
90 */ | |
91 public static Type resolve(Types types, DartUnqualifiedInvocation invocation, Element element, | |
92 Type defaultType) { | |
93 if (element == null) { | |
94 return defaultType; | |
95 } | |
96 String name = element.getName(); | |
97 List<DartExpression> arguments = invocation.getArguments(); | |
98 LibraryElement libraryElement = Elements.getDeclaringLibrary(element); | |
99 // html.query(String) | |
100 if ("query".equals(name) && isHtmlLibraryFunction(element)) { | |
101 return analyzeQuery(arguments, libraryElement, defaultType); | |
102 } | |
103 // no guess | |
104 return defaultType; | |
105 } | |
106 | |
107 /** | |
108 * Attempts to make better guess about return type of invocation. | |
109 * | |
110 * @return the better {@link Type} guess, may be "defaultType" if can not make better guess. | |
111 */ | |
112 public static Type resolve(Types types, DartMethodInvocation invocation, Eleme nt element, | |
113 Type defaultType) { | |
114 if (element == null) { | |
115 return defaultType; | |
116 } | |
117 String name = element.getName(); | |
118 List<DartExpression> arguments = invocation.getArguments(); | |
119 LibraryElement libraryElement = Elements.getDeclaringLibrary(element); | |
120 // NodeSelector.query(String) | |
121 EnclosingElement enclosingElement = element.getEnclosingElement(); | |
122 if ("query".equals(name) && isDeclaredInHtmlLibrary(element) | |
123 && ElementKind.of(enclosingElement) == ElementKind.CLASS | |
124 && "NodeSelector".equals(enclosingElement.getName())) { | |
125 return analyzeQuery(arguments, libraryElement, defaultType); | |
126 } | |
127 // no guess | |
128 return defaultType; | |
129 } | |
130 | |
131 private static Type analyzeQuery(List<DartExpression> arguments, LibraryElemen t libraryElement, | |
132 Type defaultType) { | |
133 if (arguments.size() == 1 && arguments.get(0) instanceof DartStringLiteral) { | |
134 String selectors = ((DartStringLiteral) arguments.get(0)).getValue(); | |
135 // if has spaces, full parsing required, because may be: E[text='warning t ext'] | |
136 if (selectors.contains(" ")) { | |
137 return defaultType; | |
138 } | |
139 // try to extract tag | |
140 // http://www.w3.org/TR/CSS2/selector.html | |
141 String tag = selectors; | |
142 tag = StringUtils.substringBefore(tag, ":"); | |
143 tag = StringUtils.substringBefore(tag, "["); | |
144 tag = StringUtils.substringBefore(tag, "."); | |
145 tag = StringUtils.substringBefore(tag, "#"); | |
146 tag = tag.toUpperCase(); | |
147 // prepare Element type name | |
148 String tagTypeName = tagToElementType.get(tag); | |
149 if (tagTypeName == null) { | |
150 return defaultType; | |
151 } | |
152 // lookup tag Element | |
153 Element tagTypeElement = libraryElement.lookupLocalElement(tagTypeName); | |
154 if (tagTypeElement == null) { | |
155 return defaultType; | |
156 } | |
157 // OK, we know more specific return type | |
158 Type tagType = tagTypeElement.getType(); | |
159 if (tagType != null) { | |
160 return tagType; | |
161 } | |
162 } | |
163 // no guess | |
164 return defaultType; | |
165 } | |
166 | |
167 private static boolean isHtmlLibraryFunction(Element element) { | |
168 return ElementKind.of(element) == ElementKind.METHOD && isDeclaredInHtmlLibr ary(element); | |
169 } | |
170 | |
171 private static boolean isDeclaredInHtmlLibrary(Element element) { | |
172 LibraryElement libraryElement = Elements.getDeclaringLibrary(element); | |
173 return StringUtils.startsWith(libraryElement.getName(), "dart://html"); | |
174 } | |
175 } | |
OLD | NEW |