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; |
| 6 |
| 7 import com.google.dart.compiler.ast.DartClass; |
| 8 import com.google.dart.compiler.ast.DartExprStmt; |
| 9 import com.google.dart.compiler.ast.DartExpression; |
| 10 import com.google.dart.compiler.ast.DartIdentifier; |
| 11 import com.google.dart.compiler.ast.DartMethodDefinition; |
| 12 import com.google.dart.compiler.ast.DartNode; |
| 13 import com.google.dart.compiler.ast.DartPropertyAccess; |
| 14 import com.google.dart.compiler.ast.DartReturnStatement; |
| 15 import com.google.dart.compiler.ast.DartStatement; |
| 16 import com.google.dart.compiler.ast.DartUnit; |
| 17 import com.google.dart.compiler.ast.DartUnqualifiedInvocation; |
| 18 import com.google.dart.compiler.ast.LibraryUnit; |
| 19 import com.google.dart.compiler.resolver.ClassElement; |
| 20 import com.google.dart.compiler.resolver.CoreTypeProvider; |
| 21 import com.google.dart.compiler.resolver.CoreTypeProviderImplementation; |
| 22 import com.google.dart.compiler.resolver.Element; |
| 23 import com.google.dart.compiler.resolver.FieldElement; |
| 24 import com.google.dart.compiler.resolver.MethodElement; |
| 25 import com.google.dart.compiler.resolver.Scope; |
| 26 import com.google.dart.compiler.testing.TestCompilerConfiguration; |
| 27 import com.google.dart.compiler.testing.TestCompilerContext; |
| 28 import com.google.dart.compiler.testing.TestCompilerContext.EventKind; |
| 29 import com.google.dart.compiler.testing.TestDartArtifactProvider; |
| 30 import com.google.dart.compiler.testing.TestLibrarySource; |
| 31 import com.google.dart.compiler.type.FunctionType; |
| 32 import com.google.dart.compiler.type.InterfaceType; |
| 33 import com.google.dart.compiler.type.Type; |
| 34 import com.google.dart.compiler.type.TypeAnalyzer; |
| 35 |
| 36 import junit.framework.TestCase; |
| 37 |
| 38 import java.io.IOException; |
| 39 |
| 40 /** |
| 41 * Test of the IDE API in DartCompiler. |
| 42 */ |
| 43 public class IdeTest extends TestCase { |
| 44 |
| 45 private final TestCompilerContext context = new TestCompilerContext(EventKind.
ERROR, |
| 46 EventKind.TYPE_ERROR) { |
| 47 @Override |
| 48 protected void handleEvent(DartCompilationError event, EventKind kind) { |
| 49 super.handleEvent(event, kind); |
| 50 // For debugging: |
| 51 // System.err.println(event); |
| 52 } |
| 53 }; |
| 54 |
| 55 private final DartCompilerListener listener = context; |
| 56 |
| 57 private final DartArtifactProvider provider = new TestDartArtifactProvider(); |
| 58 |
| 59 private final CompilerConfiguration config = new TestCompilerConfiguration(); |
| 60 |
| 61 public void testAnalyseNoSemicolonPropertyAccess() { |
| 62 DartUnit unit = |
| 63 analyzeUnit( |
| 64 "no_semicolon_property_access", |
| 65 "class Foo {", |
| 66 " int i;", |
| 67 " void foo() {", |
| 68 " i.y", // Missing semicolon. |
| 69 " }", |
| 70 "}"); |
| 71 assertEquals("errorCount", 1, context.getErrorCount()); // Missing semicolon
. |
| 72 assertEquals("typeErrorCount", 1, context.getTypeErrorCount()); // No member
named "y". |
| 73 DartExprStmt statement = (DartExprStmt) firstStatementOfMethod(unit, "Foo",
"foo"); |
| 74 FieldElement element = (FieldElement) qualifierElement(statement.getExpressi
on()); |
| 75 assertEquals("int", element.getType().getElement().getName()); |
| 76 } |
| 77 |
| 78 public void testAnalyseNoSemicolonBrokenPropertyAccess() { |
| 79 DartUnit unit = |
| 80 analyzeUnit( |
| 81 "no_semicolon_broken_property_access", |
| 82 "class Foo {", |
| 83 " int i;", |
| 84 " void foo() {", |
| 85 " i.", // Syntax error and missing semicolon. |
| 86 " }", |
| 87 "}"); |
| 88 // Expected identifier and missing semicolon |
| 89 assertEquals("errorCount", 2, context.getErrorCount()); |
| 90 assertEquals("typeErrorCount", 1, context.getTypeErrorCount()); // No member
named "". |
| 91 DartExprStmt statement = (DartExprStmt) firstStatementOfMethod(unit, "Foo",
"foo"); |
| 92 FieldElement element = (FieldElement) qualifierElement(statement.getExpressi
on()); |
| 93 assertEquals("int", element.getType().getElement().getName()); |
| 94 } |
| 95 |
| 96 public void testAnalyseBrokenPropertyAccess() { |
| 97 DartUnit unit = |
| 98 analyzeUnit( |
| 99 "broken_property_access", |
| 100 "class Foo {", |
| 101 " int i;", |
| 102 " void foo() {", |
| 103 " i.;", // Syntax error here. |
| 104 " }", |
| 105 "}"); |
| 106 assertEquals("errorCount", 1, context.getErrorCount()); // Expected identifi
er. |
| 107 assertEquals("typeErrorCount", 1, context.getTypeErrorCount()); // No member
named "". |
| 108 DartExprStmt statement = (DartExprStmt) firstStatementOfMethod(unit, "Foo",
"foo"); |
| 109 FieldElement element = (FieldElement) qualifierElement(statement.getExpressi
on()); |
| 110 assertEquals("int", element.getType().getElement().getName()); |
| 111 } |
| 112 |
| 113 public void testAnalyseNoSemicolonIdentifier() { |
| 114 DartUnit unit = |
| 115 analyzeUnit( |
| 116 "no_semicolon_identifier", |
| 117 "class Foo {", |
| 118 " int i;", |
| 119 " void foo() {", |
| 120 " i", // Missing semicolon. |
| 121 " }", |
| 122 "}"); |
| 123 assertEquals("errorCount", 1, context.getErrorCount()); // Missing semicolon
. |
| 124 assertEquals("typeErrorCount", 0, context.getTypeErrorCount()); |
| 125 DartExprStmt statement = (DartExprStmt) firstStatementOfMethod(unit, "Foo",
"foo"); |
| 126 FieldElement field = (FieldElement) targetElement(statement.getExpression())
; |
| 127 assertEquals("int", field.getType().getElement().getName()); |
| 128 } |
| 129 |
| 130 public void testAnalyseNoSemicolonMethodCall() { |
| 131 DartUnit unit = |
| 132 analyzeUnit( |
| 133 "no_semicolon_method_call", |
| 134 "class Foo {", |
| 135 " int i () { return 0; }", |
| 136 " void foo() {", |
| 137 " i()", // Missing semicolon. |
| 138 " }", |
| 139 "}"); |
| 140 assertEquals("errorCount", 1, context.getErrorCount()); // Missing semicolon
. |
| 141 assertEquals("typeErrorCount", 0, context.getTypeErrorCount()); |
| 142 DartExprStmt statement = (DartExprStmt) firstStatementOfMethod(unit, "Foo",
"foo"); |
| 143 DartExpression expression = statement.getExpression(); |
| 144 DartUnqualifiedInvocation invocation = (DartUnqualifiedInvocation) expressio
n; |
| 145 MethodElement method = (MethodElement) targetElement(invocation.getTarget())
; |
| 146 assertEquals("i", method.getName()); |
| 147 FunctionType type = (FunctionType) method.getType(); |
| 148 assertEquals("int", type.getReturnType().getElement().getName()); |
| 149 } |
| 150 |
| 151 public void testAnalyseVoidKeyword() { |
| 152 DartUnit unit = |
| 153 analyzeUnit( |
| 154 "void_keyword", |
| 155 "class Foo {", |
| 156 " Function voidFunction;", |
| 157 " void foo() {", |
| 158 " void", // Missing semicolon and keyword |
| 159 " }", |
| 160 "}"); |
| 161 // Expected identifier and missing semicolon. |
| 162 assertEquals("errorCount", 2, context.getErrorCount()); |
| 163 // You can't use 'void' as a member name. It might be the beginning of a va
riable declaration |
| 164 // so it isn't an error in and of itself. |
| 165 assertEquals("typeErrorCount", 0, context.getTypeErrorCount()); |
| 166 DartExprStmt statement = (DartExprStmt) firstStatementOfMethod(unit, "Foo",
"foo"); |
| 167 DartIdentifier expression = (DartIdentifier) statement.getExpression(); |
| 168 assertEquals("", expression.getName()); |
| 169 } |
| 170 |
| 171 public void testAnalyseVoidKeywordPropertyAccess() { |
| 172 DartUnit unit = |
| 173 analyzeUnit( |
| 174 "void_keyword_property_access", |
| 175 "class Foo {", |
| 176 " Function voidFunction;", |
| 177 " void foo() {", |
| 178 " this.void", // Missing semicolon and keyword |
| 179 " }", |
| 180 "}"); |
| 181 // Expected identifier and missing semicolon. |
| 182 assertEquals("errorCount", 2, context.getErrorCount()); |
| 183 assertEquals("typeErrorCount", 1, context.getTypeErrorCount()); |
| 184 DartExprStmt statement = (DartExprStmt) firstStatementOfMethod(unit, "Foo",
"foo"); |
| 185 DartPropertyAccess expression = (DartPropertyAccess) statement.getExpression
(); |
| 186 assertEquals("", expression.getPropertyName()); |
| 187 } |
| 188 |
| 189 public void testReturnIntTypeAnalysis() { |
| 190 DartUnit unit = |
| 191 analyzeUnit( |
| 192 "return_int_type_analysis", |
| 193 "class Foo {", |
| 194 " int i;", |
| 195 " int foo() {", |
| 196 " return i;", |
| 197 " }", |
| 198 "}"); |
| 199 Scope unitScope = unit.getLibrary().getElement().getScope(); |
| 200 CoreTypeProvider typeProvider = new CoreTypeProviderImplementation(unitScope
, context); |
| 201 DartClass classNode = getClassOfUnit(unit, "Foo"); |
| 202 DartReturnStatement rtnStmt = (DartReturnStatement) firstStatementOfMethod(u
nit, "Foo", "foo"); |
| 203 ClassElement classElement = classNode.getElement(); |
| 204 InterfaceType definingType = classElement.getType(); |
| 205 Type type = TypeAnalyzer.analyze(rtnStmt.getValue(), typeProvider, context,
definingType); |
| 206 assertNotNull(type); |
| 207 assertEquals("int", type.getElement().getName()); |
| 208 } |
| 209 |
| 210 private Element targetElement(DartExpression expression) { |
| 211 DartIdentifier identifier = (DartIdentifier) expression; |
| 212 Element element = identifier.getElement(); |
| 213 assertNotNull(element); |
| 214 return element; |
| 215 } |
| 216 |
| 217 private Element qualifierElement(DartExpression node) { |
| 218 DartPropertyAccess propertyAccess = (DartPropertyAccess) node; |
| 219 DartIdentifier identifier = (DartIdentifier) propertyAccess.getQualifier(); |
| 220 Element element = identifier.getElement(); |
| 221 assertNotNull(element); |
| 222 return element; |
| 223 } |
| 224 |
| 225 private DartClass getClassOfUnit(DartUnit unit, String cls) { |
| 226 DartClass dartClass = null; |
| 227 for (DartNode node : unit.getTopLevelNodes()) { |
| 228 DartClass classNode = (DartClass) node; |
| 229 if (node instanceof DartClass) { |
| 230 if (classNode.getName().getName().equals(cls)) { |
| 231 dartClass = classNode; |
| 232 } |
| 233 } |
| 234 } |
| 235 assertNotNull(dartClass); |
| 236 return dartClass; |
| 237 } |
| 238 |
| 239 private DartStatement firstStatementOfMethod(DartUnit unit, String cls, String
member) { |
| 240 DartClass classNode = getClassOfUnit(unit, cls); |
| 241 for (DartNode memberNode : classNode.getMembers()) { |
| 242 if (memberNode instanceof DartMethodDefinition) { |
| 243 DartMethodDefinition methodNode = (DartMethodDefinition) memberNode; |
| 244 if (methodNode.getName() instanceof DartIdentifier) { |
| 245 DartIdentifier methodName = (DartIdentifier) methodNode.getName(); |
| 246 if (methodName.getName().equals(member)) { |
| 247 return methodNode.getFunction().getBody().getStatements().get(0); |
| 248 } |
| 249 } |
| 250 } |
| 251 } |
| 252 fail(); |
| 253 return null; |
| 254 } |
| 255 |
| 256 private DartUnit analyzeUnit(String name, String... sourceLines) throws Assert
ionError { |
| 257 TestLibrarySource lib = new TestLibrarySource(name); |
| 258 lib.addSource(name + ".dart", sourceLines); |
| 259 LibraryUnit libraryUnit; |
| 260 try { |
| 261 libraryUnit = DartCompiler.analyzeLibrary(lib, null, config, provider, lis
tener); |
| 262 assertNotNull("libraryUnit == null", libraryUnit); |
| 263 } catch (IOException e) { |
| 264 throw new AssertionError(e); |
| 265 } |
| 266 DartUnit unit = libraryUnit.getUnit(name + ".dart"); |
| 267 assertNotNull("unit == null", unit); |
| 268 return unit; |
| 269 } |
| 270 } |
OLD | NEW |