Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Abstract Syntax Tree en Práctica

13/42
Recursos

Aportes 138

Preguntas 10

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Si estás leyendo esto y viendo esta clase por primera vez, te recomiendo que hagas el curso y lo vuelvas a hacer. Personalmente he aprendido muchísimo ahora que estoy haciendo el curso por segunda vez. Me ha gustado muchísimo esta clase y ahora la entiendo mejor. 😄

WOW  🤯

Abstract Syntax Tree en Práctica

Vamos a usar el AST para crear una regla de eslint, este analizará estéticamente nuestro código a ver si hay que levantar un warning por violar la sintaxis. Muchas de estas reglas ya viene con e eslint, pero podemos agregar nuestras propias reglas. Vamos a usar la herramienta AST | Explorer para experimentar. Usaremos la configuración por defecto, veremos en la parte superior izquierda el código que vamos a ingresar, a la derecha el tree creado, en la parte inferior izquierda las funciones de las reglas y a la derecha de eso la salida de nuestro código.

Test

En el link de AST Explorer ya tenemos un código escrito. Donde el la primera entrada tenemos las tareas que debe cumplir nuestro fixer.

const pi = 3.1415;
const half_pi = 1.57075;
// variable constantes
// variables que guarden un numero

// El nombre de la variable tiene que estar en UPPERCASE

A la derecha tenemos el árbol completo de todas estas declaraciones y gracias a el podemos manipular, detectar errores o interpretar lo que escribamos. Luego implementamos una función que recibe la declaración de la variable y accedemos a los datos que nos ofrece el AST para lograr cumplir con los requerimientos de nuestro solucionador.

export default function(context) {
  return {
    VariableDeclaration(node) {
        // tipo de variable const
          if (node.kind === "const") {
          const declaration = node.declarations[0];

          // asegurarnos que el valor es un numero
          if (typeof declaration.init.value === "number") {
            if (declaration.id.name !== declaration.id.name.toUpperCase()) {
              context.report({
                node: declaration.id,
                message: "El nombre de la constante debe estar en mayúsculas",
                fix: function(fixer) {
                  return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase())
                }
              })
            }
          }
        }
    }
  };
};

Con context.report() podemos mandar un warning y además podemos solucionar el problema que se haya presentado.

Algo que no se si se puede, pero si no se puede estaría muy bien que se @platzi lo incluya es que seria interesante una opción de videos/clases favoritas (o algo así) y que en el board del curso exista una opción para ver los favoritos o incluso mas haya en nuestro perfil que exista una opción de ver todos los favoritos (de cualquier curso/carrera).

Esta muy buenisimo este curso, yo que creia saber de JavaScript jeje

Estás usando Firefox y no te sale el ejercicio?! Creo que el AST se forma diferente en el motor que usa Firefox (SpiderMonkey) y tiene algunas diferencias para accesar a los nodos, pero examinándolo, debería resultar, al final pude implementar la regla asi:

export default function(context) {
  return {
	VariableDeclarator(node){
    	// tipo const
      const declaration = node.parent.declarations[0];
      console.log(node.parent.kind)
      if (node.parent.kind === "const"){        
        //asegurarnos que el valor es un numero
        if (typeof declaration.init.value === "number") {
          if (declaration.id.name !== declaration.id.name.toUpperCase()) {
            context.report({
            	node: declaration.id,
              	message: "Const name not in Upper case",
              	fix: function (fixer) {
                	return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase());
                }
            })
          }          
        }
      }
    }
  };
};

Sí, uso Firefox … Qué me ve Ramirez!?

iré a tomar acetaminofén para seguir con la otra clase. 🎭

No se por que, pero siento como que estoy programando el lenguaje jaja

Según yo sabía JavaScript jaja, este curso está muy bueno.

Hice una regla para nombrar a las "clases"
function MiClase(parametros) <- la primera letra de la funcion deberia ser mayuscula para saber de que estamos hablando de clases

codigo inicial

const Pi = 3.1415
const half_pi = 1.57075

function auto(marca){
	this.marca = marca
}
function Macarron(marca){
	this.marca = marcar
}

codigo final

const Pi = 3.1415
const half_pi = 1.57075

function Auto(marca){
	this.marca = marca
}
function Macarron(marca){
	this.marca = marcar
}

regla

export default function(context) {
  return {
	FunctionDeclaration(node){
    	const isClass = node.body.body[0].expression.left.object.type
        const id = node.id
        const iden = node.id.name.charAt(0)
        
        if(isClass === "ThisExpression"){
        	if(iden !== iden.charAt(0).toUpperCase()){
              context.report({
              	node: id,
                message: "La primera letra debe estar en mayuscula",
                fix: function(fixer) {
                  const r = iden.charAt(0).toUpperCase()
                  const resto = id.name.substr(1)
                  return fixer.replaceText(id, r + resto)
                }
              })
            }
        }      
    }
  };

Esta lejos de ser perfecta, es solo para practicar, el inspector ayuda mucho a identificar los elementos

Cada clase de este curso me vuela la cabeza. Tengo que verla mínimo 5 veces 😅

Todo eso por hacer una variable wtf!

Estaría genial tener un curso dedicado a ESLint y AST para crear tus propios estilos. Es un tema complejo a la vez que interesante.

No tenia idea como ast hacia su trabajo. Considero que este curso esta lleno de videos que valen oro ya que no es muy fácil encontrar cursos donde detallen o siquiera toquen estos temas!

ESLINT es un lenguaje que nos permite crear reglas y se utiliza el AST para obtener información acerca del código escrito.

export default function (context) {
  return {
    VariableDeclaration(node) {
      //Tipo de variable const
      if (node.kind === "const") {
        const declaration = node.declarations[0];

        //Hay que asegurarnos que el valor es un numero
        if (typeof declaration.init.value === "number") {
          if (declaration.id.name !== declaration.id.name.toUpperCase()) {
            //Si la variable constante no esta en mayusculas, lanzamos un error
            //Para declarar errores usaremos el argumento context.
            context.report({
              node: declaration.id,
              message: "El nombre de la constante debe estar en Mayusculas",
              //ESLINT tambien nos permite corregir los errores automaticamente
              fix: function (fixer) {
                return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase());
              }
            });
          }
        }
      }
    }
  };
}```

Por si alguien quiere una explicación mejor…
https://www.freecodecamp.org/espanol/news/que-es-linting-y-eslint/

Mi pregunta es esta nueva regla que desarrollamos como la implementamos en EsLint? ,
aun no nos enseñan como usar EsLint solo instalamos el plugin y desde node ,pero no lo hemos usado

Como puedo poner como favoritas esta clase? empece odiando el curso por lo complejo , pero cada vez le tomo mas cariño jjaja

wtf

¡Conocer como funcionan las cosas detras de escenas es asombroso!

Donde estan los apuntes de braco ? >:c

export default function(context) {
  return {
    VariableDeclaration(node) {
		// tipo de variable const
      	if (node.kind === "const") {
          const declaration = node.declarations[0];
          
          // asegurarnos que el valor es un numero
          if(typeof declaration.init.value === "number") {
            if(declaration.id.name !== declaration.id.name.toUpperCase()) {
              context.report({
                node: declaration.id,
                message: "El nombre de la constante debe estar en mayusculas",
                fix: function(fixer) {
                   return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase()) 
                }
              })
            }
          }
        }
    }
  };
};

Al generar la regla en https://astexplorer.net/ como la puedo implementar en mi eslint?

Wow… no sabía que ESLint se basaba en el AST, está genial, con esto se puede hacer muchas cosas, puedes validar lo que quieras usando el mismo lenguaje!, me gusta! Creo que empezaré a hacer mis propias reglas de validación:D!

es buena esa sugerencia y volver a hacer el curso

excelente clase todo lo que hay detrás de declarar una variable y todo el proceso que conlleva genial aunque por mi parte lo repetí varias veces el video

Si has jugado con APIs esta clase no te será tan difícil

Muy interesante esta Herramienta. Gracias!!

En shock!

Que buena clase sin duda!

Increible todo lo que no sabia que no sabia de Javascript.

Este curso esta grandioso.

Esta clase y la pasada son oro molido. Increíble.

Esto está increíble!!!!!!!!

BRACOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO DONDE ESTAAAAAAAAS?

Muy enrredado el curso 😦

Como programar un programa que este al pendiente del estilo de tu programa, escrito con el mismo lenguaje con el que estas escribiendo tu programa.

Aquí es donde te das cuenta que quizá no sabias tanto como pensabas

¿Soy el único que está así?

Esta clase pertenece al siguiente nivel.

Creamos un regla que verificar que una constante este en mayusculas, pero en la misma regla creamos una constante en minusculas?

Como ejercicio, hice un programa que siga las siguientes reglas:

  • Si el valor de la variable es un número, tendrá que ser declarada con const.
  • De lo contrario tendrá que ser declarada con let.
export default function (context) {
  return {
    VariableDeclaration(node) {
      const variableType = node.declarations[0].init.value;
      const isNumber = typeof variableType == "number";

      if (isNumber) {
        if (node.kind != "const") {
          context.report({
            node: node,
            message: "Los números deben ser declarados con const"
          });
        }
      } else {
        if (node.kind != "let") {
          context.report({
            node: node,
            message: "Las variables que no sean números deben ser declaradas con let"
          });
        }
      }
    }
  };
}

No supe como usar la propiedad fix, invitados a intentar 😃

Como es posible que videos de 10 min, terminen siendo 1 hora o mas para entenderlos. Cada vez que termino uno tengo que tomarme un Acetaminofen despues de ver tanta información. Pero ahí vamos de a poco para los que iniciamos esto si un conocimiento previo de programación. Nunca pares de aprender!

Ya había tomado este curso sin haber tomado el de Javascript basico y no entendi nada, ahora que ya se de JavaSript me es mucho mas facil entender lo que dice, por eso compañeros, no se adelanten los cursos y siempre practiquen para poder solidificar los conocimientos

Clase muy enriquecedora!

Me gusto mucho esta clase!!!

Definitivamente, fuera de serie, Gracias

Si en algún momento tienen duda de dónde se encuentra algo, solo hagan un console.log a “node” y exploren

export default function(context){
    return{
      VariableDeclaration(node){
        //Nos aseguramos que se trate de una constante
        console.log(node)
        if(node.kind === "const"){
          const declaration = node.declarations[0]
          //Nos aseguramos que se trate de un número
          if(typeof declaration.init.value === "number"){
            //Verificamos que esté en mayusculas
            if(declaration.id.name !== declaration.id.name.toUpperCase()){
            context.report({
              node: declaration.id,
              message: "Los números constantes deben estar en mayúsculas",
              fix: function(fixer){
                return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase())
              }
            })}
          }
        }
      }
    } 
   }

Gran clase !

Excelente clase. No tenía idea de todo lo que había por detrás, y mucho menos de que podías llegar a crear tus propias reglas de esta forma.

Se pueden hacer muchas cosas con el AST, Excelente!

Esta clase me gusto demasiado, fue increible escribir una regla de eslint =)

No tenía ni idea que esto se podía hacer, me encanta este curso. ❤️

Clase genial!!

Cada vez se pone más interesante 🤩😎

Interesante!

Bastante interesante !

muy bueno, muy interesante, gran informacion, ojala se pudiera profundizar mas

Interesante saber como crear reglas propias 😄

export default function(context){
  return {
    VariableDeclaration(node){
      // tipo de variable const
      if(node.kind === "const"){
        const declaration = node.declarations[0];

        // Asegurarnos que el valor es un numero
        if(typeof declaration.init.value === "number"){
          if(declaration.id.name !== declaration.id.name.toUpperCase()){
            context.report({
              node: declaration.id,
              message: "El nombre de la constante debe estár en mayusculas",
              fix: function(fixer){
                return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase())
              }
            })
          }
        }
      }
    }
  }
}```

A mi no me sale nada cuando hago console.log(node) 😕

AYUDA! En la consola no me aparece el Node… Quiero hacer le primer paso pero la consola no me da respuesta

export default function (context) {
    return {
        VariableDeclaration(node) {
            if (node.kind !== 'const') {
                return;
            }

            const declarations = node.declarations;
            declarations.forEach(declaration => {
                if (declaration.id.name !== declaration.id.naame.toUpperCase()) {
                    context.report({
                        node: declaration.id,
                        message: "El nombre de la constante debe estar en mayúsculas",
                        fix: function (fixer) {
                            return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase());
                        },
                    });
                }
            });
        }
    };
};

Con esta pequeña mejora ya podemos hacer declaraciones como esta:

const gravity = 9.81, k0 = 10.22; // const GRAVITY = 9.81, K0 = 10.22;

[SOLUCIÓN] La Consola no muestra Nada:

Para aquellos que están teniendo el inconveniente de que la consola de desarrollador no muestra nada en Chrome, hagan lo siguiente:

  1. Hagan click en configuración (el engranaje).
  2. En la pestaña Preferences diríjanse hasta casi el final de de las opciones y en la sección Console tilden el checkbox que dice “Preserve log upon navigation”

Esto me solucionó el inconveniente.

😮

muy buena clase.

Buena clase

El AST Es una estructura que descompone todo el código para analizarlo mucho más fácil. Es lo que usa JS para leer el código, convertirlo a Bytecode y poder ser interpretado

Te vuela un poquito la cabeza, pero super útil.

Está clase merece poder ponerle un Super Like!

El tema del AST y el proceso de JavaScript en el navegador también se explica en este curso: https://platzi.com/clases/javascript-navegador/ de Diego de Granda

Entendido

muy interesante

Super genial como hacer un LINTER del codigo

muy chevere 😃

Muy interesante!

Que genial todo esto!

Increible, mi cabeza está explotando!

El arreglador. 🤣

Vine buscando cobre y encontré oro 😄

Este curso me hará comprar la anualidad :v

Y pensar que yo creía saber Javascript JA!

este curso es brutal!, mi mente explota en cada clase 😮

Increiblee!

Profundizando aún más en las complejidades de js, el curso me está encantando!

Estoy 😱. ¡Què curso tan grandioso!

Estaba provando la regla y me di cuenta de algo no tomaba encuenta las declaraciones con coma ejemplo:

const uno = 1, dos = 2;

solo lanzaba el error ala primera de claració asi que le agregue un forEach para que funcionara

export default function (context) {
  return {
    VariableDeclaration(node) {
      // tipo de variable const
      if (node.kind === "const") {
        node.declarations.forEach((declaration) => {
          // asegurarnos que el valor es un numero
          if (typeof declaration.init.value === "number") {
            if (declaration.id.name !== declaration.id.name.toUpperCase()) {
              context.report({
                node: declaration.id,
                message: "El nombre de la constante debe estar en mayúsculas",
                fix: function (fixer) {
                  return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase());
                }
              });
            }
          }
        });
      }
    }
  };
}

antes:

const UNO = 1, dos = 2;

ahora:

const UNO = 1, DOS = 2;

Abstract

Entonces es gracias al Abstract Syntax Tree como el V8 Engine nos dice si hay algún error en el código y donde esta ese error. De la misma manera es como ESLint o Prettier nos ayudan a resolver errores de código o hacer que el código sea consistente, respectivamente.
.
Sin embargo, hay que tener en cuenta las limitaciones del AST, ya que incluso aunque nos ayude a resolver problemas de sintaxis, no nos puede ayudar con problemas de lógica. En ese caso me pregunto si con TypeScript se podra ver errores lógicos con solo mirar el AST…

Yo no sigo las reglas de sintaxis, las reglas de sintaxis me siguen a mi

Este curso ESTÁ BUENÍSIMO

🤯🤯🤯🤯🤯

A partir de los nodos que genera el parser, se crea el AST. Un árbol que representa tu código sintácticamente.

Javascript:

 const pi = 3.1415;
const e = 2.7114;
//variable constantes
//variables que guardan un numero

//El nombre de la variable tiene que estar en UPPERCASE
function saludar(nombre){
	this.nombre = nombre
}
function despedir(nombre){
	this.nombre = nombre
}

ESLINT

export default function (context) {
  return {
    VariableDeclaration(node) {
      //Tipo de variable const
      if (node.kind === "const") {
        //busca la primera declaracion
        const declaration = node.declarations[0];
        //Asegurarnos que el valor es un numero
        if (typeof declaration.init.value === "number") {
          if (declaration.id.name !== declaration.id.name.toUpperCase()) {
            context.report({
              node: declaration.id,
              message: "el nombre de la constante debe estar en mayuscula",
              fix: function (fixer) {
                return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase());
              }
            });
          }
        }
      }
    },
    FunctionDeclaration(node) {
      const name_function = node.body.body[0].expression.left.object.type;
      if (name_function === "ThisExpression") {
        if (node.id.name.charAt(0) !== node.id.name.charAt(0).toUpperCase()) {
          context.report({
            node: node.id,
            message: "El nombre de la funcion debe empezar con mayuscula",
            fix: function (fixer) {
              const m = node.id.name.charAt(0).toUpperCase();
              const n = node.id.name.slice(1);
              return fixer.replaceText(node.id, m + n);
            }
          });
        }
      }
    }
  };
}

13. Abstract Syntax Tree en Práctica

Vamos a usar el AST para crear una regla de eslint, este analizará estéticamente nuestro código a ver si hay que levantar un warning por violar la sintaxis. Muchas de estas reglas ya viene con e eslint, pero podemos agregar nuestras propias reglas. Vamos a usar la herramienta AST | Explorer para experimentar. Usaremos la configuración por defecto, veremos en la parte superior izquierda el código que vamos a ingresar, a la derecha el tree creado, en la parte inferior izquierda las funciones de las reglas y a la derecha de eso la salida de nuestro código.

Se usará AST para crear una regla para ESlint. Esta herramienta analiza esta estáticamente nuestro código para ver si:

  • Sí Encuentra errores
  • Sí hay que levantar warnings porque se está violando alguna regla de estilo
  • Sí el código está violando la sintaxis del lenguaje.

Muchas de estas reglas ya vienen con ESLint pero también podemos desarrollar nuevas. Para hacer eso vamos a utilizar una herramienta que se llama AST, el link es el siguiente:

Referencia:

Propuesta del ejercicio

Se tiene el siguiente código

const pi = 3.1415;
const half_pi = 1.57075

La idea es que se respete la sintaxis anterior, pero se requiere que la declaración de constantes sean en mayúsculas es decir el resultado tiene que ser el siguiente:

const PI = 3.1415;
const HALF_PI = 1.57075;
// variable constantes

Configuración previa

En AST explorer. Lo primero es que tenemos que asegurarnos que la configuración es la correcta. en la parte superior de la página se encuentra un menú, hay un menú con el siguiente símbolo </> en ses menú seleccionar la opción babel-eslint. Luego dirigirse al menú de al lado que dice: transform, en este caso seleccionar la opción con se va a procesar el lenguajeeslint v4 . Es las dos acciones anteriores harán que se despliegue 2 caja de entradas.

Reglas que se debe codificar

  1. Detectar las variables que estén declaradas tipo const y represente un valor númerico.
  2. Una vez detectadas esas condiciones, verificar que la variable este en mayúsculas o Uppercase.
  3. Si las anteriores reglas no se cumple mostrar un Error

Solución del ejercicio.

// - context
// - node representa todas las línea de declaración.
// - node.kind respresenta el tipo de declaración. si existe más de una las represanta a todas
// - node.declarations[0] representa la primera declaración
// - node.declarations[0].init.value representa el valor de la variable
export default function (context) {
	return {
		VariableDeclaration(node) {
			//Se toman todas las declaraciones con const
			if (node.kind === 'const') {
				const declaration = node.declarations[0];

				// se verifica que todas las declaraciones con const sean de tipo numerico
				if (typeof declaration.init.value === 'number') {
					
                    // se verifica que  el nombre de la variable este en mayúscula
                    if (
						declaration.id.name !==
						declaration.id.name.toUpperCase()
                    ) {
                        
                        // se envia un mensaje de error, context report recibe un objeto
						context.report({
							node: declaration.id,
							message:
                                'El nombre de la constante debe estar en mayúsculas',
                            // función que repara el  error
							fix: function (fixer) {
								return fixer.replaceText(
									declaration.id,
									declaration.id.name.toUpperCase()
								);
							},
						});
					}
				}
			}
		},
	};
}


Ejercicio resultoEjercicio resuelto