/** 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)); } } }
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()); } }