| // 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 static com.google.dart.compiler.DartCompiler.EXTENSION_DEPS; |
| import static com.google.dart.compiler.DartCompiler.EXTENSION_TIMESTAMP; |
| |
| import com.google.common.collect.Lists; |
| import com.google.dart.compiler.CompilerTestCase; |
| import com.google.dart.compiler.DartCompilationError; |
| import com.google.dart.compiler.DartCompiler; |
| import com.google.dart.compiler.DartCompilerListener; |
| import com.google.dart.compiler.DefaultCompilerConfiguration; |
| import com.google.dart.compiler.LibrarySource; |
| import com.google.dart.compiler.MockArtifactProvider; |
| import com.google.dart.compiler.MockBundleLibrarySource; |
| import com.google.dart.compiler.Source; |
| import com.google.dart.compiler.util.apache.StringUtils; |
| |
| import junit.framework.AssertionFailedError; |
| |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.io.Writer; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentSkipListSet; |
| |
| // TODO(zundel): update this test not to rely on code generation |
| public class IncrementalCompilationTest extends CompilerTestCase { |
| |
| private static final String TEST_BASE_PATH = "com/google/dart/compiler/end2end/inc/"; |
| private static final String TEST_APP = "my.app.dart"; |
| |
| 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 MockBundleLibrarySource myAppSource; |
| private MockBundleLibrarySource someLibSource; |
| private MockBundleLibrarySource someImplLibSource; |
| |
| private final List<DartCompilationError> errors = Lists.newArrayList(); |
| |
| @Override |
| protected void setUp() throws Exception { |
| config = new DefaultCompilerConfiguration() { |
| @Override |
| public boolean incremental() { |
| return true; |
| } |
| }; |
| provider = new IncMockArtifactProvider(); |
| |
| myAppSource = new MockBundleLibrarySource(IncrementalCompilationTest.class.getClassLoader(), |
| TEST_BASE_PATH, TEST_APP); |
| someLibSource = myAppSource.getImportFor("some.lib.dart"); |
| someImplLibSource = someLibSource.getImportFor("someimpl.lib.dart"); |
| } |
| |
| @Override |
| protected void tearDown() { |
| config = null; |
| provider = null; |
| myAppSource = null; |
| someLibSource = null; |
| someImplLibSource = null; |
| } |
| |
| public void testRemoveDeps() throws Exception { |
| compile(); |
| |
| MockBundleLibrarySource myNuke5AppSource = new MockBundleLibrarySource( |
| IncrementalCompilationTest.class.getClassLoader(), |
| TEST_BASE_PATH, "my.nuke5.app.dart", "my.app.dart"); |
| myNuke5AppSource.remapSource("mybase.dart", "mybase.no5ref.dart"); |
| myNuke5AppSource.remapSource("my.dart", "my.no5ref.dart"); |
| myNuke5AppSource.removeSource("myother5.dart"); |
| |
| compile(myNuke5AppSource); |
| } |
| |
| public void testFullCompile() { |
| compile(); |
| System.out.println(StringUtils.join(errors, "\n")); |
| |
| // Assert that all artifacts are written. |
| didWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didWrite("some.dart", EXTENSION_TIMESTAMP); |
| didWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| didWrite("my.app.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testNoOpRecompile() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| compile(); |
| |
| // Assert we didn't write anything. |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("my.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("my.app.dart", EXTENSION_DEPS); |
| didNotWrite("my.app.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testTouchOneSource() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.touchSource("my.dart"); |
| compile(); |
| |
| // We just bumped the timestamp on my.dart, so only my.dart.js and my.app.js should be changed. |
| // At present, the app's deps and api will be rewritten. This might be optimized later. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| // Nothing else should have changed. |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testNormalizationTracking() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.touchSource("myother7.dart"); |
| compile(); |
| |
| // Test against normalization having an effect on hashcodes |
| // SomeInterface2 is an empty interface that can have an extra default constructor added by |
| // the dartc backend normalization process. By depending on a class that implements the interface, |
| // my.app.dart.deps will transitively depend on the empty interface. If something changes |
| // with how hashcodes are generated, this test should be updated. |
| |
| // We just bumped the timestamp on myother7.dart, so only myother7.dart.js and my.app.js should |
| // be changed. At present, the app's deps and api will be rewritten. |
| |
| didWrite("myother7.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| // Nothing else should have changed. |
| didNotWrite("my.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testKnockout_timestamp() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| provider.removeArtifact("my.dart", "", EXTENSION_TIMESTAMP); |
| compile(); |
| |
| // At present, knocking out a js artifact will force an update of the library's api and |
| // deps. This could be optimized. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| |
| // Assert that everything else was left alone. |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testChangeImplementation_methodBody() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| someImplLibSource.remapSource("someimpl.dart", "someimpl.bodychange.dart"); |
| compile(); |
| |
| // Changed someimpl.dart, so it, its library, and the compiled app should be written. |
| didWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| // We've switched to (unit -> unit) dependency, so should be recompiled too. |
| didWrite("some.dart", EXTENSION_TIMESTAMP); |
| didWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("my.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("my.app.dart", EXTENSION_DEPS); |
| } |
| |
| public void testChangeApi_newStaticMethod() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother0.dart", "myother0.newstaticmethod.dart"); |
| compile(); |
| |
| // Added a new static method to Other0, which should force a recompile of my.dart, |
| // because the latter contains a reference to one of its static methods. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testChangeApi_staticFieldRef() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother3.dart", "myother3.newstaticfield.dart"); |
| compile(); |
| |
| // Added a new static field to Other0, which should force a recompile of my.dart, |
| // because the latter contains a reference to one of its static methods. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother3.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testChangeApi_viaTypeParamBound() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother4.dart", "myother4.newstaticfield.dart"); |
| compile(); |
| |
| // Added a new static field to Other0, which should force a recompile of my.dart, |
| // because the latter contains a reference to one of its static methods. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother4.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testChangeApi_returnTypeChange() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother0.dart", "myother0.returntypechange.dart"); |
| compile(); |
| |
| // Changed a return type in Other0, which should force a recompile of my.dart, |
| // because the latter contains a reference to one of its static methods. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testChangeApi_globalVarChange() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother0.dart", "myother0.globalvarchange.dart"); |
| compile(); |
| |
| // Changed a top-level variable type in Other0, which should force a recompile of my.dart, |
| // because the latter contains a reference to one of its static methods. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| } |
| |
| public void testChangeApi_globalFunctionChange() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother0.dart", "myother0.globalfunctionchange.dart"); |
| compile(); |
| |
| // Changed a return type in Other0, which should force a recompile of my.dart, |
| // because the latter contains a reference to one of its static methods. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| } |
| |
| public void testChangeApi_viaNew() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother1.dart", "myother1.change.dart"); |
| compile(); |
| |
| // Changed the api of Other1, which should force a recompile of my.dart, |
| // because the latter instantiates one of its classes. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testChangeApi_viaSubclassing() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother2.dart", "myother2.change.dart"); |
| compile(); |
| |
| // Changed the api of Other2, which should force a recompile of my.dart, |
| // because the latter subclasses one of its classes. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testChangeApi_inLibrary() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| someLibSource.remapSource("some.dart", "some.newmethod.dart"); |
| someImplLibSource.remapSource("someimpl.dart", "someimpl.change.dart"); |
| compile(); |
| |
| // We changed both the interface and implementation libraries, so almost everything should have |
| // been recompiled. |
| didWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didWrite("some.dart", EXTENSION_TIMESTAMP); |
| didWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| // Except the "others", which have no dependency on the library. |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testChangeApi_inImplLibrary() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| someImplLibSource.remapSource("someimpl.dart", "someimpl.change.dart"); |
| compile(); |
| |
| // Assert that only the interface and implementation library were recompiled. |
| didWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didWrite("some.dart", EXTENSION_TIMESTAMP); |
| didWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| // The app should remain untouched. |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("my.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("my.app.dart", EXTENSION_DEPS); |
| } |
| |
| public void testChangeApi_inInterface() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| someLibSource.remapSource("some.dart", "some.intfchange.dart"); |
| compile(); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| |
| // Assert we recompiled both some.dart and someimpl.dart, as well as my.dart. |
| // (someimpl.dart is recompiled because its interface in some.dart changed) |
| didWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didWrite("some.dart", EXTENSION_TIMESTAMP); |
| didWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| } |
| |
| // TODO(jgw): Bug 5319907. |
| public void disabled_testFieldHole() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother0.dart", "myother0.fillthehole.dart"); |
| compile(); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| |
| // Both myother0.dart and my.dart should be recompiled. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| } |
| |
| public void testMethodHole() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother0.dart", "myother0.fillthemethodhole.dart"); |
| compile(); |
| } |
| |
| public void testQualifiedFieldRef() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother5.dart", "myother5.change.dart"); |
| compile(); |
| |
| // Changed the api of Other5, which should force a recompile of my.dart, |
| // because the latter includes a qualified reference to one of its instance fields. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother5.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testQualifiedMethodRef() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother6.dart", "myother6.change.dart"); |
| compile(); |
| |
| // Changed the api of Other6, which should force a recompile of my.dart, |
| // because the latter includes a qualified reference to one of its instance methods. |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother6.dart", EXTENSION_TIMESTAMP); |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testRemoveDepClass() { |
| compile(); |
| |
| provider.resetReadsAndWrites(); |
| myAppSource.remapSource("myother5.dart", "myother5.change.dart"); |
| myAppSource.remapSource("myother6.dart", "myother6.removeclass.dart"); |
| compile(); |
| |
| // Changed myother6.dart, which should force a recompile of myother5.dart, |
| // because the latter had a qualified reference to one of its classes. |
| didWrite("myother5.dart", EXTENSION_TIMESTAMP); |
| didWrite("myother6.dart", EXTENSION_TIMESTAMP); |
| |
| didWrite("my.dart", EXTENSION_TIMESTAMP); |
| // Because of the previous changes my.app.dart is also recompile. |
| didWrite("my.app.dart", EXTENSION_DEPS); |
| |
| // No changes in not related units. |
| didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("someimpl.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("some.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("some.lib.dart", EXTENSION_DEPS); |
| |
| didNotWrite("myother0.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother1.dart", EXTENSION_TIMESTAMP); |
| didNotWrite("myother2.dart", EXTENSION_TIMESTAMP); |
| } |
| |
| public void testMergeFiles() throws Exception { |
| compile(); |
| |
| MockBundleLibrarySource myMergedAppSource = new MockBundleLibrarySource( |
| IncrementalCompilationTest.class.getClassLoader(), |
| TEST_BASE_PATH, "my.merged.app.dart", "my.app.dart"); |
| |
| compile(myMergedAppSource); |
| } |
| |
| private void compile() { |
| compile(myAppSource); |
| } |
| |
| private void compile(LibrarySource lib) { |
| try { |
| errors.clear(); |
| DartCompilerListener listener = new DartCompilerListener.Empty() { |
| @Override |
| public void onError(DartCompilationError event) { |
| errors.add(event); |
| } |
| }; |
| 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)); |
| } |
| } |