Cleanup: move expression parsing for types to SourceLanguage.

This commit is contained in:
Rene Gollent 2012-11-06 12:22:06 +01:00
parent 4235cb3e33
commit 7b74c56650
6 changed files with 120 additions and 90 deletions

View File

@ -1,11 +1,16 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "CppLanguage.h"
#include "TeamTypeInformation.h"
#include "Type.h"
#include "TypeLookupConstraints.h"
CppLanguage::CppLanguage()
{
@ -22,3 +27,81 @@ CppLanguage::Name() const
{
return "C++";
}
status_t
CppLanguage::ParseTypeExpression(const BString &expression,
TeamTypeInformation* info,
Type*& _resultType) const
{
status_t result = B_OK;
Type* baseType = NULL;
BString parsedName = expression;
BString baseTypeName;
parsedName.RemoveAll(" ");
int32 modifierIndex = -1;
for (int32 i = parsedName.Length() - 1; i >= 0; i--) {
if (parsedName[i] == '*' || parsedName[i] == '&')
modifierIndex = i;
}
if (modifierIndex >= 0) {
parsedName.CopyInto(baseTypeName, 0, modifierIndex);
parsedName.Remove(0, modifierIndex);
} else
baseTypeName = parsedName;
result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(),
baseType);
if (result != B_OK)
return result;
BReference<Type> typeRef;
typeRef.SetTo(baseType, true);
if (!parsedName.IsEmpty()) {
AddressType* derivedType = NULL;
// walk the list of modifiers trying to add each.
for (int32 i = 0; i < parsedName.Length(); i++) {
address_type_kind typeKind;
switch (parsedName[i]) {
case '*':
{
typeKind = DERIVED_TYPE_POINTER;
break;
}
case '&':
{
typeKind = DERIVED_TYPE_REFERENCE;
break;
}
default:
{
return B_BAD_VALUE;
}
}
if (derivedType == NULL) {
result = baseType->CreateDerivedAddressType(typeKind,
derivedType);
} else {
result = derivedType->CreateDerivedAddressType(typeKind,
derivedType);
}
if (result != B_OK)
return result;
typeRef.SetTo(derivedType, true);
}
_resultType = derivedType;
} else
_resultType = baseType;
typeRef.Detach();
return result;
}

View File

@ -15,6 +15,10 @@ public:
virtual ~CppLanguage();
virtual const char* Name() const;
virtual status_t ParseTypeExpression(const BString &expression,
TeamTypeInformation* lookup,
Type*& _resultType) const;
};

View File

@ -17,3 +17,11 @@ SourceLanguage::GetSyntaxHighlighter() const
{
return NULL;
}
status_t
SourceLanguage::ParseTypeExpression(const BString &expression,
TeamTypeInformation* info, Type*& _resultType) const
{
return B_NOT_SUPPORTED;
}

View File

@ -9,7 +9,10 @@
#include <Referenceable.h>
class BString;
class SyntaxHighlighter;
class TeamTypeInformation;
class Type;
class SourceLanguage : public BReferenceable {
@ -21,6 +24,10 @@ public:
virtual SyntaxHighlighter* GetSyntaxHighlighter() const;
// returns a reference,
// may return NULL, if not available
virtual status_t ParseTypeExpression(const BString &expression,
TeamTypeInformation* info,
Type*& _resultType) const;
};

View File

@ -23,12 +23,16 @@
#include "ActionMenuItem.h"
#include "Architecture.h"
#include "FileSourceCode.h"
#include "Function.h"
#include "FunctionID.h"
#include "FunctionInstance.h"
#include "GuiSettingsUtils.h"
#include "MessageCodes.h"
#include "Register.h"
#include "SettingsMenu.h"
#include "SourceLanguage.h"
#include "StackTrace.h"
#include "StackFrame.h"
#include "StackFrameValues.h"
#include "TableCellValueRenderer.h"
@ -1651,14 +1655,24 @@ VariablesView::MessageReceived(BMessage* message)
}
Type* type = NULL;
BString typeName = message->FindString("text");
if (typeName.Length() == 0)
BString typeExpression = message->FindString("text");
if (typeExpression.Length() == 0)
break;
if (_ParseInputType(typeName, type) != B_OK)
FileSourceCode* code = fStackFrame->Function()->GetFunction()
->GetSourceCode();
if (code == NULL)
break;
SourceLanguage* language = code->GetSourceLanguage();
if (language == NULL)
break;
if (language->ParseTypeExpression(typeExpression,
fThread->GetTeam()->DebugInfo(), type) != B_OK) {
break;
}
ValueNode* valueNode = NULL;
if (TypeHandlerRoster::Default()->CreateValueNode(
node->NodeChild(), type, valueNode) != B_OK) {
@ -2140,89 +2154,6 @@ VariablesView::_ApplyViewStateDescendentNodeInfos(VariablesViewState* viewState,
}
status_t
VariablesView::_ParseInputType(const BString& typeName,
Type*& _resultType) const
{
status_t result = B_OK;
Type* baseType = NULL;
TeamDebugInfo* info = fThread->GetTeam()->DebugInfo();
if (info == NULL)
return B_NO_MEMORY;
BString parsedName = typeName;
BString baseTypeName;
parsedName.RemoveAll(" ");
// TODO: this is fairly C/C++-specific and should probably be
// language-agnostic in the long run
int32 modifierIndex = -1;
for (int32 i = parsedName.Length() - 1; i >= 0; i--) {
if (parsedName[i] == '*' || parsedName[i] == '&')
modifierIndex = i;
}
if (modifierIndex >= 0) {
parsedName.CopyInto(baseTypeName, 0, modifierIndex);
parsedName.Remove(0, modifierIndex);
} else
baseTypeName = parsedName;
result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(),
baseType);
if (result != B_OK)
return result;
BReference<Type> typeRef;
typeRef.SetTo(baseType, true);
if (!parsedName.IsEmpty()) {
AddressType* derivedType = NULL;
// walk the list of modifiers trying to add each.
for (int32 i = 0; i < parsedName.Length(); i++) {
address_type_kind typeKind;
switch (parsedName[i]) {
case '*':
{
typeKind = DERIVED_TYPE_POINTER;
break;
}
case '&':
{
typeKind = DERIVED_TYPE_REFERENCE;
break;
}
default:
{
return B_BAD_VALUE;
}
}
if (derivedType == NULL) {
result = baseType->CreateDerivedAddressType(typeKind,
derivedType);
} else {
result = derivedType->CreateDerivedAddressType(typeKind,
derivedType);
}
if (result != B_OK)
return result;
typeRef.SetTo(derivedType, true);
}
_resultType = derivedType;
} else
_resultType = baseType;
typeRef.Detach();
return result;
}
// #pragma mark - Listener

View File

@ -82,9 +82,6 @@ private:
VariablesViewState* viewState, void* parent,
TreeTablePath& path);
status_t _ParseInputType(const BString& typeName,
Type*& _outputType) const;
private:
Thread* fThread;
StackFrame* fStackFrame;