Individuazione di codice mediante il modello di codice (Visual Basic)
Il modello di codice di Visual Studio consente ai client di automazione di rilevare definizioni di codice all'interno di un progetto e di modificarne gli elementi. Il modello di codice aggiorna automaticamente tutti gli oggetti a cui viene fatto riferimento ogni volta che vengono apportate modifiche all'interno dell'editor del codice. Se, ad esempio, si fa riferimento a un oggetto classe e successivamente un utente aggiunge una nuova funzione, essa verrà elencata tra i membri. Grazie al modello di codice, non è necessario che i client di automazione implementino un parser per i linguaggi Visual Studio per rilevare definizioni ad alto livello di un progetto, ad esempio classi, interfacce, strutture, metodi, proprietà e così via.
Il modello di codice di base di Visual Studio ignora le aree di codice specifiche del linguaggio, ad esempio non fornisce un modello a oggetti per le istruzioni nelle funzioni né offre informazioni dettagliate sui parametri. Per quanto riguarda i parametri, il modello di codice espone esclusivamente il tipo e il nome del parametro, senza specificare se si tratta di un parametro di input, di output, facoltativo e così via. In Visual C++ è disponibile una versione estesa del modello di codice di base destinata ai progetti Visual C++. Per ulteriori informazioni, vedere Modello di codice Visual C++.
Analisi e modifica del codice mediante il Modello codice
Il modello di codice è principalmente basato su testo, poiché il programma o il codice contenuto nei progetti è archiviato in file di testo. È possibile trovare il codice di un progetto utilizzando il modello del progetto per visitare ogni elemento di progetto, quindi utilizzare la proprietà FileCodeModel per verificare che ogni elemento contenga codice. Se un elemento di progetto contiene elementi di codice, questi possono restituire oggetti dall'editor e il modello di codice può utilizzare il modello di automazione dell'editor di testo per modificare il codice o eseguire l'analisi localizzata. Tramite il modello a oggetti dell'editor è possibile richiedere l'elemento di codice contenente il punto di inserimento dell'editor o un oggetto TextPoint a livello di funzione o di classe.
Il punto di ingresso principale del modello di codice di base di Visual Studio è l'oggetto CodeModel. Un insieme CodeElements generale viene utilizzato in varie parti del modello di codice. Uno si trova a livello della proprietà CodeElements e a livello della classe o dell'interfaccia che restituisce i membri di questi oggetti. Ogni elemento di un insieme CodeElements è un oggetto CodeElement2 e ogni oggetto CodeElement2 dispone di una proprietà Kind che ne identifica il tipo, che si tratti di classe, interfaccia, struttura, funzione, proprietà, variabile e così via.
Modelli di codice specifici del linguaggio
In Visual C++ è disponibile un'estensione al modello di codice di base destinata al codice specifico di Visual C++. Se, ad esempio, la proprietà Language indica che un determinato elemento di codice è un oggetto del modello di codice di Visual C++ e Kind = vsCMElementClass, è possibile scegliere di eseguire QI (QueryInterface) per CodeClass dal modello di codice di Visual Studio o QI per VCCodeClass dal modello di codice specifico del linguaggio Visual C++. Per ulteriori informazioni sul modello di codice specifico di Visual C++, vedere Procedura: modificare il codice tramite il modello di codice di Visual C++ (Visual Basic) e Modello di codice Visual C++.
Note relative al modello di codice di base di Visual Studio
Solo l'implementazione del modello di codice di Visual C++ esegue la modellazione specifica del linguaggio per le implementazioni dei linguaggi Microsoft.
In alcune implementazioni di linguaggi il modello di codice di Visual Studio non viene implementato. Negli argomenti della Guida sono segnalate le eventuali eccezioni. La maggior parte delle differenze tra implementazioni del modello di codice è dovuta a differenze funzionali tra i linguaggi. Non è ad esempio possibile aggiungere funzioni a oggetti CodeNamespace in Visual Basic o Visual C# poiché solo in Visual C++ sono disponibili definizioni di funzioni di primo livello.
Descrizione
In questo componente aggiuntivo vengono esaminati i diversi elementi di codice di un file di Visual Studio. Per eseguire l'esempio, è necessario che un file di codice di origine sia aperto nell'editor del codice di Visual Studio. Per ulteriori informazioni su come eseguire gli esempi, vedere Procedura: compilare ed eseguire gli esempi di codice del modello a oggetti di automazione.
Codice
' Add-in code.
Public Sub OnConnection(ByVal application As Object, ByVal _
connectMode As ext_ConnectMode, ByVal addInInst As Object, _
ByRef custom As Array) Implements IDTExtensibility2.OnConnection
_applicationObject = CType(application, DTE2)
_addInInstance = CType(addInInst, AddIn)
' Pass the applicationObject member variable to the code example.
OutlineCode(_applicationObject)
End Sub
Sub OutlineCode(ByVal dte As DTE2)
Dim fileCM As FileCodeModel2 _
= CType(dte.ActiveDocument.ProjectItem.FileCodeModel, _
FileCodeModel2)
Dim elts As CodeElements
elts = fileCM.CodeElements
Dim elt As CodeElement2
Dim i As Integer
MsgBox("About to walk top-level elements ...")
For i = 1 To fileCM.CodeElements.Count
elt = CType(elts.Item(i), CodeElement2)
CollapseElt(elt, elts, i)
Next
End Sub
Sub CollapseElt(ByVal elt As CodeElement2, ByVal elts As _
CodeElements, ByVal loc As Long)
Dim epStart As EditPoint2
Dim epEnd As EditPoint2
epStart = CType(elt.StartPoint.CreateEditPoint, EditPoint2)
' Do this since we move it later.
epEnd = CType(elt.EndPoint.CreateEditPoint, EditPoint2)
epStart.EndOfLine()
If ((elt.IsCodeType) And (elt.Kind <> _
vsCMElement.vsCMElementDelegate)) Then
MsgBox("Got type but not a delegate, named : " & elt.Name)
Dim ct As CodeType
ct = CType(elt, CodeType)
Dim mems As CodeElements
mems = ct.Members
MsgBox("Set mems = ct.members")
Dim i As Integer
For i = 1 To ct.Members.Count
CollapseElt(CType(mems.Item(i), CodeElement2), mems, i)
Next
ElseIf (elt.Kind = vsCMElement.vsCMElementNamespace) Then
MsgBox("Got a namespace, named: " & elt.Name)
Dim cns As CodeNamespace
cns = CType(elt, CodeNamespace)
MsgBox("set cns = elt, named: " & cns.Name)
Dim mems_vb As CodeElements
mems_vb = cns.Members
MsgBox("Got cns.members")
Dim i As Integer
For i = 1 To cns.Members.Count
CollapseElt(CType(mems_vb.Item(i), CodeElement2), _
mems_vb, i)
Next
End If
End Sub
Possibile modifica dei valori degli elementi del modello di codice
I valori assegnati degli elementi del modello di codice, quali classi, strutture, funzioni, attributi, delegati e così via, possono cambiare dopo alcuni tipi di modifiche. Di conseguenza, non è possibile presupporre che i valori rimarranno statici.
Se, ad esempio, si assegna un elemento del modello di codice a una variabile locale e si imposta un valore di proprietà per tale variabile, quest'ultima non potrà contenere un elemento del modello di codice quando si farà successivamente riferimento ad essa. In effetti, potrà inoltre contenere un elemento differente del modello di codice.
Si consideri una classe contenente una funzione denominata "MyFunction" assegnata a una variabile CodeFunction e che la proprietà Name della variabile CodeFunction sia impostata sul valore "YourFunction". Dopo l'assegnazione di questa variabile, non si avrà più la garanzia che la variabile locale rappresenti la stessa variabile CodeFunction. Se si accede, in un secondo momento, al valore della proprietà, potrebbe essere restituito lo stato E_FAIL.
In tali situazioni si consiglia di riassegnare in modo esplicito la variabile locale all'elemento del modello di codice corretto prima di accedere ai relativi valori di proprietà. Di seguito viene illustrato un esempio della procedura da eseguire: il codice viene presentato nella forma di un componente aggiuntivo.
Descrizione
Questo componente aggiuntivo dimostra il modo corretto per accedere ai valori di CodeElements e recuperare il valore appropriato. Per ulteriori informazioni su come eseguire gli esempi, vedere Procedura: compilare ed eseguire gli esempi di codice del modello a oggetti di automazione.
Codice
[Visual Basic]
Public Sub OnConnection(ByVal application As Object, ByVal _
connectMode As ext_ConnectMode, ByVal addInInst As Object, _
ByRef custom As Array) Implements IDTExtensibility2.OnConnection
_applicationObject = CType(application, DTE2)
_addInInstance = CType(addInInst, AddIn)
ReassignValue(_applicationObject)
End Sub
Sub ReassignValue(ByVal dte As DTE2)
' Before running, create a new Windows application project,
' and then add a function to it named MyFunction.
Try
Dim myFCM As FileCodeModel = _
dte.ActiveDocument.ProjectItem.FileCodeModel
' Change the MyFunction name in Form1 class to
' the name, OtherFunction.
Dim myClass1 As CodeClass = _
CType(myFCM.CodeElements.Item("Form1"), CodeClass2)
Dim myFunction As CodeFunction = _
CType(myClass1.Members.Item("MyFunction"), CodeFunction2)
myFunction.Name = "OtherFunction"
myFunction = CType(myClass1.Members.Item("OtherFunction"), _
CodeFunction2)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
[C#]
public void OnConnection(object application, ext_ConnectMode
connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
ReassignValue(_applicationObject);
}
// Before running, create a new Windows application project,
// and then add a function to it named MyFunction.
public void ReassignValue(DTE2 dte)
{
try
{
FileCodeModel myFCM =
dte.ActiveDocument.ProjectItem.FileCodeModel;
// Change the MyFunction name in Form1 class to
// the name, OtherFunction.
CodeClass myClass1 =
(CodeClass2)myFCM.CodeElements.Item("Form1");
CodeFunction myFunction =
(CodeFunction2)myClass1.Members.Item("MyFunction");
myFunction.Name = "OtherFunction";
myFunction =
(CodeFunction2)myClass1.Members.Item("OtherFunction");
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
Nota
L'impostazione delle proprietà di elementi figlio dell'elemento del modello di codice non rileva tale comportamento. Solo le proprietà che influiscono direttamente sul CodeElement, quali il nome dell'elemento, il tipo di una funzione, la firma di un metodo e così via, rivelano tale comportamento non deterministico.
Inoltre, tale esempio è valido solamente se il nuovo nome del CodeElement è univoco tra gli elementi di pari livello. Ciò è dovuto al fatto che la proprietà Item restituisce il primo risultato, non utilizzabile per metodi/proprietà in overload, classi parziali o spazi dei nomi con lo stesso nome.
Vedere anche
Attività
Procedura: compilare codice di esempio per l'Extensibility del modello di codice di Visual C++
Procedura: creare un componente aggiuntivo
Procedura dettagliata: creazione di una procedura guidata
Procedura: modificare il codice tramite il modello di codice di Visual C++ (Visual C#)
Concetti
Individuazione di codice mediante il modello di codice (Visual C#)
Grafico del modello a oggetti di automazione
Altre risorse
Creazione e controllo delle finestre di ambiente