| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package com.google.dart.compiler.end2end.inc; |
| |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Maps; |
| import com.google.common.collect.Sets; |
| import com.google.dart.compiler.CompilerTestCase; |
| import com.google.dart.compiler.DartCompilationError; |
| import com.google.dart.compiler.DartCompiler; |
| import com.google.dart.compiler.DartCompilerErrorCode; |
| import com.google.dart.compiler.DartCompilerListener; |
| import com.google.dart.compiler.DartSource; |
| import com.google.dart.compiler.DefaultCompilerConfiguration; |
| import com.google.dart.compiler.LibrarySource; |
| import com.google.dart.compiler.MockArtifactProvider; |
| import com.google.dart.compiler.PackageLibraryManager; |
| import com.google.dart.compiler.Source; |
| import com.google.dart.compiler.UrlSource; |
| import com.google.dart.compiler.ast.DartUnit; |
| import com.google.dart.compiler.ast.LibraryUnit; |
| import com.google.dart.compiler.common.ErrorExpectation; |
| import com.google.dart.compiler.resolver.ResolverErrorCode; |
| import com.google.dart.compiler.resolver.TypeErrorCode; |
| |
| import static com.google.dart.compiler.DartCompiler.EXTENSION_DEPS; |
| import static com.google.dart.compiler.DartCompiler.EXTENSION_TIMESTAMP; |
| import static com.google.dart.compiler.common.ErrorExpectation.assertErrors; |
| import static com.google.dart.compiler.common.ErrorExpectation.errEx; |
| |
| import junit.framework.AssertionFailedError; |
| |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.io.Writer; |
| import java.net.URI; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentSkipListSet; |
| |
| // TODO(zundel): update this test not to rely on code generation |
| public class IncrementalCompilation2Test extends CompilerTestCase { |
| private static final String APP = "Application.dart"; |
| |
| private static class IncMockArtifactProvider extends MockArtifactProvider { |
| Set<String> reads = new ConcurrentSkipListSet<String>(); |
| Set<String> writes = new ConcurrentSkipListSet<String>(); |
| |
| @Override |
| public Reader getArtifactReader(Source source, String part, String extension) { |
| reads.add(source.getName() + "/" + extension); |
| return super.getArtifactReader(source, part, extension); |
| } |
| |
| @Override |
| public Writer getArtifactWriter(Source source, String part, String extension) { |
| writes.add(source.getName() + "/" + extension); |
| return super.getArtifactWriter(source, part, extension); |
| } |
| |
| void resetReadsAndWrites() { |
| reads.clear(); |
| writes.clear(); |
| } |
| } |
| |
| private DefaultCompilerConfiguration config; |
| private IncMockArtifactProvider provider; |
| private MemoryLibrarySource appSource; |
| private final List<DartCompilationError> errors = Lists.newArrayList(); |
| private final Map<String, DartUnit> units = Maps.newHashMap(); |
| |
| @Override |
| protected void setUp() throws Exception { |
| config = new DefaultCompilerConfiguration() { |
| @Override |
| public boolean incremental() { |
| return true; |
| } |
| }; |
| provider = new IncMockArtifactProvider(); |
| appSource = new MemoryLibrarySource(APP); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "part 'A.dart';", |
| "part 'B.dart';", |
| "part 'C.dart';", |
| "")); |
| appSource.setContent("A.dart", "part of application;"); |
| appSource.setContent("B.dart", "part of application;"); |
| appSource.setContent("C.dart", "part of application;"); |
| } |
| |
| @Override |
| protected void tearDown() { |
| config = null; |
| provider = null; |
| appSource = null; |
| errors.clear(); |
| units.clear(); |
| } |
| |
| /** |
| * "not_hole" is referenced using "super" qualifier, so is not affected by declaring top-level |
| * field with same name. |
| */ |
| public void test_useQualifiedFieldReference_ignoreTopLevelDeclaration() { |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class A {", |
| " int not_hole;", |
| "}", |
| "")); |
| appSource.setContent( |
| "C.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class B extends A {", |
| " int bar() {", |
| " return super.not_hole;", // qualified reference |
| " }", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| // Update units and compile. |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "int not_hole;", |
| "")); |
| compile(); |
| // TODO(scheglov) Fix this after 1159 |
| //assertErrors(errors, errEx(ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_WARNING, -1, 7, 20)); |
| // B should be compiled because it now conflicts with A. |
| // C should not be compiled, because it reference "not_hole" field, not top-level variable. |
| didWrite("A.dart", EXTENSION_TIMESTAMP); |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("C.dart", EXTENSION_TIMESTAMP); |
| assertAppBuilt(); |
| } |
| |
| /** |
| * Referenced "hole" identifier can not be resolved, but when we declare it in A, then B should be |
| * recompiled and error message disappear. |
| */ |
| public void test_useUnresolvedField_recompileOnTopLevelDeclaration() { |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class A {", |
| " int foo() {", |
| " return hole;", // no such field |
| " }", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors, errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 12, 4)); |
| // Update units and compile. |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "int hole;", |
| "")); |
| compile(); |
| // A and B should be compiled. |
| didWrite("A.dart", EXTENSION_TIMESTAMP); |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| assertAppBuilt(); |
| // "hole" was filled with top-level field. |
| assertErrors(errors); |
| } |
| |
| /** |
| * Test for "hole" feature. If we use unqualified invocation and add/remove top-level method, this |
| * should cause compilation of invocation unit. |
| */ |
| public void test_isMethodHole_useUnqualifiedInvocation() throws Exception { |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class A {", |
| " foo() {}", |
| "}", |
| "")); |
| appSource.setContent( |
| "C.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class B extends A {", |
| " int bar() {", |
| " foo();", // unqualified invocation |
| " }", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| // Declare top-level foo(), now invocation of foo() in B should be bound to this top-level. |
| { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "foo() {}", |
| "")); |
| compile(); |
| // B should be compiled because it also declares foo(), so produces "shadow" conflict. |
| // C should be compiled because it has unqualified invocation which was declared in A. |
| didWrite("A.dart", EXTENSION_TIMESTAMP); |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| didWrite("C.dart", EXTENSION_TIMESTAMP); |
| assertAppBuilt(); |
| } |
| // Wait, because analysis is so fast that may be A will have same time as old artifact. |
| Thread.sleep(5); |
| // Remove top-level foo(), so invocation of foo() in B should be bound to the super class. |
| { |
| appSource.setContent("A.dart", "part of application;"); |
| compile(); |
| // B should be compiled because it also declares foo(), so produces "shadow" conflict. |
| // C should be compiled because it has unqualified invocation which was declared in A. |
| didWrite("A.dart", EXTENSION_TIMESTAMP); |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| didWrite("C.dart", EXTENSION_TIMESTAMP); |
| } |
| } |
| |
| /** |
| * Test for "hole" feature. If we use qualified invocation and add/remove top-level method, this |
| * should not cause compilation of invocation unit. |
| */ |
| public void test_notMethodHole_useQualifiedInvocation() { |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class A {", |
| " foo() {}", |
| "}", |
| "")); |
| appSource.setContent( |
| "C.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class B extends A {", |
| " int bar() {", |
| " super.foo();", // qualified invocation |
| " }", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| // Declare top-level foo(), but it is ignored. |
| { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "foo() {}", |
| "")); |
| compile(); |
| // B should be compiled because it also declares foo(), so produces "shadow" conflict. |
| // C should not be compiled because. |
| didWrite("A.dart", EXTENSION_TIMESTAMP); |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("C.dart", EXTENSION_TIMESTAMP); |
| assertAppBuilt(); |
| } |
| } |
| |
| /** |
| * Test for "hole" feature. If we use unqualified access and add/remove top-level field, this |
| * should cause compilation of invocation unit. |
| */ |
| public void test_fieldHole_useUnqualifiedAccess() throws Exception { |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class A {", |
| " var foo;", |
| "}", |
| "")); |
| appSource.setContent( |
| "C.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class B extends A {", |
| " int bar() {", |
| " foo = 0;", // unqualified access |
| " }", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| // Declare top-level "foo", now access to "foo" in B should be bound to this top-level. |
| { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "var foo;", |
| "")); |
| compile(); |
| // B should be compiled because it also declares "foo", so produces "shadow" conflict. |
| // C should be compiled because it has unqualified invocation which was declared in A. |
| didWrite("A.dart", EXTENSION_TIMESTAMP); |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| didWrite("C.dart", EXTENSION_TIMESTAMP); |
| assertAppBuilt(); |
| } |
| // Wait, because analysis is so fast that may be A will have same time as old artifact. |
| Thread.sleep(5); |
| // Remove top-level "foo", so access to "foo" in B should be bound to the super class. |
| { |
| appSource.setContent("A.dart", "part of application;"); |
| compile(); |
| // B should be compiled because it also declares "foo", so produces "shadow" conflict. |
| // C should be compiled because it has unqualified access which was declared in A. |
| didWrite("A.dart", EXTENSION_TIMESTAMP); |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| didWrite("C.dart", EXTENSION_TIMESTAMP); |
| } |
| } |
| |
| /** |
| * Test for "hole" feature. If we use qualified access and add/remove top-level field, this should |
| * not cause compilation of invocation unit. |
| */ |
| public void test_fieldHole_useQualifiedAccess() { |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class A {", |
| " var foo;", |
| "}", |
| "")); |
| appSource.setContent( |
| "C.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class B extends A {", |
| " int bar() {", |
| " super.foo = 0;", // qualified access |
| " }", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| // Declare top-level "foo", but it is ignored. |
| { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "var foo;", |
| "")); |
| compile(); |
| // B should be compiled because it also declares "foo", so produces "shadow" conflict. |
| // C should not be compiled because it has qualified access to "foo". |
| didWrite("A.dart", EXTENSION_TIMESTAMP); |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("C.dart", EXTENSION_TIMESTAMP); |
| assertAppBuilt(); |
| } |
| } |
| |
| public void test_declareTopLevel_conflictWithLocalVariable() { |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "methodB() {", |
| " var symbolDependency_foo;", |
| "}")); |
| compile(); |
| assertErrors(errors); |
| // Update units and compile. |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "var symbolDependency_foo;")); |
| compile(); |
| // Now there is top-level declarations conflict between A and B. |
| // So, B should be compiled. |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| // But application should be build. |
| assertAppBuilt(); |
| } |
| |
| public void test_undeclareTopLevel_conflictWithLocalVariable() { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "var duplicate;")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "bar() {", |
| " var duplicate;", |
| "}")); |
| compile(); |
| // Update units and compile. |
| appSource.setContent("A.dart", "part of application;"); |
| compile(); |
| // Top-level declaration in A was removed, so no conflict. |
| // So: |
| // ... B should be recompiled. |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| // ... but application should be rebuild. |
| assertAppBuilt(); |
| } |
| |
| /** |
| * Removes A, so changes set of top level units and forces compilation. |
| */ |
| public void test_removeOneSource() { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "var duplicate;")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "bar() {", |
| " var duplicate;", |
| "}")); |
| compile(); |
| // Exclude A and compile. |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library app;", |
| "part 'B.dart';", |
| "")); |
| compile(); |
| // Now there is top-level declarations conflict between A and B. |
| // So: |
| // ... B should be recompiled. |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| // ... but application should be rebuild. |
| didWrite(APP, EXTENSION_DEPS); |
| } |
| |
| public void test_declareField_conflictWithLocalVariable() { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class A {", |
| "}", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class B extends A {", |
| " foo() {", |
| " var bar;", |
| " }", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| // Update units and compile. |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "class A {", |
| " var bar;", |
| "}", |
| "")); |
| compile(); |
| // B depends on A class, so compiled. |
| didWrite("B.dart", EXTENSION_TIMESTAMP); |
| assertAppBuilt(); |
| } |
| |
| public void test_declareTopLevelVariable_conflictOtherTopLevelVariable() { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "var conflict;", |
| "")); |
| compile(); |
| assertErrors(errors); |
| // Update units and compile. |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "var conflict;", |
| "")); |
| compile(); |
| // A symbols intersect with new B symbols, so we compile A too. |
| // Both A and B have errors. |
| assertErrors( |
| errors, |
| errEx("A.dart", ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 8), |
| errEx("B.dart", ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 8)); |
| } |
| |
| /** |
| * Test that invalid "import" is reported as any other error between "unitAboutToCompile" and |
| * "unitCompiled". |
| */ |
| public void test_reportMissingImport() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library app;", |
| "import 'dart:noSuchLib.dart';", |
| "")); |
| // Remember errors only between unitAboutToCompile/unitCompiled. |
| errors.clear(); |
| DartCompilerListener listener = new DartCompilerListener.Empty() { |
| boolean isCompiling = false; |
| |
| @Override |
| public void unitAboutToCompile(DartSource source, boolean diet) { |
| isCompiling = true; |
| } |
| |
| @Override |
| public void onError(DartCompilationError event) { |
| if (isCompiling) { |
| errors.add(event); |
| } |
| } |
| |
| @Override |
| public void unitCompiled(DartUnit unit) { |
| isCompiling = false; |
| } |
| }; |
| DartCompiler.compileLib(appSource, config, provider, listener); |
| // Check that errors where reported (and in correct time). |
| assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 29)); |
| } |
| |
| /** |
| * Test that same prefix can be used to import several libraries. |
| */ |
| public void test_samePrefix_severalLibraries() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'A.dart' as p;", |
| "import 'B.dart' as p;", |
| "f() {", |
| " p.a = 1;", |
| " p.b = 2;", |
| "}", |
| "")); |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "var a;", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library B;", |
| "var b;", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors); |
| } |
| |
| /** |
| * It is neither an error nor a warning if N is introduced by two or more imports but never |
| * referred to. |
| */ |
| public void test_importConflict_notUsed() throws Exception { |
| prepare_importConflictAB(); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'A.dart';", |
| "import 'B.dart';", |
| "main() {", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| } |
| |
| public void test_importConflict_used_asTypeAnnotation() throws Exception { |
| prepare_importConflictAB(); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'A.dart';", |
| "import 'B.dart';", |
| "typedef Test MyTypeDef(Test p);", |
| "Test myFunction(Test p) {", |
| " Test test;", |
| "}", |
| "")); |
| compile(); |
| assertErrors( |
| errors, |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 5, 24, 4), |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 5, 9, 4), |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 6, 17, 4), |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 6, 1, 4), |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 7, 3, 4)); |
| } |
| |
| public void test_importConflict_used_notTypeAnnotation_1() throws Exception { |
| prepare_importConflictAB(); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'A.dart';", |
| "import 'B.dart';", |
| "class A extends Test {}", |
| "main() {", |
| "}", |
| "")); |
| compile(); |
| assertErrors( |
| errors, |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 5, 17, 4)); |
| } |
| |
| public void test_importConflict_used_notTypeAnnotation_2() throws Exception { |
| prepare_importConflictAB(); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'A.dart';", |
| "import 'B.dart';", |
| "main() {", |
| " Test();", |
| " Test.FOO;", |
| " Test = 0;", |
| " 0 is Test;", |
| "}", |
| "")); |
| compile(); |
| assertErrors( |
| errors, |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 6, 3, 4), |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 7, 3, 4), |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 8, 3, 4), |
| errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 9, 8, 4)); |
| } |
| |
| public void test_importConflict_used_notTypeAnnotation_3() throws Exception { |
| prepare_importConflictAB(); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'A.dart' hide Test;", |
| "import 'B.dart';", |
| "class A extends Test {}", |
| "main() {", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| } |
| |
| private void prepare_importConflictAB() { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library lib_a;", |
| "class Test {}", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library lib_b;", |
| "class Test {}", |
| "")); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=5735 |
| */ |
| public void test_importConflict_hideNoPrefix_importAgainWithPrefix() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library lib_a;", |
| "var E = 2.7;", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library lib_b;", |
| "export 'A.dart' show E;", |
| "var E = 'E';", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'B.dart';", |
| "import 'A.dart' as M show E;", |
| "main() {", |
| " print(E);", |
| " print(M.E);", |
| "}", |
| "")); |
| compile(); |
| assertErrors(errors); |
| } |
| |
| public void test_reportMissingSource() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library app;", |
| "part 'noSuchUnit.dart';", |
| "")); |
| compile(); |
| // Check that errors where reported (and in correct time). |
| assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 23)); |
| } |
| |
| public void test_reportMissingSource_withSchema_file() throws Exception { |
| URI uri = new URI("file:noSuchSource.dart"); |
| Source source = new UrlSource(uri) { |
| @Override |
| public String getName() { |
| return null; |
| } |
| }; |
| // should not cause exception |
| assertFalse(source.exists()); |
| } |
| |
| public void test_reportMissingSource_withSchema_dart() throws Exception { |
| URI uri = new URI("dart:noSuchSource"); |
| Source source = new UrlSource(uri, new PackageLibraryManager()) { |
| @Override |
| public String getName() { |
| return null; |
| } |
| }; |
| // should not cause exception |
| assertFalse(source.exists()); |
| } |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=3532 |
| */ |
| public void test_includeSameUnitTwice() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "part 'A.dart';", |
| "part 'A.dart';", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors, errEx(DartCompilerErrorCode.UNIT_WAS_ALREADY_INCLUDED, 4, 1, 14)); |
| } |
| |
| /** |
| * There was bug that we added <code>null</code> into {@link LibraryUnit#getImports()}. Here trick |
| * is that we reference "existing" {@link Source}, which can not be read. |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=2693 |
| */ |
| public void test_ignoreNullLibrary() throws Exception { |
| appSource.setContent("canNotRead.dart", MemoryLibrarySource.IO_EXCEPTION_CONTENT); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library app;", |
| "import 'canNotRead.dart';", |
| "")); |
| // use same config as Editor - resolve despite of errors |
| config = new DefaultCompilerConfiguration() { |
| @Override |
| public boolean resolveDespiteParseErrors() { |
| return true; |
| } |
| }; |
| // Ignore errors, but we should not get exceptions. |
| compile(); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=4072 |
| */ |
| public void test_inaccessibleMethod_fromOtherLibrary_static() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "class A {", |
| " static _privateStatic() {}", |
| "}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'A.dart';", |
| "main() {", |
| " A._privateStatic();", |
| "}", |
| "")); |
| // do compile, check errors |
| compile(); |
| assertErrors( |
| errors, |
| errEx(ResolverErrorCode.ILLEGAL_ACCESS_TO_PRIVATE, 5, 5, 14)); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=4072 |
| */ |
| public void test_inaccessibleMethod_fromOtherLibrary_instance() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "class A {", |
| " _privateInstance() {}", |
| "}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'A.dart';", |
| "main() {", |
| " A a = new A();", |
| " a._privateInstance();", |
| "}", |
| "")); |
| // do compile, check errors |
| compile(); |
| assertErrors( |
| errors, |
| errEx(TypeErrorCode.ILLEGAL_ACCESS_TO_PRIVATE, 6, 5, 16)); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=3266 |
| */ |
| public void test_inaccessibleSuperMethod_fromOtherLibrary() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "class A {", |
| " _method() {}", |
| "}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'A.dart';", |
| "class B extends A {", |
| " test1() {", |
| " _method();", |
| " }", |
| " test2() {", |
| " super._method();", |
| " }", |
| "}", |
| "")); |
| // do compile, check errors |
| compile(); |
| assertErrors( |
| errors, |
| errEx(ResolverErrorCode.CANNOT_ACCESS_METHOD, 6, 5, 7), |
| errEx(ResolverErrorCode.CANNOT_ACCESS_METHOD, 9, 11, 7)); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=3340 |
| */ |
| public void test_useImportPrefix_asVariableName() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'A.dart' as prf;", |
| "main() {", |
| " var prf;", |
| "}", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors, errEx(ResolverErrorCode.CANNOT_HIDE_IMPORT_PREFIX, 5, 7, 3)); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=3340 |
| */ |
| public void test_useImportPrefix_asTopLevelFieldName() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'A.dart' as prf;", |
| "var prf;", |
| "main() {", |
| "}", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors, errEx(ResolverErrorCode.CANNOT_HIDE_IMPORT_PREFIX, 4, 5, 3)); |
| } |
| |
| public void test_newLibrarySyntax_show() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.A;", |
| "class TypeA {}", |
| "class TypeB {}", |
| "class TypeC {}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'A.dart' as libA show TypeA, TypeB;", |
| "main() {", |
| " libA.TypeA v1;", |
| " libA.TypeB v2;", |
| " libA.TypeC v3;", |
| "}", |
| "")); |
| // TypeC not listed in "show" |
| compile(); |
| assertErrors(errors, errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 10)); |
| } |
| |
| public void test_newLibrarySyntax_hide() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.A;", |
| "class TypeA {}", |
| "class TypeB {}", |
| "class TypeC {}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'A.dart' as libA hide TypeC;", |
| "main() {", |
| " libA.TypeA v1;", |
| " libA.TypeB v2;", |
| " libA.TypeC v3;", |
| "}", |
| "")); |
| // TypeC is listed in "hide" |
| compile(); |
| assertErrors(errors, errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 10)); |
| } |
| |
| public void test_newLibrarySyntax_export_show() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.A;", |
| "class TypeAA {}", |
| "class TypeAB {}", |
| "class TypeAC {}", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.B;", |
| "export 'A.dart' show TypeAA, TypeAB;", |
| "class TypeBA {}", |
| "class TypeBB {}", |
| "class TypeBC {}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'B.dart' as libB hide TypeAA, TypeBB;", |
| "main() {", |
| " libB.TypeAA aa;", |
| " libB.TypeAB ab;", |
| " libB.TypeAC ac;", |
| " libB.TypeBA ba;", |
| " libB.TypeBB bb;", |
| " libB.TypeBC bc;", |
| "}", |
| "")); |
| compile(); |
| assertErrors( |
| errors, |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11), |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11), |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 9, 3, 11)); |
| assertTrue(errors.toString().contains("libB.TypeAA")); |
| assertTrue(errors.toString().contains("libB.TypeAC")); |
| assertTrue(errors.toString().contains("libB.TypeBB")); |
| } |
| |
| public void test_newLibrarySyntax_export2() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library libA;", |
| "class SourceString {}", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library libB;", |
| "import 'C.dart';", |
| "export 'A.dart' show SourceString;", |
| "")); |
| appSource.setContent( |
| "C.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library libC;", |
| "import 'B.dart';", |
| "foo() {", |
| " SourceString s;", |
| "}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library app;", |
| "import 'B.dart';", |
| "")); |
| compile(); |
| assertErrors(errors); |
| } |
| |
| public void test_newLibrarySyntax_export3() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library libA;", |
| "class SourceString {}", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library libB;", |
| "export 'C.dart';", |
| "export 'A.dart' show SourceString;", |
| "")); |
| appSource.setContent( |
| "C.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library libC;", |
| "import 'B.dart';", |
| "foo() {", |
| " SourceString s;", |
| "}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library app;", |
| "import 'B.dart';", |
| "")); |
| compile(); |
| assertErrors(errors); |
| } |
| |
| public void test_newLibrarySyntax_export4() throws Exception { |
| appSource.setContent( |
| "p1.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library lib1;", |
| "export 'p3.dart';", |
| "")); |
| appSource.setContent( |
| "p2.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library lib2;", |
| "export 'p3.dart';", |
| "")); |
| appSource.setContent( |
| "p3.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library lib3;", |
| "class MyClass {}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library app;", |
| "import 'p1.dart' hide MyClass;", |
| "import 'p2.dart';", |
| "MyClass topLevelField;", |
| "")); |
| compile(); |
| assertErrors(errors); |
| } |
| |
| public void test_newLibrarySyntax_export_hide() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.A;", |
| "class TypeAA {}", |
| "class TypeAB {}", |
| "class TypeAC {}", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.B;", |
| "export 'A.dart' hide TypeAC;", |
| "class TypeBA {}", |
| "class TypeBB {}", |
| "class TypeBC {}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'B.dart' as libB hide TypeAA, TypeBB;", |
| "main() {", |
| " libB.TypeAA aa;", |
| " libB.TypeAB ab;", |
| " libB.TypeAC ac;", |
| " libB.TypeBA ba;", |
| " libB.TypeBB bb;", |
| " libB.TypeBC bc;", |
| "}", |
| "")); |
| compile(); |
| assertErrors( |
| errors, |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11), |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11), |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 9, 3, 11)); |
| assertTrue(errors.toString().contains("libB.TypeAA")); |
| assertTrue(errors.toString().contains("libB.TypeAC")); |
| assertTrue(errors.toString().contains("libB.TypeBB")); |
| } |
| |
| public void test_newLibrarySyntax_noExport() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.A;", |
| "class TypeAA {}", |
| "class TypeAB {}", |
| "class TypeAC {}", |
| "")); |
| appSource.setContent( |
| "B.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.B;", |
| "import 'A.dart' as libA;", |
| "class TypeBA {}", |
| "class TypeBB {}", |
| "class TypeBC {}", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library test.app;", |
| "import 'B.dart' as libB;", |
| "main() {", |
| " libB.TypeAA aa;", |
| " libB.TypeAB ab;", |
| " libB.TypeAC ac;", |
| " libB.TypeBA ba;", |
| " libB.TypeBB bb;", |
| " libB.TypeBC bc;", |
| "}", |
| "")); |
| compile(); |
| assertErrors( |
| errors, |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11), |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 6, 3, 11), |
| errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11)); |
| assertTrue(errors.toString().contains("libB.TypeAA")); |
| assertTrue(errors.toString().contains("libB.TypeAB")); |
| assertTrue(errors.toString().contains("libB.TypeAC")); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=4238 |
| */ |
| public void test_typesPropagation_html_query() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'dart:html';", |
| "main() {", |
| " var v1 = query('a');", |
| " var v2 = query('A');", |
| " var v3 = query('body:active');", |
| " var v4 = query('button[foo=\"bar\"]');", |
| " var v5 = query('div.class');", |
| " var v6 = query('input#id');", |
| " var v7 = query('select#id');", |
| " // invocation of method", |
| " var m1 = document.query('div');", |
| " // unsupported currently", |
| " var b1 = query('noSuchTag');", |
| " var b2 = query('DART_EDITOR_NO_SUCH_TYPE');", |
| " var b3 = query('body div');", |
| "}", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors); |
| // validate types |
| DartUnit unit = units.get(APP); |
| assertNotNull(unit); |
| assertInferredElementTypeString(unit, "v1", "AnchorElement"); |
| assertInferredElementTypeString(unit, "v2", "AnchorElement"); |
| assertInferredElementTypeString(unit, "v3", "BodyElement"); |
| assertInferredElementTypeString(unit, "v4", "ButtonElement"); |
| assertInferredElementTypeString(unit, "v5", "DivElement"); |
| assertInferredElementTypeString(unit, "v6", "InputElement"); |
| assertInferredElementTypeString(unit, "v7", "SelectElement"); |
| // invocation of method |
| assertInferredElementTypeString(unit, "m1", "DivElement"); |
| // bad cases, or unsupported now |
| assertInferredElementTypeString(unit, "b1", "Element"); |
| assertInferredElementTypeString(unit, "b2", "Element"); |
| assertInferredElementTypeString(unit, "b3", "Element"); |
| } |
| |
| /** |
| * Libraries "dart:io" and "dart:html" can not be used together in single application. |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=3839 |
| */ |
| public void test_consoleWebMix() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'dart:io';", |
| "import 'dart:html';", |
| "")); |
| // do compiled |
| compile(); |
| // find expected error |
| boolean found = false; |
| for (DartCompilationError error : errors) { |
| found |= error.getErrorCode() == DartCompilerErrorCode.CONSOLE_WEB_MIX; |
| } |
| assertTrue(found); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=3531 |
| */ |
| public void test_builtInIdentifier_asTypeAnnotation() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'A.dart' as abstract;", |
| "import 'A.dart' as as;", |
| "import 'A.dart' as dynamic;", |
| "import 'A.dart' as export;", |
| "import 'A.dart' as external;", |
| "import 'A.dart' as factory;", |
| "import 'A.dart' as get;", |
| "import 'A.dart' as implements;", |
| "import 'A.dart' as import;", |
| "import 'A.dart' as library;", |
| "import 'A.dart' as operator;", |
| "import 'A.dart' as part;", |
| "import 'A.dart' as set;", |
| "import 'A.dart' as static;", |
| "import 'A.dart' as typedef;", |
| "main() {", |
| " var prf;", |
| "}", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| { |
| assertEquals(15, errors.size()); |
| for (DartCompilationError error : errors) { |
| assertEquals(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_IMPORT_PREFIX, error.getErrorCode()); |
| } |
| } |
| } |
| |
| public void test_implicitlyImportCore() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'dart:core';", |
| "")); |
| compile(); |
| ErrorExpectation.assertErrors(errors); |
| } |
| |
| /** |
| * Investigation of failing "language/ct_const4_test". |
| */ |
| public void test_useConstFromLib() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "final B = 1;", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "import 'A.dart' as mylib;", |
| "final A = mylib.B;", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors); |
| } |
| |
| /** |
| * Part should have one and only one directive - "part of". |
| */ |
| public void test_partDirectives_otherThenPartOf() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "part 'A.dart';", |
| "")); |
| // do compile |
| compile(); |
| assertErrors(errors, errEx(DartCompilerErrorCode.ILLEGAL_DIRECTIVES_IN_SOURCED_UNIT, 2, 1, 10)); |
| } |
| |
| /** |
| * Part should have one and only one directive - "part of". |
| */ |
| public void test_partDirectives_otherThenPartOf2() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of application;", |
| "part 'A.dart';", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "part 'A.dart';", |
| "")); |
| // do compile |
| compile(); |
| assertErrors(errors, errEx(DartCompilerErrorCode.ILLEGAL_DIRECTIVES_IN_SOURCED_UNIT, 2, 1, 20)); |
| } |
| |
| /** |
| * Part should have one and only one directive - "part of". |
| */ |
| public void test_partDirectives_noPartOf() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "part 'A.dart';", |
| "")); |
| // do compile |
| compile(); |
| assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_PART_OF_DIRECTIVE, -1, -1, 0)); |
| } |
| |
| /** |
| * Part should have one and only one directive - "part of". |
| */ |
| public void test_partDirectives_wrongNameInPartOf() throws Exception { |
| appSource.setContent( |
| "A.dart", |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "part of Z;", |
| "")); |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library application;", |
| "part 'A.dart';", |
| "")); |
| // do compile |
| compile(); |
| assertErrors( |
| errors, |
| errEx(DartCompilerErrorCode.WRONG_PART_OF_NAME, 2, 1, 10), |
| errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 2, 9, 1)); |
| } |
| |
| /** |
| * Internals of Dart use "dart-ext:" import scheme, and these libraries are allowed to use |
| * "native". New import syntax. |
| */ |
| public void test_useNative_withDartExt_new() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "library A;", |
| "import 'dart-ext:test_extension';", |
| "class A {", |
| " static int ifNull(a, b) native 'TestExtension_IfNull';", |
| "}", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors); |
| } |
| |
| /** |
| * Internals of Dart use "dart-ext:" import scheme, and these libraries are allowed to use |
| * "native". Obsolete import syntax. |
| */ |
| public void test_useNative_withDartExt_obsolete() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode( |
| "// filler filler filler filler filler filler filler filler filler filler filler", |
| "#library('A');", |
| "#import('dart-ext:test_extension');", |
| "class A {", |
| " static int ifNull(a, b) native 'TestExtension_IfNull';", |
| "}", |
| "")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors); |
| } |
| |
| /** |
| * <p> |
| * http://code.google.com/p/dart/issues/detail?id=6077 |
| */ |
| public void test_dartMirrors_notFullyImplemented() throws Exception { |
| appSource.setContent( |
| APP, |
| makeCode("// filler filler filler filler filler filler filler filler filler filler filler", |
| "import 'dart:mirrors';")); |
| // do compile, no errors expected |
| compile(); |
| assertErrors(errors, errEx(DartCompilerErrorCode.MIRRORS_NOT_FULLY_IMPLEMENTED, 2, 1, 22)); |
| } |
| |
| private void assertAppBuilt() { |
| didWrite(APP, EXTENSION_DEPS); |
| } |
| |
| private void compile() { |
| compile(appSource); |
| } |
| |
| private void compile(LibrarySource lib) { |
| try { |
| provider.resetReadsAndWrites(); |
| errors.clear(); |
| DartCompilerListener listener = new DartCompilerListener.Empty() { |
| Set<URI> compilingUris = Sets.newHashSet(); |
| |
| @Override |
| public void unitAboutToCompile(DartSource source, boolean diet) { |
| compilingUris.add(source.getUri()); |
| } |
| |
| @Override |
| public void onError(DartCompilationError event) { |
| // Remember errors only between unitAboutToCompile/unitCompiled. |
| Source source = event.getSource(); |
| if (source != null && compilingUris.contains(source.getUri())) { |
| errors.add(event); |
| } |
| } |
| |
| @Override |
| public void unitCompiled(DartUnit unit) { |
| compilingUris.remove(unit.getSourceInfo().getSource().getUri()); |
| units.put(unit.getSourceName(), unit); |
| } |
| }; |
| DartCompiler.compileLib(lib, config, provider, listener); |
| } catch (IOException e) { |
| throw new AssertionFailedError("Unexpected IOException: " + e.getMessage()); |
| } |
| } |
| |
| private void didWrite(String sourceName, String extension) { |
| String spec = sourceName + "/" + extension; |
| assertTrue("Expected write: " + spec, provider.writes.contains(spec)); |
| } |
| |
| private void didNotWrite(String sourceName, String extension) { |
| String spec = sourceName + "/" + extension; |
| assertFalse("Didn't expect write: " + spec, provider.writes.contains(spec)); |
| } |
| } |