Linter Demo Errors: 0Warnings: 9File: /home/fstrocco/Dart/dart/benchmark/compiler/lib/src/js_backend/patch_resolver.dart // Copyright (c) 2014, 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. library dart2js.js_backend.patch_resolver; import '../dart2jslib.dart'; import '../dart_types.dart'; import '../elements/elements.dart'; import '../elements/modelx.dart'; import '../resolution/resolution.dart'; import '../tree/tree.dart'; import '../util/util.dart'; class PatchResolverTask extends CompilerTask { PatchResolverTask(Compiler compiler) : super(compiler); String get name => 'JavaScript patch resolver'; FunctionElement resolveExternalFunction(FunctionElementX element) { if (element.isPatched) { FunctionElementX patch = element.patch; compiler.withCurrentElement(patch, () { patch.parseNode(compiler); patch.computeType(compiler); }); checkMatchingPatchSignatures(element, patch); element = patch; } else { compiler.reportError( element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); } return element; } void checkMatchingPatchParameters(FunctionElement origin, Link originParameters, Link patchParameters) { while (!originParameters.isEmpty) { ParameterElementX originParameter = originParameters.head; ParameterElementX patchParameter = patchParameters.head; // TODO(johnniwinther): Remove the conditional patching when we never // resolve the same method twice. if (!originParameter.isPatched) { originParameter.applyPatch(patchParameter); } else { assert(invariant(origin, originParameter.patch == patchParameter, message: "Inconsistent repatch of $originParameter.")); } DartType originParameterType = originParameter.computeType(compiler); DartType patchParameterType = patchParameter.computeType(compiler); if (originParameterType != patchParameterType) { compiler.reportError( originParameter.parseNode(compiler), MessageKind.PATCH_PARAMETER_TYPE_MISMATCH, {'methodName': origin.name, 'parameterName': originParameter.name, 'originParameterType': originParameterType, 'patchParameterType': patchParameterType}); compiler.reportInfo(patchParameter, MessageKind.PATCH_POINT_TO_PARAMETER, {'parameterName': patchParameter.name}); } else { // Hack: Use unparser to test parameter equality. This only works // because we are restricting patch uses and the approach cannot be used // elsewhere. // The node contains the type, so there is a potential overlap. // Therefore we only check the text if the types are identical. String originParameterText = originParameter.parseNode(compiler).toString(); String patchParameterText = patchParameter.parseNode(compiler).toString(); if (originParameterText != patchParameterText // We special case the list constructor because of the // optional parameter. && origin != compiler.unnamedListConstructor) { compiler.reportError( originParameter.parseNode(compiler), MessageKind.PATCH_PARAMETER_MISMATCH, {'methodName': origin.name, 'originParameter': originParameterText, 'patchParameter': patchParameterText}); compiler.reportInfo(patchParameter, MessageKind.PATCH_POINT_TO_PARAMETER, {'parameterName': patchParameter.name}); } } originParameters = originParameters.tail; patchParameters = patchParameters.tail; } } void checkMatchingPatchSignatures(FunctionElement origin, FunctionElement patch) { // TODO(johnniwinther): Show both origin and patch locations on errors. FunctionExpression originTree = origin.node; FunctionSignature originSignature = origin.functionSignature; FunctionExpression patchTree = patch.node; FunctionSignature patchSignature = patch.functionSignature; if (originSignature.type.returnType != patchSignature.type.returnType) { compiler.withCurrentElement(patch, () { Node errorNode = patchTree.returnType != null ? patchTree.returnType : patchTree; compiler.reportError( errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, {'methodName': origin.name, 'originReturnType': originSignature.type.returnType, 'patchReturnType': patchSignature.type.returnType}); }); } if (originSignature.requiredParameterCount != patchSignature.requiredParameterCount) { compiler.withCurrentElement(patch, () { compiler.reportError( patchTree, MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH, {'methodName': origin.name, 'originParameterCount': originSignature.requiredParameterCount, 'patchParameterCount': patchSignature.requiredParameterCount}); }); } else { checkMatchingPatchParameters(origin, originSignature.requiredParameters, patchSignature.requiredParameters); } if (originSignature.optionalParameterCount != 0 && patchSignature.optionalParameterCount != 0) { if (originSignature.optionalParametersAreNamed != patchSignature.optionalParametersAreNamed) { compiler.withCurrentElement(patch, () { compiler.reportError( patchTree, MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH, {'methodName': origin.name}); }); } } if (originSignature.optionalParameterCount != patchSignature.optionalParameterCount) { compiler.withCurrentElement(patch, () { compiler.reportError( patchTree, MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH, {'methodName': origin.name, 'originParameterCount': originSignature.optionalParameterCount, 'patchParameterCount': patchSignature.optionalParameterCount}); }); } else { checkMatchingPatchParameters(origin, originSignature.optionalParameters, patchSignature.optionalParameters); } } }