/**
   * Resolve the given source and verify that the arguments in a specific method invocation were
   * correctly resolved.
   *
   * <p>The source is expected to be source for a compilation unit, the first declaration is
   * expected to be a class, the first member of which is expected to be a method with a block body,
   * and the first statement in the body is expected to be an expression statement whose expression
   * is a method invocation. It is the arguments to that method invocation that are tested. The
   * method invocation can contain errors.
   *
   * <p>The arguments were resolved correctly if the number of expressions in the list matches the
   * length of the array of indices and if, for each index in the array of indices, the parameter to
   * which the argument expression was resolved is the parameter in the invoked method's list of
   * parameters at that index. Arguments that should not be resolved to a parameter because of an
   * error can be denoted by including a negative index in the array of indices.
   *
   * @param source the source to be resolved
   * @param indices the array of indices used to associate arguments with parameters
   * @throws Exception if the source could not be resolved or if the structure of the source is not
   *     valid
   */
  private void validateArgumentResolution(Source source, int... indices) throws Exception {
    LibraryElement library = resolve(source);
    assertNotNull(library);
    ClassElement classElement = library.getDefiningCompilationUnit().getTypes()[0];
    ParameterElement[] parameters = classElement.getMethods()[1].getParameters();

    CompilationUnit unit = resolveCompilationUnit(source, library);
    assertNotNull(unit);
    ClassDeclaration classDeclaration = (ClassDeclaration) unit.getDeclarations().get(0);
    MethodDeclaration methodDeclaration =
        ((MethodDeclaration) classDeclaration.getMembers().get(0));
    Block block = ((BlockFunctionBody) methodDeclaration.getBody()).getBlock();
    ExpressionStatement statement = (ExpressionStatement) block.getStatements().get(0);
    MethodInvocation invocation = (MethodInvocation) statement.getExpression();
    NodeList<Expression> arguments = invocation.getArgumentList().getArguments();

    int argumentCount = arguments.size();
    assertEquals(indices.length, argumentCount);
    for (int i = 0; i < argumentCount; i++) {
      Expression argument = arguments.get(i);
      ParameterElement element = argument.getStaticParameterElement();
      int index = indices[i];
      if (index < 0) {
        assertNull(element);
      } else {
        assertSame(parameters[index], element);
      }
    }
  }
  public void test_multipleFiles() throws Exception {
    Source librarySource =
        addSource(
            "/lib.dart",
            createSource( //
                "library lib;", "part 'first.dart';", "part 'second.dart';", "", "class A {}"));
    addSource(
        "/first.dart",
        createSource( //
            "part of lib;", "class B {}"));
    addSource(
        "/second.dart",
        createSource( //
            "part of lib;", "class C {}"));

    LibraryElement element = buildLibrary(librarySource);
    assertNotNull(element);
    CompilationUnitElement[] sourcedUnits = element.getParts();
    assertLength(2, sourcedUnits);

    assertTypes(element.getDefiningCompilationUnit(), "A");
    if (sourcedUnits[0].getName().equals("first.dart")) {
      assertTypes(sourcedUnits[0], "B");
      assertTypes(sourcedUnits[1], "C");
    } else {
      assertTypes(sourcedUnits[0], "C");
      assertTypes(sourcedUnits[1], "B");
    }
  }
 public void test_metadata_typedef() throws Exception {
   Source source =
       addSource(
           createSource( //
               "const A = null;", "@A typedef F<A>();"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   CompilationUnitElement unitElement = library.getDefiningCompilationUnit();
   assertNotNull(unitElement);
   FunctionTypeAliasElement[] aliases = unitElement.getFunctionTypeAliases();
   assertLength(1, aliases);
   ElementAnnotation[] annotations = aliases[0].getMetadata();
   assertLength(1, annotations);
   assertNoErrors(source);
   verify(source);
   CompilationUnit unit = resolveCompilationUnit(source, library);
   NodeList<CompilationUnitMember> declarations = unit.getDeclarations();
   assertSizeOfList(2, declarations);
   Element expectedElement =
       ((TopLevelVariableDeclaration) declarations.get(0))
           .getVariables()
           .getVariables()
           .get(0)
           .getName()
           .getStaticElement();
   assertInstanceOf(PropertyInducingElement.class, expectedElement);
   expectedElement = ((PropertyInducingElement) expectedElement).getGetter();
   Element actualElement =
       ((FunctionTypeAlias) declarations.get(1)).getMetadata().get(0).getName().getStaticElement();
   assertSame(expectedElement, actualElement);
 }
 public void test_argumentResolution_setter_static_propertyAccess() throws Exception {
   Source source =
       addSource(
           createSource( //
               "main() {",
               "  A a = new A();",
               "  a.b.sss = 0;",
               "}",
               "class A {",
               "  B b = new B();",
               "}",
               "class B {",
               "  set sss(x) {}",
               "}"));
   LibraryElement library = resolve(source);
   CompilationUnitElement unit = library.getDefiningCompilationUnit();
   // find "a.b.sss = 0"
   AssignmentExpression assignment;
   {
     FunctionElement mainElement = unit.getFunctions()[0];
     FunctionBody mainBody = mainElement.getNode().getFunctionExpression().getBody();
     Statement statement = ((BlockFunctionBody) mainBody).getBlock().getStatements().get(1);
     ExpressionStatement expressionStatement = (ExpressionStatement) statement;
     assignment = (AssignmentExpression) expressionStatement.getExpression();
   }
   // get parameter
   Expression rhs = assignment.getRightHandSide();
   ParameterElement parameter = rhs.getStaticParameterElement();
   assertNotNull(parameter);
   assertEquals("x", parameter.getDisplayName());
   // validate
   ClassElement classB = unit.getTypes()[1];
   PropertyAccessorElement setter = classB.getAccessors()[0];
   assertSame(parameter, setter.getParameters()[0]);
 }
 public void test_metadata_libraryDirective() throws Exception {
   Source source =
       addSource(
           createSource( //
               "@A library lib;", "const A = null;"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   ElementAnnotation[] annotations = library.getMetadata();
   assertLength(1, annotations);
   assertNoErrors(source);
   verify(source);
 }
  public void test_singleFile() throws Exception {
    Source librarySource =
        addSource(
            "/lib.dart",
            createSource( //
                "library lib;", "", "class A {}"));

    LibraryElement element = buildLibrary(librarySource);
    assertNotNull(element);

    assertTypes(element.getDefiningCompilationUnit(), "A");
  }
 @Override
 protected void setUp() throws Exception {
   super.setUp();
   when(contextA.toString()).thenReturn("contextA");
   when(contextB.toString()).thenReturn("contextB");
   when(contextC.toString()).thenReturn("contextC");
   when(sourceA.toString()).thenReturn("sourceA");
   when(sourceB.toString()).thenReturn("sourceB");
   when(sourceC.toString()).thenReturn("sourceC");
   when(sourceD.toString()).thenReturn("sourceD");
   when(elementA.toString()).thenReturn("elementA");
   when(elementB.toString()).thenReturn("elementB");
   when(elementC.toString()).thenReturn("elementC");
   when(elementD.toString()).thenReturn("elementD");
   when(elementA.getContext()).thenReturn(contextA);
   when(elementB.getContext()).thenReturn(contextA);
   when(elementC.getContext()).thenReturn(contextA);
   when(elementD.getContext()).thenReturn(contextA);
   when(elementA.getLocation()).thenReturn(elementLocationA);
   when(elementB.getLocation()).thenReturn(elementLocationB);
   when(elementC.getLocation()).thenReturn(elementLocationC);
   when(elementD.getLocation()).thenReturn(elementLocationD);
   when(elementA.getEnclosingElement()).thenReturn(unitElementA);
   when(elementB.getEnclosingElement()).thenReturn(unitElementB);
   when(elementC.getEnclosingElement()).thenReturn(unitElementC);
   when(elementD.getEnclosingElement()).thenReturn(unitElementD);
   when(elementA.getSource()).thenReturn(sourceA);
   when(elementB.getSource()).thenReturn(sourceB);
   when(elementC.getSource()).thenReturn(sourceC);
   when(elementD.getSource()).thenReturn(sourceD);
   when(elementA.getLibrary()).thenReturn(libraryElement);
   when(elementB.getLibrary()).thenReturn(libraryElement);
   when(elementC.getLibrary()).thenReturn(libraryElement);
   when(elementD.getLibrary()).thenReturn(libraryElement);
   when(unitElementA.getSource()).thenReturn(sourceA);
   when(unitElementB.getSource()).thenReturn(sourceB);
   when(unitElementC.getSource()).thenReturn(sourceC);
   when(unitElementD.getSource()).thenReturn(sourceD);
   when(unitElementA.getLibrary()).thenReturn(libraryElement);
   when(unitElementB.getLibrary()).thenReturn(libraryElement);
   when(unitElementC.getLibrary()).thenReturn(libraryElement);
   when(unitElementD.getLibrary()).thenReturn(libraryElement);
   // library
   when(librarySource.toString()).thenReturn("libSource");
   when(libraryUnitElement.getSource()).thenReturn(librarySource);
   when(libraryElement.getSource()).thenReturn(librarySource);
   when(libraryElement.getDefiningCompilationUnit()).thenReturn(libraryUnitElement);
   // by default index all units
   store.aboutToIndex(contextA, unitElementA);
   store.aboutToIndex(contextA, unitElementB);
   store.aboutToIndex(contextA, unitElementC);
   store.aboutToIndex(contextA, unitElementD);
 }
 public void test_entryPoint_none() throws Exception {
   Source source =
       addNamedSource(
           "/one.dart",
           createSource( //
               "library one;"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   assertNull(library.getEntryPoint());
   assertNoErrors(source);
   verify(source);
 }
 private void validate(int scriptIndex, EmbeddedHtmlScriptElementImpl script) {
   LibraryElement library = script.getScriptLibrary();
   assertNotNull("script " + scriptIndex, library);
   assertSame("script " + scriptIndex, context, script.getContext());
   CompilationUnitElement unit = library.getDefiningCompilationUnit();
   assertNotNull("script " + scriptIndex, unit);
   TopLevelVariableElement[] variables = unit.getTopLevelVariables();
   assertLength(expectedVariables.length, variables);
   for (int index = 0; index < variables.length; index++) {
     expectedVariables[index].validate(scriptIndex, variables[index]);
   }
   assertSame("script " + scriptIndex, script, library.getEnclosingElement());
 }
 public void test_entryPoint_local() throws Exception {
   Source source =
       addNamedSource(
           "/one.dart",
           createSource( //
               "library one;", "main() {}"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   FunctionElement main = library.getEntryPoint();
   assertNotNull(main);
   assertSame(library, main.getLibrary());
   assertNoErrors(source);
   verify(source);
 }
 public void test_isValidMixin_valid() throws Exception {
   Source source =
       addSource(
           createSource( //
               "class A {}"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   CompilationUnitElement unit = library.getDefiningCompilationUnit();
   assertNotNull(unit);
   ClassElement[] classes = unit.getTypes();
   assertLength(1, classes);
   assertTrue(classes[0].isValidMixin());
   assertNoErrors(source);
   verify(source);
 }
 public void test_metadata_function() throws Exception {
   Source source =
       addSource(
           createSource( //
               "const A = null;", "@A f() {}"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   CompilationUnitElement unit = library.getDefiningCompilationUnit();
   assertNotNull(unit);
   FunctionElement[] functions = unit.getFunctions();
   assertLength(1, functions);
   ElementAnnotation[] annotations = functions[0].getMetadata();
   assertLength(1, annotations);
   assertNoErrors(source);
   verify(source);
 }
 public void test_hasReferenceToSuper() throws Exception {
   Source source =
       addSource(
           createSource( //
               "class A {}", "class B {toString() => super.toString();}"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   CompilationUnitElement unit = library.getDefiningCompilationUnit();
   assertNotNull(unit);
   ClassElement[] classes = unit.getTypes();
   assertLength(2, classes);
   assertFalse(classes[0].hasReferenceToSuper());
   assertTrue(classes[1].hasReferenceToSuper());
   assertNoErrors(source);
   verify(source);
 }
 public void test_metadata_method() throws Exception {
   Source source =
       addSource(
           createSource( //
               "const A = null;", "class C {", "  @A void m() {}", "}"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   CompilationUnitElement unit = library.getDefiningCompilationUnit();
   assertNotNull(unit);
   ClassElement[] classes = unit.getTypes();
   assertLength(1, classes);
   MethodElement method = classes[0].getMethods()[0];
   ElementAnnotation[] annotations = method.getMetadata();
   assertLength(1, annotations);
   assertNoErrors(source);
   verify(source);
 }
 private static CompilationUnitElement getCompilationUnit(Element element) {
   // may be CompilationUnitElement
   if (element instanceof CompilationUnitElement) {
     return (CompilationUnitElement) element;
   }
   // may be part of CompilationUnitElement
   CompilationUnitElement unit = element.getAncestor(CompilationUnitElement.class);
   if (unit != null) {
     return unit;
   }
   // may be part of LibraryElement
   LibraryElement library = element.getLibrary();
   if (library != null) {
     return library.getDefiningCompilationUnit();
   }
   // not found
   return null;
 }
 public void test_metadata_simpleParameter() throws Exception {
   Source source =
       addSource(
           createSource( //
               "const A = null;", "f(@A p1, @A int p2) {}"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   CompilationUnitElement unit = library.getDefiningCompilationUnit();
   assertNotNull(unit);
   FunctionElement[] functions = unit.getFunctions();
   assertLength(1, functions);
   ParameterElement[] parameters = functions[0].getParameters();
   assertLength(2, parameters);
   ElementAnnotation[] annotations1 = parameters[0].getMetadata();
   assertLength(1, annotations1);
   ElementAnnotation[] annotations2 = parameters[1].getMetadata();
   assertLength(1, annotations2);
   assertNoErrors(source);
   verify(source);
 }
 public void test_metadata_fieldFormalParameter() throws Exception {
   Source source =
       addSource(
           createSource( //
               "const A = null;", "class C {", "  int f;", "  C(@A this.f);", "}"));
   LibraryElement library = resolve(source);
   assertNotNull(library);
   CompilationUnitElement unit = library.getDefiningCompilationUnit();
   assertNotNull(unit);
   ClassElement[] classes = unit.getTypes();
   assertLength(1, classes);
   ConstructorElement[] constructors = classes[0].getConstructors();
   assertLength(1, constructors);
   ParameterElement[] parameters = constructors[0].getParameters();
   assertLength(1, parameters);
   ElementAnnotation[] annotations = parameters[0].getMetadata();
   assertLength(1, annotations);
   assertNoErrors(source);
   verify(source);
 }
 public void test_aboutToIndex_unitExcluded() throws Exception {
   // build library with defining unit
   Source librarySource = mock(Source.class);
   LibraryElement library = mock(LibraryElement.class);
   CompilationUnitElement libraryUnit = mock(CompilationUnitElement.class);
   when(library.getContext()).thenReturn(contextA);
   when(library.getDefiningCompilationUnit()).thenReturn(libraryUnit);
   when(library.getSource()).thenReturn(librarySource);
   when(libraryUnit.getContext()).thenReturn(contextA);
   when(libraryUnit.getSource()).thenReturn(librarySource);
   when(libraryUnit.getLibrary()).thenReturn(library);
   // build 2 library units
   CompilationUnitElement unitA = mock(CompilationUnitElement.class);
   CompilationUnitElement unitB = mock(CompilationUnitElement.class);
   when(unitA.getContext()).thenReturn(contextA);
   when(unitB.getContext()).thenReturn(contextA);
   when(unitA.getSource()).thenReturn(sourceA);
   when(unitB.getSource()).thenReturn(sourceB);
   when(unitA.getLibrary()).thenReturn(library);
   when(unitB.getLibrary()).thenReturn(library);
   // prepare locations
   Location locationA = mockLocation(unitA);
   Location locationB = mockLocation(unitB);
   // initially A and B in library
   when(library.getParts()).thenReturn(new CompilationUnitElement[] {unitA, unitB});
   store.aboutToIndex(contextA, libraryUnit);
   store.aboutToIndex(contextA, unitA);
   store.aboutToIndex(contextA, unitB);
   store.recordRelationship(elementA, relationship, locationA);
   store.recordRelationship(elementA, relationship, locationB);
   {
     Location[] locations = store.getRelationships(elementA, relationship);
     assertLocations(locations, locationA, locationB);
   }
   // exclude A from library
   when(library.getParts()).thenReturn(new CompilationUnitElement[] {unitA});
   boolean mayIndex = store.aboutToIndex(contextA, libraryUnit);
   assertTrue(mayIndex);
   {
     Location[] locations = store.getRelationships(elementA, relationship);
     assertLocations(locations, locationA);
   }
   // exclude B from library, empty now
   when(library.getParts()).thenReturn(new CompilationUnitElement[] {});
   store.aboutToIndex(contextA, libraryUnit);
   {
     Location[] locations = store.getRelationships(elementA, relationship);
     assertLocations(locations);
   }
 }
  public void test_empty() throws Exception {
    Source librarySource = addSource("/lib.dart", "library lib;");

    LibraryElement element = buildLibrary(librarySource);
    assertNotNull(element);
    assertEquals("lib", element.getName());
    assertNull(element.getEntryPoint());
    assertLength(0, element.getImportedLibraries());
    assertLength(0, element.getImports());
    assertNull(element.getLibrary());
    assertLength(0, element.getPrefixes());
    assertLength(0, element.getParts());

    CompilationUnitElement unit = element.getDefiningCompilationUnit();
    assertNotNull(unit);
    assertEquals("lib.dart", unit.getName());
    assertEquals(element, unit.getLibrary());
    assertLength(0, unit.getAccessors());
    assertLength(0, unit.getFields());
    assertLength(0, unit.getFunctions());
    assertLength(0, unit.getTypeAliases());
    assertLength(0, unit.getTypes());
  }
 public void test_aboutToIndex_sharedSource_inTwoLibraries() throws Exception {
   Source librarySourceA = mock(Source.class);
   Source librarySourceB = mock(Source.class);
   LibraryElement libraryA = mock(LibraryElement.class);
   LibraryElement libraryB = mock(LibraryElement.class);
   CompilationUnitElement libraryAUnit = mock(CompilationUnitElement.class);
   CompilationUnitElement libraryBUnit = mock(CompilationUnitElement.class);
   when(libraryA.getDefiningCompilationUnit()).thenReturn(libraryAUnit);
   when(libraryB.getDefiningCompilationUnit()).thenReturn(libraryBUnit);
   when(libraryA.getSource()).thenReturn(librarySourceA);
   when(libraryB.getSource()).thenReturn(librarySourceB);
   when(libraryAUnit.getSource()).thenReturn(librarySourceA);
   when(libraryBUnit.getSource()).thenReturn(librarySourceB);
   when(libraryAUnit.getLibrary()).thenReturn(libraryA);
   when(libraryBUnit.getLibrary()).thenReturn(libraryB);
   // build 2 units in different libraries
   CompilationUnitElement unitA = mock(CompilationUnitElement.class);
   CompilationUnitElement unitB = mock(CompilationUnitElement.class);
   when(unitA.getContext()).thenReturn(contextA);
   when(unitB.getContext()).thenReturn(contextA);
   when(unitA.getSource()).thenReturn(sourceA);
   when(unitB.getSource()).thenReturn(sourceA);
   when(unitA.getLibrary()).thenReturn(libraryA);
   when(unitB.getLibrary()).thenReturn(libraryB);
   when(libraryA.getParts()).thenReturn(new CompilationUnitElement[] {unitA});
   when(libraryB.getParts()).thenReturn(new CompilationUnitElement[] {unitB});
   // record relationships in both A and B
   Location locationA = mockLocation(unitA);
   Location locationB = mockLocation(unitB);
   store.aboutToIndex(contextA, libraryAUnit);
   store.aboutToIndex(contextA, libraryBUnit);
   store.aboutToIndex(contextA, unitA);
   store.aboutToIndex(contextA, unitB);
   store.recordRelationship(elementA, relationship, locationA);
   store.recordRelationship(elementA, relationship, locationB);
   {
     Location[] locations = store.getRelationships(elementA, relationship);
     assertLocations(locations, locationA, locationB);
   }
 }