Skip to content

Commit

Permalink
feat(android): detailed getter and setter deprecation warning (#11049)
Browse files Browse the repository at this point in the history
Fixes TIMOB-27242
  • Loading branch information
garymathews authored Jul 17, 2020
1 parent 87246de commit 3507dd0
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,10 @@ void ${className}::${method.apiName}(const FunctionCallbackInfo<Value>& args)

<#if method.args?size == 0 && name[0..2] == "get" && isDynamic>
<#assign propertyName = name[3]?lower_case + name[4..]>
LOGW(TAG, "Automatic getter methods for properties are deprecated in SDK 8.0.0 and will be removed in SDK 10.0.0. Please access the property in standard JS style: obj.${propertyName}; or obj['${propertyName}'];");
Proxy::logDeprecation(isolate, "Getter method deprecated, please use \"obj.${propertyName};\" or \"obj['${propertyName}'];\" instead.");
<#elseif method.args?size == 1 && name[0..2] == "set" && isDynamic>
<#assign propertyName = name[3]?lower_case + name[4..]>
LOGW(TAG, "Automatic setter methods for properties are deprecated in SDK 8.0.0 and will be removed in SDK 10.0.0. Please modify the property in standard JS style: obj.${propertyName} = value; or obj['${propertyName}'] = value;");
Proxy::logDeprecation(isolate, "Setter method deprecated, please use \"obj.${propertyName} = val;\" or \"obj['${propertyName}'] = val;\" instead.");
</#if>

jobject javaProxy = proxy->getJavaObject();
Expand Down
37 changes: 35 additions & 2 deletions android/runtime/v8/src/native/Proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,12 @@ void Proxy::getProperty(const FunctionCallbackInfo<Value>& args)

// Spit out deprecation notice to use normal property getter
v8::String::Utf8Value propertyKey(isolate, name);
LOGW(TAG, "Automatic getter methods for properties are deprecated in SDK 8.0.0 and will be removed in SDK 10.0.0. Please access the property in standard JS style: obj.%s; or obj['%s'];", *propertyKey, *propertyKey);
char* deprecationMessage;
asprintf(&deprecationMessage, "Getter method deprecated, please use \"obj.%s;\" or \"obj['%s'];\" instead.", *propertyKey, *propertyKey);
if (deprecationMessage != nullptr) {
Proxy::logDeprecation(isolate, deprecationMessage);
free(deprecationMessage);
}

args.GetReturnValue().Set(getPropertyForProxy(isolate, name, args.Holder()));
}
Expand Down Expand Up @@ -213,7 +218,12 @@ void Proxy::onPropertyChanged(const v8::FunctionCallbackInfo<v8::Value>& args)
Local<Name> name = args.Data().As<Name>();
// Spit out deprecation notice to use normal property setter, not setX() style method.
v8::String::Utf8Value propertyKey(isolate, name);
LOGW(TAG, "Automatic setter methods for properties are deprecated in SDK 8.0.0 and will be removed in SDK 10.0.0. Please modify the property in standard JS style: obj.%s = value; or obj['%s'] = value;", *propertyKey, *propertyKey);
char* deprecationMessage;
asprintf(&deprecationMessage, "Setter method deprecated, please use \"obj.%s = value;\" or \"obj['%s'] = value;\" instead.", *propertyKey, *propertyKey);
if (deprecationMessage != nullptr) {
Proxy::logDeprecation(isolate, deprecationMessage);
free(deprecationMessage);
}

Local<Value> value = args[0];
Local<Context> context = isolate->GetCurrentContext();
Expand Down Expand Up @@ -584,4 +594,27 @@ jobject Proxy::unwrapJavaProxy(const v8::FunctionCallbackInfo<v8::Value>& args)
return firstArgument->IsExternal() ? (jobject) (firstArgument.As<External>()->Value()) : NULL;
}

void Proxy::logDeprecation(Isolate* isolate, const char* message)
{
// Print deprecation message.
LOGW(TAG, message);

// Create exception to obtain current stack and source line.
Local<Message> exception = Exception::CreateMessage(isolate, Exception::Error(v8::String::NewFromUtf8(isolate, message, v8::NewStringType::kNormal).ToLocalChecked()));

// Obtain and print source line.
v8::String::Utf8Value sourceLine(isolate, exception->GetSourceLine(isolate->GetCurrentContext()).ToLocalChecked());
std::string sourceLineString = std::string(*sourceLine, sourceLine.length());
LOGW(TAG, sourceLineString.c_str());

// Log erroneous column.
if (exception->GetEndColumn() > 0) {
LOGW(TAG, (std::string(exception->GetEndColumn() - 1, ' ') + std::string("^")).c_str());
}

// Log location of deprecated usage.
std::string stackString = V8Util::stackTraceString(isolate, exception->GetStackTrace(), 1);
LOGW(TAG, stackString.c_str());
}

} // namespace titanium
5 changes: 5 additions & 0 deletions android/runtime/v8/src/native/Proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ class Proxy : public JavaObject

static void dispose(v8::Isolate* isolate);

/**
* Log detailed deprecation warning.
*/
static void logDeprecation(v8::Isolate* isolate, const char* message);

private:

/**
Expand Down
4 changes: 2 additions & 2 deletions android/runtime/v8/src/native/V8Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,14 @@ void V8Util::dispose()
isNaNFunction.Reset();
}

std::string V8Util::stackTraceString(v8::Isolate* isolate, Local<StackTrace> frames) {
std::string V8Util::stackTraceString(Isolate* isolate, Local<StackTrace> frames, int maxCount) {
if (frames.IsEmpty()) {
return std::string();
}

std::stringstream stack;

for (int i = 0, count = frames->GetFrameCount(); i < count; i++) {
for (int i = 0, count = frames->GetFrameCount() < maxCount ? frames->GetFrameCount() : maxCount; i < count; i++) {
v8::Local<v8::StackFrame> frame = frames->GetFrame(isolate, i);

v8::String::Utf8Value jsFunctionName(isolate, frame->GetFunctionName());
Expand Down
2 changes: 1 addition & 1 deletion android/runtime/v8/src/native/V8Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class V8Util {
static bool constructorNameMatches(v8::Isolate* isolate, v8::Local<v8::Object>, const char* name);
static bool isNaN(v8::Isolate* isolate, v8::Local<v8::Value> value);
static void dispose();
static std::string stackTraceString(v8::Isolate* isolate, v8::Local<v8::StackTrace> frames);
static std::string stackTraceString(v8::Isolate* isolate, v8::Local<v8::StackTrace> frames, int maxCount = 0);
};

}
Expand Down

0 comments on commit 3507dd0

Please sign in to comment.