/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.engine.internal.scope; import com.google.dart.engine.ast.Identifier; import com.google.dart.engine.context.AnalysisContext; import com.google.dart.engine.context.AnalysisContextFactory; import com.google.dart.engine.element.ClassElement; import com.google.dart.engine.element.Element; import com.google.dart.engine.element.ImportElement; import com.google.dart.engine.element.LibraryElement; import com.google.dart.engine.element.MultiplyDefinedElement; import com.google.dart.engine.error.GatheringErrorListener; import com.google.dart.engine.error.StaticWarningCode; import com.google.dart.engine.internal.context.AnalysisContextImpl; import com.google.dart.engine.internal.element.ClassElementImpl; import com.google.dart.engine.internal.element.CompilationUnitElementImpl; import com.google.dart.engine.internal.element.ImportElementImpl; import com.google.dart.engine.internal.element.LibraryElementImpl; import com.google.dart.engine.resolver.ResolverTestCase; import com.google.dart.engine.source.SourceFactory; import static com.google.dart.engine.ast.AstFactory.identifier; import static com.google.dart.engine.ast.AstFactory.methodDeclaration; import static com.google.dart.engine.ast.AstFactory.typeName; import static com.google.dart.engine.element.ElementFactory.classElement; import static com.google.dart.engine.element.ElementFactory.importFor; import static com.google.dart.engine.element.ElementFactory.prefix; public class LibraryImportScopeTest extends ResolverTestCase { public void test_conflictingImports() { AnalysisContext context = new AnalysisContextImpl(); context.setSourceFactory(new SourceFactory()); String typeNameA = "A"; String typeNameB = "B"; String typeNameC = "C"; ClassElement typeA = classElement(typeNameA); ClassElement typeB1 = classElement(typeNameB); ClassElement typeB2 = classElement(typeNameB); ClassElement typeC = classElement(typeNameC); LibraryElement importedLibrary1 = createTestLibrary(context, "imported1"); ((CompilationUnitElementImpl) importedLibrary1.getDefiningCompilationUnit()).setTypes(new ClassElement[] { typeA, typeB1}); ImportElementImpl import1 = importFor(importedLibrary1, null); LibraryElement importedLibrary2 = createTestLibrary(context, "imported2"); ((CompilationUnitElementImpl) importedLibrary2.getDefiningCompilationUnit()).setTypes(new ClassElement[] { typeB2, typeC}); ImportElementImpl import2 = importFor(importedLibrary2, null); LibraryElementImpl importingLibrary = createTestLibrary(context, "importing"); importingLibrary.setImports(new ImportElement[] {import1, import2}); { GatheringErrorListener errorListener = new GatheringErrorListener(); Scope scope = new LibraryImportScope(importingLibrary, errorListener); assertEquals(typeA, scope.lookup(identifier(typeNameA), importingLibrary)); errorListener.assertNoErrors(); assertEquals(typeC, scope.lookup(identifier(typeNameC), importingLibrary)); errorListener.assertNoErrors(); Element element = scope.lookup(identifier(typeNameB), importingLibrary); errorListener.assertErrorsWithCodes(StaticWarningCode.AMBIGUOUS_IMPORT); assertInstanceOf(MultiplyDefinedElement.class, element); Element[] conflictingElements = ((MultiplyDefinedElement) element).getConflictingElements(); assertLength(2, conflictingElements); if (conflictingElements[0] == typeB1) { assertSame(typeB2, conflictingElements[1]); } else if (conflictingElements[0] == typeB2) { assertSame(typeB1, conflictingElements[1]); } else { assertSame(typeB1, conflictingElements[0]); } } { GatheringErrorListener errorListener = new GatheringErrorListener(); Scope scope = new LibraryImportScope(importingLibrary, errorListener); Identifier identifier = identifier(typeNameB); methodDeclaration(null, typeName(identifier), null, null, identifier("foo"), null); Element element = scope.lookup(identifier, importingLibrary); errorListener.assertErrorsWithCodes(StaticWarningCode.AMBIGUOUS_IMPORT); assertInstanceOf(MultiplyDefinedElement.class, element); } } public void test_creation_empty() { LibraryElement definingLibrary = createDefaultTestLibrary(); GatheringErrorListener errorListener = new GatheringErrorListener(); new LibraryImportScope(definingLibrary, errorListener); } public void test_creation_nonEmpty() { AnalysisContext context = new AnalysisContextImpl(); context.setSourceFactory(new SourceFactory()); String importedTypeName = "A"; ClassElement importedType = new ClassElementImpl(identifier(importedTypeName)); LibraryElement importedLibrary = createTestLibrary(context, "imported"); ((CompilationUnitElementImpl) importedLibrary.getDefiningCompilationUnit()).setTypes(new ClassElement[] {importedType}); LibraryElementImpl definingLibrary = createTestLibrary(context, "importing"); ImportElementImpl importElement = new ImportElementImpl(0); importElement.setImportedLibrary(importedLibrary); definingLibrary.setImports(new ImportElement[] {importElement}); GatheringErrorListener errorListener = new GatheringErrorListener(); Scope scope = new LibraryImportScope(definingLibrary, errorListener); assertEquals(importedType, scope.lookup(identifier(importedTypeName), definingLibrary)); } public void test_getErrorListener() throws Exception { LibraryElement definingLibrary = createDefaultTestLibrary(); GatheringErrorListener errorListener = new GatheringErrorListener(); LibraryImportScope scope = new LibraryImportScope(definingLibrary, errorListener); assertEquals(errorListener, scope.getErrorListener()); } public void test_nonConflictingImports_fromSdk() { AnalysisContext context = AnalysisContextFactory.contextWithCore(); String typeName = "List"; ClassElement type = classElement(typeName); LibraryElement importedLibrary = createTestLibrary(context, "lib"); ((CompilationUnitElementImpl) importedLibrary.getDefiningCompilationUnit()).setTypes(new ClassElement[] {type}); ImportElementImpl importCore = importFor( context.getLibraryElement(context.getSourceFactory().forUri("dart:core")), null); ImportElementImpl importLib = importFor(importedLibrary, null); LibraryElementImpl importingLibrary = createTestLibrary(context, "importing"); importingLibrary.setImports(new ImportElement[] {importCore, importLib}); GatheringErrorListener errorListener = new GatheringErrorListener(); Scope scope = new LibraryImportScope(importingLibrary, errorListener); assertEquals(type, scope.lookup(identifier(typeName), importingLibrary)); errorListener.assertErrorsWithCodes(StaticWarningCode.CONFLICTING_DART_IMPORT); } public void test_nonConflictingImports_sameElement() { AnalysisContext context = new AnalysisContextImpl(); context.setSourceFactory(new SourceFactory()); String typeNameA = "A"; String typeNameB = "B"; ClassElement typeA = classElement(typeNameA); ClassElement typeB = classElement(typeNameB); LibraryElement importedLibrary = createTestLibrary(context, "imported"); ((CompilationUnitElementImpl) importedLibrary.getDefiningCompilationUnit()).setTypes(new ClassElement[] { typeA, typeB}); ImportElementImpl import1 = importFor(importedLibrary, null); ImportElementImpl import2 = importFor(importedLibrary, null); LibraryElementImpl importingLibrary = createTestLibrary(context, "importing"); importingLibrary.setImports(new ImportElement[] {import1, import2}); GatheringErrorListener errorListener = new GatheringErrorListener(); Scope scope = new LibraryImportScope(importingLibrary, errorListener); assertEquals(typeA, scope.lookup(identifier(typeNameA), importingLibrary)); errorListener.assertNoErrors(); assertEquals(typeB, scope.lookup(identifier(typeNameB), importingLibrary)); errorListener.assertNoErrors(); } public void test_prefixedAndNonPrefixed() { AnalysisContext context = new AnalysisContextImpl(); context.setSourceFactory(new SourceFactory()); String typeName = "C"; String prefixName = "p"; ClassElement prefixedType = classElement(typeName); ClassElement nonPrefixedType = classElement(typeName); LibraryElement prefixedLibrary = createTestLibrary(context, "import.prefixed"); ((CompilationUnitElementImpl) prefixedLibrary.getDefiningCompilationUnit()).setTypes(new ClassElement[] {prefixedType}); ImportElementImpl prefixedImport = importFor(prefixedLibrary, prefix(prefixName)); LibraryElement nonPrefixedLibrary = createTestLibrary(context, "import.nonPrefixed"); ((CompilationUnitElementImpl) nonPrefixedLibrary.getDefiningCompilationUnit()).setTypes(new ClassElement[] {nonPrefixedType}); ImportElementImpl nonPrefixedImport = importFor(nonPrefixedLibrary, null); LibraryElementImpl importingLibrary = createTestLibrary(context, "importing"); importingLibrary.setImports(new ImportElement[] {prefixedImport, nonPrefixedImport}); GatheringErrorListener errorListener = new GatheringErrorListener(); Scope scope = new LibraryImportScope(importingLibrary, errorListener); Element prefixedElement = scope.lookup(identifier(prefixName, typeName), importingLibrary); errorListener.assertNoErrors(); assertSame(prefixedType, prefixedElement); Element nonPrefixedElement = scope.lookup(identifier(typeName), importingLibrary); errorListener.assertNoErrors(); assertSame(nonPrefixedType, nonPrefixedElement); } }