Index: Source/bindings/scripts/deprecated_code_generator_v8.pm |
diff --git a/Source/bindings/scripts/deprecated_code_generator_v8.pm b/Source/bindings/scripts/deprecated_code_generator_v8.pm |
index c327e69218601d12d2b9af4af6bb0e4cd0dca716..e75bc23cd1979786bf3ba81416720b88f399143c 100644 |
--- a/Source/bindings/scripts/deprecated_code_generator_v8.pm |
+++ b/Source/bindings/scripts/deprecated_code_generator_v8.pm |
@@ -198,6 +198,7 @@ my %svgAttributesInHTMLHash = ("class" => 1, "id" => 1, "onabort" => 1, "onclick |
"onmouseup" => 1, "onresize" => 1, "onscroll" => 1, |
"onunload" => 1); |
+### DONE |
my %svgTypeNeedingTearOff = ( |
"SVGAngle" => "SVGPropertyTearOff<SVGAngle>", |
"SVGLength" => "SVGPropertyTearOff<SVGLength>", |
@@ -267,19 +268,26 @@ sub IDLFileForInterface |
my $interfaceName = shift; |
unless ($idlFiles) { |
+# use Data::Dumper; |
+# print "[direc]", Dumper($idlDirectories), "\n"; |
my @directories = map { $_ = "$sourceRoot/$_" if -d "$sourceRoot/$_"; $_ } @$idlDirectories; |
push(@directories, "."); |
+# print "[directories]", Dumper(@directories), "\n"; |
$idlFiles = { }; |
foreach my $idlFile (@$interfaceIdlFiles) { |
$idlFiles->{fileparse(basename($idlFile), ".idl")} = $idlFile; |
} |
+# use Data::Dumper; |
+# print "[idlFiles]", Dumper($idlFiles), "\n"; |
my $wanted = sub { |
+# print "<find> ", $File::Find::name, "\n"; |
$idlFiles->{$1} = $File::Find::name if /^([A-Z].*)\.idl$/; |
$File::Find::prune = 1 if /^\../; |
}; |
find($wanted, @directories); |
+# print "[idlFiles]", scalar(keys($idlFiles)), "\n"; |
} |
return $idlFiles->{$interfaceName}; |
@@ -297,7 +305,10 @@ sub ParseInterface |
my $filename = IDLFileForInterface($interfaceName) |
or die("Could NOT find IDL file for interface \"$interfaceName\" $!\n"); |
- print " | |> Parsing parent IDL \"$filename\" for interface \"$interfaceName\"\n" if $verbose; |
+# use Carp qw(cluck); |
+# cluck "HEY"; |
+# print " | |> Parsing parent IDL \"$filename\" for interface \"$interfaceName\"\n" if $verbose; |
+ print " | |> Parsing $interfaceName ( $filename )\n"; |
# Step #2: Parse the found IDL file (in quiet mode). |
my $parser = deprecated_idl_parser->new(1); |
@@ -318,6 +329,11 @@ sub GenerateInterface |
my $object = shift; |
my $interface = shift; |
+ print "[GenerateInterface] ", $interface->name, "\n"; |
+# ForAllParents($interface, sub { |
+# my $parent = shift; |
+# print " - ", $parent->name, "\n" |
+# }); |
%callbackFunctionTypeHash = map { $_->name => $_ } @{$idlDocument->callbackFunctions}; |
%enumTypeHash = map { $_->name => $_->values } @{$idlDocument->enumerations}; |
my $v8ClassName = GetV8ClassName($interface); |
@@ -392,6 +408,10 @@ sub AddToImplIncludes |
{ |
my $header = shift; |
$implIncludes{$header} = 1; |
+ if($header eq "core/svg/properties/SVGAnimatedPropertyTearOff.h") { |
+# use Carp qw(cluck); |
+# cluck "HEY"; |
+ } |
} |
sub AddToHeaderIncludes |
@@ -403,6 +423,7 @@ sub AddToHeaderIncludes |
} |
} |
+### DONE |
sub SkipIncludeHeader |
{ |
my $type = shift; |
@@ -417,6 +438,7 @@ sub SkipIncludeHeader |
sub AddIncludesForType |
{ |
my $type = shift; |
+# print "BEBE AddIncludesForType ", $type, "\n"; |
return if SkipIncludeHeader($type); |
@@ -439,23 +461,31 @@ sub HeaderFilesForInterface |
my $interfaceName = shift; |
my $implClassName = shift; |
+ use Data::Dumper; |
my @includes = (); |
if (IsTypedArrayType($interfaceName)) { |
+ ### DONE |
push(@includes, "wtf/${interfaceName}.h"); |
} elsif (!SkipIncludeHeader($interfaceName)) { |
+ ### DONE |
my $idlFilename = IDLFileForInterface($interfaceName) or die("Could NOT find IDL file for interface \"$interfaceName\" $!\n"); |
my $idlRelPath= "bindings/" . File::Spec->abs2rel($idlFilename, $sourceRoot); |
+# print "GEHEHE ", $idlRelPath, "\n"; |
+# print "GEHEHE ", dirname($idlRelPath), "\n"; |
push(@includes, dirname($idlRelPath) . "/" . $implClassName . ".h"); |
} |
+# print "[HeaderFilesForInterface]", Dumper(@includes); |
return @includes; |
} |
+### DONE |
sub NeedsOpaqueRootForGC |
{ |
my $interface = shift; |
return $interface->extendedAttributes->{"GenerateIsReachable"} || $interface->extendedAttributes->{"CustomIsReachable"}; |
} |
+### DONE |
sub GenerateOpaqueRootForGC |
{ |
my $interface = shift; |
@@ -489,6 +519,7 @@ END |
$implementation{nameSpaceWebCore}->add($code); |
} |
+### DONE |
sub GetSVGPropertyTypes |
{ |
my $implType = shift; |
@@ -596,7 +627,12 @@ sub GenerateHeader |
LinkOverloadedFunctions($interface); |
# Ensure the IsDOMNodeType function is in sync. |
- die("IsDOMNodeType is out of date with respect to $interfaceName") if IsDOMNodeType($interfaceName) != InheritsInterface($interface, "Node"); |
+# my $_dom = IsDOMNodeType($interfaceName) ? "DOM" : ""; |
+# my $_inh = InheritsInterface($interface, "Node") ? "INH" : ""; |
+# print "[DOMDOM] $_dom $_inh ", $interface->name, "\n"; |
+ if(IsDOMNodeType($interfaceName) != InheritsInterface($interface, "Node")) { |
+ die("IsDOMNodeType is out of date with respect to $interfaceName") |
+ } |
my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($interfaceName); |
@@ -610,6 +646,7 @@ sub GenerateHeader |
$header{includes}->add("#include \"${headerInclude}\"\n"); |
} |
+ ### DONE |
$header{nameSpaceWebCore}->addHeader("\ntemplate<typename PropertyType> class SVGPropertyTearOff;\n") if $svgPropertyType; |
if ($svgNativeType) { |
if ($svgNativeType =~ /SVGStaticListPropertyTearOff/) { |
@@ -619,8 +656,10 @@ sub GenerateHeader |
} |
} |
+ ### DONE |
$header{nameSpaceWebCore}->addHeader("\nclass Dictionary;") if IsConstructorTemplate($interface, "Event"); |
+ ### impl_class_name and svg_type_needing_tear_off in python generator |
my $nativeType = GetNativeTypeForConversions($interface); |
if ($interface->extendedAttributes->{"NamedConstructor"}) { |
$header{nameSpaceWebCore}->addHeader(<<END); |
@@ -672,6 +711,7 @@ END |
next if $name eq ""; |
my $attrExt = $function->extendedAttributes; |
+# if (HasCustomMethod($attrExt) && !$attrExt->{"ImplementedBy"} && $function->{overloadIndex} == 1) { |
if (HasCustomMethod($attrExt) && $function->{overloadIndex} == 1) { |
my $conditionalString = GenerateConditionalString($function); |
$header{classPublic}->add("#if ${conditionalString}\n") if $conditionalString; |
@@ -698,14 +738,16 @@ END |
my $name = $attribute->name; |
my $attrExt = $attribute->extendedAttributes; |
my $conditionalString = GenerateConditionalString($attribute); |
- if (HasCustomGetter($attrExt) && !$attrExt->{"ImplementedBy"}) { |
+# if (HasCustomGetter($attrExt) && !$attrExt->{"ImplementedBy"}) { |
+ if (HasCustomGetter($attrExt)) { |
$header{classPublic}->add("#if ${conditionalString}\n") if $conditionalString; |
$header{classPublic}->add(<<END); |
static void ${name}AttrGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>&); |
END |
$header{classPublic}->add("#endif // ${conditionalString}\n") if $conditionalString; |
} |
- if (HasCustomSetter($attrExt) && !$attrExt->{"ImplementedBy"}) { |
+# if (HasCustomSetter($attrExt) && !$attrExt->{"ImplementedBy"}) { |
+ if (HasCustomSetter($attrExt)) { |
$header{classPublic}->add("#if ${conditionalString}\n") if $conditionalString; |
$header{classPublic}->add(<<END); |
static void ${name}AttrSetterCustom(v8::Local<v8::String> name, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<void>&); |
@@ -1192,6 +1234,7 @@ static void ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const |
END |
} |
+### macro get_feature_observation_parameter in template |
sub GenerateFeatureObservation |
{ |
my $measureAs = shift; |
@@ -1204,6 +1247,7 @@ sub GenerateFeatureObservation |
return ""; |
} |
+### macro deprecation_notification_parameter in template |
sub GenerateDeprecationNotification |
{ |
my $deprecateAs = shift; |
@@ -1215,6 +1259,7 @@ sub GenerateDeprecationNotification |
return ""; |
} |
+### DONE |
sub GenerateActivityLogging |
{ |
my $accessType = shift; |
@@ -1268,25 +1313,32 @@ sub GenerateNormalAttrGetterCallback |
my $attrExt = $attribute->extendedAttributes; |
my $attrName = $attribute->name; |
+ ### DONE |
my $conditionalString = GenerateConditionalString($attribute); |
my $code = ""; |
$code .= "#if ${conditionalString}\n\n" if $conditionalString; |
$code .= "static void ${attrName}AttrGetterCallback${forMainWorldSuffix}(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)\n"; |
$code .= "{\n"; |
+ ### DONE |
$code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMGetter\");\n"; |
$code .= GenerateFeatureObservation($attrExt->{"MeasureAs"}); |
+ ### DONE |
$code .= GenerateDeprecationNotification($attrExt->{"DeprecateAs"}); |
+ ### DONE |
if (HasActivityLogging($forMainWorldSuffix, $attrExt, "Getter")) { |
$code .= GenerateActivityLogging("Getter", $interface, "${attrName}"); |
} |
if (HasCustomGetter($attrExt)) { |
+ ### DONE |
$code .= " ${v8ClassName}::${attrName}AttrGetterCustom(name, info);\n"; |
} else { |
+ ### TODO |
$code .= " ${implClassName}V8Internal::${attrName}AttrGetter${forMainWorldSuffix}(name, info);\n"; |
} |
$code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |
$code .= "}\n\n"; |
+ ### DONE |
$code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |
$implementation{nameSpaceInternal}->add($code); |
@@ -1298,6 +1350,7 @@ sub GenerateNormalAttrGetter |
my $interface = shift; |
my $forMainWorldSuffix = shift; |
+print " [GenerateNormalAttrGetter]", $attribute->type, " ", $attribute->name, "\n"; |
my $interfaceName = $interface->name; |
my $implClassName = GetImplName($interface); |
my $v8ClassName = GetV8ClassName($interface); |
@@ -1320,7 +1373,9 @@ sub GenerateNormalAttrGetter |
static void ${attrName}AttrGetter${forMainWorldSuffix}(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) |
{ |
END |
+ ### First, get impl_class instance |
if ($svgNativeType) { |
+ ### TODO |
my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($interfaceName); |
if ($svgWrappedNativeType =~ /List/) { |
$code .= <<END; |
@@ -1334,6 +1389,7 @@ END |
END |
} |
} elsif ($attrExt->{"OnProto"} || $attrExt->{"Unforgeable"}) { |
+ ### TODO |
if ($interfaceName eq "Window") { |
$code .= <<END; |
v8::Handle<v8::Object> holder = info.Holder(); |
@@ -1350,6 +1406,7 @@ END |
${implClassName}* imp = ${v8ClassName}::toNative(holder); |
END |
} else { |
+ ### DONE |
my $reflect = $attribute->extendedAttributes->{"Reflect"}; |
my $url = $attribute->extendedAttributes->{"URL"}; |
if ($reflect && !$url && InheritsInterface($interface, "Node") && $attrType eq "DOMString") { |
@@ -1375,12 +1432,14 @@ END |
END |
} |
if (!$attribute->isStatic) { |
+ ### generally this is taken. |
$code .= <<END; |
${implClassName}* imp = ${v8ClassName}::toNative(info.Holder()); |
END |
} |
} |
+ ### DONE |
# Generate security checks if necessary |
if ($attribute->extendedAttributes->{"CheckSecurityForNode"}) { |
AddToImplIncludes("bindings/v8/BindingSecurity.h"); |
@@ -1429,13 +1488,17 @@ END |
$code .= " return;\n"; |
} |
+ ### TODO: always use intermediate variable v! |
if ($useExceptions || $isNullable) { |
if ($nativeType =~ /^V8StringResource/) { |
+ ### is it necessary??? |
$code .= " " . ConvertToV8StringResource($attribute, $nativeType, "v", $getterString) . ";\n"; |
} else { |
+ # Done |
$code .= " $nativeType v = $getterString;\n"; |
} |
+ ### DONE |
if ($isNullable) { |
$code .= " if (isNull) {\n"; |
$code .= " v8SetReturnValueNull(info);\n"; |
@@ -1444,12 +1507,14 @@ END |
} |
if ($useExceptions) { |
+ ### DONE |
if ($useExceptions) { |
$code .= " if (UNLIKELY(es.throwIfNeeded()))\n"; |
$code .= " return;\n"; |
} |
if (ExtendedAttributeContains($attribute->extendedAttributes->{"CallWith"}, "ScriptState")) { |
+ ### TODO |
$code .= " if (state.hadException()) {\n"; |
$code .= " throwError(state.exception());\n"; |
$code .= " return;\n"; |
@@ -1457,6 +1522,7 @@ END |
} |
} |
+ ## getter_expression in python |
$expression = "v"; |
$expression .= ".release()" if (IsRefPtrType($returnType)); |
} else { |
@@ -1466,7 +1532,10 @@ END |
$expression = "static_pointer_cast<SVGAnimatedEnumeration>($expression)" if $returnType eq "SVGAnimatedEnumeration"; |
} |
+# print "[BAR] ", $expression, "\n" if $interface->name eq "WebKitSourceBuffer"; |
+ ### FIXME: remove this special case! |
if (ShouldKeepAttributeAlive($interface, $attribute, $returnType)) { |
+ ### DONE |
my $arrayType = GetArrayType($returnType); |
if ($arrayType) { |
AddIncludeForType("V8$arrayType.h"); |
@@ -1482,6 +1551,7 @@ END |
# Check for a wrapper in the wrapper cache. If there is one, we know that a hidden reference has already |
# been created. If we don't find a wrapper, we create both a wrapper and a hidden reference. |
my $nativeReturnType = GetNativeType($returnType); |
+ # getterString is native_value_expression in python generator |
my $v8ReturnType = "V8" . $returnType; |
$code .= " $nativeReturnType result = ${getterString};\n"; |
if ($forMainWorldSuffix) { |
@@ -1503,6 +1573,7 @@ END |
} |
if ((IsSVGAnimatedType($interfaceName) or $interfaceName eq "SVGViewSpec") and IsSVGTypeNeedingTearOff($attrType)) { |
+ ### DONE |
AddToImplIncludes("V8$attrType.h"); |
my $svgNativeType = GetSVGTypeNeedingTearOff($attrType); |
# Convert from abstract SVGProperty to real type, so the right toJS() method can be invoked. |
@@ -1513,6 +1584,7 @@ END |
} |
$code .= " return;\n"; |
} elsif (IsSVGTypeNeedingTearOff($attrType) and not $interfaceName =~ /List$/) { |
+ ### DONE |
AddToImplIncludes("V8$attrType.h"); |
AddToImplIncludes("core/svg/properties/SVGPropertyTearOff.h"); |
my $tearOffType = GetSVGTypeNeedingTearOff($attrType); |
@@ -1550,6 +1622,7 @@ END |
} |
$code .= " return;\n"; |
} elsif ($attribute->type eq "SerializedScriptValue" && $attrExt->{"CachedAttribute"}) { |
+ ### DONE |
my $getterFunc = ToMethodName($attribute->name); |
$code .= <<END; |
RefPtr<SerializedScriptValue> serialized = imp->${getterFunc}(); |
@@ -1559,6 +1632,7 @@ END |
return; |
END |
} elsif ($attribute->type eq "EventHandler") { |
+ ### DONE |
AddToImplIncludes("bindings/v8/V8AbstractEventListener.h"); |
my $getterFunc = ToMethodName($attribute->name); |
# FIXME: Pass the main world ID for main-world-only getters. |
@@ -1566,6 +1640,7 @@ END |
$code .= " v8SetReturnValue(info, listener ? v8::Handle<v8::Value>(V8AbstractEventListener::cast(listener)->getListenerObject(imp->scriptExecutionContext())) : v8::Handle<v8::Value>(v8::Null(info.GetIsolate())));\n"; |
$code .= " return;\n"; |
} else { |
+ ### main |
my $nativeValue = NativeToJSValue($attribute->type, $attribute->extendedAttributes, $expression, " ", "", "info.Holder()", "info.GetIsolate()", "info", "imp", $forMainWorldSuffix, "return"); |
$code .= "${nativeValue}\n"; |
$code .= " return;\n"; |
@@ -1607,9 +1682,11 @@ sub ShouldKeepAttributeAlive |
return 0 if $returnType =~ /SVG/; |
return 0 if $returnType =~ /HTML/; |
+# print "[FOO] ", $returnType, "\n"; |
return 1; |
} |
+### TODO |
sub GenerateReplaceableAttrSetterCallback |
{ |
my $interface = shift; |
@@ -1659,6 +1736,7 @@ END |
$implementation{nameSpaceInternal}->add($code); |
} |
+### DONE ... macro custom_element_invocation in python |
sub GenerateCustomElementInvocationScopeIfNeeded |
{ |
my $code = ""; |
@@ -1693,24 +1771,34 @@ sub GenerateNormalAttrSetterCallback |
my $conditionalString = GenerateConditionalString($attribute); |
my $code = ""; |
+ ### DONE |
$code .= "#if ${conditionalString}\n\n" if $conditionalString; |
$code .= "static void ${attrName}AttrSetterCallback${forMainWorldSuffix}(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)\n"; |
$code .= "{\n"; |
+ ### DONE |
$code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMSetter\");\n"; |
+ ### DONE |
$code .= GenerateFeatureObservation($attrExt->{"MeasureAs"}); |
+ ### DONE |
$code .= GenerateDeprecationNotification($attrExt->{"DeprecateAs"}); |
+ ### DONE |
if (HasActivityLogging($forMainWorldSuffix, $attrExt, "Setter")) { |
$code .= GenerateActivityLogging("Setter", $interface, "${attrName}"); |
} |
+ ### DONE |
$code .= GenerateCustomElementInvocationScopeIfNeeded($attrExt); |
if (HasCustomSetter($attrExt)) { |
+ ### DONE |
$code .= " ${v8ClassName}::${attrName}AttrSetterCustom(name, value, info);\n"; |
} else { |
+ ### DONE |
$code .= " ${implClassName}V8Internal::${attrName}AttrSetter${forMainWorldSuffix}(name, value, info);\n"; |
} |
+ ### DONE |
$code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"V8\", \"Execution\");\n"; |
$code .= "}\n\n"; |
+ ### DONE |
$code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |
$implementation{nameSpaceInternal}->add($code); |
} |
@@ -1743,6 +1831,7 @@ sub GenerateNormalAttrSetter |
# thrown rather than silently passing NULL to the C++ code. |
# Per the Web IDL and ECMAScript specifications, incoming values can always be converted to both |
# strings and numbers, so do not throw TypeError if the attribute is of these types. |
+ ### TODO |
if ($attribute->extendedAttributes->{"StrictTypeChecking"}) { |
my $argType = $attribute->type; |
if (IsWrapperType($argType)) { |
@@ -1755,6 +1844,7 @@ sub GenerateNormalAttrSetter |
my $svgNativeType = GetSVGTypeNeedingTearOff($interfaceName); |
if ($svgNativeType) { |
+ ### TODO |
my $svgWrappedNativeType = GetSVGWrappedTypeNeedingTearOff($interfaceName); |
if ($svgWrappedNativeType =~ /List$/) { |
$code .= <<END; |
@@ -1771,10 +1861,12 @@ END |
$code .= " $svgWrappedNativeType* imp = &impInstance;\n"; |
} |
} elsif ($attrExt->{"OnProto"}) { |
+ ### TODO |
$code .= <<END; |
${implClassName}* imp = ${v8ClassName}::toNative(info.Holder()); |
END |
} else { |
+ ### main path |
my $reflect = $attribute->extendedAttributes->{"Reflect"}; |
if ($reflect && InheritsInterface($interface, "Node") && $attrType eq "DOMString") { |
# Generate super-compact call for regular attribute setter: |
@@ -1800,14 +1892,17 @@ END |
my $nativeType = GetNativeType($attribute->type, $attribute->extendedAttributes, "parameter"); |
if ($attribute->type eq "EventHandler") { |
+ ### DONE |
if ($interface->name eq "Window") { |
$code .= " if (!imp->document())\n"; |
$code .= " return;\n"; |
} |
} else { |
+ ### DONE |
$code .= JSValueToNativeStatement($attribute->type, $attribute->extendedAttributes, "value", "v", " ", "info.GetIsolate()"); |
} |
+ ### TODO |
if (IsEnumType($attrType)) { |
# setter ignores invalid enumeration values |
my @enumValues = ValidEnumValues($attrType); |
@@ -1954,6 +2049,7 @@ sub GenerateParametersCheckExpression |
# As per Web IDL specification, the length of a function Object is |
# its number of mandatory parameters. |
+### get_function_mandatory_parameters in python generator |
sub GetFunctionLength |
{ |
my $function = shift; |
@@ -1993,6 +2089,7 @@ sub GenerateFunctionParametersCheck |
return ($numMandatoryParams, join(" || ", @orExpression)); |
} |
+### TODO |
sub GenerateOverloadedFunction |
{ |
my $function = shift; |
@@ -2063,8 +2160,11 @@ static void ${name}MethodCallback${forMainWorldSuffix}(const v8::FunctionCallbac |
{ |
END |
$code .= " TRACE_EVENT_SET_SAMPLING_STATE(\"Blink\", \"DOMMethod\");\n"; |
+ ### DONE |
$code .= GenerateFeatureObservation($function->extendedAttributes->{"MeasureAs"}); |
+ ### DONE |
$code .= GenerateDeprecationNotification($function->extendedAttributes->{"DeprecateAs"}); |
+ ### DONE |
if (HasActivityLogging($forMainWorldSuffix, $function->extendedAttributes, "Access")) { |
$code .= GenerateActivityLogging("Method", $interface, "${name}"); |
} |
@@ -2079,8 +2179,10 @@ END |
$implementation{nameSpaceInternal}->add($code); |
} |
+### __FUNC__ |
sub GenerateFunction |
{ |
+ print " [GenerateFunction]\n"; |
my $function = shift; |
my $interface = shift; |
my $forMainWorldSuffix = shift; |
@@ -2108,6 +2210,7 @@ sub GenerateFunction |
$code .= "{\n"; |
if ($name eq "addEventListener" || $name eq "removeEventListener") { |
+ ### TODO |
my $lookupType = ($name eq "addEventListener") ? "OrCreate" : "Only"; |
my $passRefPtrHandling = ($name eq "addEventListener") ? "" : ".get()"; |
my $hiddenDependencyAction = ($name eq "addEventListener") ? "create" : "remove"; |
@@ -2140,9 +2243,11 @@ END |
return; |
} |
+ ### DONE |
$code .= GenerateArgumentsCountCheck($function, $interface); |
if ($name eq "set" and IsConstructorTemplate($interface, "TypedArray")) { |
+ ### TODO |
AddToImplIncludes("bindings/v8/custom/V8ArrayBufferViewCustom.h"); |
$code .= <<END; |
setWebGLArrayHelper<$implClassName, ${v8ClassName}>(args); |
@@ -2153,8 +2258,10 @@ END |
return; |
} |
+ ### TODO |
my ($svgPropertyType, $svgListPropertyType, $svgNativeType) = GetSVGPropertyTypes($interfaceName); |
+ ### TODO |
if ($svgNativeType) { |
my $nativeClassName = GetNativeType($interfaceName); |
if ($interfaceName =~ /List$/) { |
@@ -2172,14 +2279,17 @@ END |
$code .= " $svgWrappedNativeType* imp = &impInstance;\n"; |
} |
} elsif (!$function->isStatic) { |
+ ### main |
$code .= <<END; |
${implClassName}* imp = ${v8ClassName}::toNative(args.Holder()); |
END |
} |
+ ### TODO |
$code .= GenerateCustomElementInvocationScopeIfNeeded($funcExt); |
# Check domain security if needed |
+ ### TODO |
if ($interface->extendedAttributes->{"CheckSecurity"} && !$function->extendedAttributes->{"DoNotCheckSecurity"}) { |
# We have not find real use cases yet. |
AddToImplIncludes("core/page/Frame.h"); |
@@ -2190,6 +2300,7 @@ END |
END |
} |
+ ### DONE |
my $raisesExceptions = $function->extendedAttributes->{"RaisesException"}; |
if (!$raisesExceptions) { |
foreach my $parameter (@{$function->parameters}) { |
@@ -2199,11 +2310,13 @@ END |
} |
} |
+ ### DONE |
if ($raisesExceptions) { |
AddToImplIncludes("bindings/v8/ExceptionState.h"); |
$code .= " ExceptionState es(args.GetIsolate());\n"; |
} |
+ ### TODO |
if ($function->extendedAttributes->{"CheckSecurityForNode"}) { |
AddToImplIncludes("bindings/v8/BindingSecurity.h"); |
$code .= " if (!BindingSecurity::shouldAllowAccessToNode(imp->" . GetImplName($function) . "(es))) {\n"; |
@@ -2213,16 +2326,25 @@ END |
END |
} |
+ ### main DONE |
+ print " [GenerateParametersCheck]\n"; |
my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interface, $forMainWorldSuffix); |
$code .= $parameterCheckString; |
# Build the function call string. |
+ ### TODO |
+ ### main |
+ if($paramIndex != @{$function->parameters}) { |
+ ## Never |
+ } |
$code .= GenerateFunctionCallString($function, $paramIndex, " ", $interface, $forMainWorldSuffix, %replacements); |
$code .= "}\n\n"; |
$code .= "#endif // ${conditionalString}\n\n" if $conditionalString; |
$implementation{nameSpaceInternal}->add($code); |
} |
+### get_call_with_parameter and call_with_statements macro in python |
+### DONE |
sub GenerateCallWith |
{ |
my $callWith = shift; |
@@ -2259,6 +2381,7 @@ sub GenerateCallWith |
return ([@callWithArgs], $code); |
} |
+### no corresponds function in python generator. write in template. |
sub GenerateArgumentsCountCheck |
{ |
my $function = shift; |
@@ -2285,6 +2408,7 @@ sub GenerateArgumentsCountCheck |
return $argumentsCountCheckString; |
} |
+### see macro.template |
sub GenerateParametersCheck |
{ |
my $function = shift; |
@@ -2302,10 +2426,11 @@ sub GenerateParametersCheck |
# Optional arguments without [Default=...] should generate an early call with fewer arguments. |
# Optional arguments with [Optional=...] should not generate the early call. |
# Optional Dictionary arguments always considered to have default of empty dictionary. |
+ ### DONE early_call in python |
if ($parameter->isOptional && !$parameter->extendedAttributes->{"Default"} && $nativeType ne "Dictionary" && !IsCallbackInterface($parameter->type)) { |
$parameterCheckString .= " if (args.Length() <= $paramIndex)"; |
my $functionCall = GenerateFunctionCallString($function, $paramIndex, " " x 2, $interface, $forMainWorldSuffix, %replacements); |
- my $multiLine = ($functionCall =~ tr/\n//) > 1; |
+ my $multiLine = ($functionCall =~ tr/\n//) > 1; # always true |
$parameterCheckString .= $multiLine ? " {\n" : "\n"; |
$parameterCheckString .= $functionCall; |
$parameterCheckString .= $multiLine ? " }\n" : "\n"; |
@@ -2317,6 +2442,7 @@ sub GenerateParametersCheck |
my $v8ClassName = "V8" . $parameter->type; |
AddToImplIncludes("$v8ClassName.h"); |
if ($parameter->isOptional) { |
+ ### DONE |
$parameterCheckString .= " RefPtr<" . $parameter->type . "> $parameterName;\n"; |
$parameterCheckString .= " if (args.Length() > $paramIndex && !args[$paramIndex]->IsNull() && !args[$paramIndex]->IsUndefined()) {\n"; |
$parameterCheckString .= " if (!args[$paramIndex]->IsFunction()) {\n"; |
@@ -2326,6 +2452,7 @@ sub GenerateParametersCheck |
$parameterCheckString .= " $parameterName = ${v8ClassName}::create(args[$paramIndex], getScriptExecutionContext());\n"; |
$parameterCheckString .= " }\n"; |
} else { |
+ ### was DONE ? |
$parameterCheckString .= " if (args.Length() <= $paramIndex || "; |
if ($parameter->isNullable) { |
$parameterCheckString .= "!(args[$paramIndex]->IsFunction() || args[$paramIndex]->IsNull())"; |
@@ -2341,6 +2468,7 @@ sub GenerateParametersCheck |
$parameterCheckString .= "${v8ClassName}::create(args[$paramIndex], getScriptExecutionContext());\n"; |
} |
} elsif ($parameter->extendedAttributes->{"Clamp"}) { |
+ ### DONE |
my $nativeValue = "${parameterName}NativeValue"; |
my $paramType = $parameter->type; |
$parameterCheckString .= " $paramType $parameterName = 0;\n"; |
@@ -2348,15 +2476,17 @@ sub GenerateParametersCheck |
$parameterCheckString .= " if (!std::isnan($nativeValue))\n"; |
$parameterCheckString .= " $parameterName = clampTo<$paramType>($nativeValue);\n"; |
} elsif ($parameter->type eq "SerializedScriptValue") { |
+ ### DONE |
AddToImplIncludes("bindings/v8/SerializedScriptValue.h"); |
$parameterCheckString .= " bool ${parameterName}DidThrow = false;\n"; |
$parameterCheckString .= " $nativeType $parameterName = SerializedScriptValue::create(args[$paramIndex], 0, 0, ${parameterName}DidThrow, args.GetIsolate());\n"; |
$parameterCheckString .= " if (${parameterName}DidThrow)\n"; |
$parameterCheckString .= " return;\n"; |
} elsif ($parameter->isVariadic) { |
+ ### DONE |
my $nativeElementType = GetNativeType($parameter->type); |
if ($nativeElementType =~ />$/) { |
- $nativeElementType .= " "; |
+ $nativeElementType .= " "; # TODO |
} |
my $argType = $parameter->type; |
@@ -2373,6 +2503,7 @@ sub GenerateParametersCheck |
$parameterCheckString .= " V8TRYCATCH_VOID(Vector<$nativeElementType>, $parameterName, toNativeArguments<$nativeElementType>(args, $paramIndex));\n"; |
} |
} elsif ($nativeType =~ /^V8StringResource/) { |
+ ### DONE |
my $default = defined $parameter->extendedAttributes->{"Default"} ? $parameter->extendedAttributes->{"Default"} : ""; |
my $jsValue = $parameter->isOptional && $default eq "NullString" ? "argumentOrNull(args, $paramIndex)" : "args[$paramIndex]"; |
$parameterCheckString .= JSValueToNativeStatement($parameter->type, $parameter->extendedAttributes, $jsValue, $parameterName, " ", "args.GetIsolate()"); |
@@ -2417,6 +2548,7 @@ sub GenerateParametersCheck |
} |
} |
+ ### DONE |
if ($parameter->extendedAttributes->{"IsIndex"}) { |
AddToImplIncludes("core/dom/ExceptionCode.h"); |
$parameterCheckString .= " if (UNLIKELY($parameterName < 0)) {\n"; |
@@ -2427,6 +2559,8 @@ sub GenerateParametersCheck |
$paramIndex++; |
} |
+ print "PARAM STRING\n", $parameterCheckString, "\n" if $interface->name eq "CanvasGradient"; |
+ # $paramIndex == len(parameters) |
return ($parameterCheckString, $paramIndex, %replacements); |
} |
@@ -2464,6 +2598,8 @@ END |
$implementation{nameSpaceInternal}->add($code); |
} |
+### get_single_constructor_callback_parameter in python code generator |
+### DONE |
sub GenerateSingleConstructorCallback |
{ |
my $interface = shift; |
@@ -2476,14 +2612,15 @@ sub GenerateSingleConstructorCallback |
$overloadedIndexString .= $function->overloadedIndex; |
} |
- my $raisesExceptions = $function->extendedAttributes->{"RaisesException"}; |
+ my $raisesExceptions = $function->extendedAttributes->{"RaisesException"}; ### never be true! |
if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |
- $raisesExceptions = 1; |
+ $raisesExceptions = 1; ### exist |
} |
if (!$raisesExceptions) { |
foreach my $parameter (@{$function->parameters}) { |
if ($parameter->extendedAttributes->{"IsIndex"}) { |
$raisesExceptions = 1; |
+ # Never executed! |
} |
} |
} |
@@ -2581,6 +2718,7 @@ sub GetInterfaceLength |
return $leastConstructorLength; |
} |
+### DONE |
sub GenerateConstructorCallback |
{ |
my $interface = shift; |
@@ -2591,8 +2729,11 @@ sub GenerateConstructorCallback |
$code .= "void ${v8ClassName}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args)\n"; |
$code .= "{\n"; |
$code .= " TRACE_EVENT_SCOPED_SAMPLING_STATE(\"Blink\", \"DOMConstructor\");\n"; |
+ ### DONE |
$code .= GenerateFeatureObservation($interface->extendedAttributes->{"MeasureAs"}); |
+ ### DONE |
$code .= GenerateDeprecationNotification($interface->extendedAttributes->{"DeprecateAs"}); |
+ ### DONE |
$code .= GenerateConstructorHeader(); |
if (HasCustomConstructor($interface)) { |
$code .= " ${v8ClassName}::constructorCustom(args);\n"; |
@@ -2608,8 +2749,10 @@ sub GenerateConstructor |
my $interface = shift; |
if (@{$interface->constructors} == 1) { |
+ ### DONE |
GenerateSingleConstructorCallback($interface, @{$interface->constructors}[0]); |
} else { |
+ ### TODO |
foreach my $constructor (@{$interface->constructors}) { |
GenerateSingleConstructorCallback($interface, $constructor); |
} |
@@ -2623,6 +2766,7 @@ sub GenerateEventConstructor |
my $implClassName = GetImplName($interface); |
my $v8ClassName = GetV8ClassName($interface); |
+ ### TODO MERGE |
my @anyAttributeNames; |
my @serializableAnyAttributeNames; |
foreach my $attribute (@{$interface->attributes}) { |
@@ -2635,6 +2779,7 @@ sub GenerateEventConstructor |
} |
AddToImplIncludes("bindings/v8/Dictionary.h"); |
+ ### DONE |
$implementation{nameSpaceInternal}->add(<<END); |
static void constructor(const v8::FunctionCallbackInfo<v8::Value>& args) |
{ |
@@ -2695,6 +2840,7 @@ END |
} |
END |
+ ### DONE |
my $code = ""; |
$code .= <<END; |
bool fill${implClassName}Init(${implClassName}Init& eventInit, const Dictionary& options) |
@@ -2710,6 +2856,7 @@ END |
END |
} |
+ ### TODO |
foreach my $attribute (@{$interface->attributes}) { |
if ($attribute->extendedAttributes->{"InitializedByEventConstructor"}) { |
if ($attribute->type ne "any") { |
@@ -2735,6 +2882,7 @@ END |
$implementation{nameSpaceWebCore}->add($code); |
} |
+### DONE |
sub GenerateNamedConstructor |
{ |
my $function = shift; |
@@ -2742,13 +2890,17 @@ sub GenerateNamedConstructor |
my $implClassName = GetImplName($interface); |
my $v8ClassName = GetV8ClassName($interface); |
+ # thif is always false here |
my $raisesExceptions = $function->extendedAttributes->{"RaisesException"}; |
+# print "NEVER\n" if $raisesExceptions; |
if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |
$raisesExceptions = 1; |
} |
if (!$raisesExceptions) { |
foreach my $parameter (@{$function->parameters}) { |
if ($parameter->extendedAttributes->{"IsIndex"}) { |
+ # NEVER! |
+# print "NEVER\n"; |
$raisesExceptions = 1; |
} |
} |
@@ -2769,6 +2921,7 @@ sub GenerateNamedConstructor |
if (InheritsInterface($interface, "EventTarget")) { |
$toEventTarget = "${v8ClassName}::toEventTarget"; |
} |
+# print "GEHEHE", $interface->name, "\n"; |
AddToImplIncludes("core/page/Frame.h"); |
$implementation{nameSpaceWebCore}->add(<<END); |
@@ -2781,10 +2934,14 @@ END |
static void ${v8ClassName}ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
{ |
END |
+ ### DONE |
$code .= $maybeObserveFeature if $maybeObserveFeature; |
+ ### DONE |
$code .= $maybeDeprecateFeature if $maybeDeprecateFeature; |
+ ### DONE |
$code .= GenerateConstructorHeader(); |
AddToImplIncludes("V8Document.h"); |
+ ### DONE |
$code .= <<END; |
Document* document = currentDocument(); |
@@ -2794,22 +2951,28 @@ END |
END |
+ ### DONE |
$code .= GenerateArgumentsCountCheck($function, $interface); |
+ ### DONE |
if ($raisesExceptions) { |
AddToImplIncludes("bindings/v8/ExceptionState.h"); |
$code .= " ExceptionState es(args.GetIsolate());\n"; |
} |
+ ### DONE |
my ($parameterCheckString, $paramIndex, %replacements) = GenerateParametersCheck($function, $interface); |
$code .= $parameterCheckString; |
+ ### DONE |
push(@beforeArgumentList, "document"); |
+ ### DONE |
if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |
push(@afterArgumentList, "es"); |
} |
+ ### DONE |
my @argumentList; |
my $index = 0; |
foreach my $parameter (@{$function->parameters}) { |
@@ -2822,16 +2985,20 @@ END |
$index++; |
} |
+ ### DONE |
my $argumentString = join(", ", @beforeArgumentList, @argumentList, @afterArgumentList); |
+ ### DONE |
$code .= "\n"; |
$code .= " RefPtr<${implClassName}> impl = ${implClassName}::createForJSConstructor(${argumentString});\n"; |
$code .= " v8::Handle<v8::Object> wrapper = args.Holder();\n"; |
+ ### DONE |
if ($interface->extendedAttributes->{"ConstructorRaisesException"}) { |
$code .= " if (es.throwIfNeeded())\n"; |
$code .= " return;\n"; |
} |
+ ### DONE |
$code .= <<END; |
V8DOMWrapper::associateObjectWithWrapper<${v8ClassName}>(impl.release(), &${v8ClassName}Constructor::info, wrapper, args.GetIsolate(), WrapperConfiguration::Dependent); |
@@ -2841,6 +3008,7 @@ END |
END |
$implementation{nameSpaceWebCore}->add($code); |
+ ### DONE |
$code = <<END; |
v8::Handle<v8::FunctionTemplate> ${v8ClassName}Constructor::GetTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType) |
{ |
@@ -2868,6 +3036,7 @@ END |
$implementation{nameSpaceWebCore}->add($code); |
} |
+### DONE |
sub GenerateConstructorHeader |
{ |
AddToImplIncludes("bindings/v8/V8ObjectConstructor.h"); |
@@ -2903,6 +3072,7 @@ sub GenerateBatchedAttributeData |
return $code; |
} |
+### get_single_batched_attribute in python |
sub GenerateSingleBatchedAttribute |
{ |
my $interface = shift; |
@@ -3118,10 +3288,13 @@ END |
return $code; |
} |
+### DONE |
+# get_is_null_expression in python |
sub GenerateIsNullExpression |
{ |
my $type = shift; |
my $variableName = shift; |
+ ### DONE |
if (IsUnionType($type)) { |
my $types = $type->unionMemberTypes; |
my @expression = (); |
@@ -3133,6 +3306,7 @@ sub GenerateIsNullExpression |
} |
return join " && ", @expression; |
} |
+ ### DONE |
if (IsRefPtrType($type)) { |
return "!${variableName}"; |
} elsif ($type eq "DOMString") { |
@@ -3178,11 +3352,14 @@ sub GenerateImplementationIndexedPropertyAccessors |
if ($indexedGetterFunction) { |
my $hasCustomIndexedGetter = $indexedGetterFunction->extendedAttributes->{"Custom"}; |
if (!$hasCustomIndexedGetter) { |
+ ### working |
GenerateImplementationIndexedPropertyGetter($interface, $indexedGetterFunction); |
} |
+ ### working |
GenerateImplementationIndexedPropertyGetterCallback($interface, $hasCustomIndexedGetter); |
} |
+ ### TODO |
my $indexedSetterFunction = GetIndexedSetterFunction($interface); |
if ($indexedSetterFunction) { |
my $hasCustomIndexedSetter = $indexedSetterFunction->extendedAttributes->{"Custom"}; |
@@ -3192,6 +3369,7 @@ sub GenerateImplementationIndexedPropertyAccessors |
GenerateImplementationIndexedPropertySetterCallback($interface, $hasCustomIndexedSetter); |
} |
+ ### TODO |
my $indexedDeleterFunction = GetIndexedDeleterFunction($interface); |
if ($indexedDeleterFunction) { |
my $hasCustomIndexedDeleter = $indexedDeleterFunction->extendedAttributes->{"Custom"}; |
@@ -3201,13 +3379,16 @@ sub GenerateImplementationIndexedPropertyAccessors |
GenerateImplementationIndexedPropertyDeleterCallback($interface, $hasCustomIndexedDeleter); |
} |
+ ### DONE |
my $indexedEnumeratorFunction = $indexedGetterFunction; |
$indexedEnumeratorFunction = 0 if $indexedGetterFunction && $indexedGetterFunction->extendedAttributes->{"NotEnumerable"}; |
+ ### DONE |
my $indexedQueryFunction = 0; |
# If there is an enumerator, there MUST be a query method to properly communicate property attributes. |
my $hasQuery = $indexedQueryFunction || $indexedEnumeratorFunction; |
+ ### DONE |
my $setOn = "Instance"; |
# V8 has access-check callback API (see ObjectTemplate::SetAccessCheckCallbacks) and it's used on Window |
@@ -3218,6 +3399,7 @@ sub GenerateImplementationIndexedPropertyAccessors |
$setOn = "Prototype"; |
} |
+ ### DONE |
my $code = ""; |
if ($indexedGetterFunction || $indexedSetterFunction || $indexedDeleterFunction || $indexedEnumeratorFunction || $hasQuery) { |
$code .= " desc->${setOn}Template()->SetIndexedPropertyHandler(${implClassName}V8Internal::indexedPropertyGetterCallback"; |
@@ -3243,26 +3425,35 @@ sub GenerateImplementationIndexedPropertyGetter |
my $nativeType = GetNativeType($returnType); |
my $nativeValue = "element"; |
$nativeValue .= ".release()" if (IsRefPtrType($returnType)); |
+ ### DONE |
my $isNull = GenerateIsNullExpression($returnType, "element"); |
+ ### DONE |
my $returnJSValueCode = NativeToJSValue($indexedGetterFunction->type, $indexedGetterFunction->extendedAttributes, $nativeValue, " ", "", "info.Holder()", "info.GetIsolate()", "info", "collection", "", "return"); |
my $raisesExceptions = $indexedGetterFunction->extendedAttributes->{"RaisesException"}; |
+ ### DONE |
my $methodCallCode = GenerateMethodCall($returnType, "element", "collection->${methodName}", "index", $raisesExceptions); |
+ ### DONE |
my $getterCode = "static void indexedPropertyGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)\n"; |
$getterCode .= "{\n"; |
$getterCode .= " ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));\n"; |
$getterCode .= " ${implClassName}* collection = ${v8ClassName}::toNative(info.Holder());\n"; |
+ ### DONE |
if ($raisesExceptions) { |
$getterCode .= " ExceptionState es(info.GetIsolate());\n"; |
} |
+ ### DONE but use function_call later |
$getterCode .= $methodCallCode . "\n"; |
+ ### DONE |
if ($raisesExceptions) { |
$getterCode .= " if (es.throwIfNeeded())\n"; |
$getterCode .= " return;\n"; |
} |
if (IsUnionType($returnType)) { |
+ ### TDOO |
$getterCode .= "${returnJSValueCode}\n"; |
$getterCode .= " return;\n"; |
} else { |
+ ### DONE |
$getterCode .= " if (${isNull})\n"; |
$getterCode .= " return;\n"; |
$getterCode .= $returnJSValueCode . "\n"; |
@@ -3365,6 +3556,7 @@ sub GenerateImplementationIndexedPropertySetter |
} |
push @conditions, ""; |
push @statements, "collection->${methodName}(index, propertyValue$extraArguments);"; |
+ # TODO |
$code .= GenerateIfElseStatement("bool", "result", \@conditions, \@statements); |
$code .= " if (!result)\n"; |
@@ -3548,6 +3740,8 @@ sub GenerateImplementationNamedPropertyQueryCallback |
$implementation{nameSpaceInternal}->add($code); |
} |
+### TODO: use js_value_to_native |
+### get_function_call_statements in python |
sub GenerateMethodCall |
{ |
my $returnType = shift; # string or UnionType |
@@ -3794,6 +3988,7 @@ static void namedPropertyQuery(v8::Local<v8::String> name, const v8::PropertyCal |
END |
} |
+### TODO 7/16 |
sub GenerateImplementationLegacyCall |
{ |
my $interface = shift; |
@@ -3819,6 +4014,7 @@ sub GenerateImplementationMasqueradesAsUndefined |
return $code; |
} |
+# __IMPL__ |
sub GenerateImplementation |
{ |
my $object = shift; |
@@ -3852,6 +4048,7 @@ sub GenerateImplementation |
} |
my $parentClassInfo = $parentClass ? "&${parentClass}::info" : "0"; |
+ ### only DOMException isException==True |
my $WrapperTypePrototype = $interface->isException ? "WrapperTypeErrorPrototype" : "WrapperTypeObjectPrototype"; |
if (!IsSVGTypeNeedingTearOff($interfaceName)) { |
@@ -3919,41 +4116,56 @@ END |
AddToImplIncludes("bindings/v8/SerializedScriptValue.h"); |
} |
+ ### DONE |
GenerateNormalAttrGetter($attribute, $interface, ""); |
+ ### DONE |
GenerateNormalAttrGetterCallback($attribute, $interface, ""); |
if ($attrExt->{"PerWorldBindings"}) { |
+ ### DONE |
GenerateNormalAttrGetter($attribute, $interface, "ForMainWorld"); |
+ ### DONE |
GenerateNormalAttrGetterCallback($attribute, $interface, "ForMainWorld"); |
} |
if (!HasCustomSetter($attrExt) && $attrExt->{"Replaceable"}) { |
+ ### TODO |
$hasReplaceable = 1; |
} elsif (!IsReadonly($attribute)) { |
+ ### DONE(basic) |
GenerateNormalAttrSetter($attribute, $interface, ""); |
+ ### DONE |
GenerateNormalAttrSetterCallback($attribute, $interface, ""); |
if ($attrExt->{"PerWorldBindings"}) { |
+ ### DONE(basic) |
GenerateNormalAttrSetter($attribute, $interface, "ForMainWorld"); |
+ ### DONE |
GenerateNormalAttrSetterCallback($attribute, $interface, "ForMainWorld"); |
} |
} |
} |
if ($hasConstructors) { |
+ ### TODO |
GenerateConstructorGetter($interface); |
} |
if ($hasConstructors || $hasReplaceable) { |
+ ### TODO |
GenerateReplaceableAttrSetter($interface); |
+ ### TODO |
GenerateReplaceableAttrSetterCallback($interface); |
} |
if (NeedsOpaqueRootForGC($interface)) { |
+ ### DONE |
GenerateOpaqueRootForGC($interface); |
} |
if ($interface->extendedAttributes->{"CheckSecurity"} && $interface->name ne "Window") { |
+ ### TODO |
GenerateSecurityCheckFunctions($interface); |
} |
+ ### TODO |
if (IsConstructorTemplate($interface, "TypedArray")) { |
my ($nativeType, $arrayType) = GetNativeTypeOfTypedArray($interface); |
$implementation{nameSpaceWebCore}->add(<<END); |
@@ -3975,19 +4187,24 @@ END |
# Generate methods for functions. |
foreach my $function (@{$interface->functions}) { |
next if $function->name eq ""; |
+ ### DONE (basic) |
GenerateFunction($function, $interface, ""); |
if ($function->extendedAttributes->{"PerWorldBindings"}) { |
+ ### TODO |
GenerateFunction($function, $interface, "ForMainWorld"); |
} |
if ($function->{overloadIndex} == @{$function->{overloads}}) { |
+ ### TODO |
if ($function->{overloadIndex} > 1) { |
GenerateOverloadedFunction($function, $interface, ""); |
if ($function->extendedAttributes->{"PerWorldBindings"}) { |
GenerateOverloadedFunction($function, $interface, "ForMainWorld"); |
} |
} |
+ ### DONE |
GenerateFunctionCallback($function, $interface, ""); |
if ($function->extendedAttributes->{"PerWorldBindings"}) { |
+ ### TODO |
GenerateFunctionCallback($function, $interface, "ForMainWorld"); |
} |
} |
@@ -3995,6 +4212,7 @@ END |
# If the function does not need domain security check, we need to |
# generate an access getter that returns different function objects |
# for different calling context. |
+ ### TODO |
if ($interface->extendedAttributes->{"CheckSecurity"} && $function->extendedAttributes->{"DoNotCheckSecurity"}) { |
if (!HasCustomMethod($function->extendedAttributes) || $function->{overloadIndex} == 1) { |
GenerateDomainSafeFunctionGetter($function, $interface); |
@@ -4004,6 +4222,7 @@ END |
} |
} |
+ ### TODO |
# Separate out functions that are enabled per context so we can process them specially. |
if ($function->extendedAttributes->{"EnabledPerContext"}) { |
push(@enabledPerContextFunctions, $function); |
@@ -4013,6 +4232,7 @@ END |
} |
if ($needsDomainSafeFunctionSetter) { |
+ ### TODO |
GenerateDomainSafeFunctionSetter($interface); |
} |
@@ -4028,6 +4248,7 @@ END |
my @normalAttributes; |
foreach my $attribute (@$attributes) { |
+ ### TODO |
if ($interfaceName eq "Window" && $attribute->extendedAttributes->{"Unforgeable"}) { |
push(@disallowsShadowing, $attribute); |
} elsif ($attribute->extendedAttributes->{"EnabledAtRuntime"} || $attribute->extendedAttributes->{"EnabledPerContext"}) { |
@@ -4044,6 +4265,7 @@ END |
AddToImplIncludes("bindings/v8/V8DOMConfiguration.h"); |
$attributes = \@normalAttributes; |
# Put the attributes that disallow shadowing on the shadow object. |
+ ### DONE |
if (@disallowsShadowing) { |
my $code = ""; |
$code .= "static const V8DOMConfiguration::BatchedAttribute shadowAttrs[] = {\n"; |
@@ -4052,6 +4274,8 @@ END |
$implementation{nameSpaceWebCore}->add($code); |
} |
+# use Data::Dumper; |
+# print "GEHEHE", Dumper($attributes), "\n" if $interface->name eq "File"; |
my $has_attributes = 0; |
if (@$attributes) { |
$has_attributes = 1; |
@@ -4106,13 +4330,16 @@ END |
my $value = $constant->value; |
my $attrExt = $constant->extendedAttributes; |
my $implementedBy = $attrExt->{"ImplementedBy"}; |
+ ### DONE |
if ($implementedBy) { |
my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy); |
AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implementedByImplName)); |
} |
if ($attrExt->{"EnabledAtRuntime"}) { |
+ ### TODO |
push(@constantsEnabledAtRuntime, $constant); |
} else { |
+ ### DONE |
my $conditionalString = GenerateConditionalString($constant); |
$code .= "#if ${conditionalString}\n" if $conditionalString; |
# If the value we're dealing with is a hex number, preprocess it into a signed integer |
@@ -4132,24 +4359,31 @@ END |
$implementation{nameSpaceWebCore}->add($code); |
} |
+ ### working |
if (!HasCustomConstructor($interface)) { |
if ($interface->extendedAttributes->{"NamedConstructor"}) { |
+ ### DONE |
GenerateNamedConstructor(@{$interface->constructors}[0], $interface); |
} elsif ($interface->extendedAttributes->{"Constructor"}) { |
+ ### DONE |
GenerateConstructor($interface); |
} elsif (IsConstructorTemplate($interface, "Event")) { |
+ ### TODO |
GenerateEventConstructor($interface); |
} |
} |
if (IsConstructable($interface)) { |
+ ### DONE |
GenerateConstructorCallback($interface); |
} |
+ ### DONE |
my $access_check = ""; |
if ($interface->extendedAttributes->{"CheckSecurity"} && $interfaceName ne "Window") { |
$access_check = "instance->SetAccessCheckCallbacks(${implClassName}V8Internal::namedSecurityCheck, ${implClassName}V8Internal::indexedSecurityCheck, v8::External::New(&${v8ClassName}::info));"; |
} |
+ ### TODO |
# For the Window interface, generate the shadow object template |
# configuration method. |
if ($interfaceName eq "Window") { |
@@ -4214,12 +4448,14 @@ END |
UNUSED_PARAM(defaultSignature); // In some cases, it will not be used. |
END |
+ ### TODO |
if (IsConstructable($interface)) { |
$code .= " desc->SetCallHandler(${v8ClassName}::constructorCallback);\n"; |
my $interfaceLength = GetInterfaceLength($interface); |
$code .= " desc->SetLength(${interfaceLength});\n"; |
} |
+ ### DONE |
if ($access_check or @enabledAtRuntimeAttributes or @normalFunctions or $has_constants) { |
$code .= <<END; |
v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate(); |
@@ -4229,10 +4465,12 @@ END |
END |
} |
+ ### DONE |
if ($access_check) { |
$code .= " $access_check\n"; |
} |
+ ### DONE |
# Setup the enable-at-runtime attrs if we have them |
foreach my $runtime_attr (@enabledAtRuntimeAttributes) { |
next if grep { $_ eq $runtime_attr } @enabledPerContextAttributes; |
@@ -4249,6 +4487,7 @@ END |
$code .= "\n#endif // ${conditionalString}\n" if $conditionalString; |
} |
+ ### DONE |
# Setup the enable-at-runtime constants if we have them |
foreach my $runtime_const (@constantsEnabledAtRuntime) { |
my $enable_function = GetRuntimeEnableFunctionName($runtime_const); |
@@ -4265,9 +4504,13 @@ END |
$code .= "\n#endif // ${conditionalString}\n" if $conditionalString; |
} |
+ ### TODO |
$code .= GenerateImplementationIndexedPropertyAccessors($interface); |
+ ### TODO |
$code .= GenerateImplementationNamedPropertyAccessors($interface); |
+ ### TODO |
$code .= GenerateImplementationLegacyCall($interface); |
+ ### TODO |
$code .= GenerateImplementationMasqueradesAsUndefined($interface); |
# Define our functions with Set() or SetAccessor() |
@@ -4279,12 +4522,14 @@ END |
$total_functions++; |
next if IsStandardFunction($interface, $function); |
+ ### DONE |
$code .= GenerateNonStandardFunction($interface, $function); |
$num_callbacks++; |
} |
die "Wrong number of callbacks generated for $interfaceName ($num_callbacks, should be $total_functions)" if $num_callbacks != $total_functions; |
+ ### DONE |
if ($has_constants) { |
$code .= <<END; |
V8DOMConfiguration::batchConfigureConstants(desc, proto, ${v8ClassName}Consts, WTF_ARRAY_LENGTH(${v8ClassName}Consts), isolate); |
@@ -4292,6 +4537,7 @@ END |
} |
# Special cases |
+ ### TODO |
if ($interfaceName eq "Window") { |
$code .= <<END; |
@@ -4304,12 +4550,14 @@ END |
instance->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window::indexedSecurityCheckCustom, v8::External::New(&V8Window::info), false); |
END |
} |
+ ### TODO |
if ($interfaceName eq "HTMLDocument" or $interfaceName eq "DedicatedWorkerGlobalScope" or $interfaceName eq "SharedWorkerGlobalScope") { |
$code .= <<END; |
desc->SetHiddenPrototype(true); |
END |
} |
+ ### DONE |
$code .= <<END; |
// Custom toString template |
@@ -4337,6 +4585,7 @@ v8::Handle<v8::FunctionTemplate> ${v8ClassName}::GetTemplate(v8::Isolate* isolat |
} |
END |
+ ### DONE |
$implementation{nameSpaceWebCore}->add(<<END); |
bool ${v8ClassName}::HasInstance(v8::Handle<v8::Value> value, v8::Isolate* isolate, WrapperWorldType currentWorldType) |
{ |
@@ -4344,6 +4593,7 @@ bool ${v8ClassName}::HasInstance(v8::Handle<v8::Value> value, v8::Isolate* isola |
} |
END |
+ ### DONE |
$implementation{nameSpaceWebCore}->add(<<END); |
bool ${v8ClassName}::HasInstanceInAnyWorld(v8::Handle<v8::Value> value, v8::Isolate* isolate) |
{ |
@@ -4354,6 +4604,7 @@ bool ${v8ClassName}::HasInstanceInAnyWorld(v8::Handle<v8::Value> value, v8::Isol |
END |
+ ### TODO |
if (@enabledPerContextAttributes) { |
my $code = ""; |
$code .= <<END; |
@@ -4389,6 +4640,7 @@ END |
$implementation{nameSpaceWebCore}->add($code); |
} |
+ ### TODO |
if (@enabledPerContextFunctions) { |
my $code = ""; |
$code .= <<END; |
@@ -4424,6 +4676,7 @@ END |
$implementation{nameSpaceWebCore}->add($code); |
} |
+ ### DONE |
if (InheritsExtendedAttribute($interface, "ActiveDOMObject")) { |
# MessagePort is handled like an active dom object even though it doesn't inherit |
# from ActiveDOMObject, so don't try to cast it to ActiveDOMObject. |
@@ -4437,6 +4690,7 @@ ActiveDOMObject* ${v8ClassName}::toActiveDOMObject(v8::Handle<v8::Object> object |
END |
} |
+ ### DONE |
if (InheritsInterface($interface, "EventTarget")) { |
$implementation{nameSpaceWebCore}->add(<<END); |
EventTarget* ${v8ClassName}::toEventTarget(v8::Handle<v8::Object> object) |
@@ -4447,6 +4701,7 @@ EventTarget* ${v8ClassName}::toEventTarget(v8::Handle<v8::Object> object) |
END |
} |
+ ### TODO |
if ($interfaceName eq "Window") { |
$implementation{nameSpaceWebCore}->add(<<END); |
v8::Handle<v8::ObjectTemplate> V8Window::GetShadowObjectTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType) |
@@ -4537,6 +4792,8 @@ sub GenerateCallbackHeader |
END |
+#print "[CallbackHeader]", $interface->name, "\n"; |
+ |
# Functions |
my $numFunctions = @{$interface->functions}; |
if ($numFunctions > 0) { |
@@ -4550,6 +4807,7 @@ END |
} |
my @params = @{$function->parameters}; |
foreach my $param (@params) { |
+ print "[gch]", $param->name, "\n" if $interface->name eq "MIDISuccessCallback"; |
push(@args, GetNativeTypeForCallbacks($param->type) . " " . $param->name); |
} |
$code .= join(", ", @args); |
@@ -4599,6 +4857,8 @@ ${v8ClassName}::~${v8ClassName}() |
END |
+#print "[CallbackImp]", $interface->name, "\n"; |
+ |
# Functions |
my $numFunctions = @{$interface->functions}; |
if ($numFunctions > 0) { |
@@ -4819,10 +5079,14 @@ sub GetNamespaceForInterface |
return "WebCore"; |
} |
+# get_function_call_parameter and macro function_call in python |
sub GenerateFunctionCallString |
{ |
my $function = shift; |
my $numberOfParameters = shift; |
+ if ($numberOfParameters != @{$function->parameters}) { |
+# print "NEVER\n"; |
+ } |
my $indent = shift; |
my $interface = shift; |
my $forMainWorldSuffix = shift; |
@@ -4844,24 +5108,29 @@ sub GenerateFunctionCallString |
my $functionName; |
my $implementedBy = $function->extendedAttributes->{"ImplementedBy"}; |
if ($implementedBy) { |
+ ### DONE |
my $implementedByImplName = GetImplNameFromImplementedBy($implementedBy); |
AddToImplIncludes(HeaderFilesForInterface($implementedBy, $implementedByImplName)); |
unshift(@arguments, "imp") if !$function->isStatic; |
$functionName = "${implementedByImplName}::${name}"; |
} elsif ($function->isStatic) { |
+ ### DONE |
$functionName = "${implClassName}::${name}"; |
} else { |
+ ### DONE |
$functionName = "imp->${name}"; |
} |
+ ### DONE |
my $callWith = $function->extendedAttributes->{"CallWith"}; |
my ($callWithArgs, $subCode) = GenerateCallWith($callWith, $indent, 1, $function); |
$code .= $subCode; |
unshift(@arguments, @$callWithArgs); |
- $index += @$callWithArgs; |
- $numberOfParameters += @$callWithArgs; |
+# $index += @$callWithArgs; |
+# $numberOfParameters += @$callWithArgs; |
foreach my $parameter (@{$function->parameters}) { |
+ ### DONE |
if ($index eq $numberOfParameters) { |
last; |
} |
@@ -4869,10 +5138,13 @@ sub GenerateFunctionCallString |
my $paramType = $parameter->type; |
if ($replacements{$paramName}) { |
+ ### DONE |
push @arguments, $replacements{$paramName}; |
} elsif ($parameter->type eq "NodeFilter" || $parameter->type eq "XPathNSResolver") { |
+ ### DONE |
push @arguments, "$paramName.get()"; |
} elsif (IsSVGTypeNeedingTearOff($parameter->type) and not $interfaceName =~ /List$/) { |
+ ### DONE |
AddToImplIncludes("core/dom/ExceptionCode.h"); |
push @arguments, "$paramName->propertyReference()"; |
$code .= $indent . "if (!$paramName) {\n"; |
@@ -4880,41 +5152,55 @@ sub GenerateFunctionCallString |
$code .= $indent . " return;\n"; |
$code .= $indent . "}\n"; |
} elsif ($parameter->type eq "SVGMatrix" and $interfaceName eq "SVGTransformList") { |
+ ### DONE |
push @arguments, "$paramName.get()"; |
} else { |
+ ### main |
push @arguments, $paramName; |
} |
$index++; |
} |
+ ### DONE |
if ($function->extendedAttributes->{"RaisesException"}) { |
push @arguments, "es"; |
} |
+ ### DONE |
+ ### function_call_expression in python |
my $functionString = "$functionName(" . join(", ", @arguments) . ")"; |
+ ### DONE native_value_expression in python |
my $return = "result"; |
my $returnIsRef = IsRefPtrType($returnType); |
if ($returnType eq "void") { |
+ ### DONE |
+ ### function_call_statement in python generator |
$code .= $indent . "$functionString;\n"; |
} elsif (ExtendedAttributeContains($callWith, "ScriptState") or $function->extendedAttributes->{"RaisesException"}) { |
+ ### DONE |
+ ### function_call_statement in python generator |
$code .= $indent . $nativeReturnType . " result = $functionString;\n"; |
} else { |
+ ### DONE |
# Can inline the function call into the return statement to avoid overhead of using a Ref<> temporary |
$return = $functionString; |
$returnIsRef = 0; |
+ ### TODO |
if ($interfaceName eq "SVGTransformList" and IsRefPtrType($returnType)) { |
$return = "WTF::getPtr(" . $return . ")"; |
} |
} |
+ ### DONE |
if ($function->extendedAttributes->{"RaisesException"}) { |
$code .= $indent . "if (es.throwIfNeeded())\n"; |
$code .= $indent . " return;\n"; |
} |
+ ### DONE |
if (ExtendedAttributeContains($callWith, "ScriptState")) { |
$code .= $indent . "if (state.hadException()) {\n"; |
$code .= $indent . " v8::Local<v8::Value> exception = state.exception();\n"; |
@@ -4924,6 +5210,7 @@ sub GenerateFunctionCallString |
$code .= $indent . "}\n"; |
} |
+ ### TODO |
if ($isSVGTearOffType) { |
AddToImplIncludes("V8$returnType.h"); |
AddToImplIncludes("core/svg/properties/SVGPropertyTearOff.h"); |
@@ -4942,21 +5229,26 @@ sub GenerateFunctionCallString |
return $code; |
} |
+ ### TODO |
# If the implementing class is a POD type, commit changes |
if (IsSVGTypeNeedingTearOff($interfaceName) and not $interfaceName =~ /List$/) { |
$code .= $indent . "wrapper->commitChange();\n"; |
} |
+ ### DONE |
$return .= ".release()" if ($returnIsRef); |
my $nativeValue; |
# FIXME: Update for all ScriptWrappables. |
if (IsDOMNodeType($interfaceName)) { |
+ ### DONE |
$nativeValue = NativeToJSValue($function->type, $function->extendedAttributes, $return, $indent, "", "args.Holder()", "args.GetIsolate()", "args", "imp", $forMainWorldSuffix, "return"); |
} else { |
+ ### DONE |
$nativeValue = NativeToJSValue($function->type, $function->extendedAttributes, $return, $indent, "", "args.Holder()", "args.GetIsolate()", "args", 0, $forMainWorldSuffix, "return"); |
} |
+ ### DONE |
$code .= $nativeValue . "\n"; |
$code .= $indent . "return;\n"; |
@@ -4968,6 +5260,8 @@ sub GetNativeType |
my $type = shift; |
my $extendedAttributes = shift; |
my $isParameter = shift; |
+ my $isw = IsWrapperType($type) ? "WT":""; |
+print "[GetNativeType] $type, $isParameter $isw\n"; |
my $svgNativeType = GetSVGTypeNeedingTearOff($type); |
if ($svgNativeType) { |
@@ -5007,6 +5301,7 @@ sub GetNativeType |
return "String" if $type eq "DOMString" or IsEnumType($type); |
+ ### DONE |
return "Range::CompareHow" if $type eq "CompareHow"; |
return "DOMTimeStamp" if $type eq "DOMTimeStamp"; |
return "double" if $type eq "Date"; |
@@ -5027,6 +5322,9 @@ sub GetNativeType |
# We need to check [ImplementedAs] extended attribute for wrapper types. |
if (IsWrapperType($type)) { |
+# print "GEHEHE ", $type, "\n"; |
+# use Carp qw(cluck); |
+# cluck "HEY"; |
my $interface = ParseInterface($type); |
my $implClassName = GetImplName($interface); |
return $isParameter ? "${implClassName}*" : "RefPtr<${implClassName}>"; |
@@ -5048,6 +5346,10 @@ sub GetNativeType |
sub GetNativeTypeForCallbacks |
{ |
my $type = shift; |
+ print "#####\n[GetNativeTypeForCallbacks] $type\n" if $type eq "DOMException"; |
+# print "#####\n[Callback] DOMString\n" if $type eq "DOMString"; |
+# print "#####\n[Callback] SerializedScriptValue\n" if $type eq "SerializedScriptValue"; |
+ |
return "const String&" if $type eq "DOMString"; |
return "PassRefPtr<SerializedScriptValue>" if $type eq "SerializedScriptValue"; |
@@ -5175,6 +5477,7 @@ sub JSValueToNative |
return "V8${type}::HasInstance($value, $getIsolate, worldType($getIsolate)) ? V8${type}::toNative(v8::Handle<v8::Object>::Cast($value)) : 0"; |
} |
+### DONE |
sub CreateCustomSignature |
{ |
my $function = shift; |
@@ -5344,6 +5647,9 @@ sub NativeToJSValue |
my $returnValueArg = shift || 0; |
my $isReturnValue = $returnValueArg eq "return"; |
+ print " [NativeToJSValue]", $type, " ", $nativeValue, "\n"; |
+# if $type eq "AudioBuffer"; |
+ |
if (IsUnionType($type)) { |
my $types = $type->unionMemberTypes; |
my @codes = (); |
@@ -5465,6 +5771,7 @@ sub NativeToJSValue |
AddIncludesForType($type); |
+ ### DONE |
if ($type eq "SerializedScriptValue") { |
my $returnValue = "$nativeValue ? $nativeValue->deserialize() : v8::Handle<v8::Value>(v8::Null($getIsolate))"; |
return "${indent}v8SetReturnValue(${getCallbackInfo}, $returnValue);" if $isReturnValue; |
@@ -5589,7 +5896,7 @@ sub ForAllParents |
{ |
my $interface = shift; |
my $beforeRecursion = shift; |
- my $afterRecursion = shift; |
+ my $afterRecursion = shift; # nbarth: ? |
my $recurse; |
$recurse = sub { |
@@ -5601,7 +5908,7 @@ sub ForAllParents |
&$beforeRecursion($parentInterface) eq 'prune' and return; |
} |
&$recurse($parentInterface); |
- &$afterRecursion($parentInterface) if $afterRecursion; |
+ &$afterRecursion($parentInterface) if $afterRecursion; # nbarth: ? |
} |
}; |
@@ -5612,7 +5919,7 @@ sub FindSuperMethod |
{ |
my ($interface, $functionName) = @_; |
my $indexer; |
- ForAllParents($interface, undef, sub { |
+ ForAllParents($interface, undef, sub { # nbarth: (undef) ? |
my $currentInterface = shift; |
foreach my $function (@{$currentInterface->functions}) { |
if ($function->name eq $functionName) { |
@@ -5663,6 +5970,8 @@ sub ValidEnumValues |
return @{$enumTypeHash{$type}}; |
} |
+ |
+# merged with GetSVGTypeNeedingTearOff |
sub IsSVGTypeNeedingTearOff |
{ |
my $type = shift; |
@@ -5671,6 +5980,7 @@ sub IsSVGTypeNeedingTearOff |
return 0; |
} |
+### DONE |
sub IsSVGTypeWithWritablePropertiesNeedingTearOff |
{ |
my $type = shift; |
@@ -5702,6 +6012,7 @@ sub IsRefPtrType |
return 1; |
} |
+### DONE |
sub GetSVGTypeNeedingTearOff |
{ |
my $type = shift; |
@@ -5710,6 +6021,7 @@ sub GetSVGTypeNeedingTearOff |
return undef; |
} |
+### DONE |
sub GetSVGWrappedTypeNeedingTearOff |
{ |
my $type = shift; |
@@ -5779,6 +6091,7 @@ sub FirstLetterToUpperCase |
return $ret; |
} |
+### DONE |
# URL becomes url, but SetURL becomes setURL. |
sub ToMethodName |
{ |
@@ -5822,6 +6135,7 @@ sub LinkOverloadedFunctions |
} |
} |
+### DONE |
sub AttributeNameForGetterAndSetter |
{ |
my $attribute = shift; |
@@ -5850,6 +6164,8 @@ sub ContentAttributeName |
return "WebCore::${namespace}::${contentAttributeName}Attr"; |
} |
+### get_attribute_getter_info in python |
+### DONE |
sub GetterExpression |
{ |
my ($interfaceName, $attribute) = @_; |
@@ -5968,6 +6284,7 @@ sub GenerateCompileTimeCheckForEnumsIfNeeded |
return @checks; |
} |
+### call_with_contains in python |
sub ExtendedAttributeContains |
{ |
my $callWith = shift; |