예제 #1
0
  /** Add runtime type information to a "new" expression, if necessary. */
  void mayAddRuntimeTypeToConstrutorOrFactoryCall(
      ClassElement enclosingClass, DartNewExpression x, JsInvocation invoke) {
    // TODO(johnlenz):in optimized mode, only add this where it is needed.

    InterfaceType instanceType = Types.constructorType(x);
    if (instanceType == null) {
      // TODO(johnlenz): HackHack. Currently the "new FallThroughError" injected by the
      // Normalizer does not have the instance type attached. But in this
      // case we know it does not have any type parameters.
      // reportError(x.getParent().getParent(), new AssertionError("missing type information"));
      assert typeProvider
          .getFallThroughError()
          .getElement()
          .lookupConstructor("")
          .equals(x.getSymbol());
    } else if (constructorHasTypeParameters(x)) {
      ConstructorElement constructor = x.getSymbol();
      ClassElement containingClassElement = enclosingClass;
      if (constructor.getModifiers().isFactory()) {
        // We are calling a factory, this is either in a class
        FunctionType functionType = (FunctionType) constructor.getType();
        JsExpression typeArgs =
            generateTypeArgsArrayForFactory(functionType, instanceType, containingClassElement);
        assert typeArgs != null;
        invoke.getArguments().add(0, typeArgs);
      } else {
        ClassElement constructorClassElement = constructor.getConstructorType();
        invoke
            .getArguments()
            .add(
                0,
                generateRTTLookup(constructorClassElement, instanceType, containingClassElement));
      }
    }
  }
예제 #2
0
 private JsExpression generateTypeArgsArrayForFactory(
     FunctionType functionType, InterfaceType instanceType, ClassElement contextClassElement) {
   JsExpression typeArgs;
   if (inFactoryOrStatic(contextClassElement)) {
     if (inFactory()) {
       // When building a type list in a static context like a factory, type
       // variables are
       // resolved from the type parameters to the static method.
       DartClassMember<?> member = context.getCurrentClassMember();
       DartMethodDefinition containingMethod = (DartMethodDefinition) member;
       ConstructorElement contextElement = (ConstructorElement) containingMethod.getSymbol();
       typeArgs =
           buildTypeArgsForFactory(
               functionType,
               instanceType,
               ((FunctionType) contextElement.getType()).getTypeVariables(),
               buildFactoryTypeInfoReference());
     } else {
       typeArgs = buildTypeArgsForFactory(functionType, instanceType, null, null);
     }
   } else {
     // Build type args in a class context:
     // When building a type list in a class instance, type variables are
     // resolved from the runtime type information on the instance of the
     // object.
     JsExpression typeArgContextExpr = buildTypeArgsReference(contextClassElement);
     typeArgs =
         buildTypeArgsForFactory(
             functionType,
             instanceType,
             contextClassElement.getTypeParameters(),
             typeArgContextExpr);
   }
   return typeArgs;
 }
예제 #3
0
 private boolean constructorHasTypeParameters(DartNewExpression x) {
   ConstructorElement element = x.getSymbol();
   if (element.getModifiers().isFactory()) {
     return isParameterizedFactoryMethod((DartMethodDefinition) element.getNode());
   } else {
     InterfaceType instanceType = Types.constructorType(x);
     return hasTypeParameters(instanceType.getElement());
   }
 }